Skip to content
This repository has been archived by the owner on Oct 26, 2024. It is now read-only.

Commit

Permalink
fix(YouTube - ReturnYouTubeDislike): Do not show more than 1 connecti…
Browse files Browse the repository at this point in the history
…on toasts if the API is broken
  • Loading branch information
LisoUseInAIKyrios committed Jan 29, 2024
1 parent f1e0365 commit bc6241a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import app.revanced.integrations.youtube.patches.components.ReturnYouTubeDislikeFilterPatch;
import app.revanced.integrations.youtube.patches.spoof.SpoofAppVersionPatch;
import app.revanced.integrations.youtube.returnyoutubedislike.ReturnYouTubeDislike;
import app.revanced.integrations.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
import app.revanced.integrations.youtube.settings.Settings;
import app.revanced.integrations.youtube.shared.PlayerType;
import app.revanced.integrations.shared.Logger;
Expand All @@ -21,7 +22,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

import static app.revanced.integrations.youtube.returnyoutubedislike.ReturnYouTubeDislike.Vote;

Expand Down Expand Up @@ -70,17 +70,16 @@ public class ReturnYouTubeDislikePatch {
private static volatile boolean lithoShortsShouldUseCurrentData;

/**
* Last video id prefetched. Field is prevent prefetching the same video id multiple times in a row.
* Last video id prefetched. Field is to prevent prefetching the same video id multiple times in a row.
*/
@Nullable
private static volatile String lastPrefetchedVideoId;

public static void onRYDStatusChange(boolean rydEnabled) {
if (!rydEnabled) {
// Must remove all values to protect against using stale data
// if the user enables RYD while a video is on screen.
clearData();
}
ReturnYouTubeDislikeApi.resetRateLimits();
// Must remove all values to protect against using stale data
// if the user enables RYD while a video is on screen.
clearData();
}

private static void clearData() {
Expand Down Expand Up @@ -240,10 +239,6 @@ private static CharSequence onLithoTextLoaded(@NonNull Object conversionContext,
}
replacement = videoData.getDislikesSpanForRegularVideo((Spanned) original,
true, isRollingNumber);

// When spoofing between 17.09.xx and 17.30.xx the UI is the old layout
// but uses litho and the dislikes is "|dislike_button.eml|".
// But spoofing to that range gives a broken UI layout so no point checking for that.
} else if (!isRollingNumber && conversionContextString.contains("|shorts_dislike_button.eml|")) {
// Litho Shorts player.
if (!Settings.RYD_SHORTS.get()) {
Expand Down Expand Up @@ -300,9 +295,10 @@ public static String onRollingNumberLoaded(@NonNull Object conversionContext,
@NonNull String original) {
try {
CharSequence replacement = onLithoTextLoaded(conversionContext, original, true);
if (!replacement.toString().equals(original)) {
String replacementString = replacement.toString();
if (!replacementString.equals(original)) {
rollingNumberSpan = replacement;
return replacement.toString();
return replacementString;
} // Else, the text was not a likes count but instead the view count or something else.
} catch (Exception ex) {
Logger.printException(() -> "onRollingNumberLoaded failure", ex);
Expand Down Expand Up @@ -348,9 +344,8 @@ private static void addRollingNumberPatchChanges(TextView view) {
} else {
view.setCompoundDrawables(separator, null, null, null);
}
// Liking/disliking can cause the span to grow in size,
// which is ok and is laid out correctly,
// but if the user then undoes their action the layout will not remove the extra padding.
// Disliking can cause the span to grow in size, which is ok and is laid out correctly,
// but if the user then removes their dislike the layout will not adjust to the new shorter width.
// Use a center alignment to take up any extra space.
view.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
// Single line mode does not clip words if the span is larger than the view bounds.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public enum Vote {
private final Future<RYDVoteData> future;

/**
* Time this instance and the future was created.
* Time this instance and the fetch future was created.
*/
private final long timeFetched;

Expand Down Expand Up @@ -185,12 +185,12 @@ public enum Vote {

/**
* Color of the left and middle separator, based on the color of the right separator.
* It's unknown where YT gets the color from, and the colors here are approximated by hand.
* Ideally, the color here would be the actual color YT uses at runtime.
* It's unknown where YT gets the color from, and the values here are approximated by hand.
* Ideally, this would be the actual color YT uses at runtime.
*
* Older versions before the 'Me' library tab use a slightly different color.
* If spoofing was previously used and is now turned off,
* or an old version was recently upgraded then the old colors are sometimes used.
* or an old version was recently upgraded then the old colors are sometimes still used.
*/
private static int getSeparatorColor() {
if (IS_SPOOFING_TO_OLD_SEPARATOR_COLOR) {
Expand Down Expand Up @@ -411,7 +411,7 @@ public static ReturnYouTubeDislike getFetchForVideoId(@Nullable String videoId)
}

/**
* Should be called if the user changes settings for dislikes appearance.
* Should be called if the user changes dislikes appearance settings.
*/
public static void clearAllUICaches() {
synchronized (fetchCache) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public class ReturnYouTubeDislikeApi {
* How long to wait until API calls are resumed, if the API requested a back off.
* No clear guideline of how long to wait until resuming.
*/
private static final int BACKOFF_RATE_LIMIT_MILLISECONDS = 5 * 60 * 1000; // 5 Minutes.
private static final int BACKOFF_RATE_LIMIT_MILLISECONDS = 10 * 60 * 1000; // 10 Minutes.

/**
* How long to wait until API calls are resumed, if any connection error occurs.
Expand All @@ -72,7 +72,13 @@ public class ReturnYouTubeDislikeApi {
/**
* If non zero, then the system time of when API calls can resume.
*/
private static volatile long timeToResumeAPICalls; // must be volatile, since different threads read/write to this
private static volatile long timeToResumeAPICalls;

/**
* If the last API getVotes call failed for any reason (including server requested rate limit).
* Used to prevent showing repeat connection toasts when the API is down.
*/
private static volatile boolean lastApiCallFailed;

/**
* Number of times {@link #HTTP_STATUS_CODE_RATE_LIMIT} was requested by RYD api.
Expand Down Expand Up @@ -148,6 +154,18 @@ private static void randomlyWaitIfLocallyDebugging() {
}
}

/**
* Clears any backoff rate limits in effect.
* Should be called if RYD is turned on/off.
*/
public static void resetRateLimits() {
if (lastApiCallFailed || timeToResumeAPICalls != 0) {
Logger.printDebug(() -> "Reset rate limit");
}
lastApiCallFailed = false;
timeToResumeAPICalls = 0;
}

/**
* @return True, if api rate limit is in effect.
*/
Expand Down Expand Up @@ -193,25 +211,30 @@ private static void updateRateLimitAndStats(long timeNetworkCallStarted, boolean
timeToResumeAPICalls = System.currentTimeMillis() + BACKOFF_CONNECTION_ERROR_MILLISECONDS;
fetchCallResponseTimeLast = responseTimeOfFetchCall;
fetchCallNumberOfFailures++;
lastApiCallFailed = true;
} else if (rateLimitHit) {
Logger.printDebug(() -> "API rate limit was hit. Stopping API calls for the next "
+ BACKOFF_RATE_LIMIT_MILLISECONDS + " seconds");
timeToResumeAPICalls = System.currentTimeMillis() + BACKOFF_RATE_LIMIT_MILLISECONDS;
numberOfRateLimitRequestsEncountered++;
fetchCallResponseTimeLast = FETCH_CALL_RESPONSE_TIME_VALUE_RATE_LIMIT;
Utils.showToastLong(str("revanced_ryd_failure_client_rate_limit_requested"));
if (!lastApiCallFailed && Settings.RYD_TOAST_ON_CONNECTION_ERROR.get()) {
Utils.showToastLong(str("revanced_ryd_failure_client_rate_limit_requested"));
}
lastApiCallFailed = true;
} else {
fetchCallResponseTimeLast = responseTimeOfFetchCall;
lastApiCallFailed = false;
}
}

private static void handleConnectionError(@NonNull String toastMessage, @Nullable Exception ex) {
if (Settings.RYD_TOAST_ON_CONNECTION_ERROR.get()) {
if (!lastApiCallFailed && Settings.RYD_TOAST_ON_CONNECTION_ERROR.get()) {
Utils.showToastShort(toastMessage);
}
if (ex != null) {
Logger.printInfo(() -> toastMessage, ex);
}
lastApiCallFailed = true;

Logger.printInfo(() -> toastMessage, ex);
}

/**
Expand Down

0 comments on commit bc6241a

Please sign in to comment.