mirror of
https://github.com/revanced/revanced-integrations.git
synced 2024-12-28 13:45:51 +01:00
feat(youtube/return-youtube-dislike): compatibility for old and new button layout
This commit is contained in:
parent
3698a502c3
commit
a92c932a20
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user