From bc637cef37e8ed66f3eda05ac753b7167f9ec2f8 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Tue, 24 Dec 2024 22:13:23 +0400 Subject: [PATCH 1/3] feat(YouTube - Hide Shorts components): Add option to hide Shorts in watch history --- .../patches/components/ShortsFilter.java | 44 +++++++++++-------- .../extension/youtube/settings/Settings.java | 1 + .../hide/shorts/HideShortsComponentsPatch.kt | 1 + .../resources/addresources/values/strings.xml | 15 ++++--- 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java index 1588ad70f7..48ef78fb29 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java @@ -324,21 +324,24 @@ boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBuff } private static boolean shouldHideShortsFeedItems() { + // Known issue if hide home is on but at least one other hide is off: + // + // Shorts suggestions can load in the background if a video is opened and + // then immediately minimized before any suggestions are loaded. + // In this state the player type will show minimized, which cannot + // distinguish between Shorts suggestions loading in the player and between + // scrolling thru search/home/subscription tabs while a player is minimized. final boolean hideHome = Settings.HIDE_SHORTS_HOME.get(); final boolean hideSubscriptions = Settings.HIDE_SHORTS_SUBSCRIPTIONS.get(); final boolean hideSearch = Settings.HIDE_SHORTS_SEARCH.get(); + final boolean hideHistory = Settings.HIDE_SHORTS_HISTORY.get(); - if (hideHome && hideSubscriptions && hideSearch) { - // Shorts suggestions can load in the background if a video is opened and - // then immediately minimized before any suggestions are loaded. - // In this state the player type will show minimized, which makes it not possible to - // distinguish between Shorts suggestions loading in the player and between - // scrolling thru search/home/subscription tabs while a player is minimized. - // - // To avoid this situation for users that never want to show Shorts (all hide Shorts options are enabled) - // then hide all Shorts everywhere including the Library history and Library playlists. + if (hideHome && hideSubscriptions && hideSearch && hideHistory) { return true; } + if (!hideHome && !hideSubscriptions && !hideSearch && !hideHistory) { + return false; + } // Must check player type first, as search bar can be active behind the player. if (PlayerType.getCurrent().isMaximizedOrFullscreen()) { @@ -352,24 +355,29 @@ private static boolean shouldHideShortsFeedItems() { } // Avoid checking navigation button status if all other Shorts should show. - if (!hideHome && !hideSubscriptions) { + if (!hideHome && !hideSubscriptions && !hideHistory) { return false; } + // Check navigation absolutely last since the check may block this thread. NavigationButton selectedNavButton = NavigationButton.getSelectedNavigationButton(); if (selectedNavButton == null) { return hideHome; // Unknown tab, treat the same as home. } - if (selectedNavButton == NavigationButton.HOME) { - return hideHome; - } - if (selectedNavButton == NavigationButton.SUBSCRIPTIONS) { - return hideSubscriptions; - } - // User must be in the library tab. Don't hide the history or any playlists here. - return false; + + return switch (selectedNavButton) { + case HOME -> hideHome; + case SUBSCRIPTIONS -> hideSubscriptions; + case LIBRARY -> hideHistory; + default -> false; + }; } + /** + * Injection point. Only used if patching older than 19.03, + * and this hook may be obsolete even for those old versions + * as Shorts show using a litho Shorts shelf like newer versions. + */ public static void hideShortsShelf(final View shortsShelfView) { if (shouldHideShortsFeedItems()) { Utils.hideViewByLayoutParams(shortsShelfView); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index b147249d8f..41f4441d6c 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -233,6 +233,7 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_SHORTS_FULL_VIDEO_LINK_LABEL = new BooleanSetting("revanced_hide_shorts_full_video_link_label", FALSE); public static final BooleanSetting HIDE_SHORTS_GREEN_SCREEN_BUTTON = new BooleanSetting("revanced_hide_shorts_green_screen_button", TRUE); public static final BooleanSetting HIDE_SHORTS_HASHTAG_BUTTON = new BooleanSetting("revanced_hide_shorts_hashtag_button", TRUE); + public static final BooleanSetting HIDE_SHORTS_HISTORY = new BooleanSetting("revanced_hide_shorts_history", FALSE); public static final BooleanSetting HIDE_SHORTS_HOME = new BooleanSetting("revanced_hide_shorts_home", FALSE); public static final BooleanSetting HIDE_SHORTS_INFO_PANEL = new BooleanSetting("revanced_hide_shorts_info_panel", TRUE); public static final BooleanSetting HIDE_SHORTS_JOIN_BUTTON = new BooleanSetting("revanced_hide_shorts_join_button", TRUE); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt index 9dc15d5688..fb0cfe999b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt @@ -71,6 +71,7 @@ private val hideShortsComponentsResourcePatch = resourcePatch { SwitchPreference("revanced_hide_shorts_home"), SwitchPreference("revanced_hide_shorts_subscriptions"), SwitchPreference("revanced_hide_shorts_search"), + SwitchPreference("revanced_hide_shorts_history"), PreferenceScreenPreference( key = "revanced_shorts_player_screen", diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index f566b1837e..af85c7a76c 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -632,15 +632,18 @@ Note: Enabling this also forcibly hides video ads" Hide or show components in the Shorts player Hide Shorts in home feed - Shorts in home feed are hidden - Shorts in home feed are shown + Home feed and related videos are hidden + Home feed and related videos are shown Hide Shorts in subscription feed - Shorts in subscription feed are hidden - Shorts in subscription feed are shown + Hidden in subscription feed + Shown in subscription feed Hide Shorts in search results - Shorts in search results are hidden - Shorts in search results are shown + Hidden in search results + Shown in search results + Hide Shorts in watch history + Hidden in watch history + Shown in watch history Hide join button Join button is hidden From 79a9b44b46e3193ac127601eb3a86246a33f7451 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Tue, 24 Dec 2024 22:24:29 +0400 Subject: [PATCH 2/3] fix: Increase nav button latch timeout. Increasing max wait time should reduce the chance of the history incorrectly hiding due to delayed thread executions, especially on low end devices with heavy background activities. --- .../youtube/shared/NavigationBar.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/shared/NavigationBar.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/shared/NavigationBar.java index 960df3bf07..3a24567956 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/shared/NavigationBar.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/shared/NavigationBar.java @@ -54,20 +54,21 @@ public static boolean isSearchBarActive() { * How long to wait for the set nav button latch to be released. Maximum wait time must * be as small as possible while still allowing enough time for the nav bar to update. * - * YT calls it's back button handlers out of order, - * and litho starts filtering before the navigation bar is updated. + * YT calls it's back button handlers out of order, and litho starts filtering before the + * navigation bar is updated. Fixing this situation and not needlessly waiting requires + * somehow detecting if a back button key/gesture will not change the active tab. * - * Fixing this situation and not needlessly waiting requires somehow - * detecting if a back button key-press will cause a tab change. + * On average the time between pressing the back button and the first litho event is + * about 10-20ms. Waiting up to 75-150ms should be enough time to handle normal use cases + * and not be noticeable, since YT typically takes 100-200ms (or more) to update the view. * - * Typically after pressing the back button, the time between the first litho event and - * when the nav button is updated is about 10-20ms. Using 50-100ms here should be enough time - * and not noticeable, since YT typically takes 100-200ms (or more) to update the view anyways. + * This delay is only noticeable when the device back button/gesture will not + * change the current navigation tab, such as backing out of the watch history. * * This issue can also be avoided on a patch by patch basis, by avoiding calls to * {@link NavigationButton#getSelectedNavigationButton()} unless absolutely necessary. */ - private static final long LATCH_AWAIT_TIMEOUT_MILLISECONDS = 75; + private static final long LATCH_AWAIT_TIMEOUT_MILLISECONDS = 120; /** * Used as a workaround to fix the issue of YT calling back button handlers out of order. @@ -113,7 +114,8 @@ private static void waitForNavButtonLatchIfNeeded() { // The latch is released from the main thread, and waiting from the main thread will always timeout. // This situation has only been observed when navigating out of a submenu and not changing tabs. // and for that use case the nav bar does not change so it's safe to return here. - Logger.printDebug(() -> "Cannot block main thread waiting for nav button. Using last known navbar button status."); + Logger.printDebug(() -> "Cannot block main thread waiting for nav button. " + + "Using last known navbar button status."); return; } @@ -131,7 +133,9 @@ private static void waitForNavButtonLatchIfNeeded() { Logger.printDebug(() -> "Latch wait timed out"); } catch (InterruptedException ex) { - Logger.printException(() -> "Latch wait interrupted failure", ex); // Will never happen. + // Calling YouTube thread was interrupted. + Logger.printException(() -> "Latch wait interrupted", ex); + Thread.currentThread().interrupt(); // Restore interrupt status flag. } } @@ -283,8 +287,8 @@ public enum NavigationButton { * * All code calling this method should handle a null return value. * - * Due to issues with how YT processes physical back button events, - * this patch uses workarounds that can cause this method to take up to 75ms + * Due to issues with how YT processes physical back button/gesture events, + * this patch uses workarounds that can cause this method to take up to 120ms * if the device back button was recently pressed. * * @return The active navigation tab. From 19b92da5cd18d3cea03c8f7797b55398064fe966 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Wed, 25 Dec 2024 01:31:16 +0400 Subject: [PATCH 3/3] Cleanup --- .../patches/components/ShortsFilter.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java index 48ef78fb29..ac8218c417 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java @@ -297,7 +297,7 @@ boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBuff if (matchedGroup == suggestedAction) { // Skip searching the buffer if all suggested actions are set to hidden. // This has a secondary effect of hiding all new un-identified actions - // under the assumption that the user wants all actions hidden. + // under the assumption that the user wants all suggestions hidden. if (isEverySuggestedActionFilterEnabled()) { return super.isFiltered(path, identifier, protobufBufferArray, matchedGroup, contentType, contentIndex); } @@ -326,8 +326,8 @@ boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBuff private static boolean shouldHideShortsFeedItems() { // Known issue if hide home is on but at least one other hide is off: // - // Shorts suggestions can load in the background if a video is opened and - // then immediately minimized before any suggestions are loaded. + // Shorts suggestions will load in the background if a video is opened and + // immediately minimized before any suggestions are loaded. // In this state the player type will show minimized, which cannot // distinguish between Shorts suggestions loading in the player and between // scrolling thru search/home/subscription tabs while a player is minimized. @@ -336,12 +336,12 @@ private static boolean shouldHideShortsFeedItems() { final boolean hideSearch = Settings.HIDE_SHORTS_SEARCH.get(); final boolean hideHistory = Settings.HIDE_SHORTS_HISTORY.get(); - if (hideHome && hideSubscriptions && hideSearch && hideHistory) { - return true; - } if (!hideHome && !hideSubscriptions && !hideSearch && !hideHistory) { return false; } + if (hideHome && hideSubscriptions && hideSearch && hideHistory) { + return true; + } // Must check player type first, as search bar can be active behind the player. if (PlayerType.getCurrent().isMaximizedOrFullscreen()) { @@ -374,9 +374,9 @@ private static boolean shouldHideShortsFeedItems() { } /** - * Injection point. Only used if patching older than 19.03, - * and this hook may be obsolete even for those old versions - * as Shorts show using a litho Shorts shelf like newer versions. + * Injection point. Only used if patching older than 19.03. + * This hook may be obsolete even for old versions + * as they now use a litho layout like newer versions. */ public static void hideShortsShelf(final View shortsShelfView) { if (shouldHideShortsFeedItems()) {