mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-16 07:43:56 +00:00
Compare commits
17 Commits
v5.17.0-de
...
v5.18.1-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccb76983ff | ||
|
|
318b55b8fe | ||
|
|
49ade9efbc | ||
|
|
d77515bd68 | ||
|
|
087bf1e152 | ||
|
|
c2994d583d | ||
|
|
127b0a63fe | ||
|
|
27aafd0ee1 | ||
|
|
49c54c0e54 | ||
|
|
842ba4fc4d | ||
|
|
66ecadce4f | ||
|
|
73ca04da5e | ||
|
|
a5d26208c1 | ||
|
|
497291c478 | ||
|
|
b24278a544 | ||
|
|
135f9ead3c | ||
|
|
ca4f960171 |
63
CHANGELOG.md
63
CHANGELOG.md
@@ -1,3 +1,66 @@
|
||||
## [5.18.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.18.0...v5.18.1-dev.1) (2025-03-31)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Remove background playback restrictions:** Do not show media controls when playing Shorts from the feed ([2ed675c](https://github.com/ReVanced/revanced-patches/commit/2ed675cdd058fb5876381a9d30dee5263f6b2e26))
|
||||
|
||||
# [5.18.0](https://github.com/ReVanced/revanced-patches/compare/v5.17.0...v5.18.0) (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))
|
||||
|
||||
|
||||
### 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.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)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Facebook - Hide 'Sponsored Stories':** Constrain patch to latest compatible version ([#4657](https://github.com/ReVanced/revanced-patches/issues/4657)) ([46bd1c8](https://github.com/ReVanced/revanced-patches/commit/46bd1c829acd5f83600025e0ceb7d482ae80be69))
|
||||
* **Spotify - Unlock Premium:** Override additional attributes ([#4651](https://github.com/ReVanced/revanced-patches/issues/4651)) ([568b40d](https://github.com/ReVanced/revanced-patches/commit/568b40da9692eae9039bbb3cec513a61ca627c24))
|
||||
* **Spotify - Unlock Premium:** Use correct patch description convention ([a486522](https://github.com/ReVanced/revanced-patches/commit/a4865228f8481d2efc8fbf4e90902a03289d9a3f))
|
||||
* **X / Twitter:** Constrain patches to latest compatible versions ([#4683](https://github.com/ReVanced/revanced-patches/issues/4683)) ([f579728](https://github.com/ReVanced/revanced-patches/commit/f5797289f45186052537982c7f5db6f2b0769aee))
|
||||
* **YouTube - Navigation buttons:** Add user dialog message to 'Disable translucent status bar' ([a4a0e68](https://github.com/ReVanced/revanced-patches/commit/a4a0e6869e23d15ee09262460f4e290c90629eeb))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Spotify - Unlock Premium:** Disable the "Spotify Premium" upsell experiment in context menus ([9a10ee4](https://github.com/ReVanced/revanced-patches/commit/9a10ee4d22fb53da2012a182e038749d3ad72377))
|
||||
|
||||
# [5.17.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.17.0-dev.3...v5.17.0-dev.4) (2025-03-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **X / Twitter:** Constrain patches to latest compatible versions ([#4683](https://github.com/ReVanced/revanced-patches/issues/4683)) ([f579728](https://github.com/ReVanced/revanced-patches/commit/f5797289f45186052537982c7f5db6f2b0769aee))
|
||||
|
||||
# [5.17.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.17.0-dev.2...v5.17.0-dev.3) (2025-03-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Spotify - Unlock Premium:** Override additional attributes ([#4651](https://github.com/ReVanced/revanced-patches/issues/4651)) ([568b40d](https://github.com/ReVanced/revanced-patches/commit/568b40da9692eae9039bbb3cec513a61ca627c24))
|
||||
|
||||
# [5.17.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.17.0-dev.1...v5.17.0-dev.2) (2025-03-27)
|
||||
|
||||
|
||||
|
||||
@@ -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,3 +1,16 @@
|
||||
dependencies {
|
||||
compileOnly(project(":extensions:shared:library"))
|
||||
compileOnly(project(":extensions:spotify:stub"))
|
||||
compileOnly(libs.annotation)
|
||||
}
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
minSdk = 24
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package app.revanced.extension.youtube.patches;
|
||||
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.shared.PlayerType;
|
||||
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@@ -23,7 +24,13 @@ public class BackgroundPlaybackPatch {
|
||||
// 7. Close the Short
|
||||
// 8. Resume playing the regular video
|
||||
// 9. Minimize the app (PIP should appear)
|
||||
return !ShortsPlayerState.isOpen();
|
||||
if (ShortsPlayerState.isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the video player is opened and it's not playing in the feed.
|
||||
PlayerType current = PlayerType.getCurrent();
|
||||
return !current.isNoneOrHidden() && current != PlayerType.INLINE_MINIMAL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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-dev.2
|
||||
version = 5.18.1-dev.1
|
||||
|
||||
@@ -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 {
|
||||
@@ -820,6 +820,10 @@ public final class app/revanced/patches/spotify/misc/UnlockPremiumPatchKt {
|
||||
public static final fun getUnlockPremiumPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/spotify/misc/extension/ExtensionPatchKt {
|
||||
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/spotify/misc/fix/SpoofSignaturePatchKt {
|
||||
public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
@@ -1181,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 {
|
||||
@@ -1386,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 }
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.util.findFreeRegister
|
||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
@@ -31,7 +32,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",
|
||||
@@ -92,14 +95,14 @@ fun spoofVideoStreamsPatch(
|
||||
getReference<MethodReference>()?.name == "newUrlRequestBuilder"
|
||||
}
|
||||
val urlRegister = getInstruction<FiveRegisterInstruction>(newRequestBuilderIndex).registerD
|
||||
val freeRegister = getInstruction<OneRegisterInstruction>(newRequestBuilderIndex + 1).registerA
|
||||
val freeRegister = findFreeRegister(newRequestBuilderIndex, urlRegister)
|
||||
|
||||
addInstructions(
|
||||
newRequestBuilderIndex,
|
||||
"""
|
||||
move-object v$freeRegister, p1
|
||||
invoke-static { v$urlRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
|
||||
""",
|
||||
move-object v$freeRegister, p1
|
||||
invoke-static { v$urlRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
@@ -241,13 +244,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()
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.w3c.dom.Element
|
||||
val customThemePatch = resourcePatch(
|
||||
name = "Custom theme",
|
||||
description = "Applies a custom theme.",
|
||||
use = false,
|
||||
) {
|
||||
compatibleWith("com.spotify.music")
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package app.revanced.patches.spotify.misc.extension
|
||||
|
||||
import app.revanced.patches.shared.misc.extension.sharedExtensionPatch
|
||||
|
||||
val sharedExtensionPatch = sharedExtensionPatch("spotify", spotifyMainActivityOnCreate)
|
||||
@@ -0,0 +1,10 @@
|
||||
package app.revanced.patches.spotify.misc.extension
|
||||
|
||||
import app.revanced.patches.shared.misc.extension.extensionHook
|
||||
|
||||
internal val spotifyMainActivityOnCreate = extensionHook {
|
||||
custom { method, classDef ->
|
||||
classDef.type == "Lcom/spotify/music/SpotifyMainActivity;" &&
|
||||
method.name == "onCreate"
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,13 @@ val dynamicColorPatch = resourcePatch(
|
||||
name = "Dynamic color",
|
||||
description = "Replaces the default X (Formerly Twitter) Blue with the user's Material You palette.",
|
||||
) {
|
||||
compatibleWith("com.twitter.android")
|
||||
compatibleWith(
|
||||
"com.twitter.android"(
|
||||
"10.84.0-release.0",
|
||||
"10.60.0-release.0",
|
||||
"10.48.0-release.0"
|
||||
)
|
||||
)
|
||||
|
||||
execute {
|
||||
val resDirectory = get("res")
|
||||
|
||||
@@ -11,7 +11,15 @@ fun hookPatch(
|
||||
) = bytecodePatch(name) {
|
||||
dependsOn(jsonHookPatch)
|
||||
|
||||
compatibleWith("com.twitter.android")
|
||||
compatibleWith(
|
||||
"com.twitter.android"(
|
||||
// 10.85+ uses Pairip and requires additional changes to work.
|
||||
"10.84.0-release.0",
|
||||
// Confirmed to not show reply ads. Slightly newer versions may also work.
|
||||
"10.60.0-release.0",
|
||||
"10.48.0-release.0"
|
||||
)
|
||||
)
|
||||
|
||||
execute {
|
||||
addJsonHook(JsonHook(hookClassDescriptor))
|
||||
|
||||
@@ -37,7 +37,13 @@ val changeLinkSharingDomainPatch = bytecodePatch(
|
||||
sharedExtensionPatch,
|
||||
)
|
||||
|
||||
compatibleWith("com.twitter.android")
|
||||
compatibleWith(
|
||||
"com.twitter.android"(
|
||||
"10.84.0-release.0",
|
||||
"10.60.0-release.0",
|
||||
"10.48.0-release.0"
|
||||
)
|
||||
)
|
||||
|
||||
val domainName by stringOption(
|
||||
key = "domainName",
|
||||
|
||||
@@ -8,7 +8,13 @@ val sanitizeSharingLinksPatch = bytecodePatch(
|
||||
name = "Sanitize sharing links",
|
||||
description = "Removes the tracking query parameters from links before they are shared.",
|
||||
) {
|
||||
compatibleWith("com.twitter.android")
|
||||
compatibleWith(
|
||||
"com.twitter.android"(
|
||||
"10.84.0-release.0",
|
||||
"10.60.0-release.0",
|
||||
"10.48.0-release.0"
|
||||
)
|
||||
)
|
||||
|
||||
execute {
|
||||
sanitizeSharingLinksFingerprint.method.addInstructions(
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -20,12 +20,14 @@ import app.revanced.patches.shared.misc.settings.preference.*
|
||||
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.versionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_07_or_greater
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.util.findFreeRegister
|
||||
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
|
||||
@@ -120,7 +122,6 @@ val hideLayoutComponentsPatch = bytecodePatch(
|
||||
addResourcesPatch,
|
||||
hideLayoutComponentsResourcePatch,
|
||||
navigationBarHookPatch,
|
||||
versionCheckPatch
|
||||
)
|
||||
|
||||
compatibleWith(
|
||||
@@ -132,6 +133,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
@@ -247,29 +249,31 @@ 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 {
|
||||
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
|
||||
val insertIndex = startIndex + 1
|
||||
val freeRegister = findFreeRegister(insertIndex, conversionContextRegister, returnEmptyComponentRegister)
|
||||
|
||||
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(
|
||||
insertIndex,
|
||||
"""
|
||||
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 +349,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",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@ 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.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
import app.revanced.util.findFreeRegister
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
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
|
||||
|
||||
@@ -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",
|
||||
),
|
||||
)
|
||||
|
||||
@@ -107,11 +106,12 @@ val openShortsInRegularPlayerPatch = bytecodePatch(
|
||||
getReference<MethodReference>()?.returnType ==
|
||||
"Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;"
|
||||
}
|
||||
val freeRegister = getInstruction<FiveRegisterInstruction>(index).registerC
|
||||
val playbackStartRegister = getInstruction<OneRegisterInstruction>(index + 1).registerA
|
||||
val insertIndex = index + 2
|
||||
val freeRegister = findFreeRegister(insertIndex, playbackStartRegister)
|
||||
|
||||
addInstructionsWithLabels(
|
||||
index + 2,
|
||||
insertIndex,
|
||||
extensionInstructions(playbackStartRegister, freeRegister)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -7,11 +7,14 @@ 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.findFreeRegister
|
||||
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.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
@@ -38,6 +41,7 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
"20.07.39",
|
||||
),
|
||||
)
|
||||
|
||||
@@ -48,25 +52,47 @@ 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 freeRegister = findFreeRegister(listenableInstructionIndex)
|
||||
|
||||
addInstructionsAtControlFlowLabel(
|
||||
listenableInstructionIndex,
|
||||
"""
|
||||
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z
|
||||
move-result v$freeRegister
|
||||
if-eqz v$freeRegister, :show
|
||||
return-void
|
||||
:show
|
||||
nop
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.util.findFreeRegister
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
@@ -42,13 +43,14 @@ val fixPlaybackSpeedWhilePlayingPatch = bytecodePatch{
|
||||
}
|
||||
|
||||
playbackSpeedInFeedsFingerprint.method.apply {
|
||||
val freeRegister = implementation!!.registerCount - parameters.size - 2
|
||||
val playbackSpeedIndex = indexOfGetPlaybackSpeedInstruction(this)
|
||||
val playbackSpeedRegister = getInstruction<TwoRegisterInstruction>(playbackSpeedIndex).registerA
|
||||
val returnIndex = indexOfFirstInstructionOrThrow(playbackSpeedIndex, Opcode.RETURN_VOID)
|
||||
val insertIndex = playbackSpeedIndex + 1
|
||||
val freeRegister = findFreeRegister(insertIndex, playbackSpeedRegister)
|
||||
|
||||
addInstructionsWithLabels(
|
||||
playbackSpeedIndex + 1,
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static { v$playbackSpeedRegister }, $EXTENSION_CLASS_DESCRIPTOR->playbackSpeedChanged(F)Z
|
||||
move-result v$freeRegister
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -8,19 +8,21 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
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.findFreeRegister
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.*
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@@ -190,17 +192,7 @@ val lithoFilterPatch = bytecodePatch(
|
||||
},
|
||||
).registerA
|
||||
|
||||
// Find a free temporary register.
|
||||
val freeRegister = getInstruction<OneRegisterInstruction>(
|
||||
// Immediately before is a StringBuilder append constant character.
|
||||
indexOfFirstInstructionReversedOrThrow(insertHookIndex, Opcode.CONST_16),
|
||||
).registerA
|
||||
|
||||
// Verify the temp register will not clobber the method result register.
|
||||
if (stringBuilderRegister == freeRegister) {
|
||||
throw PatchException("Free register will clobber StringBuilder register")
|
||||
}
|
||||
|
||||
val freeRegister = findFreeRegister(insertHookIndex, identifierRegister, stringBuilderRegister)
|
||||
val invokeFilterInstructions = """
|
||||
invoke-static { v$identifierRegister, v$stringBuilderRegister }, $EXTENSION_CLASS_DESCRIPTOR->filter(Ljava/lang/String;Ljava/lang/StringBuilder;)Z
|
||||
move-result v$freeRegister
|
||||
@@ -235,7 +227,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#")
|
||||
}
|
||||
|
||||
|
||||
@@ -15,13 +15,135 @@ import app.revanced.patches.shared.misc.mapping.get
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
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.instruction.Instruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.RegisterRangeInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ThreeRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
import java.util.EnumSet
|
||||
|
||||
/**
|
||||
* Starting from and including the instruction at index [startIndex],
|
||||
* finds the next register that is wrote to and not read from. If a return instruction
|
||||
* is encountered, then the lowest unused register is returned.
|
||||
*
|
||||
* This method can return a non 4-bit register, and the calling code may need to temporarily
|
||||
* swap register contents if a 4-bit register is required.
|
||||
*
|
||||
* @param startIndex Inclusive starting index.
|
||||
* @param registersToExclude Registers to exclude, and consider as used. For most use cases,
|
||||
* all registers used in injected code should be specified.
|
||||
* @throws IllegalArgumentException If a branch or conditional statement is encountered
|
||||
* before a suitable register is found.
|
||||
*/
|
||||
internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude: Int): Int {
|
||||
if (implementation == null) {
|
||||
throw IllegalArgumentException("Method has no implementation: $this")
|
||||
}
|
||||
if (startIndex < 0 || startIndex >= instructions.count()) {
|
||||
throw IllegalArgumentException("startIndex out of bounds: $startIndex")
|
||||
}
|
||||
|
||||
// All registers used by an instruction.
|
||||
fun Instruction.getRegistersUsed() = when (this) {
|
||||
is FiveRegisterInstruction -> listOf(registerC, registerD, registerE, registerF, registerG)
|
||||
is ThreeRegisterInstruction -> listOf(registerA, registerB, registerC)
|
||||
is TwoRegisterInstruction -> listOf(registerA, registerB)
|
||||
is OneRegisterInstruction -> listOf(registerA)
|
||||
is RegisterRangeInstruction -> (startRegister until (startRegister + registerCount)).toList()
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
// Register that is written to by an instruction.
|
||||
fun Instruction.getRegisterWritten() = when (this) {
|
||||
is ThreeRegisterInstruction -> registerA
|
||||
is TwoRegisterInstruction -> registerA
|
||||
is OneRegisterInstruction -> registerA
|
||||
else -> throw IllegalStateException("Not a write instruction: $this")
|
||||
}
|
||||
|
||||
val writeOpcodes = EnumSet.of(
|
||||
NEW_INSTANCE, NEW_ARRAY,
|
||||
MOVE, MOVE_FROM16, MOVE_16, MOVE_WIDE, MOVE_WIDE_FROM16, MOVE_WIDE_16, MOVE_OBJECT,
|
||||
MOVE_OBJECT_FROM16, MOVE_OBJECT_16, MOVE_RESULT, MOVE_RESULT_WIDE, MOVE_RESULT_OBJECT, MOVE_EXCEPTION,
|
||||
IGET, IGET_WIDE, IGET_OBJECT, IGET_BOOLEAN, IGET_BYTE, IGET_CHAR, IGET_SHORT,
|
||||
SGET, SGET_WIDE, SGET_OBJECT, SGET_BOOLEAN, SGET_BYTE, SGET_CHAR, SGET_SHORT,
|
||||
)
|
||||
|
||||
val branchOpcodes = EnumSet.of(
|
||||
GOTO, GOTO_16, GOTO_32,
|
||||
IF_EQ, IF_NE, IF_LT, IF_GE, IF_GT, IF_LE,
|
||||
IF_EQZ, IF_NEZ, IF_LTZ, IF_GEZ, IF_GTZ, IF_LEZ,
|
||||
)
|
||||
|
||||
val returnOpcodes = EnumSet.of(
|
||||
RETURN_VOID, RETURN, RETURN_WIDE, RETURN_OBJECT,
|
||||
)
|
||||
|
||||
// Highest 4-bit register available, exclusive. Ideally return a free register less than this.
|
||||
val maxRegister4Bits = 16
|
||||
var bestFreeRegisterFound: Int? = null
|
||||
val usedRegisters = registersToExclude.toMutableSet()
|
||||
|
||||
for (i in startIndex until instructions.count()) {
|
||||
val instruction = getInstruction(i)
|
||||
|
||||
if (instruction.opcode in returnOpcodes) {
|
||||
// Method returns. Use lowest register that hasn't been encountered.
|
||||
val freeRegister = (0 until implementation!!.registerCount).find {
|
||||
it !in usedRegisters
|
||||
}
|
||||
if (freeRegister != null) {
|
||||
return freeRegister
|
||||
}
|
||||
if (bestFreeRegisterFound != null) {
|
||||
return bestFreeRegisterFound;
|
||||
}
|
||||
|
||||
// Somehow every method register was read from before any register was wrote to.
|
||||
// In practice this never occurs.
|
||||
throw IllegalArgumentException("Could not find a free register from startIndex: " +
|
||||
"$startIndex excluding: $registersToExclude")
|
||||
}
|
||||
|
||||
if (instruction.opcode in branchOpcodes) {
|
||||
if (bestFreeRegisterFound != null) {
|
||||
return bestFreeRegisterFound;
|
||||
}
|
||||
// This method is simple and does not follow branching.
|
||||
throw IllegalArgumentException("Encountered a branch statement before a free register could be found")
|
||||
}
|
||||
|
||||
if (instruction.opcode in writeOpcodes) {
|
||||
val freeRegister = instruction.getRegisterWritten()
|
||||
if (freeRegister !in usedRegisters) {
|
||||
if (freeRegister < maxRegister4Bits) {
|
||||
// Found an ideal register.
|
||||
return freeRegister
|
||||
}
|
||||
|
||||
// Continue searching for a 4-bit register if available.
|
||||
if (bestFreeRegisterFound == null || freeRegister < bestFreeRegisterFound) {
|
||||
bestFreeRegisterFound = freeRegister
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usedRegisters.addAll(instruction.getRegistersUsed())
|
||||
}
|
||||
|
||||
// Cannot be reached since a branch or return statement will
|
||||
// be encountered before the end of the method.
|
||||
throw IllegalStateException()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the [MutableMethod] from a given [Method] in a [MutableClass].
|
||||
@@ -395,7 +517,7 @@ fun Method.findInstructionIndicesReversedOrThrow(opcode: Opcode): List<Int> {
|
||||
|
||||
internal fun MutableMethod.insertFeatureFlagBooleanOverride(literal: Long, extensionsMethod: String) {
|
||||
val literalIndex = indexOfFirstLiteralInstructionOrThrow(literal)
|
||||
val index = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
|
||||
val index = indexOfFirstInstructionOrThrow(literalIndex, MOVE_RESULT)
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
val operation = if (register < 16) {
|
||||
@@ -423,7 +545,7 @@ fun BytecodePatchContext.forEachLiteralValueInstruction(
|
||||
classes.forEach { classDef ->
|
||||
classDef.methods.forEach { method ->
|
||||
method.implementation?.instructions?.forEachIndexed { index, instruction ->
|
||||
if (instruction.opcode == Opcode.CONST &&
|
||||
if (instruction.opcode == CONST &&
|
||||
(instruction as WideLiteralInstruction).wideLiteral == literal
|
||||
) {
|
||||
val mutableMethod = proxy(classDef).mutableClass.findMutableMethodOf(method)
|
||||
|
||||
@@ -22,7 +22,7 @@ Second \"item\" text"</string>
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.checkEnvironmentPatch">
|
||||
<string name="revanced_check_environment_failed_title">ŲØ´ŲØĒ ØšŲ
ŲŲØ§ØĒ Ø§ŲØĒØŲŲ</string>
|
||||
<string name="revanced_check_environment_failed_title">ŲØ´ŲØĒ اŲŲØŲØĩاØĒ</string>
|
||||
<string name="revanced_check_environment_dialog_open_official_source_button">ŲØĒØ اŲŲ
Ųب𠨧ب਺Ų
Ų</string>
|
||||
<string name="revanced_check_environment_dialog_ignore_button">ØĒØŦاŲŲ</string>
|
||||
<string name="revanced_check_environment_failed_message"><h5>ŲØ§ ŲØ¨Ø¯Ų ØŖŲ ŲØ°Ø§ Ø§ŲØĒØˇØ¨ŲŲ ŲØ¯ ØĒŲ
ØĒؚدŲŲŲ Ų
Ų ŲØ¨ŲŲ.</h5><br>ŲØ¯ ŲØ§ ŲØšŲ
Ų ŲØ°Ø§ Ø§ŲØĒØˇØ¨ŲŲ Ø¨Ø´ŲŲ ØĩØŲØØ <b>ŲØ¯ ŲŲŲŲ ØļØ§ØąŲØ§ ØŖŲ ØØĒŲ ØŽØˇŲØąŲا ŲŲØ§ØŗØĒ؎داŲ
</b>.<br><br>ØĒØ´ŲØą ŲØ°Ų اŲŲØŲØĩاØĒ ØĨŲŲ ØŖŲ ŲØ°Ø§ Ø§ŲØĒØˇØ¨ŲŲ ØĒŲ
ØĒؚدŲŲŲ Ų
ØŗØ¨ŲŲØ§ ØŖŲ ØĒŲ
Ø§ŲØØĩŲŲ ØšŲŲŲ Ų
Ų Ø´ØŽØĩ ØĸØŽØą:<br><br><small>%1$s</small><br>ŲŲØĩŲ Ø¨Ø´Ø¯ØŠ Ø¨Ų <b>ØĨŲØēØ§ØĄ ØĒØĢØ¨ŲØĒ ŲØ°Ø§ Ø§ŲØĒØˇØ¨ŲŲ ŲØĒØšØ¯ŲŲŲ Ø¨ŲŲØŗŲ</b> ŲŲØĒØŖŲد Ų
Ų ØŖŲŲ ØĒØŗØĒ؎دŲ
ØĒØˇØ¨ŲŲŲØ§ Ų
ØšØĒŲ
Ø¯ŲØ§ ŲØĸŲ
ŲŲØ§.<p><br>ŲŲ ØØ§ŲØŠ ØĒØŦاŲŲ ŲØ°Ø§ Ø§ŲØĒØØ°ŲØąØ ØŗŲØĒŲ
ØšØąØļŲ Ų
ØąØĒŲŲ ŲŲØˇ.</string>
|
||||
@@ -30,13 +30,13 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_check_environment_manager_not_expected_installer">ŲŲ
ŲØĒŲ
ØĒØĢØ¨ŲØĒŲ Ø¨ŲØ§ØŗØˇØŠ ReVanced Manager</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time">ØĒŲ
ØĒؚدŲŲŲ ŲØ¨Ų ØŖŲØĢØą Ų
Ų 10 Ø¯ŲØ§ØĻŲ</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_days">ØĒŲ
Ø§ŲØĒØšØ¯ŲŲ Ų
ŲØ° %s ŲŲŲ
</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_invalid">ØĒØ§ØąŲØŽ ØĨŲØ´Ø§ØĄ APK ØĒاŲŲ</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_invalid">ØĒØ§ØąŲØŽ Ø¨ŲØ§ØĄ APK ØĒاŲŲ</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.settingsResourcePatch">
|
||||
<string name="revanced_settings_submenu_title">Ø§ŲØĨؚداداØĒ</string>
|
||||
<string name="revanced_settings_confirm_user_dialog_title">ŲŲ ØĒØąØēب ŲŲ Ø§ŲŲ
ØĒابؚ؊Ø</string>
|
||||
<string name="revanced_settings_reset">ØĨؚاد؊ Ø§ŲØĒØšŲŲŲ</string>
|
||||
<string name="revanced_settings_restart_title">ØĒØØ¯ŲØĢ ŲØĨؚاد؊ ØĒØ´ØēŲŲ</string>
|
||||
<string name="revanced_settings_restart_title">ØĒØØ¯ŲØĢ ŲØĨؚاد؊ Ø§ŲØĒØ´ØēŲŲ</string>
|
||||
<string name="revanced_settings_restart">ØĨؚاد؊ Ø§ŲØĒØ´ØēŲŲ</string>
|
||||
<string name="revanced_settings_import">Ø§ØŗØĒŲØąØ§Ø¯</string>
|
||||
<string name="revanced_settings_import_copy">ŲØŗØŽ</string>
|
||||
@@ -106,9 +106,9 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_debug_protobuffer_title">ØŗØŦŲ Ø¨ØąŲØĒŲŲŲŲ Ø§ŲØĒØŽØ˛ŲŲ Ø§ŲŲ
Ø¤ŲØĒ</string>
|
||||
<string name="revanced_debug_protobuffer_summary_on">ØĒØĒØļŲ
Ų ØŗØŦŲØ§ØĒ Ø§ŲØĒØĩØŲØ Ø§ŲØĒØŽØ˛ŲŲ Ø§ŲŲ
Ø¤ŲØĒ</string>
|
||||
<string name="revanced_debug_protobuffer_summary_off">ŲØ§ ØĒØĒØļŲ
Ų ØŗØŦŲØ§ØĒ Ø§ŲØĒØĩØŲØ Ø§ŲØĒØŽØ˛ŲŲ Ø§ŲŲ
Ø¤ŲØĒ</string>
|
||||
<string name="revanced_debug_stacktrace_title">ØŗØŦŲ ØšŲ
ŲŲØ§ØĒ Ø§ŲØĒØˇØ¨ŲŲ</string>
|
||||
<string name="revanced_debug_stacktrace_summary_on">ØĒØĒØļŲ
Ų ØŗØŦŲØ§ØĒ Ø§ŲØĒØĩØŲØ ØŗŲØŦŲŲ ØšŲ
ŲŲØ§ØĒ Ø§ŲØĒØˇØ¨ŲŲ</string>
|
||||
<string name="revanced_debug_stacktrace_summary_off">ŲØ§ ØĒØĒØļŲ
Ų ØŗØŦŲØ§ØĒ Ø§ŲØĒØĩØŲØ ØŗŲØŦŲŲ ØšŲ
ŲŲØ§ØĒ Ø§ŲØĒØˇØ¨ŲŲ</string>
|
||||
<string name="revanced_debug_stacktrace_title">ØŗØŦŲ ØĒØĒبؚ اŲŲ
ŲØ¯Øŗ</string>
|
||||
<string name="revanced_debug_stacktrace_summary_on">ØĒØĒØļŲ
Ų ØŗØŦŲØ§ØĒ Ø§ŲØĒØĩØŲØ ØŗØŦŲ ØĒØĒبؚ اŲŲ
ŲØ¯Øŗ</string>
|
||||
<string name="revanced_debug_stacktrace_summary_off">ŲØ§ ØĒØĒØļŲ
Ų ØŗØŦŲØ§ØĒ Ø§ŲØĒØĩØŲØ ØŗØŦŲ ØĒØĒبؚ اŲŲ
ŲØ¯Øŗ</string>
|
||||
<string name="revanced_debug_toast_on_error_title">ØšØąØļ Ų
ŲØ§ØØ¸ØŠ ØšŲØ¯ ŲØŦŲØ¯ ØŽØˇØŖ ŲŲ ReVanced</string>
|
||||
<string name="revanced_debug_toast_on_error_summary_on">ŲØĒŲ
ØšØąØļ Ų
ŲØ§ØØ¸ØŠ ŲŲ ØØ§ŲØŠ ØØ¯ŲØĢ ØŽØˇØŖ</string>
|
||||
<string name="revanced_debug_toast_on_error_summary_off">ŲØ§ ŲØĒŲ
ØšØąØļ Ų
ŲØ§ØØ¸ØŠ ŲŲ ØØ§ŲØŠ ØØ¯ŲØĢ ØŽØˇØŖ</string>
|
||||
@@ -214,9 +214,9 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_related_videos_title">ØĨØŽŲØ§ØĄ اŲŲŲØ¯ŲŲŲØ§ØĒ ذاØĒ Ø§ŲØĩŲØŠ ŲŲ Ø§ŲØĨØŦØąØ§ØĄØ§ØĒ Ø§ŲØŗØąŲؚ؊</string>
|
||||
<string name="revanced_hide_related_videos_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ اŲŲŲØ¯ŲŲŲØ§ØĒ ذاØĒ Ø§ŲØĩŲØŠ</string>
|
||||
<string name="revanced_hide_related_videos_summary_off">ŲØĒŲ
ØšØąØļ اŲŲŲØ¯ŲŲŲØ§ØĒ ذاØĒ Ø§ŲØĩŲØŠ</string>
|
||||
<string name="revanced_hide_image_shelf_title">ØĨØŽŲØ§ØĄ ØąŲŲŲ Ø§ŲØĩŲØą ŲŲ ŲØĒØ§ØĻØŦ Ø§ŲØ¨ØØĢ</string>
|
||||
<string name="revanced_hide_image_shelf_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ØąŲŲŲ Ø§ŲØĩŲØąØŠ</string>
|
||||
<string name="revanced_hide_image_shelf_summary_off">ŲØĒŲ
ØšØąØļ ØąŲŲŲ Ø§ŲØĩŲØąØŠ</string>
|
||||
<string name="revanced_hide_image_shelf_title">ØĨØŽŲØ§ØĄ ØąŲ Ø§ŲØĩŲØąØŠ ŲŲ ŲØĒØ§ØĻØŦ Ø§ŲØ¨ØØĢ</string>
|
||||
<string name="revanced_hide_image_shelf_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ØąŲ Ø§ŲØĩŲØąØŠ</string>
|
||||
<string name="revanced_hide_image_shelf_summary_off">ŲØĒŲ
ØšØąØļ ØąŲ Ø§ŲØĩŲØąØŠ</string>
|
||||
<string name="revanced_hide_latest_posts_ads_title">ØĨØŽŲØ§ØĄ ØĸØŽØą اŲŲ
Ø´Ø§ØąŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_latest_posts_ads_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ØŖØØ¯ØĢ اŲŲ
Ø´Ø§ØąŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_latest_posts_ads_summary_off">ŲØĒŲ
ØšØąØļ ØŖØØ¯ØĢ اŲŲ
Ø´Ø§ØąŲØ§ØĒ</string>
|
||||
@@ -226,7 +226,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_artist_cards_title">ØĨØŽŲØ§ØĄ Ø¨ØˇØ§ŲØ§ØĒ اŲŲŲØ§Ų</string>
|
||||
<string name="revanced_hide_artist_cards_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ø¨ØˇØ§ŲØ§ØĒ اŲŲŲØ§Ų</string>
|
||||
<string name="revanced_hide_artist_cards_summary_off">ŲØĒŲ
ØšØąØļ Ø¨ØˇØ§ŲØ§ØĒ اŲŲŲØ§Ų</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_title">ØĨØŽŲØ§ØĄ \"Ų
ŲØŽØĩ اŲŲŲØ¯ŲŲ Ø§ŲØ°Ų ØĒŲ
ØĨŲØ´Ø§Ø¤Ų Ø¨ŲØ§ØŗØˇØŠ Ø§ŲØ°ŲØ§ØĄ Ø§ŲØ§ØĩØˇŲØ§ØšŲ\"</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_title">ØĨØŽŲØ§ØĄ \'Ų
ŲØŽØĩ اŲŲŲØ¯ŲŲ Ø§ŲØ°Ų ØĒŲ
ØĨŲØ´Ø§Ø¤Ų Ø¨ŲØ§ØŗØˇØŠ Ø§ŲØ°ŲØ§ØĄ Ø§ŲØ§ØĩØˇŲØ§ØšŲ\'</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ŲØŗŲ
Ų
ŲØŽØĩ اŲŲŲØ¯ŲŲ</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_summary_off">ŲØĒŲ
ØšØąØļ ŲØŗŲ
Ų
ŲØŽØĩ اŲŲŲØ¯ŲŲ</string>
|
||||
<string name="revanced_hide_attributes_section_title">ØĨØŽŲØ§ØĄ Ø§ŲØĩŲØ§ØĒ</string>
|
||||
@@ -253,31 +253,31 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_description_components_screen_title">ŲØĩŲ Ø§ŲŲŲØ¯ŲŲ</string>
|
||||
<string name="revanced_hide_description_components_screen_summary">ØĨØŽŲØ§ØĄ ØŖŲ ØšØąØļ Ų
ŲŲŲØ§ØĒ ŲØĩŲ Ø§ŲŲŲØ¯ŲŲ</string>
|
||||
<string name="revanced_hide_filter_bar_screen_title">Ø´ØąŲØˇ Ø§ŲØĒØĩŲŲØŠ</string>
|
||||
<string name="revanced_hide_filter_bar_screen_summary">ØĨØŽŲØ§ØĄ ØŖŲ ØĨØ¸ŲØ§Øą Ø´ØąŲØˇ اŲŲŲØĒØą ŲŲ Ø§ŲØŽŲاØĩØŠ ŲŲØĒØ§ØĻØŦ Ø§ŲØ¨ØØĢ ŲŲ
ŲØ§ØˇØš اŲŲŲØ¯ŲŲ Ø°Ø§ØĒ Ø§ŲØĩŲØŠ</string>
|
||||
<string name="revanced_hide_filter_bar_screen_summary">ØĨØŽŲØ§ØĄ ØŖŲ ØšØąØļ Ø´ØąŲØˇ اŲŲŲØĒØą ŲŲ Ø§ŲŲ
ŲØŦØ˛ ŲŲØĒØ§ØĻØŦ Ø§ŲØ¨ØØĢ ŲØ§ŲŲŲØ¯ŲŲŲØ§ØĒ ذاØĒ Ø§ŲØĩŲØŠ</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_feed_title">ØĨØŽŲØ§ØĄ ŲŲ Ø§ŲŲ
ŲØŦØ˛</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Ų
ØŽŲŲ ŲŲ Ø§ŲŲ
ŲØŦØ˛</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_feed_summary_off">ŲØšØąØļ ŲŲ Ø§ŲŲ
ŲØŦØ˛</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_feed_summary_off">ŲŲØšØąØļ ŲŲ Ø§ŲŲ
ŲØŦØ˛</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_search_title">ØĨØŽŲØ§ØĄ ŲŲ ŲØĒØ§ØĻØŦ Ø§ŲØ¨ØØĢ</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_search_summary_on">Ų
ØŽŲŲ ŲŲ ŲØĒØ§ØĻØŦ Ø§ŲØ¨ØØĢ</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_search_summary_off">ŲØ¸ŲØą ŲŲ ŲØĒØ§ØĻØŦ Ø§ŲØ¨ØØĢ</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_search_summary_off">ŲŲØšØąØļ ŲŲ ŲØĒØ§ØĻØŦ Ø§ŲØ¨ØØĢ</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">ØĨØŽŲØ§ØĄ ŲŲ Ø§ŲŲŲØ¯ŲŲŲØ§ØĒ ذاØĒ Ø§ŲØĩŲØŠ</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Ų
ØŽŲŲ ŲŲ Ø§ŲŲŲØ¯ŲŲŲØ§ØĒ ذاØĒ Ø§ŲØĩŲØŠ</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">ŲØšØąØļ ŲŲ Ø§ŲŲŲØ¯ŲŲŲØ§ØĒ ذاØĒ Ø§ŲØĩŲØŠ</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">ŲŲØšØąØļ ŲŲ Ø§ŲŲŲØ¯ŲŲŲØ§ØĒ ذاØĒ Ø§ŲØĩŲØŠ</string>
|
||||
<string name="revanced_comments_screen_title">Ø§ŲØĒØšŲŲŲØ§ØĒ</string>
|
||||
<string name="revanced_comments_screen_summary">ØĨØŽŲØ§ØĄ ØŖŲ ØšØąØļ Ų
ŲŲŲØ§ØĒ ŲØŗŲ
Ø§ŲØĒØšŲŲŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_title">ØĨØŽŲØ§ØĄ Ų
ŲØŽØĩ Ø¯ØąØ¯Ø´ØŠ Ø§ŲØ°ŲØ§ØĄ Ø§ŲØ§ØĩØˇŲØ§ØšŲ</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_title">ØĨØŽŲØ§ØĄ Ų
ŲØŽØĩ Ų
ØØ§Ø¯ØĢاØĒ Ø§ŲØ°ŲØ§ØĄ Ø§ŲØ§ØĩØˇŲØ§ØšŲ</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ų
ŲØŽØĩ اŲŲ
ØØ§Ø¯ØĢاØĒ</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_off">ŲØĒŲ
ØšØąØļ Ų
ŲØŽØĩ اŲŲ
ØØ§Ø¯ØĢاØĒ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_title">ØĨØŽŲØ§ØĄ Ų
ŲØŽØĩ ØĒØšŲŲŲØ§ØĒ Ø§ŲØ°ŲØ§ØĄ Ø§ŲØ§ØĩØˇŲØ§ØšŲ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_on">Ų
ŲØŽØĩ Ø§ŲØĒØšŲŲŲØ§ØĒ Ų
ØŽŲŲ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_off">Ų
ŲØŽØĩ Ø§ŲØĒØšŲŲŲØ§ØĒ Ų
ØšØąŲØļ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ų
ŲØŽØĩ Ø§ŲØĒØšŲŲŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_off">ŲØĒŲ
ØšØąØļ Ų
ŲØŽØĩ Ø§ŲØĒØšŲŲŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_comments_by_members_header_title">ØĨØŽŲØ§ØĄ ØąØŖØŗ \'ØĒØšŲŲŲØ§ØĒ Ø§ŲØŖØšØļØ§ØĄ\'</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ØšŲØ§Ų
ØŠ ØĒØšŲŲŲØ§ØĒ Ų
Ų Ø§ŲØŖØšØļØ§ØĄ</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_off">ŲØĒŲ
ØšØąØļ ØšŲØ§Ų
ØŠ ØĒØšŲŲŲØ§ØĒ Ų
Ų Ø§ŲØŖØšØļØ§ØĄ</string>
|
||||
<string name="revanced_hide_comments_section_title">ØĨØŽŲØ§ØĄ ŲØŗŲ
Ø§ŲØĒØšŲŲŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_comments_section_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ŲØŗŲ
Ø§ŲØĒØšŲŲŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_comments_section_summary_off">ŲØĒŲ
ØšØąØļ ŲØŗŲ
Ø§ŲØĒØšŲŲŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_comments_create_a_short_button_title">ØĨØŽŲØ§ØĄ Ø˛Øą \'ØĨŲØ´Ø§ØĄ Ų
ŲØˇØš Short\'</string>
|
||||
<string name="revanced_hide_comments_create_a_short_button_title">ØĨØŽŲØ§ØĄ Ø˛Øą \'ØĨŲØ´Ø§ØĄ Short\'</string>
|
||||
<string name="revanced_hide_comments_create_a_short_button_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ø˛Øą ØĨŲØ´Ø§ØĄ Short</string>
|
||||
<string name="revanced_hide_comments_create_a_short_button_summary_off">ŲØĒŲ
ØšØąØļ Ø˛Øą ØĨŲØ´Ø§ØĄ Short</string>
|
||||
<string name="revanced_hide_comments_timestamp_and_emoji_buttons_title">ØĨØŽŲØ§ØĄ ØŖØ˛ØąØ§Øą Ø§ŲØąŲ
ŲØ˛ Ø§ŲØĒØšØ¨ŲØąŲØŠ ŲØ§ŲØˇŲØ§Ø¨Øš Ø§ŲØ˛Ų
ŲŲØŠ</string>
|
||||
@@ -305,7 +305,7 @@ Second \"item\" text"</string>
|
||||
<!-- 'Component path builder strings' is the technical name for identifying the Litho UI layout items to hide. This is an advanced feature and most users will never use this. -->
|
||||
<string name="revanced_custom_filter_strings_summary">ŲØ§ØĻŲ
ØŠ ØŗŲØ§ØŗŲ Ų
ŲØ´ØĻ Ų
ØŗØ§Øą اŲŲ
ŲŲŲØ§ØĒ اŲŲ
ØąØ§Ø¯ ØĒØĩŲŲØĒŲØ§ Ų
ŲØĩŲŲØŠ Ø¨ØŗØˇØą ØŦØ¯ŲØ¯</string>
|
||||
<string name="revanced_custom_filter_toast_invalid_syntax">ŲŲØĒØą Ų
ØŽØĩØĩ ØēŲØą ØĩØ§ŲØ: %s</string>
|
||||
<string name="revanced_hide_keyword_content_screen_title">ØĨØŽŲØ§ØĄ Ų
ØØĒŲŲ Ø§ŲŲŲŲ
اØĒ Ø§ŲØąØĻŲØŗŲØŠ</string>
|
||||
<string name="revanced_hide_keyword_content_screen_title">ØĨØŽŲØ§ØĄ Ų
ØØĒŲŲ Ø§ŲŲŲŲ
اØĒ اŲŲ
ŲØĒØ§ØŲØŠ</string>
|
||||
<string name="revanced_hide_keyword_content_screen_summary">ØĨØŽŲØ§ØĄ ŲŲØ¯ŲŲŲØ§ØĒ Ø§ŲØ¨ØØĢ ŲØ§ŲŲ
ŲØŦØ˛ Ø¨Ø§ØŗØĒ؎داŲ
ŲŲØ§ØĒØą اŲŲŲŲ
اØĒ اŲŲ
ŲØĒØ§ØŲØŠ</string>
|
||||
<string name="revanced_hide_keyword_content_home_title">ØĨØŽŲØ§ØĄ ŲŲØ¯ŲŲŲØ§ØĒ Ø§ŲØĩŲØØŠ Ø§ŲØąØĻŲØŗŲØŠ Ø¨ŲØ§ØŗØˇØŠ اŲŲŲŲ
اØĒ اŲŲ
ŲØĒØ§ØŲØŠ</string>
|
||||
<string name="revanced_hide_keyword_content_home_summary_on">ØĒØĒŲ
ØĒØĩŲŲØŠ Ø§ŲŲŲØ¯ŲŲŲØ§ØĒ ŲŲ ØšŲØ§Ų
ØŠ Ø§ŲØĒØ¨ŲŲØ¨ \"Ø§ŲØĩŲØØŠ Ø§ŲØąØĻŲØŗŲØŠ\" ØØŗØ¨ اŲŲŲŲ
اØĒ اŲŲ
ŲØĒØ§ØŲØŠ</string>
|
||||
@@ -335,11 +335,11 @@ Second \"item\" text"</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc.) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_summary">ØŗŲØ¤Ø¯Ų ŲØļØš ØšŲØ§Ų
ØŠ Ø§ŲØĒØ¨Ø§Øŗ Ų
Ø˛Ø¯ŲØŦØŠ ØŲŲ ŲŲŲ
ØŠ ØąØĻŲØŗŲØŠ/ØšØ¨Ø§ØąØŠ ØĨŲŲ Ų
ب𠨧بǨˇØ§Ø¨ŲاØĒ Ø§ŲØŦØ˛ØĻŲØŠ ŲØšŲاŲŲŲ Ø§ŲŲŲØ¯ŲŲ ŲØŖØŗŲ
Ø§ØĄ اŲŲŲŲØ§ØĒ.<br><br>ØšŲŲ ØŗØ¨ŲŲ Ø§ŲŲ
ØĢØ§ŲØ<br><b>\"ai\"</b> ØŗŲØŽŲŲ Ø§ŲŲŲØ¯ŲŲ: <b>How does AI work?</b><br>ŲŲŲŲ ŲŲ ŲØŽŲŲ: <b>What does fair use mean?</b></string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">ŲØ§ ŲŲ
ŲŲ Ø§ØŗØĒ؎داŲ
اŲŲŲŲ
ØŠ Ø§ŲØąØĻŲØŗŲØŠ: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common_whole_word_required">ØĨØļØ§ŲØŠ Ø§ŲØĒØ¨Ø§ØŗØ§ØĒ ŲØ§ØŗØĒ؎داŲ
اŲŲŲŲ
ØŠ Ø§ŲØąØĻŲØŗŲØŠ: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_conflicting">اŲŲŲŲ
ØŠ Ø§ŲØąØĻŲØŗŲØŠ ŲŲØ§ Ø¨ŲØ§ŲاØĒ Ų
ØĒØļØ§ØąØ¨ØŠ: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">اŲŲŲŲ
ØŠ Ø§ŲØąØĻŲØŗŲØŠ ŲØĩŲØąØŠ ØŦØ¯ŲØ§ ŲØĒØĒØˇŲب Ø§ŲØĒØ¨Ø§ØŗØ§ØĒ: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">اŲŲŲŲ
ØŠ Ø§ŲØąØĻŲØŗŲØŠ ØŗŲŲ ØĒØŽŲŲ ØŦŲ
ب𠨧ŲŲŲØ¯ŲŲŲØ§ØĒ: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">ŲØ§ ŲŲ
ŲŲ Ø§ØŗØĒ؎داŲ
اŲŲŲŲ
ØŠ اŲŲ
ŲØĒØ§ØŲØŠ: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common_whole_word_required">ØĨØļØ§ŲØŠ Ø§ŲØĒØ¨Ø§ØŗØ§ØĒ ŲØ§ØŗØĒ؎داŲ
اŲŲŲŲ
ØŠ اŲŲ
ŲØĒØ§ØŲØŠ: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_conflicting">اŲŲŲŲ
ØŠ اŲŲ
ŲØĒØ§ØŲØŠ ŲŲØ§ Ø¨ŲØ§ŲاØĒ Ų
ØĒØļØ§ØąØ¨ØŠ: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">اŲŲŲŲ
ØŠ اŲŲ
ŲØĒØ§ØŲØŠ ŲØĩŲØąØŠ ØŦØ¯ŲØ§ ŲØĒØĒØˇŲب Ø§ŲØĒØ¨Ø§ØŗØ§ØĒ: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">اŲŲŲŲ
ØŠ اŲŲ
ŲØĒØ§ØŲØŠ ØŗŲŲ ØĒØŽŲŲ ØŦŲ
ب𠨧ŲŲŲØ¯ŲŲŲØ§ØĒ: %s</string>
|
||||
</patch>
|
||||
<patch id="ad.general.hideAdsResourcePatch">
|
||||
<string name="revanced_hide_general_ads_title">ØĨØŽŲØ§ØĄ Ø§ŲØĨØšŲØ§ŲاØĒ Ø§ŲØšØ§Ų
ØŠ</string>
|
||||
@@ -359,20 +359,20 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_title">ØĨØŽŲØ§ØĄ Ø¨ØˇØ§ŲØ§ØĒ Ø§ŲØąØšØ§ŲØŠ Ø§ŲØ°Ø§ØĒŲØŠ</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ø¨ØˇØ§ŲØ§ØĒ Ø§ŲØąØšØ§ŲØŠ Ø§ŲØ°Ø§ØĒŲØŠ</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_off">ŲØĒŲ
ØšØąØļ Ø¨ØˇØ§ŲØ§ØĒ Ø§ŲØąØšØ§ŲØŠ Ø§ŲØ°Ø§ØĒŲØŠ</string>
|
||||
<string name="revanced_hide_products_banner_title">ØĨØŽŲØ§ØĄ ŲØ§ŲØĒØŠ \"ØšØąØļ اŲŲ
ŲØĒØŦاØĒ\"</string>
|
||||
<string name="revanced_hide_products_banner_title">ØĨØŽŲØ§ØĄ ŲØ§ŲØĒØŠ \'ØšØąØļ اŲŲ
ŲØĒØŦاØĒ\'</string>
|
||||
<string name="revanced_hide_products_banner_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ø§ŲØ¨Ø§ŲØą</string>
|
||||
<string name="revanced_hide_products_banner_summary_off">ŲØĒŲ
ØšØąØļ Ø§ŲØ¨Ø§ŲØą</string>
|
||||
<string name="revanced_hide_end_screen_store_banner_title">ØĨØŽŲØ§ØĄ ŲØ§ŲØĒØŠ شاش؊ اŲŲ
ØĒØŦØą اŲŲŲØ§ØĻŲØŠ</string>
|
||||
<string name="revanced_hide_end_screen_store_banner_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ŲØ§ŲØĒØŠ اŲŲ
ØĒØŦØą</string>
|
||||
<string name="revanced_hide_end_screen_store_banner_summary_off">ŲØĒŲ
ØšØąØļ ŲØ§ŲØĒØŠ اŲŲ
ØĒØŦØą</string>
|
||||
<string name="revanced_hide_player_store_shelf_title">ØĨØŽŲØ§ØĄ ØąŲ Ų
Ø´ØēŲ Ø§ŲØĒØŗŲŲ</string>
|
||||
<string name="revanced_hide_player_store_shelf_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ØąŲŲŲ Ø§ŲØĒØŗŲŲ</string>
|
||||
<string name="revanced_hide_player_store_shelf_summary_off">ŲØĒŲ
ØšØąØļ ØąŲŲŲ Ø§ŲØĒØŗŲŲ</string>
|
||||
<string name="revanced_hide_player_store_shelf_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ØąŲ Ø§ŲØĒØŗŲŲ</string>
|
||||
<string name="revanced_hide_player_store_shelf_summary_off">ŲØĒŲ
ØšØąØļ ØąŲ Ø§ŲØĒØŗŲŲ</string>
|
||||
<string name="revanced_hide_shopping_links_title">ØĨØŽŲØ§ØĄ ØąŲØ§Ø¨Øˇ Ø§ŲØĒØŗŲŲ ŲŲ ŲØĩŲ Ø§ŲŲŲØ¯ŲŲ</string>
|
||||
<string name="revanced_hide_shopping_links_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ØąŲØ§Ø¨Øˇ Ø§ŲØĒØŗŲŲ ŲŲ ŲØĩŲ Ø§ŲŲŲØ¯ŲŲ</string>
|
||||
<string name="revanced_hide_shopping_links_summary_off">ŲØĒŲ
ØšØąØļ ØąŲØ§Ø¨Øˇ Ø§ŲØĒØŗŲŲ ŲŲ ŲØĩŲ Ø§ŲŲŲØ¯ŲŲ</string>
|
||||
<!-- 'Visit store' should be translated with the same localized wording that YouTube displays. -->
|
||||
<string name="revanced_hide_visit_store_button_title">ØĨØŽŲØ§ØĄ Ø˛Øą \"Ø˛ŲØ§ØąØŠ اŲŲ
ØĒØŦØą\" ØšŲŲ ØĩŲØØ§ØĒ اŲŲŲØ§ØŠ</string>
|
||||
<string name="revanced_hide_visit_store_button_title">ØĨØŽŲØ§ØĄ Ø˛Øą \'Ø˛ŲØ§ØąØŠ اŲŲ
ØĒØŦØą\' ØšŲŲ ØĩŲØØ§ØĒ اŲŲŲØ§ØŠ</string>
|
||||
<string name="revanced_hide_visit_store_button_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ø§ŲØ˛Øą ŲŲ ØĩŲØØŠ اŲŲŲØ§ØŠ</string>
|
||||
<string name="revanced_hide_visit_store_button_summary_off">ŲØĒŲ
ØšØąØļ Ø§ŲØ˛Øą ŲŲ ØĩŲØØŠ اŲŲŲØ§ØŠ</string>
|
||||
<string name="revanced_hide_web_search_results_title">ØĨØŽŲØ§ØĄ ŲØĒØ§ØĻØŦ Ø¨ØØĢ Ø§ŲŲŲØ¨</string>
|
||||
@@ -387,7 +387,7 @@ Second \"item\" text"</string>
|
||||
<patch id="ad.getpremium.hideGetPremiumPatch">
|
||||
<string name="revanced_hide_get_premium_title">ØĨØŽŲØ§ØĄ ØĒØąŲŲØŠ YouTube Premium</string>
|
||||
<string name="revanced_hide_get_premium_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ØšØąŲØļ YouTube Premium Ø§ŲØĒØąŲŲØŦŲØŠ ØĒØØĒ Ų
Ø´ØēŲ Ø§ŲŲŲØ¯ŲŲ</string>
|
||||
<string name="revanced_hide_get_premium_summary_off">ŲØĒŲ
ØšØąØļ ØšØąŲØļ YouTube Premium Ø§ŲØĒØąŲŲØŦŲØŠ ØĒØØĒ Ų
Ø´ØēŲ Ø§ŲŲŲØ¯ŲŲ</string>
|
||||
<string name="revanced_hide_get_premium_summary_off">ŲØĒŲ
ØĨØ¸ŲØ§Øą ØšØąŲØļ YouTube Premium Ø§ŲØĒØąŲŲØŦŲØŠ ØĒØØĒ Ų
Ø´ØēŲ Ø§ŲŲŲØ¯ŲŲ</string>
|
||||
</patch>
|
||||
<patch id="ad.video.videoAdsPatch">
|
||||
<string name="revanced_hide_video_ads_title">ØĨØŽŲØ§ØĄ ØĨØšŲØ§ŲاØĒ اŲŲŲØ¯ŲŲ</string>
|
||||
@@ -430,9 +430,9 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_disable_precise_seeking_gesture_summary_off">ØĒŲ
ØĒŲ
ŲŲŲ Ø§ŲØĨŲŲ
Ø§ØĄØŠ</string>
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSeekbarTappingPatch">
|
||||
<string name="revanced_seekbar_tapping_title">ØĒŲ
ŲŲŲ Ø§ŲŲŲØą ŲŲØ¨ØØĢ</string>
|
||||
<string name="revanced_seekbar_tapping_summary_on">ØĒŲ
ØĒŲ
ŲŲŲ Ø§ŲŲŲØą ŲŲØĒŲŲŲ</string>
|
||||
<string name="revanced_seekbar_tapping_summary_off">ØĒŲ
ØĒØšØˇŲŲ Ø§ŲŲŲØą ŲŲØ¨ØØĢ</string>
|
||||
<string name="revanced_seekbar_tapping_title">ØĒŲ
ŲŲŲ Ø§ŲŲŲØą ŲŲØĒŲ
ØąŲØą</string>
|
||||
<string name="revanced_seekbar_tapping_summary_on">ØĒŲ
ØĒŲ
ŲŲŲ Ø§ŲŲŲØą ŲŲØĒŲ
ØąŲØą</string>
|
||||
<string name="revanced_seekbar_tapping_summary_off">ØĒŲ
ØĒØšØˇŲŲ Ø§ŲŲŲØą ŲŲØĒŲ
ØąŲØą</string>
|
||||
</patch>
|
||||
<patch id="interaction.swipecontrols.swipeControlsResourcePatch">
|
||||
<string name="revanced_swipe_brightness_title">Ø§ŲØĒØŲŲ
Ø¨Ø§ŲØŗØˇŲØš ØšŲ ØˇØąŲŲ Ø§ŲŲ
Ø§ØĄØŠ Ø§ŲØĒŲ
ØąŲØą</string>
|
||||
@@ -555,6 +555,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_disable_translucent_status_bar_title">ØĒØšØˇŲŲ Ø´ØąŲØˇ Ø§ŲØØ§ŲØŠ Ø§ŲØ´ŲاŲ</string>
|
||||
<string name="revanced_disable_translucent_status_bar_summary_on">Ø´ØąŲØˇ Ø§ŲØØ§ŲØŠ ØēŲØą Ø´ŲاŲ</string>
|
||||
<string name="revanced_disable_translucent_status_bar_summary_off">Ø´ØąŲØˇ Ø§ŲØØ§ŲØŠ Ų
ØšØĒŲ
ØŖŲ Ø´ŲØ§Ų</string>
|
||||
<string name="revanced_disable_translucent_status_bar_user_dialog_message">ŲŲ Ø¨ØšØļ Ø§ŲØŖØŦŲØ˛ØŠØ ŲØ¯ ŲØ¤Ø¯Ų ØĒŲ
ŲŲŲ ŲØ°Ų اŲŲ
ŲØ˛ØŠ ØĨŲŲ ØĒØēŲŲØą Ø´ØąŲØˇ Ø§ŲØĒŲŲŲ ŲŲ Ø§ŲŲØ¸Ø§Ų
ØĨŲŲ Ø´ŲØ§Ų.</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_title">ØĒØšØˇŲŲ Ø§ŲØ´ØąŲØˇ Ø§ŲØ´ŲØ§Ų Ø§ŲŲØ§ØĒØ</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_summary_on">Ø´ØąŲØˇ Ø§ŲØĒŲŲŲ ŲŲ Ø§ŲŲØļØš اŲŲØ§ØĒØ ØēŲØą Ø´ŲاŲ</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_summary_off">Ø´ØąŲØˇ Ø§ŲØĒŲŲŲ ŲŲ Ø§ŲŲØļØš اŲŲØ§ØĒØ Ų
ØšØĒŲ
Ø§Ų Ø´ŲØ§Ų</string>
|
||||
@@ -666,17 +667,17 @@ Second \"item\" text"</string>
|
||||
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
||||
<string name="revanced_hide_shorts_home_title">ØĨØŽŲØ§ØĄ Shorts ŲŲ Ų
ŲØŦØ˛ Ø§ŲØĩŲØØŠ Ø§ŲØąØĻŲØŗŲØŠ</string>
|
||||
<string name="revanced_hide_shorts_home_summary_on">Ų
ØŽŲŲØŠ ŲŲ Ø§ŲØĩŲØØŠ Ø§ŲØąØĻŲØŗŲØŠ ŲØ§ŲŲŲØ¯ŲŲŲØ§ØĒ ذاØĒ Ø§ŲØĩŲØŠ</string>
|
||||
<string name="revanced_hide_shorts_home_summary_off">ØĒØšØąØļ ŲŲ Ø§ŲØĩŲØØŠ Ø§ŲØąØĻŲØŗŲØŠ ŲØ§ŲŲŲØ¯ŲŲŲØ§ØĒ ذاØĒ Ø§ŲØĩŲØŠ</string>
|
||||
<string name="revanced_hide_shorts_home_summary_off">ØĒŲØšØąØļ ŲŲ Ø§ŲØĩŲØØŠ Ø§ŲØąØĻŲØŗŲØŠ ŲØ§ŲŲŲØ¯ŲŲŲØ§ØĒ ذاØĒ Ø§ŲØĩŲØŠ</string>
|
||||
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
||||
<string name="revanced_hide_shorts_subscriptions_title">ØĨØŽŲØ§ØĄ Shorts ŲŲ Ų
ŲØŦØ˛ Ø§ŲØ§Ø´ØĒØąØ§ŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_shorts_subscriptions_summary_on">Ų
ØŽŲŲØŠ ŲŲ Ų
ŲØŦØ˛ Ø§ŲØ§Ø´ØĒØąØ§ŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_shorts_subscriptions_summary_off">ØĒØšØąØļ ŲŲ Ų
ŲØŦØ˛ Ø§ŲØ§Ø´ØĒØąØ§ŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_shorts_subscriptions_summary_off">ØĒŲØšØąØļ ŲŲ Ų
ŲØŦØ˛ Ø§ŲØ§Ø´ØĒØąØ§ŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_shorts_search_title">ØĨØŽŲØ§ØĄ Shorts ŲŲ ŲØĒØ§ØĻØŦ Ø§ŲØ¨ØØĢ</string>
|
||||
<string name="revanced_hide_shorts_search_summary_on">Ų
ØŽŲŲØŠ ŲŲ ŲØĒØ§ØĻØŦ Ø§ŲØ¨ØØĢ</string>
|
||||
<string name="revanced_hide_shorts_search_summary_off">ØĒØšØąØļ ŲŲ ŲØĒØ§ØĻØŦ Ø§ŲØ¨ØØĢ</string>
|
||||
<string name="revanced_hide_shorts_search_summary_off">ØĒŲØšØąØļ ŲŲ ŲØĒØ§ØĻØŦ Ø§ŲØ¨ØØĢ</string>
|
||||
<string name="revanced_hide_shorts_history_title">ØĨØŽŲØ§ØĄ Shorts ŲŲ ØŗØŦŲ Ø§ŲŲ
Ø´Ø§ŲØ¯ØŠ</string>
|
||||
<string name="revanced_hide_shorts_history_summary_on">Ų
ØŽŲŲØŠ ŲŲ ØŗØŦŲ Ø§ŲŲ
Ø´Ø§ŲØ¯ØŠ</string>
|
||||
<string name="revanced_hide_shorts_history_summary_off">ØĒØšØąØļ ŲŲ ØŗØŦŲ Ø§ŲŲ
Ø´Ø§ŲØ¯ØŠ</string>
|
||||
<string name="revanced_hide_shorts_history_summary_off">ØĒŲØšØąØļ ŲŲ ØŗØŦŲ Ø§ŲŲ
Ø´Ø§ŲØ¯ØŠ</string>
|
||||
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
||||
<string name="revanced_hide_shorts_join_button_title">ØĨØŽŲØ§ØĄ Ø˛Øą Ø§ŲØ§ŲØļŲ
اŲ
</string>
|
||||
<string name="revanced_hide_shorts_join_button_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ø˛Øą Ø§ŲØ§ŲØļŲ
اŲ
</string>
|
||||
@@ -765,7 +766,7 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="layout.hide.endscreensuggestion.hideEndScreenSuggestedVideoPatch">
|
||||
<string name="revanced_end_screen_suggested_video_title">ØĨØŽŲØ§ØĄ اŲŲŲØ¯ŲŲ Ø§ŲŲ
بǨਠŲŲ Ø´Ø§Ø´ØŠ اŲŲŲØ§ŲØŠ</string>
|
||||
<string name="revanced_end_screen_suggested_video_summary_on">"ŲØĒŲ
ØĨØŽŲØ§ØĄ اŲŲŲØ¯ŲŲ Ø§ŲŲ
بǨਠŲŲ Ø´Ø§Ø´ØŠ اŲŲŲØ§ŲØŠ ØšŲØ¯ ØĨŲŲØ§Ų Ø§ŲØĒØ´ØēŲŲ Ø§ŲØĒŲŲØ§ØĻŲ
|
||||
<string name="revanced_end_screen_suggested_video_summary_on">"ØĒŲ
ØĨØŽŲØ§ØĄ اŲŲŲØ¯ŲŲ Ø§ŲŲ
بǨਠŲŲ Ø´Ø§Ø´ØŠ اŲŲŲØ§ŲØŠ ØšŲØ¯ ØĨŲŲØ§Ų Ø§ŲØĒØ´ØēŲŲ Ø§ŲØĒŲŲØ§ØĻŲ
|
||||
|
||||
ŲŲ
ŲŲ ØĒØēŲŲØą Ø§ŲØĒØ´ØēŲŲ Ø§ŲØĒŲŲØ§ØĻŲ ŲŲ ØĨؚداداØĒ YouTube:
|
||||
Ø§ŲØĨؚداداØĒ â Ø§ŲØĒØ´ØēŲŲ â ØĒØ´ØēŲŲ Ø§ŲŲŲØ¯ŲŲ Ø§ŲØĒØ§ŲŲ ØĒŲŲØ§ØĻŲŲØ§"</string>
|
||||
@@ -863,7 +864,7 @@ Second \"item\" text"</string>
|
||||
|
||||
Ų
ØĩØēØąØ§ØĒ Ø´ØąŲØˇ Ø§ŲØĒŲØ¯Ų
ØŗŲŲ ØĒØŗØĒ؎دŲ
ŲŲØŗ ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ Ø§ŲØØ§ŲŲ.
|
||||
|
||||
ØĒØšŲ
Ų ŲØ°Ų اŲŲ
ŲØ˛ØŠ بشŲŲ ØŖŲØļŲ Ų
Øš ØŦŲØ¯ØŠ ŲŲØ¯ŲŲ 720p ØŖŲ ØŖŲŲ ŲØšŲد Ø§ØŗØĒ؎داŲ
اØĒØĩØ§Ų ØĨŲØĒØąŲØĒ ØŗØąŲØš ØŦداŲ."</string>
|
||||
ØĒØšŲ
Ų ŲØ°Ų اŲŲ
ŲØ˛ØŠ بشŲŲ ØŖŲØļŲ Ų
Øš ØŦŲØ¯ØŠ ŲŲØ¯ŲŲ 720p ØŖŲ ØŖŲŲ ŲØšŲد Ø§ØŗØĒ؎داŲ
اØĒØĩØ§Ų ØĨŲØĒØąŲØĒ ØŗØąŲØš ØŦØ¯ŲØ§."</string>
|
||||
<string name="revanced_restore_old_seekbar_thumbnails_title">Ø§ØŗØĒؚاد؊ Ų
ØĩØēØąØ§ØĒ Ø´ØąŲØˇ Ø§ŲØĒŲØ¯Ų
اŲŲØ¯ŲŲ
ØŠ</string>
|
||||
<string name="revanced_restore_old_seekbar_thumbnails_summary_on">Ų
ØĩØēØąØ§ØĒ Ø´ØąŲØˇ Ø§ŲØĒŲØ¯Ų
ØŗØĒØ¸ŲØą ŲŲŲ Ø´ØąŲØˇ ØĒŲØ¯Ų
اŲŲŲØ¯ŲŲ</string>
|
||||
<string name="revanced_restore_old_seekbar_thumbnails_summary_off">Ų
ØĩØēØąØ§ØĒ Ø´ØąŲØˇ Ø§ŲØĒŲØ¯Ų
ØŗØĒØ¸ŲØą ŲŲ Ų
ŲØĄ Ø§ŲØ´Ø§Ø´ØŠ</string>
|
||||
@@ -936,15 +937,15 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_sb_settings_revanced_export_user_id_warning_dismiss">ŲØ§ ØĒØšØąØļ Ų
ØąØŠ ØŖØŽØąŲ</string>
|
||||
<string name="revanced_sb_diff_segments">ØĒØēŲŲØą ØŗŲŲŲ Ø§ŲŲ
ŲØˇØš</string>
|
||||
<string name="revanced_sb_segments_sponsor">Ø§ŲØąØ§ØšŲ</string>
|
||||
<string name="revanced_sb_segments_sponsor_sum">Ø§ŲØĒØąŲŲØŦ اŲŲ
دŲب𠨧بŖØŦØąØ ŲØ§ŲØĨØØ§ŲاØĒ اŲŲ
دŲŲØšØŠ Ø§ŲØŖØŦØą ŲØ§ŲØĨØšŲØ§ŲاØĒ اŲŲ
Ø¨Ø§Ø´ØąØŠ. ŲŲØŗ ŲŲØĒØąŲŲØŦ Ø§ŲØ°Ø§ØĒŲ ØŖŲ ŲØĩØąØ§ØšØ§ØĒ Ų
ØŦاŲŲØŠ ŲŲب﨧ب§/اŲŲ
بدؚŲŲ/اŲŲ
ŲØ§ŲØš Ø§ŲØĨŲŲØĒØąŲŲŲØŠ/اŲŲ
ŲØĒØŦاØĒ Ø§ŲØĒŲ ŲØØ¨ŲŲ Ø§ŲØØĩŲŲ ØšŲŲŲØ§</string>
|
||||
<string name="revanced_sb_segments_sponsor_sum">Ø§ŲØĒØąŲŲØŦ اŲŲ
دŲŲØšØ ŲØ§ŲØĨØØ§ŲاØĒ اŲŲ
دŲŲØšØŠØ ŲØ§ŲØĨØšŲØ§ŲاØĒ اŲŲ
Ø¨Ø§Ø´ØąØŠ. ŲŲØŗ ŲŲØĒØąŲŲØŦ Ø§ŲØ°Ø§ØĒŲ ØŖŲ Ø§ŲØĒØąŲŲØŦ اŲŲ
ØŦاŲŲ ŲŲب﨧ب§/اŲŲ
بدؚŲŲ/اŲŲ
ŲØ§ŲØš Ø§ŲØĨŲŲØĒØąŲŲŲØŠ/اŲŲ
ŲØĒØŦاØĒ Ø§ŲØĒŲ ŲŲØļŲŲŲŲØ§</string>
|
||||
<string name="revanced_sb_segments_selfpromo">ØĒØąŲŲØŦ Ø´ØŽØĩŲ/ØēŲØą Ų
دŲب𠨧بŖØŦØą</string>
|
||||
<string name="revanced_sb_segments_selfpromo_sum">Ų
Ø´Ø§Ø¨ŲØŠ ŲŲ \"Ø§ŲØąØ§ØšŲ\" Ø¨Ø§ØŗØĒØĢŲØ§ØĄ Ų
ا ŲØĒØšŲŲ Ø¨Ø§ŲØĨØšŲØ§ŲاØĒ ØēŲØą Ø§ŲŲ
دŲŲØšØŠ Ø§ŲØŖØŦØą ØŖŲ Ø§ŲØ°Ø§ØĒŲØŠ. ŲŲØ´Ų
Ų Ø°ŲŲ ØŖŲØŗØ§Ų
ØšŲ Ø§ŲØŗŲØš ØŖŲ Ø§ŲØĒØ¨ØąØšØ§ØĒ ØŖŲ Ø§ŲŲ
ØšŲŲŲ
اØĒ اŲŲ
ØĒØšŲŲØŠ Ø¨Ų
Ų ØĒؚاŲŲŲØ§ Ų
Øš ŲØ§Ø´Øą اŲŲ
ØØĒŲŲ</string>
|
||||
<string name="revanced_sb_segments_selfpromo_sum">Ų
Ø´Ø§Ø¨ŲØŠ ŲŲ \'Ø§ŲØąØ§ØšŲ\' Ø¨Ø§ØŗØĒØĢŲØ§ØĄ Ų
ا ŲØĒØšŲŲ Ø¨Ø§ŲØĨØšŲØ§ŲاØĒ ØēŲØą Ø§ŲŲ
دŲŲØšØŠ Ø§ŲØŖØŦØą ØŖŲ Ø§ŲØ°Ø§ØĒŲØŠ. ŲŲØ´Ų
Ų Ø°ŲŲ ØŖŲØŗØ§Ų
ØšŲ Ø§ŲØŗŲØš ØŖŲ Ø§ŲØĒØ¨ØąØšØ§ØĒ ØŖŲ Ø§ŲŲ
ØšŲŲŲ
اØĒ اŲŲ
ØĒØšŲŲØŠ Ø¨Ų
Ų ØĒؚاŲŲŲØ§ Ų
Øš ŲØ§Ø´Øą اŲŲ
ØØĒŲŲ</string>
|
||||
<string name="revanced_sb_segments_interaction">ØĒذŲŲØą Ø¨Ø§ŲØĒŲØ§ØšŲ (اشØĒØąØ§Ų)</string>
|
||||
<string name="revanced_sb_segments_interaction_sum">ØĒذŲŲØą ŲØĩŲØą ŲŲØĨØšØŦاب ØŖŲ Ø§ŲØ§Ø´ØĒØąØ§Ų ØŖŲ Ø§ŲŲ
ØĒابؚ؊ ŲŲ Ų
ŲØĒØĩŲ Ø§ŲŲ
ØØĒŲŲ. ØĨذا ŲØ§ŲØĒ ØˇŲŲŲØŠ ØŖŲ ØĒØĒØšŲŲ Ø¨Ø´ŲØĄ Ų
ØØ¯Ø¯Ø ŲŲØŦب ØŖŲ ØĒŲŲŲ ØŽØ§Øļؚ؊ ŲŲØĒØąŲŲØŦ Ø§ŲØ´ØŽØĩŲ Ø¨Ø¯ŲØ§Ų Ų
Ų Ø°ŲŲ</string>
|
||||
<string name="revanced_sb_segments_highlight">Ø§ŲØŖØ¨ØąØ˛</string>
|
||||
<string name="revanced_sb_segments_highlight_sum">Ø§ŲØŦØ˛ØĄ Ų
Ų Ø§ŲŲŲØ¯ŲŲ Ø§ŲØ°Ų ŲØ¨ØØĢ ØšŲŲ Ų
ؚظŲ
اŲŲØ§Øŗ</string>
|
||||
<string name="revanced_sb_segments_intro">اŲŲ
ŲØ¯Ų
ØŠ/ŲØ§ØĩŲ</string>
|
||||
<string name="revanced_sb_segments_intro_sum">ŲØ§ØĩŲ Ø˛Ų
ŲŲ Ø¨Ø¯ŲŲ Ų
ØØĒŲŲ ŲØšŲŲ. ŲŲ
ŲŲ ØŖŲ ŲŲŲŲ ŲŲŲØ§Ų Ų
Ø¤ŲØĒØ§ŲØ ØŖŲ ØĨØˇØ§ØąŲØ§ ØĢابØĒØ§ŲØ ØŖŲ ØĒŲØąØ§ØąŲØ§. ŲØ§ ŲØĒØļŲ
Ų Ø§ŲØĒØŲŲØ§ØĒ Ø§ŲØĒŲ ØĒØØĒŲŲ ØšŲŲ Ų
ØšŲŲŲ
اØĒ</string>
|
||||
<string name="revanced_sb_segments_intro_sum">ŲØ§ØĩŲ Ø˛Ų
ŲŲ Ø¨Ø¯ŲŲ Ų
ØØĒŲŲ ŲØšŲŲ. ŲØ¯ ŲŲŲŲ ØĒŲŲŲŲØ§ Ų
Ø¤ŲØĒŲØ§Ø ØŖŲ ØĨØˇØ§ØąŲØ§ ØĢابØĒŲØ§Ø ØŖŲ ØąØŗŲŲ
ŲØ§ Ų
ØĒØØąŲØŠ Ų
ØĒŲØąØąØŠ. ŲØ§ ŲØĒØļŲ
Ų Ø§ŲØĒŲØ§ŲاØĒ ØĒØØĒŲŲ ØšŲŲ Ų
ØšŲŲŲ
اØĒ</string>
|
||||
<string name="revanced_sb_segments_outro">Ø§ŲØŽØ§ØĒŲ
ØŠ/ØĒØĒØąØ§ØĒ اŲŲŲØ§ŲØŠ</string>
|
||||
<string name="revanced_sb_segments_outro_sum">ØĒØĒØą اŲŲŲØ§ŲØŠ ØŖŲ ØšŲØ¯Ų
ا ØĒØ¸ŲØą Ø¨ØˇØ§ŲاØĒ ŲŲØ§ŲØŠ YouTubeØ ŲŲØ§ŲاØĒ ØēŲØą Ų
ŲØˇŲŲØŠ. ŲŲØŗ ŲŲØ§ØŗØĒŲØĒØ§ØŦاØĒ Ų
Øš اŲŲ
ØšŲŲŲ
اØĒ</string>
|
||||
<string name="revanced_sb_segments_preview">Ų
ؚاŲŲØŠ/Ų
ŲØŦØ˛/ØąØ¨Øˇ</string>
|
||||
@@ -1078,9 +1079,9 @@ Second \"item\" text"</string>
|
||||
ØĒØĩŲ
ŲŲ
Ø§ŲØŦŲØ§Ø˛ اŲŲŲØŲ
|
||||
âĸ Ų
Ø´Ø§ØąŲØ§ØĒ اŲŲ
ØŦØĒŲ
Øš Ų
ØŽŲŲØŠ
|
||||
|
||||
ØĒØĩŲ
ŲŲ
Ø§ŲØŗŲØ§ØąØŠ
|
||||
ØĒØĩŲ
ŲŲ
Automotive
|
||||
âĸ ŲØĒŲ
ŲØĒØ Shorts ŲŲ Ø§ŲŲ
Ø´ØēŲ Ø§ŲØšØ§Ø¯Ų
|
||||
âĸ ŲØĒŲ
ØĒŲØ¸ŲŲ
Ø§ŲØŽŲاØĩØŠ ØØŗØ¨ اŲŲ
ŲØ§ØļŲØš ŲØ§ŲŲŲŲØ§ØĒ"</string>
|
||||
âĸ ŲØĒŲ
ØĒŲØ¸ŲŲ
اŲŲ
ŲØŦØ˛ ØØŗØ¨ اŲŲ
ŲØ§ØļŲØš ŲØ§ŲŲŲŲØ§ØĒ"</string>
|
||||
</patch>
|
||||
<patch id="layout.spoofappversion.spoofAppVersionPatch">
|
||||
<string name="revanced_spoof_app_version_title">ØŽŲØ¯Ø§Øš ØĨØĩØ¯Ø§Øą Ø§ŲØĒØˇØ¨ŲŲ</string>
|
||||
@@ -1154,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>
|
||||
@@ -1173,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>
|
||||
@@ -1216,7 +1218,7 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="layout.thumbnails.alternativeThumbnailsPatch">
|
||||
<!-- 'Home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
||||
<string name="revanced_alt_thumbnail_home_title">ØšŲØ§Ų
ØŠ ØĒبŲŲØ¨ Ø§ŲØĩŲØØŠ Ø§ŲØąØĻŲØŗŲØŠ</string>
|
||||
<string name="revanced_alt_thumbnail_home_title">ØšŲØ§Ų
ØŠ Ø§ŲØĒØ¨ŲŲØ¨ Ø§ŲØĩŲØØŠ Ø§ŲØąØĻŲØŗŲØŠ</string>
|
||||
<!-- 'Subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
||||
<string name="revanced_alt_thumbnail_subscription_title">ØšŲØ§Ų
ØŠ Ø§ŲØĒØ¨ŲŲØ¨ Ø§ŲØ§Ø´ØĒØąØ§ŲØ§ØĒ</string>
|
||||
<!-- 'You' should be translated using the same localized wording YouTube displays for the You (library) tab. -->
|
||||
@@ -1227,11 +1229,11 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_2">DeArrow & اŲŲ
ØĩŲØēØąØ§ØĒ Ø§ŲØŖØĩŲŲØŠ</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_3">DeArrow & اŲŲŲØˇØ§ØĒ Ø§ŲØĢØ§Ø¨ØĒØŠ</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_4">اŲŲŲØˇØ§ØĒ Ø§ŲØĢØ§Ø¨ØĒØŠ</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_about_summary">"ŲŲŲØą DeArrow Ų
ØĩØēØąØ§ØĒ ŲŲØ¯ŲŲ Ų
Ų Ų
ØĩØ§Ø¯Øą ØŦŲ
Ø§ØšŲØŠ ŲŲŲØ¯ŲŲŲØ§ØĒ YouTube. ŲØ°Ų اŲŲ
ØĩØēØąØ§ØĒ ØēØ§ŲØ¨Ø§ Ų
ا ØĒŲŲŲ ØŖŲØĢØą ØĩŲØŠ Ų
Ų ØĒŲŲ Ø§ŲŲ
ŲØ¯Ų
ØŠ Ų
Ų YouTube
|
||||
<string name="revanced_alt_thumbnail_dearrow_about_summary">"ŲŲŲØą DeArrow Ų
ØĩØēØąØ§ØĒ ŲŲØ¯ŲŲ Ų
Ų Ų
ØĩØ§Ø¯Øą ØŦŲ
Ø§ØšŲØŠ ŲŲŲØ¯ŲŲŲØ§ØĒ YouTube. ŲØ°Ų اŲŲ
ØĩØēØąØ§ØĒ ØēØ§ŲØ¨Ųا Ų
ا ØĒŲŲŲ ØŖŲØĢØą ØĩŲØŠ Ų
Ų ØĒŲŲ Ø§ŲŲ
ŲØ¯Ų
ØŠ Ų
Ų YouTube
|
||||
|
||||
ØĨذا ØĒŲ
ØĒŲØšŲŲŲØ§Ø ØŗŲØĒŲ
ØĨØąØŗØ§Ų ØąŲØ§Ø¨Øˇ اŲŲŲØ¯ŲŲ ØĨŲŲ ØŽØ§Ø¯Ų
API ŲŲŲ ŲØĒŲ
ØĨØąØŗØ§Ų ØŖŲ Ø¨ŲØ§ŲاØĒ ØŖØŽØąŲ. ØĨذا ŲØ§Ų اŲŲŲØ¯ŲŲ ŲØ§ ŲØØĒŲŲ ØšŲŲ Ų
ØĩØēØąØ§ØĒ DArrowØ ØŗŲØĒŲ
ØšØąØļ اŲŲ
ŲØ§ØˇØš Ø§ŲØŖØĩŲŲØŠ ØŖŲ Ø§ŲŲŲØˇØ§ØĒ Ø§ŲØĢØ§Ø¨ØĒØŠ
|
||||
ØĨذا ØĒŲ
ØĒŲØšŲŲŲØ§Ø ØŗŲØĒŲ
ØĨØąØŗØ§Ų ØąŲØ§Ø¨Øˇ اŲŲŲØ¯ŲŲ ØĨŲŲ ØŽØ§Ø¯Ų
API ŲŲŲ ŲØĒŲ
ØĨØąØŗØ§Ų ØŖŲ Ø¨ŲØ§ŲاØĒ ØŖØŽØąŲ. ØĨذا ŲØ§Ų اŲŲŲØ¯ŲŲ ŲØ§ ŲØØĒŲŲ ØšŲŲ Ų
ØĩØēØąØ§ØĒ DeArrowØ ØŗŲØĒŲ
ØšØąØļ اŲŲ
ŲØ§ØˇØš Ø§ŲØŖØĩŲŲØŠ ØŖŲ Ø§ŲŲŲØˇØ§ØĒ Ø§ŲØĢØ§Ø¨ØĒØŠ
|
||||
|
||||
اØļØēØˇ ŲŲØ§ ŲŲ
ØšØąŲØŠ Ø§ŲŲ
Ø˛ŲØ¯ ØšŲ DArrow"</string>
|
||||
اØļØēØˇ ŲŲØ§ ŲŲ
ØšØąŲØŠ Ø§ŲŲ
Ø˛ŲØ¯ ØšŲ DeArrow"</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_title">ØšØąØļ Ų
ŲØ§ØØ¸ØŠ ØĨذا ŲØ§Ų API ØēŲØą Ų
ØĒاØ</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_on">ŲØĒŲ
ØšØąØļ Ų
ŲØ§ØØ¸ØŠ ØĨذا ŲØ§Ų DeArrow ØēŲØą Ų
ØĒŲŲØą</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_off">ŲØ§ ŲØĒŲ
ØšØąØļ Ų
ŲØ§ØØ¸ØŠ ØĨذا ŲØ§Ų DeArrow ØēŲØą Ų
ØĒŲŲØą</string>
|
||||
@@ -1307,7 +1309,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_force_original_audio_summary_on">Ø§ØŗØĒ؎داŲ
ŲØēØŠ Ø§ŲØĩŲØĒ Ø§ŲØŖØĩŲŲØŠ</string>
|
||||
<string name="revanced_force_original_audio_summary_off">Ø§ØŗØĒ؎داŲ
Ø§ŲØĩŲØĒ Ø§ŲØ§ŲØĒØąØ§ØļŲ</string>
|
||||
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||
<string name="revanced_force_original_audio_not_available">ŲØ§ØŗØĒ؎داŲ
ŲØ°Ų اŲŲ
ŲØ˛ØŠØ ØēŲŲØą \"Ø§ŲØĒØØ§Ų Ø¯ŲŲØ§ØĒ اŲŲŲØ¯ŲŲ\" ØĨŲŲ iOS TV</string>
|
||||
<string name="revanced_force_original_audio_not_available">ŲØ§ØŗØĒ؎داŲ
ŲØ°Ų اŲŲ
ŲØ˛ØŠØ ØēŲŲØą \'Spoof Video Streams\' ØĨŲŲ iOS TV</string>
|
||||
</patch>
|
||||
<patch id="video.quality.rememberVideoQualityPatch">
|
||||
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||
@@ -1321,7 +1323,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_summary_on">ØĒŲØˇØ¨Ų ØĒØēŲبਧØĒ Ø§ŲØŦŲØ¯ØŠ ØšŲŲ ØŦŲ
ŲØš ŲŲØ¯ŲŲŲØ§ØĒ Shorts</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_summary_off">ØĒŲØˇØ¨Ų ØĒØēŲبਧØĒ Ø§ŲØŦŲØ¯ØŠ ŲŲØˇ ØšŲŲ ŲŲØ¯ŲŲ Short Ø§ŲØØ§ŲŲ</string>
|
||||
<string name="revanced_shorts_quality_default_wifi_title">ØŦŲØ¯ØŠ Shorts Ø§ŲØ§ŲØĒØąØ§ØļŲØŠ ØšŲŲ Ø´Ø¨ŲØŠ Wi-Fi</string>
|
||||
<string name="revanced_shorts_quality_default_mobile_title">ØŦŲØ¯ØŠ Shorts Ø§ŲØ§ŲØĒØąØ§ØļŲØŠ ØšŲŲ Ø´Ø¨ŲØŠ Ø§ŲØŦŲØ§Ų</string>
|
||||
<string name="revanced_shorts_quality_default_mobile_title">ØŦŲØ¯ØŠ Shorts Ø§ŲØ§ŲØĒØąØ§ØļŲØŠ ØšŲŲ Ø´Ø¨ŲØŠ Ø§ŲØŦŲŲØ§Ų</string>
|
||||
<string name="revanced_remember_video_quality_mobile">Ø§ŲØŦŲŲØ§Ų</string>
|
||||
<string name="revanced_remember_video_quality_wifi">Wi-Fi</string>
|
||||
<string name="revanced_remember_video_quality_toast">ØĒŲ
ØĒØēŲŲØą ØŦŲØ¯ØŠ %1$s Ø§ŲØ§ŲØĒØąØ§ØļŲØŠ ØĨŲŲ: %2$s</string>
|
||||
@@ -1357,7 +1359,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_disable_hdr_video_summary_off">ØĒŲ
ØĒŲ
ŲŲŲ ŲŲØ¯ŲŲ HDR</string>
|
||||
</patch>
|
||||
<patch id="video.quality.advancedVideoQualityMenuPatch">
|
||||
<string name="revanced_advanced_video_quality_menu_title">ØĨØ¸ŲØ§Øą ŲØ§ØĻŲ
ØŠ ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ Ø§ŲŲ
ØĒŲØ¯Ų
ØŠ</string>
|
||||
<string name="revanced_advanced_video_quality_menu_title">ØšØąØļ ŲØ§ØĻŲ
ØŠ ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ Ø§ŲŲ
ØĒŲØ¯Ų
ØŠ</string>
|
||||
<string name="revanced_advanced_video_quality_menu_summary_on">ŲØĒŲ
ØšØąØļ ŲØ§ØĻŲ
ØŠ ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ Ø§ŲŲ
ØĒŲØ¯Ų
ØŠ</string>
|
||||
<string name="revanced_advanced_video_quality_menu_summary_off">ŲØ§ ŲØĒŲ
ØšØąØļ ŲØ§ØĻŲ
ØŠ ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ Ø§ŲŲ
ØĒŲØ¯Ų
ØŠ</string>
|
||||
</patch>
|
||||
@@ -1391,7 +1393,7 @@ AVC ŲØ¯ŲŲ ØØ¯ ØŖŲØĩŲ ŲŲØ¯ŲØŠ 1080pØ ŲØ§ ŲØĒŲŲØą ØĒØąŲ
ŲØ˛ Ø§ŲØĩ
|
||||
âĸ Ų
ØŗØĒŲŲ Ø§ŲØĩŲØĒ Ø§ŲØĢØ§Ø¨ØĒ ØēŲØą Ų
ØĒاØ
|
||||
âĸ ŲØąØļ Ø§ŲØĩŲØĒ Ø§ŲØŖØĩŲŲ ØēŲØą Ų
ØĒŲŲØą"</string>
|
||||
<string name="revanced_spoof_video_streams_about_no_av1">âĸ ŲØ§ ŲŲØŦد ØĒØąŲ
ŲØ˛ اŲŲŲØ¯ŲŲ AV1</string>
|
||||
<string name="revanced_spoof_video_streams_about_kids_videos">âĸ اŲŲŲØ¯ŲŲØ§ØĒ Ø§ŲØšØąØ¨ŲØŠ ŲØ§ ŲŲ
ŲŲ ØĒØ´ØēŲŲ ØŖŲ ŲŲ ŲØļØš Ø§ŲØĒØ´ØēŲŲ ØŖŲ ŲŲ ØØ§ŲØŠ Ø§ŲØŽŲŲØŠ</string>
|
||||
<string name="revanced_spoof_video_streams_about_kids_videos">âĸ ŲØ¯ ŲØ§ ŲØĒŲ
ØĒØ´ØēŲŲ Ø§ŲŲŲØ¯ŲŲŲØ§ØĒ اŲŲ
ØŽØĩØĩØŠ ŲŲØŖØˇŲØ§Ų ØšŲØ¯ ØĒØŗØŦŲŲ Ø§ŲØŽØąŲØŦ ØŖŲ ØšŲØ¯ Ø§ØŗØĒ؎داŲ
ŲØļØš Ø§ŲØĒØĩŲØ اŲŲ
ØĒØŽŲŲ</string>
|
||||
<string name="revanced_spoof_streaming_data_stats_for_nerds_title">ØšØąØļ ŲŲ ØĨØØĩØ§ØĄØ§ØĒ ØĒŲŲŲØŠ</string>
|
||||
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_on">ŲØĒŲ
ØšØąØļ Ųب𠨧بšŲ
ŲŲ ŲŲ ØĨØØĩØ§ØĄØ§ØĒ ØĒŲŲŲØŠ</string>
|
||||
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">ØĒŲ
ØĨØŽŲØ§ØĄ Ųب𠨧بšŲ
ŲŲ ŲŲ ØĨØØĩØ§ØĄØ§ØĒ ØĒŲŲŲØŠ</string>
|
||||
|
||||
@@ -226,6 +226,9 @@ GÃļzlÉnilmÉz hallardan xÉbÉrdar olmayacaqsÄąnÄąz."</string>
|
||||
<string name="revanced_hide_artist_cards_title">SÉnÉtçi kartlarÄąnÄą gizlÉt</string>
|
||||
<string name="revanced_hide_artist_cards_summary_on">SÉnÉtçi kartlarÄą gizlidir</string>
|
||||
<string name="revanced_hide_artist_cards_summary_off">SÉnÉtçi kartlarÄą gÃļstÉrilir</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_title">\"AI ilÉ yaradÄąlan video xÃŧlasÉsini\" gizlÉt</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_summary_on">Video xÃŧlasÉ bÃļlmÉsi gizlÉdilib</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_summary_off">Video xÃŧlasÉ bÃļlmÉsi gÃļstÉrilir</string>
|
||||
<string name="revanced_hide_attributes_section_title">AtributlarÄą GizlÉt</string>
|
||||
<string name="revanced_hide_attributes_section_summary_on">SeçilÉn yerlÉr, Oyunlar, Musiqi vÉ qeyd edilÉn insanlar bÃļlmÉlÉri gizlÉdilir</string>
|
||||
<string name="revanced_hide_attributes_section_summary_off">SeçilÉn yerlÉr, Oyunlar, Musiqi vÉ qeyd edilÉn insanlar bÃļlmÉlÉri gÃļrÃŧnÃŧr</string>
|
||||
@@ -262,8 +265,12 @@ GÃļzlÉnilmÉz hallardan xÉbÉrdar olmayacaqsÄąnÄąz."</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">ÆlaqÉli videolarda gÃļrÃŧnÃŧr</string>
|
||||
<string name="revanced_comments_screen_title">ÅÉrhlÉr</string>
|
||||
<string name="revanced_comments_screen_summary">ÅÉrhlÉr bÃļlmÉsi elementlÉrin gizlÉt vÉ ya gÃļstÉr</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_title">AI SÃļhbÉt XÃŧlasÉsini GizlÉt</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_on">SÃļhbÉt yekunu gizlidir </string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_off">SÃļhbÉt yekunu gÃļrÃŧnÃŧr</string>
|
||||
<string name="revanced_hide_comments_ai_summary_title">AI ášĸÉrhlÉr XÃŧlasÉsini GizlÉt</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_on">ášĸÉrh yekunu gizlidir </string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_off">ÅÉrh yekunu gÃļrÃŧnÃŧr</string>
|
||||
<string name="revanced_hide_comments_by_members_header_title">\'ÃzvlÉrin ÅÉrhlÉri\' baÅlÄąÄÄąnÄą gizlÉt</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_on">ÃzvlÉrin ÅÉrhlÉri baÅlÄąÄÄą gizlidir</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_off">ÃzvlÉrin ÅÉrhlÉri baÅlÄąÄÄą gÃļrÃŧnÃŧr</string>
|
||||
@@ -423,6 +430,9 @@ Bu xÃŧsusiyyÉt yalnÄąz kÃļhnÉ cihazlar ÃŧçÃŧn mÃļvcuddur"</string>
|
||||
<string name="revanced_disable_precise_seeking_gesture_summary_off">Jest aktivlÉÅdirilib</string>
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSeekbarTappingPatch">
|
||||
<string name="revanced_seekbar_tapping_title">Axtarmaq ÃŧçÃŧn toxun\'u aktivlÉÅdir</string>
|
||||
<string name="revanced_seekbar_tapping_summary_on">Axtarmaq ÃŧçÃŧn toxun, aktivdir</string>
|
||||
<string name="revanced_seekbar_tapping_summary_off">Axtarmaq ÃŧçÃŧn toxun qapalÄądÄąr</string>
|
||||
</patch>
|
||||
<patch id="interaction.swipecontrols.swipeControlsResourcePatch">
|
||||
<string name="revanced_swipe_brightness_title">ParlaqlÄąq jestini aktivlÉÅdir</string>
|
||||
@@ -435,6 +445,9 @@ EkranÄąn sol tÉrÉfindÉ dikinÉ sÃŧrÃŧÅdÃŧrÉrÉk parlaqlÄąÄÄą tÉnzimlÉyin
|
||||
|
||||
EkranÄąn saÄ tÉrÉfindÉ dÃŧzÃŧnÉ sÃŧrÃŧÅdÃŧrÉrÉk sÉs sÉviyyÉsini tÉnzimlÉ"</string>
|
||||
<string name="revanced_swipe_volume_summary_off">Tam ekran sÉs sÃŧrÃŧÅdÃŧrmÉsi qapalÄądÄąr</string>
|
||||
<string name="revanced_swipe_press_to_engage_title">SÃŧrÃŧÅdÃŧrmÉ jesti ÃŧçÃŧn sÄąxmanÄą aktiv et</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_on">SÃŧrÃŧÅdÃŧrmÉ ÃŧçÃŧn sÄąxma aktivdir</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_off">SÃŧrÃŧÅdÃŧrmÉ ÃŧçÃŧn sÄąxma qapalÄądÄąr</string>
|
||||
<string name="revanced_swipe_haptic_feedback_title">Æks-ÉlaqÉ reaksiyasÄąnÄą aktivlÉÅdir</string>
|
||||
<string name="revanced_swipe_haptic_feedback_summary_on">Æks-ÉlaqÉ reaksiyasÄą aktivlÉÅdirilib</string>
|
||||
<string name="revanced_swipe_haptic_feedback_summary_off">Æks-ÉlaqÉ reaksiyasÄą qeyri-aktivdir</string>
|
||||
@@ -542,6 +555,7 @@ Bu seçimi dÉyiÅdirmÉ iÅÉ dÃŧÅmÃŧrsÉ, Gizli rejimÉ keçmÉyÉ Ã§alÄąÅÄą
|
||||
<string name="revanced_disable_translucent_status_bar_title">YarÄąmÅÉffaf mÃļvqe cizgisin qapat</string>
|
||||
<string name="revanced_disable_translucent_status_bar_summary_on">MÃļvqe cizgisi qeyri-ÅÉffafdÄąr</string>
|
||||
<string name="revanced_disable_translucent_status_bar_summary_off">MÃļvqe cizgisi qeyri-ÅÉffaf vÉ ya ÅÉffafdÄąr</string>
|
||||
<string name="revanced_disable_translucent_status_bar_user_dialog_message">BÉzi cihazlarda bu xÃŧsusiyyÉt aktivlÉÅmÉsi sistem fÉaliyyÉt cÉrgÉsini ÅÉffaf-a dÉyiÅÉ bilÉr.</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_title">AÃ§Äąq temada ÅÉffaf cizgini qapat</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_summary_on">İÅÄąqlÄą rejim fÉaliyyÉt cÉrgÉsi qeyri-ÅÉffafdÄąr</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_summary_off">İÅÄąqlÄą rejim fÉaliyyÉt cÉrgÉsi qeyri-ÅÉffaf vÉ ya ÅÉffafdÄąr</string>
|
||||
@@ -1140,6 +1154,7 @@ Sonradan qapadÄąlarsa, UI sÉhvlÉrin ÃļnlÉmÉk ÃŧçÃŧn tÉtbiq mÉlumatlarÄąn
|
||||
<string name="revanced_miniplayer_type_entry_4">MÃŧasir 1</string>
|
||||
<string name="revanced_miniplayer_type_entry_5">MÃŧasir 2</string>
|
||||
<string name="revanced_miniplayer_type_entry_6">MÃŧasir 3</string>
|
||||
<string name="revanced_miniplayer_type_entry_7">MÃŧasir 4</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_title">DairÉvi kÃŧnclÉri aktivlÉÅdir</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_on">KÃŧnclÉr dairÉvidir</string>
|
||||
<string name="revanced_miniplayer_rounded_corners_summary_off">KÃŧnclÉr kvadratdÄąr</string>
|
||||
@@ -1159,14 +1174,14 @@ 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
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_title">ÃrtÃŧk dÃŧymÉlÉrini gizlÉt</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_on">ÃrtÃŧk dÃŧymÉlÉri gizlidir</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_summary_off">ÃrtÃŧk dÃŧymÉlÉri gÃļrÃŧnÃŧr</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_legacy_title">GeniÅlÉndir vÉ baÄla dÃŧymÉlÉrini gizlÉt</string>
|
||||
<string name="revanced_miniplayer_hide_overlay_buttons_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_overlay_buttons_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>
|
||||
|
||||
@@ -555,6 +555,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_disable_translucent_status_bar_title">ĐĐ´ĐēĐģŅŅŅŅŅ ĐŋŅаСŅŅŅŅŅŅ ĐŋаĐŊŅĐģŅ ŅŅаĐŊŅ</string>
|
||||
<string name="revanced_disable_translucent_status_bar_summary_on">ĐаĐŊŅĐģŅ ŅŅаĐŊŅ ĐŊĐĩĐŋŅаСŅŅŅŅаŅ.</string>
|
||||
<string name="revanced_disable_translucent_status_bar_summary_off">ĐаĐŊŅĐģŅ ŅŅаĐŊŅ ĐŊŅĐŋŅаСŅŅŅŅĐ°Ņ ŅŅ ĐŋŅаСŅŅŅŅаŅ.</string>
|
||||
<string name="revanced_disable_translucent_status_bar_user_dialog_message">Đа ĐŊĐĩĐēаŅĐžŅŅŅ
ĐŋŅŅĐģадаŅ
ŅĐēĐģŅŅŅĐŊĐŊĐĩ ĐŗŅŅаК ŅŅĐŊĐēŅŅŅ ĐŧĐžĐļа СĐŧŅĐŊŅŅŅ ĐŋаĐŊŅĐģŅ ĐŊавŅĐŗĐ°ŅŅŅ ŅŅŅŅŅĐŧŅ ĐŊа ĐŋŅаСŅŅŅŅŅŅ.</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_title">ĐĐ´ĐēĐģŅŅŅŅŅ ŅвĐĩŅĐģŅŅ ĐŋŅаСŅŅŅŅŅŅ ĐŋаĐŊŅĐģŅ</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_summary_on">ĐаĐŊŅĐģŅ ĐŊавŅĐŗĐ°ŅŅŅ Ņ ŅвĐĩŅĐģŅĐŧ ŅŅĐļŅĐŧĐĩ ĐŊĐĩĐŋŅаСŅŅŅŅаŅ</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_summary_off">ĐаĐŊŅĐģŅ ĐŊавŅĐŗĐ°ŅŅŅ Ņ ŅвĐĩŅĐģаК ŅŅĐŧĐĩ ĐŊŅĐŋŅаСŅŅŅŅĐ°Ņ ŅŅ ĐŋŅаСŅŅŅŅаŅ.</string>
|
||||
@@ -1155,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>
|
||||
@@ -1174,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>
|
||||
|
||||
@@ -555,6 +555,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_disable_translucent_status_bar_title">ĐĐĩаĐēŅивиŅаК ĐŋĐžĐģŅĐŋŅОСŅаŅĐŊаŅа ĐģĐĩĐŊŅа ĐŊа ŅŅŅŅĐžŅĐŊиĐĩŅĐž</string>
|
||||
<string name="revanced_disable_translucent_status_bar_summary_on">ĐĄŅаŅŅŅĐŊĐ°Ņ ĐģĐĩĐŊŅа Đĩ ĐŊĐĩĐŋŅОСŅаŅĐŊа</string>
|
||||
<string name="revanced_disable_translucent_status_bar_summary_off">ĐĄŅаŅŅŅĐŊĐ°Ņ ĐģĐĩĐŊŅа Đĩ ĐŊĐĩĐŋŅОСŅаŅĐŊа иĐģи ĐŋŅОСŅаŅĐŊа</string>
|
||||
<string name="revanced_disable_translucent_status_bar_user_dialog_message">Đа ĐŊŅĐēОи ŅŅŅŅОКŅŅва аĐēŅивиŅаĐŊĐĩŅĐž ĐŊа ŅаСи ŅŅĐŊĐēŅĐ¸Ņ ĐŧĐžĐļĐĩ да ĐŋŅĐžĐŧĐĩĐŊи ĐŊĐ°Đ˛Đ¸ĐŗĐ°ŅиОĐŊĐŊаŅа ĐģĐĩĐŊŅа ĐŊа ŅиŅŅĐĩĐŧаŅа ĐŊа ĐŋŅОСŅаŅĐŊа.</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_title">ĐĐĩаĐēŅивиŅаК ĐŋĐžĐģŅĐŋŅОСŅаŅĐŊаŅа ŅвĐĩŅĐģа ĐģĐĩĐŊŅа Са ĐŊĐ°Đ˛Đ¸ĐŗĐ°ŅиŅ</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_summary_on">ХвĐĩŅĐģаŅа ĐģĐĩĐŊŅа Са ĐŊĐ°Đ˛Đ¸ĐŗĐ°ŅĐ¸Ņ Đĩ ĐŊĐĩĐŋŅОСŅаŅĐŊа</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_summary_off">ХвĐĩŅĐģаŅа ĐģĐĩĐŊŅа Са ĐŊĐ°Đ˛Đ¸ĐŗĐ°ŅĐ¸Ņ Đĩ ĐŊĐĩĐŋŅОСŅаŅĐŊа иĐģи ĐŋŅОСŅаŅĐŊа</string>
|
||||
@@ -1154,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>
|
||||
@@ -1173,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>
|
||||
|
||||
@@ -555,6 +555,7 @@ MicroG-āĻāϰ āĻāύā§āϝ āĻŦā§āϝāĻžāĻāĻžāϰāĻŋ āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ
|
||||
<string name="revanced_disable_translucent_status_bar_title">āĻ
āϰā§āϧāϏā§āĻŦāĻā§āĻ āϏā§āĻĨāĻŋāϤāĻŋ āĻŦāĻžāϰ āύāĻŋāώā§āĻā§āϰāĻŋāϝāĻŧ āĻāϰā§āύ</string>
|
||||
<string name="revanced_disable_translucent_status_bar_summary_on">āϏā§āĻā§āϝāĻžāĻāĻžāϏ āĻŦāĻžāϰāĻāĻŋ āĻ
āϏā§āĻŦāĻā§āĻ</string>
|
||||
<string name="revanced_disable_translucent_status_bar_summary_off">āϏā§āĻā§āϝāĻžāĻāĻžāϏ āĻŦāĻžāϰāĻāĻŋ āĻ
āϏā§āĻŦāĻā§āĻ āĻŦāĻž āϏā§āĻŦāĻā§āĻ</string>
|
||||
<string name="revanced_disable_translucent_status_bar_user_dialog_message">āĻāĻŋāĻā§ āĻĄāĻŋāĻāĻžāĻāϏā§, āĻāĻ āĻŦā§āĻļāĻŋāώā§āĻā§āϝāĻāĻŋ āϏāĻā§āώāĻŽ āĻāϰāϞ⧠āϏāĻŋāϏā§āĻā§āĻŽ āύā§āĻāĻŋāĻā§āĻļāύ āĻŦāĻžāϰ āϏā§āĻŦāĻā§āĻ āĻšā§ā§ āϝā§āϤ⧠āĻĒāĻžāϰā§āĨ¤</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_title">āĻ
āϰā§āϧāϏā§āĻŦāĻā§āĻ āĻšāĻžāϞāĻāĻž āĻŦāĻžāϰ āύāĻŋāώā§āĻā§āϰāĻŋāϝāĻŧ āĻāϰā§āύ</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_summary_on">āĻšāĻžāϞāĻāĻž āĻŽā§āĻĄ āύā§āĻāĻŋāĻā§āĻļāύ āĻŦāĻžāϰ āĻ
āϏā§āĻŦāĻā§āĻ</string>
|
||||
<string name="revanced_disable_translucent_navigation_bar_light_summary_off">āϞāĻžāĻāĻ āĻŽā§āĻĄ āύā§āϝāĻžāĻāĻŋāĻā§āĻļāύ āĻŦāĻžāϰāĻāĻŋ āĻ
āϏā§āĻŦāĻā§āĻ āĻŦāĻž āϏā§āĻŦāĻā§āĻ</string>
|
||||
@@ -1154,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>
|
||||
@@ -1173,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>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user