mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-16 06:02:27 +01:00
Compare commits
31 Commits
v5.19.0-de
...
v5.20.0-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86f867fe97 | ||
|
|
0f687ecfd3 | ||
|
|
6c8b7d09c1 | ||
|
|
3d6958f157 | ||
|
|
43d7cc7374 | ||
|
|
5ebd449f1f | ||
|
|
346a061df8 | ||
|
|
13e490a422 | ||
|
|
b4e8540bbc | ||
|
|
775c1baec2 | ||
|
|
9419fb8ec4 | ||
|
|
c510931eb0 | ||
|
|
7160699384 | ||
|
|
9db67a6eb2 | ||
|
|
e684d87dd3 | ||
|
|
2d1752a1eb | ||
|
|
c9ff7092fe | ||
|
|
d451bc6d6d | ||
|
|
741fd36872 | ||
|
|
517f8cf59a | ||
|
|
b78fb24435 | ||
|
|
a3faccb21b | ||
|
|
5f0fddc122 | ||
|
|
854a18ff72 | ||
|
|
b994a16bdc | ||
|
|
f68d06dbf3 | ||
|
|
04c6a2e5f4 | ||
|
|
e6ae55fa99 | ||
|
|
fb62474ff4 | ||
|
|
e084f01fd0 | ||
|
|
d573386e0f |
130
CHANGELOG.md
130
CHANGELOG.md
@@ -1,3 +1,133 @@
|
|||||||
|
# [5.20.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.6...v5.20.0-dev.7) (2025-04-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Spotify:** Fix login by replacing `Spoof signature` patch with new `Spoof package info` patch ([#4794](https://github.com/ReVanced/revanced-patches/issues/4794)) ([d639151](https://github.com/ReVanced/revanced-patches/commit/d639151641352ce651037b17fb65bd58953cd51c))
|
||||||
|
|
||||||
|
# [5.20.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.5...v5.20.0-dev.6) (2025-04-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Duolingo - Hide ads:** Support lastest app release ([#4790](https://github.com/ReVanced/revanced-patches/issues/4790)) ([215fccb](https://github.com/ReVanced/revanced-patches/commit/215fccbaf2fdd54251c46cbda106029eb304996b))
|
||||||
|
|
||||||
|
# [5.20.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.4...v5.20.0-dev.5) (2025-04-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Swipe controls:** Add option to change volume swipe sensitivity (step size) ([#4557](https://github.com/ReVanced/revanced-patches/issues/4557)) ([8957325](https://github.com/ReVanced/revanced-patches/commit/8957325d78eb42e087c4c1ff0abedb2146aa4423))
|
||||||
|
|
||||||
|
# [5.20.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.3...v5.20.0-dev.4) (2025-04-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Spotify - Unlock Spotify Premium:** Remove premium restriction for 'Spotify Connect' ([#4782](https://github.com/ReVanced/revanced-patches/issues/4782)) ([50f5b1a](https://github.com/ReVanced/revanced-patches/commit/50f5b1ac54372542d76e87626f00ddefb54da125))
|
||||||
|
|
||||||
|
# [5.20.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.2...v5.20.0-dev.3) (2025-04-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Remove background playback restrictions:** Restore PiP button functionality after screen is unlocked ([6837348](https://github.com/ReVanced/revanced-patches/commit/6837348c45156d6743a63fef8b6e045087afbda8))
|
||||||
|
|
||||||
|
# [5.20.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.1...v5.20.0-dev.2) (2025-04-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Spotify - Custom theme:** Add option to use unmodified player background gradient ([#4741](https://github.com/ReVanced/revanced-patches/issues/4741)) ([0ee3693](https://github.com/ReVanced/revanced-patches/commit/0ee36939f43f325afca37119db1cf1af3b63be27))
|
||||||
|
|
||||||
|
# [5.20.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.19.1...v5.20.0-dev.1) (2025-04-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add `Set target SDK version 34` patch (Disable edge-to-edge display) ([#4780](https://github.com/ReVanced/revanced-patches/issues/4780)) ([dcf6178](https://github.com/ReVanced/revanced-patches/commit/dcf6178f19f86dd1b57d54c855b8c47b086dd33a))
|
||||||
|
|
||||||
|
## [5.19.1](https://github.com/ReVanced/revanced-patches/compare/v5.19.0...v5.19.1) (2025-04-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Google Photos:** Restore patching with ReVanced Manager ([#4773](https://github.com/ReVanced/revanced-patches/issues/4773)) ([3e18e86](https://github.com/ReVanced/revanced-patches/commit/3e18e868bbd9fd0600fe81a7fe8767b4bd89a00e))
|
||||||
|
* **Spotify:** Restore patching with ReVanced Manager ([#4769](https://github.com/ReVanced/revanced-patches/issues/4769)) ([89d44da](https://github.com/ReVanced/revanced-patches/commit/89d44da171c3f56f13112d1d82bc4ea4a56c7c06))
|
||||||
|
|
||||||
|
## [5.19.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.19.1-dev.1...v5.19.1-dev.2) (2025-04-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Google Photos:** Restore patching with ReVanced Manager ([#4773](https://github.com/ReVanced/revanced-patches/issues/4773)) ([3e18e86](https://github.com/ReVanced/revanced-patches/commit/3e18e868bbd9fd0600fe81a7fe8767b4bd89a00e))
|
||||||
|
|
||||||
|
## [5.19.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.19.0...v5.19.1-dev.1) (2025-04-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Spotify:** Restore patching with ReVanced Manager ([#4769](https://github.com/ReVanced/revanced-patches/issues/4769)) ([89d44da](https://github.com/ReVanced/revanced-patches/commit/89d44da171c3f56f13112d1d82bc4ea4a56c7c06))
|
||||||
|
|
||||||
|
# [5.19.0](https://github.com/ReVanced/revanced-patches/compare/v5.18.0...v5.19.0) (2025-04-12)
|
||||||
|
|
||||||
|
|
||||||
|
### 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))
|
||||||
|
* **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))
|
||||||
|
* **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))
|
||||||
|
* **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))
|
||||||
|
* **Spotify:** Remove ads sections from home ([#4722](https://github.com/ReVanced/revanced-patches/issues/4722)) ([0b9a5e7](https://github.com/ReVanced/revanced-patches/commit/0b9a5e7f89a89d971762b3539166d4f145111481))
|
||||||
|
* **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))
|
||||||
|
* **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))
|
||||||
|
* **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))
|
||||||
|
* **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))
|
||||||
|
* **YouTube - Return YouTube Dislike:** Correctly update label after disliking a Short with 20.07 ([0bb3e32](https://github.com/ReVanced/revanced-patches/commit/0bb3e32244fa10809aee5c4e549f77ed4054537e))
|
||||||
|
* **YouTube - Return YouTube Dislike:** Fix inconsistent label after disliking a Short ([ea92a2e](https://github.com/ReVanced/revanced-patches/commit/ea92a2e36c7aab3bd115f7d0ec40467179485b32))
|
||||||
|
* **YouTube - Seekbar:** Correctly hide the feed seekbar with target 20.07 ([ddc6e4c](https://github.com/ReVanced/revanced-patches/commit/ddc6e4c34fe35fa34bd859bf34e25645a23dbdc9))
|
||||||
|
* **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))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Angulus:** Add `Hide ads` patch ([#4604](https://github.com/ReVanced/revanced-patches/issues/4604)) ([87c86b5](https://github.com/ReVanced/revanced-patches/commit/87c86b53a91b0054ac892a3f02bbe7bf83bbf813))
|
||||||
|
* **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))
|
||||||
|
* **Photomath:** Support latest version ([#4672](https://github.com/ReVanced/revanced-patches/issues/4672)) ([8e16483](https://github.com/ReVanced/revanced-patches/commit/8e1648322948151e4565fb0d86e0f37d0a02d73f))
|
||||||
|
* **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))
|
||||||
|
* **Spotify:** Add `Check environment` patch ([#4765](https://github.com/ReVanced/revanced-patches/issues/4765)) ([6d7101c](https://github.com/ReVanced/revanced-patches/commit/6d7101cb2e546e01a934eff9cad1264367aeafe3))
|
||||||
|
* **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))
|
||||||
|
* **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))
|
||||||
|
* **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.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)
|
# [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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -319,6 +319,7 @@ public class Settings extends BaseSettings {
|
|||||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||||
public static final IntegerSetting SWIPE_MAGNITUDE_THRESHOLD = new IntegerSetting("revanced_swipe_threshold", 30, true,
|
public static final IntegerSetting SWIPE_MAGNITUDE_THRESHOLD = new IntegerSetting("revanced_swipe_threshold", 30, true,
|
||||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||||
|
public static final IntegerSetting SWIPE_VOLUME_SENSITIVITY = new IntegerSetting("revanced_swipe_volume_sensitivity", 1, true, parent(SWIPE_VOLUME));
|
||||||
public static final BooleanSetting SWIPE_SHOW_CIRCULAR_OVERLAY = new BooleanSetting("revanced_swipe_show_circular_overlay", FALSE, true,
|
public static final BooleanSetting SWIPE_SHOW_CIRCULAR_OVERLAY = new BooleanSetting("revanced_swipe_show_circular_overlay", FALSE, true,
|
||||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||||
public static final BooleanSetting SWIPE_OVERLAY_MINIMAL_STYLE = new BooleanSetting("revanced_swipe_overlay_minimal_style", FALSE, true,
|
public static final BooleanSetting SWIPE_OVERLAY_MINIMAL_STYLE = new BooleanSetting("revanced_swipe_overlay_minimal_style", FALSE, true,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package app.revanced.extension.youtube.swipecontrols
|
package app.revanced.extension.youtube.swipecontrols
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import app.revanced.extension.shared.StringRef.str
|
import app.revanced.extension.shared.StringRef.str
|
||||||
import app.revanced.extension.shared.Utils
|
import app.revanced.extension.shared.Utils
|
||||||
@@ -9,12 +8,8 @@ import app.revanced.extension.youtube.shared.PlayerType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* provider for configuration for volume and brightness swipe controls
|
* provider for configuration for volume and brightness swipe controls
|
||||||
*
|
|
||||||
* @param context the context to create in
|
|
||||||
*/
|
*/
|
||||||
class SwipeControlsConfigurationProvider(
|
class SwipeControlsConfigurationProvider {
|
||||||
private val context: Context,
|
|
||||||
) {
|
|
||||||
//region swipe enable
|
//region swipe enable
|
||||||
/**
|
/**
|
||||||
* should swipe controls be enabled? (global setting)
|
* should swipe controls be enabled? (global setting)
|
||||||
@@ -60,6 +55,23 @@ class SwipeControlsConfigurationProvider(
|
|||||||
*/
|
*/
|
||||||
val swipeMagnitudeThreshold: Int
|
val swipeMagnitudeThreshold: Int
|
||||||
get() = Settings.SWIPE_MAGNITUDE_THRESHOLD.get()
|
get() = Settings.SWIPE_MAGNITUDE_THRESHOLD.get()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How much volume will change by single swipe.
|
||||||
|
* If it is set to 0, it will reset to the default value because 0 would disable swiping.
|
||||||
|
* */
|
||||||
|
val volumeSwipeSensitivity: Int
|
||||||
|
get() {
|
||||||
|
val sensitivity = Settings.SWIPE_VOLUME_SENSITIVITY.get()
|
||||||
|
|
||||||
|
if (sensitivity < 1) {
|
||||||
|
Settings.SWIPE_VOLUME_SENSITIVITY.resetToDefault()
|
||||||
|
|
||||||
|
return Settings.SWIPE_VOLUME_SENSITIVITY.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
return sensitivity
|
||||||
|
}
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
//region overlay adjustments
|
//region overlay adjustments
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ class SwipeControlsHostActivity : Activity() {
|
|||||||
private fun initialize() {
|
private fun initialize() {
|
||||||
// create controllers
|
// create controllers
|
||||||
printDebug { "initializing swipe controls controllers" }
|
printDebug { "initializing swipe controls controllers" }
|
||||||
config = SwipeControlsConfigurationProvider(this)
|
config = SwipeControlsConfigurationProvider()
|
||||||
keys = VolumeKeysController(this)
|
keys = VolumeKeysController(this)
|
||||||
audio = createAudioController()
|
audio = createAudioController()
|
||||||
screen = createScreenController()
|
screen = createScreenController()
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class VolumeKeysController(
|
|||||||
private fun handleVolumeKeyEvent(event: KeyEvent, volumeUp: Boolean): Boolean {
|
private fun handleVolumeKeyEvent(event: KeyEvent, volumeUp: Boolean): Boolean {
|
||||||
if (event.action == KeyEvent.ACTION_DOWN) {
|
if (event.action == KeyEvent.ACTION_DOWN) {
|
||||||
controller.audio?.apply {
|
controller.audio?.apply {
|
||||||
volume += if (volumeUp) 1 else -1
|
volume += controller.config.volumeSwipeSensitivity * if (volumeUp) 1 else -1
|
||||||
controller.overlay.onVolumeChanged(volume, maxVolume)
|
controller.overlay.onVolumeChanged(volume, maxVolume)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ abstract class BaseGestureController(
|
|||||||
controller.overlay,
|
controller.overlay,
|
||||||
10,
|
10,
|
||||||
1,
|
1,
|
||||||
|
controller.config.volumeSwipeSensitivity,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ interface VolumeAndBrightnessScroller {
|
|||||||
* @param overlayController overlay controller instance
|
* @param overlayController overlay controller instance
|
||||||
* @param volumeDistance unit distance for volume scrolling, in dp
|
* @param volumeDistance unit distance for volume scrolling, in dp
|
||||||
* @param brightnessDistance unit distance for brightness scrolling, in dp
|
* @param brightnessDistance unit distance for brightness scrolling, in dp
|
||||||
|
* @param volumeSwipeSensitivity how much volume will change by single swipe
|
||||||
*/
|
*/
|
||||||
class VolumeAndBrightnessScrollerImpl(
|
class VolumeAndBrightnessScrollerImpl(
|
||||||
context: Context,
|
context: Context,
|
||||||
@@ -49,6 +50,7 @@ class VolumeAndBrightnessScrollerImpl(
|
|||||||
private val overlayController: SwipeControlsOverlay,
|
private val overlayController: SwipeControlsOverlay,
|
||||||
volumeDistance: Int = 10,
|
volumeDistance: Int = 10,
|
||||||
brightnessDistance: Int = 1,
|
brightnessDistance: Int = 1,
|
||||||
|
private val volumeSwipeSensitivity: Int,
|
||||||
) : VolumeAndBrightnessScroller {
|
) : VolumeAndBrightnessScroller {
|
||||||
|
|
||||||
// region volume
|
// region volume
|
||||||
@@ -60,7 +62,7 @@ class VolumeAndBrightnessScrollerImpl(
|
|||||||
),
|
),
|
||||||
) { _, _, direction ->
|
) { _, _, direction ->
|
||||||
volumeController?.run {
|
volumeController?.run {
|
||||||
volume += direction
|
volume += direction * volumeSwipeSensitivity
|
||||||
overlayController.onVolumeChanged(volume, maxVolume)
|
overlayController.onVolumeChanged(volume, maxVolume)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class SwipeControlsOverlayLayout(
|
|||||||
private val config: SwipeControlsConfigurationProvider,
|
private val config: SwipeControlsConfigurationProvider,
|
||||||
) : RelativeLayout(context), SwipeControlsOverlay {
|
) : RelativeLayout(context), SwipeControlsOverlay {
|
||||||
|
|
||||||
constructor(context: Context) : this(context, SwipeControlsConfigurationProvider(context))
|
constructor(context: Context) : this(context, SwipeControlsConfigurationProvider())
|
||||||
|
|
||||||
// Drawable icons for brightness and volume
|
// Drawable icons for brightness and volume
|
||||||
private val autoBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_auto")
|
private val autoBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_auto")
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
|
|||||||
org.gradle.parallel = true
|
org.gradle.parallel = true
|
||||||
android.useAndroidX = true
|
android.useAndroidX = true
|
||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 5.19.0-dev.13
|
version = 5.20.0-dev.7
|
||||||
|
|||||||
@@ -108,6 +108,10 @@ public final class app/revanced/patches/all/misc/shortcut/sharetargets/RemoveSha
|
|||||||
public static final fun getRemoveShareTargetsPatch ()Lapp/revanced/patcher/patch/ResourcePatch;
|
public static final fun getRemoveShareTargetsPatch ()Lapp/revanced/patcher/patch/ResourcePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/all/misc/targetSdk/SetTargetSdkVersion34Kt {
|
||||||
|
public static final fun getSetTargetSdkVersion34 ()Lapp/revanced/patcher/patch/ResourcePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract interface class app/revanced/patches/all/misc/transformation/IMethodCall {
|
public abstract interface class app/revanced/patches/all/misc/transformation/IMethodCall {
|
||||||
public abstract fun getDefinedClassName ()Ljava/lang/String;
|
public abstract fun getDefinedClassName ()Ljava/lang/String;
|
||||||
public abstract fun getMethodName ()Ljava/lang/String;
|
public abstract fun getMethodName ()Ljava/lang/String;
|
||||||
@@ -568,7 +572,9 @@ public final class app/revanced/patches/shared/misc/extension/ExtensionHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/shared/misc/extension/SharedExtensionPatchKt {
|
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 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 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 (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;
|
public static final fun sharedExtensionPatch ([Lapp/revanced/patches/shared/misc/extension/ExtensionHook;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
@@ -836,6 +842,10 @@ public final class app/revanced/patches/spotify/misc/extension/ExtensionPatchKt
|
|||||||
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatchKt {
|
||||||
|
public static final fun getSpoofPackageInfoPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/spotify/misc/fix/SpoofSignaturePatchKt {
|
public final class app/revanced/patches/spotify/misc/fix/SpoofSignaturePatchKt {
|
||||||
public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
@@ -1519,7 +1529,11 @@ public final class app/revanced/patches/yuka/misc/unlockpremium/UnlockPremiumPat
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/util/BytecodeUtilsKt {
|
public final class app/revanced/util/BytecodeUtilsKt {
|
||||||
|
public static final fun addInstructionsAtControlFlowLabel (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/String;)V
|
||||||
|
public static final fun containsLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;D)Z
|
||||||
|
public static final fun containsLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;F)Z
|
||||||
public static final fun containsLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
|
public static final fun containsLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
|
||||||
|
public static final fun findFreeRegister (Lcom/android/tools/smali/dexlib2/iface/Method;I[I)I
|
||||||
public static final fun findInstructionIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)Ljava/util/List;
|
public static final fun findInstructionIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)Ljava/util/List;
|
||||||
public static final fun findInstructionIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
|
public static final fun findInstructionIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
|
||||||
public static final fun findInstructionIndicesReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)Ljava/util/List;
|
public static final fun findInstructionIndicesReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)Ljava/util/List;
|
||||||
@@ -1546,9 +1560,17 @@ public final class app/revanced/util/BytecodeUtilsKt {
|
|||||||
public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;)I
|
public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;)I
|
||||||
public static synthetic fun indexOfFirstInstructionReversedOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I
|
public static synthetic fun indexOfFirstInstructionReversedOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I
|
||||||
public static synthetic fun indexOfFirstInstructionReversedOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)I
|
public static synthetic fun indexOfFirstInstructionReversedOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)I
|
||||||
|
public static final fun indexOfFirstLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;D)I
|
||||||
|
public static final fun indexOfFirstLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;F)I
|
||||||
public static final fun indexOfFirstLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
public static final fun indexOfFirstLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
||||||
|
public static final fun indexOfFirstLiteralInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;D)I
|
||||||
|
public static final fun indexOfFirstLiteralInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;F)I
|
||||||
public static final fun indexOfFirstLiteralInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
public static final fun indexOfFirstLiteralInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
||||||
|
public static final fun indexOfFirstLiteralInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;D)I
|
||||||
|
public static final fun indexOfFirstLiteralInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;F)I
|
||||||
public static final fun indexOfFirstLiteralInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
public static final fun indexOfFirstLiteralInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
||||||
|
public static final fun indexOfFirstLiteralInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;D)I
|
||||||
|
public static final fun indexOfFirstLiteralInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;F)I
|
||||||
public static final fun indexOfFirstLiteralInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
public static final fun indexOfFirstLiteralInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
||||||
public static final fun indexOfFirstResourceId (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
|
public static final fun indexOfFirstResourceId (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
|
||||||
public static final fun indexOfFirstResourceIdOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
|
public static final fun indexOfFirstResourceIdOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package app.revanced.patches.all.misc.targetSdk
|
||||||
|
|
||||||
|
import app.revanced.patcher.patch.resourcePatch
|
||||||
|
import app.revanced.util.getNode
|
||||||
|
import org.w3c.dom.Element
|
||||||
|
import java.util.logging.Logger
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val setTargetSdkVersion34 = resourcePatch(
|
||||||
|
name = "Set target SDK version 34",
|
||||||
|
description = "Changes the target SDK to version 34 (Android 14). " +
|
||||||
|
"For devices running Android 15+, this will disable edge-to-edge display.",
|
||||||
|
use = false,
|
||||||
|
) {
|
||||||
|
execute {
|
||||||
|
val targetSdkOverride = 34 // Android 14.
|
||||||
|
|
||||||
|
document("AndroidManifest.xml").use { document ->
|
||||||
|
fun getLogger() = Logger.getLogger(this::class.java.name)
|
||||||
|
|
||||||
|
// Ideally, the override should only be applied if the existing target is higher.
|
||||||
|
// But since ApkTool does not add targetSdkVersion to the decompiled AndroidManifest,
|
||||||
|
// there is no way to check targetSdkVersion. Instead, check compileSdkVersion and print a warning.
|
||||||
|
try {
|
||||||
|
val manifestElement = document.getNode("manifest") as Element
|
||||||
|
val compileSdkVersion = Integer.parseInt(
|
||||||
|
manifestElement.getAttribute("android:compileSdkVersion")
|
||||||
|
)
|
||||||
|
if (compileSdkVersion <= targetSdkOverride) {
|
||||||
|
getLogger().warning(
|
||||||
|
"This app does not appear to use a target SDK above $targetSdkOverride: " +
|
||||||
|
"(compileSdkVersion: $compileSdkVersion)"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (_: Exception) {
|
||||||
|
getLogger().warning("Could not check compileSdkVersion")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change targetSdkVersion to override value.
|
||||||
|
document.getElementsByTagName("manifest").item(0).let {
|
||||||
|
var element = it.ownerDocument.createElement("uses-sdk")
|
||||||
|
element.setAttribute("android:targetSdkVersion", targetSdkOverride.toString())
|
||||||
|
|
||||||
|
it.appendChild(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,8 @@ internal val initializeMonetizationDebugSettingsFingerprint = fingerprint {
|
|||||||
"Z", // useDebugBilling
|
"Z", // useDebugBilling
|
||||||
"Z", // showManageSubscriptions
|
"Z", // showManageSubscriptions
|
||||||
"Z", // alwaysShowSuperAds
|
"Z", // alwaysShowSuperAds
|
||||||
"Lcom/duolingo/debug/FamilyQuestOverride;",
|
// matches "Lcom/duolingo/debug/FamilyQuestOverride;" or "Lcom/duolingo/data/debug/monetization/FamilyQuestOverride;"
|
||||||
|
"Lcom/duolingo/",
|
||||||
)
|
)
|
||||||
opcodes(Opcode.IPUT_BOOLEAN)
|
opcodes(Opcode.IPUT_BOOLEAN)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,4 +27,5 @@ private fun gmsCoreSupportResourcePatch(
|
|||||||
toPackageName = REVANCED_MAGAZINES_PACKAGE_NAME,
|
toPackageName = REVANCED_MAGAZINES_PACKAGE_NAME,
|
||||||
spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a666",
|
spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a666",
|
||||||
gmsCoreVendorGroupIdOption = gmsCoreVendorGroupIdOption,
|
gmsCoreVendorGroupIdOption = gmsCoreVendorGroupIdOption,
|
||||||
|
addStringResources = false,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ private fun gmsCoreSupportResourcePatch(
|
|||||||
) = app.revanced.patches.shared.misc.gms.gmsCoreSupportResourcePatch(
|
) = app.revanced.patches.shared.misc.gms.gmsCoreSupportResourcePatch(
|
||||||
fromPackageName = PHOTOS_PACKAGE_NAME,
|
fromPackageName = PHOTOS_PACKAGE_NAME,
|
||||||
toPackageName = REVANCED_PHOTOS_PACKAGE_NAME,
|
toPackageName = REVANCED_PHOTOS_PACKAGE_NAME,
|
||||||
|
addStringResources = false,
|
||||||
spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a600",
|
spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a600",
|
||||||
gmsCoreVendorGroupIdOption = gmsCoreVendorGroupIdOption,
|
gmsCoreVendorGroupIdOption = gmsCoreVendorGroupIdOption,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,23 +3,28 @@ package app.revanced.patches.googlephotos.misc.preferences
|
|||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
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
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Deprecated("This patch no longer works and this code will soon be deleted")
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val restoreHiddenBackUpWhileChargingTogglePatch = bytecodePatch(
|
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 {
|
execute {
|
||||||
// Patches 'backup_prefs_had_backup_only_when_charging_enabled' to always be true.
|
// Patches 'backup_prefs_had_backup_only_when_charging_enabled' to always be true.
|
||||||
val chargingPrefStringIndex = backupPreferencesFingerprint.stringMatches!!.first().index
|
backupPreferencesFingerprint.let {
|
||||||
backupPreferencesFingerprint.method.apply {
|
it.method.apply {
|
||||||
// Get the register of move-result.
|
val index = indexOfFirstInstructionOrThrow(
|
||||||
val resultRegister = getInstruction<OneRegisterInstruction>(chargingPrefStringIndex + 2).registerA
|
it.stringMatches!!.first().index,
|
||||||
// Insert const after move-result to override register as true.
|
Opcode.MOVE_RESULT
|
||||||
addInstruction(chargingPrefStringIndex + 3, "const/4 v$resultRegister, 0x1")
|
)
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
|
addInstruction(index + 1, "const/4 v$register, 0x1")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,11 +41,12 @@ fun sharedExtensionPatch(
|
|||||||
|
|
||||||
execute {
|
execute {
|
||||||
if (classes.none { EXTENSION_CLASS_DESCRIPTOR == it.type }) {
|
if (classes.none { EXTENSION_CLASS_DESCRIPTOR == it.type }) {
|
||||||
throw PatchException(
|
throw PatchException("Shared extension is not available. This patch can not succeed without it.")
|
||||||
"Shared extension has not been merged yet. This patch can not succeed without merging 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) }
|
hooks.forEach { hook -> hook(EXTENSION_CLASS_DESCRIPTOR) }
|
||||||
|
|
||||||
// Modify Utils method to include the patches release version.
|
// Modify Utils method to include the patches release version.
|
||||||
@@ -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(
|
fun extensionHook(
|
||||||
insertIndexResolver: ((Method) -> Int) = { 0 },
|
insertIndexResolver: ((Method) -> Int) = { 0 },
|
||||||
contextRegisterResolver: (Method) -> String = { "p0" },
|
contextRegisterResolver: (Method) -> String = { "p0" },
|
||||||
fingerprintBuilderBlock: FingerprintBuilder.() -> Unit,
|
fingerprintBuilderBlock: FingerprintBuilder.() -> Unit,
|
||||||
) = ExtensionHook(fingerprint(block = fingerprintBuilderBlock), insertIndexResolver, contextRegisterResolver)
|
) = extensionHook(insertIndexResolver, contextRegisterResolver, fingerprint(block = fingerprintBuilderBlock))
|
||||||
|
|||||||
@@ -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.builder.instruction.BuilderInstruction21c
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
|
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.iface.reference.StringReference
|
||||||
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableStringReference
|
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableStringReference
|
||||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
@@ -110,8 +109,7 @@ fun gmsCoreSupportPatch(
|
|||||||
|
|
||||||
// region Collection of transformations that are applied to all strings.
|
// region Collection of transformations that are applied to all strings.
|
||||||
|
|
||||||
fun commonTransform(referencedString: String): String? =
|
fun commonTransform(referencedString: String): String? = when (referencedString) {
|
||||||
when (referencedString) {
|
|
||||||
"com.google",
|
"com.google",
|
||||||
"com.google.android.gms",
|
"com.google.android.gms",
|
||||||
in PERMISSIONS,
|
in PERMISSIONS,
|
||||||
@@ -205,16 +203,8 @@ fun gmsCoreSupportPatch(
|
|||||||
|
|
||||||
// Verify GmsCore is installed and whitelisted for power optimizations and background usage.
|
// Verify GmsCore is installed and whitelisted for power optimizations and background usage.
|
||||||
mainActivityOnCreateFingerprint.method.apply {
|
mainActivityOnCreateFingerprint.method.apply {
|
||||||
// Temporary fix for patches with an extension patch that hook the onCreate method as well.
|
|
||||||
val setContextIndex = indexOfFirstInstruction {
|
|
||||||
val reference = getReference<MethodReference>() ?: 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(
|
addInstructions(
|
||||||
if (setContextIndex < 0) 0 else setContextIndex + 1,
|
0,
|
||||||
"invoke-static/range { p0 .. p0 }, Lapp/revanced/extension/shared/GmsCoreSupport;->" +
|
"invoke-static/range { p0 .. p0 }, Lapp/revanced/extension/shared/GmsCoreSupport;->" +
|
||||||
"checkGmsCore(Landroid/app/Activity;)V",
|
"checkGmsCore(Landroid/app/Activity;)V",
|
||||||
)
|
)
|
||||||
@@ -510,13 +500,44 @@ private object Constants {
|
|||||||
* @param executeBlock The additional execution block of the patch.
|
* @param executeBlock The additional execution block of the patch.
|
||||||
* @param block The additional block to build the patch.
|
* @param block The additional block to build the patch.
|
||||||
*/
|
*/
|
||||||
fun gmsCoreSupportResourcePatch(
|
fun gmsCoreSupportResourcePatch( // This is here only for binary compatibility.
|
||||||
fromPackageName: String,
|
fromPackageName: String,
|
||||||
toPackageName: String,
|
toPackageName: String,
|
||||||
spoofedPackageSignature: String,
|
spoofedPackageSignature: String,
|
||||||
gmsCoreVendorGroupIdOption: Option<String>,
|
gmsCoreVendorGroupIdOption: Option<String>,
|
||||||
executeBlock: ResourcePatchContext.() -> Unit = {},
|
executeBlock: ResourcePatchContext.() -> Unit = {},
|
||||||
block: ResourcePatchBuilder.() -> Unit = {},
|
block: ResourcePatchBuilder.() -> Unit = {},
|
||||||
|
) = gmsCoreSupportResourcePatch(
|
||||||
|
fromPackageName,
|
||||||
|
toPackageName,
|
||||||
|
spoofedPackageSignature,
|
||||||
|
gmsCoreVendorGroupIdOption,
|
||||||
|
true,
|
||||||
|
executeBlock,
|
||||||
|
block
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract resource patch that allows Google apps to run without root and under a different package name
|
||||||
|
* by using GmsCore instead of Google Play Services.
|
||||||
|
*
|
||||||
|
* @param fromPackageName The package name of the original app.
|
||||||
|
* @param toPackageName The package name to fall back to if no custom package name is specified in patch options.
|
||||||
|
* @param spoofedPackageSignature The signature of the package to spoof to.
|
||||||
|
* @param gmsCoreVendorGroupIdOption The option to get the vendor group ID of GmsCore.
|
||||||
|
* @param addStringResources If the GmsCore shared strings should be added to the patched app.
|
||||||
|
* @param executeBlock The additional execution block of the patch.
|
||||||
|
* @param block The additional block to build the patch.
|
||||||
|
*/
|
||||||
|
// TODO: On the next major release make this public and delete the public overloaded constructor.
|
||||||
|
internal fun gmsCoreSupportResourcePatch(
|
||||||
|
fromPackageName: String,
|
||||||
|
toPackageName: String,
|
||||||
|
spoofedPackageSignature: String,
|
||||||
|
gmsCoreVendorGroupIdOption: Option<String>,
|
||||||
|
addStringResources: Boolean = true,
|
||||||
|
executeBlock: ResourcePatchContext.() -> Unit = {},
|
||||||
|
block: ResourcePatchBuilder.() -> Unit = {},
|
||||||
) = resourcePatch {
|
) = resourcePatch {
|
||||||
dependsOn(
|
dependsOn(
|
||||||
changePackageNamePatch,
|
changePackageNamePatch,
|
||||||
@@ -526,7 +547,10 @@ fun gmsCoreSupportResourcePatch(
|
|||||||
val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption
|
val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
|
// Some patches don't use shared String resources so there's no need to add them.
|
||||||
|
if (addStringResources) {
|
||||||
addResources("shared", "misc.gms.gmsCoreSupportResourcePatch")
|
addResources("shared", "misc.gms.gmsCoreSupportResourcePatch")
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add metadata to manifest to support spoofing the package name and signature of GmsCore.
|
* Add metadata to manifest to support spoofing the package name and signature of GmsCore.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import app.revanced.util.findFreeRegister
|
|||||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.insertFeatureFlagBooleanOverride
|
import app.revanced.util.insertLiteralOverride
|
||||||
import app.revanced.util.returnEarly
|
import app.revanced.util.returnEarly
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
@@ -235,7 +235,7 @@ fun spoofVideoStreamsPatch(
|
|||||||
|
|
||||||
// region Fix iOS livestream current time.
|
// region Fix iOS livestream current time.
|
||||||
|
|
||||||
hlsCurrentTimeFingerprint.method.insertFeatureFlagBooleanOverride(
|
hlsCurrentTimeFingerprint.method.insertLiteralOverride(
|
||||||
HLS_CURRENT_TIME_FEATURE_FLAG,
|
HLS_CURRENT_TIME_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->fixHLSCurrentTime(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->fixHLSCurrentTime(Z)Z"
|
||||||
)
|
)
|
||||||
@@ -245,21 +245,21 @@ fun spoofVideoStreamsPatch(
|
|||||||
// region turn off stream config replacement feature flag.
|
// region turn off stream config replacement feature flag.
|
||||||
|
|
||||||
if (fixMediaFetchHotConfigChanges()) {
|
if (fixMediaFetchHotConfigChanges()) {
|
||||||
mediaFetchHotConfigFingerprint.method.insertFeatureFlagBooleanOverride(
|
mediaFetchHotConfigFingerprint.method.insertLiteralOverride(
|
||||||
MEDIA_FETCH_HOT_CONFIG_FEATURE_FLAG,
|
MEDIA_FETCH_HOT_CONFIG_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fixMediaFetchHotConfigAlternativeChanges()) {
|
if (fixMediaFetchHotConfigAlternativeChanges()) {
|
||||||
mediaFetchHotConfigAlternativeFingerprint.method.insertFeatureFlagBooleanOverride(
|
mediaFetchHotConfigAlternativeFingerprint.method.insertLiteralOverride(
|
||||||
MEDIA_FETCH_HOT_CONFIG_ALTERNATIVE_FEATURE_FLAG,
|
MEDIA_FETCH_HOT_CONFIG_ALTERNATIVE_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fixParsePlaybackResponseFeatureFlag()) {
|
if (fixParsePlaybackResponseFeatureFlag()) {
|
||||||
playbackStartDescriptorFeatureFlagFingerprint.method.insertFeatureFlagBooleanOverride(
|
playbackStartDescriptorFeatureFlagFingerprint.method.insertLiteralOverride(
|
||||||
PLAYBACK_START_CHECK_ENDPOINT_USED_FEATURE_FLAG,
|
PLAYBACK_START_CHECK_ENDPOINT_USED_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->usePlaybackStartFeatureFlag(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->usePlaybackStartFeatureFlag(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
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<OneRegisterInstruction>(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<FieldReference>()!!.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!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,133 @@
|
|||||||
package app.revanced.patches.spotify.layout.theme
|
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.booleanOption
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patcher.patch.resourcePatch
|
import app.revanced.patcher.patch.resourcePatch
|
||||||
|
import app.revanced.patcher.patch.stringOption
|
||||||
|
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
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
|
|
||||||
|
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/spotify/layout/theme/CustomThemePatch;"
|
||||||
|
|
||||||
|
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 overridePlayerGradientColor = booleanOption(
|
||||||
|
key = "overridePlayerGradientColor",
|
||||||
|
default = false,
|
||||||
|
title = "Override player gradient color",
|
||||||
|
description = "Apply primary background color to the player gradient color, which changes dynamically with the song.",
|
||||||
|
required = false
|
||||||
|
)
|
||||||
|
|
||||||
|
internal val spotifyBackgroundColorSecondary = stringOption(
|
||||||
|
key = "backgroundColorSecondary",
|
||||||
|
default = "#FF121212",
|
||||||
|
title = "Secondary background color",
|
||||||
|
description =
|
||||||
|
"The secondary background color. (e.g. playlist list in home, player artist, song 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,
|
||||||
|
)
|
||||||
|
|
||||||
|
private val customThemeBytecodePatch = bytecodePatch {
|
||||||
|
dependsOn(sharedExtensionPatch)
|
||||||
|
|
||||||
|
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<OneRegisterInstruction>(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.originalMethod) {
|
||||||
|
// "Encore" colors are referenced right before the value of POSITIVE_INFINITY is returned.
|
||||||
|
// Begin the instruction find using the index of where POSITIVE_INFINITY is set into the register.
|
||||||
|
val positiveInfinityIndex = indexOfFirstLiteralInstructionOrThrow(
|
||||||
|
Float.POSITIVE_INFINITY
|
||||||
|
)
|
||||||
|
val encoreColorsFieldReferenceIndex = indexOfFirstInstructionReversedOrThrow(
|
||||||
|
positiveInfinityIndex,
|
||||||
|
Opcode.SGET_OBJECT
|
||||||
|
)
|
||||||
|
|
||||||
|
getInstruction(encoreColorsFieldReferenceIndex)
|
||||||
|
.getReference<FieldReference>()!!.definingClass
|
||||||
|
}
|
||||||
|
|
||||||
|
val encoreColorsConstructorFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
|
||||||
|
custom { method, classDef ->
|
||||||
|
classDef.type == encoreColorsClassName &&
|
||||||
|
method.containsLiteralInstruction(PLAYLIST_BACKGROUND_COLOR_LITERAL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val backgroundColor by spotifyBackgroundColor
|
||||||
|
val backgroundColorSecondary by spotifyBackgroundColorSecondary
|
||||||
|
|
||||||
|
encoreColorsConstructorFingerprint.method.apply {
|
||||||
|
addColorChangeInstructions(PLAYLIST_BACKGROUND_COLOR_LITERAL, backgroundColor!!)
|
||||||
|
addColorChangeInstructions(SHARE_MENU_BACKGROUND_COLOR_LITERAL, backgroundColorSecondary!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
homeCategoryPillColorsFingerprint.method.addColorChangeInstructions(
|
||||||
|
HOME_CATEGORY_PILL_COLOR_LITERAL,
|
||||||
|
backgroundColorSecondary!!
|
||||||
|
)
|
||||||
|
|
||||||
|
settingsHeaderColorFingerprint.method.addColorChangeInstructions(
|
||||||
|
SETTINGS_HEADER_COLOR_LITERAL,
|
||||||
|
backgroundColorSecondary!!
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val customThemePatch = resourcePatch(
|
val customThemePatch = resourcePatch(
|
||||||
name = "Custom theme",
|
name = "Custom theme",
|
||||||
@@ -11,9 +136,10 @@ val customThemePatch = resourcePatch(
|
|||||||
) {
|
) {
|
||||||
compatibleWith("com.spotify.music")
|
compatibleWith("com.spotify.music")
|
||||||
|
|
||||||
dependsOn(customThemeByteCodePatch)
|
dependsOn(customThemeBytecodePatch)
|
||||||
|
|
||||||
val backgroundColor by spotifyBackgroundColor()
|
val backgroundColor by spotifyBackgroundColor()
|
||||||
|
val overridePlayerGradientColor by overridePlayerGradientColor()
|
||||||
val backgroundColorSecondary by spotifyBackgroundColorSecondary()
|
val backgroundColorSecondary by spotifyBackgroundColorSecondary()
|
||||||
val accentColor by spotifyAccentColor()
|
val accentColor by spotifyAccentColor()
|
||||||
val accentColorPressed by spotifyAccentColorPressed()
|
val accentColorPressed by spotifyAccentColorPressed()
|
||||||
@@ -25,31 +151,39 @@ val customThemePatch = resourcePatch(
|
|||||||
val childNodes = resourcesNode.childNodes
|
val childNodes = resourcesNode.childNodes
|
||||||
for (i in 0 until childNodes.length) {
|
for (i in 0 until childNodes.length) {
|
||||||
val node = childNodes.item(i) as? Element ?: continue
|
val node = childNodes.item(i) as? Element ?: continue
|
||||||
|
val name = node.getAttribute("name")
|
||||||
|
|
||||||
node.textContent = when (node.getAttribute("name")) {
|
// Skip overriding song/player gradient start color if the option is disabled.
|
||||||
// Gradient next to user photo and "All" in home page
|
// Gradient end color should be themed regardless to allow the gradient to connect with
|
||||||
|
// our primary background color.
|
||||||
|
if (name == "bg_gradient_start_color" && !overridePlayerGradientColor!!) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
node.textContent = when (name) {
|
||||||
|
// Gradient next to user photo and "All" in home page.
|
||||||
"dark_base_background_base",
|
"dark_base_background_base",
|
||||||
// Main background
|
// Main background.
|
||||||
"gray_7",
|
"gray_7",
|
||||||
// Left sidebar background in tablet mode
|
// Left sidebar background in tablet mode.
|
||||||
"gray_10",
|
"gray_10",
|
||||||
// Add account, Settings and privacy, View Profile left sidebar background
|
// "Add account", "Settings and privacy", "View Profile" left sidebar background.
|
||||||
"dark_base_background_elevated_base",
|
"dark_base_background_elevated_base",
|
||||||
// Song/player background
|
// Song/player gradient start/end color.
|
||||||
"bg_gradient_start_color", "bg_gradient_end_color",
|
"bg_gradient_start_color", "bg_gradient_end_color",
|
||||||
// Login screen
|
// Login screen background and gradient start.
|
||||||
"sthlm_blk", "sthlm_blk_grad_start", "stockholm_black",
|
"sthlm_blk", "sthlm_blk_grad_start",
|
||||||
// Misc
|
// Misc.
|
||||||
"image_placeholder_color",
|
"image_placeholder_color",
|
||||||
-> backgroundColor
|
-> backgroundColor
|
||||||
|
|
||||||
// Track credits, merch in song player
|
// Track credits, merch background in song player.
|
||||||
"track_credits_card_bg", "benefit_list_default_color", "merch_card_background",
|
"track_credits_card_bg", "benefit_list_default_color", "merch_card_background",
|
||||||
// Playlist list background in home page
|
// Playlist list background in home page.
|
||||||
"opacity_white_10",
|
"opacity_white_10",
|
||||||
// About artist background in song player
|
// "About the artist" background in song player.
|
||||||
"gray_15",
|
"gray_15",
|
||||||
// What's New pills background
|
// "What's New" pills background.
|
||||||
"dark_base_background_tinted_highlight"
|
"dark_base_background_tinted_highlight"
|
||||||
-> backgroundColorSecondary
|
-> backgroundColorSecondary
|
||||||
|
|
||||||
@@ -59,5 +193,13 @@ val customThemePatch = resourcePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Login screen gradient.
|
||||||
|
document("res/drawable/start_screen_gradient.xml").use { document ->
|
||||||
|
val gradientNode = document.getElementsByTagName("gradient").item(0) as Element
|
||||||
|
|
||||||
|
gradientNode.setAttribute("android:startColor", backgroundColor)
|
||||||
|
gradientNode.setAttribute("android:endColor", backgroundColor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import app.revanced.util.containsLiteralInstruction
|
|||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
internal val encoreThemeFingerprint = fingerprint {
|
internal val encoreThemeFingerprint = fingerprint {
|
||||||
strings("Encore theme was not provided.") // Partial string match.
|
strings("No EncoreLayoutTheme provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
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 PLAYLIST_BACKGROUND_COLOR_LITERAL = 0xFF121212
|
||||||
internal const val SHARE_MENU_BACKGROUND_COLOR_LITERAL = 0xFF1F1F1F
|
internal const val SHARE_MENU_BACKGROUND_COLOR_LITERAL = 0xFF1F1F1F
|
||||||
|
internal const val HOME_CATEGORY_PILL_COLOR_LITERAL = 0xFF333333
|
||||||
|
internal const val SETTINGS_HEADER_COLOR_LITERAL = 0xFF282828
|
||||||
|
|
||||||
internal val homeCategoryPillColorsFingerprint = fingerprint{
|
internal val homeCategoryPillColorsFingerprint = fingerprint{
|
||||||
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
|
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
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,
|
|
||||||
)
|
|
||||||
@@ -35,6 +35,27 @@ internal val contextMenuExperimentsFingerprint = fingerprint {
|
|||||||
strings("remove_ads_upsell_enabled")
|
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 {
|
internal val homeSectionFingerprint = fingerprint {
|
||||||
custom { _, classDef -> classDef.endsWith("homeapi/proto/Section;") }
|
custom { _, classDef -> classDef.endsWith("homeapi/proto/Section;") }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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",
|
||||||
|
)
|
||||||
@@ -2,6 +2,7 @@ package app.revanced.patches.spotify.misc.extension
|
|||||||
|
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patches.shared.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.shared.misc.extension.sharedExtensionPatch
|
||||||
|
import app.revanced.patches.spotify.shared.SPOTIFY_MAIN_ACTIVITY_LEGACY
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If patching a legacy 8.x target. This may also be set if patching slightly older/newer app targets,
|
* If patching a legacy 8.x target. This may also be set if patching slightly older/newer app targets,
|
||||||
@@ -11,10 +12,10 @@ import app.revanced.patches.shared.misc.extension.sharedExtensionPatch
|
|||||||
internal var IS_SPOTIFY_LEGACY_APP_TARGET = false
|
internal var IS_SPOTIFY_LEGACY_APP_TARGET = false
|
||||||
|
|
||||||
val sharedExtensionPatch = bytecodePatch {
|
val sharedExtensionPatch = bytecodePatch {
|
||||||
dependsOn(sharedExtensionPatch("spotify", spotifyMainActivityOnCreate))
|
dependsOn(sharedExtensionPatch("spotify", mainActivityOnCreateHook))
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
IS_SPOTIFY_LEGACY_APP_TARGET = spotifyMainActivityOnCreate.fingerprint
|
IS_SPOTIFY_LEGACY_APP_TARGET = mainActivityOnCreateHook.fingerprint
|
||||||
.originalClassDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY
|
.originalClassDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
package app.revanced.patches.spotify.misc.extension
|
package app.revanced.patches.spotify.misc.extension
|
||||||
|
|
||||||
import app.revanced.patches.shared.misc.extension.extensionHook
|
import app.revanced.patches.shared.misc.extension.extensionHook
|
||||||
|
import app.revanced.patches.spotify.shared.mainActivityOnCreateFingerprint
|
||||||
|
|
||||||
private const val SPOTIFY_MAIN_ACTIVITY = "Lcom/spotify/music/SpotifyMainActivity;"
|
internal val mainActivityOnCreateHook = extensionHook(fingerprint = mainActivityOnCreateFingerprint)
|
||||||
|
|
||||||
/**
|
|
||||||
* Main activity of target 8.6.98.900.
|
|
||||||
*/
|
|
||||||
internal const val SPOTIFY_MAIN_ACTIVITY_LEGACY = "Lcom/spotify/music/MainActivity;"
|
|
||||||
|
|
||||||
internal val spotifyMainActivityOnCreate = extensionHook {
|
|
||||||
custom { method, classDef ->
|
|
||||||
method.name == "onCreate" && (classDef.type == SPOTIFY_MAIN_ACTIVITY
|
|
||||||
|| classDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,4 +2,16 @@ package app.revanced.patches.spotify.misc.fix
|
|||||||
|
|
||||||
import app.revanced.patcher.fingerprint
|
import app.revanced.patcher.fingerprint
|
||||||
|
|
||||||
internal val getAppSignatureFingerprint = fingerprint { strings("Failed to get the application signatures") }
|
internal val getPackageInfoFingerprint = fingerprint {
|
||||||
|
strings(
|
||||||
|
"Failed to get the application signatures",
|
||||||
|
"Failed to get installer package"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val getPackageInfoLegacyFingerprint = fingerprint {
|
||||||
|
strings(
|
||||||
|
"Failed to get the application signatures"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package app.revanced.patches.spotify.misc.fix
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.spotify.misc.extension.IS_SPOTIFY_LEGACY_APP_TARGET
|
||||||
|
import app.revanced.util.addInstructionsAtControlFlowLabel
|
||||||
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
|
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val spoofPackageInfoPatch = bytecodePatch(
|
||||||
|
name = "Spoof package info",
|
||||||
|
description = "Spoofs the package info of the app to fix various functions of the app.",
|
||||||
|
) {
|
||||||
|
compatibleWith("com.spotify.music")
|
||||||
|
|
||||||
|
execute {
|
||||||
|
val getPackageInfoFingerprint = if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
||||||
|
getPackageInfoLegacyFingerprint
|
||||||
|
} else {
|
||||||
|
getPackageInfoFingerprint
|
||||||
|
}
|
||||||
|
|
||||||
|
getPackageInfoFingerprint.method.apply {
|
||||||
|
val stringMatches = getPackageInfoFingerprint.stringMatches!!
|
||||||
|
|
||||||
|
// region Spoof signature.
|
||||||
|
|
||||||
|
val failedToGetSignaturesStringIndex = stringMatches.first().index
|
||||||
|
|
||||||
|
val concatSignaturesIndex = indexOfFirstInstructionReversedOrThrow(
|
||||||
|
failedToGetSignaturesStringIndex,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
)
|
||||||
|
|
||||||
|
val signatureRegister = getInstruction<OneRegisterInstruction>(concatSignaturesIndex).registerA
|
||||||
|
val expectedSignature = "d6a6dced4a85f24204bf9505ccc1fce114cadb32"
|
||||||
|
|
||||||
|
replaceInstruction(concatSignaturesIndex, "const-string v$signatureRegister, \"$expectedSignature\"")
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Spoof installer name.
|
||||||
|
|
||||||
|
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
||||||
|
// Installer name is not used in the legacy app target.
|
||||||
|
return@execute
|
||||||
|
}
|
||||||
|
|
||||||
|
val expectedInstallerName = "com.android.vending"
|
||||||
|
|
||||||
|
val returnInstallerNameIndex = indexOfFirstInstructionOrThrow(
|
||||||
|
stringMatches.last().index,
|
||||||
|
Opcode.RETURN_OBJECT
|
||||||
|
)
|
||||||
|
|
||||||
|
val installerNameRegister = getInstruction<OneRegisterInstruction>(
|
||||||
|
returnInstallerNameIndex
|
||||||
|
).registerA
|
||||||
|
|
||||||
|
addInstructionsAtControlFlowLabel(
|
||||||
|
returnInstallerNameIndex,
|
||||||
|
"const-string v$installerNameRegister, \"$expectedInstallerName\""
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,33 +1,13 @@
|
|||||||
package app.revanced.patches.spotify.misc.fix
|
package app.revanced.patches.spotify.misc.fix
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|
||||||
|
|
||||||
|
@Deprecated("Superseded by spoofPackageInfoPatch", ReplaceWith("spoofPackageInfoPatch"))
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val spoofSignaturePatch = bytecodePatch(
|
val spoofSignaturePatch = bytecodePatch(
|
||||||
name = "Spoof signature",
|
description = "Spoofs the signature of the app fix various functions of the app.",
|
||||||
description = "Spoofs the signature of the app to fix various functions of the app.",
|
|
||||||
) {
|
) {
|
||||||
compatibleWith("com.spotify.music")
|
compatibleWith("com.spotify.music")
|
||||||
|
|
||||||
execute {
|
dependsOn(spoofPackageInfoPatch)
|
||||||
getAppSignatureFingerprint.method.apply {
|
|
||||||
val failedToGetSignaturesStringMatch = getAppSignatureFingerprint.stringMatches!!.first()
|
|
||||||
|
|
||||||
val concatSignaturesIndex = indexOfFirstInstructionReversedOrThrow(
|
|
||||||
failedToGetSignaturesStringMatch.index,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
|
||||||
)
|
|
||||||
|
|
||||||
val register = getInstruction<OneRegisterInstruction>(concatSignaturesIndex).registerA
|
|
||||||
|
|
||||||
val expectedSignature = "d6a6dced4a85f24204bf9505ccc1fce114cadb32"
|
|
||||||
|
|
||||||
replaceInstruction(concatSignaturesIndex, "const-string v$register, \"$expectedSignature\"")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,6 +47,7 @@ private val swipeControlsResourcePatch = resourcePatch {
|
|||||||
TextPreference("revanced_swipe_overlay_background_opacity", inputType = InputType.NUMBER),
|
TextPreference("revanced_swipe_overlay_background_opacity", inputType = InputType.NUMBER),
|
||||||
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
|
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
|
||||||
TextPreference("revanced_swipe_threshold", inputType = InputType.NUMBER),
|
TextPreference("revanced_swipe_threshold", inputType = InputType.NUMBER),
|
||||||
|
TextPreference("revanced_swipe_volume_sensitivity", inputType = InputType.NUMBER),
|
||||||
)
|
)
|
||||||
|
|
||||||
copyResources(
|
copyResources(
|
||||||
@@ -117,7 +118,7 @@ val swipeControlsPatch = bytecodePatch(
|
|||||||
// region patch to enable/disable swipe to change video.
|
// region patch to enable/disable swipe to change video.
|
||||||
|
|
||||||
if (is_19_43_or_greater) {
|
if (is_19_43_or_greater) {
|
||||||
swipeChangeVideoFingerprint.method.insertFeatureFlagBooleanOverride(
|
swipeChangeVideoFingerprint.method.insertLiteralOverride(
|
||||||
SWIPE_CHANGE_VIDEO_FEATURE_FLAG,
|
SWIPE_CHANGE_VIDEO_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->allowSwipeChangeVideo(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->allowSwipeChangeVideo(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
|||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.insertFeatureFlagBooleanOverride
|
import app.revanced.util.insertLiteralOverride
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
@@ -119,17 +119,17 @@ val navigationButtonsPatch = bytecodePatch(
|
|||||||
|
|
||||||
// Force on/off translucent effect on status bar and navigation buttons.
|
// Force on/off translucent effect on status bar and navigation buttons.
|
||||||
if (is_19_25_or_greater) {
|
if (is_19_25_or_greater) {
|
||||||
translucentNavigationStatusBarFeatureFlagFingerprint.method.insertFeatureFlagBooleanOverride(
|
translucentNavigationStatusBarFeatureFlagFingerprint.method.insertLiteralOverride(
|
||||||
TRANSLUCENT_NAVIGATION_STATUS_BAR_FEATURE_FLAG,
|
TRANSLUCENT_NAVIGATION_STATUS_BAR_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationStatusBar(Z)Z",
|
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationStatusBar(Z)Z",
|
||||||
)
|
)
|
||||||
|
|
||||||
translucentNavigationButtonsFeatureFlagFingerprint.method.insertFeatureFlagBooleanOverride(
|
translucentNavigationButtonsFeatureFlagFingerprint.method.insertLiteralOverride(
|
||||||
TRANSLUCENT_NAVIGATION_BUTTONS_FEATURE_FLAG,
|
TRANSLUCENT_NAVIGATION_BUTTONS_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
|
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
|
||||||
)
|
)
|
||||||
|
|
||||||
translucentNavigationButtonsSystemFeatureFlagFingerprint.method.insertFeatureFlagBooleanOverride(
|
translucentNavigationButtonsSystemFeatureFlagFingerprint.method.insertLiteralOverride(
|
||||||
TRANSLUCENT_NAVIGATION_BUTTONS_SYSTEM_FEATURE_FLAG,
|
TRANSLUCENT_NAVIGATION_BUTTONS_SYSTEM_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
|
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
fun Fingerprint.insertMiniplayerFeatureFlagBooleanOverride(
|
fun Fingerprint.insertMiniplayerFeatureFlagBooleanOverride(
|
||||||
literal: Long,
|
literal: Long,
|
||||||
extensionMethod: String,
|
extensionMethod: String,
|
||||||
) = method.insertFeatureFlagBooleanOverride(
|
) = method.insertLiteralOverride(
|
||||||
literal,
|
literal,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->$extensionMethod(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->$extensionMethod(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patches.youtube.layout.shortsplayer.openShortsInRegularPlaye
|
|||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
|
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
|
||||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||||
import app.revanced.util.insertFeatureFlagBooleanOverride
|
import app.revanced.util.insertLiteralOverride
|
||||||
|
|
||||||
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
"Lapp/revanced/extension/youtube/patches/OpenVideosFullscreenHookPatch;"
|
"Lapp/revanced/extension/youtube/patches/OpenVideosFullscreenHookPatch;"
|
||||||
@@ -24,7 +24,7 @@ internal val openVideosFullscreenHookPatch = bytecodePatch {
|
|||||||
return@execute
|
return@execute
|
||||||
}
|
}
|
||||||
|
|
||||||
openVideosFullscreenPortraitFingerprint.method.insertFeatureFlagBooleanOverride(
|
openVideosFullscreenPortraitFingerprint.method.insertLiteralOverride(
|
||||||
OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG,
|
OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->openVideoFullscreenPortrait(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->openVideoFullscreenPortrait(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -28,9 +28,8 @@ import app.revanced.util.findElementByAttributeValueOrThrow
|
|||||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
|
||||||
import app.revanced.util.inputStreamFromBundledResource
|
import app.revanced.util.inputStreamFromBundledResource
|
||||||
import app.revanced.util.insertFeatureFlagBooleanOverride
|
import app.revanced.util.insertLiteralOverride
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||||
@@ -229,16 +228,9 @@ val seekbarColorPatch = bytecodePatch(
|
|||||||
|
|
||||||
execute {
|
execute {
|
||||||
fun MutableMethod.addColorChangeInstructions(resourceId: Long) {
|
fun MutableMethod.addColorChangeInstructions(resourceId: Long) {
|
||||||
val index = indexOfFirstLiteralInstructionOrThrow(resourceId)
|
insertLiteralOverride(
|
||||||
val insertIndex = indexOfFirstInstructionOrThrow(index, Opcode.MOVE_RESULT)
|
resourceId,
|
||||||
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
"$EXTENSION_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I"
|
||||||
|
|
||||||
addInstructions(
|
|
||||||
insertIndex + 1,
|
|
||||||
"""
|
|
||||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I
|
|
||||||
move-result v$register
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +346,7 @@ val seekbarColorPatch = bytecodePatch(
|
|||||||
launchScreenLayoutTypeFingerprint,
|
launchScreenLayoutTypeFingerprint,
|
||||||
mainActivityOnCreateFingerprint
|
mainActivityOnCreateFingerprint
|
||||||
).forEach { fingerprint ->
|
).forEach { fingerprint ->
|
||||||
fingerprint.method.insertFeatureFlagBooleanOverride(
|
fingerprint.method.insertLiteralOverride(
|
||||||
launchScreenLayoutTypeLotteFeatureFlag,
|
launchScreenLayoutTypeLotteFeatureFlag,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->useLotteLaunchSplashScreen(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->useLotteLaunchSplashScreen(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
|||||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
import app.revanced.util.forEachChildElement
|
import app.revanced.util.forEachChildElement
|
||||||
import app.revanced.util.insertFeatureFlagBooleanOverride
|
import app.revanced.util.insertLiteralOverride
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
@@ -233,7 +233,7 @@ val themePatch = bytecodePatch(
|
|||||||
SwitchPreference("revanced_gradient_loading_screen"),
|
SwitchPreference("revanced_gradient_loading_screen"),
|
||||||
)
|
)
|
||||||
|
|
||||||
useGradientLoadingScreenFingerprint.method.insertFeatureFlagBooleanOverride(
|
useGradientLoadingScreenFingerprint.method.insertLiteralOverride(
|
||||||
GRADIENT_LOADING_SCREEN_AB_CONSTANT,
|
GRADIENT_LOADING_SCREEN_AB_CONSTANT,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->gradientLoadingScreenEnabled(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->gradientLoadingScreenEnabled(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import app.revanced.patches.shared.misc.mapping.resourceMappings
|
|||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
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.patches.youtube.misc.settings.PreferenceScreen
|
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
import app.revanced.patches.youtube.video.information.videoInformationPatch
|
import app.revanced.patches.youtube.video.information.videoInformationPatch
|
||||||
@@ -44,6 +46,7 @@ val backgroundPlaybackPatch = bytecodePatch(
|
|||||||
playerTypeHookPatch,
|
playerTypeHookPatch,
|
||||||
videoInformationPatch,
|
videoInformationPatch,
|
||||||
settingsPatch,
|
settingsPatch,
|
||||||
|
versionCheckPatch
|
||||||
)
|
)
|
||||||
|
|
||||||
compatibleWith(
|
compatibleWith(
|
||||||
@@ -100,5 +103,13 @@ val backgroundPlaybackPatch = bytecodePatch(
|
|||||||
|
|
||||||
// Force allowing background play for videos labeled for kids.
|
// Force allowing background play for videos labeled for kids.
|
||||||
kidsBackgroundPlaybackPolicyControllerFingerprint.method.returnEarly()
|
kidsBackgroundPlaybackPolicyControllerFingerprint.method.returnEarly()
|
||||||
|
|
||||||
|
// Fix PiP buttons not working after locking/unlocking device screen.
|
||||||
|
if (is_19_34_or_greater) {
|
||||||
|
pipInputConsumerFeatureFlagFingerprint.method.insertLiteralOverride(
|
||||||
|
PIP_INPUT_CONSUMER_FEATURE_FLAG,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,3 +84,10 @@ internal val shortsBackgroundPlaybackFeatureFlagFingerprint = fingerprint {
|
|||||||
parameters()
|
parameters()
|
||||||
literal { 45415425 }
|
literal { 45415425 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal const val PIP_INPUT_CONSUMER_FEATURE_FLAG = 45638483L
|
||||||
|
|
||||||
|
// Fix 'E/InputDispatcher: Window handle pip_input_consumer has no registered input channel'
|
||||||
|
internal val pipInputConsumerFeatureFlagFingerprint = fingerprint {
|
||||||
|
literal { PIP_INPUT_CONSUMER_FEATURE_FLAG}
|
||||||
|
}
|
||||||
@@ -269,7 +269,7 @@ val settingsPatch = bytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add setting to force cairo settings fragment on/off.
|
// Add setting to force cairo settings fragment on/off.
|
||||||
cairoFragmentConfigFingerprint.method.insertFeatureFlagBooleanOverride(
|
cairoFragmentConfigFingerprint.method.insertLiteralOverride(
|
||||||
CAIRO_CONFIG_LITERAL_VALUE,
|
CAIRO_CONFIG_LITERAL_VALUE,
|
||||||
"$activityHookClassDescriptor->useCairoSettingsFragment(Z)Z"
|
"$activityHookClassDescriptor->useCairoSettingsFragment(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -121,11 +121,11 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
|
|||||||
|
|
||||||
// Override the min/max speeds that can be used.
|
// Override the min/max speeds that can be used.
|
||||||
speedLimiterFingerprint.method.apply {
|
speedLimiterFingerprint.method.apply {
|
||||||
val limitMinIndex = indexOfFirstLiteralInstructionOrThrow(0.25f.toRawBits().toLong())
|
val limitMinIndex = indexOfFirstLiteralInstructionOrThrow(0.25f)
|
||||||
var limitMaxIndex = indexOfFirstLiteralInstruction(2.0f.toRawBits().toLong())
|
var limitMaxIndex = indexOfFirstLiteralInstruction(2.0f)
|
||||||
// Newer targets have 4x max speed.
|
// Newer targets have 4x max speed.
|
||||||
if (limitMaxIndex < 0) {
|
if (limitMaxIndex < 0) {
|
||||||
limitMaxIndex = indexOfFirstLiteralInstructionOrThrow(4.0f.toRawBits().toLong())
|
limitMaxIndex = indexOfFirstLiteralInstructionOrThrow(4.0f)
|
||||||
}
|
}
|
||||||
|
|
||||||
val limitMinRegister = getInstruction<OneRegisterInstruction>(limitMinIndex).registerA
|
val limitMinRegister = getInstruction<OneRegisterInstruction>(limitMinIndex).registerA
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
|||||||
import app.revanced.patches.shared.misc.mapping.get
|
import app.revanced.patches.shared.misc.mapping.get
|
||||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||||
|
import app.revanced.util.InstructionUtils.Companion.branchOpcodes
|
||||||
|
import app.revanced.util.InstructionUtils.Companion.returnOpcodes
|
||||||
|
import app.revanced.util.InstructionUtils.Companion.writeOpcodes
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
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.Method
|
||||||
@@ -43,7 +46,7 @@ import java.util.EnumSet
|
|||||||
* @throws IllegalArgumentException If a branch or conditional statement is encountered
|
* @throws IllegalArgumentException If a branch or conditional statement is encountered
|
||||||
* before a suitable register is found.
|
* before a suitable register is found.
|
||||||
*/
|
*/
|
||||||
internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude: Int): Int {
|
fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude: Int): Int {
|
||||||
if (implementation == null) {
|
if (implementation == null) {
|
||||||
throw IllegalArgumentException("Method has no implementation: $this")
|
throw IllegalArgumentException("Method has no implementation: $this")
|
||||||
}
|
}
|
||||||
@@ -51,82 +54,6 @@ internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude:
|
|||||||
throw IllegalArgumentException("startIndex out of bounds: $startIndex")
|
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.
|
// Highest 4-bit register available, exclusive. Ideally return a free register less than this.
|
||||||
val maxRegister4Bits = 16
|
val maxRegister4Bits = 16
|
||||||
var bestFreeRegisterFound: Int? = null
|
var bestFreeRegisterFound: Int? = null
|
||||||
@@ -134,10 +61,9 @@ internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude:
|
|||||||
|
|
||||||
for (i in startIndex until instructions.count()) {
|
for (i in startIndex until instructions.count()) {
|
||||||
val instruction = getInstruction(i)
|
val instruction = getInstruction(i)
|
||||||
val instructionRegisters = instruction.getRegistersUsed()
|
val instructionRegisters = instruction.registersUsed
|
||||||
|
|
||||||
if (instruction.opcode in returnOpcodes) {
|
if (instruction.isReturnInstruction) {
|
||||||
// Method returns.
|
|
||||||
usedRegisters.addAll(instructionRegisters)
|
usedRegisters.addAll(instructionRegisters)
|
||||||
|
|
||||||
// Use lowest register that hasn't been encountered.
|
// Use lowest register that hasn't been encountered.
|
||||||
@@ -157,7 +83,7 @@ internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude:
|
|||||||
"$startIndex excluding: $registersToExclude")
|
"$startIndex excluding: $registersToExclude")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instruction.opcode in branchOpcodes) {
|
if (instruction.isBranchInstruction) {
|
||||||
if (bestFreeRegisterFound != null) {
|
if (bestFreeRegisterFound != null) {
|
||||||
return bestFreeRegisterFound
|
return bestFreeRegisterFound
|
||||||
}
|
}
|
||||||
@@ -165,9 +91,9 @@ internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude:
|
|||||||
throw IllegalArgumentException("Encountered a branch statement before a free register could be found")
|
throw IllegalArgumentException("Encountered a branch statement before a free register could be found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instruction.opcode in writeOpcodes) {
|
|
||||||
val writeRegister = instruction.getWriteRegister()
|
|
||||||
|
|
||||||
|
val writeRegister = instruction.writeRegister
|
||||||
|
if (writeRegister != null) {
|
||||||
if (writeRegister !in usedRegisters) {
|
if (writeRegister !in usedRegisters) {
|
||||||
// Verify the register is only used for write and not also as a parameter.
|
// 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 the instruction uses the write register once then it's not also a read register.
|
||||||
@@ -194,6 +120,53 @@ internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude:
|
|||||||
throw IllegalArgumentException("Start index is outside the range of normal control flow: $startIndex")
|
throw IllegalArgumentException("Start index is outside the range of normal control flow: $startIndex")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The registers used by this instruction.
|
||||||
|
*/
|
||||||
|
internal val Instruction.registersUsed: List<Int>
|
||||||
|
get() = 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()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The register that is written to by this instruction,
|
||||||
|
* or NULL if this is not a write opcode.
|
||||||
|
*/
|
||||||
|
internal val Instruction.writeRegister: Int?
|
||||||
|
get() {
|
||||||
|
if (this.opcode !in writeOpcodes) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
if (this !is OneRegisterInstruction) {
|
||||||
|
throw IllegalStateException("Not a write instruction: $this")
|
||||||
|
}
|
||||||
|
return registerA
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return If this instruction is an unconditional or conditional branch opcode.
|
||||||
|
*/
|
||||||
|
internal val Instruction.isBranchInstruction: Boolean
|
||||||
|
get() = this.opcode in branchOpcodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return If this instruction returns or throws.
|
||||||
|
*/
|
||||||
|
internal val Instruction.isReturnInstruction: Boolean
|
||||||
|
get() = this.opcode in returnOpcodes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the [MutableMethod] from a given [Method] in a [MutableClass].
|
* Find the [MutableMethod] from a given [Method] in a [MutableClass].
|
||||||
@@ -247,7 +220,7 @@ fun MutableMethod.injectHideViewCall(
|
|||||||
* (patch code)
|
* (patch code)
|
||||||
* (original code)
|
* (original code)
|
||||||
*/
|
*/
|
||||||
internal fun MutableMethod.addInstructionsAtControlFlowLabel(
|
fun MutableMethod.addInstructionsAtControlFlowLabel(
|
||||||
insertIndex: Int,
|
insertIndex: Int,
|
||||||
instructions: String,
|
instructions: String,
|
||||||
) {
|
) {
|
||||||
@@ -298,7 +271,7 @@ fun Method.indexOfFirstResourceIdOrThrow(resourceName: String): Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the index of the first literal instruction with the given value.
|
* Find the index of the first literal instruction with the given long value.
|
||||||
*
|
*
|
||||||
* @return the first literal instruction with the value, or -1 if not found.
|
* @return the first literal instruction with the value, or -1 if not found.
|
||||||
* @see indexOfFirstLiteralInstructionOrThrow
|
* @see indexOfFirstLiteralInstructionOrThrow
|
||||||
@@ -310,14 +283,56 @@ fun Method.indexOfFirstLiteralInstruction(literal: Long) = implementation?.let {
|
|||||||
} ?: -1
|
} ?: -1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the index of the first literal instruction with the given value,
|
* Find the index of the first literal instruction with the given long value,
|
||||||
* or throw an exception if not found.
|
* or throw an exception if not found.
|
||||||
*
|
*
|
||||||
* @return the first literal instruction with the value, or throws [PatchException] if not found.
|
* @return the first literal instruction with the value, or throws [PatchException] if not found.
|
||||||
*/
|
*/
|
||||||
fun Method.indexOfFirstLiteralInstructionOrThrow(literal: Long): Int {
|
fun Method.indexOfFirstLiteralInstructionOrThrow(literal: Long): Int {
|
||||||
val index = indexOfFirstLiteralInstruction(literal)
|
val index = indexOfFirstLiteralInstruction(literal)
|
||||||
if (index < 0) throw PatchException("Could not find literal value: $literal")
|
if (index < 0) throw PatchException("Could not find long literal: $literal")
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the index of the first literal instruction with the given float value.
|
||||||
|
*
|
||||||
|
* @return the first literal instruction with the value, or -1 if not found.
|
||||||
|
* @see indexOfFirstLiteralInstructionOrThrow
|
||||||
|
*/
|
||||||
|
fun Method.indexOfFirstLiteralInstruction(literal: Float) =
|
||||||
|
indexOfFirstLiteralInstruction(literal.toRawBits().toLong())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the index of the first literal instruction with the given float value,
|
||||||
|
* or throw an exception if not found.
|
||||||
|
*
|
||||||
|
* @return the first literal instruction with the value, or throws [PatchException] if not found.
|
||||||
|
*/
|
||||||
|
fun Method.indexOfFirstLiteralInstructionOrThrow(literal: Float): Int {
|
||||||
|
val index = indexOfFirstLiteralInstruction(literal)
|
||||||
|
if (index < 0) throw PatchException("Could not find float literal: $literal")
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the index of the first literal instruction with the given double value.
|
||||||
|
*
|
||||||
|
* @return the first literal instruction with the value, or -1 if not found.
|
||||||
|
* @see indexOfFirstLiteralInstructionOrThrow
|
||||||
|
*/
|
||||||
|
fun Method.indexOfFirstLiteralInstruction(literal: Double) =
|
||||||
|
indexOfFirstLiteralInstruction(literal.toRawBits().toLong())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the index of the first literal instruction with the given double value,
|
||||||
|
* or throw an exception if not found.
|
||||||
|
*
|
||||||
|
* @return the first literal instruction with the value, or throws [PatchException] if not found.
|
||||||
|
*/
|
||||||
|
fun Method.indexOfFirstLiteralInstructionOrThrow(literal: Double): Int {
|
||||||
|
val index = indexOfFirstLiteralInstruction(literal)
|
||||||
|
if (index < 0) throw PatchException("Could not find double literal: $literal")
|
||||||
return index
|
return index
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,24 +349,80 @@ fun Method.indexOfFirstLiteralInstructionReversed(literal: Long) = implementatio
|
|||||||
} ?: -1
|
} ?: -1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the index of the last wide literal instruction with the given value,
|
* Find the index of the last wide literal instruction with the given long value,
|
||||||
* or throw an exception if not found.
|
* or throw an exception if not found.
|
||||||
*
|
*
|
||||||
* @return the last literal instruction with the value, or throws [PatchException] if not found.
|
* @return the last literal instruction with the value, or throws [PatchException] if not found.
|
||||||
*/
|
*/
|
||||||
fun Method.indexOfFirstLiteralInstructionReversedOrThrow(literal: Long): Int {
|
fun Method.indexOfFirstLiteralInstructionReversedOrThrow(literal: Long): Int {
|
||||||
val index = indexOfFirstLiteralInstructionReversed(literal)
|
val index = indexOfFirstLiteralInstructionReversed(literal)
|
||||||
if (index < 0) throw PatchException("Could not find literal value: $literal")
|
if (index < 0) throw PatchException("Could not find long literal: $literal")
|
||||||
return index
|
return index
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the method contains a literal with the given value.
|
* Find the index of the last literal instruction with the given float value.
|
||||||
|
*
|
||||||
|
* @return the last literal instruction with the value, or -1 if not found.
|
||||||
|
* @see indexOfFirstLiteralInstructionOrThrow
|
||||||
|
*/
|
||||||
|
fun Method.indexOfFirstLiteralInstructionReversed(literal: Float) =
|
||||||
|
indexOfFirstLiteralInstructionReversed(literal.toRawBits().toLong())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the index of the last wide literal instruction with the given float value,
|
||||||
|
* or throw an exception if not found.
|
||||||
|
*
|
||||||
|
* @return the last literal instruction with the value, or throws [PatchException] if not found.
|
||||||
|
*/
|
||||||
|
fun Method.indexOfFirstLiteralInstructionReversedOrThrow(literal: Float): Int {
|
||||||
|
val index = indexOfFirstLiteralInstructionReversed(literal)
|
||||||
|
if (index < 0) throw PatchException("Could not find float literal: $literal")
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the index of the last literal instruction with the given double value.
|
||||||
|
*
|
||||||
|
* @return the last literal instruction with the value, or -1 if not found.
|
||||||
|
* @see indexOfFirstLiteralInstructionOrThrow
|
||||||
|
*/
|
||||||
|
fun Method.indexOfFirstLiteralInstructionReversed(literal: Double) =
|
||||||
|
indexOfFirstLiteralInstructionReversed(literal.toRawBits().toLong())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the index of the last wide literal instruction with the given double value,
|
||||||
|
* or throw an exception if not found.
|
||||||
|
*
|
||||||
|
* @return the last literal instruction with the value, or throws [PatchException] if not found.
|
||||||
|
*/
|
||||||
|
fun Method.indexOfFirstLiteralInstructionReversedOrThrow(literal: Double): Int {
|
||||||
|
val index = indexOfFirstLiteralInstructionReversed(literal)
|
||||||
|
if (index < 0) throw PatchException("Could not find double literal: $literal")
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the method contains a literal with the given long value.
|
||||||
*
|
*
|
||||||
* @return if the method contains a literal with the given value.
|
* @return if the method contains a literal with the given value.
|
||||||
*/
|
*/
|
||||||
fun Method.containsLiteralInstruction(literal: Long) = indexOfFirstLiteralInstruction(literal) >= 0
|
fun Method.containsLiteralInstruction(literal: Long) = indexOfFirstLiteralInstruction(literal) >= 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the method contains a literal with the given float value.
|
||||||
|
*
|
||||||
|
* @return if the method contains a literal with the given value.
|
||||||
|
*/
|
||||||
|
fun Method.containsLiteralInstruction(literal: Float) = indexOfFirstLiteralInstruction(literal) >= 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the method contains a literal with the given double value.
|
||||||
|
*
|
||||||
|
* @return if the method contains a literal with the given value.
|
||||||
|
*/
|
||||||
|
fun Method.containsLiteralInstruction(literal: Double) = indexOfFirstLiteralInstruction(literal) >= 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Traverse the class hierarchy starting from the given root class.
|
* Traverse the class hierarchy starting from the given root class.
|
||||||
*
|
*
|
||||||
@@ -565,7 +636,12 @@ fun Method.findInstructionIndicesReversedOrThrow(opcode: Opcode): List<Int> {
|
|||||||
return instructions
|
return instructions
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun MutableMethod.insertFeatureFlagBooleanOverride(literal: Long, extensionsMethod: String) {
|
/**
|
||||||
|
* Overrides the first move result with an extension call.
|
||||||
|
* Suitable for calls to extension code to override boolean and integer values.
|
||||||
|
*/
|
||||||
|
internal fun MutableMethod.insertLiteralOverride(literal: Long, extensionMethodDescriptor: String) {
|
||||||
|
// TODO: make this work with objects and wide values.
|
||||||
val literalIndex = indexOfFirstLiteralInstructionOrThrow(literal)
|
val literalIndex = indexOfFirstLiteralInstructionOrThrow(literal)
|
||||||
val index = indexOfFirstInstructionOrThrow(literalIndex, MOVE_RESULT)
|
val index = indexOfFirstInstructionOrThrow(literalIndex, MOVE_RESULT)
|
||||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
@@ -579,9 +655,24 @@ internal fun MutableMethod.insertFeatureFlagBooleanOverride(literal: Long, exten
|
|||||||
addInstructions(
|
addInstructions(
|
||||||
index + 1,
|
index + 1,
|
||||||
"""
|
"""
|
||||||
$operation, $extensionsMethod
|
$operation, $extensionMethodDescriptor
|
||||||
move-result v$register
|
move-result v$register
|
||||||
""",
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides a literal value result with a constant value.
|
||||||
|
*/
|
||||||
|
internal fun MutableMethod.insertLiteralOverride(literal: Long, override: Boolean) {
|
||||||
|
val literalIndex = indexOfFirstLiteralInstructionOrThrow(literal)
|
||||||
|
val index = indexOfFirstInstructionOrThrow(literalIndex, MOVE_RESULT)
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
|
val overrideValue = if (override) "0x1" else "0x0"
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
index + 1,
|
||||||
|
"const v$register, $overrideValue"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -643,3 +734,58 @@ fun FingerprintBuilder.literal(literalSupplier: () -> Long) {
|
|||||||
method.containsLiteralInstruction(literalSupplier())
|
method.containsLiteralInstruction(literalSupplier())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class InstructionUtils {
|
||||||
|
companion object {
|
||||||
|
val branchOpcodes: EnumSet<Opcode> = 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<Opcode> = EnumSet.of(
|
||||||
|
RETURN_VOID, RETURN, RETURN_WIDE, RETURN_OBJECT, RETURN_VOID_NO_BARRIER,
|
||||||
|
THROW
|
||||||
|
)
|
||||||
|
|
||||||
|
val writeOpcodes: EnumSet<Opcode> = 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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">إخفاء المقطع الصوتي</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">إخفاء المقطع الصوتي</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">تم إخفاء قائمة المقطع الصوتي</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">تم إخفاء قائمة المقطع الصوتي</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">يتم عرض قائمة المقطع الصوتي</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">يتم عرض قائمة المقطع الصوتي</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"تم إخفاء قائمة المقطع الصوتي
|
||||||
|
|
||||||
|
لعرض قائمة المقطع الصوتي، غيّر 'Spoof Video Streams' إلى iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">إخفاء المشاهدة في VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">إخفاء المشاهدة في VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">تم إخفاء قائمة المشاهدة في الوضع الافتراضي</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">تم إخفاء قائمة المشاهدة في الوضع الافتراضي</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Bu seçimi dəyişdirmə işə düşmürsə, Gizli rejimə keçməyə çalışı
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Səs trekini gizlət</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Səs trekini gizlət</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Səs axını menyusu gizlidir</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Səs axını menyusu gizlidir</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Səs axını menyusu göstərilir</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Səs axını menyusu göstərilir</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Audio trek seçimi gizlədilib
|
||||||
|
|
||||||
|
Audio trek seçimin göstərmək üçün \"Video axınları saxtalaşdır\"ı iOS TV-yə dəyiş"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">\"VR-da İzləni\" gizlət</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">\"VR-da İzləni\" gizlət</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">VR menyusunda izləmə gizlidir</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">VR menyusunda izləmə gizlidir</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Схаваць гукавую дарожку</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Схаваць гукавую дарожку</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Меню гукавой дарожкі схавана</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Меню гукавой дарожкі схавана</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Адлюструецца меню гукавой дарожкі</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Адлюструецца меню гукавой дарожкі</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Меню аўдыядарожкі схавана
|
||||||
|
|
||||||
|
Каб паказаць меню аўдыядарожкі, змяніце \"Падробка відэаструменяў\" на iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Схаваць гадзіннік у VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Схаваць гадзіннік у VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Меню прагляду ў VR схавана</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Меню прагляду ў VR схавана</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Избор на Аудио</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Избор на Аудио</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Менюто за избор на Аудио е скрито</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Менюто за избор на Аудио е скрито</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Менюто за избор на Аудио се показва</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Менюто за избор на Аудио се показва</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Менюто за аудио тракове е скрито
|
||||||
|
|
||||||
|
За да покажете менюто за аудио тракове, променете \"Подмяна на видео потоци\" на iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Гледайте във VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Гледайте във VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Менюто за гледане в VR е скрито</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Менюто за гледане в VR е скрито</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">অডিও ট্র্যাক লুকান</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">অডিও ট্র্যাক লুকান</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">অডিও ট্র্যাক মেনু লুকানো আছে</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">অডিও ট্র্যাক মেনু লুকানো আছে</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">অডিও ট্র্যাক মেনু দেখানো হয়</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">অডিও ট্র্যাক মেনু দেখানো হয়</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"অডিও ট্র্যাক মেনু লুকানো আছে
|
||||||
|
|
||||||
|
অডিও ট্র্যাক মেনু দেখাতে, 'স্পুফ ভিডিও স্ট্রিম' পরিবর্তন করে iOS TV করুন"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">ভিআর-এ ঘড়ি লুকান</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">ভিআর-এ ঘড়ি লুকান</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">ভিআর মেনুতে দেখুন লুকানো আছে</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">ভিআর মেনুতে দেখুন লুকানো আছে</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Si canviar aquesta opció no té cap efecte, prova a canviar al mode d'incògnit
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Amaga la pista d\'àudio</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Amaga la pista d\'àudio</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">El menú de la pista d\'àudio s\'amaga</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">El menú de la pista d\'àudio s\'amaga</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Es mostra el menú de la pista d\'àudio</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Es mostra el menú de la pista d\'àudio</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"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"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Amaga Mira en VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Amaga Mira en VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">El menú Mira en VR s\'amaga</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">El menú Mira en VR s\'amaga</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Pokud změna tohoto nastavení nemá žádný účinek, zkuste přepnout do rež
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Skrýt Zvuková stopa</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Skrýt Zvuková stopa</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menu Zvuková stopa je skryto</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menu Zvuková stopa je skryto</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menu Zvuková stopa je zobrazeno</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menu Zvuková stopa je zobrazeno</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Nabídka zvukové stopy je skrytá.
|
||||||
|
|
||||||
|
Chcete-li zobrazit nabídku zvukové stopy, změňte možnost „Zfalšovat streamy videa“ na iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Skrýt Sledovat ve VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Skrýt Sledovat ve VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Menu Sledovat ve VR je skryto</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Menu Sledovat ve VR je skryto</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -576,6 +575,10 @@ Hvis ændring af denne indstilling ikke træder i kraft, kan du prøve at skifte
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Skjul lydspor</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Skjul lydspor</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menuen for lydspor er skjult</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menuen for lydspor er skjult</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menuen Lydspor vises</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menuen Lydspor vises</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Lydspormenuen er skjult
|
||||||
|
|
||||||
|
For at vise lydspormenuen skal du ændre \"Spoof videostream\" til iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Skjul vagt i VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Skjul vagt i VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Se i VR-menuen er skjult</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Se i VR-menuen er skjult</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -606,6 +605,10 @@ Wenn diese Änderung nicht wirksam wird, versuchen Sie, in den Inkognito-Modus z
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Audiospur ausblenden</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Audiospur ausblenden</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Audiospur-Menü ist ausgeblendet</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Audiospur-Menü ist ausgeblendet</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Audiospurmenü wird angezeigt</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Audiospurmenü wird angezeigt</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Das Audiotrack-Menü ist ausgeblendet.
|
||||||
|
|
||||||
|
Um das Audiotrack-Menü anzuzeigen, ändere \"Video-Streams fälschen\" zu iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Überwachung in VR ausblenden</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Überwachung in VR ausblenden</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Im VR-Menü beobachten ist ausgeblendet</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Im VR-Menü beobachten ist ausgeblendet</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -615,6 +614,10 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Μενού «Κομμάτι ήχου»</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Μενού «Κομμάτι ήχου»</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Κρυμμένο</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Κρυμμένο</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Εμφανίζεται</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Εμφανίζεται</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Το μενού «Κομμάτι ήχου» είναι κρυμμένο
|
||||||
|
|
||||||
|
Για να εμφανίζεται το μενού κομματιού ήχου, αλλάξτε την «Παραποίηση ροών βίντεο» σε iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Μενού «Προβολή σε VR»</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Μενού «Προβολή σε VR»</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Κρυμμένο</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Κρυμμένο</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -610,6 +609,10 @@ Si cambiar este ajuste no tiene efecto, intenta cambiar al modo incógnito."</st
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Ocultar pista de audio</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Ocultar pista de audio</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">El menú de pista de audio está oculto</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">El menú de pista de audio está oculto</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">El menú de pista de audio se muestra</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">El menú de pista de audio se muestra</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"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"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Ocultar reloj en VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Ocultar reloj en VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Ver en el menú VR está oculto</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Ver en el menú VR está oculto</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Kui selle sätte muutmine ei avalda mõju, proovige lülituda Inkognito režiimi
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Peida Helitraek</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Peida Helitraek</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Helitraekide menüü on peidetud</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Helitraekide menüü on peidetud</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Helitraekide menüü on nähtav</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Helitraekide menüü on nähtav</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Heliriba menüü on peidetud
|
||||||
|
|
||||||
|
Heliriba menüü kuvamiseks muutke valikut „Võltsitud videovoogedastus“ väärtuseks iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Peida Vaata VR-is</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Peida Vaata VR-is</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Vaata VR-is menüü on peidetud</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Vaata VR-is menüü on peidetud</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -127,6 +126,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Jos tämän asetuksen muuttaminen ei tule voimaan, kokeile vaihtaa Incognito-til
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Piilota Ääniraita</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Piilota Ääniraita</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Ääniraitavalikko on piilotettu</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Ääniraitavalikko on piilotettu</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Ääniraitavalikko näytetään</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Ääniraitavalikko näytetään</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Ääniraitavalikko on piilotettu
|
||||||
|
|
||||||
|
Jos haluat nähdä sen, aseta \"Naamioi videovirrat\" iOS TV:ksi"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Piilota Katso VR-tilassa</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Piilota Katso VR-tilassa</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Katso VR-tilassa -valinta on piilotettu</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Katso VR-tilassa -valinta on piilotettu</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -611,6 +610,10 @@ Tandaan: Ang pagpapagana nito ay nagtatago rin ng mga ad ng video"</string>
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Itago ang Audio track</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Itago ang Audio track</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Nakatago ang menu ng audio track</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Nakatago ang menu ng audio track</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Ipinapakita ang menu ng audio track</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Ipinapakita ang menu ng audio track</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Nakatago ang menu ng audio track
|
||||||
|
|
||||||
|
Upang ipakita ang menu ng Audio track, baguhin ang 'Spoof video streams' sa iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Itago ang Panoorin sa VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Itago ang Panoorin sa VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Nakatago ang panonood sa VR menu</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Nakatago ang panonood sa VR menu</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Si la modification de ce paramètre ne prend pas effet, essayez de passer en mod
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Masquer \"Piste audio\"</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Masquer \"Piste audio\"</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Le menu Piste audio est masqué</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Le menu Piste audio est masqué</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Le menu Piste audio est affiché</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Le menu Piste audio est affiché</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Le menu Piste audio est masqué
|
||||||
|
|
||||||
|
Pour afficher le menu Piste audio, définissez \"Falsifier les flux vidéo\" sur iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Masquer \"Regarder en RV\"</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Masquer \"Regarder en RV\"</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Le menu Regarder en RV est masqué</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Le menu Regarder en RV est masqué</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Mura dtagann aon athrú ar an socrú seo, bain triail as mód Incognito a chur a
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Folaigh Rian Fuaime</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Folaigh Rian Fuaime</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Tá roghchlár rian fuaime i bhfolach</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Tá roghchlár rian fuaime i bhfolach</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Taispeántar roghchlár rian fuaime</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Taispeántar roghchlár rian fuaime</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"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"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Folaigh Watch i VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Folaigh Watch i VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Tá faire i roghchlár VR i bhfolach</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Tá faire i roghchlár VR i bhfolach</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Ha a beállítás módosítása nem lép életbe, próbáljon meg Inkognitó mó
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Hangsáv elrejtése</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Hangsáv elrejtése</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">A hangsáv menü el van rejtve</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">A hangsáv menü el van rejtve</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">A hangsáv menü megjelenik</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">A hangsáv menü megjelenik</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"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"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">\"Megtekintés VR-módban\" elrejtése</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">\"Megtekintés VR-módban\" elrejtése</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">A megtekintés VR-módban menü el van rejtve</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">A megtekintés VR-módban menü el van rejtve</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ MicroG-ի համար մարտկոցի օպտիմալացումը անջատել
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Աուդիո ձայնագրությունը թաքցնել</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Աուդիո ձայնագրությունը թաքցնել</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Աուդիո ձայնագրման մենյուը թաքցված է</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Աուդիո ձայնագրման մենյուը թաքցված է</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Աուդիո ձայնագրման մենյուը երևում է</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Աուդիո ձայնագրման մենյուը երևում է</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Աուդիո ուղու ընտրացանկը թաքնված է:
|
||||||
|
|
||||||
|
Աուդիո ուղու ընտրացանկը ցուցադրելու համար փոխեք «Կեղծել տեսահոսքերը»-ը iOS TV-ի"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Դիտել VR-ով թաքցնել</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Դիտել VR-ով թաքցնել</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">VR-ով դիտել մենյուը թաքցված է</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">VR-ով դիտել մենյուը թաքցված է</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Jika mengubah setelan ini tidak berpengaruh, coba beralih ke mode Penyamaran."</
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Sembunyikan trek Audio</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Sembunyikan trek Audio</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menu trek audio disembunyikan</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menu trek audio disembunyikan</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menu trek audio ditampilkan</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menu trek audio ditampilkan</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Menu trek audio disembunyikan
|
||||||
|
|
||||||
|
Untuk menampilkan menu trek Audio, ubah 'Spoof aliran video' ke iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Sembunyikan Tonton di VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Sembunyikan Tonton di VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Menu tonton di VR disembunyikan</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Menu tonton di VR disembunyikan</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Se la modifica di questa impostazione non ha effetto, prova a passare alla modal
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Nascondi Traccia audio</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Nascondi Traccia audio</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Il menu Traccia audio è nascosto</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Il menu Traccia audio è nascosto</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Il menu Traccia audio è visibile</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Il menu Traccia audio è visibile</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Il menu della traccia audio è nascosto
|
||||||
|
|
||||||
|
Per mostrare il menu della traccia audio, cambia \"Spoof video streams\" in iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Nascondi Guarda in VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Nascondi Guarda in VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Il menu Guarda in VR è nascosto</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Il menu Guarda in VR è nascosto</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -596,6 +595,7 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">הסתר טראק אודיו</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">הסתר טראק אודיו</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">תפריט טראק אודיו מוסתר</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">תפריט טראק אודיו מוסתר</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">תפריט טראק אודיו מוצג</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">תפריט טראק אודיו מוצג</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">הסתר \'צפה ב-VR\'</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">הסתר \'צפה ב-VR\'</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">תפריט \'צפה ב-VR\' מוסתר</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">תפריט \'צפה ב-VR\' מוסתר</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -25,7 +24,7 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_check_environment_failed_title">チェックに失敗しました</string>
|
<string name="revanced_check_environment_failed_title">チェックに失敗しました</string>
|
||||||
<string name="revanced_check_environment_dialog_open_official_source_button">公式サイトを開く</string>
|
<string name="revanced_check_environment_dialog_open_official_source_button">公式サイトを開く</string>
|
||||||
<string name="revanced_check_environment_dialog_ignore_button">無視する</string>
|
<string name="revanced_check_environment_dialog_ignore_button">無視する</string>
|
||||||
<string name="revanced_check_environment_failed_message"><h5>このアプリは、あなたによってパッチが適用されていないようです。</h5><br>このアプリは正しく動作しない可能性があり、<b>有害または危険なものである可能性があります</b>。<br><br>以下の検査結果は、このアプリがパッチ済みAPKであるか、または他のユーザーから取得したものであることを示唆しています。<br><br><small>%1$s</small><br>検証済みで安全なアプリを確実に使用するために、<b>このアプリをアンインストールして、自分でパッチを適用する</b>ことを強くお勧めします。<p><br>無視した場合、この警告は2回のみ表示されます。</string>
|
<string name="revanced_check_environment_failed_message"><h5>このアプリは、あなたによってパッチが適用されていないようです。</h5><br>このアプリは正しく動作しない可能性があり、<b>有害または危険なものである可能性があります</b>。<br><br>以下の検査結果は、このアプリがパッチ済みAPKであるか、または他のユーザーから取得したものであることを示唆しています。<br><br><small>%1$s</small><br>検証済みで安全なアプリを確実に使用するために、<b>このアプリをアンインストールして、自分でパッチを適用する</b>ことを強くお勧めします。<p><br>無視した場合、この警告は2回だけ表示されます。</string>
|
||||||
<string name="revanced_check_environment_not_same_patching_device">別のデバイス上でパッチが適用されている</string>
|
<string name="revanced_check_environment_not_same_patching_device">別のデバイス上でパッチが適用されている</string>
|
||||||
<string name="revanced_check_environment_manager_not_expected_installer">ReVanced Manager によってインストールされていない</string>
|
<string name="revanced_check_environment_manager_not_expected_installer">ReVanced Manager によってインストールされていない</string>
|
||||||
<string name="revanced_check_environment_not_near_patch_time">10 分以上前にパッチが適用されている</string>
|
<string name="revanced_check_environment_not_near_patch_time">10 分以上前にパッチが適用されている</string>
|
||||||
@@ -615,6 +614,10 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">「音声トラック」を非表示</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">「音声トラック」を非表示</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">「音声トラック」は表示されません</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">「音声トラック」は表示されません</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">「音声トラック」は表示されます</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">「音声トラック」は表示されます</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"「音声トラック」は表示されません
|
||||||
|
|
||||||
|
「音声トラック」を表示するには、「動画ストリームを偽装する」の「デフォルトのクライアント」を iOS TV に変更してください"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">「VR で見る」を非表示</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">「VR で見る」を非表示</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">「VR で見る」は表示されません</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">「VR で見る」は表示されません</string>
|
||||||
@@ -849,7 +852,7 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ
|
|||||||
<string name="revanced_ryd_statistics_getFetchCallNumberOfFailures_title">API fetch votes, number of timeout</string>
|
<string name="revanced_ryd_statistics_getFetchCallNumberOfFailures_title">API fetch votes, number of timeout</string>
|
||||||
<string name="revanced_ryd_statistics_getFetchCallNumberOfFailures_zero_summary">ネットワーク通話がタイムアウトされていません</string>
|
<string name="revanced_ryd_statistics_getFetchCallNumberOfFailures_zero_summary">ネットワーク通話がタイムアウトされていません</string>
|
||||||
<string name="revanced_ryd_statistics_getFetchCallNumberOfFailures_non_zero_summary">%d ネットワーク呼び出しがタイムアウトしました</string>
|
<string name="revanced_ryd_statistics_getFetchCallNumberOfFailures_non_zero_summary">%d ネットワーク呼び出しがタイムアウトしました</string>
|
||||||
<string name="revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_title">APIクライアントのレート制限</string>
|
<string name="revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_title">API クライアントのレート制限</string>
|
||||||
<string name="revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_zero_summary">クライアント レート制限は発生していません</string>
|
<string name="revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_zero_summary">クライアント レート制限は発生していません</string>
|
||||||
<string name="revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_non_zero_summary">クライアント レート制限が %d 回発生しました</string>
|
<string name="revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_non_zero_summary">クライアント レート制限が %d 回発生しました</string>
|
||||||
<string name="revanced_ryd_statistics_millisecond_text">%d ミリ秒前</string>
|
<string name="revanced_ryd_statistics_millisecond_text">%d ミリ秒前</string>
|
||||||
@@ -1051,15 +1054,15 @@ MicroG GmsCore に対する電池の最適化を無効にしても、バッテ
|
|||||||
<string name="revanced_sb_stats_username_changed">ユーザー名は正常に変更されました</string>
|
<string name="revanced_sb_stats_username_changed">ユーザー名は正常に変更されました</string>
|
||||||
<string name="revanced_sb_stats_reputation">あなたの評判は <b>%.2f</b></string>
|
<string name="revanced_sb_stats_reputation">あなたの評判は <b>%.2f</b></string>
|
||||||
<string name="revanced_sb_stats_submissions"><b>%s</b> 個のセグメントを作成しました</string>
|
<string name="revanced_sb_stats_submissions"><b>%s</b> 個のセグメントを作成しました</string>
|
||||||
<string name="revanced_sb_stats_submissions_sum">セグメントを見るにはここをタップしてください</string>
|
<string name="revanced_sb_stats_submissions_sum">作成したセグメントを表示するには、ここをタップしてください</string>
|
||||||
<string name="revanced_sb_stats_saved_zero">SponsorBlockリーダーボード</string>
|
<string name="revanced_sb_stats_saved_zero">SponsorBlock リーダーボード</string>
|
||||||
<string name="revanced_sb_stats_saved"><b>%s</b> 個のセグメントから人々を救いました</string>
|
<string name="revanced_sb_stats_saved">合計で <b>%s</b> 個のセグメントから人々を救いました</string>
|
||||||
<string name="revanced_sb_stats_saved_sum_zero">ここをタップすると、世界的な統計とトップの貢献者を見ることができます</string>
|
<string name="revanced_sb_stats_saved_sum_zero">グローバルの統計と上位の貢献者を表示するには、ここをタップしてください</string>
|
||||||
<string name="revanced_sb_stats_saved_sum">それは <b>%s</b> の生活です。<br>ここをタップしてリーダーボードを見る</string>
|
<string name="revanced_sb_stats_saved_sum">時間にして <b>%s</b> です。<br>ここをタップすると、リーダーボードが表示されます</string>
|
||||||
<string name="revanced_sb_stats_self_saved">合計で <b>%s</b> 個のセグメントをスキップしました</string>
|
<string name="revanced_sb_stats_self_saved">合計で <b>%s</b> 個のセグメントをスキップしました</string>
|
||||||
<string name="revanced_sb_stats_self_saved_sum"><b>%s</b></string>
|
<string name="revanced_sb_stats_self_saved_sum">時間にして <b>%s</b> です</string>
|
||||||
<string name="revanced_sb_stats_self_saved_reset_title">スキップしたセグメントの合計をリセットしますか?</string>
|
<string name="revanced_sb_stats_self_saved_reset_title">スキップしたセグメントの合計をリセットしますか?</string>
|
||||||
<string name="revanced_sb_stats_saved_hour_format">%1$s時間%2$s分</string>
|
<string name="revanced_sb_stats_saved_hour_format">%1$s 時間 %2$s 分</string>
|
||||||
<string name="revanced_sb_stats_saved_minute_format">%1$s 分 %2$s 秒</string>
|
<string name="revanced_sb_stats_saved_minute_format">%1$s 分 %2$s 秒</string>
|
||||||
<string name="revanced_sb_stats_saved_second_format">%s 秒</string>
|
<string name="revanced_sb_stats_saved_second_format">%s 秒</string>
|
||||||
<string name="revanced_sb_color_opacity_label">透明度:</string>
|
<string name="revanced_sb_color_opacity_label">透明度:</string>
|
||||||
@@ -1235,7 +1238,7 @@ Automotive レイアウト
|
|||||||
<string name="revanced_alt_thumbnail_options_entry_4">静止画サムネイル</string>
|
<string name="revanced_alt_thumbnail_options_entry_4">静止画サムネイル</string>
|
||||||
<string name="revanced_alt_thumbnail_dearrow_about_summary">"DeArrow は、YouTube 動画のサムネイルをクラウドソーシングで提供する機能です。DeArrow のサムネイルは、YouTube が提供するサムネイルよりも適切なことが多いです。これを有効にすると、動画の URL が API サーバーに送信されますが、他のデータは送信されません。動画に DeArrow サムネイルがない場合は、オリジナルのサムネイルまたは静止画サムネイルが表示されます
|
<string name="revanced_alt_thumbnail_dearrow_about_summary">"DeArrow は、YouTube 動画のサムネイルをクラウドソーシングで提供する機能です。DeArrow のサムネイルは、YouTube が提供するサムネイルよりも適切なことが多いです。これを有効にすると、動画の URL が API サーバーに送信されますが、他のデータは送信されません。動画に DeArrow サムネイルがない場合は、オリジナルのサムネイルまたは静止画サムネイルが表示されます
|
||||||
|
|
||||||
DeArrow の詳細については、ここをタップしてください"</string>
|
詳細については、ここをタップしてください"</string>
|
||||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_title">API が利用できない場合はトーストを表示する</string>
|
<string name="revanced_alt_thumbnail_dearrow_connection_toast_title">API が利用できない場合はトーストを表示する</string>
|
||||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_on">DeArrow が利用できない場合はトースト ポップアップが表示されます</string>
|
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_on">DeArrow が利用できない場合はトースト ポップアップが表示されます</string>
|
||||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_off">DeArrow が利用できない場合でもトースト ポップアップは表示されません</string>
|
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_off">DeArrow が利用できない場合でもトースト ポップアップは表示されません</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">오디오 트랙 메뉴 숨기기</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">오디오 트랙 메뉴 숨기기</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">오디오 트랙 메뉴가 숨겨집니다</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">오디오 트랙 메뉴가 숨겨집니다</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">오디오 트랙 메뉴가 표시됩니다</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">오디오 트랙 메뉴가 표시됩니다</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"오디오 트랙 메뉴가 숨겨집니다
|
||||||
|
|
||||||
|
오디오 트랙 메뉴를 표시하려면 '스트리밍 데이터 변경하기'에서 기본 클라이언트를 iOS TV로 변경하세요"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">VR로 보기 메뉴 숨기기</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">VR로 보기 메뉴 숨기기</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">VR로 보기 메뉴가 숨겨집니다</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">VR로 보기 메뉴가 숨겨집니다</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,8 @@ Jei pakeitus šį nustatymą neįsigalioja, pabandykite perjungti į inkognito r
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Slėpti Garso takelius</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Slėpti Garso takelius</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Garso takelių meniu yra paslėptas</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Garso takelių meniu yra paslėptas</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Garso takelių meniu yra rodomas</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Garso takelių meniu yra rodomas</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Garso takelio meniu yra paslėptas.\n\nNorėdami parodyti garso takelio meniu, pakeiskite „Apsimesti vaizdo srautais“ į „iOS TV“"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Slėpti Žiūrėti VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Slėpti Žiūrėti VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Žiūrėti VR meniu yra paslėptas</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Žiūrėti VR meniu yra paslėptas</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Ja šī iestatījuma maiņa nestājas spēkā, mēģiniet pārslēgties uz inkog
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Paslēpt Audio ceļu</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Paslēpt Audio ceļu</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Audio ceļa izvēlne ir paslēpta</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Audio ceļa izvēlne ir paslēpta</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Audio ceļa izvēlne ir redzama</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Audio ceļa izvēlne ir redzama</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"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"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Paslēpt Skatīties VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Paslēpt Skatīties VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Skatīties VR izvēlne ir paslēpta</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Skatīties VR izvēlne ir paslēpta</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Als het wijzigen van deze instelling geen effect heeft, probeer dan over te scha
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Verberg Audiotrack</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Verberg Audiotrack</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menu Audiotrack is verborgen</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menu Audiotrack is verborgen</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menu Audiotrack wordt weergegeven</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menu Audiotrack wordt weergegeven</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Audiotrackmenu is verborgen
|
||||||
|
|
||||||
|
Om het audiotrackmenu weer te geven, wijzigt u 'Videostreams vervalsen' in iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Verberg Bekijk in VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Verberg Bekijk in VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Menu Bekijk in VR is verborgen</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Menu Bekijk in VR is verborgen</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Jeśli zmiana tego ustawienia nie przyniesie efektu, spróbuj przełączyć się
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Menu ścieżki dźwiękowej</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Menu ścieżki dźwiękowej</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menu ścieżki dźwiękowej jest ukryte</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menu ścieżki dźwiękowej jest ukryte</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menu ścieżki dźwiękowej jest widoczne</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menu ścieżki dźwiękowej jest widoczne</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Menu ścieżki audio jest ukryte
|
||||||
|
|
||||||
|
Aby pokazać menu ścieżki audio, zmień opcję „Fałszuj strumienie wideo” na iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Menu oglądania w VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Menu oglądania w VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Menu oglądania w VR jest ukryte</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Menu oglądania w VR jest ukryte</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -611,6 +610,10 @@ Se alterar esta configuração não fizer efeito, tente mudar para o modo anôni
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Ocultar Faixa de áudio</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Ocultar Faixa de áudio</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menu faixa de áudio está oculto</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menu faixa de áudio está oculto</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menu faixa de áudio não está oculto</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menu faixa de áudio não está oculto</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"O menu da faixa de áudio está oculto
|
||||||
|
|
||||||
|
Para exibir o menu da faixa de áudio, altere \"Spoof video streams\" para iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Ocultar Assistir no VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Ocultar Assistir no VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Menu assistir no VR está oculto</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Menu assistir no VR está oculto</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Se alterar esta configuração não fizer efeito, tente alternar para o modo an
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Esconder faixa de áudio</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Esconder faixa de áudio</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menu de faixa de áudio escondida</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Menu de faixa de áudio escondida</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menu da faixa de áudio visível</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Menu da faixa de áudio visível</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"O menu da faixa de áudio está oculto
|
||||||
|
|
||||||
|
Para mostrar o menu da faixa de áudio, altere \"Spoof video streams\" para iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Esconder relógio no VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Esconder relógio no VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Assista no menu VR está escondido</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Assista no menu VR está escondido</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Dacă modificarea acestei setări nu are efect, încercați să comutați la mod
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Ascunde piesa audio</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Ascunde piesa audio</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Meniul piesei audio este ascuns</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Meniul piesei audio este ascuns</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Meniul piesei audio este afișat</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Meniul piesei audio este afișat</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Meniul pentru pista audio este ascuns
|
||||||
|
|
||||||
|
Pentru a afișa meniul pentru pista audio, schimbați opțiunea „Falsifică fluxurile video” în iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Ascunde ceas în VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Ascunde ceas în VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Vizionarea în meniul VR este ascunsă</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Vizionarea în meniul VR este ascunsă</string>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -613,6 +612,10 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Скрыть пункт \"Звуковая дорожка\"</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Скрыть пункт \"Звуковая дорожка\"</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Пункт \"Звуковая дорожка\" в выдвижном меню плеера скрыт</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Пункт \"Звуковая дорожка\" в выдвижном меню плеера скрыт</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Пункт \"Звуковая дорожка\" в выдвижном меню плеера показан</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Пункт \"Звуковая дорожка\" в выдвижном меню плеера показан</string>
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Пункт \"Звуковая дорожка\" в выдвижном меню плеера скрыт
|
||||||
|
|
||||||
|
Для показа пункта \"Звуковая дорожка\" измените клиент \"Подмены видеопотоков\" на iOS TV"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Скрыть пункт \"Смотреть в VR-режиме\"</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Скрыть пункт \"Смотреть в VR-режиме\"</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Пункт \"Смотреть в VR-режиме\" в выдвижном меню плеера скрыт</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Пункт \"Смотреть в VR-режиме\" в выдвижном меню плеера скрыт</string>
|
||||||
@@ -1373,7 +1376,7 @@ Second \"item\" text"</string>
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
|
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
|
||||||
<string name="revanced_spoof_video_streams_screen_title">Подмена видеопотоков</string>
|
<string name="revanced_spoof_video_streams_screen_title">Подмена видеопотоков</string>
|
||||||
<string name="revanced_spoof_video_streams_screen_summary">Подмена видеопотоков клиента для предотвращения проблем с воспроизведением видео</string>
|
<string name="revanced_spoof_video_streams_screen_summary">Подмена клиента видеопотоков для предотвращения проблем с воспроизведением видео</string>
|
||||||
<string name="revanced_spoof_video_streams_title">Подменить видеопотоки</string>
|
<string name="revanced_spoof_video_streams_title">Подменить видеопотоки</string>
|
||||||
<string name="revanced_spoof_video_streams_summary_on">Видеопотоки подменены</string>
|
<string name="revanced_spoof_video_streams_summary_on">Видеопотоки подменены</string>
|
||||||
<string name="revanced_spoof_video_streams_summary_off">"Видеопотоки не подменены
|
<string name="revanced_spoof_video_streams_summary_off">"Видеопотоки не подменены
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
All strings must have a unique path, even if the same string is declared in two different apps.
|
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 <app> and <patch> elements.
|
This is because Crowdin requires temporarily flattening this file and removing the <app> and <patch> elements.
|
||||||
|
|
||||||
|
|
||||||
Strings with new lines must be raw strings where they're wrapped in quotes and new lines are not encoded.
|
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.
|
Raw strings still requires escaping embedded double quotes but escaping embedded single quotes is optional.
|
||||||
|
|
||||||
@@ -107,6 +106,7 @@ Second \"item\" text"</string>
|
|||||||
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
This menu only appears for some videos. Translate the name normally if the menu cannot be found. -->
|
||||||
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Lock screen' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Audio track' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user