From ea92a2e36c7aab3bd115f7d0ec40467179485b32 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Wed, 9 Apr 2025 20:32:27 +0200 Subject: [PATCH] fix(YouTube - Return YouTube Dislike): Fix inconsistent label after disliking a Short --- .../patches/ReturnYouTubeDislikePatch.java | 77 ++++++++++--------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch.java index 78f724e7b..c5ba1c033 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch.java @@ -8,11 +8,11 @@ import android.text.Spanned; import android.view.View; import android.widget.TextView; +import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.Objects; -import java.util.concurrent.atomic.AtomicInteger; import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Utils; @@ -56,12 +56,12 @@ public class ReturnYouTubeDislikePatch { private static volatile ReturnYouTubeDislike lastLithoShortsVideoData; /** - * Because the litho Shorts spans are created after {@link ReturnYouTubeDislikeFilterPatch} - * detects the video ids, after the user votes the litho will update - * but {@link #lastLithoShortsVideoData} is not the correct data to use. - * If this is non zero, then instead decrement this value and use {@link #currentVideoData}. + * Because litho Shorts spans are created offscreen after {@link ReturnYouTubeDislikeFilterPatch} + * detects the video ids, but the current Short can arbitrarily reload the same span, + * then use the {@link #lastLithoShortsVideoData} if this value is greater than zero. */ - private static final AtomicInteger lithoShortsUseCurrentVideoData = new AtomicInteger(); + @GuardedBy("ReturnYouTubeDislikePatch.class") + private static int useLithoShortsVideoDataCount; /** * Last video id prefetched. Field is to prevent prefetching the same video id multiple times in a row. @@ -79,12 +79,28 @@ public class ReturnYouTubeDislikePatch { private static void clearData() { currentVideoData = null; lastLithoShortsVideoData = null; - lithoShortsUseCurrentVideoData.set(0); + synchronized (ReturnYouTubeDislike.class) { + useLithoShortsVideoDataCount = 0; + } + // Rolling number text should not be cleared, // as it's used if incognito Short is opened/closed // while a regular video is on screen. } + /** + * @return If {@link #useLithoShortsVideoDataCount} was greater than zero. + */ + private static boolean decrementUseLithoDataIfNeeded() { + synchronized (ReturnYouTubeDislikePatch.class) { + if (useLithoShortsVideoDataCount > 0) { + useLithoShortsVideoDataCount--; + return true; + } + + return false; + } + } // // Litho player for both regular videos and Shorts. @@ -148,10 +164,13 @@ public class ReturnYouTubeDislikePatch { return getShortsSpan(original, true); } - if (conversionContextString.contains("|shorts_like_button.eml") - && !Utils.containsNumber(original)) { - Logger.printDebug(() -> "Replacing hidden likes count"); - return getShortsSpan(original, false); + if (conversionContextString.contains("|shorts_like_button.eml")) { + if (!Utils.containsNumber(original)) { + Logger.printDebug(() -> "Replacing hidden likes count"); + return getShortsSpan(original, false); + } else { + decrementUseLithoDataIfNeeded(); + } } } catch (Exception ex) { Logger.printException(() -> "onLithoTextLoaded failure", ex); @@ -166,7 +185,14 @@ public class ReturnYouTubeDislikePatch { return original; } - ReturnYouTubeDislike videoData = lastLithoShortsVideoData; + final ReturnYouTubeDislike videoData; + if (decrementUseLithoDataIfNeeded()) { + // New Short is loading off screen. + videoData = lastLithoShortsVideoData; + } else { + videoData = currentVideoData; + } + if (videoData == null) { // The Shorts litho video id filter did not detect the video id. // This is normal in incognito mode, but otherwise is abnormal. @@ -174,19 +200,6 @@ public class ReturnYouTubeDislikePatch { return original; } - // Use the correct dislikes data after voting. - // Must check if positive and cannot check for zero, - // because multiple get and add calls could be interleaved together. - if (lithoShortsUseCurrentVideoData.get() > 0) { - lithoShortsUseCurrentVideoData.getAndAdd(-1); - videoData = currentVideoData; - if (videoData == null) { - Logger.printException(() -> "currentVideoData is null"); // Should never happen - return original; - } - Logger.printDebug(() -> "Using current video data for litho span"); - } - return isDislikesSpan ? videoData.getDislikeSpanForShort((Spanned) original) : videoData.getLikeSpanForShort((Spanned) original); @@ -441,7 +454,10 @@ public class ReturnYouTubeDislikePatch { ReturnYouTubeDislike videoData = ReturnYouTubeDislike.getFetchForVideoId(videoId); videoData.setVideoIdIsShort(true); lastLithoShortsVideoData = videoData; - lithoShortsUseCurrentVideoData.set(0); + synchronized (ReturnYouTubeDislikePatch.class) { + // Use litho Shorts data for the next like and dislike spans. + useLithoShortsVideoDataCount = 2; + } } private static boolean videoIdIsSame(@Nullable ReturnYouTubeDislike fetch, @Nullable String videoId) { @@ -476,15 +492,6 @@ public class ReturnYouTubeDislikePatch { for (Vote v : Vote.values()) { if (v.value == vote) { videoData.sendVote(v); - - if (isNoneHiddenOrMinimized) { - if (lastLithoShortsVideoData != null) { - // Like and dislikes can be loaded out of order, - // so allow the next 2 litho text replacements to use the current video. - lithoShortsUseCurrentVideoData.set(2); - } - } - return; } }