diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b43701df..08352ff48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,142 @@ +# [5.19.0-dev.17](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.16...v5.19.0-dev.17) (2025-04-12) + + +### Features + +* **Spotify:** Add `Check environment` patch ([#4765](https://github.com/ReVanced/revanced-patches/issues/4765)) ([6d7101c](https://github.com/ReVanced/revanced-patches/commit/6d7101cb2e546e01a934eff9cad1264367aeafe3)) + +# [5.19.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.15...v5.19.0-dev.16) (2025-04-11) + + +### Bug Fixes + +* **Google Photos:** Remove obsolete non functional patch `Restore hidden 'Back up while charging' toggle` ([#4764](https://github.com/ReVanced/revanced-patches/issues/4764)) ([56e48f4](https://github.com/ReVanced/revanced-patches/commit/56e48f4c89da51f81ff11a79a164eaa5b440690e)) + +# [5.19.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.14...v5.19.0-dev.15) (2025-04-11) + + +### Bug Fixes + +* **Google Photos - Restore hidden 'Back up while charging' toggle:** Constrain to last working app target ([#4761](https://github.com/ReVanced/revanced-patches/issues/4761)) ([152bb7c](https://github.com/ReVanced/revanced-patches/commit/152bb7c3ee7cf36bc07460e7a3444631ec540441)) + +# [5.19.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.13...v5.19.0-dev.14) (2025-04-11) + + +### Bug Fixes + +* **Spotify - Unlock Spotify Premium:** Remove restrictions for Google voice assistant ([#4702](https://github.com/ReVanced/revanced-patches/issues/4702)) ([106202f](https://github.com/ReVanced/revanced-patches/commit/106202f9ebb7699c4ba4ae46b82133e35f1ac6b9)) + +# [5.19.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.12...v5.19.0-dev.13) (2025-04-11) + + +### Features + +* **Spotify:** Add limited support for version `8.6.98.900` (last version that supports Kenwood and Pioneer car stereos) ([#4750](https://github.com/ReVanced/revanced-patches/issues/4750)) ([a3fde87](https://github.com/ReVanced/revanced-patches/commit/a3fde874af993125ba7a741820e7bd48e3641b84)) + +# [5.19.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.11...v5.19.0-dev.12) (2025-04-11) + + +### Features + +* **Strava - Disable subscription suggestions:** Make compatible with latest version ([#4739](https://github.com/ReVanced/revanced-patches/issues/4739)) ([649a2c0](https://github.com/ReVanced/revanced-patches/commit/649a2c06161c72a2040b179dbed5b415847d7527)) + +# [5.19.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.10...v5.19.0-dev.11) (2025-04-10) + + +### Features + +* **Messenger:** Add `Remove Meta AI tab` patch ([#4726](https://github.com/ReVanced/revanced-patches/issues/4726)) ([e3fad97](https://github.com/ReVanced/revanced-patches/commit/e3fad97484d7eb962aeb53d44a0047b34a881071)) + +# [5.19.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.9...v5.19.0-dev.10) (2025-04-10) + + +### Bug Fixes + +* **YouTube - Hide layout components:** Do not hide video description music/game links if hide horizontal shelves is enabled ([3864f35](https://github.com/ReVanced/revanced-patches/commit/3864f3550153617e23ad9979fb543d8a7fb4dc0a)) + +# [5.19.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.8...v5.19.0-dev.9) (2025-04-10) + + +### Bug Fixes + +* **YouTube - Hide player flyout menu items:** Show more detailed summary text for 'Hide Audio track' if using Android spoof client ([#4756](https://github.com/ReVanced/revanced-patches/issues/4756)) ([b67bbb2](https://github.com/ReVanced/revanced-patches/commit/b67bbb299669336addb68cf52a8ce5b39c68cec0)) + +# [5.19.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.7...v5.19.0-dev.8) (2025-04-09) + + +### Bug Fixes + +* **YouTube - Return YouTube Dislike:** Fix inconsistent label after disliking a Short ([ea92a2e](https://github.com/ReVanced/revanced-patches/commit/ea92a2e36c7aab3bd115f7d0ec40467179485b32)) + +# [5.19.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.6...v5.19.0-dev.7) (2025-04-07) + + +### Bug Fixes + +* **YouTube - Return YouTube Dislike:** Correctly update label after disliking a Short with 20.07 ([0bb3e32](https://github.com/ReVanced/revanced-patches/commit/0bb3e32244fa10809aee5c4e549f77ed4054537e)) + +# [5.19.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.5...v5.19.0-dev.6) (2025-04-04) + + +### Bug Fixes + +* **Spotify:** Remove ads sections from home ([#4722](https://github.com/ReVanced/revanced-patches/issues/4722)) ([0b9a5e7](https://github.com/ReVanced/revanced-patches/commit/0b9a5e7f89a89d971762b3539166d4f145111481)) + +# [5.19.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.4...v5.19.0-dev.5) (2025-04-02) + + +### Bug Fixes + +* **Spotify - Custom theme:** Override more color resources ([#4690](https://github.com/ReVanced/revanced-patches/issues/4690)) ([d7a7a0b](https://github.com/ReVanced/revanced-patches/commit/d7a7a0b982dbafa181b04f984a5f7618fb067c2a)) + +# [5.19.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.3...v5.19.0-dev.4) (2025-04-02) + + +### Bug Fixes + +* **YouTube - Seekbar:** Correctly hide the feed seekbar with target 20.07 ([ddc6e4c](https://github.com/ReVanced/revanced-patches/commit/ddc6e4c34fe35fa34bd859bf34e25645a23dbdc9)) + +# [5.19.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.2...v5.19.0-dev.3) (2025-04-02) + + +### Features + +* **Proton Mail:** Add `Remove 'Sent from' signature` patch ([#4514](https://github.com/ReVanced/revanced-patches/issues/4514)) ([34c14c9](https://github.com/ReVanced/revanced-patches/commit/34c14c9b443092824d035afd77adb678c6f89e3e)) + +# [5.19.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.19.0-dev.1...v5.19.0-dev.2) (2025-04-02) + + +### Features + +* **YouTube - Settings:** Add icons to the ReVanced settings ([#4496](https://github.com/ReVanced/revanced-patches/issues/4496)) ([d0c85f0](https://github.com/ReVanced/revanced-patches/commit/d0c85f044083d720c63a8ea4ff15d42eefeb9db7)) + +# [5.19.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.18.1-dev.2...v5.19.0-dev.1) (2025-04-01) + + +### Bug Fixes + +* **Twitter - Hide recommended users:** Make hiding work again by filtering for new entryId prefix ([#4456](https://github.com/ReVanced/revanced-patches/issues/4456)) ([ff846b0](https://github.com/ReVanced/revanced-patches/commit/ff846b0b7ef5060caaffedb08c1f901172f5b2d1)) + + +### Features + +* **Angulus:** Add `Hide ads` patch ([#4604](https://github.com/ReVanced/revanced-patches/issues/4604)) ([87c86b5](https://github.com/ReVanced/revanced-patches/commit/87c86b53a91b0054ac892a3f02bbe7bf83bbf813)) +* **Photomath:** Support latest version ([#4672](https://github.com/ReVanced/revanced-patches/issues/4672)) ([8e16483](https://github.com/ReVanced/revanced-patches/commit/8e1648322948151e4565fb0d86e0f37d0a02d73f)) + +## [5.18.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.18.1-dev.1...v5.18.1-dev.2) (2025-04-01) + + +### Bug Fixes + +* **YouTube:** Combine multiple seekbar patches into a single patch ([#4705](https://github.com/ReVanced/revanced-patches/issues/4705)) ([503b7eb](https://github.com/ReVanced/revanced-patches/commit/503b7eb8d413ef7f248394f128f3b2a6f3192ba6)) + +## [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) diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/Utils.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/Utils.java index 47806567c..8343d595c 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/Utils.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/Utils.java @@ -9,6 +9,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; +import android.graphics.Color; import android.net.ConnectivityManager; import android.os.Build; import android.os.Bundle; @@ -799,4 +800,14 @@ public class Utils { builder.getContext().setTheme(editTextDialogStyle); } } + + /** + * Parse a color resource or hex code to an int representation of the color. + */ + public static int getColorFromString(String colorString) throws IllegalArgumentException, Resources.NotFoundException { + if (colorString.startsWith("#")) { + return Color.parseColor(colorString); + } + return getResourceColor(colorString); + } } diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java index 84e2faf8b..6b9665277 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java @@ -23,6 +23,11 @@ public class BaseSettings { public static final EnumSetting REVANCED_LANGUAGE = new EnumSetting<>("revanced_language", AppLanguage.DEFAULT, true, "revanced_language_user_dialog_message"); + /** + * Use the icons declared in the preferences created during patching. If no icons or styles are declared then this setting does nothing. + */ + public static final BooleanSetting SHOW_MENU_ICONS = new BooleanSetting("revanced_show_menu_icons", TRUE, true); + public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true, "revanced_spoof_video_streams_user_dialog_message"); public static final EnumSetting SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AppLanguage.DEFAULT, new AudioStreamLanguageOverrideAvailability()); public static final BooleanSetting SPOOF_STREAMING_DATA_STATS_FOR_NERDS = new BooleanSetting("revanced_spoof_streaming_data_stats_for_nerds", TRUE, parent(SPOOF_VIDEO_STREAMS)); diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/AbstractPreferenceFragment.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/AbstractPreferenceFragment.java index 17646fec9..0a09789c7 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/AbstractPreferenceFragment.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/AbstractPreferenceFragment.java @@ -86,7 +86,6 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment { } }; - /** * Initialize this instance, and do any custom behavior. *

