From d09a8872bcb74c331d4d0d064e8e4926b5610313 Mon Sep 17 00:00:00 2001 From: Francesco146 Date: Sun, 28 Jul 2024 12:24:43 +0200 Subject: [PATCH 1/9] feat(YouTube - Download Playlist Button): Attempt to always show the download playlist button --- .../patches/misc/DownloadPlaylistButton.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java new file mode 100644 index 0000000000..03c30459e9 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java @@ -0,0 +1,30 @@ +package app.revanced.integrations.youtube.patches.misc; + +import android.view.View; +import app.revanced.integrations.shared.utils.Logger; + +@SuppressWarnings("unused") +public class DownloadPlaylistButton { + + /* + * Injection point + */ + public static int enablePlaylistDownloadButton(int i) { + Logger.printInfo(() -> + "[DownloadPlaylistButton] Enabling playlist download button, " + + "before: " + i + ); + return 2; + } + + /* + * Injection point + */ + public static void setPlaylistDownloadButtonVisibility(View offlineArrowView) { + Logger.printInfo(() -> + "[DownloadPlaylistButton] Setting playlist download button visibility, " + + "before: " + (offlineArrowView == null ? "null" : offlineArrowView.toString()) + ); + offlineArrowView.setVisibility(View.VISIBLE); + } +} From 5ac1fa111c6da1cce65c854d45fb4e37bc8fa912 Mon Sep 17 00:00:00 2001 From: Francesco146 Date: Sun, 28 Jul 2024 16:18:22 +0200 Subject: [PATCH 2/9] fix(YouTube - Download Playlist Button): Pass the view to the integrations --- .../youtube/patches/misc/DownloadPlaylistButton.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java index 03c30459e9..8ebcbf953e 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java @@ -1,5 +1,6 @@ package app.revanced.integrations.youtube.patches.misc; +import android.graphics.Color; import android.view.View; import app.revanced.integrations.shared.utils.Logger; @@ -26,5 +27,6 @@ public static void setPlaylistDownloadButtonVisibility(View offlineArrowView) { "before: " + (offlineArrowView == null ? "null" : offlineArrowView.toString()) ); offlineArrowView.setVisibility(View.VISIBLE); + offlineArrowView.setEnabled(true); } } From c74cbbcb167d8d0a7e63df67d9a5f7600d2e85d3 Mon Sep 17 00:00:00 2001 From: Francesco146 Date: Mon, 29 Jul 2024 11:56:29 +0200 Subject: [PATCH 3/9] fix(YouTube - Download Playlist Button): Make the button fully visible and refactor --- .../patches/misc/DownloadPlaylistButton.java | 25 ++----------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java index 8ebcbf953e..2fc602ecaf 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java @@ -1,32 +1,11 @@ package app.revanced.integrations.youtube.patches.misc; -import android.graphics.Color; -import android.view.View; -import app.revanced.integrations.shared.utils.Logger; - @SuppressWarnings("unused") public class DownloadPlaylistButton { - - /* - * Injection point - */ - public static int enablePlaylistDownloadButton(int i) { - Logger.printInfo(() -> - "[DownloadPlaylistButton] Enabling playlist download button, " + - "before: " + i - ); - return 2; - } - /* * Injection point */ - public static void setPlaylistDownloadButtonVisibility(View offlineArrowView) { - Logger.printInfo(() -> - "[DownloadPlaylistButton] Setting playlist download button visibility, " + - "before: " + (offlineArrowView == null ? "null" : offlineArrowView.toString()) - ); - offlineArrowView.setVisibility(View.VISIBLE); - offlineArrowView.setEnabled(true); + public static boolean setPlaylistDownloadButtonVisibility() { + return true; } } From 1cb063b1bb0b0ba1b7db97683deb32e9325db91f Mon Sep 17 00:00:00 2001 From: Francesco146 Date: Mon, 29 Jul 2024 16:16:54 +0200 Subject: [PATCH 4/9] feat(YouTube - Download Playlist Button): Hook playlist download button onClick method --- .../patches/misc/DownloadPlaylistButton.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java index 2fc602ecaf..c4cbf0dd7d 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java @@ -1,11 +1,28 @@ package app.revanced.integrations.youtube.patches.misc; +import app.revanced.integrations.shared.utils.Logger; + @SuppressWarnings("unused") public class DownloadPlaylistButton { /* * Injection point */ - public static boolean setPlaylistDownloadButtonVisibility() { + public static boolean isPlaylistDownloadButtonHooked() { return true; } + + /* + * Injection point + */ + public static String startPlaylistDownloadActivity(String playlistId) { + // Hook the playlist download button + Logger.printInfo(() -> "[DownloadPlaylistButton] String: " + playlistId); + + if (!isPlaylistDownloadButtonHooked()) return playlistId; + + + // return an empty string to prevent + // the original method from being called + return ""; + } } From f5a0a827a2904d3b052f9053794d74752e8b50ee Mon Sep 17 00:00:00 2001 From: Francesco146 Date: Mon, 29 Jul 2024 17:09:58 +0200 Subject: [PATCH 5/9] feat(YouTube - Download Playlist Button): Add setting toggle and call the external downloader --- .../patches/misc/DownloadPlaylistButton.java | 12 ++++++------ .../integrations/youtube/settings/Settings.java | 1 + .../integrations/youtube/utils/VideoUtils.java | 15 +++++++++++---- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java index c4cbf0dd7d..9cada3c410 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java @@ -1,28 +1,28 @@ package app.revanced.integrations.youtube.patches.misc; -import app.revanced.integrations.shared.utils.Logger; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.utils.VideoUtils; @SuppressWarnings("unused") public class DownloadPlaylistButton { + /* * Injection point */ public static boolean isPlaylistDownloadButtonHooked() { - return true; + return Settings.HOOK_PLAYLIST_DOWNLOAD_BUTTON.get(); } /* * Injection point */ public static String startPlaylistDownloadActivity(String playlistId) { - // Hook the playlist download button - Logger.printInfo(() -> "[DownloadPlaylistButton] String: " + playlistId); - if (!isPlaylistDownloadButtonHooked()) return playlistId; + VideoUtils.launchExternalDownloader(playlistId, true); // return an empty string to prevent - // the original method from being called + // the original implementation from being called return ""; } } 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 263f5e01ed..eeaec3c286 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 @@ -135,6 +135,7 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_GRAY_SEPARATOR = new BooleanSetting("revanced_hide_gray_separator", TRUE); public static final BooleanSetting HIDE_SNACK_BAR = new BooleanSetting("revanced_hide_snack_bar", FALSE); public static final BooleanSetting REMOVE_VIEWER_DISCRETION_DIALOG = new BooleanSetting("revanced_remove_viewer_discretion_dialog", FALSE); + public static final BooleanSetting HOOK_PLAYLIST_DOWNLOAD_BUTTON = new BooleanSetting("revanced_hook_playlist_download_button", TRUE); public static final BooleanSetting ENABLE_PHONE_LAYOUT = new BooleanSetting("revanced_enable_phone_layout", FALSE, true); public static final BooleanSetting ENABLE_TABLET_LAYOUT = new BooleanSetting("revanced_enable_tablet_layout", FALSE, true); diff --git a/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java b/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java index 158d79c9be..c3a0924912 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java +++ b/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java @@ -94,7 +94,7 @@ public static boolean inAppDownloadButtonOnClick(String videoId) { if (videoId == null || videoId.isEmpty()) { return false; } - launchExternalDownloader(videoId); + launchExternalDownloader(videoId, false); return true; } catch (Exception ex) { @@ -104,10 +104,10 @@ public static boolean inAppDownloadButtonOnClick(String videoId) { } public static void launchExternalDownloader() { - launchExternalDownloader(VideoInformation.getVideoId()); + launchExternalDownloader(VideoInformation.getVideoId(), false); } - public static void launchExternalDownloader(@NonNull String videoId) { + public static void launchExternalDownloader(@NonNull String resourceId, boolean isPlaylist) { try { String downloaderPackageName = externalDownloaderPackageName.get().trim(); @@ -121,7 +121,14 @@ public static void launchExternalDownloader(@NonNull String videoId) { } isExternalDownloaderLaunched.compareAndSet(false, true); - final String content = String.format("https://youtu.be/%s", videoId); + + final String content; + + if (isPlaylist) + content = String.format("https://www.youtube.com/playlist?list=%s", resourceId); + else + content = String.format("https://youtu.be/%s", resourceId); + launchExternalDownloader(content, downloaderPackageName); } catch (Exception ex) { Logger.printException(() -> "launchExternalDownloader failure", ex); From 5dd4f7a0767ce3383d0d90723374437a0a97f4e1 Mon Sep 17 00:00:00 2001 From: Francesco146 Date: Sat, 3 Aug 2024 21:46:51 +0200 Subject: [PATCH 6/9] fix(YouTube - Download Playlist Button): Use YTDLnis downloader for playlists to ensure compatibility --- .../integrations/youtube/utils/VideoUtils.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java b/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java index c3a0924912..7511c7c689 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java +++ b/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java @@ -109,7 +109,15 @@ public static void launchExternalDownloader() { public static void launchExternalDownloader(@NonNull String resourceId, boolean isPlaylist) { try { - String downloaderPackageName = externalDownloaderPackageName.get().trim(); + + String downloaderPackageName; + + // use default downloader (YTDLnis) if user tries to download a playlist + // because most downloaders don't support playlist download + if (isPlaylist) + downloaderPackageName = externalDownloaderPackageName.defaultValue; + else + downloaderPackageName = externalDownloaderPackageName.get().trim(); if (downloaderPackageName.isEmpty()) { externalDownloaderPackageName.resetToDefault(); From 20be58e07de4ebf1b3a3481dbb0aab4ef5afd167 Mon Sep 17 00:00:00 2001 From: Francesco146 Date: Sun, 4 Aug 2024 10:55:17 +0200 Subject: [PATCH 7/9] refactor(YouTube - Download Playlist Button): Separate video external downloader from playlist external downloader --- .../patches/misc/DownloadPlaylistButton.java | 2 +- .../youtube/utils/VideoUtils.java | 43 +++++++++++-------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java index 9cada3c410..ecee63a2b8 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java @@ -19,7 +19,7 @@ public static boolean isPlaylistDownloadButtonHooked() { public static String startPlaylistDownloadActivity(String playlistId) { if (!isPlaylistDownloadButtonHooked()) return playlistId; - VideoUtils.launchExternalDownloader(playlistId, true); + VideoUtils.launchPlaylistExternalDownloader(playlistId); // return an empty string to prevent // the original implementation from being called diff --git a/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java b/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java index 7511c7c689..4b8bd643ca 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java +++ b/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java @@ -94,7 +94,7 @@ public static boolean inAppDownloadButtonOnClick(String videoId) { if (videoId == null || videoId.isEmpty()) { return false; } - launchExternalDownloader(videoId, false); + launchExternalDownloader(videoId); return true; } catch (Exception ex) { @@ -104,20 +104,13 @@ public static boolean inAppDownloadButtonOnClick(String videoId) { } public static void launchExternalDownloader() { - launchExternalDownloader(VideoInformation.getVideoId(), false); + launchExternalDownloader(VideoInformation.getVideoId()); } - public static void launchExternalDownloader(@NonNull String resourceId, boolean isPlaylist) { + public static void launchExternalDownloader(@NonNull String videoID) { try { - String downloaderPackageName; - - // use default downloader (YTDLnis) if user tries to download a playlist - // because most downloaders don't support playlist download - if (isPlaylist) - downloaderPackageName = externalDownloaderPackageName.defaultValue; - else - downloaderPackageName = externalDownloaderPackageName.get().trim(); + String downloaderPackageName = externalDownloaderPackageName.get().trim(); if (downloaderPackageName.isEmpty()) { externalDownloaderPackageName.resetToDefault(); @@ -130,12 +123,7 @@ public static void launchExternalDownloader(@NonNull String resourceId, boolean isExternalDownloaderLaunched.compareAndSet(false, true); - final String content; - - if (isPlaylist) - content = String.format("https://www.youtube.com/playlist?list=%s", resourceId); - else - content = String.format("https://youtu.be/%s", resourceId); + final String content = String.format("https://youtu.be/%s", videoID); launchExternalDownloader(content, downloaderPackageName); } catch (Exception ex) { @@ -145,6 +133,27 @@ public static void launchExternalDownloader(@NonNull String resourceId, boolean } } + public static void launchPlaylistExternalDownloader(@NonNull String playlistId) { + try { + // use default downloader (YTDLnis) if user tries to download a playlist + // because most downloaders don't support playlist download + String downloaderPackageName = externalDownloaderPackageName.defaultValue; + + final String content = String.format("https://www.youtube.com/playlist?list=%s", playlistId); + + if (!checkPackageIsEnabled()) { + return; + } + + isExternalDownloaderLaunched.compareAndSet(false, true); + launchExternalDownloader(content, downloaderPackageName); + } catch (Exception ex) { + Logger.printException(() -> "launchPlaylistExternalDownloader failure", ex); + } finally { + runOnMainThreadDelayed(() -> isExternalDownloaderLaunched.compareAndSet(true, false), 500); + } + } + /** * Create playlist from all channel videos from oldest to newest, * starting from the video where button is clicked. From 6707799fa3a4bf7c54f4974eb76694c270b78c64 Mon Sep 17 00:00:00 2001 From: Francesco146 Date: Sun, 4 Aug 2024 11:55:36 +0200 Subject: [PATCH 8/9] refactor(YouTube - Download Playlist Button): Rename `DownloadPlaylistButton` to `HookDownloadAction` --- .../{DownloadPlaylistButton.java => HookDownloadAction.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename app/src/main/java/app/revanced/integrations/youtube/patches/misc/{DownloadPlaylistButton.java => HookDownloadAction.java} (95%) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/HookDownloadAction.java similarity index 95% rename from app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/misc/HookDownloadAction.java index ecee63a2b8..9a12fab7c2 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/DownloadPlaylistButton.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/HookDownloadAction.java @@ -4,7 +4,7 @@ import app.revanced.integrations.youtube.utils.VideoUtils; @SuppressWarnings("unused") -public class DownloadPlaylistButton { +public class HookDownloadAction { /* * Injection point From 90c690a0e79a8aae8b306db0729bbb455321f794 Mon Sep 17 00:00:00 2001 From: Francesco146 Date: Sun, 4 Aug 2024 11:56:39 +0200 Subject: [PATCH 9/9] refactor(YouTube - Download Playlist Button): Use hardcoded value as package name --- .../settings/preference/ExternalDownloaderPreference.java | 6 ++++++ .../revanced/integrations/youtube/utils/VideoUtils.java | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/settings/preference/ExternalDownloaderPreference.java b/app/src/main/java/app/revanced/integrations/youtube/settings/preference/ExternalDownloaderPreference.java index 9cc05138d7..437c8e174a 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/settings/preference/ExternalDownloaderPreference.java +++ b/app/src/main/java/app/revanced/integrations/youtube/settings/preference/ExternalDownloaderPreference.java @@ -160,4 +160,10 @@ public static boolean checkPackageIsEnabled() { return checkPackageIsValid(context, packageName); } + public static boolean checkPackageIsEnabled(String packageName) { + final Context context = Utils.getActivity(); + mClickedDialogEntryIndex = Arrays.asList(mEntryValues).indexOf(packageName); + return checkPackageIsValid(context, packageName); + } + } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java b/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java index 4b8bd643ca..e1f36b3ceb 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java +++ b/app/src/main/java/app/revanced/integrations/youtube/utils/VideoUtils.java @@ -107,7 +107,7 @@ public static void launchExternalDownloader() { launchExternalDownloader(VideoInformation.getVideoId()); } - public static void launchExternalDownloader(@NonNull String videoID) { + public static void launchExternalDownloader(@NonNull String videoId) { try { String downloaderPackageName = externalDownloaderPackageName.get().trim(); @@ -123,7 +123,7 @@ public static void launchExternalDownloader(@NonNull String videoID) { isExternalDownloaderLaunched.compareAndSet(false, true); - final String content = String.format("https://youtu.be/%s", videoID); + final String content = String.format("https://youtu.be/%s", videoId); launchExternalDownloader(content, downloaderPackageName); } catch (Exception ex) { @@ -137,11 +137,11 @@ public static void launchPlaylistExternalDownloader(@NonNull String playlistId) try { // use default downloader (YTDLnis) if user tries to download a playlist // because most downloaders don't support playlist download - String downloaderPackageName = externalDownloaderPackageName.defaultValue; + String downloaderPackageName = "com.deniscerri.ytdl"; final String content = String.format("https://www.youtube.com/playlist?list=%s", playlistId); - if (!checkPackageIsEnabled()) { + if (!checkPackageIsEnabled(downloaderPackageName)) { return; }