From 33fb91ce4d21ed9a815df4a9be869c97e46a8594 Mon Sep 17 00:00:00 2001 From: Aaron Veil <70171475+anddea@users.noreply.github.com> Date: Mon, 30 Sep 2024 13:27:14 +0300 Subject: [PATCH] feat(YouTube - Hide feed components): Add `Hide related videos` setting --- .../patches/feed/RelatedVideoPatch.java | 49 ++++++++++++++++++ .../patches/utils/BottomSheetHookPatch.java | 21 ++++++++ .../youtube/settings/Settings.java | 4 ++ .../youtube/shared/BottomSheetState.kt | 51 +++++++++++++++++++ .../youtube/shared/LockModeState.kt | 2 +- .../integrations/youtube/shared/PlayerType.kt | 6 +-- .../integrations/youtube/shared/VideoState.kt | 2 +- 7 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/app/revanced/integrations/youtube/patches/feed/RelatedVideoPatch.java create mode 100644 app/src/main/java/app/revanced/integrations/youtube/patches/utils/BottomSheetHookPatch.java create mode 100644 app/src/main/java/app/revanced/integrations/youtube/shared/BottomSheetState.kt diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/feed/RelatedVideoPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/feed/RelatedVideoPatch.java new file mode 100644 index 0000000000..5ee4fe97f4 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/feed/RelatedVideoPatch.java @@ -0,0 +1,49 @@ +package app.revanced.integrations.youtube.patches.feed; + +import androidx.annotation.Nullable; + +import java.util.concurrent.atomic.AtomicBoolean; + +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.shared.BottomSheetState; +import app.revanced.integrations.youtube.shared.RootView; + +@SuppressWarnings("unused") +public final class RelatedVideoPatch { + private static final boolean HIDE_RELATED_VIDEOS = Settings.HIDE_RELATED_VIDEOS.get(); + + private static final int OFFSET = Settings.RELATED_VIDEOS_OFFSET.get(); + + // video title,channel bar, video action bar, comment + private static final int MAX_ITEM_COUNT = 4 + OFFSET; + + private static final AtomicBoolean engagementPanelOpen = new AtomicBoolean(false); + + public static void showEngagementPanel(@Nullable Object object) { + engagementPanelOpen.set(object != null); + } + + public static void hideEngagementPanel() { + engagementPanelOpen.compareAndSet(true, false); + } + + public static int overrideItemCounts(int itemCounts) { + if (!HIDE_RELATED_VIDEOS) { + return itemCounts; + } + if (itemCounts < MAX_ITEM_COUNT) { + return itemCounts; + } + if (!RootView.isPlayerActive()) { + return itemCounts; + } + if (BottomSheetState.getCurrent().isOpen()) { + return itemCounts; + } + if (engagementPanelOpen.get()) { + return itemCounts; + } + return MAX_ITEM_COUNT; + } + +} diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/utils/BottomSheetHookPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/utils/BottomSheetHookPatch.java new file mode 100644 index 0000000000..de6386c5fa --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/utils/BottomSheetHookPatch.java @@ -0,0 +1,21 @@ +package app.revanced.integrations.youtube.patches.utils; + +import app.revanced.integrations.youtube.shared.BottomSheetState; + +@SuppressWarnings("unused") +public class BottomSheetHookPatch { + /** + * Injection point. + */ + public static void onAttachedToWindow() { + BottomSheetState.set(BottomSheetState.OPEN); + } + + /** + * Injection point. + */ + public static void onDetachedFromWindow() { + BottomSheetState.set(BottomSheetState.CLOSED); + } +} + diff --git a/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java b/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java index 52bf6000be..a48e3d990a 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java +++ b/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java @@ -131,6 +131,10 @@ public class Settings extends BaseSettings { public static final StringSetting HIDE_VIDEO_VIEW_COUNTS_MULTIPLIER = new StringSetting("revanced_hide_video_view_counts_multiplier", str("revanced_hide_video_view_counts_multiplier_default_value"), true, parentsAny(HIDE_VIDEO_BY_VIEW_COUNTS_HOME, HIDE_VIDEO_BY_VIEW_COUNTS_SEARCH, HIDE_VIDEO_BY_VIEW_COUNTS_SUBSCRIPTIONS)); + // Experimental Flags + public static final BooleanSetting HIDE_RELATED_VIDEOS = new BooleanSetting("revanced_hide_related_videos", FALSE, true, "revanced_hide_related_videos_user_dialog_message"); + public static final IntegerSetting RELATED_VIDEOS_OFFSET = new IntegerSetting("revanced_related_videos_offset", 1, true, parent(HIDE_RELATED_VIDEOS)); + // PreferenceScreen: General public static final EnumSetting CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.ORIGINAL, true); diff --git a/app/src/main/java/app/revanced/integrations/youtube/shared/BottomSheetState.kt b/app/src/main/java/app/revanced/integrations/youtube/shared/BottomSheetState.kt new file mode 100644 index 0000000000..bf2072daa7 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/shared/BottomSheetState.kt @@ -0,0 +1,51 @@ +package app.revanced.integrations.youtube.shared + +import app.revanced.integrations.shared.utils.Event +import app.revanced.integrations.shared.utils.Logger + +/** + * BottomSheetState bottom sheet state. + */ +enum class BottomSheetState { + CLOSED, + OPEN; + + companion object { + + @JvmStatic + fun set(enum: BottomSheetState) { + if (current != enum) { + Logger.printDebug { "BottomSheetState changed to: ${enum.name}" } + current = enum + } + } + + /** + * The current bottom sheet state. + */ + @JvmStatic + var current + get() = currentBottomSheetState + private set(value) { + currentBottomSheetState = value + onChange(currentBottomSheetState) + } + + @Volatile // value is read/write from different threads + private var currentBottomSheetState = CLOSED + + /** + * bottom sheet state change listener + */ + @JvmStatic + val onChange = Event() + } + + /** + * Check if the bottom sheet is [OPEN]. + * Useful for checking if a bottom sheet is open. + */ + fun isOpen(): Boolean { + return this == OPEN + } +} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/integrations/youtube/shared/LockModeState.kt b/app/src/main/java/app/revanced/integrations/youtube/shared/LockModeState.kt index d457ba6b94..538ba285aa 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/shared/LockModeState.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/shared/LockModeState.kt @@ -16,7 +16,7 @@ enum class LockModeState { companion object { - private val nameToLockModeState = values().associateBy { it.name } + private val nameToLockModeState = entries.associateBy { it.name } @JvmStatic fun setFromString(enumName: String) { diff --git a/app/src/main/java/app/revanced/integrations/youtube/shared/PlayerType.kt b/app/src/main/java/app/revanced/integrations/youtube/shared/PlayerType.kt index 2c3e1d92e3..7a5d34d4ba 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/shared/PlayerType.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/shared/PlayerType.kt @@ -47,7 +47,7 @@ enum class PlayerType { companion object { - private val nameToPlayerType = values().associateBy { it.name } + private val nameToPlayerType = entries.associateBy { it.name } @JvmStatic fun setFromString(enumName: String) { @@ -129,12 +129,12 @@ enum class PlayerType { /** * Check if the current player type is - * [WATCH_WHILE_MAXIMIZED], [WATCH_WHILE_FULLSCREEN], [WATCH_WHILE_SLIDING_MINIMIZED_MAXIMIZED]. + * [WATCH_WHILE_MAXIMIZED], [WATCH_WHILE_FULLSCREEN], [WATCH_WHILE_SLIDING_MINIMIZED_MAXIMIZED], [WATCH_WHILE_SLIDING_MAXIMIZED_FULLSCREEN]. * * Useful to check if a regular video is being played. */ fun isMaximizedOrFullscreenOrSliding(): Boolean { - return this == WATCH_WHILE_MAXIMIZED || this == WATCH_WHILE_FULLSCREEN || this == WATCH_WHILE_SLIDING_MINIMIZED_MAXIMIZED + return this == WATCH_WHILE_MAXIMIZED || this == WATCH_WHILE_FULLSCREEN || this == WATCH_WHILE_SLIDING_MINIMIZED_MAXIMIZED || this == WATCH_WHILE_SLIDING_MAXIMIZED_FULLSCREEN } /** diff --git a/app/src/main/java/app/revanced/integrations/youtube/shared/VideoState.kt b/app/src/main/java/app/revanced/integrations/youtube/shared/VideoState.kt index 028bab35b7..bb20934982 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/shared/VideoState.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/shared/VideoState.kt @@ -15,7 +15,7 @@ enum class VideoState { companion object { - private val nameToVideoState = values().associateBy { it.name } + private val nameToVideoState = entries.associateBy { it.name } @JvmStatic fun setFromString(enumName: String) {