From 5dadb0d523f2b1eb4216d43770af37a156c8a477 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 28 Sep 2023 01:28:34 +0200 Subject: [PATCH] feat(YouTube): Bump compatibility to `18.37.36` (#483) Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> --- .../patches/ReturnYouTubeDislikePatch.java | 38 ++++---- .../patches/components/LithoFilterPatch.java | 6 +- .../patches/components/ShortsFilter.java | 86 ++++++++++++++----- .../requests/StoryboardRendererRequester.java | 4 +- .../ReturnYouTubeDislike.java | 2 +- 5 files changed, 88 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/patches/ReturnYouTubeDislikePatch.java b/app/src/main/java/app/revanced/integrations/patches/ReturnYouTubeDislikePatch.java index 48a7e81a..383d3185 100644 --- a/app/src/main/java/app/revanced/integrations/patches/ReturnYouTubeDislikePatch.java +++ b/app/src/main/java/app/revanced/integrations/patches/ReturnYouTubeDislikePatch.java @@ -1,25 +1,12 @@ package app.revanced.integrations.patches; -import static app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike.Vote; - import android.graphics.Rect; import android.os.Build; -import android.text.Editable; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.Spanned; -import android.text.TextWatcher; +import android.text.*; import android.view.View; import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; - import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike; import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi; import app.revanced.integrations.settings.SettingsEnum; @@ -27,6 +14,13 @@ import app.revanced.integrations.shared.PlayerType; import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.ReVancedUtils; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +import static app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike.Vote; + /** * Handles all interaction of UI patch components. * @@ -149,23 +143,27 @@ public class ReturnYouTubeDislikePatch { @NonNull AtomicReference textRef, @NonNull CharSequence original) { try { - if (!SettingsEnum.RYD_ENABLED.getBoolean() || PlayerType.getCurrent().isNoneOrHidden()) { + if (!SettingsEnum.RYD_ENABLED.getBoolean()) { return original; } String conversionContextString = conversionContext.toString(); LogHelper.printDebug(() -> "conversionContext: " + conversionContextString); - final boolean isSegmentedButton; + final Spanned replacement; if (conversionContextString.contains("|segmented_like_dislike_button.eml|")) { - isSegmentedButton = true; - } else if (conversionContextString.contains("|dislike_button.eml|")) { - isSegmentedButton = false; + replacement = ReturnYouTubeDislike.getDislikesSpanForRegularVideo((Spannable) original, true); + } else if (conversionContextString.contains("|dislike_button.eml|") ) { + // This code path is basically dead because it's only used when spoofing between 17.09.xx and 17.30.xx + // but spoofing to that range gives a broken UI layout. + // Keep this check here anyways just in case the old litho layout is somehow still used. + replacement = ReturnYouTubeDislike.getDislikesSpanForRegularVideo((Spannable) original, false); + } else if (conversionContextString.contains("|shorts_dislike_button.eml|")) { + replacement = ReturnYouTubeDislike.getDislikeSpanForShort((Spannable) original); } else { return original; } - Spanned replacement = ReturnYouTubeDislike.getDislikesSpanForRegularVideo((Spannable) original, isSegmentedButton); textRef.set(replacement); return replacement; } catch (Exception ex) { diff --git a/app/src/main/java/app/revanced/integrations/patches/components/LithoFilterPatch.java b/app/src/main/java/app/revanced/integrations/patches/components/LithoFilterPatch.java index 44cbbeaf..7cfe060b 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/LithoFilterPatch.java +++ b/app/src/main/java/app/revanced/integrations/patches/components/LithoFilterPatch.java @@ -292,10 +292,10 @@ abstract class Filter { boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray, FilterGroupList matchedList, FilterGroup matchedGroup, int matchedIndex) { if (SettingsEnum.DEBUG.getBoolean()) { - if (pathFilterGroupList == matchedList) { - LogHelper.printDebug(() -> getClass().getSimpleName() + " Filtered path: " + path); - } else if (identifierFilterGroupList == matchedList) { + if (matchedList == identifierFilterGroupList) { LogHelper.printDebug(() -> getClass().getSimpleName() + " Filtered identifier: " + identifier); + } else { + LogHelper.printDebug(() -> getClass().getSimpleName() + " Filtered path: " + path); } } return true; diff --git a/app/src/main/java/app/revanced/integrations/patches/components/ShortsFilter.java b/app/src/main/java/app/revanced/integrations/patches/components/ShortsFilter.java index b6e1f3fa..e253d917 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/ShortsFilter.java +++ b/app/src/main/java/app/revanced/integrations/patches/components/ShortsFilter.java @@ -1,31 +1,29 @@ package app.revanced.integrations.patches.components; +import android.os.Build; +import android.view.View; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import app.revanced.integrations.settings.SettingsEnum; +import com.google.android.libraries.youtube.rendering.ui.pivotbar.PivotBar; + import static app.revanced.integrations.utils.ReVancedUtils.hideViewBy1dpUnderCondition; import static app.revanced.integrations.utils.ReVancedUtils.hideViewUnderCondition; -import android.view.View; - -import androidx.annotation.Nullable; - -import com.google.android.libraries.youtube.rendering.ui.pivotbar.PivotBar; - -import app.revanced.integrations.settings.SettingsEnum; - +@RequiresApi(api = Build.VERSION_CODES.N) public final class ShortsFilter extends Filter { - private static final String REEL_CHANNEL_BAR_PATH = "reel_channel_bar.eml"; public static PivotBar pivotBar; // Set by patch. + private final String REEL_CHANNEL_BAR_PATH = "reel_channel_bar.eml"; private final StringFilterGroup channelBar; private final StringFilterGroup soundButton; private final StringFilterGroup infoPanel; - private final StringFilterGroup shortsShelfHeader; + private final StringFilterGroup shelfHeader; + + private final StringFilterGroup videoActionButton; + private final ByteArrayFilterGroupList videoActionButtonGroupList = new ByteArrayFilterGroupList(); public ShortsFilter() { - // Home / subscription feed components. - var thanksButton = new StringFilterGroup( - SettingsEnum.HIDE_SHORTS_THANKS_BUTTON, - "suggested_action" - ); var shorts = new StringFilterGroup( SettingsEnum.HIDE_SHORTS, "shorts_shelf", @@ -33,14 +31,22 @@ public final class ShortsFilter extends Filter { "shorts_grid", "shorts_video_cell", "shorts_pivot_item" + ); + // Feed Shorts shelf header. // Use a different filter group for this pattern, as it requires an additional check after matching. - shortsShelfHeader = new StringFilterGroup( + shelfHeader = new StringFilterGroup( SettingsEnum.HIDE_SHORTS, "shelf_header.eml" ); - identifierFilterGroupList.addAll(shorts, shortsShelfHeader, thanksButton); + // Home / subscription feed components. + var thanksButton = new StringFilterGroup( + SettingsEnum.HIDE_SHORTS_THANKS_BUTTON, + "suggested_action" + ); + + identifierFilterGroupList.addAll(shorts, shelfHeader, thanksButton); // Shorts player components. var joinButton = new StringFilterGroup( @@ -51,6 +57,7 @@ public final class ShortsFilter extends Filter { SettingsEnum.HIDE_SHORTS_SUBSCRIBE_BUTTON, "subscribe_button" ); + channelBar = new StringFilterGroup( SettingsEnum.HIDE_SHORTS_CHANNEL_BAR, REEL_CHANNEL_BAR_PATH @@ -59,11 +66,37 @@ public final class ShortsFilter extends Filter { SettingsEnum.HIDE_SHORTS_SOUND_BUTTON, "reel_pivot_button" ); + infoPanel = new StringFilterGroup( SettingsEnum.HIDE_SHORTS_INFO_PANEL, "shorts_info_panel_overview" ); - pathFilterGroupList.addAll(joinButton, subscribeButton, channelBar, soundButton, infoPanel); + + videoActionButton = new StringFilterGroup( + null, + "ContainerType|shorts_video_action_button" + ); + + pathFilterGroupList.addAll( + joinButton, subscribeButton, channelBar, soundButton, infoPanel, videoActionButton + ); + + var shortsCommentButton = new ByteArrayAsStringFilterGroup( + SettingsEnum.HIDE_SHORTS_COMMENTS_BUTTON, + "reel_comment_button" + ); + + var shortsShareButton = new ByteArrayAsStringFilterGroup( + SettingsEnum.HIDE_SHORTS_SHARE_BUTTON, + "reel_share_button" + ); + + var shortsRemixButton = new ByteArrayAsStringFilterGroup( + SettingsEnum.HIDE_SHORTS_REMIX_BUTTON, + "reel_remix_button" + ); + + videoActionButtonGroupList.addAll(shortsCommentButton, shortsShareButton, shortsRemixButton); } @Override @@ -72,27 +105,34 @@ public final class ShortsFilter extends Filter { if (matchedList == pathFilterGroupList) { // Always filter if matched. if (matchedGroup == soundButton || matchedGroup == infoPanel || matchedGroup == channelBar) - return super.isFiltered(path, identifier, protobufBufferArray, matchedList, matchedGroup, matchedIndex); + return super.isFiltered(identifier, path, protobufBufferArray, matchedList, matchedGroup, matchedIndex); + + // Video action buttons (comment, share, remix) have the same path. + if (matchedGroup == videoActionButton) { + if (videoActionButtonGroupList.check(protobufBufferArray).isFiltered()) + return super.isFiltered(identifier, path, protobufBufferArray, matchedList, matchedGroup, matchedIndex); + return false; + } // Filter other path groups from pathFilterGroupList, only when reelChannelBar is visible // to avoid false positives. if (!path.startsWith(REEL_CHANNEL_BAR_PATH)) return false; - } else if (matchedGroup == shortsShelfHeader) { + } else if (matchedGroup == shelfHeader) { // Because the header is used in watch history and possibly other places, check for the index, // which is 0 when the shelf header is used for Shorts. if (matchedIndex != 0) return false; } // Super class handles logging. - return super.isFiltered(path, identifier, protobufBufferArray, matchedList, matchedGroup, matchedIndex); + return super.isFiltered(identifier, path, protobufBufferArray, matchedList, matchedGroup, matchedIndex); } public static void hideShortsShelf(final View shortsShelfView) { hideViewBy1dpUnderCondition(SettingsEnum.HIDE_SHORTS, shortsShelfView); } - // Additional components that have to be hidden by setting their visibility + // region Hide the buttons in older versions of YouTube. New versions use Litho. public static void hideShortsCommentsButton(final View commentsButtonView) { hideViewUnderCondition(SettingsEnum.HIDE_SHORTS_COMMENTS_BUTTON, commentsButtonView); @@ -106,6 +146,8 @@ public final class ShortsFilter extends Filter { hideViewUnderCondition(SettingsEnum.HIDE_SHORTS_SHARE_BUTTON, shareButtonView); } + // endregion + public static void hideNavigationBar() { if (!SettingsEnum.HIDE_SHORTS_NAVIGATION_BAR.getBoolean()) return; if (pivotBar == null) return; diff --git a/app/src/main/java/app/revanced/integrations/patches/spoof/requests/StoryboardRendererRequester.java b/app/src/main/java/app/revanced/integrations/patches/spoof/requests/StoryboardRendererRequester.java index d2b79e8d..31386305 100644 --- a/app/src/main/java/app/revanced/integrations/patches/spoof/requests/StoryboardRendererRequester.java +++ b/app/src/main/java/app/revanced/integrations/patches/spoof/requests/StoryboardRendererRequester.java @@ -100,10 +100,10 @@ public class StoryboardRendererRequester { var renderer = getStoryboardRendererUsingBody(String.format(ANDROID_INNER_TUBE_BODY, videoId)); if (renderer == null) { - LogHelper.printDebug(() -> videoId + " not available using android client"); + LogHelper.printDebug(() -> videoId + " not available using Android client"); renderer = getStoryboardRendererUsingBody(String.format(TV_EMBED_INNER_TUBE_BODY, videoId, videoId)); if (renderer == null) { - LogHelper.printDebug(() -> videoId + " not available using tv embedded client"); + LogHelper.printDebug(() -> videoId + " not available using TV embedded client"); } } diff --git a/app/src/main/java/app/revanced/integrations/returnyoutubedislike/ReturnYouTubeDislike.java b/app/src/main/java/app/revanced/integrations/returnyoutubedislike/ReturnYouTubeDislike.java index 7fcd9d0f..21f72b9d 100644 --- a/app/src/main/java/app/revanced/integrations/returnyoutubedislike/ReturnYouTubeDislike.java +++ b/app/src/main/java/app/revanced/integrations/returnyoutubedislike/ReturnYouTubeDislike.java @@ -279,7 +279,7 @@ public class ReturnYouTubeDislike { // 2. opened a short (without closing the regular video) // 3. closed the short // 4. regular video is now present, but the videoId and RYD data is still for the short - LogHelper.printDebug(() -> "Ignoring getDislikeSpanForContext(), as data loaded is for prior short"); + LogHelper.printDebug(() -> "Ignoring dislike span, as data loaded is for prior short"); return original; } return waitForFetchAndUpdateReplacementSpan(original, isSegmentedButton);