mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-04-29 22:24:27 +02:00
chore: Merge branch dev
to main
(#4686)
This commit is contained in:
commit
aaa826607e
14
CHANGELOG.md
14
CHANGELOG.md
@ -1,3 +1,17 @@
|
||||
# [5.18.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.18.0-dev.1...v5.18.0-dev.2) (2025-03-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Spotify:** Ignore optional attributes if not present ([#4688](https://github.com/ReVanced/revanced-patches/issues/4688)) ([84f5854](https://github.com/ReVanced/revanced-patches/commit/84f585492e4be3604c6c7680ffb3bebcea5a675f))
|
||||
|
||||
# [5.18.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.17.0...v5.18.0-dev.1) (2025-03-28)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube:** Support version `20.07.39` ([#4677](https://github.com/ReVanced/revanced-patches/issues/4677)) ([c1379f6](https://github.com/ReVanced/revanced-patches/commit/c1379f6e520c683d2c9d6a490a69ca542168b3b3))
|
||||
|
||||
# [5.17.0](https://github.com/ReVanced/revanced-patches/compare/v5.16.1...v5.17.0) (2025-03-28)
|
||||
|
||||
|
||||
|
@ -122,6 +122,21 @@ public class SpoofVideoStreamsPatch {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
* Turns off a feature flag that interferes with video playback.
|
||||
*/
|
||||
public static boolean usePlaybackStartFeatureFlag(boolean original) {
|
||||
if (original) {
|
||||
Logger.printDebug(() -> "usePlaybackStartFeatureFlag is set on");
|
||||
}
|
||||
|
||||
if (!SPOOF_STREAMING_DATA) {
|
||||
return original;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
|
@ -1,54 +1,87 @@
|
||||
package app.revanced.extension.spotify.misc;
|
||||
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
|
||||
import com.spotify.remoteconfig.internal.AccountAttribute;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
|
||||
/**
|
||||
* @noinspection unused
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public final class UnlockPremiumPatch {
|
||||
|
||||
private static final Map<String, Object> OVERRIDES = new HashMap<>() {{
|
||||
// Disables player and app ads.
|
||||
put("ads", false);
|
||||
// Works along on-demand, allows playing any song without restriction.
|
||||
put("player-license", "premium");
|
||||
// Disables shuffle being initially enabled when first playing a playlist.
|
||||
put("shuffle", false);
|
||||
// Allows playing any song on-demand, without a shuffled order.
|
||||
put("on-demand", true);
|
||||
// Make sure playing songs is not disabled remotely and playlists show up.
|
||||
put("streaming", true);
|
||||
// Allows adding songs to queue and removes the smart shuffle mode restriction,
|
||||
// allowing to pick any of the other modes.
|
||||
put("pick-and-shuffle", false);
|
||||
// Disables shuffle-mode streaming-rule, which forces songs to be played shuffled
|
||||
// and breaks the player when other patches are applied.
|
||||
put("streaming-rules", "");
|
||||
// Enables premium UI in settings and removes the premium button in the nav-bar.
|
||||
put("nft-disabled", "1");
|
||||
// Enable Cross-Platform Spotify Car Thing.
|
||||
put("can_use_superbird", true);
|
||||
// Removes the premium button in the nav-bar for tablet users.
|
||||
put("tablet-free", false);
|
||||
}};
|
||||
private static class OverrideAttribute {
|
||||
/**
|
||||
* Account attribute key.
|
||||
*/
|
||||
final String key;
|
||||
|
||||
/**
|
||||
* Override value.
|
||||
*/
|
||||
final Object overrideValue;
|
||||
|
||||
/**
|
||||
* If this attribute is expected to be present in all situations.
|
||||
* If false, then no error is raised if the attribute is missing.
|
||||
*/
|
||||
final boolean isExpected;
|
||||
|
||||
OverrideAttribute(String key, Object overrideValue) {
|
||||
this(key, overrideValue, true);
|
||||
}
|
||||
|
||||
OverrideAttribute(String key, Object overrideValue, boolean isExpected) {
|
||||
this.key = Objects.requireNonNull(key);
|
||||
this.overrideValue = Objects.requireNonNull(overrideValue);
|
||||
this.isExpected = isExpected;
|
||||
}
|
||||
}
|
||||
|
||||
private static final List<OverrideAttribute> OVERRIDES = List.of(
|
||||
// Disables player and app ads.
|
||||
new OverrideAttribute("ads", FALSE),
|
||||
// Works along on-demand, allows playing any song without restriction.
|
||||
new OverrideAttribute("player-license", "premium"),
|
||||
// Disables shuffle being initially enabled when first playing a playlist.
|
||||
new OverrideAttribute("shuffle", FALSE),
|
||||
// Allows playing any song on-demand, without a shuffled order.
|
||||
new OverrideAttribute("on-demand", TRUE),
|
||||
// Make sure playing songs is not disabled remotely and playlists show up.
|
||||
new OverrideAttribute("streaming", TRUE),
|
||||
// Allows adding songs to queue and removes the smart shuffle mode restriction,
|
||||
// allowing to pick any of the other modes.
|
||||
new OverrideAttribute("pick-and-shuffle", FALSE),
|
||||
// Disables shuffle-mode streaming-rule, which forces songs to be played shuffled
|
||||
// and breaks the player when other patches are applied.
|
||||
new OverrideAttribute("streaming-rules", ""),
|
||||
// Enables premium UI in settings and removes the premium button in the nav-bar.
|
||||
new OverrideAttribute("nft-disabled", "1"),
|
||||
// Enable Spotify Car Thing hardware device.
|
||||
// Device is discontinued and no longer works with the latest releases,
|
||||
// but it might still work with older app targets.
|
||||
new OverrideAttribute("can_use_superbird", TRUE, false),
|
||||
// Removes the premium button in the nav-bar for tablet users.
|
||||
new OverrideAttribute("tablet-free", FALSE, false)
|
||||
);
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void overrideAttribute(Map<String, AccountAttribute> attributes) {
|
||||
try {
|
||||
for (var entry : OVERRIDES.entrySet()) {
|
||||
var key = entry.getKey();
|
||||
var attribute = attributes.get(key);
|
||||
for (var override : OVERRIDES) {
|
||||
var attribute = attributes.get(override.key);
|
||||
if (attribute == null) {
|
||||
Logger.printException(() -> "Account attribute not found: " + key);
|
||||
if (override.isExpected) {
|
||||
Logger.printException(() -> "''" + override.key + "' expected but not found");
|
||||
}
|
||||
} else {
|
||||
attribute.value_ = entry.getValue();
|
||||
attribute.value_ = override.overrideValue;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
|
@ -2,7 +2,7 @@ package app.revanced.extension.youtube.patches;
|
||||
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
|
||||
/** @noinspection unused*/
|
||||
@SuppressWarnings("unused")
|
||||
public class DisableResumingStartupShortsPlayerPatch {
|
||||
|
||||
/**
|
||||
@ -11,4 +11,11 @@ public class DisableResumingStartupShortsPlayerPatch {
|
||||
public static boolean disableResumingStartupShortsPlayer() {
|
||||
return Settings.DISABLE_RESUMING_SHORTS_PLAYER.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static boolean disableResumingStartupShortsPlayer(boolean original) {
|
||||
return original && !Settings.DISABLE_RESUMING_SHORTS_PLAYER.get();
|
||||
}
|
||||
}
|
||||
|
@ -43,10 +43,13 @@ public final class MiniplayerPatch {
|
||||
MODERN_2(null, 2),
|
||||
MODERN_3(null, 3),
|
||||
/**
|
||||
* Half broken miniplayer, that might be work in progress or left over abandoned code.
|
||||
* Can force this type by editing the import/export settings.
|
||||
* Works and is functional with 20.03+
|
||||
*/
|
||||
MODERN_4(null, 4);
|
||||
MODERN_4(null, 4),
|
||||
/**
|
||||
* Half broken miniplayer, and in 20.02 and earlier is declared as type 4.
|
||||
*/
|
||||
MODERN_5(null, 5);
|
||||
|
||||
/**
|
||||
* Legacy tablet hook value.
|
||||
@ -126,12 +129,13 @@ public final class MiniplayerPatch {
|
||||
private static final boolean DRAG_AND_DROP_ENABLED =
|
||||
CURRENT_TYPE.isModern() && Settings.MINIPLAYER_DRAG_AND_DROP.get();
|
||||
|
||||
private static final boolean HIDE_EXPAND_CLOSE_ENABLED =
|
||||
Settings.MINIPLAYER_HIDE_EXPAND_CLOSE.get()
|
||||
&& Settings.MINIPLAYER_HIDE_EXPAND_CLOSE.isAvailable();
|
||||
private static final boolean HIDE_OVERLAY_BUTTONS_ENABLED =
|
||||
Settings.MINIPLAYER_HIDE_OVERLAY_BUTTONS.get()
|
||||
&& Settings.MINIPLAYER_HIDE_OVERLAY_BUTTONS.isAvailable();
|
||||
|
||||
private static final boolean HIDE_SUBTEXT_ENABLED =
|
||||
(CURRENT_TYPE == MODERN_1 || CURRENT_TYPE == MODERN_3) && Settings.MINIPLAYER_HIDE_SUBTEXT.get();
|
||||
(CURRENT_TYPE == MODERN_1 || CURRENT_TYPE == MODERN_3 || CURRENT_TYPE == MODERN_4)
|
||||
&& Settings.MINIPLAYER_HIDE_SUBTEXT.get();
|
||||
|
||||
// 19.25 is last version that has forward/back buttons for phones,
|
||||
// but buttons still show for tablets/foldable devices and they don't work well so always hide.
|
||||
@ -139,7 +143,7 @@ public final class MiniplayerPatch {
|
||||
&& (VersionCheckPatch.IS_19_34_OR_GREATER || Settings.MINIPLAYER_HIDE_REWIND_FORWARD.get());
|
||||
|
||||
private static final boolean MINIPLAYER_ROUNDED_CORNERS_ENABLED =
|
||||
Settings.MINIPLAYER_ROUNDED_CORNERS.get();
|
||||
CURRENT_TYPE.isModern() && Settings.MINIPLAYER_ROUNDED_CORNERS.get();
|
||||
|
||||
private static final boolean MINIPLAYER_HORIZONTAL_DRAG_ENABLED =
|
||||
DRAG_AND_DROP_ENABLED && Settings.MINIPLAYER_HORIZONTAL_DRAG.get();
|
||||
@ -172,11 +176,12 @@ public final class MiniplayerPatch {
|
||||
}
|
||||
}
|
||||
|
||||
public static final class MiniplayerHideExpandCloseAvailability implements Setting.Availability {
|
||||
public static final class MiniplayerHideOverlayButtonsAvailability implements Setting.Availability {
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
MiniplayerType type = Settings.MINIPLAYER_TYPE.get();
|
||||
return (!IS_19_20_OR_GREATER && (type == MODERN_1 || type == MODERN_3))
|
||||
return type == MODERN_4
|
||||
|| (!IS_19_20_OR_GREATER && (type == MODERN_1 || type == MODERN_3))
|
||||
|| (!IS_19_26_OR_GREATER && type == MODERN_1
|
||||
&& !Settings.MINIPLAYER_DOUBLE_TAP_ACTION.get() && !Settings.MINIPLAYER_DRAG_AND_DROP.get())
|
||||
|| (IS_19_29_OR_GREATER && type == MODERN_3);
|
||||
@ -227,9 +232,13 @@ public final class MiniplayerPatch {
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void adjustMiniplayerOpacity(ImageView view) {
|
||||
public static void adjustMiniplayerOpacity(View view) {
|
||||
if (CURRENT_TYPE == MODERN_1) {
|
||||
view.setImageAlpha(OPACITY_LEVEL);
|
||||
if (view instanceof ImageView imageView) {
|
||||
imageView.setImageAlpha(OPACITY_LEVEL);
|
||||
} else {
|
||||
Logger.printException(() -> "Unknown miniplayer overlay view: " + view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,7 +256,7 @@ public final class MiniplayerPatch {
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static boolean enableMiniplayerDoubleTapAction(boolean original) {
|
||||
public static boolean getMiniplayerDoubleTapAction(boolean original) {
|
||||
if (CURRENT_TYPE == DEFAULT) {
|
||||
return original;
|
||||
}
|
||||
@ -258,7 +267,7 @@ public final class MiniplayerPatch {
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static boolean enableMiniplayerDragAndDrop(boolean original) {
|
||||
public static boolean getMiniplayerDragAndDrop(boolean original) {
|
||||
if (CURRENT_TYPE == DEFAULT) {
|
||||
return original;
|
||||
}
|
||||
@ -266,13 +275,36 @@ public final class MiniplayerPatch {
|
||||
return DRAG_AND_DROP_ENABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static boolean getRoundedCorners(boolean original) {
|
||||
if (CURRENT_TYPE == DEFAULT) {
|
||||
return original;
|
||||
}
|
||||
|
||||
return MINIPLAYER_ROUNDED_CORNERS_ENABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static boolean setRoundedCorners(boolean original) {
|
||||
if (CURRENT_TYPE.isModern()) {
|
||||
return MINIPLAYER_ROUNDED_CORNERS_ENABLED;
|
||||
public static boolean getHorizontalDrag(boolean original) {
|
||||
if (CURRENT_TYPE == DEFAULT) {
|
||||
return original;
|
||||
}
|
||||
|
||||
return MINIPLAYER_HORIZONTAL_DRAG_ENABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static boolean getMaximizeAnimation(boolean original) {
|
||||
// This must be forced on if horizontal drag is enabled,
|
||||
// otherwise the UI has visual glitches when maximizing the miniplayer.
|
||||
if (MINIPLAYER_HORIZONTAL_DRAG_ENABLED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return original;
|
||||
@ -281,7 +313,7 @@ public final class MiniplayerPatch {
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static int setMiniplayerDefaultSize(int original) {
|
||||
public static int getMiniplayerDefaultSize(int original) {
|
||||
if (CURRENT_TYPE.isModern()) {
|
||||
return MINIPLAYER_SIZE;
|
||||
}
|
||||
@ -289,29 +321,26 @@ public final class MiniplayerPatch {
|
||||
return original;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void hideMiniplayerExpandClose(View view) {
|
||||
Utils.hideViewByRemovingFromParentUnderCondition(HIDE_OVERLAY_BUTTONS_ENABLED, view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static boolean setHorizontalDrag(boolean original) {
|
||||
if (CURRENT_TYPE.isModern()) {
|
||||
return MINIPLAYER_HORIZONTAL_DRAG_ENABLED;
|
||||
public static void hideMiniplayerActionButton(View view) {
|
||||
if (CURRENT_TYPE == MODERN_4) {
|
||||
Utils.hideViewByRemovingFromParentUnderCondition(HIDE_OVERLAY_BUTTONS_ENABLED, view);
|
||||
}
|
||||
|
||||
return original;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void hideMiniplayerExpandClose(ImageView view) {
|
||||
Utils.hideViewByRemovingFromParentUnderCondition(HIDE_EXPAND_CLOSE_ENABLED, view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void hideMiniplayerRewindForward(ImageView view) {
|
||||
public static void hideMiniplayerRewindForward(View view) {
|
||||
Utils.hideViewByRemovingFromParentUnderCondition(HIDE_REWIND_FORWARD_ENABLED, view);
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,15 @@ package app.revanced.extension.youtube.patches;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
|
||||
public class VersionCheckPatch {
|
||||
public static final boolean IS_19_17_OR_GREATER = Utils.getAppVersionName().compareTo("19.17.00") >= 0;
|
||||
public static final boolean IS_19_20_OR_GREATER = Utils.getAppVersionName().compareTo("19.20.00") >= 0;
|
||||
public static final boolean IS_19_21_OR_GREATER = Utils.getAppVersionName().compareTo("19.21.00") >= 0;
|
||||
public static final boolean IS_19_26_OR_GREATER = Utils.getAppVersionName().compareTo("19.26.00") >= 0;
|
||||
public static final boolean IS_19_29_OR_GREATER = Utils.getAppVersionName().compareTo("19.29.00") >= 0;
|
||||
public static final boolean IS_19_34_OR_GREATER = Utils.getAppVersionName().compareTo("19.34.00") >= 0;
|
||||
public static final boolean IS_19_46_OR_GREATER = Utils.getAppVersionName().compareTo("19.46.00") >= 0;
|
||||
private static boolean isVersionOrGreater(String version) {
|
||||
return Utils.getAppVersionName().compareTo(version) >= 0;
|
||||
}
|
||||
|
||||
public static final boolean IS_19_17_OR_GREATER = isVersionOrGreater("19.17.00");
|
||||
public static final boolean IS_19_20_OR_GREATER = isVersionOrGreater("19.20.00");
|
||||
public static final boolean IS_19_21_OR_GREATER = isVersionOrGreater("19.21.00");
|
||||
public static final boolean IS_19_26_OR_GREATER = isVersionOrGreater("19.26.00");
|
||||
public static final boolean IS_19_29_OR_GREATER = isVersionOrGreater("19.29.00");
|
||||
public static final boolean IS_19_34_OR_GREATER = isVersionOrGreater("19.34.00");
|
||||
public static final boolean IS_19_46_OR_GREATER = isVersionOrGreater("19.46.00");
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ public class ReturnYouTubeDislike {
|
||||
private static final Rect middleSeparatorBounds;
|
||||
|
||||
/**
|
||||
* Left separator horizontal padding for Rolling Number layout.
|
||||
* Horizontal padding between the left and middle separator.
|
||||
*/
|
||||
public static final int leftSeparatorShapePaddingPixels;
|
||||
private static final ShapeDrawable leftSeparatorShape;
|
||||
@ -129,7 +129,7 @@ public class ReturnYouTubeDislike {
|
||||
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3.7f, dp);
|
||||
middleSeparatorBounds = new Rect(0, 0, middleSeparatorSize, middleSeparatorSize);
|
||||
|
||||
leftSeparatorShapePaddingPixels = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10.0f, dp);
|
||||
leftSeparatorShapePaddingPixels = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8.4f, dp);
|
||||
|
||||
leftSeparatorShape = new ShapeDrawable(new RectShape());
|
||||
leftSeparatorShape.setBounds(leftSeparatorBounds);
|
||||
@ -238,7 +238,7 @@ public class ReturnYouTubeDislike {
|
||||
String leftSeparatorString = getTextDirectionString();
|
||||
final Spannable leftSeparatorSpan;
|
||||
if (isRollingNumber) {
|
||||
leftSeparatorSpan = new SpannableString(leftSeparatorString);
|
||||
leftSeparatorSpan = new SpannableString(leftSeparatorString);
|
||||
} else {
|
||||
leftSeparatorString += " ";
|
||||
leftSeparatorSpan = new SpannableString(leftSeparatorString);
|
||||
@ -623,7 +623,7 @@ public class ReturnYouTubeDislike {
|
||||
userVote = vote;
|
||||
clearUICache();
|
||||
}
|
||||
|
||||
|
||||
if (future.isDone()) {
|
||||
// Update the fetched vote data.
|
||||
RYDVoteData voteData = getFetchData(MAX_MILLISECONDS_TO_BLOCK_UI_WAITING_FOR_FETCH);
|
||||
|
@ -10,7 +10,6 @@ import static app.revanced.extension.youtube.patches.ChangeFormFactorPatch.FormF
|
||||
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage;
|
||||
import static app.revanced.extension.youtube.patches.ExitFullscreenPatch.FullscreenMode;
|
||||
import static app.revanced.extension.youtube.patches.ForceOriginalAudioPatch.ForceOriginalAudioAvailability;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHideExpandCloseAvailability;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHorizontalDragAvailability;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType;
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MINIMAL;
|
||||
@ -40,6 +39,7 @@ import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.DeArrow
|
||||
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.StillImagesAvailability;
|
||||
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption;
|
||||
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailStillTime;
|
||||
import app.revanced.extension.youtube.patches.MiniplayerPatch;
|
||||
import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
|
||||
|
||||
public class Settings extends BaseSettings {
|
||||
@ -156,7 +156,7 @@ public class Settings extends BaseSettings {
|
||||
public static final BooleanSetting MINIPLAYER_DOUBLE_TAP_ACTION = new BooleanSetting("revanced_miniplayer_double_tap_action", TRUE, true, MINIPLAYER_ANY_MODERN);
|
||||
public static final BooleanSetting MINIPLAYER_DRAG_AND_DROP = new BooleanSetting("revanced_miniplayer_drag_and_drop", TRUE, true, MINIPLAYER_ANY_MODERN);
|
||||
public static final BooleanSetting MINIPLAYER_HORIZONTAL_DRAG = new BooleanSetting("revanced_miniplayer_horizontal_drag", FALSE, true, new MiniplayerHorizontalDragAvailability());
|
||||
public static final BooleanSetting MINIPLAYER_HIDE_EXPAND_CLOSE = new BooleanSetting("revanced_miniplayer_hide_expand_close", FALSE, true, new MiniplayerHideExpandCloseAvailability());
|
||||
public static final BooleanSetting MINIPLAYER_HIDE_OVERLAY_BUTTONS = new BooleanSetting("revanced_miniplayer_hide_overlay_buttons", FALSE, true, new MiniplayerPatch.MiniplayerHideOverlayButtonsAvailability());
|
||||
public static final BooleanSetting MINIPLAYER_HIDE_SUBTEXT = new BooleanSetting("revanced_miniplayer_hide_subtext", FALSE, true, MINIPLAYER_TYPE.availability(MODERN_1, MODERN_3));
|
||||
public static final BooleanSetting MINIPLAYER_HIDE_REWIND_FORWARD = new BooleanSetting("revanced_miniplayer_hide_rewind_forward", TRUE, true, MINIPLAYER_TYPE.availability(MODERN_1));
|
||||
public static final BooleanSetting MINIPLAYER_ROUNDED_CORNERS = new BooleanSetting("revanced_miniplayer_rounded_corners", TRUE, true, MINIPLAYER_ANY_MODERN);
|
||||
|
@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
|
||||
org.gradle.parallel = true
|
||||
android.useAndroidX = true
|
||||
kotlin.code.style = official
|
||||
version = 5.17.0
|
||||
version = 5.18.0-dev.2
|
||||
|
@ -776,8 +776,8 @@ public final class app/revanced/patches/shared/misc/settings/preference/TextPref
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatchKt {
|
||||
public static final fun spoofVideoStreamsPatch (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
public static synthetic fun spoofVideoStreamsPatch$default (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
public static final fun spoofVideoStreamsPatch (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
public static synthetic fun spoofVideoStreamsPatch$default (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/shared/misc/spoof/UserAgentClientSpoofPatchKt {
|
||||
@ -1185,17 +1185,7 @@ public final class app/revanced/patches/youtube/layout/hide/time/HideTimestampPa
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatchKt {
|
||||
public static final fun getFloatyBarButtonTopMargin ()J
|
||||
public static final fun getMiniplayerMaxSize ()J
|
||||
public static final fun getMiniplayerPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
public static final fun getModernMiniplayerClose ()J
|
||||
public static final fun getModernMiniplayerExpand ()J
|
||||
public static final fun getModernMiniplayerForwardButton ()J
|
||||
public static final fun getModernMiniplayerRewindButton ()J
|
||||
public static final fun getPlayerOverlays ()J
|
||||
public static final fun getScrimOverlay ()J
|
||||
public static final fun getYtOutlinePictureInPictureWhite24 ()J
|
||||
public static final fun getYtOutlineXWhite24 ()J
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatchKt {
|
||||
@ -1390,6 +1380,12 @@ public final class app/revanced/patches/youtube/misc/playservice/VersionCheckPat
|
||||
public static final fun is_19_46_or_greater ()Z
|
||||
public static final fun is_19_47_or_greater ()Z
|
||||
public static final fun is_19_49_or_greater ()Z
|
||||
public static final fun is_20_02_or_greater ()Z
|
||||
public static final fun is_20_03_or_greater ()Z
|
||||
public static final fun is_20_05_or_greater ()Z
|
||||
public static final fun is_20_07_or_greater ()Z
|
||||
public static final fun is_20_09_or_greater ()Z
|
||||
public static final fun is_20_10_or_greater ()Z
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatchKt {
|
||||
|
@ -145,7 +145,25 @@ internal val patchIncludedExtensionMethodFingerprint = fingerprint {
|
||||
internal const val MEDIA_FETCH_HOT_CONFIG_FEATURE_FLAG = 45645570L
|
||||
|
||||
internal val mediaFetchHotConfigFingerprint = fingerprint {
|
||||
literal {
|
||||
MEDIA_FETCH_HOT_CONFIG_FEATURE_FLAG
|
||||
}
|
||||
literal { MEDIA_FETCH_HOT_CONFIG_FEATURE_FLAG }
|
||||
}
|
||||
|
||||
// 20.10+
|
||||
internal const val MEDIA_FETCH_HOT_CONFIG_ALTERNATIVE_FEATURE_FLAG = 45683169L
|
||||
|
||||
internal val mediaFetchHotConfigAlternativeFingerprint = fingerprint {
|
||||
literal { MEDIA_FETCH_HOT_CONFIG_ALTERNATIVE_FEATURE_FLAG }
|
||||
}
|
||||
|
||||
// Feature flag that enables different code for parsing and starting video playback,
|
||||
// but it's exact purpose is not known. If this flag is enabled while stream spoofing
|
||||
// then videos will never start playback and load forever.
|
||||
// Flag does not seem to affect playback if spoofing is off.
|
||||
internal const val PLAYBACK_START_CHECK_ENDPOINT_USED_FEATURE_FLAG = 45665455L
|
||||
|
||||
internal val playbackStartDescriptorFeatureFlagFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
parameters()
|
||||
returns("Z")
|
||||
literal { PLAYBACK_START_CHECK_ENDPOINT_USED_FEATURE_FLAG }
|
||||
}
|
||||
|
@ -31,7 +31,9 @@ internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
|
||||
fun spoofVideoStreamsPatch(
|
||||
block: BytecodePatchBuilder.() -> Unit = {},
|
||||
applyMediaFetchHotConfigChanges: BytecodePatchBuilder.() -> Boolean = { false },
|
||||
fixMediaFetchHotConfigChanges: BytecodePatchBuilder.() -> Boolean = { false },
|
||||
fixMediaFetchHotConfigAlternativeChanges: BytecodePatchBuilder.() -> Boolean = { false },
|
||||
fixParsePlaybackResponseFeatureFlag: BytecodePatchBuilder.() -> Boolean = { false },
|
||||
executeBlock: BytecodePatchContext.() -> Unit = {},
|
||||
) = bytecodePatch(
|
||||
name = "Spoof video streams",
|
||||
@ -241,13 +243,27 @@ fun spoofVideoStreamsPatch(
|
||||
|
||||
// region turn off stream config replacement feature flag.
|
||||
|
||||
if (applyMediaFetchHotConfigChanges()) {
|
||||
if (fixMediaFetchHotConfigChanges()) {
|
||||
mediaFetchHotConfigFingerprint.method.insertFeatureFlagBooleanOverride(
|
||||
MEDIA_FETCH_HOT_CONFIG_FEATURE_FLAG,
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
||||
)
|
||||
}
|
||||
|
||||
if (fixMediaFetchHotConfigAlternativeChanges()) {
|
||||
mediaFetchHotConfigAlternativeFingerprint.method.insertFeatureFlagBooleanOverride(
|
||||
MEDIA_FETCH_HOT_CONFIG_ALTERNATIVE_FEATURE_FLAG,
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
||||
)
|
||||
}
|
||||
|
||||
if (fixParsePlaybackResponseFeatureFlag()) {
|
||||
playbackStartDescriptorFeatureFlagFingerprint.method.insertFeatureFlagBooleanOverride(
|
||||
PLAYBACK_START_CHECK_ENDPOINT_USED_FEATURE_FLAG,
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->usePlaybackStartFeatureFlag(Z)Z"
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
executeBlock()
|
||||
|
@ -82,9 +82,8 @@ val hideAdsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -29,9 +29,8 @@ val hideGetPremiumPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -27,9 +27,8 @@ val videoAdsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -57,9 +57,8 @@ val copyVideoUrlPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -28,9 +28,8 @@ val removeViewerDiscretionDialogPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -72,9 +72,8 @@ val downloadsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -27,9 +27,8 @@ val disablePreciseSeekingGesturePatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -30,9 +30,8 @@ val enableSeekbarTappingPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -39,9 +39,8 @@ val enableSlideToSeekPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -33,9 +33,8 @@ val seekbarThumbnailsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -84,9 +84,8 @@ val swipeControlsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -26,9 +26,8 @@ val autoCaptionsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -47,9 +47,8 @@ val customBrandingPatch = resourcePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -45,9 +45,8 @@ val changeHeaderPatch = resourcePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -26,9 +26,8 @@ val hideButtonsPatch = resourcePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -44,9 +44,8 @@ val navigationButtonsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -58,9 +58,8 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -37,9 +37,8 @@ val changeFormFactorPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -63,9 +63,8 @@ val hideEndscreenCardsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -35,9 +35,8 @@ val hideEndScreenSuggestedVideoPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -33,9 +33,8 @@ val disableFullscreenAmbientModePatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -15,7 +15,21 @@ internal val hideShowMoreButtonFingerprint = fingerprint {
|
||||
literal { expandButtonDownId }
|
||||
}
|
||||
|
||||
/**
|
||||
* 20.07+
|
||||
*/
|
||||
internal val parseElementFromBufferFingerprint = fingerprint {
|
||||
parameters("L", "L", "[B", "L", "L")
|
||||
opcodes(
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IGET_BOOLEAN,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
)
|
||||
strings("Failed to parse Element") // String is a partial match.
|
||||
}
|
||||
|
||||
internal val parseElementFromBufferLegacyFingerprint = fingerprint {
|
||||
parameters("L", "L", "[B", "L", "L")
|
||||
opcodes(
|
||||
Opcode.IGET_OBJECT,
|
||||
@ -110,7 +124,6 @@ internal val showFloatingMicrophoneButtonFingerprint = fingerprint {
|
||||
opcodes(
|
||||
Opcode.IGET_BOOLEAN,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.RETURN_VOID,
|
||||
)
|
||||
literal { fabButtonId }
|
||||
}
|
||||
|
@ -21,11 +21,14 @@ import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter
|
||||
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
|
||||
import app.revanced.patches.youtube.misc.navigation.navigationBarHookPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_47_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_07_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
@ -132,6 +135,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
@ -247,29 +251,32 @@ val hideLayoutComponentsPatch = bytecodePatch(
|
||||
|
||||
// region Mix playlists
|
||||
|
||||
parseElementFromBufferFingerprint.method.apply {
|
||||
val startIndex = parseElementFromBufferFingerprint.patternMatch!!.startIndex
|
||||
// Target code is a mess with a lot of register moves.
|
||||
// There is no simple way to find a free register for all versions so this is hard coded.
|
||||
val freeRegister = if (is_19_47_or_greater) 6 else 0
|
||||
val byteArrayParameter = "p3"
|
||||
val conversionContextRegister = getInstruction<TwoRegisterInstruction>(startIndex).registerA
|
||||
val returnEmptyComponentInstruction = instructions.last { it.opcode == Opcode.INVOKE_STATIC }
|
||||
val returnEmptyComponentRegister = (returnEmptyComponentInstruction as FiveRegisterInstruction).registerC
|
||||
(if (is_20_07_or_greater) parseElementFromBufferFingerprint
|
||||
else parseElementFromBufferLegacyFingerprint).let {
|
||||
it.method.apply {
|
||||
// Target code is a mess with a lot of register moves.
|
||||
// There is no simple way to find a free register for all versions so this is hard coded.
|
||||
val freeRegister = if (is_19_47_or_greater) 6 else 0
|
||||
val byteArrayParameter = "p3"
|
||||
val startIndex = it.patternMatch!!.startIndex
|
||||
val conversionContextRegister = getInstruction<TwoRegisterInstruction>(startIndex).registerA
|
||||
val returnEmptyComponentInstruction = instructions.last { it.opcode == Opcode.INVOKE_STATIC }
|
||||
val returnEmptyComponentRegister = (returnEmptyComponentInstruction as FiveRegisterInstruction).registerC
|
||||
|
||||
addInstructionsWithLabels(
|
||||
startIndex + 1,
|
||||
"""
|
||||
invoke-static { v$conversionContextRegister, $byteArrayParameter }, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->filterMixPlaylists(Ljava/lang/Object;[B)Z
|
||||
move-result v$freeRegister
|
||||
if-eqz v$freeRegister, :show
|
||||
move-object v$returnEmptyComponentRegister, p1 # Required for 19.47
|
||||
goto :return_empty_component
|
||||
:show
|
||||
const/4 v$freeRegister, 0x0 # Restore register, required for 19.16
|
||||
""",
|
||||
ExternalLabel("return_empty_component", returnEmptyComponentInstruction),
|
||||
)
|
||||
addInstructionsWithLabels(
|
||||
startIndex + 1,
|
||||
"""
|
||||
invoke-static { v$conversionContextRegister, $byteArrayParameter }, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->filterMixPlaylists(Ljava/lang/Object;[B)Z
|
||||
move-result v$freeRegister
|
||||
if-eqz v$freeRegister, :show
|
||||
move-object v$returnEmptyComponentRegister, p1 # Required for 19.47
|
||||
goto :return_empty_component
|
||||
:show
|
||||
const/4 v$freeRegister, 0x0 # Restore register, required for 19.16
|
||||
""",
|
||||
ExternalLabel("return_empty_component", returnEmptyComponentInstruction),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
@ -345,19 +352,18 @@ val hideLayoutComponentsPatch = bytecodePatch(
|
||||
|
||||
// region hide floating microphone
|
||||
|
||||
showFloatingMicrophoneButtonFingerprint.let {
|
||||
it.method.apply {
|
||||
val startIndex = it.patternMatch!!.startIndex
|
||||
val register = getInstruction<TwoRegisterInstruction>(startIndex).registerA
|
||||
showFloatingMicrophoneButtonFingerprint.method.apply {
|
||||
val literalIndex = indexOfFirstLiteralInstructionOrThrow(fabButtonId)
|
||||
val booleanIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.IGET_BOOLEAN)
|
||||
val register = getInstruction<TwoRegisterInstruction>(booleanIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
startIndex + 1,
|
||||
"""
|
||||
addInstructions(
|
||||
booleanIndex + 1,
|
||||
"""
|
||||
invoke-static { v$register }, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->hideFloatingMicrophoneButton(Z)Z
|
||||
move-result v$register
|
||||
""",
|
||||
)
|
||||
}
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
@ -61,9 +61,8 @@ val hideInfoCardsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -28,9 +28,8 @@ val hidePlayerFlyoutMenuPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -33,9 +33,8 @@ val disableRollingNumberAnimationPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -29,9 +29,8 @@ val hideSeekbarPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -176,9 +176,8 @@ val hideShortsComponentsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -25,9 +25,8 @@ val hideTimestampPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -30,7 +30,7 @@ internal val miniplayerModernAddViewListenerFingerprint = fingerprint {
|
||||
|
||||
internal val miniplayerModernCloseButtonFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("Landroid/widget/ImageView;")
|
||||
returns("L")
|
||||
parameters()
|
||||
literal { modernMiniplayerClose }
|
||||
}
|
||||
@ -62,7 +62,7 @@ internal val miniplayerOnCloseHandlerFingerprint = fingerprint {
|
||||
*/
|
||||
internal val miniplayerModernExpandButtonFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("Landroid/widget/ImageView;")
|
||||
returns("L")
|
||||
parameters()
|
||||
literal { modernMiniplayerExpand }
|
||||
}
|
||||
@ -82,7 +82,7 @@ internal val miniplayerModernExpandCloseDrawablesFingerprint = fingerprint {
|
||||
*/
|
||||
internal val miniplayerModernForwardButtonFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("Landroid/widget/ImageView;")
|
||||
returns("L")
|
||||
parameters()
|
||||
literal { modernMiniplayerForwardButton }
|
||||
}
|
||||
@ -92,7 +92,6 @@ internal val miniplayerModernForwardButtonFingerprint = fingerprint {
|
||||
*/
|
||||
internal val miniplayerModernOverlayViewFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("V")
|
||||
parameters()
|
||||
literal { scrimOverlay }
|
||||
}
|
||||
@ -102,7 +101,7 @@ internal val miniplayerModernOverlayViewFingerprint = fingerprint {
|
||||
*/
|
||||
internal val miniplayerModernRewindButtonFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("Landroid/widget/ImageView;")
|
||||
returns("L")
|
||||
parameters()
|
||||
literal { modernMiniplayerRewindButton }
|
||||
}
|
||||
@ -114,6 +113,13 @@ internal val miniplayerModernViewParentFingerprint = fingerprint {
|
||||
strings("player_overlay_modern_mini_player_controls")
|
||||
}
|
||||
|
||||
internal val miniplayerModernActionButtonFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("L")
|
||||
parameters()
|
||||
literal { modernMiniPlayerOverlayActionButton }
|
||||
}
|
||||
|
||||
internal val miniplayerMinimumSizeFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||
custom { method, _ ->
|
||||
|
@ -34,27 +34,29 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
|
||||
var floatyBarButtonTopMargin = -1L
|
||||
internal var floatyBarButtonTopMargin = -1L
|
||||
private set
|
||||
|
||||
// Only available in 19.15 and upwards.
|
||||
var ytOutlineXWhite24 = -1L
|
||||
internal var ytOutlineXWhite24 = -1L
|
||||
private set
|
||||
var ytOutlinePictureInPictureWhite24 = -1L
|
||||
internal var ytOutlinePictureInPictureWhite24 = -1L
|
||||
private set
|
||||
var scrimOverlay = -1L
|
||||
internal var scrimOverlay = -1L
|
||||
private set
|
||||
var modernMiniplayerClose = -1L
|
||||
internal var modernMiniplayerClose = -1L
|
||||
private set
|
||||
var modernMiniplayerExpand = -1L
|
||||
internal var modernMiniplayerExpand = -1L
|
||||
private set
|
||||
var modernMiniplayerRewindButton = -1L
|
||||
internal var modernMiniplayerRewindButton = -1L
|
||||
private set
|
||||
var modernMiniplayerForwardButton = -1L
|
||||
internal var modernMiniplayerForwardButton = -1L
|
||||
private set
|
||||
var playerOverlays = -1L
|
||||
internal var modernMiniPlayerOverlayActionButton = -1L
|
||||
private set
|
||||
var miniplayerMaxSize = -1L
|
||||
internal var playerOverlays = -1L
|
||||
private set
|
||||
internal var miniplayerMaxSize = -1L
|
||||
private set
|
||||
|
||||
private val miniplayerResourcePatch = resourcePatch {
|
||||
@ -100,6 +102,11 @@ private val miniplayerResourcePatch = resourcePatch {
|
||||
"modern_miniplayer_forward_button",
|
||||
]
|
||||
|
||||
modernMiniPlayerOverlayActionButton = resourceMappings[
|
||||
"id",
|
||||
"modern_miniplayer_overlay_action_button"
|
||||
]
|
||||
|
||||
// Resource id is not used during patching, but is used by extension.
|
||||
// Verify the resource is present while patching.
|
||||
resourceMappings[
|
||||
@ -167,6 +174,7 @@ val miniplayerPatch = bytecodePatch(
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
@ -175,19 +183,25 @@ val miniplayerPatch = bytecodePatch(
|
||||
|
||||
val preferences = mutableSetOf<BasePreference>()
|
||||
|
||||
|
||||
preferences +=
|
||||
if (is_19_43_or_greater) {
|
||||
if (is_20_03_or_greater) {
|
||||
ListPreference(
|
||||
"revanced_miniplayer_type",
|
||||
summaryKey = null,
|
||||
)
|
||||
} else if (is_19_43_or_greater) {
|
||||
ListPreference(
|
||||
"revanced_miniplayer_type",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_miniplayer_type_legacy_19_43_entries",
|
||||
entryValuesKey = "revanced_miniplayer_type_legacy_19_43_entry_values",
|
||||
)
|
||||
} else {
|
||||
ListPreference(
|
||||
"revanced_miniplayer_type",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_miniplayer_type_legacy_entries",
|
||||
entryValuesKey = "revanced_miniplayer_type_legacy_entry_values",
|
||||
entriesKey = "revanced_miniplayer_type_legacy_19_16_entries",
|
||||
entryValuesKey = "revanced_miniplayer_type_legacy_19_16_entry_values",
|
||||
)
|
||||
}
|
||||
|
||||
@ -209,13 +223,13 @@ val miniplayerPatch = bytecodePatch(
|
||||
preferences += SwitchPreference("revanced_miniplayer_hide_subtext")
|
||||
|
||||
preferences += if (is_19_26_or_greater) {
|
||||
SwitchPreference("revanced_miniplayer_hide_expand_close")
|
||||
SwitchPreference("revanced_miniplayer_hide_overlay_buttons")
|
||||
} else {
|
||||
SwitchPreference(
|
||||
key = "revanced_miniplayer_hide_expand_close",
|
||||
titleKey = "revanced_miniplayer_hide_expand_close_legacy_title",
|
||||
summaryOnKey = "revanced_miniplayer_hide_expand_close_legacy_summary_on",
|
||||
summaryOffKey = "revanced_miniplayer_hide_expand_close_legacy_summary_off",
|
||||
key = "revanced_miniplayer_hide_overlay_buttons",
|
||||
titleKey = "revanced_miniplayer_hide_overlay_buttons_legacy_title",
|
||||
summaryOnKey = "revanced_miniplayer_hide_overlay_buttons_legacy_summary_on",
|
||||
summaryOffKey = "revanced_miniplayer_hide_overlay_buttons_legacy_summary_off",
|
||||
)
|
||||
}
|
||||
|
||||
@ -365,7 +379,7 @@ val miniplayerPatch = bytecodePatch(
|
||||
if (is_19_23_or_greater) {
|
||||
miniplayerModernConstructorFingerprint.insertMiniplayerFeatureFlagBooleanOverride(
|
||||
MINIPLAYER_DRAG_DROP_FEATURE_KEY,
|
||||
"enableMiniplayerDragAndDrop",
|
||||
"getMiniplayerDragAndDrop",
|
||||
)
|
||||
}
|
||||
|
||||
@ -382,7 +396,7 @@ val miniplayerPatch = bytecodePatch(
|
||||
|
||||
miniplayerModernConstructorFingerprint.insertMiniplayerFeatureFlagBooleanOverride(
|
||||
MINIPLAYER_DOUBLE_TAP_FEATURE_KEY,
|
||||
"enableMiniplayerDoubleTapAction",
|
||||
"getMiniplayerDoubleTapAction",
|
||||
)
|
||||
}
|
||||
|
||||
@ -398,7 +412,7 @@ val miniplayerPatch = bytecodePatch(
|
||||
addInstructions(
|
||||
targetIndex + 1,
|
||||
"""
|
||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->setMiniplayerDefaultSize(I)I
|
||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getMiniplayerDefaultSize(I)I
|
||||
move-result v$register
|
||||
""",
|
||||
)
|
||||
@ -421,7 +435,7 @@ val miniplayerPatch = bytecodePatch(
|
||||
if (is_19_36_or_greater) {
|
||||
miniplayerModernConstructorFingerprint.insertMiniplayerFeatureFlagBooleanOverride(
|
||||
MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY,
|
||||
"setRoundedCorners",
|
||||
"getRoundedCorners",
|
||||
)
|
||||
}
|
||||
|
||||
@ -433,7 +447,7 @@ val miniplayerPatch = bytecodePatch(
|
||||
|
||||
miniplayerModernConstructorFingerprint.insertMiniplayerFeatureFlagBooleanOverride(
|
||||
MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY,
|
||||
"setHorizontalDrag",
|
||||
"getHorizontalDrag",
|
||||
)
|
||||
}
|
||||
|
||||
@ -473,6 +487,11 @@ val miniplayerPatch = bytecodePatch(
|
||||
modernMiniplayerClose,
|
||||
"hideMiniplayerExpandClose",
|
||||
),
|
||||
Triple(
|
||||
miniplayerModernActionButtonFingerprint,
|
||||
modernMiniPlayerOverlayActionButton,
|
||||
"hideMiniplayerActionButton"
|
||||
),
|
||||
Triple(
|
||||
miniplayerModernRewindButtonFingerprint,
|
||||
modernMiniplayerRewindButton,
|
||||
@ -490,12 +509,25 @@ val miniplayerPatch = bytecodePatch(
|
||||
),
|
||||
).forEach { (fingerprint, literalValue, methodName) ->
|
||||
fingerprint.match(
|
||||
miniplayerModernViewParentFingerprint.classDef,
|
||||
).method.hookInflatedView(
|
||||
literalValue,
|
||||
"Landroid/widget/ImageView;",
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->$methodName(Landroid/widget/ImageView;)V",
|
||||
)
|
||||
miniplayerModernViewParentFingerprint.originalClassDef
|
||||
).method.apply {
|
||||
val literalIndex = indexOfFirstLiteralInstructionOrThrow(literalValue)
|
||||
val checkCastIndex = indexOfFirstInstruction(literalIndex) {
|
||||
opcode == Opcode.CHECK_CAST &&
|
||||
getReference<TypeReference>()?.type == "Landroid/widget/ImageView;"
|
||||
}
|
||||
val viewIndex = if (checkCastIndex >= 0) {
|
||||
checkCastIndex
|
||||
} else {
|
||||
indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||
}
|
||||
val viewRegister = getInstruction<OneRegisterInstruction>(viewIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
viewIndex + 1,
|
||||
"invoke-static { v$viewRegister }, $EXTENSION_CLASS_DESCRIPTOR->$methodName(Landroid/view/View;)V"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
miniplayerModernAddViewListenerFingerprint.match(
|
||||
@ -510,33 +542,40 @@ val miniplayerPatch = bytecodePatch(
|
||||
// Modern 2 uses the same overlay controls as the regular video player,
|
||||
// and the overlay views are added at runtime.
|
||||
// Add a hook to the overlay class, and pass the added views to extension.
|
||||
// Problem is fixed in 19.21+
|
||||
//
|
||||
// NOTE: Modern 2 uses the same video UI as the regular player except resized to smaller.
|
||||
// This patch code could be used to hide other player overlays that do not use Litho.
|
||||
playerOverlaysLayoutFingerprint.classDef.methods.add(
|
||||
ImmutableMethod(
|
||||
YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME,
|
||||
"addView",
|
||||
listOf(
|
||||
ImmutableMethodParameter("Landroid/view/View;", null, null),
|
||||
ImmutableMethodParameter("I", null, null),
|
||||
ImmutableMethodParameter("Landroid/view/ViewGroup\$LayoutParams;", null, null),
|
||||
),
|
||||
"V",
|
||||
AccessFlags.PUBLIC.value,
|
||||
null,
|
||||
null,
|
||||
MutableMethodImplementation(4),
|
||||
).toMutable().apply {
|
||||
addInstructions(
|
||||
"""
|
||||
invoke-super { p0, p1, p2, p3 }, Landroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup${'$'}LayoutParams;)V
|
||||
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->playerOverlayGroupCreated(Landroid/view/View;)V
|
||||
return-void
|
||||
"""
|
||||
)
|
||||
}
|
||||
)
|
||||
if (!is_19_17_or_greater) {
|
||||
playerOverlaysLayoutFingerprint.classDef.methods.add(
|
||||
ImmutableMethod(
|
||||
YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME,
|
||||
"addView",
|
||||
listOf(
|
||||
ImmutableMethodParameter("Landroid/view/View;", null, null),
|
||||
ImmutableMethodParameter("I", null, null),
|
||||
ImmutableMethodParameter(
|
||||
"Landroid/view/ViewGroup\$LayoutParams;",
|
||||
null,
|
||||
null
|
||||
),
|
||||
),
|
||||
"V",
|
||||
AccessFlags.PUBLIC.value,
|
||||
null,
|
||||
null,
|
||||
MutableMethodImplementation(4),
|
||||
).toMutable().apply {
|
||||
addInstructions(
|
||||
"""
|
||||
invoke-super { p0, p1, p2, p3 }, Landroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup${'$'}LayoutParams;)V
|
||||
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->playerOverlayGroupCreated(Landroid/view/View;)V
|
||||
return-void
|
||||
"""
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
@ -25,9 +25,8 @@ val playerPopupPanelsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -16,9 +16,8 @@ val playerControlsBackgroundPatch = resourcePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -25,9 +25,8 @@ internal val exitFullscreenPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -27,6 +27,7 @@ val openVideosFullscreenPatch = bytecodePatch(
|
||||
"com.google.android.youtube"(
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -56,9 +56,8 @@ val customPlayerOverlayOpacityPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -12,6 +12,7 @@ import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter
|
||||
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
|
||||
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_33_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_10_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.addSettingPreference
|
||||
import app.revanced.patches.youtube.misc.settings.newIntent
|
||||
@ -56,9 +57,8 @@ val returnYouTubeDislikePatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
@ -121,7 +121,7 @@ val returnYouTubeDislikePatch = bytecodePatch(
|
||||
val tempRegister: Int
|
||||
val charSequenceRegister: Int
|
||||
|
||||
if (is_19_33_or_greater) {
|
||||
if (is_19_33_or_greater && !is_20_10_or_greater) {
|
||||
insertIndex = indexOfFirstInstructionOrThrow {
|
||||
(opcode == Opcode.INVOKE_STATIC || opcode == Opcode.INVOKE_STATIC_RANGE)
|
||||
&& getReference<MethodReference>()?.returnType == textDataClassType
|
||||
|
@ -33,9 +33,8 @@ val wideSearchbarPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -37,12 +37,25 @@ internal val shortsSeekbarColorFingerprint = fingerprint {
|
||||
literal { reelTimeBarPlayedColorId }
|
||||
}
|
||||
|
||||
internal val playerSeekbarHandleColorFingerprint = fingerprint {
|
||||
internal val playerSeekbarHandle1ColorFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||
parameters("Landroid/content/Context;")
|
||||
literal { ytStaticBrandRedId }
|
||||
custom { method, _ ->
|
||||
method.containsLiteralInstruction(ytTextSecondaryId) &&
|
||||
method.containsLiteralInstruction(ytStaticBrandRedId)
|
||||
}
|
||||
}
|
||||
|
||||
internal val playerSeekbarHandle2ColorFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||
parameters("Landroid/content/Context;")
|
||||
custom { method, _ ->
|
||||
method.containsLiteralInstruction(inlineTimeBarLiveSeekableRangeId) &&
|
||||
method.containsLiteralInstruction(ytStaticBrandRedId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal val watchHistoryMenuUseProgressDrawableFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("V")
|
||||
|
@ -53,6 +53,10 @@ internal var ytYoutubeMagentaColorId = -1L
|
||||
private set
|
||||
internal var ytStaticBrandRedId = -1L
|
||||
private set
|
||||
internal var ytTextSecondaryId = -1L
|
||||
private set
|
||||
internal var inlineTimeBarLiveSeekableRangeId = -1L
|
||||
private set
|
||||
|
||||
internal const val splashSeekbarColorAttributeName = "splash_custom_seekbar_color"
|
||||
|
||||
@ -76,6 +80,18 @@ private val seekbarColorResourcePatch = resourcePatch {
|
||||
"color",
|
||||
"inline_time_bar_played_not_highlighted_color",
|
||||
]
|
||||
ytStaticBrandRedId = resourceMappings[
|
||||
"attr",
|
||||
"ytStaticBrandRed"
|
||||
]
|
||||
ytTextSecondaryId = resourceMappings[
|
||||
"attr",
|
||||
"ytTextSecondary"
|
||||
]
|
||||
inlineTimeBarLiveSeekableRangeId = resourceMappings[
|
||||
"color",
|
||||
"inline_time_bar_live_seekable_range"
|
||||
]
|
||||
|
||||
// Modify the resume playback drawable and replace the progress bar with a custom drawable.
|
||||
document("res/drawable/resume_playback_progressbar_drawable.xml").use { document ->
|
||||
@ -211,7 +227,7 @@ val seekbarColorPatch = bytecodePatch(
|
||||
)
|
||||
|
||||
execute {
|
||||
fun MutableMethod.addColorChangeInstructions(resourceId: Long, methodName: String) {
|
||||
fun MutableMethod.addColorChangeInstructions(resourceId: Long) {
|
||||
val index = indexOfFirstLiteralInstructionOrThrow(resourceId)
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(index, Opcode.MOVE_RESULT)
|
||||
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
@ -219,19 +235,19 @@ val seekbarColorPatch = bytecodePatch(
|
||||
addInstructions(
|
||||
insertIndex + 1,
|
||||
"""
|
||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->$methodName(I)I
|
||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I
|
||||
move-result v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
playerSeekbarColorFingerprint.method.apply {
|
||||
addColorChangeInstructions(inlineTimeBarColorizedBarPlayedColorDarkId, "getVideoPlayerSeekbarColor")
|
||||
addColorChangeInstructions(inlineTimeBarPlayedNotHighlightedColorId, "getVideoPlayerSeekbarColor")
|
||||
addColorChangeInstructions(inlineTimeBarColorizedBarPlayedColorDarkId)
|
||||
addColorChangeInstructions(inlineTimeBarPlayedNotHighlightedColorId)
|
||||
}
|
||||
|
||||
shortsSeekbarColorFingerprint.method.apply {
|
||||
addColorChangeInstructions(reelTimeBarPlayedColorId, "getVideoPlayerSeekbarColor")
|
||||
addColorChangeInstructions(reelTimeBarPlayedColorId)
|
||||
}
|
||||
|
||||
setSeekbarClickedColorFingerprint.originalMethod.let {
|
||||
@ -257,8 +273,11 @@ val seekbarColorPatch = bytecodePatch(
|
||||
|
||||
// 19.25+ changes
|
||||
|
||||
playerSeekbarHandleColorFingerprint.method.apply {
|
||||
addColorChangeInstructions(ytStaticBrandRedId, "getVideoPlayerSeekbarColor")
|
||||
arrayOf(
|
||||
playerSeekbarHandle1ColorFingerprint,
|
||||
playerSeekbarHandle2ColorFingerprint
|
||||
).forEach {
|
||||
it.method.addColorChangeInstructions(ytStaticBrandRedId)
|
||||
}
|
||||
|
||||
// If hiding feed seekbar thumbnails, then turn off the cairo gradient
|
||||
|
@ -37,9 +37,8 @@ val shortsAutoplayPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -45,9 +45,8 @@ val openShortsInRegularPlayerPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -110,9 +110,8 @@ val sponsorBlockPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -62,9 +62,8 @@ val spoofAppVersionPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -33,9 +33,8 @@ val changeStartPagePatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -1,18 +1,22 @@
|
||||
package app.revanced.patches.youtube.layout.startupshortsreset
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_02_or_greater
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.util.addInstructionsAtControlFlowLabel
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
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.reference.MethodReference
|
||||
|
||||
@ -38,6 +42,7 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
@ -48,25 +53,51 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
|
||||
SwitchPreference("revanced_disable_resuming_shorts_player"),
|
||||
)
|
||||
|
||||
userWasInShortsFingerprint.method.apply {
|
||||
val listenableInstructionIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_INTERFACE &&
|
||||
getReference<MethodReference>()?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" &&
|
||||
getReference<MethodReference>()?.name == "isDone"
|
||||
}
|
||||
val freeRegister = getInstruction<OneRegisterInstruction>(listenableInstructionIndex + 1).registerA
|
||||
if (is_20_02_or_greater) {
|
||||
userWasInShortsAlternativeFingerprint.let {
|
||||
it.method.apply {
|
||||
val stringIndex = it.stringMatches!!.first().index
|
||||
val booleanValueIndex = indexOfFirstInstructionReversedOrThrow(stringIndex) {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "booleanValue"
|
||||
}
|
||||
val booleanValueRegister =
|
||||
getInstruction<OneRegisterInstruction>(booleanValueIndex + 1).registerA
|
||||
|
||||
addInstructionsAtControlFlowLabel(
|
||||
listenableInstructionIndex,
|
||||
"""
|
||||
invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z
|
||||
move-result v$freeRegister
|
||||
if-eqz v$freeRegister, :show_startup_shorts_player
|
||||
return-void
|
||||
:show_startup_shorts_player
|
||||
nop
|
||||
""",
|
||||
)
|
||||
addInstructions(
|
||||
booleanValueIndex + 2, """
|
||||
invoke-static {v$booleanValueRegister}, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer(Z)Z
|
||||
move-result v$booleanValueRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
userWasInShortsLegacyFingerprint.method.apply {
|
||||
val listenableInstructionIndex = indexOfFirstInstructionOrThrow {
|
||||
val reference = getReference<MethodReference>()
|
||||
opcode == Opcode.INVOKE_INTERFACE &&
|
||||
reference?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" &&
|
||||
reference.name == "isDone"
|
||||
}
|
||||
val originalInstructionRegister =
|
||||
getInstruction<FiveRegisterInstruction>(listenableInstructionIndex).registerC
|
||||
val freeRegister =
|
||||
getInstruction<OneRegisterInstruction>(listenableInstructionIndex + 1).registerA
|
||||
|
||||
addInstructionsWithLabels(
|
||||
listenableInstructionIndex + 1,
|
||||
"""
|
||||
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z
|
||||
move-result v$freeRegister
|
||||
if-eqz v$freeRegister, :show
|
||||
return-void
|
||||
:show
|
||||
invoke-interface {v$originalInstructionRegister}, Lcom/google/common/util/concurrent/ListenableFuture;->isDone()Z
|
||||
"""
|
||||
)
|
||||
removeInstruction(listenableInstructionIndex)
|
||||
}
|
||||
}
|
||||
|
||||
userWasInShortsConfigFingerprint.method.addInstructions(
|
||||
|
@ -4,7 +4,17 @@ import app.revanced.patcher.fingerprint
|
||||
import app.revanced.util.literal
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val userWasInShortsFingerprint = fingerprint {
|
||||
/**
|
||||
* YouTube 20.02.08 ~
|
||||
*/
|
||||
internal val userWasInShortsAlternativeFingerprint = fingerprint {
|
||||
returns("V")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
parameters("Ljava/lang/Object;")
|
||||
strings("userIsInShorts: ")
|
||||
}
|
||||
|
||||
internal val userWasInShortsLegacyFingerprint = fingerprint {
|
||||
returns("V")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
parameters("Ljava/lang/Object;")
|
||||
|
@ -221,9 +221,8 @@ val themePatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -37,9 +37,8 @@ val alternativeThumbnailsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -31,9 +31,8 @@ val bypassImageRegionRestrictionsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -27,9 +27,8 @@ val announcementsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -28,9 +28,8 @@ val autoRepeatPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -52,9 +52,8 @@ val backgroundPlaybackPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -38,9 +38,8 @@ val enableDebuggingPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -28,9 +28,8 @@ val spoofDeviceDimensionsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -25,9 +25,8 @@ val checkWatchHistoryDomainNameResolutionPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -39,9 +39,8 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -13,9 +13,11 @@ import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
||||
|
||||
val bypassURLRedirectsPatch = bytecodePatch(
|
||||
name = "Bypass URL redirects",
|
||||
@ -37,6 +39,7 @@ val bypassURLRedirectsPatch = bytecodePatch(
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
@ -80,3 +83,8 @@ internal fun Method.findUriParseIndex() = indexOfFirstInstruction {
|
||||
val reference = getReference<MethodReference>()
|
||||
reference?.returnType == "Landroid/net/Uri;" && reference.name == "parse"
|
||||
}
|
||||
|
||||
internal fun Method.findWebViewCheckCastIndex() = indexOfFirstInstruction {
|
||||
val reference = getReference<TypeReference>()
|
||||
opcode == Opcode.CHECK_CAST && reference?.type?.endsWith("/WebviewEndpointOuterClass${'$'}WebviewEndpoint;") == true
|
||||
}
|
||||
|
@ -11,12 +11,21 @@ internal val abUriParserFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("Ljava/lang/Object")
|
||||
parameters("Ljava/lang/Object")
|
||||
strings(
|
||||
"Found entityKey=`",
|
||||
"` that does not contain a PlaylistVideoEntityId message as it's identifier.",
|
||||
)
|
||||
custom { method, _ ->
|
||||
method.findUriParseIndex() >= 0
|
||||
method.findUriParseIndex() >= 0 && method.findWebViewCheckCastIndex() >= 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Target 19.33+
|
||||
*/
|
||||
internal val httpUriParserFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("Landroid/net/Uri")
|
||||
parameters("Ljava/lang/String")
|
||||
strings("https", "://", "https:")
|
||||
custom { methodDef, _ ->
|
||||
methodDef.findUriParseIndex() >= 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,19 +56,6 @@ internal val abUriParserLegacyFingerprint = fingerprint {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Target 19.33+
|
||||
*/
|
||||
internal val httpUriParserFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("Landroid/net/Uri")
|
||||
parameters("Ljava/lang/String")
|
||||
strings("https", "https:", "://")
|
||||
custom { methodDef, _ ->
|
||||
methodDef.findUriParseIndex() >= 0
|
||||
}
|
||||
}
|
||||
|
||||
internal val httpUriParserLegacyFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("Landroid/net/Uri")
|
||||
|
@ -45,9 +45,8 @@ val openLinksExternallyPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -10,7 +10,11 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
* In 19.18+ this resolves to a different method.
|
||||
*/
|
||||
internal val componentContextParserFingerprint = fingerprint {
|
||||
strings("Component was not found %s because it was removed due to duplicate converter bindings.")
|
||||
strings(
|
||||
"TreeNode result must be set.",
|
||||
// String is a partial match and changed slightly in 20.03+
|
||||
"it was removed due to duplicate converter bindings."
|
||||
)
|
||||
}
|
||||
|
||||
internal val lithoFilterFingerprint = fingerprint {
|
||||
|
@ -14,6 +14,7 @@ import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_18_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_05_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
@ -235,7 +236,10 @@ val lithoFilterPatch = bytecodePatch(
|
||||
|
||||
// Turn off native code that handles litho component names. If this feature is on then nearly
|
||||
// all litho components have a null name and identifier/path filtering is completely broken.
|
||||
if (is_19_25_or_greater) {
|
||||
//
|
||||
// Flag was removed in 20.05. It appears a new flag might be used instead (45660109L),
|
||||
// but if the flag is forced on then litho filtering still works correctly.
|
||||
if (is_19_25_or_greater && !is_20_05_or_greater) {
|
||||
lithoComponentNameUpbFeatureFlagFingerprint.method.apply {
|
||||
// Don't use return early, so the debug patch logs if this was originally on.
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.RETURN)
|
||||
|
@ -46,6 +46,18 @@ var is_19_47_or_greater = false
|
||||
private set
|
||||
var is_19_49_or_greater = false
|
||||
private set
|
||||
var is_20_02_or_greater = false
|
||||
private set
|
||||
var is_20_03_or_greater = false
|
||||
private set
|
||||
var is_20_05_or_greater = false
|
||||
private set
|
||||
var is_20_07_or_greater = false
|
||||
private set
|
||||
var is_20_09_or_greater = false
|
||||
private set
|
||||
var is_20_10_or_greater = false
|
||||
private set
|
||||
|
||||
val versionCheckPatch = resourcePatch(
|
||||
description = "Uses the Play Store service version to find the major/minor version of the YouTube target app.",
|
||||
@ -80,5 +92,11 @@ val versionCheckPatch = resourcePatch(
|
||||
is_19_46_or_greater = 244705000 <= playStoreServicesVersion
|
||||
is_19_47_or_greater = 244799000 <= playStoreServicesVersion
|
||||
is_19_49_or_greater = 245005000 <= playStoreServicesVersion
|
||||
is_20_02_or_greater = 250299000 <= playStoreServicesVersion
|
||||
is_20_03_or_greater = 250405000 <= playStoreServicesVersion
|
||||
is_20_05_or_greater = 250605000 <= playStoreServicesVersion
|
||||
is_20_07_or_greater = 250805000 <= playStoreServicesVersion
|
||||
is_20_09_or_greater = 251006000 <= playStoreServicesVersion
|
||||
is_20_10_or_greater = 251105000 <= playStoreServicesVersion
|
||||
}
|
||||
}
|
||||
|
@ -34,9 +34,8 @@ val removeTrackingQueryParameterPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -7,6 +7,8 @@ import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPref
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.shared.misc.spoof.spoofVideoStreamsPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_03_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_10_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
@ -18,9 +20,8 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
@ -31,6 +32,10 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
|
||||
)
|
||||
}, {
|
||||
is_19_34_or_greater
|
||||
}, {
|
||||
is_20_10_or_greater
|
||||
}, {
|
||||
is_20_03_or_greater
|
||||
}, {
|
||||
addResources("youtube", "misc.fix.playback.spoofVideoStreamsPatch")
|
||||
|
||||
|
@ -25,9 +25,8 @@ val zoomHapticsPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -45,9 +45,8 @@ val forceOriginalAudioPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -32,9 +32,8 @@ val disableHdrPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -2,11 +2,65 @@ package app.revanced.patches.youtube.video.playerresponse
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.stringtemplate.v4.compiler.Bytecode.instructions
|
||||
|
||||
/**
|
||||
* For targets 19.25 and later.
|
||||
* For targets 20.10 and later.
|
||||
*/
|
||||
internal val playerParameterBuilderFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("L")
|
||||
parameters(
|
||||
"Ljava/lang/String;", // VideoId.
|
||||
"[B",
|
||||
"Ljava/lang/String;", // Player parameters proto buffer.
|
||||
"Ljava/lang/String;",
|
||||
"I",
|
||||
"Z",
|
||||
"I",
|
||||
"L",
|
||||
"Ljava/util/Set;",
|
||||
"Ljava/lang/String;",
|
||||
"Ljava/lang/String;",
|
||||
"L",
|
||||
"Z", // Appears to indicate if the video id is being opened or is currently playing.
|
||||
"Z",
|
||||
"Z",
|
||||
"Z"
|
||||
)
|
||||
strings("psps")
|
||||
}
|
||||
|
||||
/**
|
||||
* For targets 20.02 to 20.09.
|
||||
*/
|
||||
internal val playerParameterBuilder2002Fingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("L")
|
||||
parameters(
|
||||
"Ljava/lang/String;", // VideoId.
|
||||
"[B",
|
||||
"Ljava/lang/String;", // Player parameters proto buffer.
|
||||
"Ljava/lang/String;",
|
||||
"I",
|
||||
"I",
|
||||
"L", // 19.25+ parameter
|
||||
"Ljava/util/Set;",
|
||||
"Ljava/lang/String;",
|
||||
"Ljava/lang/String;",
|
||||
"L",
|
||||
"Z", // Appears to indicate if the video id is being opened or is currently playing.
|
||||
"Z",
|
||||
"Z",
|
||||
"Z",
|
||||
)
|
||||
strings("psps")
|
||||
}
|
||||
|
||||
/**
|
||||
* For targets 19.25 to 19.50.
|
||||
*/
|
||||
internal val playerParameterBuilder1925Fingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("L")
|
||||
parameters(
|
||||
|
@ -1,11 +1,14 @@
|
||||
package app.revanced.patches.youtube.video.playerresponse
|
||||
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_23_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_02_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_10_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
|
||||
private val hooks = mutableSetOf<Hook>()
|
||||
@ -35,15 +38,21 @@ val playerResponseMethodHookPatch = bytecodePatch {
|
||||
)
|
||||
|
||||
execute {
|
||||
playerResponseMethod = if (is_19_23_or_greater) {
|
||||
val fingerprint : Fingerprint
|
||||
if (is_20_10_or_greater) {
|
||||
parameterIsShortAndOpeningOrPlaying = 13
|
||||
fingerprint = playerParameterBuilderFingerprint
|
||||
} else if (is_20_02_or_greater) {
|
||||
parameterIsShortAndOpeningOrPlaying = 12
|
||||
|
||||
playerParameterBuilderFingerprint
|
||||
fingerprint = playerParameterBuilder2002Fingerprint
|
||||
} else if (is_19_23_or_greater) {
|
||||
parameterIsShortAndOpeningOrPlaying = 12
|
||||
fingerprint = playerParameterBuilder1925Fingerprint
|
||||
} else {
|
||||
parameterIsShortAndOpeningOrPlaying = 11
|
||||
|
||||
playerParameterBuilderLegacyFingerprint
|
||||
}.method
|
||||
fingerprint = playerParameterBuilderLegacyFingerprint
|
||||
}
|
||||
playerResponseMethod = fingerprint.method
|
||||
|
||||
// On some app targets the method has too many registers pushing the parameters past v15.
|
||||
// If needed, move the parameters to 4-bit registers, so they can be passed to the extension.
|
||||
|
@ -27,9 +27,8 @@ val videoQualityPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -32,9 +32,8 @@ val playbackSpeedPatch = bytecodePatch(
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -22,14 +22,6 @@ internal val speedArrayGeneratorFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("[L")
|
||||
parameters("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;")
|
||||
opcodes(
|
||||
Opcode.IF_NEZ,
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.GOTO_16,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
)
|
||||
strings("0.0#")
|
||||
}
|
||||
|
||||
|
@ -1155,6 +1155,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_miniplayer_type_entry_4">حديث 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">حديث 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">حديث 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">الوضع الحديث 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">تمكين الزوايا المستديرة</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">الزوايا مستديرة</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">الزوايا مربعة</string>
|
||||
@ -1174,14 +1175,14 @@ Second \"item\" text"</string>
|
||||
|
||||
يمكن سحب المشغل المصغر خارج الشاشة إلى اليسار أو اليمين"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">تم تعطيل إيماءة السحب الأفقية</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">إخفاء زر الإغلاق</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">تم إخفاء زر الإغلاق</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">يتم عرض زر الإغلاق</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">إخفاء أزرار التوسيع والإغلاق</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"تم إخفاء الأزرار
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">إخفاء أزرار التراكب</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">أزرار التراكب مخفية</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">أزرار التراكب ظاهرة</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">إخفاء زري التوسيع والإغلاق</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"الأزرار مخفية
|
||||
|
||||
مرر للتوسيع أو الإغلاق"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">يتم عرض أزرار التوسيع والإغلاق</string>
|
||||
اسحب للتوسيع أو الإغلاق"</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">زرا التوسيع والإغلاق ظاهران</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">إخفاء النصوص الفرعية</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">تم إخفاء النصوص الفرعية</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">يتم عرض النصوص الفرعية</string>
|
||||
|
@ -1159,14 +1159,6 @@ Kiçik oynadıcı ekranın istənilən küncünə sürüklənə bilər"</string>
|
||||
|
||||
Kiçik oynadıcı ekrandan sola və ya sağa sürüklənə bilər"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Üfüqi sürükləmə jesti qapatıldı</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">\"Bağla\" düyməsini gizlət</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">\"Bağla\" düyməsi gizlidir</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">\"Bağla\" düyməsi göstərilir</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Genişləndir və bağla düymələrini gizlət</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Düymələr gizlidir
|
||||
|
||||
Genişləndirmək və ya bağlamaq üçün sürüşdür"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Genişləndir və bağla düymələri göstərilir</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Alt mətnləri gizlət</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Alt mətnlər gizlədilir</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Alt mətnlər göstərilir</string>
|
||||
|
@ -1156,6 +1156,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_miniplayer_type_entry_4">Сучасны 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">Сучасны 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">Сучасны 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">Сучасны 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">Включить закругленные углы</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Углы закруглены</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Углы квадратные</string>
|
||||
@ -1175,14 +1176,14 @@ Second \"item\" text"</string>
|
||||
|
||||
Міні-прайгравальнік можна перацягнуць за межы экрана ўлева ці ўправа"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Горизонтальный жест перетаскивания отключен</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Скрыть кнопку закрытия</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">Кнопка закрытия скрыта</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Кнопка закрытия отображается</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Схаваць кнопкі разгортвання і закрыцця</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Кнопкі схаваны
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">Схаваць кнопкі накладання</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">Кнопкі накладання схаваныя</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">Кнопкі накладання паказаны</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">Схаваць кнопкі разгортвання і закрыцця</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"Кнопкі схаваныя
|
||||
|
||||
Працягвайце пальцам, каб разгарнуць або закрыць"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Паказваюцца кнопкі разгарнуць і закрыць</string>
|
||||
Правядзіце пальцам, каб разгарнуць ці закрыць"</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">Кнопкі разгортвання і закрыцця паказаны</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Схаваць падтэксты</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Падтэксты схаваныя</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Паказваюцца падтэксты</string>
|
||||
|
@ -1155,6 +1155,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_miniplayer_type_entry_4">Модерен 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">Модерен 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">Модерен 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">Модерен 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">Активирайте заоблени ъгли</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Ъглите са заоблени</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Ъглите са нормални</string>
|
||||
@ -1174,14 +1175,14 @@ Second \"item\" text"</string>
|
||||
|
||||
Мини плейърът може да бъде плъзган извън екрана наляво или надясно"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Жестът за хоризонтално плъзгане е деактивиран</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Скриване на бутона за затваряне</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">Бутонът за затваряне е скрит</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Показан е бутон за затваряне</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Бутони за разширяване и свиване на екрана</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Бутоните са скрити
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">Скриване на бутоните за наслагване</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">Бутоните за наслагване са скрити</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">Бутоните за наслагване са показани</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">Скриване на бутоните за разгъване и затваряне</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"Бутоните са скрити
|
||||
|
||||
Плъзнете, за да разгънете или затворите"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Бутони за разширяване и свиване на екрана са видими</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">Бутоните за разгъване и затваряне са показани</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Екранни текстове, етикети</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Скрити</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Показват се</string>
|
||||
|
@ -1155,6 +1155,7 @@ YouTube সেটিংসে অটো প্লে পরিবর্তন
|
||||
<string name="revanced_miniplayer_type_entry_4">মর্ডান ১</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">মর্ডান ২</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">মর্ডান ৩</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">আধুনিক ৪</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">গোলাকার কোণ সক্ষম করুন</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">কোণগুলি গোলাকার</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">কোণগুলি বর্গাকার</string>
|
||||
@ -1174,14 +1175,14 @@ Miniplayer স্ক্রিনের যেকোনো কোণে টান
|
||||
|
||||
Miniplayer স্ক্রিন থেকে বামে বা ডানে টানা যাবে"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">অনুভূমিক ড্র্যাগ অঙ্গভঙ্গি অক্ষম</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">বন্ধ বোতাম লুকান</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">বন্ধ বোতাম লুকানো আছে</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">বন্ধ বোতাম দেখানো হচ্ছে</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">বিস্তৃত ও বন্ধ করার বোতাম লুকান</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"বোতামগুলি লুকানো হয়
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">ওভারলে বোতাম লুকান</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">ওভারলে বোতাম লুকানো আছে</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">ওভারলে বোতাম দেখানো হয়েছে</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">বিস্তৃত এবং বন্ধ বোতাম লুকান</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"বোতাম লুকানো আছে
|
||||
|
||||
বিস্তৃত করতে বা বন্ধ করতে সোয়াইপ করুন"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">বিস্তৃত এবং বন্ধ বোতাম দেখানো হচ্ছে</string>
|
||||
বিস্তৃত করতে বা বন্ধ করতে সোয়াইপ করুন"</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">বিস্তৃত এবং বন্ধ করার বোতাম দেখানো হয়েছে</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">উপপাঠ লুকান</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">উপপাঠ লুকিয়ে রয়েছে</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">উপপাঠ প্রদর্শিত হয়েছে</string>
|
||||
|
@ -1154,6 +1154,7 @@ Si després es desactiva, es recomana esborrar les dades de l'aplicació per evi
|
||||
<string name="revanced_miniplayer_type_entry_4">Modern 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">Modern 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">Modern 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">Modern 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">Habilita cantonades arrodonides</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Les cantonades són arrodonides</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Les cantonades són quadrades</string>
|
||||
@ -1173,14 +1174,14 @@ El minireproductor es pot arrossegar a qualsevol racó de la pantalla"</string>
|
||||
|
||||
El minireproductor es pot arrossegar fora de la pantalla cap a l'esquerra o la dreta"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Gest d\'arrossegar horitzontalment deshabilitat</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Amaga el botó de tancament</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">El botó de tancament està amagat</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">El botó de tancament es mostra</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Amaga els botons d\'expansió i tancament</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Els botons estan ocults
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">Amaga els botons de superposició</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">Els botons de superposició estan amagats</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">Es mostren els botons de superposició</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">Amaga els botons per expandir i tancar</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"S'han amagat els botons
|
||||
|
||||
Desliza para ampliar o cerrar"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Els botons d\'expansió i tancament es mostren</string>
|
||||
Llisca per expandir o tancar"</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">Es mostren els botons per expandir i tancar</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Amaga els subtítols</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Els subtítols estan amagats</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Els subtítols es mostren</string>
|
||||
|
@ -1154,6 +1154,7 @@ Pokud bude později vypnuta, doporučujeme vymazat data aplikace, aby se zabrán
|
||||
<string name="revanced_miniplayer_type_entry_4">Moderní 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">Moderní 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">Moderní 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">Moderní 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">Povolit zaoblené rohy</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Rohy jsou zaoblené</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Rohy jsou čtvercové</string>
|
||||
@ -1173,14 +1174,14 @@ Pokud bude později vypnuta, doporučujeme vymazat data aplikace, aby se zabrán
|
||||
|
||||
\"Miniplayer\" lze přetáhnout z obrazovky doleva nebo doprava"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Horizontální posun je zakázán</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Skrýt tlačítko zavření</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">Tlačítko zavření je skryto</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Tlačítko zavření je zobrazeno</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Skrýt tlačítka pro rozbalení a zavření</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Tlačítka jsou skryta
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">Skrýt tlačítka překrytí</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">Tlačítka překrytí jsou skrytá</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">Tlačítka překrytí jsou zobrazena</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">Skrýt tlačítka rozbalení a zavření</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"Tlačítka jsou skrytá
|
||||
|
||||
Přejeďte prstem pro rozbalení nebo zavření"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Tlačítka pro rozbalení a zavření jsou zobrazena</string>
|
||||
Rozbalte nebo zavřete přejetím prstem"</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">Tlačítka rozbalení a zavření jsou zobrazena</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Skrýt podtexty</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Podtexty jsou skryty</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Podtexty jsou zobrazeny</string>
|
||||
|
@ -1100,6 +1100,7 @@ Hvis det senere slås fra, anbefales det at rydde app-dataene for at forhindre U
|
||||
<string name="revanced_miniplayer_type_entry_4">Moderne 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">Moderne 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">Moderne 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">Moderne 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">Aktiver afrundede hjørner</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Hjørner er afrundede</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Hjørner er firkantede</string>
|
||||
@ -1119,14 +1120,14 @@ Miniafspiller kan trækkes til et hvilket som helst hjørne af skærmen"</string
|
||||
|
||||
Miniafspiller kan trækkes ud over skærmen til venstre eller højre"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Vandret trækbevægelse deaktiveret</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Skjul lukkeknap</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">Luk knappen er skjult</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Luk knappen vises</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Skjul udvid og luk knapper</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Knapper er skjult
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">Skjul overlay-knapper</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">Overlay-knapper er skjult</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">Overlay-knapper vises</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">Skjul udvid- og luk-knapper</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"Knapper er skjult
|
||||
|
||||
Stryg for at udvide eller lukke"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Udvid og luk knapper vises</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">Udvid- og luk-knapper vises</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Skjul undertekster</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Undertekster er skjult</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Undertekster er vist</string>
|
||||
|
@ -1148,6 +1148,7 @@ Wenn Sie die Funktion später deaktivieren, wird empfohlen, die App-Daten zu lö
|
||||
<string name="revanced_miniplayer_type_entry_4">Modern 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">Modern 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">Modern 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">Modern 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">Abgerundete Ecken aktivieren</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Ecken sind abgerundet</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Ecken sind Quadrat</string>
|
||||
@ -1167,14 +1168,14 @@ Der Mini-Player kann in jede Ecke des Bildschirms gezogen werden"</string>
|
||||
|
||||
Der Mini-Player kann mit einer Wischgeste vom Bildschirm nach links oder rechts gezogen werden"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Horizontale Drag Geste deaktiviert</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Schließen-Button ausblenden</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">Schließen-Button ist ausgeblendet</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Schließen-Schaltfläche wird angezeigt</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Ausklappen und Schließen der Tasten ausblenden</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Schaltflächen sind ausgeblendet
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">Overlay-Buttons ausblenden</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">Overlay-Buttons sind ausgeblendet</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">Overlay-Buttons werden angezeigt</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">Schaltflächen zum Erweitern und Schließen ausblenden</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"Schaltflächen sind ausgeblendet
|
||||
|
||||
Wischen Sie, um zu erweitern oder zu schließen"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Erweitern und Schließen Tasten werden angezeigt</string>
|
||||
Zum Erweitern oder Schließen wischen"</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">Schaltflächen zum Erweitern und Schließen werden angezeigt</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Untertexte ausblenden</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Subtexte sind ausgeblendet</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Untertexte werden angezeigt</string>
|
||||
|
@ -1156,6 +1156,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_miniplayer_type_entry_4">Μοντέρνος 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">Μοντέρνος 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">Μοντέρνος 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">Μοντέρνος 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">Στρογγυλεμένες γωνίες</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Οι γωνίες είναι στρογγυλεμένες</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Οι γωνίες είναι τετράγωνες</string>
|
||||
@ -1175,14 +1176,14 @@ Second \"item\" text"</string>
|
||||
|
||||
Η ελαχιστοποιημένη οθόνη μπορεί να συρθεί εκτός οθόνης προς τα αριστερά ή δεξιά"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Η χειρονομία οριζόντιας σύρσης είναι απενεργοποιημένη</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Κουμπί κλεισίματος</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">Κρυμμένο</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Εμφανίζεται</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Κουμπιά επέκτασης και κλεισίματος</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Κρυμμένα
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">Κουμπιά επικάλυψης οθόνης αναπαραγωγής</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">Κρυμμένα</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">Εμφανίζονται</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">Κουμπιά επέκτασης και κλεισίματος</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"Τα κουμπιά δεν εμφανίζονται
|
||||
|
||||
Σύρετε την ελαχιστοποιημένη οθόνη αναπαραγωγής για επέκταση ή κλείσιμο του βίντεο"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Εμφανίζονται</string>
|
||||
Σύρετε για να αναπτύξετε ή να κλείσετε"</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">Τα κουμπιά εμφανίζονται</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Κείμενα οθόνης αναπαραγωγής</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Κρυμμένα</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Εμφανίζονται</string>
|
||||
|
@ -1143,6 +1143,7 @@ Si se desactiva posteriormente, se recomienda borrar los datos de la aplicación
|
||||
<string name="revanced_miniplayer_type_entry_4">Moderna 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">Moderna 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">Moderna 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">Moderno 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">Habilitar esquinas redondeadas</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Las esquinas están redondeadas</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Las esquinas son cuadradas</string>
|
||||
@ -1162,14 +1163,14 @@ El minireproductor se puede arrastrar a cualquier esquina de la pantalla"</strin
|
||||
|
||||
El minireproductor se puede arrastrar fuera de la pantalla hacia la izquierda o la derecha"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Gesto de arrastre horizontal desactivado</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Ocultar botón de cerrar</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">El botón de cierre está oculto</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Se muestra el botón de cerrar</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Ocultar botones de expansión y cierre</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Los botones están ocultos
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">Ocultar botones de superposición</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">Los botones de superposición están ocultos</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">Se muestran los botones de superposición</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">Ocultar botones de expandir y cerrar</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"Los botones están ocultos
|
||||
|
||||
Desliza para expandir o cerrar"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Mostrar los botones de ampliación y cierre</string>
|
||||
Desliza el dedo para expandir o cerrar"</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">Se muestran los botones de expandir y cerrar</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Ocultar subtextos</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Los subtextos están ocultos</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Los subtextos se muestran</string>
|
||||
|
@ -1155,6 +1155,7 @@ Kui see hiljem välja lülitatakse, on soovitatav rakenduse andmed kustutada, et
|
||||
<string name="revanced_miniplayer_type_entry_4">Kaasaegne 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">Kaasaegne 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">Kaasaegne 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">Moodne 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">Lülita ümarate nurkade režiim sisse</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Nurgad on ümarad</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Nurgad on ruudukujulised</string>
|
||||
@ -1174,14 +1175,14 @@ Minimaalset mängijat saab lohistada ekraani mis tahes nurka"</string>
|
||||
|
||||
Minimaalset mängijat saab lohistada ekraanilt vasakule või paremale"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Horisontaalse lohistamise žest on keelatud</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Peida sulgemisnupp</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">Sulgemisnupp on peidetud</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Sulgemisnupp on nähtav</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Peida laiendamis- ja sulgemisnupud</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Nupud on peidetud
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">Peida ülekatteliidese nupud</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">Ülekatteliidese nupud on peidetud</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">Ülekatteliidese nupud on nähtaval</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">Peida laiendus- ja sulgemisnupud</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"Nupud on peidetud
|
||||
|
||||
Pühkige laiendamiseks või sulgemiseks"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Laiendamis- ja sulgemisnupud on nähtavad</string>
|
||||
Laiendamiseks või sulgemiseks libista"</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">Laiendus- ja sulgemisnupud on nähtaval</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Peida alatähed</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Alatähed on peidetud</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Alatähed on nähtavad</string>
|
||||
|
@ -1141,6 +1141,7 @@ Jos tämä poistetaan myöhemmin käytöstä, on suositeltavaa tyhjentää sovel
|
||||
<string name="revanced_miniplayer_type_entry_4">Moderni 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">Moderni 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">Moderni 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">Moderni 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">Ota pyöristetyt kulmat käyttöön</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Kulmat on pyöristetty</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Kulmat ovat suorakulmaisia</string>
|
||||
@ -1160,14 +1161,11 @@ Minisoitin voidaan vetää mihin tahansa näytön kulmaan"</string>
|
||||
|
||||
Minisoitin voidaan vetää pois näytöltä vasemmalle tai oikealle"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Vaakasuuntainen vetoele ei ole käytössä</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Piilota sulje-painike</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">Sulje-painike on piilotettu</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Sulje-painike näytetään</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Piilota laajenna- ja sulje-painikkeet</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Painikkeet piilotetaan
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">Piilota laajenna- ja sulje-painikkeet</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"Painikkeet piilotetaan
|
||||
|
||||
Pyyhkäise laajentaaksesi tai sulkeaksesi"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Laajenna- ja sulje-painikkeet näytetään</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">Laajenna- ja sulje-painikkeet näytetään</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Piilota alatekstit</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Alatekstit on piilotettu</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Alatekstit näytetään</string>
|
||||
|
@ -1153,6 +1153,7 @@ Kung mamaya ay patayin, inirerekumenda na i-clear ang data ng app upang maiwasan
|
||||
<string name="revanced_miniplayer_type_entry_4">Moderno 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">Moderno 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">Moderno 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">Makabagong 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">Paganahin ang mga bilugan na sulok</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Bilugan ang mga sulok</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Parihaba ang mga sulok</string>
|
||||
@ -1172,14 +1173,14 @@ Ang \"miniplayer\" ay maaaring i-drag sa anumang sulok ng screen"</string>
|
||||
|
||||
Ang \"miniplayer\" ay maaaring i-drag palabas ng screen sa kaliwa o kanan"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Hindi pinagana ang pahalang na drag gesture</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Itago ang pindutan ng pagsara</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">Nakatago ang pindutan ng pagsara</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Ipinapakita ang pindutan ng pagsara</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Itago ang mga button na palawakin at isara</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Ang mga pindutan ay nakatago
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">Itago ang mga button ng overlay</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">Nakatago ang mga button ng overlay</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">Ipinapakita ang mga button ng overlay</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">Itago ang mga button para palawakin at isara</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"Nakatago ang mga button
|
||||
|
||||
Mag-swipe upang palawakin o isara"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Ang mga pindutan ng palawakin at isara ay ipinapakita</string>
|
||||
Mag-swipe para palawakin o isara"</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">Ipinapakita ang mga button para palawakin at isara</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Itago ang mga subtext</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Nakatago ang mga subtext</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Ipinapakita ang mga subtext</string>
|
||||
|
@ -1154,6 +1154,7 @@ Si désactivé ultérieurement, il est recommandé d'effacer les données de l'a
|
||||
<string name="revanced_miniplayer_type_entry_4">Moderne 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">Moderne 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">Moderne 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">Moderne 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">Activer les coins arrondis</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">Les coins sont arrondis</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">Les coins sont carrés</string>
|
||||
@ -1173,14 +1174,14 @@ Le lecteur réduit peut être déplacé vers n'importe quel coin de l'écran"</s
|
||||
|
||||
Le lecteur réduit peut être déplacé hors de l'écran, à gauche comme à droite"</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Geste de déplacement horizontal désactivé</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Masquer le bouton de fermeture</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">Le bouton de fermeture est masqué</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Le bouton de fermeture est affiché</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_title">Masquer les boutons Agrandir et Fermer</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_on">"Les boutons sont masqués
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">Masquer les boutons de superposition</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">Les boutons de superposition sont masqués</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">Les boutons de superposition sont affichés</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">Masquer les boutons Agrandir et Fermer</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_on">"Les boutons sont masqués
|
||||
|
||||
Balayez pour développer ou fermer"</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_legacy_summary_off">Les boutons Agrandir et Fermer sont affichés</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_summary_off">Les boutons Agrandir et Fermer sont affichés</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_title">Masquer les sous-textes</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_on">Les sous-textes sont masqués</string>
|
||||
<string name="revanced_miniplayer_hide_subtext_summary_off">Les sous-textes sont affichés</string>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user