@@ -95,7 +94,10 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment { * so all app specific {@link Setting} instances are loaded before this method returns. */ protected void initialize() { - final var identifier = Utils.getResourceIdentifier("revanced_prefs", "xml"); + String preferenceResourceName = BaseSettings.SHOW_MENU_ICONS.get() + ? "revanced_prefs_icons" + : "revanced_prefs"; + final var identifier = Utils.getResourceIdentifier(preferenceResourceName, "xml"); if (identifier == 0) return; addPreferencesFromResource(identifier); diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/layout/theme/CustomThemePatch.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/layout/theme/CustomThemePatch.java new file mode 100644 index 000000000..8949b9b2d --- /dev/null +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/layout/theme/CustomThemePatch.java @@ -0,0 +1,22 @@ +package app.revanced.extension.spotify.layout.theme; + +import android.graphics.Color; + +import app.revanced.extension.shared.Logger; +import app.revanced.extension.shared.Utils; + +@SuppressWarnings("unused") +public final class CustomThemePatch { + + /** + * Injection point. + */ + public static long getThemeColor(String colorString) { + try { + return Utils.getColorFromString(colorString); + } catch (Exception ex) { + Logger.printException(() -> "Invalid custom color: " + colorString, ex); + return Color.BLACK; + } + } +} diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/UnlockPremiumPatch.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/UnlockPremiumPatch.java index 1410b308e..49dfffaec 100644 --- a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/UnlockPremiumPatch.java +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/UnlockPremiumPatch.java @@ -3,7 +3,7 @@ package app.revanced.extension.spotify.misc; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; -import com.spotify.remoteconfig.internal.AccountAttribute; +import com.spotify.home.evopage.homeapi.proto.Section; import java.util.List; import java.util.Map; @@ -14,6 +14,25 @@ import app.revanced.extension.shared.Logger; @SuppressWarnings("unused") public final class UnlockPremiumPatch { + private static final String SPOTIFY_MAIN_ACTIVITY_LEGACY = "com.spotify.music.MainActivity"; + + /** + * If the app target is 8.6.98.900. + */ + private static final boolean IS_SPOTIFY_LEGACY_APP_TARGET; + + static { + boolean legacy; + try { + Class.forName(SPOTIFY_MAIN_ACTIVITY_LEGACY); + legacy = true; + } catch (ClassNotFoundException ex) { + legacy = false; + } + + IS_SPOTIFY_LEGACY_APP_TARGET = legacy; + } + private static class OverrideAttribute { /** * Account attribute key. @@ -54,8 +73,8 @@ public final class UnlockPremiumPatch { // Make sure playing songs is not disabled remotely and playlists show up. new OverrideAttribute("streaming", TRUE), // Allows adding songs to queue and removes the smart shuffle mode restriction, - // allowing to pick any of the other modes. - new OverrideAttribute("pick-and-shuffle", FALSE), + // allowing to pick any of the other modes. Flag is not present in legacy app target. + new OverrideAttribute("pick-and-shuffle", FALSE, !IS_SPOTIFY_LEGACY_APP_TARGET), // Disables shuffle-mode streaming-rule, which forces songs to be played shuffled // and breaks the player when other patches are applied. new OverrideAttribute("streaming-rules", ""), @@ -69,23 +88,51 @@ public final class UnlockPremiumPatch { new OverrideAttribute("tablet-free", FALSE, false) ); + private static final List REMOVED_HOME_SECTIONS = List.of( + Section.VIDEO_BRAND_AD_FIELD_NUMBER, + Section.IMAGE_BRAND_AD_FIELD_NUMBER + ); + /** - * Injection point. + * Injection point. Override account attributes. */ - public static void overrideAttribute(Map attributes) { + public static void overrideAttribute(Map attributes) { try { for (var override : OVERRIDES) { var attribute = attributes.get(override.key); if (attribute == null) { if (override.isExpected) { - Logger.printException(() -> "''" + override.key + "' expected but not found"); + Logger.printException(() -> "'" + override.key + "' expected but not found"); } } else { - attribute.value_ = override.overrideValue; + Object overrideValue = override.overrideValue; + if (IS_SPOTIFY_LEGACY_APP_TARGET) { + ((com.spotify.useraccount.v1.AccountAttribute) attribute).value_ = overrideValue; + } else { + ((com.spotify.remoteconfig.internal.AccountAttribute) attribute).value_ = overrideValue; + } } } } catch (Exception ex) { Logger.printException(() -> "overrideAttribute failure", ex); } } + + /** + * Injection point. Remove station data from Google assistant URI. + */ + public static String removeStationString(String spotifyUriOrUrl) { + return spotifyUriOrUrl.replace("spotify:station:", "spotify:"); + } + + /** + * Injection point. Remove ads sections from home. + */ + public static void removeHomeSections(List

sections) { + try { + sections.removeIf(section -> REMOVED_HOME_SECTIONS.contains(section.featureTypeCase_)); + } catch (Exception ex) { + Logger.printException(() -> "Remove home sections failure", ex); + } + } } diff --git a/extensions/spotify/stub/src/main/java/com/spotify/home/evopage/homeapi/proto/Section.java b/extensions/spotify/stub/src/main/java/com/spotify/home/evopage/homeapi/proto/Section.java new file mode 100644 index 000000000..cc7da5f71 --- /dev/null +++ b/extensions/spotify/stub/src/main/java/com/spotify/home/evopage/homeapi/proto/Section.java @@ -0,0 +1,7 @@ +package com.spotify.home.evopage.homeapi.proto; + +public final class Section { + public static final int VIDEO_BRAND_AD_FIELD_NUMBER = 20; + public static final int IMAGE_BRAND_AD_FIELD_NUMBER = 21; + public int featureTypeCase_; +} diff --git a/extensions/spotify/stub/src/main/java/com/spotify/useraccount/v1/AccountAttribute.java b/extensions/spotify/stub/src/main/java/com/spotify/useraccount/v1/AccountAttribute.java new file mode 100644 index 000000000..a03b583bf --- /dev/null +++ b/extensions/spotify/stub/src/main/java/com/spotify/useraccount/v1/AccountAttribute.java @@ -0,0 +1,8 @@ +package com.spotify.useraccount.v1; + +/** + * Used for target 8.6.98.900. Class is still present in newer app targets. + */ +public class AccountAttribute { + public Object value_; +} diff --git a/extensions/tiktok/src/main/java/app/revanced/extension/tiktok/settings/preference/ReVancedPreferenceFragment.java b/extensions/tiktok/src/main/java/app/revanced/extension/tiktok/settings/preference/ReVancedPreferenceFragment.java index b36dcb79a..c1c48b04c 100644 --- a/extensions/tiktok/src/main/java/app/revanced/extension/tiktok/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/tiktok/src/main/java/app/revanced/extension/tiktok/settings/preference/ReVancedPreferenceFragment.java @@ -9,7 +9,6 @@ import app.revanced.extension.tiktok.settings.preference.categories.DownloadsPre import app.revanced.extension.tiktok.settings.preference.categories.FeedFilterPreferenceCategory; import app.revanced.extension.tiktok.settings.preference.categories.ExtensionPreferenceCategory; import app.revanced.extension.tiktok.settings.preference.categories.SimSpoofPreferenceCategory; -import org.jetbrains.annotations.NotNull; /** * Preference fragment for ReVanced settings diff --git a/extensions/twitter/src/main/java/app/revanced/twitter/patches/hook/twifucker/TwiFucker.kt b/extensions/twitter/src/main/java/app/revanced/twitter/patches/hook/twifucker/TwiFucker.kt index af5b0312e..f9a132056 100644 --- a/extensions/twitter/src/main/java/app/revanced/twitter/patches/hook/twifucker/TwiFucker.kt +++ b/extensions/twitter/src/main/java/app/revanced/twitter/patches/hook/twifucker/TwiFucker.kt @@ -163,7 +163,7 @@ internal object TwiFucker { private fun JSONObject.entryIsWhoToFollow(): Boolean = optString("entryId").let { - it.startsWith("whoToFollow-") || it.startsWith("who-to-follow-") || it.startsWith("connect-module-") + it.startsWith("whoToFollow-") || it.startsWith("who-to-follow-") || it.startsWith("connect-module-") || it.startsWith("who-to-subscribe-") } private fun JSONObject.itemContainsPromotedUser(): Boolean = diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/ThemeHelper.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/ThemeHelper.java index c4887b8e3..80b9b583c 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/ThemeHelper.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/ThemeHelper.java @@ -45,13 +45,24 @@ public class ThemeHelper { return "@color/yt_black3"; } + private static int getThemeColor(String resourceName, int defaultColor) { + try { + return Utils.getColorFromString(resourceName); + } catch (Exception ex) { + // User entered an invalid custom theme color. + // Normally this should never be reached, and no localized strings are needed. + Utils.showToastLong("Invalid custom theme color: " + resourceName); + return defaultColor; + } + } + /** * @return The dark theme color as specified by the Theme patch (if included), * or the dark mode background color unpatched YT uses. */ public static int getDarkThemeColor() { if (darkThemeColor == null) { - darkThemeColor = getColorInt(darkThemeResourceName()); + darkThemeColor = getThemeColor(darkThemeResourceName(), Color.BLACK); } return darkThemeColor; } @@ -71,18 +82,11 @@ public class ThemeHelper { */ public static int getLightThemeColor() { if (lightThemeColor == null) { - lightThemeColor = getColorInt(lightThemeResourceName()); + lightThemeColor = getThemeColor(lightThemeResourceName(), Color.WHITE); } return lightThemeColor; } - private static int getColorInt(String colorString) { - if (colorString.startsWith("#")) { - return Color.parseColor(colorString); - } - return Utils.getResourceColor(colorString); - } - public static int getBackgroundColor() { return isDarkTheme() ? getDarkThemeColor() : getLightThemeColor(); } @@ -96,6 +100,6 @@ public class ThemeHelper { ? "yt_black3" : "yt_white1"; - return getColorInt(colorName); + return Utils.getColorFromString(colorName); } } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/BackgroundPlaybackPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/BackgroundPlaybackPatch.java index 1ab3374d7..7575414ba 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/BackgroundPlaybackPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/BackgroundPlaybackPatch.java @@ -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; } /** diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch.java index 5c54985bb..c5ba1c033 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch.java @@ -2,20 +2,16 @@ package app.revanced.extension.youtube.patches; import static app.revanced.extension.youtube.returnyoutubedislike.ReturnYouTubeDislike.Vote; -import android.graphics.Rect; import android.graphics.drawable.ShapeDrawable; -import android.text.Spannable; import android.text.SpannableString; import android.text.Spanned; import android.view.View; import android.widget.TextView; +import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; import java.util.Objects; import app.revanced.extension.shared.Logger; @@ -60,12 +56,12 @@ public class ReturnYouTubeDislikePatch { private static volatile ReturnYouTubeDislike lastLithoShortsVideoData; /** - * Because the litho Shorts spans are created after {@link ReturnYouTubeDislikeFilterPatch} - * detects the video ids, after the user votes the litho will update - * but {@link #lastLithoShortsVideoData} is not the correct data to use. - * If this is true, then instead use {@link #currentVideoData}. + * Because litho Shorts spans are created offscreen after {@link ReturnYouTubeDislikeFilterPatch} + * detects the video ids, but the current Short can arbitrarily reload the same span, + * then use the {@link #lastLithoShortsVideoData} if this value is greater than zero. */ - private static volatile boolean lithoShortsShouldUseCurrentData; + @GuardedBy("ReturnYouTubeDislikePatch.class") + private static int useLithoShortsVideoDataCount; /** * Last video id prefetched. Field is to prevent prefetching the same video id multiple times in a row. @@ -83,12 +79,28 @@ public class ReturnYouTubeDislikePatch { private static void clearData() { currentVideoData = null; lastLithoShortsVideoData = null; - lithoShortsShouldUseCurrentData = false; + synchronized (ReturnYouTubeDislike.class) { + useLithoShortsVideoDataCount = 0; + } + // Rolling number text should not be cleared, // as it's used if incognito Short is opened/closed // while a regular video is on screen. } + /** + * @return If {@link #useLithoShortsVideoDataCount} was greater than zero. + */ + private static boolean decrementUseLithoDataIfNeeded() { + synchronized (ReturnYouTubeDislikePatch.class) { + if (useLithoShortsVideoDataCount > 0) { + useLithoShortsVideoDataCount--; + return true; + } + + return false; + } + } // // Litho player for both regular videos and Shorts. @@ -152,10 +164,13 @@ public class ReturnYouTubeDislikePatch { return getShortsSpan(original, true); } - if (conversionContextString.contains("|shorts_like_button.eml") - && !Utils.containsNumber(original)) { - Logger.printDebug(() -> "Replacing hidden likes count"); - return getShortsSpan(original, false); + if (conversionContextString.contains("|shorts_like_button.eml")) { + if (!Utils.containsNumber(original)) { + Logger.printDebug(() -> "Replacing hidden likes count"); + return getShortsSpan(original, false); + } else { + decrementUseLithoDataIfNeeded(); + } } } catch (Exception ex) { Logger.printException(() -> "onLithoTextLoaded failure", ex); @@ -170,7 +185,14 @@ public class ReturnYouTubeDislikePatch { return original; } - ReturnYouTubeDislike videoData = lastLithoShortsVideoData; + final ReturnYouTubeDislike videoData; + if (decrementUseLithoDataIfNeeded()) { + // New Short is loading off screen. + videoData = lastLithoShortsVideoData; + } else { + videoData = currentVideoData; + } + if (videoData == null) { // The Shorts litho video id filter did not detect the video id. // This is normal in incognito mode, but otherwise is abnormal. @@ -178,19 +200,6 @@ public class ReturnYouTubeDislikePatch { return original; } - // Use the correct dislikes data after voting. - if (lithoShortsShouldUseCurrentData) { - if (isDislikesSpan) { - lithoShortsShouldUseCurrentData = false; - } - videoData = currentVideoData; - if (videoData == null) { - Logger.printException(() -> "currentVideoData is null"); // Should never happen - return original; - } - Logger.printDebug(() -> "Using current video data for litho span"); - } - return isDislikesSpan ? videoData.getDislikeSpanForShort((Spanned) original) : videoData.getLikeSpanForShort((Spanned) original); @@ -445,7 +454,10 @@ public class ReturnYouTubeDislikePatch { ReturnYouTubeDislike videoData = ReturnYouTubeDislike.getFetchForVideoId(videoId); videoData.setVideoIdIsShort(true); lastLithoShortsVideoData = videoData; - lithoShortsShouldUseCurrentData = false; + synchronized (ReturnYouTubeDislikePatch.class) { + // Use litho Shorts data for the next like and dislike spans. + useLithoShortsVideoDataCount = 2; + } } private static boolean videoIdIsSame(@Nullable ReturnYouTubeDislike fetch, @Nullable String videoId) { @@ -480,13 +492,6 @@ public class ReturnYouTubeDislikePatch { for (Vote v : Vote.values()) { if (v.value == vote) { videoData.sendVote(v); - - if (isNoneHiddenOrMinimized) { - if (lastLithoShortsVideoData != null) { - lithoShortsShouldUseCurrentData = true; - } - } - return; } } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java index 2d617d4a4..4f6c1366c 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java @@ -454,16 +454,20 @@ public final class LayoutComponentsFilter extends Filter { } private static boolean hideShelves() { - // If the player is opened while library is selected, - // then filter any recommendations below the player. - if (PlayerType.getCurrent().isMaximizedOrFullscreen() - // Or if the search is active while library is selected, then also filter. - || NavigationBar.isSearchBarActive()) { + // Horizontal shelves are used for music/game links in video descriptions, + // such as https://youtube.com/watch?v=W8kI1na3S2M + if (PlayerType.getCurrent().isMaximizedOrFullscreen()) { + return false; + } + + // Must check search bar after player type, since search results + // can be in the background behind an open player. + if (NavigationBar.isSearchBarActive()) { return true; } // Do not hide if the navigation back button is visible, - // otherwise the content shelves in the YouTube Movie/Courses pages is hidden. + // otherwise the content shelves in the explore/music/courses pages are hidde. if (NavigationBar.isBackButtonVisible()) { return false; } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/PlayerFlyoutMenuItemsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/PlayerFlyoutMenuItemsFilter.java index 6b59d484e..b200017ab 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/PlayerFlyoutMenuItemsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/PlayerFlyoutMenuItemsFilter.java @@ -2,12 +2,25 @@ package app.revanced.extension.youtube.patches.components; import androidx.annotation.Nullable; +import app.revanced.extension.shared.settings.Setting; +import app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch; import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.shared.PlayerType; @SuppressWarnings("unused") public class PlayerFlyoutMenuItemsFilter extends Filter { + public static final class HideAudioFlyoutMenuAvailability implements Setting.Availability { + private static final boolean AVAILABLE_ON_LAUNCH = SpoofVideoStreamsPatch.notSpoofingToAndroid(); + + @Override + public boolean isAvailable() { + // Check conditions of launch and now. Otherwise if spoofing is changed + // without a restart the setting will show as available when it's not. + return AVAILABLE_ON_LAUNCH && SpoofVideoStreamsPatch.notSpoofingToAndroid(); + } + } + private final ByteArrayFilterGroupList flyoutFilterGroupList = new ByteArrayFilterGroupList(); private final ByteArrayFilterGroup exception; diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/SeekbarColorPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/SeekbarColorPatch.java index 31153a4d7..2283106bf 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/SeekbarColorPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/SeekbarColorPatch.java @@ -226,6 +226,7 @@ public final class SeekbarColorPatch { } private static String loadRawResourceAsString(int resourceId) { + //noinspection CharsetObjectCanBeUsed try (InputStream inputStream = Utils.getContext().getResources().openRawResource(resourceId); Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8.name()).useDelimiter("\\A")) { return scanner.next(); @@ -281,6 +282,20 @@ public final class SeekbarColorPatch { /** * Injection point. + * 19.49+ + */ + public static int[] getPlayerLinearGradient(int[] original, int x0, int y1) { + // This hook is used for both the player and the feed. + // Feed usage always has x0 and y1 value of zero, and the player is always non zero. + if (HIDE_SEEKBAR_THUMBNAIL_ENABLED && x0 == 0 && y1 == 0) { + return HIDDEN_SEEKBAR_GRADIENT_COLORS; + } + return getPlayerLinearGradient(original); + } + + /** + * Injection point. + * Pre 19.49 */ public static int[] getPlayerLinearGradient(int[] original) { return SEEKBAR_CUSTOM_COLOR_ENABLED diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index b082704af..75128e3dd 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -19,6 +19,7 @@ import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerT import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_4; import static app.revanced.extension.youtube.patches.OpenShortsInRegularPlayerPatch.ShortsPlayerType; import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability; +import static app.revanced.extension.youtube.patches.components.PlayerFlyoutMenuItemsFilter.HideAudioFlyoutMenuAvailability; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY; @@ -198,7 +199,7 @@ public class Settings extends BaseSettings { // Player flyout menu items public static final BooleanSetting HIDE_PLAYER_FLYOUT_ADDITIONAL_SETTINGS = new BooleanSetting("revanced_hide_player_flyout_additional_settings", FALSE); public static final BooleanSetting HIDE_PLAYER_FLYOUT_AMBIENT_MODE = new BooleanSetting("revanced_hide_player_flyout_ambient_mode", FALSE); - public static final BooleanSetting HIDE_PLAYER_FLYOUT_AUDIO_TRACK = new BooleanSetting("revanced_hide_player_flyout_audio_track", FALSE); + public static final BooleanSetting HIDE_PLAYER_FLYOUT_AUDIO_TRACK = new BooleanSetting("revanced_hide_player_flyout_audio_track", FALSE, new HideAudioFlyoutMenuAvailability()); public static final BooleanSetting HIDE_PLAYER_FLYOUT_CAPTIONS = new BooleanSetting("revanced_hide_player_flyout_captions", FALSE); public static final BooleanSetting HIDE_PLAYER_FLYOUT_HELP = new BooleanSetting("revanced_hide_player_flyout_help", TRUE); public static final BooleanSetting HIDE_PLAYER_FLYOUT_LOCK_SCREEN = new BooleanSetting("revanced_hide_player_flyout_lock_screen", FALSE); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/HideAudioFlyoutMenuPreference.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/HideAudioFlyoutMenuPreference.java new file mode 100644 index 000000000..4d67360a7 --- /dev/null +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/HideAudioFlyoutMenuPreference.java @@ -0,0 +1,36 @@ +package app.revanced.extension.youtube.settings.preference; + +import static app.revanced.extension.shared.StringRef.str; + +import android.content.Context; +import android.preference.SwitchPreference; +import android.util.AttributeSet; + +import app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch; + +@SuppressWarnings({"deprecation", "unused"}) +public class HideAudioFlyoutMenuPreference extends SwitchPreference { + + { + // Audio menu is not available if spoofing to Android client type. + if (!SpoofVideoStreamsPatch.notSpoofingToAndroid()) { + String summary = str("revanced_hide_player_flyout_audio_track_not_available"); + setSummary(summary); + setSummaryOn(summary); + setSummaryOff(summary); + } + } + + public HideAudioFlyoutMenuPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + public HideAudioFlyoutMenuPreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + public HideAudioFlyoutMenuPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + public HideAudioFlyoutMenuPreference(Context context) { + super(context); + } +} diff --git a/gradle.properties b/gradle.properties index fe67040d9..d8a46e5cd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.18.0 +version = 5.19.0-dev.17 diff --git a/patches/api/patches.api b/patches/api/patches.api index e672bf3ad..5416c799e 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -132,6 +132,10 @@ public final class app/revanced/patches/amazon/DeepLinkingPatchKt { public static final fun getDeepLinkingPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/angulus/ads/RemoveAdsPatchKt { + public static final fun getAngulusPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/backdrops/misc/pro/ProUnlockPatchKt { public static final fun getProUnlockPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -268,6 +272,10 @@ public final class app/revanced/patches/messenger/inputfield/DisableTypingIndica public static final fun getDisableTypingIndicatorPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/messenger/navbar/RemoveMetaAITabPatchKt { + public static final fun getRemoveMetaAITabPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatchKt { public static final fun getForceEnglishLocalePatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -396,6 +404,10 @@ public final class app/revanced/patches/pixiv/ads/HideAdsPatchKt { public static final fun getHideAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/protonmail/signature/RemoveSentFromSignaturePatchKt { + public static final fun getRemoveSentFromSignaturePatch ()Lapp/revanced/patcher/patch/ResourcePatch; +} + public final class app/revanced/patches/rar/misc/annoyances/purchasereminder/HidePurchaseReminderPatchKt { public static final fun getHidePurchaseReminderPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -556,7 +568,9 @@ public final class app/revanced/patches/shared/misc/extension/ExtensionHook { } public final class app/revanced/patches/shared/misc/extension/SharedExtensionPatchKt { + public static final fun extensionHook (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lapp/revanced/patcher/Fingerprint;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; public static final fun extensionHook (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; + public static synthetic fun extensionHook$default (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lapp/revanced/patcher/Fingerprint;ILjava/lang/Object;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; public static synthetic fun extensionHook$default (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; public static final fun sharedExtensionPatch (Ljava/lang/String;[Lapp/revanced/patches/shared/misc/extension/ExtensionHook;)Lapp/revanced/patcher/patch/BytecodePatch; public static final fun sharedExtensionPatch ([Lapp/revanced/patches/shared/misc/extension/ExtensionHook;)Lapp/revanced/patcher/patch/BytecodePatch; @@ -1096,6 +1110,14 @@ public final class app/revanced/patches/youtube/interaction/seekbar/EnableSlideT public static final fun getEnableSlideToSeekPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/youtube/interaction/seekbar/HideSeekbarPatchKt { + public static final fun getHideSeekbarPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + +public final class app/revanced/patches/youtube/interaction/seekbar/SeekbarPatchKt { + public static final fun getSeekbarPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/youtube/interaction/seekbar/SeekbarThumbnailsPatchKt { public static final fun getSeekbarThumbnailsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/angulus/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/angulus/ads/Fingerprints.kt new file mode 100644 index 000000000..3196adb7e --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/angulus/ads/Fingerprints.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.angulus.ads + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +// Keywords to search for in case the method name changes: +// dailyMeasurementCount +// lastMeasurementDate +// dailyAdResetCount +// MeasurementPrefs + +// This fingerprint targets a method that returns the daily measurement count. +// This method is used to determine if the user has reached the daily limit of measurements. +internal val getDailyMeasurementCountFingerprint = fingerprint { + accessFlags(AccessFlags.PRIVATE) + returns("I") + strings("dailyMeasurementCount") +} diff --git a/patches/src/main/kotlin/app/revanced/patches/angulus/ads/RemoveAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/angulus/ads/RemoveAdsPatch.kt new file mode 100644 index 000000000..5eb585cf5 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/angulus/ads/RemoveAdsPatch.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.angulus.ads + +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.util.returnEarly + +@Suppress("unused") +val angulusPatch = bytecodePatch(name = "Hide ads") { + compatibleWith("com.drinkplusplus.angulus") + + execute { + // Always return 0 as the daily measurement count. + getDailyMeasurementCountFingerprint.method.returnEarly() + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/preferences/RestoreHiddenBackUpWhileChargingTogglePatch.kt b/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/preferences/RestoreHiddenBackUpWhileChargingTogglePatch.kt index 04fe29715..ea65658bd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/preferences/RestoreHiddenBackUpWhileChargingTogglePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/preferences/RestoreHiddenBackUpWhileChargingTogglePatch.kt @@ -3,23 +3,28 @@ package app.revanced.patches.googlephotos.misc.preferences import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch +import app.revanced.util.indexOfFirstInstructionOrThrow +import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +@Deprecated("This patch no longer works and this code will soon be deleted") @Suppress("unused") val restoreHiddenBackUpWhileChargingTogglePatch = bytecodePatch( - name = "Restore hidden 'Back up while charging' toggle", - description = "Restores a hidden toggle to only run backups when the device is charging.", + description = "Restores a hidden toggle to only run backups when the device is charging." ) { - compatibleWith("com.google.android.apps.photos") + compatibleWith("com.google.android.apps.photos"("7.11.0.705590205")) execute { // Patches 'backup_prefs_had_backup_only_when_charging_enabled' to always be true. - val chargingPrefStringIndex = backupPreferencesFingerprint.stringMatches!!.first().index - backupPreferencesFingerprint.method.apply { - // Get the register of move-result. - val resultRegister = getInstruction(chargingPrefStringIndex + 2).registerA - // Insert const after move-result to override register as true. - addInstruction(chargingPrefStringIndex + 3, "const/4 v$resultRegister, 0x1") + backupPreferencesFingerprint.let { + it.method.apply { + val index = indexOfFirstInstructionOrThrow( + it.stringMatches!!.first().index, + Opcode.MOVE_RESULT + ) + val register = getInstruction(index).registerA + addInstruction(index + 1, "const/4 v$register, 0x1") + } } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/messenger/navbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/messenger/navbar/Fingerprints.kt new file mode 100644 index 000000000..766e20209 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/messenger/navbar/Fingerprints.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.messenger.navbar + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.Opcode + +internal val createTabConfigurationFingerprint = fingerprint { + strings("MessengerTabConfigurationCreator.createTabConfiguration") + opcodes( + Opcode.INVOKE_DIRECT, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ, + Opcode.INVOKE_DIRECT, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ, + ) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/messenger/navbar/RemoveMetaAITabPatch.kt b/patches/src/main/kotlin/app/revanced/patches/messenger/navbar/RemoveMetaAITabPatch.kt new file mode 100644 index 000000000..75fb98577 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/messenger/navbar/RemoveMetaAITabPatch.kt @@ -0,0 +1,25 @@ +package app.revanced.patches.messenger.navbar + +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Suppress("unused") +val removeMetaAITabPatch = bytecodePatch( + name = "Remove Meta AI tab", + description = "Removes the 'Meta AI' tab from the navbar.", +) { + compatibleWith("com.facebook.orca") + + execute { + createTabConfigurationFingerprint.let { + val moveResultIndex = it.patternMatch!!.startIndex + 1 + val enabledRegister = it.method.getInstruction(moveResultIndex).registerA + it.method.replaceInstruction( + moveResultIndex, + "const/4 v$enabledRegister, 0x0" + ) + } + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/deviceid/SpoofDeviceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/deviceid/SpoofDeviceIdPatch.kt index 16c84b056..ca308be08 100644 --- a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/deviceid/SpoofDeviceIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/deviceid/SpoofDeviceIdPatch.kt @@ -12,7 +12,7 @@ val getDeviceIdPatch = bytecodePatch( ) { dependsOn(signatureDetectionPatch) - compatibleWith("com.microblink.photomath"("8.37.0")) + compatibleWith("com.microblink.photomath") execute { getDeviceIdFingerprint.method.replaceInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/Fingerprints.kt index 5d7a20783..c6563270e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/Fingerprints.kt @@ -14,5 +14,5 @@ internal val checkSignatureFingerprint = fingerprint { Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, ) - strings("signatures") -} \ No newline at end of file + strings("SHA") +} diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/misc/annoyances/HideUpdatePopupPatch.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/misc/annoyances/HideUpdatePopupPatch.kt index a3586de1c..e8e09b417 100644 --- a/patches/src/main/kotlin/app/revanced/patches/photomath/misc/annoyances/HideUpdatePopupPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/photomath/misc/annoyances/HideUpdatePopupPatch.kt @@ -11,7 +11,7 @@ val hideUpdatePopupPatch = bytecodePatch( ) { dependsOn(signatureDetectionPatch) - compatibleWith("com.microblink.photomath"("8.32.0")) + compatibleWith("com.microblink.photomath") execute { hideUpdatePopupFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/plus/UnlockPlusPatch.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/plus/UnlockPlusPatch.kt index 8cc80c72e..1339a4477 100644 --- a/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/plus/UnlockPlusPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/plus/UnlockPlusPatch.kt @@ -11,7 +11,7 @@ val unlockPlusPatch = bytecodePatch( ) { dependsOn(signatureDetectionPatch, enableBookpointPatch) - compatibleWith("com.microblink.photomath"("8.37.0")) + compatibleWith("com.microblink.photomath") execute { isPlusUnlockedFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/protonmail/signature/RemoveSentFromSignaturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/protonmail/signature/RemoveSentFromSignaturePatch.kt new file mode 100644 index 000000000..f3d2b2dd2 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/protonmail/signature/RemoveSentFromSignaturePatch.kt @@ -0,0 +1,42 @@ +package app.revanced.patches.protonmail.signature + +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.resourcePatch +import app.revanced.util.findElementByAttributeValue +import java.io.File + +@Suppress("unused") +val removeSentFromSignaturePatch = resourcePatch( + name = "Remove 'Sent from' signature", + description = "Removes the 'Sent from Proton Mail mobile' signature from emails.", +) { + compatibleWith("ch.protonmail.android") + + execute { + val stringResourceFiles = mutableListOf() + + get("res").walk().forEach { file -> + if (file.isFile && file.name.equals("strings.xml", ignoreCase = true)) { + stringResourceFiles.add(file) + } + } + + var foundString = false + stringResourceFiles.forEach { filePath -> + document(filePath.absolutePath).use { document -> + var node = document.documentElement.childNodes.findElementByAttributeValue( + "name", + "mail_settings_identity_mobile_footer_default_free" + ) + + // String is not localized in all languages. + if (node != null) { + node.textContent = "" + foundString = true + } + } + } + + if (!foundString) throw PatchException("Could not find 'sent from' string in resources") + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt index 5233f186f..4828fe48a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt @@ -41,11 +41,12 @@ fun sharedExtensionPatch( execute { if (classes.none { EXTENSION_CLASS_DESCRIPTOR == it.type }) { - throw PatchException( - "Shared extension has not been merged yet. This patch can not succeed without merging it.", - ) + throw PatchException("Shared extension is not available. This patch can not succeed without it.") } + } + finalize { + // The hooks are made in finalize to ensure that the context is hooked before any other patches. hooks.forEach { hook -> hook(EXTENSION_CLASS_DESCRIPTOR) } // Modify Utils method to include the patches release version. @@ -92,7 +93,7 @@ fun sharedExtensionPatch( } class ExtensionHook internal constructor( - private val fingerprint: Fingerprint, + internal val fingerprint: Fingerprint, private val insertIndexResolver: ((Method) -> Int), private val contextRegisterResolver: (Method) -> String, ) { @@ -109,8 +110,14 @@ class ExtensionHook internal constructor( } } +fun extensionHook( + insertIndexResolver: ((Method) -> Int) = { 0 }, + contextRegisterResolver: (Method) -> String = { "p0" }, + fingerprint: Fingerprint, +) = ExtensionHook(fingerprint, insertIndexResolver, contextRegisterResolver) + fun extensionHook( insertIndexResolver: ((Method) -> Int) = { 0 }, contextRegisterResolver: (Method) -> String = { "p0" }, fingerprintBuilderBlock: FingerprintBuilder.() -> Unit, -) = ExtensionHook(fingerprint(block = fingerprintBuilderBlock), insertIndexResolver, contextRegisterResolver) +) = extensionHook(insertIndexResolver, contextRegisterResolver, fingerprint(block = fingerprintBuilderBlock)) diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt index 0e54bb691..64173c18c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt @@ -17,7 +17,6 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c -import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.StringReference import com.android.tools.smali.dexlib2.immutable.reference.ImmutableStringReference import com.android.tools.smali.dexlib2.util.MethodUtil @@ -110,19 +109,18 @@ fun gmsCoreSupportPatch( // region Collection of transformations that are applied to all strings. - fun commonTransform(referencedString: String): String? = - when (referencedString) { - "com.google", - "com.google.android.gms", - in PERMISSIONS, - in ACTIONS, - in AUTHORITIES, - -> referencedString.replace("com.google", gmsCoreVendorGroupId!!) + fun commonTransform(referencedString: String): String? = when (referencedString) { + "com.google", + "com.google.android.gms", + in PERMISSIONS, + in ACTIONS, + in AUTHORITIES, + -> referencedString.replace("com.google", gmsCoreVendorGroupId!!) - // No vendor prefix for whatever reason... - "subscribedfeeds" -> "$gmsCoreVendorGroupId.subscribedfeeds" - else -> null - } + // No vendor prefix for whatever reason... + "subscribedfeeds" -> "$gmsCoreVendorGroupId.subscribedfeeds" + else -> null + } fun contentUrisTransform(str: String): String? { // only when content:// uri @@ -205,16 +203,8 @@ fun gmsCoreSupportPatch( // Verify GmsCore is installed and whitelisted for power optimizations and background usage. mainActivityOnCreateFingerprint.method.apply { - // Temporary fix for patches with an extension patch that hook the onCreate method as well. - val setContextIndex = indexOfFirstInstruction { - val reference = getReference() ?: return@indexOfFirstInstruction false - - reference.toString() == "Lapp/revanced/extension/shared/Utils;->setContext(Landroid/content/Context;)V" - } - - // Add after setContext call, because this patch needs the context. addInstructions( - if (setContextIndex < 0) 0 else setContextIndex + 1, + 0, "invoke-static/range { p0 .. p0 }, Lapp/revanced/extension/shared/GmsCoreSupport;->" + "checkGmsCore(Landroid/app/Activity;)V", ) diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/settings/SettingsPatch.kt index d6d9df94c..c8d8bd1ea 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/settings/SettingsPatch.kt @@ -7,6 +7,8 @@ import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.shared.misc.settings.preference.BasePreference import app.revanced.patches.shared.misc.settings.preference.IntentPreference +import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory +import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference import app.revanced.util.ResourceGroup import app.revanced.util.copyResources import app.revanced.util.getNode @@ -36,14 +38,14 @@ fun settingsPatch ( execute { copyResources( "settings", - ResourceGroup("xml", "revanced_prefs.xml"), + ResourceGroup("xml", "revanced_prefs.xml", "revanced_prefs_icons.xml"), ) addResources("shared", "misc.settings.settingsResourcePatch") } finalize { - fun Node.addPreference(preference: BasePreference, prepend: Boolean = false) { + fun Node.addPreference(preference: BasePreference) { preference.serialize(ownerDocument) { resource -> // TODO: Currently, resources can only be added to "values", which may not be the correct place. // It may be necessary to ask for the desired resourceValue in the future. @@ -61,7 +63,7 @@ fun settingsPatch ( val preferenceFileName = "res/xml/$fileName.xml" if (get(preferenceFileName).exists()) { document(preferenceFileName).use { document -> - document.getNode("PreferenceScreen").addPreference(intent, true) + document.getNode("PreferenceScreen").addPreference(intent) } modified = true } @@ -71,6 +73,30 @@ fun settingsPatch ( } // Add all preferences to the ReVanced fragment. + document("res/xml/revanced_prefs_icons.xml").use { document -> + val revancedPreferenceScreenNode = document.getNode("PreferenceScreen") + preferences.forEach { revancedPreferenceScreenNode.addPreference(it) } + } + + // Because the icon preferences require declaring a layout resource, + // there is no easy way to change to the Android default preference layout + // after the preference is inflated. + // Using two different preference files is the simplest and most robust solution. + fun removeIconsAndLayout(preferences: Collection) { + preferences.forEach { preference -> + preference.icon = null + preference.layout = null + + if (preference is PreferenceCategory) { + removeIconsAndLayout(preference.preferences) + } + if (preference is PreferenceScreenPreference) { + removeIconsAndLayout(preference.preferences) + } + } + } + removeIconsAndLayout(preferences) + document("res/xml/revanced_prefs.xml").use { document -> val revancedPreferenceScreenNode = document.getNode("PreferenceScreen") preferences.forEach { revancedPreferenceScreenNode.addPreference(it) } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/settings/preference/BasePreference.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/settings/preference/BasePreference.kt index a07bdc4fe..5428b3983 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/settings/preference/BasePreference.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/settings/preference/BasePreference.kt @@ -19,10 +19,17 @@ abstract class BasePreference( val key: String? = null, val titleKey: String? = "${key}_title", val summaryKey: String? = "${key}_summary", - val icon: String? = null, - val layout: String? = null, + icon: String? = null, + layout: String? = null, val tag: String ) { + + var icon: String? = icon + internal set + + var layout: String? = layout + internal set + /** * Serialize preference element to XML. * Overriding methods should invoke super and operate on its return value. diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt index a24d1c334..7872b00be 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt @@ -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 @@ -94,14 +95,14 @@ fun spoofVideoStreamsPatch( getReference()?.name == "newUrlRequestBuilder" } val urlRegister = getInstruction(newRequestBuilderIndex).registerD - val freeRegister = getInstruction(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 + """ ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemeBytecodePatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemeBytecodePatch.kt new file mode 100644 index 000000000..2f639ef8d --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemeBytecodePatch.kt @@ -0,0 +1,82 @@ +package app.revanced.patches.spotify.layout.theme + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.fingerprint +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.spotify.misc.extension.IS_SPOTIFY_LEGACY_APP_TARGET +import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch +import app.revanced.util.* +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference + +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/spotify/layout/theme/CustomThemePatch;" + +internal val customThemeByteCodePatch = bytecodePatch { + dependsOn(sharedExtensionPatch) + + val backgroundColor by spotifyBackgroundColor + val backgroundColorSecondary by spotifyBackgroundColorSecondary + + execute { + if (IS_SPOTIFY_LEGACY_APP_TARGET) { + // Bytecode changes are not needed for legacy app target. + // Player background color is changed with existing resource patch. + return@execute + } + + fun MutableMethod.addColorChangeInstructions(literal: Long, colorString: String) { + val index = indexOfFirstLiteralInstructionOrThrow(literal) + val register = getInstruction(index).registerA + + addInstructions( + index + 1, + """ + const-string v$register, "$colorString" + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getThemeColor(Ljava/lang/String;)J + move-result-wide v$register + """ + ) + } + + val encoreColorsClassName = with(encoreThemeFingerprint) { + // Find index of the first static get found after the string constant. + val encoreColorsFieldReferenceIndex = originalMethod.indexOfFirstInstructionOrThrow( + stringMatches!!.first().index, + Opcode.SGET_OBJECT + ) + + originalMethod.getInstruction(encoreColorsFieldReferenceIndex) + .getReference()!!.definingClass + } + + val encoreColorsConstructorFingerprint = fingerprint { + accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) + custom { method, classDef -> + classDef.type == encoreColorsClassName && + method.containsLiteralInstruction(PLAYLIST_BACKGROUND_COLOR_LITERAL) + } + } + + encoreColorsConstructorFingerprint.method.apply { + // Playlist song list background color. + addColorChangeInstructions(PLAYLIST_BACKGROUND_COLOR_LITERAL, backgroundColor!!) + + // Share menu background color. + addColorChangeInstructions(SHARE_MENU_BACKGROUND_COLOR_LITERAL, backgroundColorSecondary!!) + } + + homeCategoryPillColorsFingerprint.method.apply { + // Home category pills background color. + addColorChangeInstructions(HOME_CATEGORY_PILL_COLOR_LITERAL, backgroundColorSecondary!!) + } + + settingsHeaderColorFingerprint.method.apply { + // Settings header background color. + addColorChangeInstructions(SETTINGS_HEADER_COLOR_LITERAL, backgroundColorSecondary!!) + } + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt index 8af9d65fb..5f2f09435 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt @@ -1,59 +1,24 @@ -@file:Suppress("NAME_SHADOWING") - package app.revanced.patches.spotify.layout.theme import app.revanced.patcher.patch.resourcePatch -import app.revanced.patcher.patch.stringOption import org.w3c.dom.Element @Suppress("unused") val customThemePatch = resourcePatch( name = "Custom theme", - description = "Applies a custom theme.", + description = "Applies a custom theme (defaults to amoled black)", use = false, ) { compatibleWith("com.spotify.music") - val backgroundColor by stringOption( - key = "backgroundColor", - default = "@android:color/black", - title = "Primary background color", - description = "The background color. Can be a hex color or a resource reference.", - required = true, - ) + dependsOn(customThemeByteCodePatch) - val backgroundColorSecondary by stringOption( - key = "backgroundColorSecondary", - default = "#ff282828", - title = "Secondary background color", - description = "The secondary background color. (e.g. search box, artist & podcast). Can be a hex color or a resource reference.", - required = true, - ) - - val accentColor by stringOption( - key = "accentColor", - default = "#ff1ed760", - title = "Accent color", - description = "The accent color ('Spotify green' by default). Can be a hex color or a resource reference.", - required = true, - ) - - val accentColorPressed by stringOption( - key = "accentColorPressed", - default = "#ff169c46", - title = "Pressed dark theme accent color", - description = - "The color when accented buttons are pressed, by default slightly darker than accent. " + - "Can be a hex color or a resource reference.", - required = true, - ) + val backgroundColor by spotifyBackgroundColor() + val backgroundColorSecondary by spotifyBackgroundColorSecondary() + val accentColor by spotifyAccentColor() + val accentColorPressed by spotifyAccentColorPressed() execute { - val backgroundColor = backgroundColor!! - val backgroundColorSecondary = backgroundColorSecondary!! - val accentColor = accentColor!! - val accentColorPressed = accentColorPressed!! - document("res/values/colors.xml").use { document -> val resourcesNode = document.getElementsByTagName("resources").item(0) as Element @@ -61,20 +26,37 @@ val customThemePatch = resourcePatch( for (i in 0 until childNodes.length) { val node = childNodes.item(i) as? Element ?: continue - node.textContent = - when (node.getAttribute("name")) { - "dark_base_background_elevated_base", "design_dark_default_color_background", - "design_dark_default_color_surface", "gray_7", "gray_background", "gray_layer", - "sthlm_blk", + node.textContent = when (node.getAttribute("name")) { + // Gradient next to user photo and "All" in home page + "dark_base_background_base", + // Main background + "gray_7", + // Left sidebar background in tablet mode + "gray_10", + // Add account, Settings and privacy, View Profile left sidebar background + "dark_base_background_elevated_base", + // Song/player background + "bg_gradient_start_color", "bg_gradient_end_color", + // Login screen + "sthlm_blk", "sthlm_blk_grad_start", "stockholm_black", + // Misc + "image_placeholder_color", -> backgroundColor - "gray_15" -> backgroundColorSecondary + // Track credits, merch in song player + "track_credits_card_bg", "benefit_list_default_color", "merch_card_background", + // Playlist list background in home page + "opacity_white_10", + // About artist background in song player + "gray_15", + // What's New pills background + "dark_base_background_tinted_highlight" + -> backgroundColorSecondary - "dark_brightaccent_background_base", "dark_base_text_brightaccent", "green_light" -> accentColor - - "dark_brightaccent_background_press" -> accentColorPressed - else -> continue - } + "dark_brightaccent_background_base", "dark_base_text_brightaccent", "green_light" -> accentColor + "dark_brightaccent_background_press" -> accentColorPressed + else -> continue + } } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/Fingerprints.kt new file mode 100644 index 000000000..28943e040 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/Fingerprints.kt @@ -0,0 +1,30 @@ +package app.revanced.patches.spotify.layout.theme + +import app.revanced.patcher.fingerprint +import app.revanced.util.containsLiteralInstruction +import com.android.tools.smali.dexlib2.AccessFlags + +internal val encoreThemeFingerprint = fingerprint { + strings("Encore theme was not provided.") // Partial string match. +} + +internal const val SETTINGS_HEADER_COLOR_LITERAL = 0xFF282828 +internal const val HOME_CATEGORY_PILL_COLOR_LITERAL = 0xFF333333 +internal const val PLAYLIST_BACKGROUND_COLOR_LITERAL = 0xFF121212 +internal const val SHARE_MENU_BACKGROUND_COLOR_LITERAL = 0xFF1F1F1F + +internal val homeCategoryPillColorsFingerprint = fingerprint{ + accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) + custom { method, _ -> + method.containsLiteralInstruction(HOME_CATEGORY_PILL_COLOR_LITERAL) && + method.containsLiteralInstruction(0x33000000) + } +} + +internal val settingsHeaderColorFingerprint = fingerprint { + accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) + custom { method, _ -> + method.containsLiteralInstruction(SETTINGS_HEADER_COLOR_LITERAL) && + method.containsLiteralInstruction(0) + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/Options.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/Options.kt new file mode 100644 index 000000000..e71c97912 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/Options.kt @@ -0,0 +1,36 @@ +package app.revanced.patches.spotify.layout.theme + +import app.revanced.patcher.patch.stringOption + +internal val spotifyBackgroundColor = stringOption( + key = "backgroundColor", + default = "@android:color/black", + title = "Primary background color", + description = "The background color. Can be a hex color or a resource reference.", + required = true, +) + +internal val spotifyBackgroundColorSecondary = stringOption( + key = "backgroundColorSecondary", + default = "#FF121212", + title = "Secondary background color", + description = "The secondary background color. (e.g. playlist list, player arist, credits). Can be a hex color or a resource reference.", + required = true, +) + +internal val spotifyAccentColor = stringOption( + key = "accentColor", + default = "#FF1ED760", + title = "Accent color", + description = "The accent color ('Spotify green' by default). Can be a hex color or a resource reference.", + required = true, +) + +internal val spotifyAccentColorPressed = stringOption( + key = "accentColorPressed", + default = "#FF169C46", + title = "Pressed dark theme accent color", + description = + "The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.", + required = true, +) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt index 876d390f2..c6fe5fcec 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt @@ -1,15 +1,28 @@ package app.revanced.patches.spotify.misc import app.revanced.patcher.fingerprint +import app.revanced.patches.spotify.misc.extension.IS_SPOTIFY_LEGACY_APP_TARGET +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode internal val accountAttributeFingerprint = fingerprint { - custom { _, c -> c.endsWith("internal/AccountAttribute;") } + custom { _, classDef -> + classDef.type == if (IS_SPOTIFY_LEGACY_APP_TARGET) { + "Lcom/spotify/useraccount/v1/AccountAttribute;" + } else { + "Lcom/spotify/remoteconfig/internal/AccountAttribute;" + } + } } internal val productStateProtoFingerprint = fingerprint { returns("Ljava/util/Map;") custom { _, classDef -> - classDef.endsWith("ProductStateProto;") + classDef.type == if (IS_SPOTIFY_LEGACY_APP_TARGET) { + "Lcom/spotify/ucs/proto/v0/UcsResponseWrapper${'$'}AccountAttributesResponse;" + } else { + "Lcom/spotify/remoteconfig/internal/ProductStateProto;" + } } } @@ -21,3 +34,38 @@ internal val contextMenuExperimentsFingerprint = fingerprint { parameters("L") strings("remove_ads_upsell_enabled") } + +internal val contextFromJsonFingerprint = fingerprint { + opcodes( + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC + ) + custom { methodDef, classDef -> + methodDef.name == "fromJson" && + classDef.endsWith("voiceassistants/playermodels/ContextJsonAdapter;") + } +} + +internal val readPlayerOptionOverridesFingerprint = fingerprint { + custom { methodDef, classDef -> + methodDef.name == "readPlayerOptionOverrides" && + classDef.endsWith("voiceassistants/playermodels/PreparePlayOptionsJsonAdapter;") + } +} + +internal val homeSectionFingerprint = fingerprint { + custom { _, classDef -> classDef.endsWith("homeapi/proto/Section;") } +} + +internal val protobufListsFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) + custom { method, _ -> method.name == "emptyProtobufList" } +} + +internal val homeStructureFingerprint = fingerprint { + opcodes(Opcode.IGET_OBJECT, Opcode.RETURN_OBJECT) + custom { _, classDef -> classDef.endsWith("homeapi/proto/HomeStructure;") } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/UnlockPremiumPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/UnlockPremiumPatch.kt index b81699fdb..4c4889d97 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/UnlockPremiumPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/UnlockPremiumPatch.kt @@ -1,12 +1,26 @@ package app.revanced.patches.spotify.misc import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.fingerprint import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.spotify.misc.check.checkEnvironmentPatch +import app.revanced.patches.spotify.misc.extension.IS_SPOTIFY_LEGACY_APP_TARGET import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch +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.FiveRegisterInstruction 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 +import java.util.logging.Logger private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/spotify/misc/UnlockPremiumPatch;" @@ -17,7 +31,12 @@ val unlockPremiumPatch = bytecodePatch( ) { compatibleWith("com.spotify.music") - dependsOn(sharedExtensionPatch) + dependsOn( + sharedExtensionPatch, + // Currently there is no easy way to make a mandatory patch, + // so for now this is a dependent of this patch. + checkEnvironmentPatch, + ) execute { // Make _value accessible so that it can be overridden in the extension. @@ -27,23 +46,121 @@ val unlockPremiumPatch = bytecodePatch( } // Override the attributes map in the getter method. - val attributesMapRegister = 0 - val instantiateUnmodifiableMapIndex = 1 - productStateProtoFingerprint.method.addInstruction( - instantiateUnmodifiableMapIndex, - "invoke-static { v$attributesMapRegister }," + - "$EXTENSION_CLASS_DESCRIPTOR->overrideAttribute(Ljava/util/Map;)V", - ) + with(productStateProtoFingerprint.method) { + val getAttributesMapIndex = indexOfFirstInstructionOrThrow(Opcode.IGET_OBJECT) + val attributesMapRegister = getInstruction(getAttributesMapIndex).registerA + + addInstruction( + getAttributesMapIndex + 1, + "invoke-static { v$attributesMapRegister }, " + + "$EXTENSION_CLASS_DESCRIPTOR->overrideAttribute(Ljava/util/Map;)V" + ) + } + // Add the query parameter trackRows to show popular tracks in the artist page. - val addQueryParameterIndex = buildQueryParametersFingerprint.stringMatches!!.first().index - 1 - buildQueryParametersFingerprint.method.replaceInstruction(addQueryParameterIndex, "nop") + with(buildQueryParametersFingerprint) { + val addQueryParameterConditionIndex = method.indexOfFirstInstructionReversedOrThrow( + stringMatches!!.first().index, Opcode.IF_EQZ + ) + method.replaceInstruction(addQueryParameterConditionIndex, "nop") + } + + + if (IS_SPOTIFY_LEGACY_APP_TARGET) { + return@execute Logger.getLogger(this::class.java.name).warning( + "Patching a legacy Spotify version. Patch functionality may be limited." + ) + } + + + // Enable choosing a specific song/artist via Google Assistant. + contextFromJsonFingerprint.method.apply { + val insertIndex = contextFromJsonFingerprint.patternMatch!!.startIndex + // Both the URI and URL need to be modified. + val registerUrl = getInstruction(insertIndex).registerC + val registerUri = getInstruction(insertIndex + 2).registerD + + val extensionMethodDescriptor = "$EXTENSION_CLASS_DESCRIPTOR->" + + "removeStationString(Ljava/lang/String;)Ljava/lang/String;" + + addInstructions( + insertIndex, + """ + invoke-static { v$registerUrl }, $extensionMethodDescriptor + move-result-object v$registerUrl + invoke-static { v$registerUri }, $extensionMethodDescriptor + move-result-object v$registerUri + """ + ) + } + + + // Disable forced shuffle when asking for an album/playlist via Google Assistant. + readPlayerOptionOverridesFingerprint.method.apply { + val shufflingContextCallIndex = indexOfFirstInstructionOrThrow { + getReference()?.name == "shufflingContext" + } + + val registerBool = getInstruction(shufflingContextCallIndex).registerD + addInstruction( + shufflingContextCallIndex, + "sget-object v$registerBool, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;" + ) + } + // Disable the "Spotify Premium" upsell experiment in context menus. with(contextMenuExperimentsFingerprint) { - val moveIsEnabledIndex = stringMatches!!.first().index + 2 + val moveIsEnabledIndex = method.indexOfFirstInstructionOrThrow( + stringMatches!!.first().index, Opcode.MOVE_RESULT + ) val isUpsellEnabledRegister = method.getInstruction(moveIsEnabledIndex).registerA method.replaceInstruction(moveIsEnabledIndex, "const/4 v$isUpsellEnabledRegister, 0") } + + + // Make featureTypeCase_ accessible so we can check the home section type in the extension. + homeSectionFingerprint.classDef.fields.first { it.name == "featureTypeCase_" }.apply { + accessFlags = accessFlags.or(AccessFlags.PUBLIC.value).and(AccessFlags.PRIVATE.value.inv()) + } + + val protobufListClassName = with(protobufListsFingerprint.originalMethod) { + val emptyProtobufListGetIndex = indexOfFirstInstructionOrThrow(Opcode.SGET_OBJECT) + getInstruction(emptyProtobufListGetIndex).getReference()!!.definingClass + } + + val protobufListRemoveFingerprint = fingerprint { + custom { method, classDef -> + method.name == "remove" && classDef.type == protobufListClassName + } + } + + // Need to allow mutation of the list so the home ads sections can be removed. + // Protobuffer list has an 'isMutable' boolean parameter that sets the mutability. + // Forcing that always on breaks unrelated code in strange ways. + // Instead, remove the method call that checks if the list is unmodifiable. + with(protobufListRemoveFingerprint.method) { + val invokeThrowUnmodifiableIndex = indexOfFirstInstructionOrThrow { + val reference = getReference() + opcode == Opcode.INVOKE_VIRTUAL && + reference?.returnType == "V" && reference.parameterTypes.isEmpty() + } + + // Remove the method call that throws an exception if the list is not mutable. + removeInstruction(invokeThrowUnmodifiableIndex) + } + + // Remove ads sections from home. + with(homeStructureFingerprint.method) { + val getSectionsIndex = indexOfFirstInstructionOrThrow(Opcode.IGET_OBJECT) + val sectionsRegister = getInstruction(getSectionsIndex).registerA + + addInstruction( + getSectionsIndex + 1, + "invoke-static { v$sectionsRegister }, " + + "$EXTENSION_CLASS_DESCRIPTOR->removeHomeSections(Ljava/util/List;)V" + ) + } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/check/CheckEnvironmentPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/check/CheckEnvironmentPatch.kt new file mode 100644 index 000000000..81d42ce66 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/check/CheckEnvironmentPatch.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.spotify.misc.check + +import app.revanced.patches.shared.misc.checks.checkEnvironmentPatch +import app.revanced.patches.spotify.shared.mainActivityOnCreateFingerprint +import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch + +internal val checkEnvironmentPatch = checkEnvironmentPatch( + mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint, + extensionPatch = sharedExtensionPatch, + "com.spotify.music", +) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/ExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/ExtensionPatch.kt index 6b95f437a..438fe49df 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/ExtensionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/ExtensionPatch.kt @@ -1,5 +1,21 @@ package app.revanced.patches.spotify.misc.extension +import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.shared.misc.extension.sharedExtensionPatch +import app.revanced.patches.spotify.shared.SPOTIFY_MAIN_ACTIVITY_LEGACY -val sharedExtensionPatch = sharedExtensionPatch("spotify", spotifyMainActivityOnCreate) +/** + * If patching a legacy 8.x target. This may also be set if patching slightly older/newer app targets, + * but the only legacy target of interest is 8.6.98.900 as it's the last version that + * supports Spotify integration on Kenwood/Pioneer car stereos. + */ +internal var IS_SPOTIFY_LEGACY_APP_TARGET = false + +val sharedExtensionPatch = bytecodePatch { + dependsOn(sharedExtensionPatch("spotify", mainActivityOnCreateHook)) + + execute { + IS_SPOTIFY_LEGACY_APP_TARGET = mainActivityOnCreateHook.fingerprint + .originalClassDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt index baed926ea..6153f4b60 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt @@ -1,10 +1,6 @@ package app.revanced.patches.spotify.misc.extension import app.revanced.patches.shared.misc.extension.extensionHook +import app.revanced.patches.spotify.shared.mainActivityOnCreateFingerprint -internal val spotifyMainActivityOnCreate = extensionHook { - custom { method, classDef -> - classDef.type == "Lcom/spotify/music/SpotifyMainActivity;" && - method.name == "onCreate" - } -} +internal val mainActivityOnCreateHook = extensionHook(fingerprint = mainActivityOnCreateFingerprint) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/shared/Fingerprints.kt new file mode 100644 index 000000000..14149ac7a --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/shared/Fingerprints.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.spotify.shared + +import app.revanced.patcher.fingerprint + +private const val SPOTIFY_MAIN_ACTIVITY = "Lcom/spotify/music/SpotifyMainActivity;" + +/** + * Main activity of target 8.6.98.900. + */ +internal const val SPOTIFY_MAIN_ACTIVITY_LEGACY = "Lcom/spotify/music/MainActivity;" + +internal val mainActivityOnCreateFingerprint = fingerprint { + custom { method, classDef -> + method.name == "onCreate" && (classDef.type == SPOTIFY_MAIN_ACTIVITY + || classDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/strava/upselling/DisableSubscriptionSuggestionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/strava/upselling/DisableSubscriptionSuggestionsPatch.kt index 73246fa21..c91bb961a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/strava/upselling/DisableSubscriptionSuggestionsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/strava/upselling/DisableSubscriptionSuggestionsPatch.kt @@ -12,7 +12,7 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod val disableSubscriptionSuggestionsPatch = bytecodePatch( name = "Disable subscription suggestions", ) { - compatibleWith("com.strava"("320.12")) + compatibleWith("com.strava") execute { val helperMethodName = "getModulesIfNotUpselling" diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisablePreciseSeekingGesturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisablePreciseSeekingGesturePatch.kt index 4f0357954..8cecc1400 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisablePreciseSeekingGesturePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisablePreciseSeekingGesturePatch.kt @@ -11,8 +11,10 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch +private const val EXTENSION_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/youtube/patches/DisablePreciseSeekingGesturePatch;" + val disablePreciseSeekingGesturePatch = bytecodePatch( - name = "Disable precise seeking gesture", description = "Adds an option to disable precise seeking when swiping up on the seekbar.", ) { dependsOn( @@ -21,25 +23,12 @@ val disablePreciseSeekingGesturePatch = bytecodePatch( addResourcesPatch, ) - compatibleWith( - "com.google.android.youtube"( - "19.16.39", - "19.25.37", - "19.34.42", - "19.43.41", - "19.47.53", - "20.07.39", - ), - ) - execute { addResources("youtube", "interaction.seekbar.disablePreciseSeekingGesturePatch") PreferenceScreen.SEEKBAR.addPreferences( SwitchPreference("revanced_disable_precise_seeking_gesture"), ) - val extensionMethodDescriptor = - "Lapp/revanced/extension/youtube/patches/DisablePreciseSeekingGesturePatch;" allowSwipingUpGestureFingerprint.match( swipingUpGestureParentFingerprint.originalClassDef, @@ -47,7 +36,7 @@ val disablePreciseSeekingGesturePatch = bytecodePatch( addInstructionsWithLabels( 0, """ - invoke-static { }, $extensionMethodDescriptor->isGestureDisabled()Z + invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->isGestureDisabled()Z move-result v0 if-eqz v0, :disabled return-void @@ -62,7 +51,7 @@ val disablePreciseSeekingGesturePatch = bytecodePatch( addInstructionsWithLabels( 0, """ - invoke-static { }, $extensionMethodDescriptor->isGestureDisabled()Z + invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->isGestureDisabled()Z move-result v0 if-eqz v0, :disabled const/4 v0, 0x0 diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt index 60a424e28..fadf2357f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt @@ -15,7 +15,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.reference.MethodReference val enableSeekbarTappingPatch = bytecodePatch( - name = "Enable tap to seek", description = "Adds an option to enable tap to seek on the seekbar of the video player.", ) { dependsOn( @@ -24,17 +23,6 @@ val enableSeekbarTappingPatch = bytecodePatch( addResourcesPatch, ) - compatibleWith( - "com.google.android.youtube"( - "19.16.39", - "19.25.37", - "19.34.42", - "19.43.41", - "19.47.53", - "20.07.39", - ), - ) - execute { addResources("youtube", "interaction.seekbar.enableSeekbarTappingPatch") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt index e7dc185a4..1a19d5b91 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt @@ -18,11 +18,9 @@ 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 -internal const val EXTENSION_METHOD_DESCRIPTOR = - "Lapp/revanced/extension/youtube/patches/SlideToSeekPatch;->isSlideToSeekDisabled(Z)Z" +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/SlideToSeekPatch;" val enableSlideToSeekPatch = bytecodePatch( - name = "Enable slide to seek", description = "Adds an option to enable slide to seek " + "instead of playing at 2x speed when pressing and holding in the video player." ) { @@ -33,17 +31,6 @@ val enableSlideToSeekPatch = bytecodePatch( versionCheckPatch, ) - compatibleWith( - "com.google.android.youtube"( - "19.16.39", - "19.25.37", - "19.34.42", - "19.43.41", - "19.47.53", - "20.07.39", - ), - ) - execute { addResources("youtube", "interaction.seekbar.enableSlideToSeekPatch") @@ -59,6 +46,8 @@ val enableSlideToSeekPatch = bytecodePatch( val checkReference = slideToSeekFingerprint.method.getInstruction(checkIndex) .getReference()!! + val extensionMethodDescriptor = "$EXTENSION_CLASS_DESCRIPTOR->isSlideToSeekDisabled(Z)Z" + // A/B check method was only called on this class. slideToSeekFingerprint.classDef.methods.forEach { method -> method.findInstructionIndicesReversed { @@ -70,7 +59,7 @@ val enableSlideToSeekPatch = bytecodePatch( addInstructions( index + 2, """ - invoke-static { v$register }, $EXTENSION_METHOD_DESCRIPTOR + invoke-static { v$register }, $extensionMethodDescriptor move-result v$register """, ) @@ -95,7 +84,7 @@ val enableSlideToSeekPatch = bytecodePatch( addInstructions( targetIndex + 1, """ - invoke-static { v$targetRegister }, $EXTENSION_METHOD_DESCRIPTOR + invoke-static { v$targetRegister }, $extensionMethodDescriptor move-result v$targetRegister """, ) @@ -109,7 +98,7 @@ val enableSlideToSeekPatch = bytecodePatch( addInstructions( insertIndex, """ - invoke-static { v$targetRegister }, $EXTENSION_METHOD_DESCRIPTOR + invoke-static { v$targetRegister }, $extensionMethodDescriptor move-result v$targetRegister """, ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/HideSeekbarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/HideSeekbarPatch.kt new file mode 100644 index 000000000..ddf21dd85 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/HideSeekbarPatch.kt @@ -0,0 +1,46 @@ +package app.revanced.patches.youtube.interaction.seekbar + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference +import app.revanced.patches.youtube.layout.seekbar.seekbarColorPatch +import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch +import app.revanced.patches.youtube.misc.settings.PreferenceScreen +import app.revanced.patches.youtube.misc.settings.settingsPatch +import app.revanced.patches.youtube.shared.seekbarFingerprint +import app.revanced.patches.youtube.shared.seekbarOnDrawFingerprint + +val hideSeekbarPatch = bytecodePatch( + description = "Adds an option to hide the seekbar.", +) { + dependsOn( + sharedExtensionPatch, + settingsPatch, + seekbarColorPatch, + addResourcesPatch, + ) + + execute { + addResources("youtube", "layout.hide.seekbar.hideSeekbarPatch") + + PreferenceScreen.SEEKBAR.addPreferences( + SwitchPreference("revanced_hide_seekbar"), + SwitchPreference("revanced_hide_seekbar_thumbnail"), + ) + + seekbarOnDrawFingerprint.match(seekbarFingerprint.originalClassDef).method.addInstructionsWithLabels( + 0, + """ + const/4 v0, 0x0 + invoke-static { }, Lapp/revanced/extension/youtube/patches/HideSeekbarPatch;->hideSeekbar()Z + move-result v0 + if-eqz v0, :hide_seekbar + return-void + :hide_seekbar + nop + """, + ) + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarPatch.kt new file mode 100644 index 000000000..7c053f5e4 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarPatch.kt @@ -0,0 +1,31 @@ +package app.revanced.patches.youtube.interaction.seekbar + +import app.revanced.patcher.patch.bytecodePatch + +@Suppress("unused") +val seekbarPatch = bytecodePatch( + name = "Seekbar", + description = "Adds options to disable precise seeking when swiping up on the seekbar, " + + "slide to seek instead of playing at 2x speed when pressing and holding, " + + "tapping the player seekbar to seek, " + + "and hiding the video player seekbar." +) { + dependsOn( + disablePreciseSeekingGesturePatch, + enableSlideToSeekPatch, + enableSeekbarTappingPatch, + hideSeekbarPatch, + seekbarThumbnailsPatch + ) + + compatibleWith( + "com.google.android.youtube"( + "19.16.39", + "19.25.37", + "19.34.42", + "19.43.41", + "19.47.53", + "20.07.39", + ) + ) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarThumbnailsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarThumbnailsPatch.kt index a890d6c11..114f25895 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarThumbnailsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarThumbnailsPatch.kt @@ -10,6 +10,7 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.layout.seekbar.fullscreenSeekbarThumbnailsFingerprint import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.playservice.is_19_17_or_greater +import app.revanced.patches.youtube.misc.playservice.is_20_09_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen @@ -17,7 +18,6 @@ private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/SeekbarThumbnailsPatch;" val seekbarThumbnailsPatch = bytecodePatch( - name = "Seekbar thumbnails", description = "Adds an option to use high quality fullscreen seekbar thumbnails. " + "Patching 19.16.39 adds an option to restore old seekbar thumbnails.", ) { @@ -27,18 +27,13 @@ val seekbarThumbnailsPatch = bytecodePatch( versionCheckPatch, ) - compatibleWith( - "com.google.android.youtube"( - "19.16.39", - "19.25.37", - "19.34.42", - "19.43.41", - "19.47.53", - "20.07.39", - ) - ) - execute { + if (is_20_09_or_greater) { + // High quality seekbar thumbnails is partially broken in 20.09 + // and the code is completely removed in 20.10+ + return@execute + } + addResources("youtube", "layout.seekbar.seekbarThumbnailsPatch") if (is_19_17_or_greater) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt index 2d96d134b..d66202255 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt @@ -20,11 +20,10 @@ 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.is_20_07_or_greater -import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch +import app.revanced.util.findFreeRegister import app.revanced.util.findInstructionIndicesReversedOrThrow import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow @@ -123,7 +122,6 @@ val hideLayoutComponentsPatch = bytecodePatch( addResourcesPatch, hideLayoutComponentsResourcePatch, navigationBarHookPatch, - versionCheckPatch ) compatibleWith( @@ -132,8 +130,6 @@ val hideLayoutComponentsPatch = bytecodePatch( "19.25.37", "19.34.42", "19.43.41", - "19.45.38", - "19.46.42", "19.47.53", "20.07.39", ), @@ -254,17 +250,16 @@ val hideLayoutComponentsPatch = bytecodePatch( (if (is_20_07_or_greater) parseElementFromBufferFingerprint else parseElementFromBufferLegacyFingerprint).let { it.method.apply { - // Target code is a mess with a lot of register moves. - // There is no simple way to find a free register for all versions so this is hard coded. - val freeRegister = if (is_19_47_or_greater) 6 else 0 val byteArrayParameter = "p3" val startIndex = it.patternMatch!!.startIndex val conversionContextRegister = getInstruction(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, + insertIndex, """ invoke-static { v$conversionContextRegister, $byteArrayParameter }, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->filterMixPlaylists(Ljava/lang/Object;[B)Z move-result v$freeRegister @@ -272,7 +267,7 @@ val hideLayoutComponentsPatch = bytecodePatch( 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 + nop """, ExternalLabel("return_empty_component", returnEmptyComponentInstruction), ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt index c17e4668d..cf104622e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt @@ -51,7 +51,10 @@ val hidePlayerFlyoutMenuPatch = bytecodePatch( SwitchPreference("revanced_hide_player_flyout_speed"), SwitchPreference("revanced_hide_player_flyout_lock_screen"), SwitchPreference("revanced_hide_player_flyout_more_info"), - SwitchPreference("revanced_hide_player_flyout_audio_track"), + SwitchPreference( + key = "revanced_hide_player_flyout_audio_track", + tag = "app.revanced.extension.youtube.settings.preference.HideAudioFlyoutMenuPreference" + ), SwitchPreference("revanced_hide_player_flyout_watch_in_vr"), SwitchPreference("revanced_hide_player_flyout_sleep_timer"), SwitchPreference("revanced_hide_player_flyout_video_quality_footer"), diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/HideSeekbarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/HideSeekbarPatch.kt index 68b516ebb..edf7390ce 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/HideSeekbarPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/HideSeekbarPatch.kt @@ -1,58 +1,11 @@ package app.revanced.patches.youtube.layout.hide.seekbar -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.all.misc.resources.addResources -import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.settings.preference.SwitchPreference -import app.revanced.patches.youtube.layout.seekbar.seekbarColorPatch -import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch -import app.revanced.patches.youtube.misc.settings.PreferenceScreen -import app.revanced.patches.youtube.misc.settings.settingsPatch -import app.revanced.patches.youtube.shared.seekbarFingerprint -import app.revanced.patches.youtube.shared.seekbarOnDrawFingerprint +import app.revanced.patches.youtube.interaction.seekbar.hideSeekbarPatch -val hideSeekbarPatch = bytecodePatch( - name = "Hide seekbar", - description = "Adds an option to hide the seekbar.", -) { +@Deprecated("Patch was moved to app.revanced.patches.youtube.interaction.seekbar") +val hideSeekbarPatch = bytecodePatch { dependsOn( - sharedExtensionPatch, - settingsPatch, - seekbarColorPatch, - addResourcesPatch, + hideSeekbarPatch ) - - compatibleWith( - "com.google.android.youtube"( - "19.16.39", - "19.25.37", - "19.34.42", - "19.43.41", - "19.47.53", - "20.07.39", - ), - ) - - execute { - addResources("youtube", "layout.hide.seekbar.hideSeekbarPatch") - - PreferenceScreen.SEEKBAR.addPreferences( - SwitchPreference("revanced_hide_seekbar"), - SwitchPreference("revanced_hide_seekbar_thumbnail"), - ) - - seekbarOnDrawFingerprint.match(seekbarFingerprint.originalClassDef).method.addInstructionsWithLabels( - 0, - """ - const/4 v0, 0x0 - invoke-static { }, Lapp/revanced/extension/youtube/patches/HideSeekbarPatch;->hideSeekbar()Z - move-result v0 - if-eqz v0, :hide_seekbar - return-void - :hide_seekbar - nop - """, - ) - } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt index 8f8ba6b4e..87ef9b707 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt @@ -168,11 +168,8 @@ val miniplayerPatch = bytecodePatch( // 19.30.39 // Modern 3 is less broken when double tap expand is enabled, but cannot swipe to expand when double tap is off. // 19.31.36 // All Modern 1 buttons are missing. Unusable. // 19.32.36 // 19.32+ and beyond all work without issues. - // 19.33.35 "19.34.42", "19.43.41", - "19.45.38", - "19.46.42", "19.47.53", "20.07.39", ), diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatch.kt index a5ab54772..7e6166fd5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatch.kt @@ -25,7 +25,6 @@ val openVideosFullscreenPatch = bytecodePatch( compatibleWith( "com.google.android.youtube"( - "19.46.42", "19.47.53", "20.07.39", ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt index 02d9aa46d..2d972d917 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt @@ -70,6 +70,8 @@ val returnYouTubeDislikePatch = bytecodePatch( key = "revanced_settings_screen_09", titleKey = "revanced_ryd_settings_title", summaryKey = null, + icon = "@drawable/revanced_settings_screen_09_ryd", + layout = "@layout/preference_with_icon", intent = newIntent("revanced_ryd_settings_intent"), ), ) @@ -179,9 +181,6 @@ val returnYouTubeDislikePatch = bytecodePatch( // region Hook rolling numbers. - // Do this last to allow patching old unsupported versions (if the user really wants), - // On older unsupported version this will fail to match and throw an exception, - // but everything will still work correctly anyway. val dislikesIndex = rollingNumberSetterFingerprint.patternMatch!!.endIndex rollingNumberSetterFingerprint.method.apply { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt index 8ed9c4e44..25d291809 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt @@ -84,31 +84,14 @@ internal val playerLinearGradientFingerprint = fingerprint { } /** - * 19.46 - 19.47 + * 19.25 - 19.47 */ -internal val playerLinearGradientLegacy1946Fingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - parameters("I", "I", "I", "I") +internal val playerLinearGradientLegacyFingerprint = fingerprint { returns("V") opcodes( Opcode.FILLED_NEW_ARRAY, Opcode.MOVE_RESULT_OBJECT ) - custom { method, _ -> - method.name == "setBounds" && method.containsLiteralInstruction(ytYoutubeMagentaColorId) - } -} - -/** - * 19.25 - 19.45 - */ -internal val playerLinearGradientLegacy1925Fingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - parameters("Landroid/content/Context;") - opcodes( - Opcode.FILLED_NEW_ARRAY, - Opcode.MOVE_RESULT_OBJECT - ) literal { ytYoutubeMagentaColorId } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt index dbfacc7d4..2185ef849 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.youtube.layout.seekbar +import app.revanced.patcher.Fingerprint import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction @@ -310,14 +311,15 @@ val seekbarColorPatch = bytecodePatch( """ ) - val playerFingerprint = - if (is_19_49_or_greater) { - playerLinearGradientFingerprint - } else if (is_19_46_or_greater) { - playerLinearGradientLegacy1946Fingerprint - } else { - playerLinearGradientLegacy1925Fingerprint - } + val playerFingerprint: Fingerprint + val checkGradientCoordinates: Boolean + if (is_19_49_or_greater) { + playerFingerprint = playerLinearGradientFingerprint + checkGradientCoordinates = true + } else { + playerFingerprint = playerLinearGradientLegacyFingerprint + checkGradientCoordinates = false + } playerFingerprint.let { it.method.apply { @@ -326,10 +328,17 @@ val seekbarColorPatch = bytecodePatch( addInstructions( index + 1, - """ - invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getPlayerLinearGradient([I)[I - move-result-object v$register - """ + if (checkGradientCoordinates) { + """ + invoke-static { v$register, p0, p1 }, $EXTENSION_CLASS_DESCRIPTOR->getPlayerLinearGradient([III)[I + move-result-object v$register + """ + } else { + """ + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getPlayerLinearGradient([I)[I + move-result-object v$register + """ + } ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt index bf17b3792..c9bf0043d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt @@ -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 @@ -106,11 +106,12 @@ val openShortsInRegularPlayerPatch = bytecodePatch( getReference()?.returnType == "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;" } - val freeRegister = getInstruction(index).registerC val playbackStartRegister = getInstruction(index + 1).registerA + val insertIndex = index + 2 + val freeRegister = findFreeRegister(insertIndex, playbackStartRegister) addInstructionsWithLabels( - index + 2, + insertIndex, extensionInstructions(playbackStartRegister, freeRegister) ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt index 5e33ebd2d..e9f7e945c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt @@ -48,6 +48,8 @@ private val sponsorBlockResourcePatch = resourcePatch { key = "revanced_settings_screen_10", titleKey = "revanced_sb_settings_title", summaryKey = null, + icon = "@drawable/revanced_settings_screen_10_sb", + layout = "@layout/preference_with_icon", intent = newIntent("revanced_sb_settings_intent"), ), ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt index 3d5d73639..a8945a528 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt @@ -1,9 +1,7 @@ package app.revanced.patches.youtube.layout.startupshortsreset import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch @@ -12,11 +10,12 @@ 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.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference @@ -39,8 +38,6 @@ val disableResumingShortsOnStartupPatch = bytecodePatch( "19.25.37", "19.34.42", "19.43.41", - "19.45.38", - "19.46.42", "19.47.53", "20.07.39", ), @@ -80,23 +77,19 @@ val disableResumingShortsOnStartupPatch = bytecodePatch( reference?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" && reference.name == "isDone" } - val originalInstructionRegister = - getInstruction(listenableInstructionIndex).registerC - val freeRegister = - getInstruction(listenableInstructionIndex + 1).registerA + val freeRegister = findFreeRegister(listenableInstructionIndex) - addInstructionsWithLabels( - listenableInstructionIndex + 1, + addInstructionsAtControlFlowLabel( + listenableInstructionIndex, """ invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z move-result v$freeRegister if-eqz v$freeRegister, :show return-void :show - invoke-interface {v$originalInstructionRegister}, Lcom/google/common/util/concurrent/ListenableFuture;->isDone()Z + nop """ ) - removeInstruction(listenableInstructionIndex) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playbackspeed/FIxPlaybackSpeedWhilePlayingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playbackspeed/FIxPlaybackSpeedWhilePlayingPatch.kt index 4d280cd88..b63eec794 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playbackspeed/FIxPlaybackSpeedWhilePlayingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playbackspeed/FIxPlaybackSpeedWhilePlayingPatch.kt @@ -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(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 diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt index 2172d75b5..fdb65ff27 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt @@ -36,8 +36,6 @@ val bypassURLRedirectsPatch = bytecodePatch( "19.25.37", "19.34.42", "19.43.41", - "19.45.38", - "19.46.42", "19.47.53", "20.07.39", ), diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt index b586bf2e3..1ede2fe5d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt @@ -8,7 +8,6 @@ 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 @@ -16,12 +15,14 @@ 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 @@ -191,17 +192,7 @@ val lithoFilterPatch = bytecodePatch( }, ).registerA - // Find a free temporary register. - val freeRegister = getInstruction( - // 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 diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt index 3a84ca69d..8ef699f6b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt @@ -73,7 +73,22 @@ private val settingsResourcePatch = resourcePatch { appearanceStringId = resourceMappings["string", "app_theme_appearance_dark"] arrayOf( - ResourceGroup("drawable", "revanced_settings_icon.xml"), + ResourceGroup("drawable", + "revanced_settings_icon.xml", + "revanced_settings_screen_00_about.xml", + "revanced_settings_screen_01_ads.xml", + "revanced_settings_screen_02_alt_thumbnails.xml", + "revanced_settings_screen_03_feed.xml", + "revanced_settings_screen_04_general.xml", + "revanced_settings_screen_05_player.xml", + "revanced_settings_screen_06_shorts.xml", + "revanced_settings_screen_07_seekbar.xml", + "revanced_settings_screen_08_swipe_controls.xml", + "revanced_settings_screen_09_ryd.xml", + "revanced_settings_screen_10_sb.xml", + "revanced_settings_screen_11_misc.xml", + "revanced_settings_screen_12_video.xml", + ), ResourceGroup("layout", "revanced_settings_with_toolbar.xml"), ).forEach { resourceGroup -> copyResources("settings", resourceGroup) @@ -159,6 +174,8 @@ val settingsPatch = bytecodePatch( // Add an "about" preference to the top. preferences += NonInteractivePreference( key = "revanced_settings_screen_00_about", + icon = "@drawable/revanced_settings_screen_00_about", + layout = "@layout/preference_with_icon", summaryKey = null, tag = "app.revanced.extension.youtube.settings.preference.ReVancedYouTubeAboutPreference", selectable = true, @@ -170,6 +187,10 @@ val settingsPatch = bytecodePatch( ) } + PreferenceScreen.GENERAL_LAYOUT.addPreferences( + SwitchPreference("revanced_show_menu_icons") + ) + PreferenceScreen.MISC.addPreferences( TextPreference( key = null, @@ -277,37 +298,53 @@ object PreferenceScreen : BasePreferenceScreen() { val ADS = Screen( key = "revanced_settings_screen_01_ads", summaryKey = null, + icon = "@drawable/revanced_settings_screen_01_ads", + layout = "@layout/preference_with_icon", ) val ALTERNATIVE_THUMBNAILS = Screen( key = "revanced_settings_screen_02_alt_thumbnails", summaryKey = null, + icon = "@drawable/revanced_settings_screen_02_alt_thumbnails", + layout = "@layout/preference_with_icon", sorting = Sorting.UNSORTED, ) val FEED = Screen( key = "revanced_settings_screen_03_feed", summaryKey = null, + icon = "@drawable/revanced_settings_screen_03_feed", + layout = "@layout/preference_with_icon", ) val GENERAL_LAYOUT = Screen( key = "revanced_settings_screen_04_general", summaryKey = null, + icon = "@drawable/revanced_settings_screen_04_general", + layout = "@layout/preference_with_icon", ) val PLAYER = Screen( key = "revanced_settings_screen_05_player", summaryKey = null, + icon = "@drawable/revanced_settings_screen_05_player", + layout = "@layout/preference_with_icon", ) val SHORTS = Screen( key = "revanced_settings_screen_06_shorts", summaryKey = null, + icon = "@drawable/revanced_settings_screen_06_shorts", + layout = "@layout/preference_with_icon", ) val SEEKBAR = Screen( key = "revanced_settings_screen_07_seekbar", summaryKey = null, - ) + icon = "@drawable/revanced_settings_screen_07_seekbar", + layout = "@layout/preference_with_icon", + ) val SWIPE_CONTROLS = Screen( key = "revanced_settings_screen_08_swipe_controls", summaryKey = null, + icon = "@drawable/revanced_settings_screen_08_swipe_controls", + layout = "@layout/preference_with_icon", sorting = Sorting.UNSORTED, ) @@ -317,10 +354,14 @@ object PreferenceScreen : BasePreferenceScreen() { val MISC = Screen( key = "revanced_settings_screen_11_misc", summaryKey = null, + icon = "@drawable/revanced_settings_screen_11_misc", + layout = "@layout/preference_with_icon", ) val VIDEO = Screen( key = "revanced_settings_screen_12_video", summaryKey = null, + icon = "@drawable/revanced_settings_screen_12_video", + layout = "@layout/preference_with_icon", sorting = Sorting.BY_KEY, ) diff --git a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index 16e4a298d..4d3826865 100644 --- a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -15,13 +15,185 @@ 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 -> { + when (registerCount) { + 1 -> listOf(registerC) + 2 -> listOf(registerC, registerD) + 3 -> listOf(registerC, registerD, registerE) + 4 -> listOf(registerC, registerD, registerE, registerF) + else -> 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.getWriteRegister() : Int { + // Two and three register instructions extend OneRegisterInstruction. + if (this is OneRegisterInstruction) return registerA + throw IllegalStateException("Not a write instruction: $this") + } + + val writeOpcodes = EnumSet.of( + ARRAY_LENGTH, + INSTANCE_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, + CONST, CONST_4, CONST_16, CONST_HIGH16, CONST_WIDE_16, CONST_WIDE_32, + CONST_WIDE, CONST_WIDE_HIGH16, CONST_STRING, CONST_STRING_JUMBO, + IGET, IGET_WIDE, IGET_OBJECT, IGET_BOOLEAN, IGET_BYTE, IGET_CHAR, IGET_SHORT, + IGET_VOLATILE, IGET_WIDE_VOLATILE, IGET_OBJECT_VOLATILE, + SGET, SGET_WIDE, SGET_OBJECT, SGET_BOOLEAN, SGET_BYTE, SGET_CHAR, SGET_SHORT, + SGET_VOLATILE, SGET_WIDE_VOLATILE, SGET_OBJECT_VOLATILE, + AGET, AGET_WIDE, AGET_OBJECT, AGET_BOOLEAN, AGET_BYTE, AGET_CHAR, AGET_SHORT, + // Arithmetic and logical operations. + ADD_DOUBLE_2ADDR, ADD_DOUBLE, ADD_FLOAT_2ADDR, ADD_FLOAT, ADD_INT_2ADDR, + ADD_INT_LIT8, ADD_INT, ADD_LONG_2ADDR, ADD_LONG, ADD_INT_LIT16, + AND_INT_2ADDR, AND_INT_LIT8, AND_INT_LIT16, AND_INT, AND_LONG_2ADDR, AND_LONG, + DIV_DOUBLE_2ADDR, DIV_DOUBLE, DIV_FLOAT_2ADDR, DIV_FLOAT, DIV_INT_2ADDR, + DIV_INT_LIT16, DIV_INT_LIT8, DIV_INT, DIV_LONG_2ADDR, DIV_LONG, + DOUBLE_TO_FLOAT, DOUBLE_TO_INT, DOUBLE_TO_LONG, + FLOAT_TO_DOUBLE, FLOAT_TO_INT, FLOAT_TO_LONG, + INT_TO_BYTE, INT_TO_CHAR, INT_TO_DOUBLE, INT_TO_FLOAT, INT_TO_LONG, INT_TO_SHORT, + LONG_TO_DOUBLE, LONG_TO_FLOAT, LONG_TO_INT, + MUL_DOUBLE_2ADDR, MUL_DOUBLE, MUL_FLOAT_2ADDR, MUL_FLOAT, MUL_INT_2ADDR, + MUL_INT_LIT16, MUL_INT_LIT8, MUL_INT, MUL_LONG_2ADDR, MUL_LONG, + NEG_DOUBLE, NEG_FLOAT, NEG_INT, NEG_LONG, + NOT_INT, NOT_LONG, + OR_INT_2ADDR, OR_INT_LIT16, OR_INT_LIT8, OR_INT, OR_LONG_2ADDR, OR_LONG, + REM_DOUBLE_2ADDR, REM_DOUBLE, REM_FLOAT_2ADDR, REM_FLOAT, REM_INT_2ADDR, + REM_INT_LIT16, REM_INT_LIT8, REM_INT, REM_LONG_2ADDR, REM_LONG, + RSUB_INT_LIT8, RSUB_INT, + SHL_INT_2ADDR, SHL_INT_LIT8, SHL_INT, SHL_LONG_2ADDR, SHL_LONG, + SHR_INT_2ADDR, SHR_INT_LIT8, SHR_INT, SHR_LONG_2ADDR, SHR_LONG, + SUB_DOUBLE_2ADDR, SUB_DOUBLE, SUB_FLOAT_2ADDR, SUB_FLOAT, SUB_INT_2ADDR, + SUB_INT, SUB_LONG_2ADDR, SUB_LONG, + USHR_INT_2ADDR, USHR_INT_LIT8, USHR_INT, USHR_LONG_2ADDR, USHR_LONG, + XOR_INT_2ADDR, XOR_INT_LIT16, XOR_INT_LIT8, XOR_INT, XOR_LONG_2ADDR, XOR_LONG, + ) + + 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, + PACKED_SWITCH_PAYLOAD, SPARSE_SWITCH_PAYLOAD + ) + + val returnOpcodes = EnumSet.of( + RETURN_VOID, RETURN, RETURN_WIDE, RETURN_OBJECT, RETURN_VOID_NO_BARRIER, + THROW + ) + + // 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) + val instructionRegisters = instruction.getRegistersUsed() + + if (instruction.opcode in returnOpcodes) { + // Method returns. + usedRegisters.addAll(instructionRegisters) + + // 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 writeRegister = instruction.getWriteRegister() + + if (writeRegister !in usedRegisters) { + // Verify the register is only used for write and not also as a parameter. + // If the instruction uses the write register once then it's not also a read register. + if (instructionRegisters.count { register -> register == writeRegister } == 1) { + if (writeRegister < maxRegister4Bits) { + // Found an ideal register. + return writeRegister + } + + // Continue searching for a 4-bit register if available. + if (bestFreeRegisterFound == null || writeRegister < bestFreeRegisterFound) { + bestFreeRegisterFound = writeRegister + } + } + } + } + + usedRegisters.addAll(instructionRegisters) + } + + // Some methods can have array payloads at the end of the method after a return statement. + // But in normal usage this cannot be reached since a branch or return statement + // will be encountered before the end of the method. + throw IllegalArgumentException("Start index is outside the range of normal control flow: $startIndex") +} + /** * Find the [MutableMethod] from a given [Method] in a [MutableClass]. @@ -395,7 +567,7 @@ fun Method.findInstructionIndicesReversedOrThrow(opcode: Opcode): List { 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(index).registerA val operation = if (register < 16) { @@ -423,7 +595,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) diff --git a/patches/src/main/resources/addresources/values-af-rZA/strings.xml b/patches/src/main/resources/addresources/values-af-rZA/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-af-rZA/strings.xml +++ b/patches/src/main/resources/addresources/values-af-rZA/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-am-rET/strings.xml b/patches/src/main/resources/addresources/values-am-rET/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-am-rET/strings.xml +++ b/patches/src/main/resources/addresources/values-am-rET/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-ar-rSA/strings.xml b/patches/src/main/resources/addresources/values-ar-rSA/strings.xml index 7e27d1a07..bb2fa159a 100644 --- a/patches/src/main/resources/addresources/values-ar-rSA/strings.xml +++ b/patches/src/main/resources/addresources/values-ar-rSA/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -22,7 +21,7 @@ Second \"item\" text" - فشلت عمليات التحقق + فشلت الفحوصات فتح الموقع الرسمي تجاهل <h5>لا يبدو أن هذا التطبيق قد تم تعديله من قبلك.</h5><br>قد لا يعمل هذا التطبيق بشكل صحيح، <b>قد يكون ضارًا أو حتى خطيرًا للاستخدام</b>.<br><br>تشير هذه الفحوصات إلى أن هذا التطبيق تم تعديله مسبقًا أو تم الحصول عليه من شخص آخر:<br><br><small>%1$s</small><br>يوصى بشدة بـ <b>إلغاء تثبيت هذا التطبيق وتعديله بنفسك</b> للتأكد من أنك تستخدم تطبيقًا معتمدًا وآمنًا.<p><br>في حالة تجاهل هذا التحذير، سيتم عرضه مرتين فقط. @@ -30,19 +29,22 @@ Second \"item\" text" لم يتم تثبيته بواسطة ReVanced Manager تم تعديله قبل أكثر من 10 دقائق تم التعديل منذ %s يوم - تاريخ إنشاء APK تالف + تاريخ بناء APK تالف الإعدادات هل ترغب في المتابعة؟ إعادة التعيين - تحديث وإعادة تشغيل + تحديث وإعادة التشغيل إعادة التشغيل استيراد نسخ إعادة تعيين إعدادات ReVanced إلى الوضع الافتراضي تم استيراد %d إعدادات فشل الاستيراد: %s + عرض أيقونات إعدادات ReVanced + يتم عرض أيقونات الإعدادات + لا يتم عرض أيقونات الإعدادات لغة ReVanced "قد تكون الترجمات لبعض اللغات مفقودة أو غير مكتملة. @@ -106,9 +108,9 @@ Second \"item\" text" سجل بروتوكول التخزين المؤقت تتضمن سجلات التصحيح التخزين المؤقت لا تتضمن سجلات التصحيح التخزين المؤقت - سجل عمليات التطبيق - تتضمن سجلات التصحيح سِجِل عمليات التطبيق - لا تتضمن سجلات التصحيح سِجِل عمليات التطبيق + سجل تتبع المكدس + تتضمن سجلات التصحيح سجل تتبع المكدس + لا تتضمن سجلات التصحيح سجل تتبع المكدس عرض ملاحظة عند وجود خطأ في ReVanced يتم عرض ملاحظة في حالة حدوث خطأ لا يتم عرض ملاحظة في حالة حدوث خطأ @@ -214,9 +216,9 @@ Second \"item\" text" إخفاء الفيديوهات ذات الصلة في الإجراءات السريعة تم إخفاء الفيديوهات ذات الصلة يتم عرض الفيديوهات ذات الصلة - إخفاء رفوف الصور في نتائج البحث - تم إخفاء رفوف الصورة - يتم عرض رفوف الصورة + إخفاء رف الصورة في نتائج البحث + تم إخفاء رف الصورة + يتم عرض رف الصورة إخفاء آخر المشاركات تم إخفاء أحدث المشاركات يتم عرض أحدث المشاركات @@ -226,7 +228,7 @@ Second \"item\" text" إخفاء بطاقات الفنان تم إخفاء بطاقات الفنان يتم عرض بطاقات الفنان - إخفاء \"ملخص الفيديو الذي تم إنشاؤه بواسطة الذكاء الاصطناعي\" + إخفاء \'ملخص الفيديو الذي تم إنشاؤه بواسطة الذكاء الاصطناعي\' تم إخفاء قسم ملخص الفيديو يتم عرض قسم ملخص الفيديو إخفاء الصفات @@ -253,31 +255,31 @@ Second \"item\" text" وصف الفيديو إخفاء أو عرض مكونات وصف الفيديو شريط التصفية - إخفاء أو إظهار شريط الفلتر في الخلاصة ونتائج البحث ومقاطع الفيديو ذات الصلة + إخفاء أو عرض شريط الفلتر في الموجز ونتائج البحث والفيديوهات ذات الصلة إخفاء في الموجز مخفي في الموجز - يعرض في الموجز + يُعرض في الموجز إخفاء في نتائج البحث مخفي في نتائج البحث - يظهر في نتائج البحث + يُعرض في نتائج البحث إخفاء في الفيديوهات ذات الصلة مخفي في الفيديوهات ذات الصلة - يعرض في الفيديوهات ذات الصلة + يُعرض في الفيديوهات ذات الصلة التعليقات إخفاء أو عرض مكونات قسم التعليقات - إخفاء ملخص دردشة الذكاء الاصطناعي + إخفاء ملخص محادثات الذكاء الاصطناعي تم إخفاء ملخص المحادثات يتم عرض ملخص المحادثات إخفاء ملخص تعليقات الذكاء الاصطناعي - ملخص التعليقات مخفي - ملخص التعليقات معروض + تم إخفاء ملخص التعليقات + يتم عرض ملخص التعليقات إخفاء رأس \'تعليقات الأعضاء\' تم إخفاء علامة تعليقات من الأعضاء يتم عرض علامة تعليقات من الأعضاء إخفاء قسم التعليقات تم إخفاء قسم التعليقات يتم عرض قسم التعليقات - إخفاء زر \'إنشاء مقطع Short\' + إخفاء زر \'إنشاء Short\' تم إخفاء زر إنشاء Short يتم عرض زر إنشاء Short إخفاء أزرار الرموز التعبيرية والطوابع الزمنية @@ -305,7 +307,7 @@ Second \"item\" text" قائمة سلاسل منشئ مسار المكونات المراد تصفيتها مفصولة بسطر جديد فلتر مخصص غير صالح: %s - إخفاء محتوى الكلمات الرئيسية + إخفاء محتوى الكلمات المفتاحية إخفاء فيديوهات البحث والموجز باستخدام فلاتر الكلمات المفتاحية إخفاء فيديوهات الصفحة الرئيسية بواسطة الكلمات المفتاحية تتم تصفية الفيديوهات في علامة التبويب \"الصفحة الرئيسية\" حسب الكلمات المفتاحية @@ -335,11 +337,11 @@ Second \"item\" text" سيؤدي وضع علامة اقتباس مزدوجة حول كلمة رئيسية/عبارة إلى منع التطابقات الجزئية لعناوين الفيديو وأسماء القنوات.<br><br>على سبيل المثال،<br><b>\"ai\"</b> سيخفي الفيديو: <b>How does AI work?</b><br>ولكن لن يخفي: <b>What does fair use mean?</b> - لا يمكن استخدام الكلمة الرئيسية: %s - إضافة اقتباسات لاستخدام الكلمة الرئيسية: %s - الكلمة الرئيسية لها بيانات متضاربة: %s - الكلمة الرئيسية قصيرة جدًا وتتطلب اقتباسات: %s - الكلمة الرئيسية سوف تخفي جميع الفيديوهات: %s + لا يمكن استخدام الكلمة المفتاحية: %s + إضافة اقتباسات لاستخدام الكلمة المفتاحية: %s + الكلمة المفتاحية لها بيانات متضاربة: %s + الكلمة المفتاحية قصيرة جدًا وتتطلب اقتباسات: %s + الكلمة المفتاحية سوف تخفي جميع الفيديوهات: %s إخفاء الإعلانات العامة @@ -359,20 +361,20 @@ Second \"item\" text" إخفاء بطاقات الرعاية الذاتية تم إخفاء بطاقات الرعاية الذاتية يتم عرض بطاقات الرعاية الذاتية - إخفاء لافتة \"عرض المنتجات\" + إخفاء لافتة \'عرض المنتجات\' تم إخفاء البانر يتم عرض البانر إخفاء لافتة شاشة المتجر النهائية تم إخفاء لافتة المتجر يتم عرض لافتة المتجر إخفاء رف مشغل التسوق - تم إخفاء رفوف التسوق - يتم عرض رفوف التسوق + تم إخفاء رف التسوق + يتم عرض رف التسوق إخفاء روابط التسوق في وصف الفيديو تم إخفاء روابط التسوق في وصف الفيديو يتم عرض روابط التسوق في وصف الفيديو - إخفاء زر \"زيارة المتجر\" على صفحات القناة + إخفاء زر \'زيارة المتجر\' على صفحات القناة تم إخفاء الزر في صفحة القناة يتم عرض الزر في صفحة القناة إخفاء نتائج بحث الويب @@ -387,7 +389,7 @@ Second \"item\" text" إخفاء ترقية YouTube Premium تم إخفاء عروض YouTube Premium الترويجية تحت مشغل الفيديو - يتم عرض عروض YouTube Premium الترويجية تحت مشغل الفيديو + يتم إظهار عروض YouTube Premium الترويجية تحت مشغل الفيديو إخفاء إعلانات الفيديو @@ -430,9 +432,9 @@ Second \"item\" text" تم تمكين الإيماءة - تمكين النقر للبحث - تم تمكين النقر للتنقل - تم تعطيل النقر للبحث + تمكين النقر للتمرير + تم تمكين النقر للتمرير + تم تعطيل النقر للتمرير التحكم بالسطوع عن طريق ايماءة التمرير @@ -610,6 +612,10 @@ Second \"item\" text" إخفاء المقطع الصوتي تم إخفاء قائمة المقطع الصوتي يتم عرض قائمة المقطع الصوتي + + "تم إخفاء قائمة المقطع الصوتي + +لعرض قائمة المقطع الصوتي، غيّر 'Spoof Video Streams' إلى iOS TV" إخفاء المشاهدة في VR تم إخفاء قائمة المشاهدة في الوضع الافتراضي @@ -667,17 +673,17 @@ Second \"item\" text" إخفاء Shorts في موجز الصفحة الرئيسية مخفية في الصفحة الرئيسية والفيديوهات ذات الصلة - تعرض في الصفحة الرئيسية والفيديوهات ذات الصلة + تُعرض في الصفحة الرئيسية والفيديوهات ذات الصلة إخفاء Shorts في موجز الاشتراكات مخفية في موجز الاشتراكات - تعرض في موجز الاشتراكات + تُعرض في موجز الاشتراكات إخفاء Shorts في نتائج البحث مخفية في نتائج البحث - تعرض في نتائج البحث + تُعرض في نتائج البحث إخفاء Shorts في سجل المشاهدة مخفية في سجل المشاهدة - تعرض في سجل المشاهدة + تُعرض في سجل المشاهدة إخفاء زر الانضمام تم إخفاء زر الانضمام @@ -766,7 +772,7 @@ Second \"item\" text" إخفاء الفيديو المقترح في شاشة النهاية - "يتم إخفاء الفيديو المقترح في شاشة النهاية عند إيقاف التشغيل التلقائي + "تم إخفاء الفيديو المقترح في شاشة النهاية عند إيقاف التشغيل التلقائي يمكن تغيير التشغيل التلقائي في إعدادات YouTube: الإعدادات ← التشغيل ← تشغيل الفيديو التالي تلقائيًا" @@ -864,7 +870,7 @@ Second \"item\" text" مصغرات شريط التقدم سوف تستخدم نفس جودة الفيديو الحالي. -تعمل هذه الميزة بشكل أفضل مع جودة فيديو 720p أو أقل وعند استخدام اتصال إنترنت سريع جداً." +تعمل هذه الميزة بشكل أفضل مع جودة فيديو 720p أو أقل وعند استخدام اتصال إنترنت سريع جدًا." استعادة مصغرات شريط التقدم القديمة مصغرات شريط التقدم ستظهر فوق شريط تقدم الفيديو مصغرات شريط التقدم ستظهر في ملء الشاشة @@ -937,15 +943,15 @@ Second \"item\" text" لا تعرض مرة أخرى تغيير سلوك المقطع الراعي - الترويج المدفوع الأجر، والإحالات المدفوعة الأجر والإعلانات المباشرة. ليس للترويج الذاتي أو لصراعات مجانية للقضايا/المبدعين/المواقع الإلكترونية/المنتجات التي يحبون الحصول عليها + الترويج المدفوع، والإحالات المدفوعة، والإعلانات المباشرة. ليس للترويج الذاتي أو الترويج المجاني للقضايا/المبدعين/المواقع الإلكترونية/المنتجات التي يفضلونها ترويج شخصي/غير مدفوع الأجر - مشابهة لـ \"الراعي\" باستثناء ما يتعلق بالإعلانات غير المدفوعة الأجر أو الذاتية. ويشمل ذلك أقسام عن السلع أو التبرعات أو المعلومات المتعلقة بمن تعاونوا مع ناشر المحتوى + مشابهة لـ \'الراعي\' باستثناء ما يتعلق بالإعلانات غير المدفوعة الأجر أو الذاتية. ويشمل ذلك أقسام عن السلع أو التبرعات أو المعلومات المتعلقة بمن تعاونوا مع ناشر المحتوى تذكير بالتفاعل (اشتراك) تذكير قصير للإعجاب أو الاشتراك أو المتابعة في منتصف المحتوى. إذا كانت طويلة أو تتعلق بشيء محدد، فيجب أن تكون خاضعة للترويج الشخصي بدلاً من ذلك الأبرز الجزء من الفيديو الذي يبحث عنه معظم الناس المقدمة/فاصل - فاصل زمني بدون محتوى فعلي. يمكن أن يكون وقفاً مؤقتاً، أو إطارًا ثابتاً، أو تكرارًا. لا يتضمن التحولات التي تحتوي على معلومات + فاصل زمني بدون محتوى فعلي. قد يكون توقفًا مؤقتًا، أو إطارًا ثابتًا، أو رسومًا متحركة متكررة. لا يتضمن انتقالات تحتوي على معلومات الخاتمة/تترات النهاية تتر النهاية أو عندما تظهر بطاقات نهاية YouTube، نهايات غير منطوقة. ليس للاستنتاجات مع المعلومات معاينة/موجز/ربط @@ -1079,9 +1085,9 @@ Second \"item\" text" تصميم الجهاز اللوحي • مشاركات المجتمع مخفية -تصميم السيارة +تصميم Automotive • يتم فتح Shorts في المشغل العادي -• يتم تنظيم الخلاصة حسب المواضيع والقنوات" +• يتم تنظيم الموجز حسب المواضيع والقنوات" خِداع إصدار التطبيق @@ -1155,7 +1161,7 @@ Second \"item\" text" حديث 1 حديث 2 حديث 3 - الوضع الحديث 4 + حديث 4 تمكين الزوايا المستديرة الزوايا مستديرة الزوايا مربعة @@ -1175,14 +1181,14 @@ Second \"item\" text" يمكن سحب المشغل المصغر خارج الشاشة إلى اليسار أو اليمين" تم تعطيل إيماءة السحب الأفقية - إخفاء أزرار التراكب - أزرار التراكب مخفية - أزرار التراكب ظاهرة + إخفاء أزرار الواجهة + تم إخفاء أزرار الواجهة + يتم عرض أزرار الواجهة إخفاء زري التوسيع والإغلاق - "الأزرار مخفية + "تم إخفاء الأزرار اسحب للتوسيع أو الإغلاق" - زرا التوسيع والإغلاق ظاهران + يتم عرض زري التوسيع والإغلاق إخفاء النصوص الفرعية تم إخفاء النصوص الفرعية يتم عرض النصوص الفرعية @@ -1218,7 +1224,7 @@ Second \"item\" text" - علامة تبويب الصفحة الرئيسية + علامة التبويب الصفحة الرئيسية علامة التبويب الاشتراكات @@ -1229,11 +1235,11 @@ Second \"item\" text" DeArrow & المصّغرات الأصلية DeArrow & اللقطات الثابتة اللقطات الثابتة - "يوفر DeArrow مصغرات فيديو من مصادر جماعية لفيديوهات YouTube. هذه المصغرات غالبا ما تكون أكثر صلة من تلك المقدمة من YouTube + "يوفر DeArrow مصغرات فيديو من مصادر جماعية لفيديوهات YouTube. هذه المصغرات غالبًا ما تكون أكثر صلة من تلك المقدمة من YouTube -إذا تم تفعيلها، سيتم إرسال روابط الفيديو إلى خادم API ولن يتم إرسال أي بيانات أخرى. إذا كان الفيديو لا يحتوي على مصغرات DArrow، سيتم عرض المقاطع الأصلية أو اللقطات الثابتة +إذا تم تفعيلها، سيتم إرسال روابط الفيديو إلى خادم API ولن يتم إرسال أي بيانات أخرى. إذا كان الفيديو لا يحتوي على مصغرات DeArrow، سيتم عرض المقاطع الأصلية أو اللقطات الثابتة -اضغط هنا لمعرفة المزيد عن DArrow" +اضغط هنا لمعرفة المزيد عن DeArrow" عرض ملاحظة إذا كان API غير متاح يتم عرض ملاحظة إذا كان DeArrow غير متوفر لا يتم عرض ملاحظة إذا كان DeArrow غير متوفر @@ -1309,7 +1315,7 @@ Second \"item\" text" استخدام لغة الصوت الأصلية استخدام الصوت الافتراضي - لاستخدام هذه الميزة، غيّر \"انتحال دفقات الفيديو\" إلى iOS TV + لاستخدام هذه الميزة، غيّر \'Spoof Video Streams\' إلى iOS TV @@ -1323,7 +1329,7 @@ Second \"item\" text" تنطبق تغييرات الجودة على جميع فيديوهات Shorts تنطبق تغييرات الجودة فقط على فيديو Short الحالي جودة Shorts الافتراضية على شبكة Wi-Fi - جودة Shorts الافتراضية على شبكة الجوال + جودة Shorts الافتراضية على شبكة الجوّال الجوّال Wi-Fi تم تغيير جودة %1$s الافتراضية إلى: %2$s @@ -1359,7 +1365,7 @@ Second \"item\" text" تم تمكين فيديو HDR - إظهار قائمة جودة الفيديو المتقدمة + عرض قائمة جودة الفيديو المتقدمة يتم عرض قائمة جودة الفيديو المتقدمة لا يتم عرض قائمة جودة الفيديو المتقدمة @@ -1393,7 +1399,7 @@ AVC لديه حد أقصى للدقة 1080p، لا يتوفر ترميز الص • مستوى الصوت الثابت غير متاح • فرض الصوت الأصلي غير متوفر" • لا يوجد ترميز الفيديو AV1 - • الفيديوات العربية لا يمكن تشغيل أو في وضع التشغيل أو في حالة الخفية + • قد لا يتم تشغيل الفيديوهات المخصصة للأطفال عند تسجيل الخروج أو عند استخدام وضع التصفح المتخفي عرض في إحصاءات تقنية يتم عرض نوع العميل في إحصاءات تقنية تم إخفاء نوع العميل في إحصاءات تقنية diff --git a/patches/src/main/resources/addresources/values-as-rIN/strings.xml b/patches/src/main/resources/addresources/values-as-rIN/strings.xml index bfb5422fc..d0d71ccc6 100644 --- a/patches/src/main/resources/addresources/values-as-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-as-rIN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-az-rAZ/strings.xml b/patches/src/main/resources/addresources/values-az-rAZ/strings.xml index 2aeee9144..8d8a12965 100644 --- a/patches/src/main/resources/addresources/values-az-rAZ/strings.xml +++ b/patches/src/main/resources/addresources/values-az-rAZ/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced tənzimləmələr standarta təyin edildi %d tənzimləmə idxal edildi Uğursuz idxal prosesi: %s + ReVanced tənzimləmə nişanların göstər + Tənzimləmə nişanları göstərilir + Tənzimləmə nişanları göstərilmir ReVanced dili "Bəzi dillər üçün tərcümələr əskik və ya səhv ola bilər. @@ -226,6 +228,9 @@ Gözlənilməz hallardan xəbərdar olmayacaqsınız." Sənətçi kartlarını gizlət Sənətçi kartları gizlidir Sənətçi kartları göstərilir + \"AI ilə yaradılan video xülasəsini\" gizlət + Video xülasə bölməsi gizlədilib + Video xülasə bölməsi göstərilir Atributları Gizlət Seçilən yerlər, Oyunlar, Musiqi və qeyd edilən insanlar bölmələri gizlədilir Seçilən yerlər, Oyunlar, Musiqi və qeyd edilən insanlar bölmələri görünür @@ -262,8 +267,12 @@ Gözlənilməz hallardan xəbərdar olmayacaqsınız." Əlaqəli videolarda görünür Şərhlər Şərhlər bölməsi elementlərin gizlət və ya göstər + AI Söhbət Xülasəsini Gizlət Söhbət yekunu gizlidir Söhbət yekunu görünür + AI Ṣərhlər Xülasəsini Gizlət + Ṣərh yekunu gizlidir + Şərh yekunu görünür \'Üzvlərin şərhləri\' başlığını gizlət Üzvlərin şərhləri başlığı gizlidir Üzvlərin şərhləri başlığı görünür @@ -423,6 +432,9 @@ Bu xüsusiyyət yalnız köhnə cihazlar üçün mövcuddur" Jest aktivləşdirilib + Axtarmaq üçün toxun\'u aktivləşdir + Axtarmaq üçün toxun, aktivdir + Axtarmaq üçün toxun qapalıdır Parlaqlıq jestini aktivləşdir @@ -435,6 +447,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ə" Tam ekran səs sürüşdürməsi qapalıdır + Sürüşdürmə jesti üçün sıxmanı aktiv et + Sürüşdürmə üçün sıxma aktivdir + Sürüşdürmə üçün sıxma qapalıdır Əks-əlaqə reaksiyasını aktivləşdir Əks-əlaqə reaksiyası aktivləşdirilib Əks-əlaqə reaksiyası qeyri-aktivdir @@ -542,6 +557,7 @@ Bu seçimi dəyişdirmə işə düşmürsə, Gizli rejimə keçməyə çalışı Yarımşəffaf mövqe cizgisin qapat Mövqe cizgisi qeyri-şəffafdır Mövqe cizgisi qeyri-şəffaf və ya şəffafdır + Bəzi cihazlarda bu xüsusiyyət aktivləşməsi sistem fəaliyyət cərgəsini şəffaf-a dəyişə bilər. Açıq temada şəffaf cizgini qapat İşıqlı rejim fəaliyyət cərgəsi qeyri-şəffafdır İşıqlı rejim fəaliyyət cərgəsi qeyri-şəffaf və ya şəffafdır @@ -596,6 +612,7 @@ Bu seçimi dəyişdirmə işə düşmürsə, Gizli rejimə keçməyə çalışı Səs trekini gizlət Səs axını menyusu gizlidir Səs axını menyusu göstərilir + \"VR-da İzləni\" gizlət VR menyusunda izləmə gizlidir @@ -1140,6 +1157,7 @@ Sonradan qapadılarsa, UI səhvlərin önləmək üçün tətbiq məlumatların Müasir 1 Müasir 2 Müasir 3 + Müasir 4 Dairəvi küncləri aktivləşdir Künclər dairəvidir Künclər kvadratdır @@ -1159,6 +1177,14 @@ Kiçik oynadıcı ekranın istənilən küncünə sürüklənə bilər" Kiçik oynadıcı ekrandan sola və ya sağa sürüklənə bilər" Üfüqi sürükləmə jesti qapatıldı + Örtük düymələrini gizlət + Örtük düymələri gizlidir + Örtük düymələri görünür + Genişləndir və bağla düymələrini gizlət + "Düymələr gizlidir + +Genişləndirmək və ya bağlamaq üçün sürüşdür" + Genişləndir və bağla düymələri göstərilir Alt mətnləri gizlət Alt mətnlər gizlədilir Alt mətnlər göstərilir diff --git a/patches/src/main/resources/addresources/values-be-rBY/strings.xml b/patches/src/main/resources/addresources/values-be-rBY/strings.xml index 85f0645fb..534e61a90 100644 --- a/patches/src/main/resources/addresources/values-be-rBY/strings.xml +++ b/patches/src/main/resources/addresources/values-be-rBY/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Налады ReVanced скінуты да стандартных Імпартавана %d налад Памылка імпарту: %s + Паказваць значкі налад ReVanced + Значкі налад паказваюцца + Значкі налад не паказваюцца Мова ReVanced "Пераклады для некаторых моў могуць быць адсутнымі або няпоўнымі. @@ -610,6 +612,10 @@ Second \"item\" text" Схаваць гукавую дарожку Меню гукавой дарожкі схавана Адлюструецца меню гукавой дарожкі + + "Меню аўдыядарожкі схавана + +Каб паказаць меню аўдыядарожкі, змяніце \"Падробка відэаструменяў\" на iOS TV" Схаваць гадзіннік у VR Меню прагляду ў VR схавана diff --git a/patches/src/main/resources/addresources/values-bg-rBG/strings.xml b/patches/src/main/resources/addresources/values-bg-rBG/strings.xml index ef2e19571..c4612ed0d 100644 --- a/patches/src/main/resources/addresources/values-bg-rBG/strings.xml +++ b/patches/src/main/resources/addresources/values-bg-rBG/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Настройките на ReVanced бяха нулирани Следните настройки бяха импортирани успешно: %d Импортирането беше неуспешно: %s + Показване на иконите на настройките на ReVanced + Иконите на настройките се показват + Иконите на настройките не се показват Език на ReVanced "Преводите на някои езици може да липсват или да са непълни. @@ -610,6 +612,10 @@ Second \"item\" text" Избор на Аудио Менюто за избор на Аудио е скрито Менюто за избор на Аудио се показва + + "Менюто за аудио тракове е скрито + +За да покажете менюто за аудио тракове, променете \"Подмяна на видео потоци\" на iOS TV" Гледайте във VR Менюто за гледане в VR е скрито diff --git a/patches/src/main/resources/addresources/values-bn-rBD/strings.xml b/patches/src/main/resources/addresources/values-bn-rBD/strings.xml index 7441d9f9e..c1f5c0ada 100644 --- a/patches/src/main/resources/addresources/values-bn-rBD/strings.xml +++ b/patches/src/main/resources/addresources/values-bn-rBD/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced সেটিং ডিফল্ট সেট করা হয়েছে %d সেটিং আমদানি হয়েছে আমদানি করা যায়নি: %s + ReVanced সেটিং আইকন দেখান + সেটিং আইকন দেখানো হয়েছে + সেটিং আইকন দেখানো হচ্ছে না ReVanced ভাষা "কিছু ভাষার জন্য অনুবাদ অনুপস্থিত বা অসম্পূর্ণ হতে পারে। @@ -610,6 +612,10 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ অডিও ট্র্যাক লুকান অডিও ট্র্যাক মেনু লুকানো আছে অডিও ট্র্যাক মেনু দেখানো হয় + + "অডিও ট্র্যাক মেনু লুকানো আছে + +অডিও ট্র্যাক মেনু দেখাতে, 'স্পুফ ভিডিও স্ট্রিম' পরিবর্তন করে iOS TV করুন" ভিআর-এ ঘড়ি লুকান ভিআর মেনুতে দেখুন লুকানো আছে diff --git a/patches/src/main/resources/addresources/values-bs-rBA/strings.xml b/patches/src/main/resources/addresources/values-bs-rBA/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-bs-rBA/strings.xml +++ b/patches/src/main/resources/addresources/values-bs-rBA/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-ca-rES/strings.xml b/patches/src/main/resources/addresources/values-ca-rES/strings.xml index 7ec2d035b..c4424b0af 100644 --- a/patches/src/main/resources/addresources/values-ca-rES/strings.xml +++ b/patches/src/main/resources/addresources/values-ca-rES/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" La configuració de ReVanced s\'ha restablert als valors predeterminats S\'han importat %d configuracions No s\'ha pogut importar: %s + Mostra les icones de configuració de ReVanced + Es mostren les icones de configuració + No es mostren les icones de configuració Llenguatge de ReVanced "Les traduccions per a algunes llengües poden faltar o ser incompletes. @@ -610,6 +612,10 @@ Si canviar aquesta opció no té cap efecte, prova a canviar al mode d'incògnit Amaga la pista d\'àudio El menú de la pista d\'àudio s\'amaga Es mostra el menú de la pista d\'àudio + + "El menú de la pista d'àudio està amagat + +Per mostrar el menú de la pista d'àudio, canvieu \"Suplanta els fluxos de vídeo\" a iOS TV" Amaga Mira en VR El menú Mira en VR s\'amaga diff --git a/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml b/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml index 8d1ed3833..db85ae868 100644 --- a/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml +++ b/patches/src/main/resources/addresources/values-cs-rCZ/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Nastavení ReVanced obnoveno do výchozího stavu Importováno %d nastavení Importováni selhalo: %s + Zobrazit ikony nastavení ReVanced + Ikony nastavení se zobrazují + Ikony nastavení se nezobrazují Jazyk ReVanced "Překlady pro některé jazyky mohou chybět nebo být neúplné. @@ -610,6 +612,10 @@ Pokud změna tohoto nastavení nemá žádný účinek, zkuste přepnout do rež Skrýt Zvuková stopa Menu Zvuková stopa je skryto Menu Zvuková stopa je zobrazeno + + "Nabídka zvukové stopy je skrytá. + +Chcete-li zobrazit nabídku zvukové stopy, změňte možnost „Zfalšovat streamy videa“ na iOS TV" Skrýt Sledovat ve VR Menu Sledovat ve VR je skryto diff --git a/patches/src/main/resources/addresources/values-da-rDK/strings.xml b/patches/src/main/resources/addresources/values-da-rDK/strings.xml index 970685280..ba473455e 100644 --- a/patches/src/main/resources/addresources/values-da-rDK/strings.xml +++ b/patches/src/main/resources/addresources/values-da-rDK/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced-indstillinger nulstillet til standard %d indstillinger importeret Import mislykkedes: %s + Vis ReVanced-indstillingsikoner + Indstillingsikoner vises + Indstillingsikoner vises ikke ReVanced-sprog "Oversættelser for nogle sprog mangler muligvis eller er ufuldstændige. @@ -573,6 +575,10 @@ Hvis ændring af denne indstilling ikke træder i kraft, kan du prøve at skifte Skjul lydspor Menuen for lydspor er skjult Menuen Lydspor vises + + "Lydspormenuen er skjult + +For at vise lydspormenuen skal du ændre \"Spoof videostream\" til iOS TV" Skjul vagt i VR Se i VR-menuen er skjult diff --git a/patches/src/main/resources/addresources/values-de-rDE/strings.xml b/patches/src/main/resources/addresources/values-de-rDE/strings.xml index 9382d2484..0f463c51a 100644 --- a/patches/src/main/resources/addresources/values-de-rDE/strings.xml +++ b/patches/src/main/resources/addresources/values-de-rDE/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced-Einstellungen auf Standardwerte zurückgesetzt %d Einstellungen importiert Import fehlgeschlagen: %s + ReVanced-Einstellungssymbole anzeigen + Einstellungssymbole werden angezeigt + Einstellungssymbole werden nicht angezeigt ReVanced-Sprache "Übersetzungen für einige Sprachen fehlen möglicherweise oder sind unvollständig. @@ -603,6 +605,10 @@ Wenn diese Änderung nicht wirksam wird, versuchen Sie, in den Inkognito-Modus z Audiospur ausblenden Audiospur-Menü ist ausgeblendet Audiospurmenü wird angezeigt + + "Das Audiotrack-Menü ist ausgeblendet. + +Um das Audiotrack-Menü anzuzeigen, ändere \"Video-Streams fälschen\" zu iOS TV" Überwachung in VR ausblenden Im VR-Menü beobachten ist ausgeblendet diff --git a/patches/src/main/resources/addresources/values-el-rGR/strings.xml b/patches/src/main/resources/addresources/values-el-rGR/strings.xml index bc343772b..a7c50c4a0 100644 --- a/patches/src/main/resources/addresources/values-el-rGR/strings.xml +++ b/patches/src/main/resources/addresources/values-el-rGR/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Επαναφέρθηκαν οι προεπιλεγμένες ρυθμίσεις ReVanced Έγινε εισαγωγή %d ρυθμίσεων Η εισαγωγή απέτυχε: %s + Εμφάνιση εικονιδίων στις ρυθμίσεις ReVanced + Τα εικονίδια ρυθμίσεων εμφανίζονται + Τα εικονίδια ρυθμίσεων δεν εμφανίζονται Γλώσσα ρυθμίσεων ReVanced "Οι μεταφράσεις για κάποιες γλώσσες ενδέχεται να λείπουν ή να είναι ελλιπείς. @@ -612,6 +614,10 @@ Second \"item\" text" Μενού «Κομμάτι ήχου» Κρυμμένο Εμφανίζεται + + "Το μενού «Κομμάτι ήχου» είναι κρυμμένο + +Για να εμφανίζεται το μενού κομματιού ήχου, αλλάξτε την «Παραποίηση ροών βίντεο» σε iOS TV" Μενού «Προβολή σε VR» Κρυμμένο @@ -1180,10 +1186,10 @@ Second \"item\" text" Κρυμμένα Εμφανίζονται Κουμπιά επέκτασης και κλεισίματος - "Τα κουμπιά δεν εμφανίζονται + "Κρυμμένα Σύρετε για να αναπτύξετε ή να κλείσετε" - Τα κουμπιά εμφανίζονται + Εμφανίζονται Κείμενα οθόνης αναπαραγωγής Κρυμμένα Εμφανίζονται diff --git a/patches/src/main/resources/addresources/values-es-rES/strings.xml b/patches/src/main/resources/addresources/values-es-rES/strings.xml index 3c6fd9195..7cab7ecc8 100644 --- a/patches/src/main/resources/addresources/values-es-rES/strings.xml +++ b/patches/src/main/resources/addresources/values-es-rES/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Configuración ReVanced restablecida por defecto Configuración importada de %d Error de importación: %s + Mostrar iconos de configuración de ReVanced + Se muestran los iconos de configuración + No se muestran los iconos de configuración Idioma de ReVanced "Las traducciones para algunos idiomas pueden faltar o estar incompletas. @@ -607,6 +609,10 @@ Si cambiar este ajuste no tiene efecto, intenta cambiar al modo incógnito."Ocultar pista de audio El menú de pista de audio está oculto El menú de pista de audio se muestra + + "El menú de la pista de audio está oculto. + +Para mostrar el menú de la pista de audio, cambia \"Suplantar transmisiones de video\" a iOS TV" Ocultar reloj en VR Ver en el menú VR está oculto @@ -699,7 +705,7 @@ Si cambiar este ajuste no tiene efecto, intenta cambiar al modo incógnito."Etiqueta de ubicación oculta Etiqueta de ubicación mostrada Ocultar el botón Guardar música - Guardar botón de música está oculto + El botón Guardar música está oculto Mostrar el botón de guardar música Ocultar el botón Usar plantilla Botón de plantilla de uso está oculto diff --git a/patches/src/main/resources/addresources/values-et-rEE/strings.xml b/patches/src/main/resources/addresources/values-et-rEE/strings.xml index cd076e3db..4ea3261bd 100644 --- a/patches/src/main/resources/addresources/values-et-rEE/strings.xml +++ b/patches/src/main/resources/addresources/values-et-rEE/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVancedi seaded on lähtestatud Imporditi %d seadet Importimine ebaõnnestus: %s + Näita ReVancedi seadete ikoone + Seadete ikoonid on näidatud + Seadete ikoonid ei ole nähtavad Revancedi keel "Mõnede keelte tõlked võivad olla puudulikud või ebatäielikud. @@ -610,6 +612,10 @@ Kui selle sätte muutmine ei avalda mõju, proovige lülituda Inkognito režiimi Peida Helitraek Helitraekide menüü on peidetud Helitraekide menüü on nähtav + + "Heliriba menüü on peidetud + +Heliriba menüü kuvamiseks muutke valikut „Võltsitud videovoogedastus“ väärtuseks iOS TV" Peida Vaata VR-is Vaata VR-is menüü on peidetud diff --git a/patches/src/main/resources/addresources/values-eu-rES/strings.xml b/patches/src/main/resources/addresources/values-eu-rES/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-eu-rES/strings.xml +++ b/patches/src/main/resources/addresources/values-eu-rES/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-fa-rIR/strings.xml b/patches/src/main/resources/addresources/values-fa-rIR/strings.xml index 8e7160053..b60e7ac04 100644 --- a/patches/src/main/resources/addresources/values-fa-rIR/strings.xml +++ b/patches/src/main/resources/addresources/values-fa-rIR/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -127,6 +126,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-fi-rFI/strings.xml b/patches/src/main/resources/addresources/values-fi-rFI/strings.xml index 27289064e..8466c1645 100644 --- a/patches/src/main/resources/addresources/values-fi-rFI/strings.xml +++ b/patches/src/main/resources/addresources/values-fi-rFI/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Revanced-asetukset nollattiin %d asetusta tuotiin Tuonti epäonnistui: %s + Näytä ReVanced-asetuskuvakkeet + Asetuskuvakkeet näytetään + Asetuskuvakkeita ei näytetä ReVancedin kieli "Joidenkin kielten käännökset saattavat puuttua tai olla puutteellisia. @@ -226,6 +228,9 @@ Et saa ilmoituksia odottamattomista tapahtumista." Piilota artistikortit Artistikortit on piilotettu Artistikortit näytetään + Piilota \"tekoälyn luoma videoyhteenveto\" + Videon yhteenveto-osio on piilotettu + Videon yhteenveto-osio näytetään Piilota Määritteet Esitellyt paikat, Pelit, Musiikki ja Mainitut ihmiset -osiot on piilotettu Esitellyt paikat, Pelit, Musiikki ja Mainitut ihmiset -osiot näytetään @@ -262,8 +267,12 @@ Et saa ilmoituksia odottamattomista tapahtumista." Näytetään liittyvissä videoissa Kommentit Piilota tai näytä kommenttiosion osia + Piilota tekoälyn luoma chat-yhteenveto Chat-yhteenveto on piilotettu Chat-yhteenveto näytetään + Piilota tekoälyn luoma kommenttiyhteenveto + Kommenttien yhteenveto on piilotettu + Kommenttien yhteenveto näytetään Piilota \"Jäsenten kommentit\" -ylätunniste Jäsenten kommentit -ylätunniste on piilotettu Jäsenten kommentit -ylätunniste näytetään @@ -423,6 +432,9 @@ Tämä ominaisuus on käytettävissä vain vanhemmilla laitteilla" Ele on käytössä + Ota kelaus napauttamalla käyttöön + Kelaus napauttamalla on käytössä + Kelaus napauttamalla ei ole käytössä Ota kirkkauden ele käyttöön @@ -435,6 +447,9 @@ Säädä kirkkautta pyyhkäisemällä pystysuoraan näytön vasemmalla puolella" Säädä äänenvoimakkuutta pyyhkäisemällä pystysuoraan näytön oikealta puolella" Koko näytön äänenvoimakkuuden pyyhkäisy ei ole käytössä + Ota pyyhkäise painamalla -ele käyttöön + Pyyhkäise painamalla -ele on käytössä + Pyyhkäise painamalla -ele ei ole käytössä Ota haptinen palaute käyttöön Haptinen palaute on käytössä Haptinen palaute ei ole käytössä @@ -542,6 +557,7 @@ Jos tämän asetuksen muuttaminen ei tule voimaan, kokeile vaihtaa Incognito-til Poista läpikuultava tilapalkki käytöstä Tilapalkki on läpinäkymätön Tilapalkki on läpinäkymätön tai läpikuultava + Joillakin laitteilla tämän ominaisuuden käyttöönotto voi muuttaa järjestelmän navigointipalkin läpinäkyväksi. Poista vaalea läpikuultava palkki käytöstä Vaalean tilan navigointipalkki on läpinäkymätön Vaalean tilan navigointipalkki on läpinäkymätön tai läpikuultava @@ -596,6 +612,7 @@ Jos tämän asetuksen muuttaminen ei tule voimaan, kokeile vaihtaa Incognito-til Piilota Ääniraita Ääniraitavalikko on piilotettu Ääniraitavalikko näytetään + Piilota Katso VR-tilassa Katso VR-tilassa -valinta on piilotettu @@ -1161,6 +1178,9 @@ Minisoitin voidaan vetää mihin tahansa näytön kulmaan" Minisoitin voidaan vetää pois näytöltä vasemmalle tai oikealle" Vaakasuuntainen vetoele ei ole käytössä + Piilota peittokuvan painikkeet + Peittokuvan painikkeet on piilotettu + Peittokuvan painikkeet näytetään Piilota laajenna- ja sulje-painikkeet "Painikkeet piilotetaan diff --git a/patches/src/main/resources/addresources/values-fil-rPH/strings.xml b/patches/src/main/resources/addresources/values-fil-rPH/strings.xml index ecdb5326a..aacfc28c8 100644 --- a/patches/src/main/resources/addresources/values-fil-rPH/strings.xml +++ b/patches/src/main/resources/addresources/values-fil-rPH/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" I-reset ang mga ReVanced na setting sa default Na-import ang %d na mga setting Nabigo ang pag-import: %s + Ipakita ang mga icon ng setting ng ReVanced + Ipinapakita ang mga icon ng setting + Hindi ipinapakita ang mga icon ng setting Wika ng ReVanced "Ang mga pagsasalin para sa ilang mga wika ay maaaring nawawala o hindi kumpleto. @@ -608,6 +610,10 @@ Tandaan: Ang pagpapagana nito ay nagtatago rin ng mga ad ng video" Itago ang Audio track Nakatago ang menu ng audio track Ipinapakita ang menu ng audio track + + "Nakatago ang menu ng audio track + +Upang ipakita ang menu ng Audio track, baguhin ang 'Spoof video streams' sa iOS TV" Itago ang Panoorin sa VR Nakatago ang panonood sa VR menu diff --git a/patches/src/main/resources/addresources/values-fr-rFR/strings.xml b/patches/src/main/resources/addresources/values-fr-rFR/strings.xml index 82689ba73..5fee9f945 100644 --- a/patches/src/main/resources/addresources/values-fr-rFR/strings.xml +++ b/patches/src/main/resources/addresources/values-fr-rFR/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Paramètres ReVanced réinitialisés aux valeurs par défaut %d paramètres importés Importation échouée : %s + Afficher les icônes des paramètres ReVanced + Les icônes des paramètres sont affichées + Les icônes des paramètres ne sont pas affichées Langue de ReVanced "Il se peut que les traductions dans certaines langues soient manquantes ou incomplètes. @@ -610,6 +612,10 @@ Si la modification de ce paramètre ne prend pas effet, essayez de passer en mod Masquer \"Piste audio\" Le menu Piste audio est masqué Le menu Piste audio est affiché + + "Le menu Piste audio est masqué + +Pour afficher le menu Piste audio, définissez \"Falsifier les flux vidéo\" sur iOS TV" Masquer \"Regarder en RV\" Le menu Regarder en RV est masqué @@ -1174,13 +1180,13 @@ Le lecteur réduit peut être déplacé vers n'importe quel coin de l'écran" Geste de déplacement horizontal désactivé - Masquer les boutons de superposition - Les boutons de superposition sont masqués - Les boutons de superposition sont affichés + Masquer les boutons en superposition + Les boutons en superposition sont masqués + Les boutons en superposition sont affichés Masquer les boutons Agrandir et Fermer "Les boutons sont masqués -Balayez pour développer ou fermer" +Balayez pour agrandir ou fermer" Les boutons Agrandir et Fermer sont affichés Masquer les sous-textes Les sous-textes sont masqués diff --git a/patches/src/main/resources/addresources/values-ga-rIE/strings.xml b/patches/src/main/resources/addresources/values-ga-rIE/strings.xml index 1c2cf502e..f1f4f2c59 100644 --- a/patches/src/main/resources/addresources/values-ga-rIE/strings.xml +++ b/patches/src/main/resources/addresources/values-ga-rIE/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Athshocraigh socruithe ReVanced go réamhshocrú Iompórtáladh %d socruithe Theip ar allmhairiú: %s + Taispeáin deilbhíní socruithe ReVanced + Taispeántar deilbhíní socruithe + Ní thaispeántar deilbhíní socraithe Teanga ReVanced "D'fhéadfadh aistriúcháin do roinnt teangacha a bheith ar iarraidh nó mí-iomlán. @@ -610,6 +612,10 @@ Mura dtagann aon athrú ar an socrú seo, bain triail as mód Incognito a chur a Folaigh Rian Fuaime Tá roghchlár rian fuaime i bhfolach Taispeántar roghchlár rian fuaime + + "Tá roghchlár na rian fuaime i bhfolach + +Chun roghchlár na rian fuaime a thaispeáint, athraigh 'Srutháin físeáin bhréige' go iOS TV" Folaigh Watch i VR Tá faire i roghchlár VR i bhfolach diff --git a/patches/src/main/resources/addresources/values-gl-rES/strings.xml b/patches/src/main/resources/addresources/values-gl-rES/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-gl-rES/strings.xml +++ b/patches/src/main/resources/addresources/values-gl-rES/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-gu-rIN/strings.xml b/patches/src/main/resources/addresources/values-gu-rIN/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-gu-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-gu-rIN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-hi-rIN/strings.xml b/patches/src/main/resources/addresources/values-hi-rIN/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-hi-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-hi-rIN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-hr-rHR/strings.xml b/patches/src/main/resources/addresources/values-hr-rHR/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-hr-rHR/strings.xml +++ b/patches/src/main/resources/addresources/values-hr-rHR/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-hu-rHU/strings.xml b/patches/src/main/resources/addresources/values-hu-rHU/strings.xml index f5b24ff4c..f1576bf95 100644 --- a/patches/src/main/resources/addresources/values-hu-rHU/strings.xml +++ b/patches/src/main/resources/addresources/values-hu-rHU/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" A ReVanced beállítások visszaállnak az alapértelmezettre %d beállítás importálva Sikertelen importálás: %s + ReVanced beállításikonok megjelenítése + A beállításikonok láthatók + A beállítások ikonjai nem jelennek meg ReVanced nyelve "A fordítások hiányozhatnak vagy hiányosak lehetnek néhány nyelven. @@ -610,6 +612,10 @@ Ha a beállítás módosítása nem lép életbe, próbáljon meg Inkognitó mó Hangsáv elrejtése A hangsáv menü el van rejtve A hangsáv menü megjelenik + + "Az audiosáv menü rejtett + +Az audiosáv menü megjelenítéséhez módosítsa a \"Videófolyamok hamisítása\" beállítást iOS TV-re" \"Megtekintés VR-módban\" elrejtése A megtekintés VR-módban menü el van rejtve diff --git a/patches/src/main/resources/addresources/values-hy-rAM/strings.xml b/patches/src/main/resources/addresources/values-hy-rAM/strings.xml index b6331f7fa..db77b233a 100644 --- a/patches/src/main/resources/addresources/values-hy-rAM/strings.xml +++ b/patches/src/main/resources/addresources/values-hy-rAM/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced կարգավորումները վերադրվել են դեֆոլտային Import %d կարգավորում Import-ը ձախողվել է։ %s + Ցուցադրել ReVanced-ի կարգավորումների պատկերակները + Կարգավորումների պատկերակները ցուցադրվում են + Կարգավորումների պատկերակները ցուցադրված չեն ReVanced լեզվի "Որոշ լեզուների թարգմանությունները կարող են լինել բացակայուն կամ անավարտ: @@ -610,6 +612,10 @@ MicroG-ի համար մարտկոցի օպտիմալացումը անջատել Աուդիո ձայնագրությունը թաքցնել Աուդիո ձայնագրման մենյուը թաքցված է Աուդիո ձայնագրման մենյուը երևում է + + "Աուդիո ուղու ընտրացանկը թաքնված է: + +Աուդիո ուղու ընտրացանկը ցուցադրելու համար փոխեք «Կեղծել տեսահոսքերը»-ը iOS TV-ի" Դիտել VR-ով թաքցնել VR-ով դիտել մենյուը թաքցված է diff --git a/patches/src/main/resources/addresources/values-in-rID/strings.xml b/patches/src/main/resources/addresources/values-in-rID/strings.xml index 29c8e3b53..abaaeac98 100644 --- a/patches/src/main/resources/addresources/values-in-rID/strings.xml +++ b/patches/src/main/resources/addresources/values-in-rID/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Pengaturan ReVanced diatur ke setelan awal Mengimpor setelan %d Impor gagal: %s + Tampilkan ikon pengaturan ReVanced + Ikon pengaturan ditampilkan + Ikon pengaturan tidak ditampilkan Bahasa ReVanced "Terjemahan untuk beberapa bahasa mungkin hilang atau tidak lengkap. @@ -610,6 +612,10 @@ Jika mengubah setelan ini tidak berpengaruh, coba beralih ke mode Penyamaran."Sembunyikan trek Audio Menu trek audio disembunyikan Menu trek audio ditampilkan + + "Menu trek audio disembunyikan + +Untuk menampilkan menu trek Audio, ubah 'Spoof aliran video' ke iOS TV" Sembunyikan Tonton di VR Menu tonton di VR disembunyikan @@ -1174,9 +1180,9 @@ Miniplayer dapat diseret ke sudut layar mana pun" Miniplayer dapat diseret keluar layar ke kiri atau kanan" Gerakan seret horizontal dinonaktifkan - Sembunyikan tombol overlay - Tombol overlay disembunyikan - Tombol overlay ditampilkan + Sembunyikan tombol hamparan + Tombol hamparan disembunyikan + Tombol hamparan ditampilkan Sembunyikan tombol perluas dan tutup "Tombol disembunyikan diff --git a/patches/src/main/resources/addresources/values-is-rIS/strings.xml b/patches/src/main/resources/addresources/values-is-rIS/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-is-rIS/strings.xml +++ b/patches/src/main/resources/addresources/values-is-rIS/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-it-rIT/strings.xml b/patches/src/main/resources/addresources/values-it-rIT/strings.xml index 97e1870f9..c9f168e8c 100644 --- a/patches/src/main/resources/addresources/values-it-rIT/strings.xml +++ b/patches/src/main/resources/addresources/values-it-rIT/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Reimposta le impostazioni di ReVanced a quelle predefinite Importate %d impostazioni Importazione non riuscita: %s + Mostra le icone delle impostazioni di ReVanced + Le icone delle impostazioni vengono mostrate + Le icone delle impostazioni non vengono mostrate Lingua di ReVanced "Le traduzioni per alcune lingue potrebbero essere mancanti o incomplete. @@ -610,6 +612,10 @@ Se la modifica di questa impostazione non ha effetto, prova a passare alla modal Nascondi Traccia audio Il menu Traccia audio è nascosto Il menu Traccia audio è visibile + + "Il menu della traccia audio è nascosto + +Per mostrare il menu della traccia audio, cambia \"Spoof video streams\" in iOS TV" Nascondi Guarda in VR Il menu Guarda in VR è nascosto diff --git a/patches/src/main/resources/addresources/values-iw-rIL/strings.xml b/patches/src/main/resources/addresources/values-iw-rIL/strings.xml index 5282a73e4..48dde42bc 100644 --- a/patches/src/main/resources/addresources/values-iw-rIL/strings.xml +++ b/patches/src/main/resources/addresources/values-iw-rIL/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -596,6 +595,7 @@ Second \"item\" text" הסתר טראק אודיו תפריט טראק אודיו מוסתר תפריט טראק אודיו מוצג + הסתר \'צפה ב-VR\' תפריט \'צפה ב-VR\' מוסתר diff --git a/patches/src/main/resources/addresources/values-ja-rJP/strings.xml b/patches/src/main/resources/addresources/values-ja-rJP/strings.xml index e3a0b0d9f..ae5c6027a 100644 --- a/patches/src/main/resources/addresources/values-ja-rJP/strings.xml +++ b/patches/src/main/resources/addresources/values-ja-rJP/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -25,7 +24,7 @@ Second \"item\" text" チェックに失敗しました 公式サイトを開く 無視する - <h5>このアプリは、あなたによってパッチが適用されていないようです。</h5><br>このアプリは正しく動作しない可能性があり、<b>有害または危険なものである可能性があります</b>。<br><br>以下の検査結果は、このアプリがパッチ済みAPKであるか、または他のユーザーから取得したものであることを示唆しています。<br><br><small>%1$s</small><br>検証済みで安全なアプリを確実に使用するために、<b>このアプリをアンインストールして、自分でパッチを適用する</b>ことを強くお勧めします。<p><br>無視した場合、この警告は2回のみ表示されます。 + <h5>このアプリは、あなたによってパッチが適用されていないようです。</h5><br>このアプリは正しく動作しない可能性があり、<b>有害または危険なものである可能性があります</b>。<br><br>以下の検査結果は、このアプリがパッチ済みAPKであるか、または他のユーザーから取得したものであることを示唆しています。<br><br><small>%1$s</small><br>検証済みで安全なアプリを確実に使用するために、<b>このアプリをアンインストールして、自分でパッチを適用する</b>ことを強くお勧めします。<p><br>無視した場合、この警告は2回だけ表示されます。 別のデバイス上でパッチが適用されている ReVanced Manager によってインストールされていない 10 分以上前にパッチが適用されている @@ -43,7 +42,10 @@ Second \"item\" text" ReVanced 設定をデフォルトにリセット %d 個の設定をインポートしました インポート失敗: %s - ReVancedの言語 + ReVanced 設定にアイコンを表示する + ReVanced 設定にアイコンが表示されます + ReVanced 設定にアイコンは表示されません + ReVanced の言語 "一部の言語の翻訳が不足しているか、不完全である可能性があります。 新しい言語を翻訳するには、 translate.revanced.app にアクセスしてください" @@ -66,7 +68,7 @@ Second \"item\" text" 下記ウェブサイト「Don't kill my app」の携帯電話メーカー別のガイドに従い、MicroG GmsCore に対するデバイスの設定を変更してください。 -この操作はアプリが動作するために必要です。" +この操作はアプリが正常に動作するために必要です。" ウェブサイトを開く "問題を防ぐために、MicroG GmsCore に対する電池の最適化を必ず無効にしてください。 @@ -365,8 +367,8 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ 動画上に「商品を表示」ボタンや商品ボタンは表示されません 動画上に「商品を表示」ボタンや商品ボタンが表示されます 終了画面のストア バナーを非表示 - 終了画面のストア バナーは表示されません - 終了画面のストア バナーは表示されます + 動画の終了画面にストア バナーは表示されません + 動画の終了画面にストア バナーが表示されます ストア広告を非表示 ストア広告は表示されません ストア広告は表示されます @@ -438,18 +440,18 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ 明るさジェスチャーを有効にする - "全画面表示の明るさジェスチャーは有効です + "全画面表示中の明るさジェスチャーは有効です -画面の左側を縦にスワイプして明るさを調節します" - 全画面表示の明るさジェスチャーは無効です +画面左側を縦にスワイプして明るさを調節します" + 全画面表示中の明るさジェスチャーは無効です 音量ジェスチャーを有効にする - "全画面表示の音量ジェスチャーは有効です + "全画面表示中の音量ジェスチャーは有効です -画面の右側を縦にスワイプして音量を調節します" - 全画面表示の音量ジェスチャーは無効です +画面右側を縦にスワイプして音量を調節します" + 全画面表示中の音量ジェスチャーは無効です 長押しスワイプを有効にする - 画面を縦に長押しスワイプして明るさや音量を調節します - 画面を縦にスワイプして明るさや音量を調節します + 全画面表示中、画面を長押ししてから縦にスワイプして明るさや音量を調節します + 全画面表示中、画面を縦にスワイプして明るさや音量を調節します 触覚フィードバックを有効にする 触覚フィードバックは有効です 触覚フィードバックは無効です @@ -612,6 +614,10 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ 「音声トラック」を非表示 「音声トラック」は表示されません 「音声トラック」は表示されます + + "「音声トラック」は表示されません + +「音声トラック」を表示するには、「動画ストリームを偽装する」の「デフォルトのクライアント」を iOS TV に変更してください" 「VR で見る」を非表示 「VR で見る」は表示されません @@ -768,7 +774,7 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ 再生終了時に「関連動画」を表示しない - "自動再生を無効にすると、再生終了時に「関連動画」は表示されません + "再生終了時に「関連動画」は表示されませんが、自動再生がオンの場合は自動で再生されます 自動再生の設定は YouTube の設定で変更できます: 設定 → 再生 → 次の動画を自動再生" @@ -846,7 +852,7 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ API fetch votes, number of timeout ネットワーク通話がタイムアウトされていません %d ネットワーク呼び出しがタイムアウトしました - APIクライアントのレート制限 + API クライアントのレート制限 クライアント レート制限は発生していません クライアント レート制限が %d 回発生しました %d ミリ秒前 @@ -872,29 +878,29 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ シーク位置のサムネイルがプレーヤー画面全体に表示されます - SponsorBlock を有効にする - SponsorBlock は、YouTube 動画の不要な部分をスキップするためのクラウドソーシングシステムです + SponsorBlock を有効化 + SponsorBlock はユーザーからの情報提供により YouTube 動画のわずらわしい部分をスキップする機能です 外観 投票ボタンを表示 - セグメント投票ボタンが表示されます - セグメント投票ボタンは表示されません - 正方形のレイアウトを使用 - ボタンとコントロールが正方形になります - ボタンとコントロールは丸みを帯びています + プレーヤー オーバーレイにセグメントへの投票ボタンが表示されます + プレーヤー オーバーレイにセグメントへの投票ボタンは表示されません + 四角ボタンを使用する + ボタンとコントロールの角は直角です + ボタンとコントロールの角は丸角です - コンパクトな「スキップ」ボタンを使用 - スキップボタンはコンパクトに表示されます - スキップボタンは最適なサイズで表示されます - 「スキップ」ボタンを自動的に非表示 - スキップボタンは数秒後に非表示になります - セグメント全体に「スキップ」ボタンが表示されます + コンパクトなスキップボタンを使用する + ボタンに「スキップ」とだけ表示されます + ボタンにカテゴリー名が表示されます + スキップボタンを自動的に非表示にする + スキップボタンは表示された数秒後に自動的に非表示になります + スキップボタンはセグメントの開始から終了まで表示されます スキップ時にトーストを表示 - セグメントが自動的にスキップされたときにトースト ポップアップが表示されます。例を見るにはここをタップしてください + セグメントが自動的にスキップされたときにトースト ポップアップが表示されます。ここをタップするとサンプルが表示されます トースト ポップアップは表示されません。例を見るにはここをタップしてください - セグメントを除いた時間を表示 - 動画からセグメントを除いた時間が、動画全体の再生時間の横に括弧で表示されます + セグメントを除いた再生時間を表示 + セグメントを除いた再生時間が、動画全体の再生時間の横に括弧付きで表示されます 動画全体の再生時間のみが表示されます - 新しいセグメントを作成する + セグメントの作成 新しいセグメント作成ボタンを表示 新しいセグメントを作成するボタンが表示されます 新しいセグメントを作成するボタンは表示されません @@ -936,59 +942,59 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ ユーザー ID はパスワードのようなものであり、共有しないでください。" 今後表示しない - セグメントの動作を変更する + セグメントのスキップ スポンサー - 有料プロモーション, 有料紹介と直接広告. ない原因/原因/クリエイター/ウェブサイト/製品への自己宣伝または無料シャウトアウト 彼らが好きなもの - 無報酬/セルフプロモーション - スポンサーと同様に、無給または自己宣伝の場合。商品、寄付、またはコラボレーション相手に関する情報を記載したセクションが含まれます - インタラクション リマインダー (チャンネル登録) - コンテンツの途中で、購読したりフォローしたりするための短いリマインダーです。 それが長いまたは特定の何かについてである場合、それは代わりに自己宣伝の下にあるべきである。 - 強調表示 - 動画の中で多くの人々が見たい部分 - 休憩/イントロ アニメーション + 有料の宣伝 、紹介、直接広告。自己宣伝や好みのクリエーター、ウェブサイト、製品、慈善活動などの無報酬の宣伝は含まれません + 無報酬の宣伝 / 自己宣伝 + 無報酬または自己宣伝である、という点以外は「スポンサー」と同様です。商品、寄付、コラボ相手に関する宣伝を含みます + 視聴者への催促 (登録) + 動画中に差し込まれる視聴者への高評価、チャンネル登録、フォローなどの短時間の催促。時間的に長い、または何か具体的なものに関する催促は「視聴者への催促」ではなく「自己宣伝」に分類すべきです + ハイライト + 動画の中で最も興味を引く場面 + 幕間 / オープニング (イントロ) 実際のコンテンツを含まない間隔。一時停止、固定フレーム、繰り返しアニメーションを使用できます。情報を含むトランジションは含まれません。 - エンドカード/クレジット + 終了画面 / クレジット (アウトロ) クレジットまたはYouTubeのエンドカードが表示される場合、情報を持つ結論にはなりません - プレビュー/再読み込み/フック + 予告編 / 総集編 / フック ビデオやシリーズの他のビデオで何が起こったのかを示すクリップのコレクション 全ての情報が他の場所で繰り返されます - 無駄な脱線/冗談 - Tangential シーンは、ビデオの主な内容を理解する必要がないフィラーやユーモアにのみ追加されました。 コンテキストや背景の詳細を提供するセグメントが含まれていません - 音楽: 音楽ではない区間 - ミュージックビデオでのみ使用できます。音楽がないミュージックビデオのセクションでは、別のカテゴリでカバーされていません。 + 尺稼ぎの余談 / 冗談 + 動画の本筋を理解するのに必要のない、尺稼ぎやユーモアのみを目的として追加された脱線的な場面。コンテキストや背景情報を提供するセグメントは含まれません + 音楽: 楽曲以外の区間 + ミュージック ビデオ専用。ミュージック ビデオの中で楽曲が流れていない区間。他のカテゴリーのセグメントと重なる場合があります スキップ - 強調表示 - スポンサーをスキップ - プロモーションをスキップ - 対話をスキップ - スキップ - イントロをスキップ - 間隔をスキップ - 間隔をスキップ - アウトロをスキップ - プレビューをスキップ - プレビューをスキップ - 要約をスキップ - フィラーをスキップ - 音楽以外をスキップ + ハイライト + 「 スポンサー」をスキップ + 「自己宣伝」をスキップ + 「催促」をスキップ + 「ハイライト」までスキップ + 「イントロ」をスキップ + 「幕間」をスキップ + 「幕間」をスキップ + 「アウトロ」をスキップ + 「予告編」をスキップ + 「予告編」をスキップ + 「総集編」をスキップ + 「余談」をスキップ + 「楽曲以外」をスキップ セグメントをスキップ - スキップしたスポンサー - スキップしたセルフプロモーション - スキップした迷惑なリマインダー - ハイライト表示にスキップ - スキップしたイントロ - スキップされた休憩時間 - スキップされた休憩時間 - スキップしたアウトロ - スキップしたプレビュー - スキップしたプレビュー - スキップされた要約 - つなぎシーンをスキップしました - スキップした無音 + 「スポンサー」をスキップしました + 「自己宣伝」をスキップしました + 「視聴者への催促」をスキップしました + 「ハイライト」までスキップしました + 「イントロ」をスキップしました + 「幕間」をスキップしました + 「幕間」をスキップしました + 「アウトロ」をスキップしました + 「予告編」をスキップしました + 「予告編」をスキップしました + 「総集編」をスキップしました + 「余談」をスキップしました + 「楽曲以外の区間」をスキップしました 未送信のセグメントをスキップしました - 複数のセグメントをスキップ + 複数のセグメントをスキップしました 自動的にスキップ - 一度自動的にスキップ - 「スキップ」ボタンを表示 + 1 回だけ自動的にスキップ + スキップ ボタンを表示 シークバーに表示 無効 セグメントを送信できません: %s @@ -1048,15 +1054,15 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ ユーザー名は正常に変更されました あなたの評判は <b>%.2f</b> <b>%s</b> 個のセグメントを作成しました - セグメントを見るにはここをタップしてください - SponsorBlockリーダーボード - <b>%s</b> 個のセグメントから人々を救いました - ここをタップすると、世界的な統計とトップの貢献者を見ることができます - それは <b>%s</b> の生活です。<br>ここをタップしてリーダーボードを見る - <b>%s</b> セグメントをスキップしました - <b>%s</b> - スキップされたセグメントカウンターをリセットしますか? - %1$s時間%2$s分 + 作成したセグメントを表示するには、ここをタップしてください + SponsorBlock リーダーボード + 合計で <b>%s</b> 個のセグメントから人々を救いました + グローバルの統計と上位の貢献者を表示するには、ここをタップしてください + 時間にして <b>%s</b> です。<br>ここをタップすると、リーダーボードが表示されます + 合計で <b>%s</b> 個のセグメントをスキップしました + 時間にして <b>%s</b> です + スキップしたセグメントの合計をリセットしますか? + %1$s 時間 %2$s 分 %1$s 分 %2$s 秒 %s 秒 透明度: @@ -1100,11 +1106,11 @@ Automotive レイアウト 19.01.34 - ナビゲーション アイコンが旧バージョン - 起動画面 + スタート画面 デフォルト すべての登録チャンネル チャンネル一覧 - コース / 学び + 学び 探索 ファッションと美容 ゲーム @@ -1112,7 +1118,7 @@ Automotive レイアウト マイページ 高く評価した動画 ライブ - 映画 + 映画とテレビ 音楽 ニュース 通知 @@ -1177,7 +1183,7 @@ Automotive レイアウト ミニプレーヤーを画面の左または右端で最小化できます" 横方向ドラッグ ジェスチャーは無効です オーバーレイ ボタンを非表示 - オーバーレイ ボタンは非表示 + オーバーレイ ボタンは表示されません オーバーレイ ボタンは表示されます 拡大ボタンと閉じるボタンを非表示 "ボタンは表示されません @@ -1187,7 +1193,7 @@ Automotive レイアウト サブテキストを非表示 サブテキストは表示されません サブテキストは表示されます - 早送り / 巻き戻しボタンを非表示 + 早送りボタンと巻き戻しボタンを非表示 早送りボタンと巻き戻しボタンは表示されません 早送りボタンと巻き戻しボタンは表示されます デフォルトのサイズ @@ -1232,7 +1238,7 @@ Automotive レイアウト 静止画サムネイル "DeArrow は、YouTube 動画のサムネイルをクラウドソーシングで提供する機能です。DeArrow のサムネイルは、YouTube が提供するサムネイルよりも適切なことが多いです。これを有効にすると、動画の URL が API サーバーに送信されますが、他のデータは送信されません。動画に DeArrow サムネイルがない場合は、オリジナルのサムネイルまたは静止画サムネイルが表示されます -DeArrow の詳細については、ここをタップしてください" +詳細については、ここをタップしてください" API が利用できない場合はトーストを表示する DeArrow が利用できない場合はトースト ポップアップが表示されます DeArrow が利用できない場合でもトースト ポップアップは表示されません @@ -1281,8 +1287,8 @@ DeArrow の詳細については、ここをタップしてください"この機能を有効にすると、動画のカクつき、バッテリー寿命の悪化、および予期せぬ副作用を引き起こす可能性があります。 - GmsCore設定 - GmsCoreの設定 + GmsCore 設定 + GmsCore の設定 URL リダイレクトを回避する @@ -1385,8 +1391,8 @@ DeArrow の詳細については、ここをタップしてください" iOS クライアントの副作用 - "• 映画や有料動画が再生されない場合があります -• 一定音量は使用できません + "• 映画や有料動画が再生されない可能性があります +• 一定音量は利用できません • 動画が 1 秒早く終了します" Android クライアントの副作用 "• 音声トラック メニューが表示されません diff --git a/patches/src/main/resources/addresources/values-ka-rGE/strings.xml b/patches/src/main/resources/addresources/values-ka-rGE/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-ka-rGE/strings.xml +++ b/patches/src/main/resources/addresources/values-ka-rGE/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-kk-rKZ/strings.xml b/patches/src/main/resources/addresources/values-kk-rKZ/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-kk-rKZ/strings.xml +++ b/patches/src/main/resources/addresources/values-kk-rKZ/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-km-rKH/strings.xml b/patches/src/main/resources/addresources/values-km-rKH/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-km-rKH/strings.xml +++ b/patches/src/main/resources/addresources/values-km-rKH/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-kn-rIN/strings.xml b/patches/src/main/resources/addresources/values-kn-rIN/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-kn-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-kn-rIN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-ko-rKR/strings.xml b/patches/src/main/resources/addresources/values-ko-rKR/strings.xml index af248a46b..f238b037a 100644 --- a/patches/src/main/resources/addresources/values-ko-rKR/strings.xml +++ b/patches/src/main/resources/addresources/values-ko-rKR/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced 설정을 기본값으로 초기화합니다 %d 설정을 가져왔습니다 설정을 가져올 수 없습니다: %s + ReVanced 설정 아이콘 표시하기 + 설정 아이콘을 표시합니다 + 설정 아이콘을 표시하지 않습니다 ReVanced 언어 "일부 언어의 번역이 누락되었거나 완료되지 않았을 수 있습니다 @@ -409,8 +411,8 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 시청 경고 다이얼로그 제거하기 - 다음 동영상을 시청하기 전에 표시되는 시청 경고 다이얼로그를 제거합니다:\n• 연령 제한 동영상\n• 혐오감을 주는 동영상\n• 자살 또는 자해와 관련된 동영상, etc. - 다음 동영상을 시청하기 전에 표시되는 시청 경고 다이얼로그를 제거하지 않습니다:\n• 연령 제한 동영상\n• 혐오감을 주는 동영상\n• 자살 또는 자해와 관련된 동영상, etc. + 다음 동영상을 시청하기 전에 표시되는 시청 경고 다이얼로그를 제거합니다:\n• 연령 제한 동영상\n• 자살 또는 자해와 관련된 동영상, etc. + 다음 동영상을 시청하기 전에 표시되는 시청 경고 다이얼로그를 제거하지 않습니다:\n• 연령 제한 동영상\n• 자살 또는 자해와 관련된 동영상, etc. 이 설정은 다이얼로그를 자동으로 허용하기만 하며 연령 제한(성인인증 절차)을 우회할 수 없습니다 @@ -610,6 +612,10 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 오디오 트랙 메뉴 숨기기 오디오 트랙 메뉴가 숨겨집니다 오디오 트랙 메뉴가 표시됩니다 + + "오디오 트랙 메뉴가 숨겨집니다 + +오디오 트랙 메뉴를 표시하려면 '스트리밍 데이터 변경하기'에서 기본 클라이언트를 iOS TV로 변경하세요" VR로 보기 메뉴 숨기기 VR로 보기 메뉴가 숨겨집니다 diff --git a/patches/src/main/resources/addresources/values-ky-rKG/strings.xml b/patches/src/main/resources/addresources/values-ky-rKG/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-ky-rKG/strings.xml +++ b/patches/src/main/resources/addresources/values-ky-rKG/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-lo-rLA/strings.xml b/patches/src/main/resources/addresources/values-lo-rLA/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-lo-rLA/strings.xml +++ b/patches/src/main/resources/addresources/values-lo-rLA/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-lt-rLT/strings.xml b/patches/src/main/resources/addresources/values-lt-rLT/strings.xml index fd26f159b..0b4c39d0c 100644 --- a/patches/src/main/resources/addresources/values-lt-rLT/strings.xml +++ b/patches/src/main/resources/addresources/values-lt-rLT/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced nustatymai atstatyti į numatytuosius Importuota %d nustatymų Importavimas nepavyko: %s + Rodyti „ReVanced“ nustatymų piktogramas + Nustatymų piktogramos yra rodomos + Nenurodomos nustatymų piktogramos ReVanced kalba "Kai kurių kalbų vertimai gali būti neišsamūs ar trūkti. @@ -610,6 +612,8 @@ Jei pakeitus šį nustatymą neįsigalioja, pabandykite perjungti į inkognito r Slėpti Garso takelius Garso takelių meniu yra paslėptas Garso takelių meniu yra rodomas + + "Garso takelio meniu yra paslėptas.\n\nNorėdami parodyti garso takelio meniu, pakeiskite „Apsimesti vaizdo srautais“ į „iOS TV“" Slėpti Žiūrėti VR Žiūrėti VR meniu yra paslėptas diff --git a/patches/src/main/resources/addresources/values-lv-rLV/strings.xml b/patches/src/main/resources/addresources/values-lv-rLV/strings.xml index 6e57ca5c0..8f9412d8d 100644 --- a/patches/src/main/resources/addresources/values-lv-rLV/strings.xml +++ b/patches/src/main/resources/addresources/values-lv-rLV/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced iestatījumi atiestatīti uz noklusējuma vērtībām Importēti %d iestatījumi Importēšana neizdevās: %s + Rādīt ReVanced iestatījumu ikonas + Iestatījumu ikonas tiek rādītas + Ikonas iestatījumos netiek rādītas ReVanced valoda "Tulkojuma dažām valodām var būt nepilnīgs vai nebūt vispār. @@ -610,6 +612,10 @@ Ja šī iestatījuma maiņa nestājas spēkā, mēģiniet pārslēgties uz inkog Paslēpt Audio ceļu Audio ceļa izvēlne ir paslēpta Audio ceļa izvēlne ir redzama + + "Audio celiņu izvēlne ir paslēpta. + +Lai parādītu audio celiņu izvēlni, mainiet \"Video straumju viltošana\" uz iOS TV" Paslēpt Skatīties VR Skatīties VR izvēlne ir paslēpta diff --git a/patches/src/main/resources/addresources/values-mk-rMK/strings.xml b/patches/src/main/resources/addresources/values-mk-rMK/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-mk-rMK/strings.xml +++ b/patches/src/main/resources/addresources/values-mk-rMK/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-ml-rIN/strings.xml b/patches/src/main/resources/addresources/values-ml-rIN/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-ml-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-ml-rIN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-mn-rMN/strings.xml b/patches/src/main/resources/addresources/values-mn-rMN/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-mn-rMN/strings.xml +++ b/patches/src/main/resources/addresources/values-mn-rMN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-mr-rIN/strings.xml b/patches/src/main/resources/addresources/values-mr-rIN/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-mr-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-mr-rIN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-ms-rMY/strings.xml b/patches/src/main/resources/addresources/values-ms-rMY/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-ms-rMY/strings.xml +++ b/patches/src/main/resources/addresources/values-ms-rMY/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-my-rMM/strings.xml b/patches/src/main/resources/addresources/values-my-rMM/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-my-rMM/strings.xml +++ b/patches/src/main/resources/addresources/values-my-rMM/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-nb-rNO/strings.xml b/patches/src/main/resources/addresources/values-nb-rNO/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-nb-rNO/strings.xml +++ b/patches/src/main/resources/addresources/values-nb-rNO/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-ne-rIN/strings.xml b/patches/src/main/resources/addresources/values-ne-rIN/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-ne-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-ne-rIN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-nl-rNL/strings.xml b/patches/src/main/resources/addresources/values-nl-rNL/strings.xml index 60bd42c07..1be4e0569 100644 --- a/patches/src/main/resources/addresources/values-nl-rNL/strings.xml +++ b/patches/src/main/resources/addresources/values-nl-rNL/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced-instellingen zijn teruggezet naar de standaardinstellingen %d instellingen geïmporteerd Importeren mislukt: %s + Pictogrammen voor ReVanced-instellingen weergeven + Instellingspictogrammen worden weergegeven + Pictogrammen voor instellingen worden niet weergegeven ReVanced-taal "Vertalingen voor sommige talen kunnen ontbreken of onvolledig zijn. @@ -610,6 +612,10 @@ Als het wijzigen van deze instelling geen effect heeft, probeer dan over te scha Verberg Audiotrack Menu Audiotrack is verborgen Menu Audiotrack wordt weergegeven + + "Audiotrackmenu is verborgen + +Om het audiotrackmenu weer te geven, wijzigt u 'Videostreams vervalsen' in iOS TV" Verberg Bekijk in VR Menu Bekijk in VR is verborgen @@ -1096,6 +1102,7 @@ Als het later wordt uitgeschakeld, wordt aanbevolen om de app-gegevens te wissen This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> Doel voor vervalsen app-versie 19.35.36 - Herstel oude pictogrammen voor Shorts-speler + 19.01.34 - Herstel oude navigatie-iconen Startpagina instellen diff --git a/patches/src/main/resources/addresources/values-or-rIN/strings.xml b/patches/src/main/resources/addresources/values-or-rIN/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-or-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-or-rIN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-pa-rIN/strings.xml b/patches/src/main/resources/addresources/values-pa-rIN/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-pa-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-pa-rIN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-pl-rPL/strings.xml b/patches/src/main/resources/addresources/values-pl-rPL/strings.xml index 3ebd7d5ef..557c08bce 100644 --- a/patches/src/main/resources/addresources/values-pl-rPL/strings.xml +++ b/patches/src/main/resources/addresources/values-pl-rPL/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Przywrócono domyślne ustawienia ReVanced Zaimportowano %d ustawień Importowanie nie powiodło się: %s + Pokaż ikony ustawień ReVanced + Ikony ustawień są widoczne + Ikony ustawień nie są wyświetlane Język ReVanced "Tłumaczenia dla niektórych języków mogą być niepełne lub nieaktualne. @@ -610,6 +612,10 @@ Jeśli zmiana tego ustawienia nie przyniesie efektu, spróbuj przełączyć się Menu ścieżki dźwiękowej Menu ścieżki dźwiękowej jest ukryte Menu ścieżki dźwiękowej jest widoczne + + "Menu ścieżki audio jest ukryte + +Aby pokazać menu ścieżki audio, zmień opcję „Fałszuj strumienie wideo” na iOS TV" Menu oglądania w VR Menu oglądania w VR jest ukryte diff --git a/patches/src/main/resources/addresources/values-pt-rBR/strings.xml b/patches/src/main/resources/addresources/values-pt-rBR/strings.xml index a7517d7fb..257354aed 100644 --- a/patches/src/main/resources/addresources/values-pt-rBR/strings.xml +++ b/patches/src/main/resources/addresources/values-pt-rBR/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Configurações do ReVanced redefinidas para o padrão Configurações %d importadas Importação falhou: %s + Mostrar ícones de configuração do ReVanced + Ícones de configuração são mostrados + Os ícones de configuração não são mostrados Idioma do ReVanced "As traduções para alguns idiomas podem estar ausentes ou incompletas.\n\nPara traduzir novos idiomas, acesse translate.revanced.app" Idioma do aplicativo @@ -608,6 +610,10 @@ Se alterar esta configuração não fizer efeito, tente mudar para o modo anôni Ocultar Faixa de áudio Menu faixa de áudio está oculto Menu faixa de áudio não está oculto + + "O menu da faixa de áudio está oculto + +Para exibir o menu da faixa de áudio, altere \"Spoof video streams\" para iOS TV" Ocultar Assistir no VR Menu assistir no VR está oculto @@ -1093,6 +1099,7 @@ Se posteriormente desativado, é recomendável limpar os dados do aplicativo par This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> Versão de spoofing alvo 19.35.36 - Restaurar ícones antigos do player dos Shorts + 19.01.34 - Restaurar ícones de navegação antigos Definir página inicial diff --git a/patches/src/main/resources/addresources/values-pt-rPT/strings.xml b/patches/src/main/resources/addresources/values-pt-rPT/strings.xml index 981ae9a6a..1e0b53d0e 100644 --- a/patches/src/main/resources/addresources/values-pt-rPT/strings.xml +++ b/patches/src/main/resources/addresources/values-pt-rPT/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" As definições do ReVanced foram redefinidas para a predefinição Configurações importadas: %d A importação falhou: %s + Mostrar ícones de configuração do ReVanced + Os ícones de configuração são mostrados + Os ícones de configuração não são mostrados Idioma do ReVanced "As traduções para algumas línguas podem estar em falta ou incompletas. @@ -610,6 +612,10 @@ Se alterar esta configuração não fizer efeito, tente alternar para o modo an Esconder faixa de áudio Menu de faixa de áudio escondida Menu da faixa de áudio visível + + "O menu da faixa de áudio está oculto + +Para mostrar o menu da faixa de áudio, altere \"Spoof video streams\" para iOS TV" Esconder relógio no VR Assista no menu VR está escondido diff --git a/patches/src/main/resources/addresources/values-ro-rRO/strings.xml b/patches/src/main/resources/addresources/values-ro-rRO/strings.xml index 2914a06b4..6db882d86 100644 --- a/patches/src/main/resources/addresources/values-ro-rRO/strings.xml +++ b/patches/src/main/resources/addresources/values-ro-rRO/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Setările ReVanced au fost resetate la valorile implicite Au fost importate %d setări Importare eșuată: %s + Afișați pictogramele de setări ReVanced + Pictogramele de setări sunt afișate + Pictogramele setărilor nu sunt afișate Limba ReVanced "Traducerile pentru unele limbi pot lipsi sau pot fi incomplete. @@ -610,6 +612,10 @@ Dacă modificarea acestei setări nu are efect, încercați să comutați la mod Ascunde piesa audio Meniul piesei audio este ascuns Meniul piesei audio este afișat + + "Meniul pentru pista audio este ascuns + +Pentru a afișa meniul pentru pista audio, schimbați opțiunea „Falsifică fluxurile video” în iOS TV" Ascunde ceas în VR Vizionarea în meniul VR este ascunsă diff --git a/patches/src/main/resources/addresources/values-ru-rRU/strings.xml b/patches/src/main/resources/addresources/values-ru-rRU/strings.xml index 90e125001..05f608356 100644 --- a/patches/src/main/resources/addresources/values-ru-rRU/strings.xml +++ b/patches/src/main/resources/addresources/values-ru-rRU/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Настройки ReVanced восстановлены до значений по умолчанию Импортировано %d настроек Ошибка импорта: %s + Показать иконки в настройках ReVanced + Иконки в настройках ReVanced показаны + Иконки в настройках ReVanced скрыты Язык настроек ReVanced "Переводы для некоторых языков могут отсутствовать или быть неполными. @@ -226,9 +228,9 @@ Second \"item\" text" Скрыть карточки исполнителей Карточки исполнителей под плеером скрыты Карточки исполнителей под плеером показаны - Скрыть «Краткое содержание видео, созданное ИИ» - Раздел с кратким содержанием видео скрыт - Раздел с кратким содержанием видео показан + Скрыть секцию AI-резюме видео + Секция AI-резюме видео в описании видео скрыта + Секция AI-резюме видео в описании видео показана Скрыть раздел атрибутов Разделы \"Упомянутые или показанные места\", \"Игры\", \"Музыка\" и \"Люди, которых упоминали\" скрыты Разделы \"Упомянутые или показанные места\", \"Игры\", \"Музыка\" и \"Люди, которых упоминали\" показаны @@ -265,12 +267,12 @@ Second \"item\" text" Панель фильтров в похожих видео показана Комментарии Скрыть или показать компоненты раздела комментариев - Скрыть сводку чата на базе ИИ - Баннер \"Обзор чата\" в чатах прямых трансляций скрыт - Баннер \"Обзор чата\" в чатах прямых трансляций показан - Скрыть сводку комментариев на базе ИИ - Сводка комментариев скрыта - Сводка комментариев показана + Скрыть секцию AI-обзора чата + Секция AI-обзора чата в чатах прямых трансляций скрыта + Секция AI-обзора чата в чатах прямых трансляций показана + Скрыть вкладку AI-сводки по темам комментариев + Вкладка AI-сводки по темам комментариев скрыта + Вкладка AI-сводки по темам комментариев показана Скрыть заголовок \"Комментарии спонсоров\" Заголовок \"Комментарии спонсоров\" в комментариях скрыт Заголовок \"Комментарии спонсоров\" в комментариях показан @@ -430,9 +432,9 @@ Second \"item\" text" Жест покадровой перемотки включен - Включить нажатие для поиска - Нажатие для поиска включено - Нажатие для поиска отключено + Включить перемотку нажатием + Перемотка нажатием на полосу прогресса включена + Перемотка нажатием на полосу прогресса отключена Включить регулировку яркости жестом @@ -555,7 +557,7 @@ Second \"item\" text" Отключить полупрозрачность строки состояния Строка состояния непрозрачная Строка состояния непрозрачная или полупрозрачная - На некоторых устройствах включение этой функции может сделать панель навигации системы прозрачной. + На некоторых устройствах включение данной опции может сделать системную панель навигации прозрачной. Отключить полупрозрачность светлой панели навигации Панель навигации при светлой теме непрозрачная Панель навигации при светлой теме непрозрачная или полупрозрачная @@ -610,6 +612,10 @@ Second \"item\" text" Скрыть пункт \"Звуковая дорожка\" Пункт \"Звуковая дорожка\" в выдвижном меню плеера скрыт Пункт \"Звуковая дорожка\" в выдвижном меню плеера показан + + "Пункт \"Звуковая дорожка\" в выдвижном меню плеера скрыт + +Для показа пункта \"Звуковая дорожка\" измените клиент \"Подмены видеопотоков\" на iOS TV" Скрыть пункт \"Смотреть в VR-режиме\" Пункт \"Смотреть в VR-режиме\" в выдвижном меню плеера скрыт @@ -1175,9 +1181,9 @@ Second \"item\" text" Миниплеер можно перетаскивать за пределы экрана влево или вправо" Жест горизонтального перетаскивания отключен - Скрыть кнопки наложения - Кнопки наложения скрыты - Кнопки наложения отображаются + Скрыть кнопки миниплеера + Кнопки миниплеера скрыты + Кнопки миниплеера показаны Скрыть кнопки разворачивания и закрытия "Кнопки разворачивания и закрытия скрыты @@ -1370,7 +1376,7 @@ Second \"item\" text" Подмена видеопотоков - Подмена видеопотоков клиента для предотвращения проблем с воспроизведением видео + Подмена клиента видеопотоков для предотвращения проблем с воспроизведением видео Подменить видеопотоки Видеопотоки подменены "Видеопотоки не подменены diff --git a/patches/src/main/resources/addresources/values-si-rLK/strings.xml b/patches/src/main/resources/addresources/values-si-rLK/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-si-rLK/strings.xml +++ b/patches/src/main/resources/addresources/values-si-rLK/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-sk-rSK/strings.xml b/patches/src/main/resources/addresources/values-sk-rSK/strings.xml index e5de17297..ced887dff 100644 --- a/patches/src/main/resources/addresources/values-sk-rSK/strings.xml +++ b/patches/src/main/resources/addresources/values-sk-rSK/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Nastavenia ReVanced sa obnovia na predvolené Počet importovaných nastavení: %d Import zlyhal: %s + Zobraziť ikony nastavení ReVanced + Ikony nastavení sa zobrazujú + Ikony nastavení sa nezobrazujú Jazyk reVanced "Pre niektoré jazyky môžu chýbať preklady alebo môžu byť neúplné. @@ -603,6 +605,10 @@ Ak zmena tohto nastavenia nemá žiadny účinok, skúste prepnúť do režimu i Skryť zvukovú stopu Ponuka zvukovej stopy je skrytá Zobrazí sa ponuka zvukovej stopy + + "Ponuka zvukovej stopy je skrytá + +Ak chcete zobraziť ponuku zvukovej stopy, zmeňte možnosť „Oklamať videostreamy“ na iOS TV" Skryť hodinky vo VR Sledovanie v ponuke VR je skryté diff --git a/patches/src/main/resources/addresources/values-sl-rSI/strings.xml b/patches/src/main/resources/addresources/values-sl-rSI/strings.xml index 450247101..c02eff6b2 100644 --- a/patches/src/main/resources/addresources/values-sl-rSI/strings.xml +++ b/patches/src/main/resources/addresources/values-sl-rSI/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced nastavitve ponastavljene na privzeto Uvoženih %d nastavitev Uvoz ni uspel: %s + Pokaži ikone nastavitev ReVanced + Ikone nastavitev so prikazane + Ikone nastavitev niso prikazane ReVanced jezik "Prevodi za nekatere jezike morda manjkajo ali so nepopolni. @@ -610,6 +612,10 @@ Opomba: Omogočanje tega tudi prisilno skrije video oglase" Skrij zvočni posnetek Meni z zvočnim posnetkom je skrit Meni z zvočnim posnetkom je prikazan + + "Meni zvočnega posnetka je skrit + +Če želite prikazati meni zvočnega posnetka, spremenite možnost »Prikazovalnik video tokov« v iOS TV" Skrij gledanje v VR Meni z gledanjem v VR je skrit diff --git a/patches/src/main/resources/addresources/values-sq-rAL/strings.xml b/patches/src/main/resources/addresources/values-sq-rAL/strings.xml index c5d1fe7a5..8681e250e 100644 --- a/patches/src/main/resources/addresources/values-sq-rAL/strings.xml +++ b/patches/src/main/resources/addresources/values-sq-rAL/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Cilësimet e ReVanced u rivendosën në cilësimet e parazgjedhura Importuan %d cilësime Importimi dështoi: %s + Shfaq ikonat e cilësimeve të ReVanced + Ikonat e cilësimeve shfaqen + Ikonat e cilësimeve nuk shfaqen Gjuha e ReVanced "Përkthimet për disa gjuhë mund të jenë të humbura ose të paplota. @@ -610,6 +612,10 @@ Nëse ndryshimi i këtij konfigurimi nuk ka efekt, provoni të kaloni në modali Fsheh \"Shina e audios\" Menyja \"Shina e audios\" është e fshehur Menyja \"Shina e audios\" është e dukshme + + "Menyja e pistës audio është e fshehur + +Për të shfaqur menunë e pistës audio, ndryshoni 'Falsifiko transmetimet video' në iOS TV" Fsheh \"Shikoni në VR\" Menyja \"Shikoni në VR\" është e fshehur diff --git a/patches/src/main/resources/addresources/values-sr-rCS/strings.xml b/patches/src/main/resources/addresources/values-sr-rCS/strings.xml index 8e0c04188..82ffd09ae 100644 --- a/patches/src/main/resources/addresources/values-sr-rCS/strings.xml +++ b/patches/src/main/resources/addresources/values-sr-rCS/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Podešavanja ReVanceda su vraćena na podrazumevane vrednosti Uvezeno %d podešavanja Neuspešan uvoz: %s + Prikaži ikonice podešavanja ReVanceda + Ikonice podešavanja su prikazane + Ikonice podešavanja nisu prikazane Jezik ReVanceda "Prevodi za neke jezike mogu nedostajati ili biti nepotpuni. @@ -610,6 +612,10 @@ Ako se promena ove opcije ne primeni, pokušajte da pređete u režim bez arhivi Sakrij meni „Audio snimak” Meni „Audio snimak” je skriven Meni „Audio snimak” je prikazan + + "Meni „Audio snimak” je skriven + +Da biste prikazali meni „Audio snimak”, promenite opciju „Lažirani video strimovi” na iOS TV" Sakrij dugme „Gledaj u VR” Dugme „Gledaj u VR” je skriveno @@ -1154,7 +1160,7 @@ Ako se kasnije isključi, preporučuje se da izbrišete podatke aplikacije da bi Moderan 1 Moderan 2 Moderan 3 - Moderno 4 + Moderan 4 Omogući zaobljene uglove Uglovi su zaobljeni Uglovi su kvadratni @@ -1174,9 +1180,9 @@ Mini-plejer se može prevući u bilo koji ugao ekrana" Mini-plejer se može prevući sa ekrana ulevo ili udesno" Pokret horizontalnog prevlačenja je onemogućen - Sakrij dugmad za preklapanje - Dugmad za preklapanje su skrivena - Dugmad za preklapanje su prikazana + Sakrij dugmad preklopa + Dugmad preklopa su skrivena + Dugmad preklopa su prikazana Sakrij dugmad za proširivanje i zatvaranje "Dugmad su skrivena diff --git a/patches/src/main/resources/addresources/values-sr-rSP/strings.xml b/patches/src/main/resources/addresources/values-sr-rSP/strings.xml index a5c4ea62a..892604f7c 100644 --- a/patches/src/main/resources/addresources/values-sr-rSP/strings.xml +++ b/patches/src/main/resources/addresources/values-sr-rSP/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Подешавања ReVanced-а су враћена на подразумеване вредности Увезено %d подешавања Неуспешан увоз: %s + Прикажи иконице подешавања ReVanced-а + Иконице подешавања су приказане + Иконице подешавања нису приказане Језик ReVanced-a "Преводи за неке језике могу недостајати или бити непотпуни. @@ -610,6 +612,10 @@ Second \"item\" text" Сакриј мени „Аудио снимак” Мени „Аудио снимак” је скривен Мени „Аудио снимак” је приказан + + "Мени „Аудио снимак” је скривен + +Да бисте приказали мени „Аудио снимак”, промените опцију „Лажирани видео стримови” на iOS TV" Сакриј дугме „Гледај у ВР” Дугме „Гледај у ВР” је скривено @@ -1174,11 +1180,11 @@ Second \"item\" text" Мини-плејер се може превући са екрана улево или удесно" Покрет хоризонталног превлачења је онемогућен - Сакриј дугмад преклапања - Дугмад преклапања су сакривена - Дугмад преклапања су приказана + Сакриј дугмад преклопа + Дугмад преклопа су скривена + Дугмад преклопа су приказана Сакриј дугмад за проширивање и затварање - "Дугмад су сакривена + "Дугмад су скривена Превуците да бисте проширили или затворили" Дугмад за проширивање и затварање су приказана diff --git a/patches/src/main/resources/addresources/values-sv-rSE/strings.xml b/patches/src/main/resources/addresources/values-sv-rSE/strings.xml index 294e44817..a9e5312f6 100644 --- a/patches/src/main/resources/addresources/values-sv-rSE/strings.xml +++ b/patches/src/main/resources/addresources/values-sv-rSE/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced-inställningarna återställda till standard Importerade %d inställningar Importen misslyckades: %s + Visa ikoner för ReVanced-inställningar + Inställningsikoner visas + Ikoner för inställningar visas inte Språket för ReVanced "Översättningar till vissa språk kan vara ofullständiga eller saknas. @@ -610,6 +612,10 @@ Om du ändrar den här inställningen och det inte får effekt kan du försöka Dölj ljudspår Ljudspårsmenyn är dold Ljudspårsmenyn är synlig + + "Ljudspårsmenyn är dold + +För att visa ljudspårsmenyn, ändra \"Spoof video streams\" till iOS TV" Dölj klocka i VR Titta i VR-menyn är dold @@ -1095,6 +1101,7 @@ Om det senare stängs av rekommenderas det att rensa appens data för att förhi This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> Spoof app-versionsmål 19.35.36 - Återställ gamla Shorts-spelarikoner + 19.01.34 - Återställ gamla navigeringsikoner Ställ in startsida diff --git a/patches/src/main/resources/addresources/values-sw-rKE/strings.xml b/patches/src/main/resources/addresources/values-sw-rKE/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-sw-rKE/strings.xml +++ b/patches/src/main/resources/addresources/values-sw-rKE/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-ta-rIN/strings.xml b/patches/src/main/resources/addresources/values-ta-rIN/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-ta-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-ta-rIN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-te-rIN/strings.xml b/patches/src/main/resources/addresources/values-te-rIN/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-te-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-te-rIN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-th-rTH/strings.xml b/patches/src/main/resources/addresources/values-th-rTH/strings.xml index 64c0e343f..398c55ecb 100644 --- a/patches/src/main/resources/addresources/values-th-rTH/strings.xml +++ b/patches/src/main/resources/addresources/values-th-rTH/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" การตั้งค่า ReVanced ถูกตั้งค่าเป็นค่าเริ่มต้น นำเข้าการตั้งค่า %d การนำเข้าล้มเหลว: %s + แสดงไอคอนการตั้งค่า ReVanced + ไอคอนการตั้งค่าจะปรากฏขึ้น + ไม่แสดงไอคอนการตั้งค่า ภาษา ReVanced "การแปลบางภาษาอาจหายไปหรือไม่สมบูรณ์ @@ -608,6 +610,10 @@ Second \"item\" text" ซ่อนแทร็กเสียง เมนูแทร็กเสียงซ่อนอยู่ เมนูแทร็กเสียงแสดงอยู่ + + "เมนูแทร็กเสียงถูกซ่อนอยู่ + +หากต้องการแสดงเมนูแทร็กเสียง ให้เปลี่ยน 'จำลองสตรีมวิดีโอ' เป็น iOS TV" ซ่อนดูใน VR เมนูดูใน VR ซ่อนอยู่ diff --git a/patches/src/main/resources/addresources/values-tr-rTR/strings.xml b/patches/src/main/resources/addresources/values-tr-rTR/strings.xml index 2e218c0ff..13af33db0 100644 --- a/patches/src/main/resources/addresources/values-tr-rTR/strings.xml +++ b/patches/src/main/resources/addresources/values-tr-rTR/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced ayarları varsayılanlara sıfırlandı %d ayar içe aktarıldı İçe aktarılamadı: %s + ReVanced ayar simgelerini göster + Ayar simgeleri gösteriliyor + Ayar simgeleri gösterilmiyor ReVanced dili "Bazı diller için çeviriler eksik veya tamamlanmamış olabilir. @@ -610,6 +612,10 @@ Bu ayarı değiştirmek etkili olmazsa, Gizli moda geçmeyi deneyin." Ses parçası\'nı gizle Ses parçası menüsü gizli Ses parçası menüsü görünür + + "Ses parçası menüsü gizli + +Ses parçası menüsünü göstermek için \"Video akışlarını taklit et\" ayarını iOS TV olarak değiştirin" VR modunda izle\'yi gizle VR modunda izle menüsü gizli diff --git a/patches/src/main/resources/addresources/values-uk-rUA/strings.xml b/patches/src/main/resources/addresources/values-uk-rUA/strings.xml index 4d039d025..ad9e0b6a5 100644 --- a/patches/src/main/resources/addresources/values-uk-rUA/strings.xml +++ b/patches/src/main/resources/addresources/values-uk-rUA/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Налаштування ReVanced скинуто до стандартних Імпортовано %d налаштувань Не вдалося імпортувати: %s + Показувати іконки в налаштуваннях ReVanced + Іконки в налаштуваннях показуються + Іконки в налаштуваннях не показуються Мова налаштувань ReVanced "Переклади для деяких мов можуть бути відсутні або неповні. @@ -610,6 +612,10 @@ Second \"item\" text" Приховати \"Звукова доріжка\" Пункт меню \"Звукова доріжка\" приховано Пункт меню \"Звукова доріжка\" показується + + "Пункт меню \"Звукова доріжка\" приховано + +Для того, щоб пункт меню \"Звукова доріжка\" показувався, змініть клієнт \"Підробки відеопотоків\" на iOS TV" Приховати \"Дивитись у VR\" Пункт меню \"Дивитись у VR\" приховано @@ -810,12 +816,12 @@ Second \"item\" text" Приховано власником Відмітки \"Не подобається\" показуються - Відмітки \"Не подобається\" приховано + Відмітки \"Не подобається\" не показуються Відмітки \"Не подобається\" в Shorts "Відмітки \"Не подобається\" в Shorts показуються Обмеження: Відмітки \"Не подобається\" не можуть показуватися в анонімному режимі" - Відмітки \"Не подобається\" в Shorts приховано + Відмітки \"Не подобається\" в Shorts не показуються Відмітки \"Не подобається\" у відсотках Відмітки \"Не подобається\" показуються у відсотках Відмітки \"Не подобається\" показуються як число @@ -1176,7 +1182,7 @@ Second \"item\" text" Жест горизонтального перетягування вимкнено Приховати кнопки накладання Кнопки накладання приховано - Кнопки накладання відображаються + Кнопки накладання показуються Кнопки розгортання та закриття "Кнопки розгортання та закриття приховано diff --git a/patches/src/main/resources/addresources/values-ur-rIN/strings.xml b/patches/src/main/resources/addresources/values-ur-rIN/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-ur-rIN/strings.xml +++ b/patches/src/main/resources/addresources/values-ur-rIN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-uz-rUZ/strings.xml b/patches/src/main/resources/addresources/values-uz-rUZ/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-uz-rUZ/strings.xml +++ b/patches/src/main/resources/addresources/values-uz-rUZ/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values-vi-rVN/strings.xml b/patches/src/main/resources/addresources/values-vi-rVN/strings.xml index 2f793161d..95f94fa2f 100644 --- a/patches/src/main/resources/addresources/values-vi-rVN/strings.xml +++ b/patches/src/main/resources/addresources/values-vi-rVN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" Khôi phục mặc định cài đặt ReVanced Đã nhập cài đặt %d Nhập thất bại: %s + Hiện biểu tượng cài đặt ReVanced + Các biểu tượng cài đặt được hiện + Các biểu tượng cài đặt không được hiện Ngôn ngữ ReVanced "Dịch cho một số ngôn ngữ có thể bị thiếu hoặc không đầy đủ. @@ -227,8 +229,8 @@ Bạn sẽ không được thông báo về bất kỳ sự kiện bất ngờ n Thẻ nghệ sĩ được ẩn Thẻ nghệ sĩ được hiện Ẩn \'Tóm tắt video do AI tạo\' - Phần tóm tắt video bị ẩn - Phần tóm tắt video đang hiển thị + Phần tóm tắt video được ẩn + Phần tóm tắt video được hiện Ẩn Thuộc tính Phần Địa điểm nổi bật, Trò chơi, Âm nhạc và Người được đề cập bị ẩn Phần Địa điểm nổi bật, Trò chơi, Âm nhạc và Người được đề cập được hiện @@ -269,8 +271,8 @@ Bạn sẽ không được thông báo về bất kỳ sự kiện bất ngờ n Tóm tắt trò chuyện được ẩn Tóm tắt trò chuyện được hiện Ẩn tóm tắt Bình luận AI - Tóm tắt bình luận đã ẩn - Tóm tắt bình luận được hiển thị + Tóm tắt bình luận được ẩn + Tóm tắt bình luận được hiện Ẩn tiêu đề \'Bình luận bởi hội viên\' Tiêu đề Bình luận bởi hội viên được ẩn Tiêu đề Bình luận bởi hội viên được hiện @@ -432,7 +434,7 @@ Tính năng này chỉ khả dụng cho các thiết bị cũ hơn" Bật nhấn để tua Nhấn để tua được bật - Nhấn để tua bị tắt + Nhấn để tua được tắt Bật cử chỉ độ sáng @@ -446,8 +448,8 @@ Tính năng này chỉ khả dụng cho các thiết bị cũ hơn" Điều chỉnh âm lượng bằng cách vuốt dọc ở bên phải màn hình" Vuốt âm lượng được tắt Bật cử chỉ nhấn-để-vuốt - Nhấn-để-vuốt đã bật - Nhấn-để-vuốt đã tắt + Nhấn-để-vuốt được bật + Nhấn-để-vuốt được tắt Bật phản hồi xúc giác Phản hồi xúc giác đã bật Phản hồi xúc giác đã tắt @@ -610,6 +612,10 @@ Nếu việc thay đổi cài đặt này không có hiệu lực, hãy thử ch Ẩn Bản âm thanh Nút bản âm thanh được ẩn Nút bản âm thanh được hiện + + "Menu theo dõi âm thanh bị ẩn + +Để hiển thị menu Theo dõi âm thanh, hãy thay đổi 'Giả mạo luồng video' thành iOS TV" Ẩn Xem trong thực tế ảo Trình đơn xem trong thực tế ảo được ẩn @@ -622,7 +628,7 @@ Nếu việc thay đổi cài đặt này không có hiệu lực, hãy thử ch Ẩn các nút Trước & Tiếp theo Các nút được ẩn Các nút được hiện - Ẩn nút Phát sóng + Ẩn nút truyền Nút Truyền được ẩn Nút Truyền được hiện @@ -1095,7 +1101,7 @@ Nếu sau này tắt đi, bạn nên xóa dữ liệu ứng dụng để tránh This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> Phiên bản giả mạo mục tiêu 19.35.36 - Khôi phục biểu tượng trình phát Shorts cũ - 19.01.34 - Cập nhật lại biểu tượng điều hướng cũ + 19.01.34 - Khôi phục biểu tượng điều hướng cũ Đặt trang bắt đầu @@ -1175,10 +1181,10 @@ Trình phát nhỏ có thể được kéo đến bất kỳ góc nào của mà Trình phát nhỏ có thể được kéo ra khỏi màn hình sang trái hoặc phải" Cử chỉ kéo ngang được tắt Ẩn các nút lớp phủ - Các nút lớp phủ bị ẩn - Các nút lớp phủ được hiển thị + Các nút lớp phủ được ẩn + Các nút lớp phủ được hiện Ẩn các nút mở rộng và đóng - "Nút bị ẩn + "Nút được ẩn Vuốt để mở rộng hoặc đóng" Các nút mở rộng và đóng được hiện diff --git a/patches/src/main/resources/addresources/values-zh-rCN/strings.xml b/patches/src/main/resources/addresources/values-zh-rCN/strings.xml index 2ae3f1256..632e7c87d 100644 --- a/patches/src/main/resources/addresources/values-zh-rCN/strings.xml +++ b/patches/src/main/resources/addresources/values-zh-rCN/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced 设置重置为默认 导入 %d 个设置 导入失败:%s + 显示ReVanced设置图标 + 设置图标已显示 + 未显示设置图标 ReVanced 语言 "某些语言的翻译可能缺失或不完整。 @@ -362,9 +364,9 @@ Second \"item\" text" 隐藏“查看商品”横幅 横幅已隐藏 横幅已显示 - 隐藏片尾画面商店横幅 + 商店横幅已隐藏 隐藏商店横幅 - 显示商店横幅 + 商店横幅已显示 隐藏播放器购物栏 购物展示栏已隐藏 购物展示栏已显示 @@ -610,6 +612,10 @@ Second \"item\" text" 隐藏「音轨」 音轨菜单已隐藏 音轨菜单已显示 + + "音频轨道菜单已隐藏 + +要显示音频轨道菜单,请将“欺骗视频流”更改为 iOS TV" 隐藏「在 VR 模式下观看」 在 VR 模式下观看已隐藏 @@ -877,8 +883,8 @@ Second \"item\" text" 显示片段投票按钮 不显示片段投票按钮 使用方形布局 - 按钮和控件为方形 - 按钮和控件已四舍五入 + 使用方形的按钮和控件 + 使用圆角的按钮和控件 使用紧凑的跳过按钮 跳过按钮样式为最小宽度 @@ -939,7 +945,7 @@ Second \"item\" text" 赞助 付费推广、付费推荐和直接广告。不适用于自我推广或对他们喜欢的公益事业/创作者/网站/产品的免费宣传 非付费/自我推广 - 与 Sponsor 类似,但排除未付款或自我宣传。包括关于商品、捐款或他们与谁合作的信息的部分 + 与赞助类似,但没有报酬或是自我推广。包括与商品、捐款或合作方信息相关的部分 互动提醒 (订阅) 视频中间简短提醒观众来点赞、订阅或关注。 如果片段较长,或是关于某个具体事物,则应分类为自我推广 重点 @@ -1100,6 +1106,7 @@ Second \"item\" text" This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> 伪装应用程序版本为 19.35.36 - 恢复旧的 Shorts 播放器图标 + 19.01.34 - 还原旧的导航图标 设置起始页 diff --git a/patches/src/main/resources/addresources/values-zh-rTW/strings.xml b/patches/src/main/resources/addresources/values-zh-rTW/strings.xml index bed33c7fd..c4b08d8d6 100644 --- a/patches/src/main/resources/addresources/values-zh-rTW/strings.xml +++ b/patches/src/main/resources/addresources/values-zh-rTW/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" 將 ReVanced 設定重設為預設值 已匯入 %d 個設定 無法匯入:%s + 顯示 ReVanced 設定圖示 + 已顯示設定圖示 + 未顯示設定圖示 ReVanced 語言 "部分語言的翻譯可能缺少或不完整。 @@ -430,6 +432,9 @@ Second \"item\" text" 已啟用手勢 + 啟用輕觸以跳轉 + 已啟用輕觸以跳轉 + 已停用輕觸以跳轉 啟用亮度手勢 @@ -442,6 +447,9 @@ Second \"item\" text" 在螢幕右側垂直滑動即可調整音量" 已停用全螢幕音量滑動調整 + 啟用按壓滑動手勢 + 已啟用按壓滑動 + 已停用按壓滑動 啟用震動回饋 已啟用震動回饋 已停用震動回饋 @@ -455,7 +463,7 @@ Second \"item\" text" 覆蓋顯示的毫秒數 滑動覆蓋背景透明度 不透明度值介於 0 到 100 之間 - 滑動透明度必須介於 0 到 100 之間 + 滑動透明度必須介於 0 到 100 之間 滑動幅度臨界點 滑動幅度臨界點 顯示圓形覆蓋 @@ -549,6 +557,7 @@ Second \"item\" text" 停用半透明狀態列 狀態列為不透明 狀態列為不透明或半透明 + 在部分裝置上,啟用這項功能可能會使系統導覽列變成透明。 停用淺色半透明狀態列 淺色模式導覽列為不透明 淺色模式導覽列為不透明或半透明 @@ -603,6 +612,10 @@ Second \"item\" text" 隱藏音軌 已隱藏音軌選單 已顯示音軌選單 + + "已隱藏音軌選單 + +如要顯示音軌選單,請將「欺騙視訊串流」變更為 iOS TV。" 隱藏以 VR 模式觀看 已隱藏以 VR 模式觀看 @@ -700,9 +713,9 @@ Second \"item\" text" 隱藏「使用範本」按鈕 已隱藏「使用範本」按鈕 已顯示「使用範本」按鈕 - 隱藏「即將到來」按鈕 - 已隱藏「即將到來」按鈕 - 已顯示「即將到來」按鈕 + 隱藏「即將直播/首播」按鈕 + 已隱藏「即將直播/首播」按鈕 + 已顯示「即將直播/首播」按鈕 隱藏「綠幕」按鈕 已隱藏「綠幕」按鈕 已顯示「綠幕」按鈕 @@ -790,7 +803,7 @@ Second \"item\" text" 播放器覆蓋透明度 不透明度值介於 0 到 100 之間,其中 0 為完全透明 - 播放器覆蓋層的不透明度必須在 0 到 100 之間 + 播放器覆蓋的不透明度必須在 0 到 100 之間 @@ -1149,6 +1162,7 @@ Second \"item\" text" 現代 1 現代 2 現代 3 + 現代 4 啟用圓角 已將角落設為圓角 已將角落設為方角 @@ -1168,6 +1182,14 @@ Second \"item\" text" 迷你播放器可水平拖曳至螢幕左右兩側之外" 已停用水平拖曳手勢 + 隱藏暫停時顯示的按鈕 + 已隱藏暫停時顯示的按鈕 + 已顯示暫停時顯示的按鈕 + 隱藏展開和關閉按鈕 + "已隱藏按鈕 + +滑動即可展開或關閉" + 已顯示展開和關閉按鈕 隱藏字幕 已隱藏字幕 已顯示字幕 @@ -1177,9 +1199,9 @@ Second \"item\" text" 初始大小 螢幕初始大小(像素) 像素大小必須介於 %1$s 和 %2$s 之間 - 覆蓋層不透明度 + 覆蓋不透明度 不透明度值介於 0 到 100 之間,其中 0 為完全透明 - 迷你播放器覆蓋層的不透明度必須介於 0 到 100 之間 + 迷你播放器覆蓋的不透明度必須介於 0 到 100 之間 啟用漸層載入畫面 @@ -1358,11 +1380,11 @@ Second \"item\" text" 未啟用滑動預覽 - 欺騙影片串流 - 欺騙用戶端影片串流以避免播放問題 - 欺騙影片串流 - 已欺騙影片串流 - "沒有模擬影片串流 + 偽裝影片串流 + 偽裝用戶端影片串流以避免播放問題 + 偽裝影片串流 + 已偽裝影片串流 + "沒有偽裝影片串流 影片播放可能無法正常運作" 關閉此設定可能會導致影片播放發生問題 diff --git a/patches/src/main/resources/addresources/values-zu-rZA/strings.xml b/patches/src/main/resources/addresources/values-zu-rZA/strings.xml index 205a76c4f..c0d8f55c8 100644 --- a/patches/src/main/resources/addresources/values-zu-rZA/strings.xml +++ b/patches/src/main/resources/addresources/values-zu-rZA/strings.xml @@ -4,7 +4,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -107,6 +106,7 @@ Second \"item\" text" This menu only appears for some videos. Translate the name normally if the menu cannot be found. --> + diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index 7df5fd7d5..3d8330396 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -3,7 +3,6 @@ All strings must have a unique path, even if the same string is declared in two different apps. This is because Crowdin requires temporarily flattening this file and removing the and elements. - Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded. Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional. @@ -43,6 +42,9 @@ Second \"item\" text" ReVanced settings reset to default Imported %d settings Import failed: %s + Show ReVanced setting icons + Setting icons are shown + Setting icons are not shown ReVanced language "Translations for some languages may be missing or incomplete. @@ -671,6 +673,10 @@ If changing this setting does not take effect, try switching to Incognito mode." Hide Audio track Audio track menu is hidden Audio track menu is shown + + "Audio track menu is hidden + +To show the Audio track menu, change \'Spoof video streams\' to iOS TV" Hide Watch in VR Watch in VR menu is hidden diff --git a/patches/src/main/resources/copyvideourl/drawable/revanced_yt_copy.xml b/patches/src/main/resources/copyvideourl/drawable/revanced_yt_copy.xml index 2a5bbc872..1a2ab3629 100644 --- a/patches/src/main/resources/copyvideourl/drawable/revanced_yt_copy.xml +++ b/patches/src/main/resources/copyvideourl/drawable/revanced_yt_copy.xml @@ -2,7 +2,6 @@ https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/content_copy/materialsymbolsoutlined/content_copy_wght200gradN25_24px.xml Changes made: Icon has been resized. - Copyright 2022 Google Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,12 +18,11 @@ Copyright 2022 Google --> + android:pathData="M9.73481,16.9424 Q9.13812,16.9424,8.72859,16.5425 Q8.3191,16.1426,8.3191,15.5599 L8.3191,5.88248 Q8.3191,5.29979,8.7286,4.89988 Q9.13812,4.5,9.73481,4.5 L16.8843,4.5 Q17.481,4.5,17.8905,4.89988 Q18.3,5.29979,18.3,5.88248 L18.3,15.5599 Q18.3,16.1426,17.8905,16.5425 Q17.481,16.9424,16.8843,16.9424 Z M9.73481,16.1129 L16.8843,16.1129 Q17.0967,16.1129,17.2736,15.9401 Q17.4506,15.7673,17.4506,15.5599 L17.4506,5.88248 Q17.4506,5.6751,17.2736,5.50229 Q17.0966,5.32949,16.8843,5.32949 L9.73481,5.32949 Q9.52248,5.32949,9.34549,5.50229 Q9.16854,5.6751,9.16854,5.88248 L9.16854,15.5599 Q9.16854,15.7673,9.34549,15.9401 Q9.52248,16.1129,9.73481,16.1129 Z M7.11572,19.5 Q6.51902,19.5,6.1095,19.1001 Q5.7,18.7002,5.7,18.1175 L5.7,7.61058 L6.54944,7.61058 L6.54944,18.1175 Q6.54944,18.3249,6.72639,18.4977 Q6.90336,18.6705,7.11572,18.6705 L15.1146,18.6705 L15.1146,19.5 Z M9.16854,16.1129 L9.16854,5.32949 Z"/> diff --git a/patches/src/main/resources/copyvideourl/drawable/revanced_yt_copy_timestamp.xml b/patches/src/main/resources/copyvideourl/drawable/revanced_yt_copy_timestamp.xml index 7fb608414..de5835b5b 100644 --- a/patches/src/main/resources/copyvideourl/drawable/revanced_yt_copy_timestamp.xml +++ b/patches/src/main/resources/copyvideourl/drawable/revanced_yt_copy_timestamp.xml @@ -1,8 +1,7 @@ + android:pathData="M15.75,12.5 C15.2313,12.5,14.7434,12.5981,14.2871,12.7949 C13.8309,12.9918,13.4351,13.2601,13.0976,13.5976 C12.7601,13.9351,12.4917,14.3308,12.2949,14.7871 C12.098,15.2434,12,15.7313,12,16.25 C12,16.7687,12.0981,17.2566,12.2949,17.7129 C12.4918,18.1691,12.7601,18.5649,13.0976,18.9024 C13.4351,19.2399,13.8308,19.5083,14.2871,19.7051 C14.7434,19.902,15.2313,20,15.75,20 C16.2687,20,16.7566,19.9019,17.2129,19.7051 C17.6691,19.5082,18.0649,19.2399,18.4024,18.9024 C18.7399,18.5649,19.0083,18.1692,19.2051,17.7129 C19.402,17.2566,19.5,16.7687,19.5,16.25 C19.5,15.7313,19.402,15.2434,19.2051,14.7871 C19.0082,14.3309,18.7398,13.9352,18.4023,13.5977 C18.0648,13.2602,17.6691,12.9918,17.2129,12.7949 C16.7566,12.598,16.2687,12.5,15.75,12.5 Z M15.75,13.25 C16.5812,13.25,17.2887,13.5426,17.873,14.127 C18.4574,14.7113,18.75,15.4188,18.75,16.25 C18.75,17.0812,18.4574,17.7887,17.873,18.373 C17.2887,18.9574,16.5812,19.25,15.75,19.25 C14.9188,19.25,14.2113,18.9574,13.627,18.373 C13.0426,17.7887,12.75,17.0812,12.75,16.25 C12.75,15.4188,13.0426,14.7113,13.627,14.127 C14.2113,13.5426,14.9188,13.25,15.75,13.25 Z M15.375,14.375 L15.375,16.4004 L16.9883,18.0117 L17.5117,17.4883 L16.125,16.0996 L16.125,14.375 Z" /> + diff --git a/patches/src/main/resources/downloads/drawable/revanced_yt_download_button.xml b/patches/src/main/resources/downloads/drawable/revanced_yt_download_button.xml index cefb27095..18d0944b0 100644 --- a/patches/src/main/resources/downloads/drawable/revanced_yt_download_button.xml +++ b/patches/src/main/resources/downloads/drawable/revanced_yt_download_button.xml @@ -2,7 +2,6 @@ https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/download/materialsymbolsoutlined/download_wght200gradN25_24px.xml Changes made: Icon has been resized. - Copyright 2022 Google Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +18,6 @@ Copyright 2022 Google --> - + - \ No newline at end of file + diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_00_about.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_00_about.xml new file mode 100644 index 000000000..9bdf13b8d --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_00_about.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_01_ads.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_01_ads.xml new file mode 100644 index 000000000..7bd02f36d --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_01_ads.xml @@ -0,0 +1,27 @@ + + + + + \ No newline at end of file diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_02_alt_thumbnails.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_02_alt_thumbnails.xml new file mode 100644 index 000000000..06a560484 --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_02_alt_thumbnails.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_03_feed.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_03_feed.xml new file mode 100644 index 000000000..d54fe5f1f --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_03_feed.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_04_general.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_04_general.xml new file mode 100644 index 000000000..a2d9eadb7 --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_04_general.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_05_player.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_05_player.xml new file mode 100644 index 000000000..a2af26781 --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_05_player.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_06_shorts.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_06_shorts.xml new file mode 100644 index 000000000..f1383e107 --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_06_shorts.xml @@ -0,0 +1,29 @@ + + + + + + + diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_07_seekbar.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_07_seekbar.xml new file mode 100644 index 000000000..85897e068 --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_07_seekbar.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_08_swipe_controls.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_08_swipe_controls.xml new file mode 100644 index 000000000..431ffee71 --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_08_swipe_controls.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_09_ryd.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_09_ryd.xml new file mode 100644 index 000000000..80da556ca --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_09_ryd.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_10_sb.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_10_sb.xml new file mode 100644 index 000000000..fd9959714 --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_10_sb.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_11_misc.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_11_misc.xml new file mode 100644 index 000000000..455a6d642 --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_11_misc.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/patches/src/main/resources/settings/drawable/revanced_settings_screen_12_video.xml b/patches/src/main/resources/settings/drawable/revanced_settings_screen_12_video.xml new file mode 100644 index 000000000..e51a3314e --- /dev/null +++ b/patches/src/main/resources/settings/drawable/revanced_settings_screen_12_video.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/patches/src/main/resources/settings/xml/revanced_prefs_icons.xml b/patches/src/main/resources/settings/xml/revanced_prefs_icons.xml new file mode 100644 index 000000000..66304a5c0 --- /dev/null +++ b/patches/src/main/resources/settings/xml/revanced_prefs_icons.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/patches/src/main/resources/speedbutton/drawable/revanced_playback_speed_dialog_button.xml b/patches/src/main/resources/speedbutton/drawable/revanced_playback_speed_dialog_button.xml index f8b2d8664..114da2a5d 100644 --- a/patches/src/main/resources/speedbutton/drawable/revanced_playback_speed_dialog_button.xml +++ b/patches/src/main/resources/speedbutton/drawable/revanced_playback_speed_dialog_button.xml @@ -2,7 +2,6 @@ https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/slow_motion_video/materialsymbolsoutlined/slow_motion_video_wght200gradN25_24px.xml Changes made: Icon has been resized. - Copyright 2022 Google Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +18,6 @@ Copyright 2022 Google --> + android:width="30dp" + android:height="30dp" + android:viewportWidth="30" + android:viewportHeight="30"> + android:pathData="M15,17.5 C15.707,17.5,16.2969,17.2578,16.7773,16.7773 C17.2578,16.2969,17.5,15.707,17.5,15 C17.5,14.293,17.2578,13.7031,16.7773,13.2227 C16.2969,12.7422,15.707,12.5,15,12.5 C14.293,12.5,13.7031,12.7422,13.2227,13.2227 C12.7422,13.7031,12.5,14.293,12.5,15 C12.5,15.707,12.7422,16.2969,13.2227,16.7773 C13.7031,17.2578,14.293,17.5,15,17.5 Z M15.0039,26.25 C13.4492,26.25,11.9844,25.9531,10.6172,25.3633 C9.24609,24.7734,8.05469,23.9727,7.04297,22.9609 C6.03125,21.9492,5.22656,20.7578,4.63672,19.3906 C4.04688,18.0234,3.75,16.5586,3.75,15.0039 C3.75,13.4492,4.04688,11.9844,4.63672,10.6172 C5.22656,9.24609,6.02734,8.05469,7.03906,7.04297 C8.05078,6.03125,9.24219,5.22656,10.6094,4.63672 C11.9766,4.04688,13.4414,3.75,14.9961,3.75 C16.5508,3.75,18.0156,4.04688,19.3828,4.63672 C20.7539,5.22656,21.9453,6.02734,22.957,7.03906 C23.9688,8.05078,24.7734,9.24219,25.3633,10.6094 C25.9531,11.9766,26.25,13.4414,26.25,14.9961 C26.25,16.5508,25.9531,18.0156,25.3633,19.3828 C24.7734,20.7539,23.9727,21.9453,22.9609,22.957 C21.9492,23.9688,20.7578,24.7734,19.3906,25.3633 C18.0234,25.9531,16.5586,26.25,15.0039,26.25 Z M15,25 C17.793,25,20.1563,24.0313,22.0938,22.0938 C24.0313,20.1563,25,17.793,25,15 C25,12.207,24.0313,9.84375,22.0938,7.90625 C20.1563,5.96875,17.793,5,15,5 C12.207,5,9.84375,5.96875,7.90625,7.90625 C5.96875,9.84375,5,12.207,5,15 C5,17.793,5.96875,20.1563,7.90625,22.0938 C9.84375,24.0313,12.207,25,15,25 Z M15,15 Z M15,15"/> diff --git a/patches/src/main/resources/sponsorblock/drawable/revanced_sb_backward.xml b/patches/src/main/resources/sponsorblock/drawable/revanced_sb_backward.xml index 495c29d6a..d1c043cec 100644 --- a/patches/src/main/resources/sponsorblock/drawable/revanced_sb_backward.xml +++ b/patches/src/main/resources/sponsorblock/drawable/revanced_sb_backward.xml @@ -1,7 +1,6 @@ + android:width="30dp" + android:height="30dp" + android:viewportWidth="30" + android:viewportHeight="30"> + android:pathData="M24.8789,20.7695 L16.2266,15 L24.8789,9.23047 Z M13.7734,20.7695 L5.12109,15 L13.7734,9.23047 Z M12.5234,15 Z M23.6289,15 Z M12.5234,18.4375 L12.5234,11.5625 L7.35938,15 Z M23.6289,18.4375 L23.6289,11.5625 L18.4648,15 Z M23.6289,18.4375"/> diff --git a/patches/src/main/resources/sponsorblock/drawable/revanced_sb_compare.xml b/patches/src/main/resources/sponsorblock/drawable/revanced_sb_compare.xml index 04f3ecc1b..3ea5a9a21 100644 --- a/patches/src/main/resources/sponsorblock/drawable/revanced_sb_compare.xml +++ b/patches/src/main/resources/sponsorblock/drawable/revanced_sb_compare.xml @@ -1,7 +1,6 @@ + android:width="30dp" + android:height="30dp" + android:viewportWidth="30" + android:viewportHeight="30"> + android:pathData="M13.75,27.7891 L13.75,25 L7.01953,25 C6.44531,25,5.96484,24.8086,5.57813,24.4219 C5.19141,24.0352,5,23.5547,5,22.9805 L5,7.01953 C5,6.44531,5.19141,5.96484,5.57813,5.57813 C5.96484,5.19141,6.44531,5,7.01953,5 L13.75,5 L13.75,2.21094 L15,2.21094 L15,27.7891 Z M6.25,22.5 L13.75,22.5 L13.75,13.5078 Z M17.5,25 L17.5,15 L23.75,22.5 L23.75,7.01953 C23.75,6.82813,23.668,6.65234,23.5078,6.49219 C23.3477,6.33203,23.1719,6.25,22.9805,6.25 L17.5,6.25 L17.5,5 L22.9805,5 C23.5547,5,24.0352,5.19141,24.4219,5.57813 C24.8086,5.96484,25,6.44531,25,7.01953 L25,22.9805 C25,23.5547,24.8086,24.0352,24.4219,24.4219 C24.0352,24.8086,23.5547,25,22.9805,25 Z M17.5,25"/> diff --git a/patches/src/main/resources/sponsorblock/drawable/revanced_sb_edit.xml b/patches/src/main/resources/sponsorblock/drawable/revanced_sb_edit.xml index 1e1d8e378..97d77ecfe 100644 --- a/patches/src/main/resources/sponsorblock/drawable/revanced_sb_edit.xml +++ b/patches/src/main/resources/sponsorblock/drawable/revanced_sb_edit.xml @@ -1,7 +1,6 @@ + android:width="30dp" + android:height="30dp" + android:viewportWidth="30" + android:viewportHeight="30"> + android:pathData="M6.25,23.75 L7.62109,23.75 L20.9961,10.3789 L19.6211,9.00391 L6.25,22.3789 Z M5,25 L5,21.8516 L21.4766,5.35938 C21.6055,5.24219,21.7461,5.15625,21.8984,5.09375 C22.0547,5.03125,22.2148,5,22.3828,5 C22.5508,5,22.7148,5.02734,22.8711,5.07813 C23.0313,5.13281,23.1758,5.22656,23.3086,5.36719 L24.6406,6.70703 C24.7813,6.83984,24.875,6.98438,24.9258,7.14453 C24.9766,7.30469,25,7.46094,25,7.62109 C25,7.78906,24.9727,7.95313,24.9141,8.10547 C24.8555,8.26172,24.7656,8.40234,24.6406,8.53125 L8.14844,25 Z M23.7734,7.61719 L22.3828,6.22656 Z M20.2969,9.70313 L19.6211,9.00391 L20.9961,10.3789 Z M20.2969,9.70313"/> diff --git a/patches/src/main/resources/sponsorblock/drawable/revanced_sb_forward.xml b/patches/src/main/resources/sponsorblock/drawable/revanced_sb_forward.xml index c7e550b55..5abc73702 100644 --- a/patches/src/main/resources/sponsorblock/drawable/revanced_sb_forward.xml +++ b/patches/src/main/resources/sponsorblock/drawable/revanced_sb_forward.xml @@ -1,7 +1,6 @@ + android:width="30dp" + android:height="30dp" + android:viewportWidth="30" + android:viewportHeight="30"> + android:pathData="M5.12109,20.7695 L5.12109,9.23047 L13.7734,15 Z M16.2266,20.7695 L16.2266,9.23047 L24.8789,15 Z M6.37109,15 Z M17.4766,15 Z M6.37109,18.4375 L11.5352,15 L6.37109,11.5625 Z M17.4766,18.4375 L22.6406,15 L17.4766,11.5625 Z M17.4766,18.4375"/> diff --git a/patches/src/main/resources/sponsorblock/drawable/revanced_sb_logo.xml b/patches/src/main/resources/sponsorblock/drawable/revanced_sb_logo.xml index 79383e677..6b55b0da9 100644 --- a/patches/src/main/resources/sponsorblock/drawable/revanced_sb_logo.xml +++ b/patches/src/main/resources/sponsorblock/drawable/revanced_sb_logo.xml @@ -1,14 +1,11 @@ + android:width="32dp" + android:height="32dp" + android:viewportWidth="32" + android:viewportHeight="32"> + android:pathData="M15.4375,25.332 L15.4375,13.3281 L12.1602,16.6055 L11.3516,15.8086 L16,11.1602 L20.6484,15.8086 L19.8398,16.6055 L16.5625,13.3281 L16.5625,25.332 Z M6.66797,12.082 L6.66797,8.61719 C6.66797,8.07031,6.85547,7.60938,7.23047,7.23047 C7.60938,6.85547,8.07031,6.66797,8.61719,6.66797 L23.3828,6.66797 C23.9297,6.66797,24.3906,6.85547,24.7695,7.23047 C25.1445,7.60938,25.332,8.07031,25.332,8.61719 L25.332,12.082 L24.2031,12.082 L24.2031,8.61719 C24.2031,8.41016,24.1211,8.22266,23.9492,8.05078 C23.7773,7.87891,23.5898,7.79688,23.3828,7.79688 L8.61719,7.79688 C8.41016,7.79688,8.22266,7.87891,8.05078,8.05078 C7.87891,8.22266,7.79688,8.41016,7.79688,8.61719 L7.79688,12.082 Z M6.66797,12.082"/> diff --git a/patches/src/main/resources/sponsorblock/drawable/revanced_sb_voting.xml b/patches/src/main/resources/sponsorblock/drawable/revanced_sb_voting.xml index d7b0cc470..5c62953f4 100644 --- a/patches/src/main/resources/sponsorblock/drawable/revanced_sb_voting.xml +++ b/patches/src/main/resources/sponsorblock/drawable/revanced_sb_voting.xml @@ -2,7 +2,6 @@ https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/thumbs_up_down/materialsymbolsoutlined/thumbs_up_down_wght300gradN25_24px.xml Changes made: Icon has been resized. - Copyright 2022 Google Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,12 +18,11 @@ Copyright 2022 Google --> + android:pathData="M3.35592,13.078 Q2.78443,13.078,2.3922,12.6903 Q2,12.3025,2,11.722 L2,6.56351 Q2,6.41555,2.06101,6.27218 Q2.12205,6.1288,2.24535,6.0055 L6.25085,2 L6.59321,2.34236 Q6.67361,2.42442,6.73002,2.53108 Q6.78645,2.63775,6.78645,2.72542 L6.78645,2.85423 L6.02035,6.16271 L10.3263,6.16271 Q10.8502,6.16271,11.1979,6.51356 Q11.5457,6.86441,11.5457,7.38304 L11.5457,7.65478 Q11.5457,7.79152,11.5237,7.89286 Q11.5017,7.99417,11.4576,8.1017 L9.53559,12.5492 Q9.42135,12.8012,9.21194,12.9396 Q9.00255,13.078,8.73444,13.078 Z M8.7695,12.2644 L10.7322,7.67796 L10.7322,7.51863 Q10.7322,7.28983,10.5796,7.13304 Q10.4271,6.97627,10.1898,6.97627 L5.04068,6.97627 L5.75931,3.65171 L2.81356,6.60086 L2.81356,11.722 Q2.81356,11.9593,2.9661,12.1118 Q3.11864,12.2643,3.35592,12.2643 Z M17.7491,22 L17.4037,21.6569 Q17.3295,21.5814,17.2715,21.4747 Q17.2135,21.368,17.2135,21.2741 L17.2135,21.1458 L17.9796,17.8373 L13.6736,17.8373 Q13.1497,17.8373,12.802,17.4907 Q12.4542,17.1441,12.4542,16.617 L12.4542,16.3528 Q12.4542,16.217,12.4762,16.117 Q12.4982,16.017,12.5423,15.8984 L14.4643,11.4509 Q14.5762,11.2085,14.7838,11.0653 Q14.9914,10.9221,15.2643,10.9221 L20.644,10.9221 Q21.2155,10.9221,21.6077,11.3143 Q22,11.7065,22,12.278 L22,17.4373 Q22,17.5967,21.936,17.7404 Q21.872,17.8841,21.7525,17.9967 Z M15.2305,11.7356 L13.2678,16.322 L13.2678,16.4813 Q13.2678,16.7186,13.4203,16.8711 Q13.5728,17.0236,13.8101,17.0236 L18.9592,17.0236 L18.2406,20.3566 L21.1864,17.4075 L21.1864,12.2778 Q21.1864,12.049,21.0339,11.8922 Q20.8814,11.7354,20.6441,11.7354 Z M2.81356,11.722 L2.81356,6.60086 L2.81356,12.2644 Z M21.1864,12.278 L21.1864,17.4077 L21.1864,11.7357 Z"/> diff --git a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_auto.xml b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_auto.xml index 252a97982..151ebcc4e 100644 --- a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_auto.xml +++ b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_auto.xml @@ -20,8 +20,7 @@ Copyright 2022 Google android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="24"> diff --git a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_full.xml b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_full.xml index c0d45293c..3734e8e39 100644 --- a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_full.xml +++ b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_full.xml @@ -21,8 +21,7 @@ Copyright 2022 Google android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="24"> diff --git a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_high.xml b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_high.xml index fe45b31be..73440402e 100644 --- a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_high.xml +++ b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_high.xml @@ -21,8 +21,7 @@ Copyright 2022 Google android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="24"> diff --git a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_low.xml b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_low.xml index 66010e253..2b330d4a6 100644 --- a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_low.xml +++ b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_low.xml @@ -21,8 +21,7 @@ Copyright 2022 Google android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="24"> diff --git a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_medium.xml b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_medium.xml index fc191d25e..af67c5ec7 100644 --- a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_medium.xml +++ b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_brightness_medium.xml @@ -20,8 +20,7 @@ Copyright 2022 Google android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="24"> diff --git a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_high.xml b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_high.xml index 5dfb76a0e..a135d4198 100644 --- a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_high.xml +++ b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_high.xml @@ -21,8 +21,7 @@ Copyright 2022 Google android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="24"> diff --git a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_low.xml b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_low.xml index e52b1fe4a..fcbbd9982 100644 --- a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_low.xml +++ b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_low.xml @@ -21,8 +21,7 @@ Copyright 2022 Google android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="24"> diff --git a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_mute.xml b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_mute.xml index 59b9e72e4..f6dd48bb2 100644 --- a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_mute.xml +++ b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_mute.xml @@ -20,8 +20,7 @@ Copyright 2022 Google android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="24"> diff --git a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_normal.xml b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_normal.xml index 602cd2a64..bb3d4005a 100644 --- a/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_normal.xml +++ b/patches/src/main/resources/swipecontrols/drawable/revanced_ic_sc_volume_normal.xml @@ -21,8 +21,7 @@ Copyright 2022 Google android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="24">