Compare commits

...

31 Commits

Author SHA1 Message Date
semantic-release-bot
86f867fe97 chore: Release v5.20.0-dev.7 [skip ci]
# [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)) ([0f687ec](0f687ecfd3))
2025-04-15 10:56:12 +00:00
oSumAtrIX
0f687ecfd3 fix(Spotify): Fix login by replacing Spoof signature patch with new Spoof package info patch (#4794)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2025-04-15 12:53:26 +02:00
semantic-release-bot
6c8b7d09c1 chore: Release v5.20.0-dev.6 [skip ci]
# [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)) ([3d6958f](3d6958f157))
2025-04-15 07:27:06 +00:00
hoodles
3d6958f157 fix(Duolingo - Hide ads): Support lastest app release (#4790) 2025-04-15 09:24:29 +02:00
semantic-release-bot
43d7cc7374 chore: Release v5.20.0-dev.5 [skip ci]
# [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)) ([5ebd449](5ebd449f1f))
2025-04-14 08:46:51 +00:00
Kamil Kras
5ebd449f1f feat(YouTube - Swipe controls): Add option to change volume swipe sensitivity (step size) (#4557)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2025-04-14 10:43:21 +02:00
semantic-release-bot
346a061df8 chore: Release v5.20.0-dev.4 [skip ci]
# [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](50f5b1ac54))
2025-04-14 08:10:14 +00:00
semantic-release-bot
13e490a422 chore: Release v5.20.0-dev.3 [skip ci]
# [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 ([b4e8540](b4e8540bbc))
2025-04-13 22:11:10 +00:00
LisoUseInAIKyrios
b4e8540bbc fix(YouTube - Remove background playback restrictions): Restore PiP button functionality after screen is unlocked 2025-04-14 00:07:35 +02:00
github-actions[bot]
775c1baec2 chore: Sync translations (#4784) 2025-04-14 00:05:17 +02:00
semantic-release-bot
9419fb8ec4 chore: Release v5.20.0-dev.2 [skip ci]
# [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)) ([c510931](c510931eb0))
2025-04-13 19:29:33 +00:00
Nuckyz
c510931eb0 feat(Spotify - Custom theme): Add option to use unmodified player background gradient (#4741)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2025-04-13 21:26:59 +02:00
semantic-release-bot
7160699384 chore: Release v5.20.0-dev.1 [skip ci]
# [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)) ([9db67a6](9db67a6eb2))
2025-04-13 16:26:18 +00:00
LisoUseInAIKyrios
9db67a6eb2 feat: Add Set target SDK version 34 patch (Disable edge-to-edge display) (#4780)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-04-13 18:23:45 +02:00
semantic-release-bot
e684d87dd3 chore: Release v5.19.1 [skip ci]
## [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)) ([d451bc6](d451bc6d6d))
* **Spotify:** Restore patching with ReVanced Manager ([#4769](https://github.com/ReVanced/revanced-patches/issues/4769)) ([89d44da](89d44da171))
2025-04-12 19:30:34 +00:00
LisoUseInAIKyrios
2d1752a1eb chore: Merge branch dev to main (#4772) 2025-04-12 21:27:49 +02:00
semantic-release-bot
c9ff7092fe chore: Release v5.19.1-dev.2 [skip ci]
## [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)) ([d451bc6](d451bc6d6d))
2025-04-12 19:23:37 +00:00
LisoUseInAIKyrios
d451bc6d6d fix(Google Photos): Restore patching with ReVanced Manager (#4773) 2025-04-12 21:20:36 +02:00
semantic-release-bot
741fd36872 chore: Release v5.19.1-dev.1 [skip ci]
## [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](89d44da171))
2025-04-12 19:04:28 +00:00
semantic-release-bot
517f8cf59a chore: Release v5.19.0 [skip ci]
# [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)) ([e6ae55f](e6ae55fa99))
* **Google Photos:** Remove obsolete non functional patch `Restore hidden 'Back up while charging' toggle` ([#4764](https://github.com/ReVanced/revanced-patches/issues/4764)) ([f68d06d](f68d06dbf3))
* **Spotify - Custom theme:** Override more color resources ([#4690](https://github.com/ReVanced/revanced-patches/issues/4690)) ([49c8499](49c849979f))
* **Spotify - Unlock Spotify Premium:** Remove restrictions for Google voice assistant ([#4702](https://github.com/ReVanced/revanced-patches/issues/4702)) ([d573386](d573386e0f))
* **Spotify:** Remove ads sections from home ([#4722](https://github.com/ReVanced/revanced-patches/issues/4722)) ([628d184](628d18489c))
* **Twitter - Hide recommended users:** Make hiding work again by filtering for new entryId prefix ([#4456](https://github.com/ReVanced/revanced-patches/issues/4456)) ([3d68c06](3d68c06146))
* **YouTube - Hide layout components:** Do not hide video description music/game links if hide horizontal shelves is enabled ([6005c97](6005c97bf5))
* **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)) ([1abed31](1abed31968))
* **YouTube - Remove background playback restrictions:** Do not show media controls when playing Shorts from the feed ([318b55b](318b55b8fe))
* **YouTube - Return YouTube Dislike:** Correctly update label after disliking a Short with 20.07 ([0bff207](0bff207efc))
* **YouTube - Return YouTube Dislike:** Fix inconsistent label after disliking a Short ([3d67d90](3d67d90473))
* **YouTube - Seekbar:** Correctly hide the feed seekbar with target 20.07 ([2035c9e](2035c9e2e9))
* **YouTube:** Combine multiple seekbar patches into a single patch ([#4705](https://github.com/ReVanced/revanced-patches/issues/4705)) ([37984b8](37984b8b99))

### Features

* **Angulus:** Add `Hide ads` patch ([#4604](https://github.com/ReVanced/revanced-patches/issues/4604)) ([2d7b1b0](2d7b1b09af))
* **Messenger:** Add `Remove Meta AI tab` patch ([#4726](https://github.com/ReVanced/revanced-patches/issues/4726)) ([de0d11f](de0d11fcfb))
* **Photomath:** Support latest version ([#4672](https://github.com/ReVanced/revanced-patches/issues/4672)) ([ef3d5ba](ef3d5bafd5))
* **Proton Mail:** Add `Remove 'Sent from' signature` patch ([#4514](https://github.com/ReVanced/revanced-patches/issues/4514)) ([8ed9d5b](8ed9d5bf08))
* **Spotify:** Add `Check environment` patch ([#4765](https://github.com/ReVanced/revanced-patches/issues/4765)) ([854a18f](854a18ff72))
* **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)) ([e30f593](e30f593af0))
* **Strava - Disable subscription suggestions:** Make compatible with latest version ([#4739](https://github.com/ReVanced/revanced-patches/issues/4739)) ([654587a](654587a75e))
* **YouTube - Settings:** Add icons to the ReVanced settings ([#4496](https://github.com/ReVanced/revanced-patches/issues/4496)) ([fdefb67](fdefb67d02))
2025-04-12 13:27:56 +00:00
oSumAtrIX
b78fb24435 chore: Merge branch dev to main (#4699)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
Co-authored-by: Denis Kerner <11692788+dtricks@users.noreply.github.com>
Co-authored-by: Denis Kerner <denis.kerner@vodafone.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
Co-authored-by: Dawid Krajcarz <80264606+drobotk@users.noreply.github.com>
Co-authored-by: Jakub Blažej <trogper@gmail.com>
Co-authored-by: MarcaD <152095496+MarcaDian@users.noreply.github.com>
Co-authored-by: Aoife McCullough <92225779+AoifeMcCull@users.noreply.github.com>
Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com>
Co-authored-by: user5095 <140261471+user5095@users.noreply.github.com>
Co-authored-by: Brosssh <44944126+Brosssh@users.noreply.github.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: oSumAtrIX <github@osumatrix.me>
2025-04-12 15:24:43 +02:00
github-actions[bot]
a3faccb21b chore: Sync translations (#4766)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-04-12 15:19:43 +02:00
semantic-release-bot
5f0fddc122 chore: Release v5.19.0-dev.17 [skip ci]
# [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)) ([854a18f](854a18ff72))
2025-04-12 12:56:01 +00:00
oSumAtrIX
854a18ff72 feat(Spotify): Add Check environment patch (#4765) 2025-04-12 14:53:27 +02:00
semantic-release-bot
b994a16bdc chore: Release v5.19.0-dev.16 [skip ci]
# [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)) ([f68d06d](f68d06dbf3))
2025-04-11 20:15:09 +00:00
LisoUseInAIKyrios
f68d06dbf3 fix(Google Photos): Remove obsolete non functional patch Restore hidden 'Back up while charging' toggle (#4764) 2025-04-11 22:12:13 +02:00
semantic-release-bot
04c6a2e5f4 chore: Release v5.19.0-dev.15 [skip ci]
# [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)) ([e6ae55f](e6ae55fa99))
2025-04-11 19:42:49 +00:00
LisoUseInAIKyrios
e6ae55fa99 fix(Google Photos - Restore hidden 'Back up while charging' toggle): Constrain to last working app target (#4761) 2025-04-11 21:40:17 +02:00
github-actions[bot]
fb62474ff4 chore: Sync translations (#4763)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-04-11 21:39:34 +02:00
semantic-release-bot
e084f01fd0 chore: Release v5.19.0-dev.14 [skip ci]
# [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)) ([d573386](d573386e0f))
2025-04-11 19:36:38 +00:00
Brosssh
d573386e0f fix(Spotify - Unlock Spotify Premium): Remove restrictions for Google voice assistant (#4702)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-04-11 21:33:59 +02:00
119 changed files with 1130 additions and 459 deletions

View File

@@ -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)

View File

@@ -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,

View File

@@ -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

View File

@@ -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()

View File

@@ -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)
} }
} }

View File

@@ -24,6 +24,7 @@ abstract class BaseGestureController(
controller.overlay, controller.overlay,
10, 10,
1, 1,
controller.config.volumeSwipeSensitivity,
) { ) {
/** /**

View File

@@ -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)
} }
} }

View File

@@ -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")

View File

@@ -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

View File

@@ -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

View File

@@ -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)
}
}
}
}

View File

@@ -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)
} }

View File

@@ -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,
) )

View File

@@ -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,
) )

View File

@@ -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")
}
} }
} }
} }

View File

@@ -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))

View File

@@ -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.

View File

@@ -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"
) )

View File

@@ -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!!)
}
}
}

View File

@@ -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)
}
} }
} }

View File

@@ -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)

View File

@@ -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,
)

View File

@@ -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;") }
} }

View File

@@ -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",
)

View File

@@ -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
} }
} }

View File

@@ -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)
}
}

View File

@@ -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"
)
}

View File

@@ -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
}
}
}

View File

@@ -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\"")
}
}
} }

View File

@@ -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)
}
}

View File

@@ -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"
) )

View File

@@ -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",
) )

View File

@@ -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"
) )

View File

@@ -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"
) )

View File

@@ -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"
) )

View File

@@ -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"
) )

View File

@@ -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
)
}
} }
} }

View File

@@ -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}
}

View File

@@ -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"
) )

View File

@@ -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

View File

@@ -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,
)
}
}

View File

@@ -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">

View File

@@ -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">

View File

@@ -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>

View File

@@ -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">

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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">

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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">

View File

@@ -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">

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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">

View File

@@ -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>

View File

@@ -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>

View File

@@ -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">&lt;h5&gt;このアプリは、あなたによってパッチが適用されていないようです。&lt;/h5&gt;&lt;br&gt;このアプリは正しく動作しない可能性があり、&lt;b&gt;有害または危険なものである可能性があります&lt;/b&gt;&lt;br&gt;&lt;br&gt;以下の検査結果は、このアプリがパッチ済みAPKであるか、または他のユーザーから取得したものであることを示唆しています。&lt;br&gt;&lt;br&gt;&lt;small&gt;%1$s&lt;/small&gt;&lt;br&gt;検証済みで安全なアプリを確実に使用するために、&lt;b&gt;このアプリをアンインストールして、自分でパッチを適用する&lt;/b&gt;ことを強くお勧めします。&lt;p&gt;&lt;br&gt;無視した場合、この警告は2回のみ表示されます。</string> <string name="revanced_check_environment_failed_message">&lt;h5&gt;このアプリは、あなたによってパッチが適用されていないようです。&lt;/h5&gt;&lt;br&gt;このアプリは正しく動作しない可能性があり、&lt;b&gt;有害または危険なものである可能性があります&lt;/b&gt;&lt;br&gt;&lt;br&gt;以下の検査結果は、このアプリがパッチ済みAPKであるか、または他のユーザーから取得したものであることを示唆しています。&lt;br&gt;&lt;br&gt;&lt;small&gt;%1$s&lt;/small&gt;&lt;br&gt;検証済みで安全なアプリを確実に使用するために、&lt;b&gt;このアプリをアンインストールして、自分でパッチを適用する&lt;/b&gt;ことを強くお勧めします。&lt;p&gt;&lt;br&gt;無視した場合、この警告は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">あなたの評判は &lt;b&gt;%.2f&lt;/b&gt;</string> <string name="revanced_sb_stats_reputation">あなたの評判は &lt;b&gt;%.2f&lt;/b&gt;</string>
<string name="revanced_sb_stats_submissions">&lt;b&gt;%s&lt;/b&gt; 個のセグメントを作成しました</string> <string name="revanced_sb_stats_submissions">&lt;b&gt;%s&lt;/b&gt; 個のセグメントを作成しました</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">&lt;b&gt;%s&lt;/b&gt; 個のセグメントから人々を救いました</string> <string name="revanced_sb_stats_saved">合計で &lt;b&gt;%s&lt;/b&gt; 個のセグメントから人々を救いました</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">それは &lt;b&gt;%s&lt;/b&gt; の生活です。&lt;br&gt;ここをタップしてリーダーボードを見る</string> <string name="revanced_sb_stats_saved_sum">時間にして &lt;b&gt;%s&lt;/b&gt; です。&lt;br&gt;ここをタップすると、リーダーボードが表示されます</string>
<string name="revanced_sb_stats_self_saved">合計で &lt;b&gt;%s&lt;/b&gt; 個のセグメントをスキップしました</string> <string name="revanced_sb_stats_self_saved">合計で &lt;b&gt;%s&lt;/b&gt; 個のセグメントをスキップしました</string>
<string name="revanced_sb_stats_self_saved_sum">&lt;b&gt;%s&lt;/b&gt;</string> <string name="revanced_sb_stats_self_saved_sum">時間にして &lt;b&gt;%s&lt;/b&gt; です</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>

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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>

View File

@@ -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">

View File

@@ -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">

View File

@@ -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>

View File

@@ -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>

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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>

View File

@@ -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">

View File

@@ -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">

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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">"Видеопотоки не подменены

View File

@@ -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