Skip to content

Commit

Permalink
feat: return-youtube-dislikes patch (#81)
Browse files Browse the repository at this point in the history
* feat: update dislike button text

* refactor(ryd): remove unused code

* refactor: create patch class for ryd

* refactor: move VideoInformation
  • Loading branch information
j4k0xb committed Jul 16, 2022
1 parent 508f496 commit 2d513b5
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 188 deletions.
@@ -0,0 +1,33 @@
package app.revanced.integrations.patches;

import java.util.concurrent.atomic.AtomicReference;

import app.revanced.integrations.ryd.ReturnYouTubeDislikes;

/**
* Used by app.revanced.patches.youtube.layout.returnyoutubedislikes.patch.RYDPatch
*/
public class ReturnYouTubeDislikesPatch {

/**
* Called when the video id changes
*/
public static void newVideoLoaded(String videoId) {
ReturnYouTubeDislikes.newVideoLoaded(videoId);
}

/**
* Called when a litho text component is created
*/
public static void onComponentCreated(Object conversionContext, AtomicReference<Object> textRef) {
ReturnYouTubeDislikes.onComponentCreated(conversionContext, textRef);
}

/**
* Called when the like/dislike button is clicked
* @param vote -1 (dislike), 0 (none) or 1 (like)
*/
public static void sendVote(int vote) {
ReturnYouTubeDislikes.sendVote(vote);
}
}
@@ -1,35 +1,29 @@
package app.revanced.integrations.ryd;

import static app.revanced.integrations.sponsorblock.player.VideoInformation.currentVideoId;
import static app.revanced.integrations.sponsorblock.player.VideoInformation.dislikeCount;
import static app.revanced.integrations.utils.ReVancedUtils.getIdentifier;
import static app.revanced.integrations.videoplayer.VideoInformation.currentVideoId;
import static app.revanced.integrations.videoplayer.VideoInformation.dislikeCount;

import android.content.Context;
import android.icu.text.CompactDecimalFormat;
import android.os.Build;

import android.view.View;
import android.widget.TextView;
import android.text.SpannableString;

import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

import app.revanced.integrations.ryd.requests.RYDRequester;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.ryd.requests.RYDRequester;
import app.revanced.integrations.utils.ReVancedUtils;
import app.revanced.integrations.utils.SharedPrefHelper;

public class ReturnYouTubeDislikes {
public static boolean isEnabled;
private static View _dislikeView = null;
private static boolean isEnabled;
private static Thread _dislikeFetchThread = null;
private static Thread _votingThread = null;
private static Registration registration;
private static Voting voting;
private static boolean likeActive;
private static boolean dislikeActive;
private static int votingValue = 0; // 1 = like, -1 = dislike, 0 = no vote
private static CompactDecimalFormat compactNumberFormatter;

static {
Expand Down Expand Up @@ -60,7 +54,6 @@ public static void onEnabledChange(boolean enabled) {
}
}

//Was called in SB->player->VideoInformation->setCurrentVideoId(final String videoId) before, has to be called on its own at the same place now.
public static void newVideoLoaded(String videoId) {
LogHelper.debug(ReturnYouTubeDislikes.class, "newVideoLoaded - " + videoId);

Expand All @@ -80,162 +73,34 @@ public static void newVideoLoaded(String videoId) {
_dislikeFetchThread.start();
}

// Call to this needs to be injected in YT code
public static void setLikeTag(View view) {
if (!isEnabled) return;

setTag(view, "like");
}

public static void setLikeTag(View view, boolean active) {
public static void onComponentCreated(Object conversionContext, AtomicReference<Object> textRef) {
if (!isEnabled) return;

likeActive = active;
if (likeActive) {
votingValue = 1;
}

LogHelper.debug(ReturnYouTubeDislikes.class, "Like tag active " + likeActive);
setTag(view, "like");
}

// Call to this needs to be injected in YT code
public static void setDislikeTag(View view) {
if (!isEnabled) return;

_dislikeView = view;
setTag(view, "dislike");
}

public static void setDislikeTag(View view, boolean active) {
if (!isEnabled) return;

dislikeActive = active;
if (dislikeActive) {
votingValue = -1;
}
_dislikeView = view;
LogHelper.debug(ReturnYouTubeDislikes.class, "Dislike tag active " + dislikeActive);
setTag(view, "dislike");
}

// Call to this needs to be injected in YT code
public static CharSequence onSetText(View view, CharSequence originalText) {
if (!isEnabled) return originalText;
return handleOnSetText(view, originalText);
}

// Call to this needs to be injected in YT code
public static void onClick(View view, boolean inactive) {
if (!isEnabled) return;

handleOnClick(view, inactive);
}

private static CharSequence handleOnSetText(View view, CharSequence originalText) {
if (!isEnabled) return originalText;

try {
CharSequence tag = (CharSequence) view.getTag();
LogHelper.debug(ReturnYouTubeDislikes.class, "handleOnSetText - " + tag + " - original text - " + originalText);
if (tag == null) return originalText;
// Contains a pathBuilder string, used to distinguish from other litho components
if (!conversionContext.toString().contains("dislike_button")) return;

if (tag == "like") {
return originalText;
} else if (tag == "dislike") {
return dislikeCount != null ? formatDislikes(dislikeCount) : originalText;
}
} catch (Exception ex) {
LogHelper.printException(ReturnYouTubeDislikes.class, "Error while handling the setText", ex);
}

return originalText;
}
LogHelper.debug(ReturnYouTubeDislikes.class, "dislike button was created");

public static void trySetDislikes(String dislikeCount) {
if (!isEnabled) return;

try {
// Try to set normal video dislike count
if (_dislikeView == null) {
LogHelper.debug(ReturnYouTubeDislikes.class, "_dislikeView was null");
return;
}
// 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();

View buttonView = _dislikeView.findViewById(getIdentifier("button_text", "id"));
if (buttonView == null) {
LogHelper.debug(ReturnYouTubeDislikes.class, "buttonView was null");
return;
if (dislikeCount != null) {
updateDislikeText(textRef, formatDislikes(dislikeCount));
}
TextView button = (TextView) buttonView;
button.setText(dislikeCount);
LogHelper.debug(ReturnYouTubeDislikes.class, "trySetDislikes - " + dislikeCount);
} catch (Exception ex) {
LogHelper.printException(ReturnYouTubeDislikes.class, "Error while trying to set dislikes text", ex);
}
}

private static void handleOnClick(View view, boolean previousState) {
public static void sendVote(int vote) {
if (!isEnabled) return;

Context context = ReVancedUtils.getContext();
if (!isEnabled || SharedPrefHelper.getBoolean(Objects.requireNonNull(context), SharedPrefHelper.SharedPrefNames.YOUTUBE, "user_signed_out", true))
if (SharedPrefHelper.getBoolean(Objects.requireNonNull(context), SharedPrefHelper.SharedPrefNames.YOUTUBE, "user_signed_out", true))
return;

try {
String tag = (String) view.getTag();
LogHelper.debug(ReturnYouTubeDislikes.class, "handleOnClick - " + tag + " - previousState - " + previousState);
if (tag == null) return;

// If active status was removed, vote should be none
if (previousState) {
votingValue = 0;
}
if (tag.equals("like")) {

// Like was activated
if (!previousState) {
votingValue = 1;
likeActive = true;
} else {
likeActive = false;
}

// Like was activated and dislike was previously activated
if (!previousState && dislikeActive) {
dislikeCount--;
trySetDislikes(formatDislikes(dislikeCount));
}
dislikeActive = false;
} else if (tag.equals("dislike")) {
likeActive = false;

// Dislike was activated
if (!previousState) {
votingValue = -1;
dislikeActive = true;
dislikeCount++;
}
// Dislike was removed
else {
dislikeActive = false;
dislikeCount--;
}
trySetDislikes(formatDislikes(dislikeCount));
} else {
// Unknown tag
return;
}

LogHelper.debug(ReturnYouTubeDislikes.class, "New vote status - " + votingValue);
LogHelper.debug(ReturnYouTubeDislikes.class, "Like button " + likeActive + " | Dislike button " + dislikeActive);
sendVote(votingValue);
} catch (Exception ex) {
LogHelper.printException(ReturnYouTubeDislikes.class, "Error while handling the onClick", ex);
}
}

private static void sendVote(int vote) {
if (!isEnabled) return;

LogHelper.debug(ReturnYouTubeDislikes.class, "sending vote - " + vote + " for video " + currentVideoId);
try {
if (_votingThread != null && _votingThread.getState() != Thread.State.TERMINATED) {
Expand All @@ -257,22 +122,21 @@ private static void sendVote(int vote) {
_votingThread.start();
}

private static void setTag(View view, String tag) {
if (!isEnabled) return;
private static void updateDislikeText(AtomicReference<Object> textRef, String text) {
SpannableString oldString = (SpannableString) textRef.get();
SpannableString newString = new SpannableString(text);

try {
if (view == null) {
LogHelper.debug(ReturnYouTubeDislikes.class, "View was empty");
return;
}
LogHelper.debug(ReturnYouTubeDislikes.class, "setTag - " + tag);
view.setTag(tag);
} catch (Exception ex) {
LogHelper.printException(ReturnYouTubeDislikes.class, "Error while trying to set tag to view", ex);
// 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);
}

textRef.set(newString);
}

public static String formatDislikes(int dislikes) {
private static String formatDislikes(int dislikes) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && compactNumberFormatter != null) {
final String formatted = compactNumberFormatter.format(dislikes);
LogHelper.debug(ReturnYouTubeDislikes.class, "Formatting dislikes - " + dislikes + " - " + formatted);
Expand Down
@@ -1,11 +1,8 @@
package app.revanced.integrations.ryd.requests;

import static app.revanced.integrations.sponsorblock.player.VideoInformation.dislikeCount;
import static app.revanced.integrations.videoplayer.VideoInformation.dislikeCount;
import static app.revanced.integrations.whitelist.requests.Requester.parseJson;

import android.os.Handler;
import android.os.Looper;


import org.json.JSONObject;

Expand All @@ -16,7 +13,6 @@

import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.ryd.Registration;
import app.revanced.integrations.ryd.ReturnYouTubeDislikes;
import app.revanced.integrations.whitelist.requests.Requester;
import app.revanced.integrations.whitelist.requests.Route;

Expand All @@ -33,13 +29,8 @@ public static void fetchDislikes(String videoId) {
connection.setConnectTimeout(5 * 1000);
if (connection.getResponseCode() == 200) {
JSONObject json = getJSONObject(connection);
int dislikes = json.getInt("dislikes");
dislikeCount = dislikes;
dislikeCount = json.getInt("dislikes");
LogHelper.debug(RYDRequester.class, "dislikes fetched - " + dislikeCount);


// Set the dislikes
new Handler(Looper.getMainLooper()).post(() -> ReturnYouTubeDislikes.trySetDislikes(ReturnYouTubeDislikes.formatDislikes(dislikes)));
} else {
LogHelper.debug(RYDRequester.class, "dislikes fetch response was " + connection.getResponseCode());
}
Expand Down
Expand Up @@ -23,7 +23,7 @@

import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.sponsorblock.player.VideoInformation;
import app.revanced.integrations.videoplayer.VideoInformation;
import app.revanced.integrations.whitelist.Whitelist;
import app.revanced.integrations.sponsorblock.objects.SponsorSegment;
import app.revanced.integrations.sponsorblock.requests.SBRequester;
Expand Down
Expand Up @@ -7,6 +7,7 @@

import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils;
import app.revanced.integrations.videoplayer.VideoInformation;

public class VideoHelpers {

Expand Down
@@ -1,6 +1,6 @@
package app.revanced.integrations.sponsorblock.player.ui;

import static app.revanced.integrations.sponsorblock.player.VideoInformation.currentVideoId;
import static app.revanced.integrations.videoplayer.VideoInformation.currentVideoId;
import static app.revanced.integrations.sponsorblock.StringRef.str;

import android.content.Context;
Expand All @@ -10,7 +10,7 @@
import android.widget.ImageView;

import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.sponsorblock.player.VideoInformation;
import app.revanced.integrations.videoplayer.VideoInformation;
import app.revanced.integrations.whitelist.Whitelist;
import app.revanced.integrations.whitelist.WhitelistType;
import app.revanced.integrations.whitelist.requests.WhitelistRequester;
Expand Down
Expand Up @@ -9,9 +9,8 @@
import android.view.ViewGroup;

import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.sponsorblock.player.VideoInformation;
import app.revanced.integrations.videoplayer.VideoInformation;
import app.revanced.integrations.utils.ReVancedUtils;
import app.revanced.integrations.sponsorblock.SponsorBlockSettings;
import app.revanced.integrations.sponsorblock.SponsorBlockUtils;

public class SBBrowserButton extends SlimButton {
Expand Down
@@ -1,6 +1,6 @@
package app.revanced.integrations.sponsorblock.player.ui;

import static app.revanced.integrations.sponsorblock.player.VideoInformation.currentVideoId;
import static app.revanced.integrations.videoplayer.VideoInformation.currentVideoId;
import static app.revanced.integrations.sponsorblock.StringRef.str;

import android.content.Context;
Expand All @@ -10,7 +10,7 @@
import android.widget.ImageView;

import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.sponsorblock.player.VideoInformation;
import app.revanced.integrations.videoplayer.VideoInformation;
import app.revanced.integrations.whitelist.Whitelist;
import app.revanced.integrations.whitelist.WhitelistType;
import app.revanced.integrations.whitelist.requests.WhitelistRequester;
Expand Down
@@ -1,4 +1,4 @@
package app.revanced.integrations.sponsorblock.player;
package app.revanced.integrations.videoplayer;

import app.revanced.integrations.utils.LogHelper;

Expand Down

0 comments on commit 2d513b5

Please sign in to comment.