mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-19 09:03:58 +00:00
Compare commits
8 Commits
v5.2.0-dev
...
v5.2.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
545e16913a | ||
|
|
fafed099c5 | ||
|
|
a65bbebfdb | ||
|
|
1a910a2cf6 | ||
|
|
6d23a4e000 | ||
|
|
5c3c68406e | ||
|
|
b0c3709be7 | ||
|
|
cd19f976e7 |
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,3 +1,24 @@
|
|||||||
|
# [5.2.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.3...v5.2.0-dev.4) (2024-11-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Playback speed:** Allow long press 2x speed when using custom playback speeds ([#3990](https://github.com/ReVanced/revanced-patches/issues/3990)) ([79a543a](https://github.com/ReVanced/revanced-patches/commit/79a543a57470638f983862c61270e046f3ac5cb7))
|
||||||
|
|
||||||
|
# [5.2.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.2...v5.2.0-dev.3) (2024-11-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **VSCO:** Remove non functional `Unlock pro` patch ([4fddb19](https://github.com/ReVanced/revanced-patches/commit/4fddb1930bc7adeee3b60ae9cd346b143e88bd42))
|
||||||
|
|
||||||
|
# [5.2.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.1...v5.2.0-dev.2) (2024-11-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Settings:** Show navigation back button in setting sub menus ([#3991](https://github.com/ReVanced/revanced-patches/issues/3991)) ([e61686c](https://github.com/ReVanced/revanced-patches/commit/e61686c1039ae29e443273e4da4ec63956216841))
|
||||||
|
|
||||||
# [5.2.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.1.1-dev.2...v5.2.0-dev.1) (2024-11-25)
|
# [5.2.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.1.1-dev.2...v5.2.0-dev.1) (2024-11-25)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,33 @@
|
|||||||
package app.revanced.extension.shared.settings.preference;
|
package app.revanced.extension.shared.settings.preference;
|
||||||
|
|
||||||
|
import static app.revanced.extension.shared.StringRef.str;
|
||||||
|
import static app.revanced.extension.shared.Utils.getResourceIdentifier;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.*;
|
import android.preference.*;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toolbar;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
import app.revanced.extension.shared.Utils;
|
import app.revanced.extension.shared.Utils;
|
||||||
import app.revanced.extension.shared.settings.BaseSettings;
|
import app.revanced.extension.shared.settings.BaseSettings;
|
||||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||||
import app.revanced.extension.shared.settings.Setting;
|
import app.revanced.extension.shared.settings.Setting;
|
||||||
|
import app.revanced.extension.youtube.ThemeHelper;
|
||||||
import static app.revanced.extension.shared.StringRef.str;
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
||||||
@@ -71,6 +83,15 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@SuppressLint("UseCompatLoadingForDrawables")
|
||||||
|
public static Drawable getBackButtonDrawable() {
|
||||||
|
final int backButtonResource = getResourceIdentifier(ThemeHelper.isDarkTheme()
|
||||||
|
? "yt_outline_arrow_left_white_24"
|
||||||
|
: "yt_outline_arrow_left_black_24",
|
||||||
|
"drawable");
|
||||||
|
return Utils.getContext().getResources().getDrawable(backButtonResource);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize this instance, and do any custom behavior.
|
* Initialize this instance, and do any custom behavior.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -98,7 +119,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
showingUserDialogMessage = true;
|
showingUserDialogMessage = true;
|
||||||
new AlertDialog.Builder(context)
|
new AlertDialog.Builder(context)
|
||||||
.setTitle(confirmDialogTitle)
|
.setTitle(confirmDialogTitle)
|
||||||
.setMessage(setting.userDialogMessage.toString())
|
.setMessage(Objects.requireNonNull(setting.userDialogMessage).toString())
|
||||||
.setPositiveButton(android.R.string.ok, (dialog, id) -> {
|
.setPositiveButton(android.R.string.ok, (dialog, id) -> {
|
||||||
if (setting.rebootApp) {
|
if (setting.rebootApp) {
|
||||||
showRestartDialog(context);
|
showRestartDialog(context);
|
||||||
@@ -261,6 +282,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
// causes a callback to the listener even though nothing changed.
|
// causes a callback to the listener even though nothing changed.
|
||||||
initialize();
|
initialize();
|
||||||
updateUIToSettingValues();
|
updateUIToSettingValues();
|
||||||
|
setPreferenceScreenToolbar(getPreferenceScreen());
|
||||||
|
|
||||||
preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(listener);
|
preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(listener);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
@@ -273,4 +295,44 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener);
|
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener);
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setPreferenceScreenToolbar(PreferenceScreen parentScreen) {
|
||||||
|
for (int i = 0, preferenceCount = parentScreen.getPreferenceCount(); i < preferenceCount; i++) {
|
||||||
|
Preference childPreference = parentScreen.getPreference(i);
|
||||||
|
if (childPreference instanceof PreferenceScreen) {
|
||||||
|
// Recursively set sub preferences.
|
||||||
|
setPreferenceScreenToolbar((PreferenceScreen) childPreference);
|
||||||
|
|
||||||
|
childPreference.setOnPreferenceClickListener(
|
||||||
|
childScreen -> {
|
||||||
|
Dialog preferenceScreenDialog = ((PreferenceScreen) childScreen).getDialog();
|
||||||
|
ViewGroup rootView = (ViewGroup) preferenceScreenDialog
|
||||||
|
.findViewById(android.R.id.content)
|
||||||
|
.getParent();
|
||||||
|
|
||||||
|
Toolbar toolbar = new Toolbar(childScreen.getContext());
|
||||||
|
toolbar.setTitle(childScreen.getTitle());
|
||||||
|
toolbar.setNavigationIcon(getBackButtonDrawable());
|
||||||
|
toolbar.setNavigationOnClickListener(view -> preferenceScreenDialog.dismiss());
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
final int margin = (int) TypedValue.applyDimension(
|
||||||
|
TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()
|
||||||
|
);
|
||||||
|
toolbar.setTitleMargin(margin, 0, margin, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextView toolbarTextView = Utils.getChildView(toolbar,
|
||||||
|
true, TextView.class::isInstance);
|
||||||
|
if (toolbarTextView != null) {
|
||||||
|
toolbarTextView.setTextColor(ThemeHelper.getForegroundColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
rootView.addView(toolbar, 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,4 +82,12 @@ public class ThemeHelper {
|
|||||||
}
|
}
|
||||||
return Utils.getResourceColor(colorString);
|
return Utils.getResourceColor(colorString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getBackgroundColor() {
|
||||||
|
return isDarkTheme() ? getDarkThemeColor() : getLightThemeColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getForegroundColor() {
|
||||||
|
return isDarkTheme() ? getLightThemeColor() : getDarkThemeColor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package app.revanced.extension.youtube.patches;
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import app.revanced.extension.youtube.patches.playback.speed.RememberPlaybackSpeedPatch;
|
|
||||||
import app.revanced.extension.youtube.shared.VideoState;
|
|
||||||
import app.revanced.extension.shared.Logger;
|
|
||||||
import app.revanced.extension.shared.Utils;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.shared.Utils;
|
||||||
|
import app.revanced.extension.youtube.shared.VideoState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hooking class for the current playing video.
|
* Hooking class for the current playing video.
|
||||||
* @noinspection unused
|
* @noinspection unused
|
||||||
@@ -120,6 +120,16 @@ public final class VideoInformation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static void videoSpeedChanged(float currentVideoSpeed) {
|
||||||
|
if (playbackSpeed != currentVideoSpeed) {
|
||||||
|
Logger.printDebug(() -> "Video speed changed: " + currentVideoSpeed);
|
||||||
|
playbackSpeed = currentVideoSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
* Called when user selects a playback speed.
|
* Called when user selects a playback speed.
|
||||||
@@ -131,18 +141,6 @@ public final class VideoInformation {
|
|||||||
playbackSpeed = userSelectedPlaybackSpeed;
|
playbackSpeed = userSelectedPlaybackSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides the current playback speed.
|
|
||||||
* <p>
|
|
||||||
* <b> Used exclusively by {@link RememberPlaybackSpeedPatch} </b>
|
|
||||||
*/
|
|
||||||
public static void overridePlaybackSpeed(float speedOverride) {
|
|
||||||
if (playbackSpeed != speedOverride) {
|
|
||||||
Logger.printDebug(() -> "Overriding playback speed to: " + speedOverride);
|
|
||||||
playbackSpeed = speedOverride;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ public final class RememberPlaybackSpeedPatch {
|
|||||||
|
|
||||||
private static final long TOAST_DELAY_MILLISECONDS = 750;
|
private static final long TOAST_DELAY_MILLISECONDS = 750;
|
||||||
|
|
||||||
|
private static volatile boolean newVideoStarted;
|
||||||
|
|
||||||
private static long lastTimeSpeedChanged;
|
private static long lastTimeSpeedChanged;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,7 +21,7 @@ public final class RememberPlaybackSpeedPatch {
|
|||||||
*/
|
*/
|
||||||
public static void newVideoStarted(VideoInformation.PlaybackController ignoredPlayerController) {
|
public static void newVideoStarted(VideoInformation.PlaybackController ignoredPlayerController) {
|
||||||
Logger.printDebug(() -> "newVideoStarted");
|
Logger.printDebug(() -> "newVideoStarted");
|
||||||
VideoInformation.overridePlaybackSpeed(Settings.PLAYBACK_SPEED_DEFAULT.get());
|
newVideoStarted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,42 +31,56 @@ public final class RememberPlaybackSpeedPatch {
|
|||||||
* @param playbackSpeed The playback speed the user selected
|
* @param playbackSpeed The playback speed the user selected
|
||||||
*/
|
*/
|
||||||
public static void userSelectedPlaybackSpeed(float playbackSpeed) {
|
public static void userSelectedPlaybackSpeed(float playbackSpeed) {
|
||||||
if (Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED.get()) {
|
try {
|
||||||
// With the 0.05x menu, if the speed is set by integrations to higher than 2.0x
|
if (Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED.get()) {
|
||||||
// then the menu will allow increasing without bounds but the max speed is
|
// With the 0.05x menu, if the speed is set by integrations to higher than 2.0x
|
||||||
// still capped to under 8.0x.
|
// then the menu will allow increasing without bounds but the max speed is
|
||||||
playbackSpeed = Math.min(playbackSpeed, CustomPlaybackSpeedPatch.PLAYBACK_SPEED_MAXIMUM - 0.05f);
|
// still capped to under 8.0x.
|
||||||
|
playbackSpeed = Math.min(playbackSpeed, CustomPlaybackSpeedPatch.PLAYBACK_SPEED_MAXIMUM - 0.05f);
|
||||||
|
|
||||||
// Prevent toast spamming if using the 0.05x adjustments.
|
// Prevent toast spamming if using the 0.05x adjustments.
|
||||||
// Show exactly one toast after the user stops interacting with the speed menu.
|
// Show exactly one toast after the user stops interacting with the speed menu.
|
||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
lastTimeSpeedChanged = now;
|
lastTimeSpeedChanged = now;
|
||||||
|
|
||||||
final float finalPlaybackSpeed = playbackSpeed;
|
final float finalPlaybackSpeed = playbackSpeed;
|
||||||
Utils.runOnMainThreadDelayed(() -> {
|
Utils.runOnMainThreadDelayed(() -> {
|
||||||
if (lastTimeSpeedChanged != now) {
|
if (lastTimeSpeedChanged != now) {
|
||||||
// The user made additional speed adjustments and this call is outdated.
|
// The user made additional speed adjustments and this call is outdated.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.PLAYBACK_SPEED_DEFAULT.get() == finalPlaybackSpeed) {
|
if (Settings.PLAYBACK_SPEED_DEFAULT.get() == finalPlaybackSpeed) {
|
||||||
// User changed to a different speed and immediately changed back.
|
// User changed to a different speed and immediately changed back.
|
||||||
// Or the user is going past 8.0x in the glitched out 0.05x menu.
|
// Or the user is going past 8.0x in the glitched out 0.05x menu.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Settings.PLAYBACK_SPEED_DEFAULT.save(finalPlaybackSpeed);
|
Settings.PLAYBACK_SPEED_DEFAULT.save(finalPlaybackSpeed);
|
||||||
|
|
||||||
Utils.showToastLong(str("revanced_remember_playback_speed_toast", (finalPlaybackSpeed + "x")));
|
Utils.showToastLong(str("revanced_remember_playback_speed_toast", (finalPlaybackSpeed + "x")));
|
||||||
}, TOAST_DELAY_MILLISECONDS);
|
}, TOAST_DELAY_MILLISECONDS);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "userSelectedPlaybackSpeed failure", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
* Overrides the video speed. Called after video loads, and immediately after user selects a different playback speed
|
* Overrides the video speed. Called after video loads,
|
||||||
|
* and immediately after the user selects a different playback speed.
|
||||||
*/
|
*/
|
||||||
public static float getPlaybackSpeedOverride() {
|
public static float getPlaybackSpeedOverride() {
|
||||||
return VideoInformation.getPlaybackSpeed();
|
if (newVideoStarted) {
|
||||||
|
newVideoStarted = false;
|
||||||
|
|
||||||
|
final float defaultSpeed = Settings.PLAYBACK_SPEED_DEFAULT.get();
|
||||||
|
if (defaultSpeed > 0) {
|
||||||
|
return defaultSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.shared.settings.preference.AbstractPreferenceFragment;
|
||||||
import app.revanced.extension.youtube.ThemeHelper;
|
import app.revanced.extension.youtube.ThemeHelper;
|
||||||
import app.revanced.extension.youtube.settings.preference.ReVancedPreferenceFragment;
|
import app.revanced.extension.youtube.settings.preference.ReVancedPreferenceFragment;
|
||||||
import app.revanced.extension.youtube.settings.preference.ReturnYouTubeDislikePreferenceFragment;
|
import app.revanced.extension.youtube.settings.preference.ReturnYouTubeDislikePreferenceFragment;
|
||||||
@@ -39,7 +40,7 @@ public class LicenseActivityHook {
|
|||||||
|
|
||||||
PreferenceFragment fragment;
|
PreferenceFragment fragment;
|
||||||
String toolbarTitleResourceName;
|
String toolbarTitleResourceName;
|
||||||
String dataString = licenseActivity.getIntent().getDataString();
|
String dataString = Objects.requireNonNull(licenseActivity.getIntent().getDataString());
|
||||||
switch (dataString) {
|
switch (dataString) {
|
||||||
case "revanced_sb_settings_intent":
|
case "revanced_sb_settings_intent":
|
||||||
toolbarTitleResourceName = "revanced_sb_settings_title";
|
toolbarTitleResourceName = "revanced_sb_settings_title";
|
||||||
@@ -59,12 +60,14 @@ public class LicenseActivityHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setToolbarTitle(licenseActivity, toolbarTitleResourceName);
|
setToolbarTitle(licenseActivity, toolbarTitleResourceName);
|
||||||
|
|
||||||
|
//noinspection deprecation
|
||||||
licenseActivity.getFragmentManager()
|
licenseActivity.getFragmentManager()
|
||||||
.beginTransaction()
|
.beginTransaction()
|
||||||
.replace(getResourceIdentifier("revanced_settings_fragments", "id"), fragment)
|
.replace(getResourceIdentifier("revanced_settings_fragments", "id"), fragment)
|
||||||
.commit();
|
.commit();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "onCreate failure", ex);
|
Logger.printException(() -> "initialize failure", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,11 +83,7 @@ public class LicenseActivityHook {
|
|||||||
ViewGroup toolbar = activity.findViewById(getToolbarResourceId());
|
ViewGroup toolbar = activity.findViewById(getToolbarResourceId());
|
||||||
ImageButton imageButton = Objects.requireNonNull(getChildView(toolbar, false,
|
ImageButton imageButton = Objects.requireNonNull(getChildView(toolbar, false,
|
||||||
view -> view instanceof ImageButton));
|
view -> view instanceof ImageButton));
|
||||||
final int backButtonResource = getResourceIdentifier(ThemeHelper.isDarkTheme()
|
imageButton.setImageDrawable(AbstractPreferenceFragment.getBackButtonDrawable());
|
||||||
? "yt_outline_arrow_left_white_24"
|
|
||||||
: "yt_outline_arrow_left_black_24",
|
|
||||||
"drawable");
|
|
||||||
imageButton.setImageDrawable(activity.getResources().getDrawable(backButtonResource));
|
|
||||||
imageButton.setOnClickListener(view -> activity.onBackPressed());
|
imageButton.setOnClickListener(view -> activity.onBackPressed());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
|
|||||||
org.gradle.parallel = true
|
org.gradle.parallel = true
|
||||||
android.useAndroidX = true
|
android.useAndroidX = true
|
||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 5.2.0-dev.1
|
version = 5.2.0-dev.4
|
||||||
|
|||||||
@@ -1370,11 +1370,9 @@ public final class app/revanced/patches/youtube/shared/FingerprintsKt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/video/information/VideoInformationPatchKt {
|
public final class app/revanced/patches/youtube/video/information/VideoInformationPatchKt {
|
||||||
public static final fun getSetPlaybackSpeedClassFieldReference ()Ljava/lang/String;
|
|
||||||
public static final fun getSetPlaybackSpeedContainerClassFieldReference ()Ljava/lang/String;
|
|
||||||
public static final fun getSetPlaybackSpeedMethodReference ()Ljava/lang/String;
|
|
||||||
public static final fun getVideoInformationPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getVideoInformationPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
public static final fun userSelectedPlaybackSpeedHook (Ljava/lang/String;Ljava/lang/String;)V
|
public static final fun userSelectedPlaybackSpeedHook (Ljava/lang/String;Ljava/lang/String;)V
|
||||||
|
public static final fun videoSpeedChangedHook (Ljava/lang/String;Ljava/lang/String;)V
|
||||||
public static final fun videoTimeHook (Ljava/lang/String;Ljava/lang/String;)V
|
public static final fun videoTimeHook (Ljava/lang/String;Ljava/lang/String;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package app.revanced.patches.vsco.misc.pro
|
|||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
|
||||||
|
@Deprecated("This patch is deprecated because it does not work anymore and will be removed in the future.")
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val unlockProPatch = bytecodePatch(
|
val unlockProPatch = bytecodePatch(
|
||||||
name = "Unlock pro",
|
|
||||||
description = "Unlocks pro features.",
|
description = "Unlocks pro features.",
|
||||||
) {
|
) {
|
||||||
compatibleWith("com.vsco.cam"("345"))
|
compatibleWith("com.vsco.cam"("345"))
|
||||||
|
|||||||
@@ -135,8 +135,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val miniplayerPatch = bytecodePatch(
|
val miniplayerPatch = bytecodePatch(
|
||||||
name = "Miniplayer",
|
name = "Miniplayer",
|
||||||
description = "Adds options to change the in app minimized player. " +
|
description = "Adds options to change the in app minimized player."
|
||||||
"Patching target 19.16+ adds modern miniplayers.",
|
|
||||||
) {
|
) {
|
||||||
dependsOn(
|
dependsOn(
|
||||||
sharedExtensionPatch,
|
sharedExtensionPatch,
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ import app.revanced.util.getReference
|
|||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.builder.BuilderInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||||
import com.android.tools.smali.dexlib2.iface.Method
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||||
@@ -57,12 +57,16 @@ private lateinit var speedSelectionInsertMethod: MutableMethod
|
|||||||
private var speedSelectionInsertIndex = -1
|
private var speedSelectionInsertIndex = -1
|
||||||
private var speedSelectionValueRegister = -1
|
private var speedSelectionValueRegister = -1
|
||||||
|
|
||||||
|
// Change playback speed method.
|
||||||
|
private lateinit var setPlaybackSpeedMethod: MutableMethod
|
||||||
|
private var setPlaybackSpeedMethodIndex = -1
|
||||||
|
|
||||||
// Used by other patches.
|
// Used by other patches.
|
||||||
lateinit var setPlaybackSpeedContainerClassFieldReference: String
|
internal lateinit var setPlaybackSpeedContainerClassFieldReference: FieldReference
|
||||||
private set
|
private set
|
||||||
lateinit var setPlaybackSpeedClassFieldReference: String
|
internal lateinit var setPlaybackSpeedClassFieldReference: FieldReference
|
||||||
private set
|
private set
|
||||||
lateinit var setPlaybackSpeedMethodReference: String
|
internal lateinit var setPlaybackSpeedMethodReference: MethodReference
|
||||||
private set
|
private set
|
||||||
|
|
||||||
val videoInformationPatch = bytecodePatch(
|
val videoInformationPatch = bytecodePatch(
|
||||||
@@ -164,24 +168,27 @@ val videoInformationPatch = bytecodePatch(
|
|||||||
videoTimeHook(EXTENSION_CLASS_DESCRIPTOR, "setVideoTime")
|
videoTimeHook(EXTENSION_CLASS_DESCRIPTOR, "setVideoTime")
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hook the user playback speed selection
|
* Hook the user playback speed selection.
|
||||||
*/
|
*/
|
||||||
onPlaybackSpeedItemClickFingerprint.method.apply {
|
onPlaybackSpeedItemClickFingerprint.method.apply {
|
||||||
val speedSelectionMethodInstructions = implementation!!.instructions
|
val speedSelectionValueInstructionIndex = indexOfFirstInstructionOrThrow(Opcode.IGET)
|
||||||
val speedSelectionValueInstructionIndex = speedSelectionMethodInstructions.indexOfFirst {
|
|
||||||
it.opcode == Opcode.IGET
|
|
||||||
}
|
|
||||||
legacySpeedSelectionInsertMethod = this
|
legacySpeedSelectionInsertMethod = this
|
||||||
legacySpeedSelectionInsertIndex = speedSelectionValueInstructionIndex + 1
|
legacySpeedSelectionInsertIndex = speedSelectionValueInstructionIndex + 1
|
||||||
legacySpeedSelectionValueRegister =
|
legacySpeedSelectionValueRegister =
|
||||||
getInstruction<TwoRegisterInstruction>(speedSelectionValueInstructionIndex).registerA
|
getInstruction<TwoRegisterInstruction>(speedSelectionValueInstructionIndex).registerA
|
||||||
|
|
||||||
setPlaybackSpeedClassFieldReference =
|
|
||||||
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 1).reference.toString()
|
|
||||||
setPlaybackSpeedMethodReference =
|
setPlaybackSpeedMethodReference =
|
||||||
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference.toString()
|
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference as MethodReference
|
||||||
|
setPlaybackSpeedClassFieldReference =
|
||||||
|
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 1).reference as FieldReference
|
||||||
setPlaybackSpeedContainerClassFieldReference =
|
setPlaybackSpeedContainerClassFieldReference =
|
||||||
getReference(speedSelectionMethodInstructions, -1, Opcode.IF_EQZ)
|
getInstruction<ReferenceInstruction>(indexOfFirstInstructionOrThrow(Opcode.IF_EQZ) - 1).reference as FieldReference
|
||||||
|
|
||||||
|
setPlaybackSpeedMethod =
|
||||||
|
proxy(classes.first { it.type == setPlaybackSpeedMethodReference.definingClass })
|
||||||
|
.mutableClass.methods.first { it.name == setPlaybackSpeedMethodReference.name }
|
||||||
|
setPlaybackSpeedMethodIndex = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle new playback speed menu.
|
// Handle new playback speed menu.
|
||||||
@@ -195,6 +202,7 @@ val videoInformationPatch = bytecodePatch(
|
|||||||
speedSelectionValueRegister = getInstruction<TwoRegisterInstruction>(index).registerA
|
speedSelectionValueRegister = getInstruction<TwoRegisterInstruction>(index).registerA
|
||||||
}
|
}
|
||||||
|
|
||||||
|
videoSpeedChangedHook(EXTENSION_CLASS_DESCRIPTOR, "videoSpeedChanged")
|
||||||
userSelectedPlaybackSpeedHook(EXTENSION_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed")
|
userSelectedPlaybackSpeedHook(EXTENSION_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,9 +303,14 @@ fun videoTimeHook(targetMethodClass: String, targetMethodName: String) =
|
|||||||
"$targetMethodClass->$targetMethodName(J)V",
|
"$targetMethodClass->$targetMethodName(J)V",
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun getReference(instructions: List<BuilderInstruction>, offset: Int, opcode: Opcode) =
|
/**
|
||||||
(instructions[instructions.indexOfFirst { it.opcode == opcode } + offset] as ReferenceInstruction)
|
* Hook when the video speed is changed for any reason _except when the user manually selects a new speed_.
|
||||||
.reference.toString()
|
*/
|
||||||
|
fun videoSpeedChangedHook(targetMethodClass: String, targetMethodName: String) =
|
||||||
|
setPlaybackSpeedMethod.addInstruction(
|
||||||
|
setPlaybackSpeedMethodIndex++,
|
||||||
|
"invoke-static { p1 }, $targetMethodClass->$targetMethodName(F)V"
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook the video speed selected by the user.
|
* Hook the video speed selected by the user.
|
||||||
@@ -312,4 +325,4 @@ fun userSelectedPlaybackSpeedHook(targetMethodClass: String, targetMethodName: S
|
|||||||
speedSelectionInsertIndex++,
|
speedSelectionInsertIndex++,
|
||||||
"invoke-static { v$speedSelectionValueRegister }, $targetMethodClass->$targetMethodName(F)V",
|
"invoke-static { v$speedSelectionValueRegister }, $targetMethodClass->$targetMethodName(F)V",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<resources>
|
<resources>
|
||||||
<app id="shared">
|
<app id="shared">
|
||||||
<patch id="misc.checks.checkEnvironmentPatch">
|
<patch id="misc.checks.checkEnvironmentPatch">
|
||||||
<string name="revanced_check_environment_failed_title">Überprüfungen fehlgeschlagen</string>
|
<string name="revanced_check_environment_failed_title">Überprüfung fehlgeschlagen</string>
|
||||||
<string name="revanced_check_environment_dialog_open_official_source_button">Offizielle Webseite öffnen</string>
|
<string name="revanced_check_environment_dialog_open_official_source_button">Offizielle Webseite öffnen</string>
|
||||||
<string name="revanced_check_environment_dialog_ignore_button">Ignorieren</string>
|
<string name="revanced_check_environment_dialog_ignore_button">Ignorieren</string>
|
||||||
<string name="revanced_check_environment_failed_message"><h5>Diese App wurde offenbar nicht von Ihnen gepatcht.</h5><br>Diese App funktioniert möglicherweise nicht richtig, <b>könnte schädlich oder sogar gefährlich in der Verwendung sein</b>.< br><br>Diese Prüfungen deuten darauf hin, dass diese App vorab gepatcht wurde oder von jemandem bezogen wurde sonst:<br><br><small>%1$s</small><br>Es wird dringend empfohlen, <b>diese App zu deinstallieren und selbst zu patchen</b> um sicherzustellen, dass Sie eine validierte und sichere App verwenden.<p><br>Wenn Sie diese Warnung ignorieren, wird sie nur zweimal angezeigt.</string>
|
<string name="revanced_check_environment_failed_message"><h5>Diese App wurde offenbar nicht von Ihnen gepatcht.</h5><br>Diese App funktioniert möglicherweise nicht richtig, <b>könnte schädlich oder sogar gefährlich in der Verwendung sein</b>.< br><br>Diese Prüfungen deuten darauf hin, dass diese App vorab gepatcht wurde oder von jemandem bezogen wurde sonst:<br><br><small>%1$s</small><br>Es wird dringend empfohlen, <b>diese App zu deinstallieren und selbst zu patchen</b> um sicherzustellen, dass Sie eine validierte und sichere App verwenden.<p><br>Wenn Sie diese Warnung ignorieren, wird sie nur zweimal angezeigt.</string>
|
||||||
|
|||||||
@@ -1045,7 +1045,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_width_dip_summary">Awal pada ukuran layar, dalam piksel</string>
|
<string name="revanced_miniplayer_width_dip_summary">Awal pada ukuran layar, dalam piksel</string>
|
||||||
<string name="revanced_miniplayer_width_dip_invalid_toast">Ukuran piksel harus antara %1$s dan %2$s</string>
|
<string name="revanced_miniplayer_width_dip_invalid_toast">Ukuran piksel harus antara %1$s dan %2$s</string>
|
||||||
<string name="revanced_miniplayer_opacity_title">Opasitas hamparan</string>
|
<string name="revanced_miniplayer_opacity_title">Opasitas hamparan</string>
|
||||||
<string name="revanced_miniplayer_opacity_summary">Nilai opasitas antara 0-100, di mana 0 adalah transparan</string>
|
<string name="revanced_miniplayer_opacity_summary">Nilai opasitas antara 0-100, dimana 0 adalah transparan</string>
|
||||||
<string name="revanced_miniplayer_opacity_invalid_toast">Opasitas hamparan pemutar mini antara 0-100</string>
|
<string name="revanced_miniplayer_opacity_invalid_toast">Opasitas hamparan pemutar mini antara 0-100</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.theme.themePatch">
|
<patch id="layout.theme.themePatch">
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1012,6 +1012,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_type_title">Loại trình phát thu nhỏ</string>
|
<string name="revanced_miniplayer_type_title">Loại trình phát thu nhỏ</string>
|
||||||
<string name="revanced_miniplayer_type_entry_0">Đã tắt</string>
|
<string name="revanced_miniplayer_type_entry_0">Đã tắt</string>
|
||||||
<string name="revanced_miniplayer_type_entry_1">Nguyên bản</string>
|
<string name="revanced_miniplayer_type_entry_1">Nguyên bản</string>
|
||||||
|
<string name="revanced_miniplayer_type_entry_2"></string>
|
||||||
<string name="revanced_miniplayer_type_entry_3">Máy tính bảng</string>
|
<string name="revanced_miniplayer_type_entry_3">Máy tính bảng</string>
|
||||||
<string name="revanced_miniplayer_type_entry_4">Hiện đại 1</string>
|
<string name="revanced_miniplayer_type_entry_4">Hiện đại 1</string>
|
||||||
<string name="revanced_miniplayer_type_entry_5">Hiện đại 2</string>
|
<string name="revanced_miniplayer_type_entry_5">Hiện đại 2</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user