From 6aa02e50632031ad44cfc38ff3db5b7797ac88c6 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Mon, 22 Aug 2022 04:58:14 +0200 Subject: [PATCH] feat: `downloads` patch (#89) --- app/build.gradle | 3 +- .../support/constraint/ConstraintLayout.java | 20 +++ .../patches/downloads/DownloadsPatch.java | 27 +++ .../downloads/views/DownloadOptions.kt | 4 + .../integrations/settings/SettingsEnum.java | 4 + .../ReVancedSettingsFragment.java | 18 +- .../integrations/videoplayer/AutoRepeat.java | 3 +- .../integrations/videoplayer/Copy.java | 3 +- .../videoplayer/CopyWithTimeStamp.java | 3 +- .../videoplayer/DownloadButton.java | 160 ++++++++++++++++++ build.gradle | 3 +- 11 files changed, 233 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/android/support/constraint/ConstraintLayout.java create mode 100644 app/src/main/java/app/revanced/integrations/patches/downloads/DownloadsPatch.java create mode 100644 app/src/main/java/app/revanced/integrations/patches/downloads/views/DownloadOptions.kt create mode 100644 app/src/main/java/app/revanced/integrations/videoplayer/DownloadButton.java diff --git a/app/build.gradle b/app/build.gradle index db64c9b6..511646f4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,7 +34,8 @@ android { } dependencies { + //implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.22.1' + compileOnly 'androidx.annotation:annotation:1.4.0' - compileOnly 'androidx.constraintlayout:constraintlayout:2.1.4' } diff --git a/app/src/main/java/android/support/constraint/ConstraintLayout.java b/app/src/main/java/android/support/constraint/ConstraintLayout.java new file mode 100644 index 00000000..3a09f713 --- /dev/null +++ b/app/src/main/java/android/support/constraint/ConstraintLayout.java @@ -0,0 +1,20 @@ +package android.support.constraint; + +import android.content.Context; +import android.view.ViewGroup; + +/** + * "CompileOnly" class + * because android.support.constraint.ConstraintLayout is deprecated + * in favour of androidx.constraintlayout.widget.ConstraintLayout. + * + * This class will not be included and "replaced" by the real package's class. + */ +public class ConstraintLayout extends ViewGroup { + public ConstraintLayout(Context context) { + super(context); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/downloads/DownloadsPatch.java b/app/src/main/java/app/revanced/integrations/patches/downloads/DownloadsPatch.java new file mode 100644 index 00000000..be60a0b0 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/patches/downloads/DownloadsPatch.java @@ -0,0 +1,27 @@ +package app.revanced.integrations.patches.downloads; + +import app.revanced.integrations.utils.LogHelper; + +/** + * Used by app.revanced.patches.youtube.interaction.downloads.bytecode.patch.DownloadsBytecodePatch + */ +public class DownloadsPatch { + private static String videoId; + + /** + * Called when the video changes + * @param videoId The current video id + */ + public static void setVideoId(String videoId) { + LogHelper.debug(DownloadsPatch.class, "newVideoLoaded - " + videoId); + + DownloadsPatch.videoId = videoId; + } + + /** + * @return The current video id + */ + public static String getCurrentVideoId() { + return videoId; + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/downloads/views/DownloadOptions.kt b/app/src/main/java/app/revanced/integrations/patches/downloads/views/DownloadOptions.kt new file mode 100644 index 00000000..2be9ed19 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/patches/downloads/views/DownloadOptions.kt @@ -0,0 +1,4 @@ +package app.revanced.integrations.patches.downloads.views + +class DownloadOptions { +} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java index be240c2e..5ff3e044 100644 --- a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java +++ b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java @@ -1,6 +1,7 @@ package app.revanced.integrations.settings; import android.content.Context; +import android.os.Environment; import android.util.Log; import java.util.ArrayList; @@ -11,6 +12,9 @@ import app.revanced.integrations.utils.ReVancedUtils; import app.revanced.integrations.utils.SharedPrefHelper; public enum SettingsEnum { + //Download Settings + // TODO: DOWNLOAD_PATH("revanced_download_path", Environment.getExternalStorageDirectory().getPath() + "/Download", ReturnType.STRING), + DOWNLOAD_BUTTON_SHOWN("revanced_downloads", true, ReturnType.BOOLEAN), //Video Settings OLD_STYLE_QUALITY_SETTINGS("revanced_use_old_style_quality_settings", true, ReturnType.BOOLEAN), diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingsFragment.java b/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingsFragment.java index a0a492f0..99d0b144 100644 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingsFragment.java +++ b/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingsFragment.java @@ -28,6 +28,9 @@ import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.ReVancedUtils; import app.revanced.integrations.utils.SharedPrefHelper; import app.revanced.integrations.videoplayer.AutoRepeat; +import app.revanced.integrations.videoplayer.Copy; +import app.revanced.integrations.videoplayer.CopyWithTimeStamp; +import app.revanced.integrations.videoplayer.DownloadButton; public class ReVancedSettingsFragment extends PreferenceFragment { @@ -91,13 +94,14 @@ public class ReVancedSettingsFragment extends PreferenceFragment { } else { LogHelper.printException(ReVancedSettingsFragment.class, "No valid setting found: " + setting.toString()); } - /* - if ("pref_copy_video_url_timestamp_button_list".equals(str)) { - CopyWithTimeStamp.refreshShouldBeShown(); - } else if ("pref_copy_video_url_button_list".equals(str)) { - Copy.refreshShouldBeShown(); - } - */ + + if ("pref_copy_video_url_timestamp_button_list".equals(str)) { + CopyWithTimeStamp.refreshShouldBeShown(); + } else if ("pref_copy_video_url_button_list".equals(str)) { + Copy.refreshShouldBeShown(); + } else if ("pref_download_button_list".equals(str)) { + DownloadButton.refreshShouldBeShown(); + } } else { LogHelper.printException(ReVancedSettingsFragment.class, "Setting cannot be handled! " + pref.toString()); } diff --git a/app/src/main/java/app/revanced/integrations/videoplayer/AutoRepeat.java b/app/src/main/java/app/revanced/integrations/videoplayer/AutoRepeat.java index 50c912eb..8df68f1e 100644 --- a/app/src/main/java/app/revanced/integrations/videoplayer/AutoRepeat.java +++ b/app/src/main/java/app/revanced/integrations/videoplayer/AutoRepeat.java @@ -2,13 +2,12 @@ package app.revanced.integrations.videoplayer; import android.content.Context; +import android.support.constraint.ConstraintLayout; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.ImageView; -import androidx.constraintlayout.widget.ConstraintLayout; - import app.revanced.integrations.settings.SettingsEnum; import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.utils.ReVancedUtils; diff --git a/app/src/main/java/app/revanced/integrations/videoplayer/Copy.java b/app/src/main/java/app/revanced/integrations/videoplayer/Copy.java index b629daf2..02d51713 100644 --- a/app/src/main/java/app/revanced/integrations/videoplayer/Copy.java +++ b/app/src/main/java/app/revanced/integrations/videoplayer/Copy.java @@ -1,13 +1,12 @@ package app.revanced.integrations.videoplayer; import android.content.Context; +import android.support.constraint.ConstraintLayout; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.ImageView; -import androidx.constraintlayout.widget.ConstraintLayout; - import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.sponsorblock.player.VideoHelpers; import app.revanced.integrations.utils.ReVancedUtils; diff --git a/app/src/main/java/app/revanced/integrations/videoplayer/CopyWithTimeStamp.java b/app/src/main/java/app/revanced/integrations/videoplayer/CopyWithTimeStamp.java index e0d0f1f0..69a418b3 100644 --- a/app/src/main/java/app/revanced/integrations/videoplayer/CopyWithTimeStamp.java +++ b/app/src/main/java/app/revanced/integrations/videoplayer/CopyWithTimeStamp.java @@ -2,13 +2,12 @@ package app.revanced.integrations.videoplayer; import android.content.Context; +import android.support.constraint.ConstraintLayout; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.ImageView; -import androidx.constraintlayout.widget.ConstraintLayout; - import app.revanced.integrations.utils.LogHelper; import app.revanced.integrations.sponsorblock.player.VideoHelpers; import app.revanced.integrations.utils.ReVancedUtils; diff --git a/app/src/main/java/app/revanced/integrations/videoplayer/DownloadButton.java b/app/src/main/java/app/revanced/integrations/videoplayer/DownloadButton.java new file mode 100644 index 00000000..e77f402f --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/videoplayer/DownloadButton.java @@ -0,0 +1,160 @@ +package app.revanced.integrations.videoplayer; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.support.constraint.ConstraintLayout; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.ImageView; +import android.widget.Toast; + + +import java.lang.ref.WeakReference; + +import app.revanced.integrations.patches.downloads.DownloadsPatch; +import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.sponsorblock.StringRef; +import app.revanced.integrations.utils.LogHelper; +import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.utils.SharedPrefHelper; + +/* loaded from: classes6.dex */ +//ToDo: Refactor +public class DownloadButton { + static WeakReference _button = new WeakReference<>(null); + static ConstraintLayout _constraintLayout; + static int fadeDurationFast; + static int fadeDurationScheduled; + static Animation fadeIn; + static Animation fadeOut; + public static boolean isDownloadButtonEnabled; + static boolean isShowing; + + public static void initializeDownloadButton(Object obj) { + try { + LogHelper.debug(DownloadButton.class, "initializing"); + _constraintLayout = (ConstraintLayout) obj; + isDownloadButtonEnabled = shouldBeShown(); + ImageView imageView = _constraintLayout.findViewById(getIdentifier("download_button", "id")); + if (imageView == null) { + LogHelper.debug(DownloadButton.class, "Couldn't find imageView with id \"download_button\""); + return; + } + + imageView.setOnClickListener(view -> { + LogHelper.debug(DownloadButton.class, "Download button clicked"); + + final var context = view.getContext(); + final var powerTubePackageName = "ussr.razar.youtube_dl"; + + boolean packageEnabled = false; + try { + assert context != null; + packageEnabled = context.getPackageManager().getApplicationInfo(powerTubePackageName, 0).enabled; + } catch (PackageManager.NameNotFoundException error) { + LogHelper.debug(DownloadButton.class, "PowerTube could not be found: " + error); + } + + // If the package is not installed, show the toast + if (!packageEnabled) { + Toast.makeText(context, StringRef.str("powertube_not_installed_warning"), Toast.LENGTH_SHORT).show(); + Toast.makeText(context, StringRef.str("powertube_not_installed_notice"), Toast.LENGTH_LONG).show(); + return; + } + + // Launch PowerTube intent + try { + String content = String.format("https://youtu.be/%s", DownloadsPatch.getCurrentVideoId()); + + Intent intent = new Intent("android.intent.action.SEND"); + intent.setType("text/plain"); + intent.setPackage(powerTubePackageName); + intent.putExtra("android.intent.extra.TEXT", content); + context.startActivity(intent); + + LogHelper.debug(DownloadButton.class, "Launched the intent with the content: " + content); + } catch (Exception error) { + LogHelper.debug(DownloadButton.class, "Failed to launch the intent: " + error); + } + + //var options = Arrays.asList("Video", "Audio").toArray(new CharSequence[0]); + // + //new AlertDialog.Builder(view.getContext()) + // .setItems(options, (dialog, which) -> { + // LogHelper.debug(DownloadButton.class, String.valueOf(options[which])); + // }) + // .show(); + // TODO: show popup and download via newpipe + }); + _button = new WeakReference<>(imageView); + fadeDurationFast = getInteger("fade_duration_fast"); + fadeDurationScheduled = getInteger("fade_duration_scheduled"); + Animation animation = getAnimation("fade_in"); + fadeIn = animation; + animation.setDuration(fadeDurationFast); + Animation animation2 = getAnimation("fade_out"); + fadeOut = animation2; + animation2.setDuration(fadeDurationScheduled); + isShowing = true; + changeVisibility(false); + + } catch (Exception e) { + LogHelper.printException(DownloadButton.class, "Unable to set FrameLayout", e); + } + } + + public static void changeVisibility(boolean z) { + if (isShowing == z) return; + + isShowing = z; + ImageView imageView = _button.get(); + if (_constraintLayout != null && imageView != null) { + if (z && isDownloadButtonEnabled) { + LogHelper.debug(DownloadButton.class, "Fading in"); + imageView.setVisibility(View.VISIBLE); + imageView.startAnimation(fadeIn); + } else if (imageView.getVisibility() == View.VISIBLE) { + LogHelper.debug(DownloadButton.class, "Fading out"); + imageView.startAnimation(fadeOut); + imageView.setVisibility(View.GONE); + } + } + } + + public static void refreshShouldBeShown() { + isDownloadButtonEnabled = shouldBeShown(); + } + + private static boolean shouldBeShown() { + if (!SettingsEnum.DOWNLOAD_BUTTON_SHOWN.getBoolean()) { + return false; + } + + Context appContext = ReVancedUtils.getContext(); + if (appContext == null) { + LogHelper.printException(DownloadButton.class, "shouldBeShown - context is null!"); + return false; + } + String string = SharedPrefHelper.getString(appContext, SharedPrefHelper.SharedPrefNames.YOUTUBE, "pref_download_button_list", "PLAYER" /* TODO: set the default to null, as this will be set by the settings page later */); + if (string == null || string.isEmpty()) { + return false; + } + return string.equalsIgnoreCase("PLAYER"); + } + + private static int getIdentifier(String str, String str2) { + Context appContext = ReVancedUtils.getContext(); + return appContext.getResources().getIdentifier(str, str2, appContext.getPackageName()); + } + + private static int getInteger(String str) { + return ReVancedUtils.getContext().getResources().getInteger(getIdentifier(str, "integer")); + } + private static Animation getAnimation(String str) { + return AnimationUtils.loadAnimation(ReVancedUtils.getContext(), getIdentifier(str, "anim")); + } +} + diff --git a/build.gradle b/build.gradle index 78e04152..5df53c95 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.2.0' + classpath 'com.android.tools.build:gradle:7.2.1' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.0' // NOTE: Do not place your application dependencies here; they belong @@ -17,6 +17,7 @@ buildscript { allprojects { repositories { google() + maven { url 'https://jitpack.io' } mavenCentral() } }