feat(youtube/return-youtube-dislike): compatibility for old and new button layout

This commit is contained in:
oSumAtrIX 2022-10-29 01:54:03 +02:00
parent 3698a502c3
commit a92c932a20
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
5 changed files with 60 additions and 35 deletions

View File

@ -13,17 +13,12 @@ import java.util.function.Consumer;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils;
/**
* Helper functions.
*/
final class Extensions {
static boolean containsAny(final String value, final String... targets) {
for (String string : targets)
if (value.contains(string)) return true;
return false;
}
static boolean any(LithoBlockRegister register, String path) {
for (var rule : register) {
if (!rule.isEnabled()) continue;
@ -76,7 +71,7 @@ final class BlockRule {
}
public BlockResult check(final String string) {
return new BlockResult(setting, string != null && Extensions.containsAny(string, blocks));
return new BlockResult(setting, string != null && ReVancedUtils.containsAny(string, blocks));
}
}
@ -262,7 +257,7 @@ class GeneralBytecodeAdsPatch extends Filter {
public boolean filter(final String path, final String identifier) {
// Do not block on these
if (Extensions.containsAny(path,
if (ReVancedUtils.containsAny(path,
"home_video_with_context",
"related_video_with_context",
"search_video_with_context",

View File

@ -25,9 +25,15 @@ public class ReturnYouTubeDislikePatch {
/**
* Called when the like/dislike button is clicked
*
* @param vote -1 (dislike), 0 (none) or 1 (like)
*/
public static void sendVote(int vote) {
ReturnYouTubeDislike.sendVote(vote);
for (ReturnYouTubeDislike.Vote v : ReturnYouTubeDislike.Vote.values()) {
if (v.value == vote) {
ReturnYouTubeDislike.sendVote(v);
return;
}
}
}
}

View File

@ -20,6 +20,20 @@ import app.revanced.integrations.utils.SharedPrefHelper;
public class ReturnYouTubeDislike {
private static boolean isEnabled;
private static boolean segmentedButton;
public enum Vote {
LIKE(1),
DISLIKE(-1),
LIKE_REMOVE(0);
public int value;
Vote(int value) {
this.value = value;
}
}
private static Thread _dislikeFetchThread = null;
private static Thread _votingThread = null;
private static Registration registration;
@ -77,31 +91,29 @@ public class ReturnYouTubeDislike {
if (!isEnabled) return;
try {
// Contains a pathBuilder string, used to distinguish from other litho components:
// video_action_bar.eml|27b56b54d5dcba20|video_action_bar_unwrapper.eml|c5a1d399b660e52e|CellType
// |ScrollableContainerType|ContainerType|ContainerType|dislike_button.eml|966ee2cd7db5e29f
// |video_actipathBuilder=video_action_bar.eml|27b56b54d5dcba20|video_action_bar_unwrapper.eml
// |c5a1d399b660e52e|CellType|ScrollableContainerType|ContainerType|ContainerType|dislike_button.eml
// |966ee2cd7db5e29f|video_action_toggle_button.eml|8fd9d44a8e3c9162|video_action_button.eml
// |9dd3b4b44979c3af|ContainerType|TextType|on_toggle_button.eml|8fd9d44a8e3c9162|video_action_button.eml
// |9dd3b4b44979c3af|ContainerType|TextType|
if (!conversionContext.toString().contains("|dislike_button.eml|")) return;
var conversionContextString = conversionContext.toString();
// Check for new component
if (conversionContextString.contains("|segmented_like_dislike_button.eml|"))
segmentedButton = true;
else if (!conversionContextString.contains("|dislike_button.eml|"))
return;
LogHelper.debug(ReturnYouTubeDislike.class, "dislike button was created");
// Have to block the current thread until fetching is done
// There's no known way to edit the text after creation yet
if (_dislikeFetchThread != null) _dislikeFetchThread.join();
if (dislikeCount != null) {
updateDislikeText(textRef, formatDislikes(dislikeCount));
}
if (dislikeCount == null) return;
updateDislike(textRef, dislikeCount);
LogHelper.debug(ReturnYouTubeDislike.class, "Updated text on component" + conversionContextString);
} catch (Exception ex) {
LogHelper.printException(ReturnYouTubeDislike.class, "Error while trying to set dislikes text", ex);
}
}
public static void sendVote(int vote) {
public static void sendVote(Vote vote) {
if (!isEnabled) return;
Context context = ReVancedUtils.getContext();
@ -129,16 +141,23 @@ public class ReturnYouTubeDislike {
_votingThread.start();
}
private static void updateDislikeText(AtomicReference<Object> textRef, String text) {
SpannableString oldString = (SpannableString) textRef.get();
SpannableString newString = new SpannableString(text);
private static void updateDislike(AtomicReference<Object> textRef, Integer dislikeCount) {
SpannableString oldSpannableString = (SpannableString) textRef.get();
// parse the buttons string
// if the button is segmented, only get the like count as a string
var oldButtonString = oldSpannableString.toString();
if (segmentedButton) oldButtonString = oldButtonString.split(" \\| ")[0];
var dislikeString = formatDislikes(dislikeCount);
SpannableString newString = new SpannableString(
segmentedButton ? (oldButtonString + " | " + dislikeString) : dislikeString
);
// Copy style (foreground color, etc) to new string
Object[] spans = oldString.getSpans(0, oldString.length(), Object.class);
for (Object span : spans) {
int flags = oldString.getSpanFlags(span);
newString.setSpan(span, 0, newString.length(), flags);
}
Object[] spans = oldSpannableString.getSpans(0, oldSpannableString.length(), Object.class);
for (Object span : spans)
newString.setSpan(span, 0, newString.length(), oldSpannableString.getSpanFlags(span));
textRef.set(newString);
}

View File

@ -10,9 +10,9 @@ public class Voting {
this.registration = registration;
}
public boolean sendVote(String videoId, int vote) {
public boolean sendVote(String videoId, ReturnYouTubeDislike.Vote vote) {
String userId = registration.getUserId();
LogHelper.debug(Voting.class, "Trying to vote the following video: " + videoId + " with vote " + vote + " and userId: " + userId);
return ReturnYouTubeDislikeApi.sendVote(videoId, userId, vote);
return ReturnYouTubeDislikeApi.sendVote(videoId, userId, vote.value);
}
}

View File

@ -12,14 +12,19 @@ public class ReVancedUtils {
private static PlayerType env;
public static boolean newVideo = false;
//Used by Integrations patch
public static Context context;
//Used by Integrations patch
public static boolean containsAny(final String value, final String... targets) {
for (String string : targets)
if (value.contains(string)) return true;
return false;
}
public static void setNewVideo(boolean started) {
LogHelper.debug(ReVancedUtils.class, "New video started: " + started);
newVideo = started;
}
public static boolean isNewVideoStarted() {
return newVideo;
}