Compare commits

...

55 Commits

Author SHA1 Message Date
semantic-release-bot
76d32e21c2 chore: Release v5.15.0-dev.4 [skip ci]
# [5.15.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.15.0-dev.3...v5.15.0-dev.4) (2025-03-21)

### Bug Fixes

* **YouTube - Spoof app version:** Change oldest spoof target to 19.01.34 ([54a7afa](54a7afa540))
2025-03-21 09:26:53 +00:00
LisoUseInAIKyrios
54a7afa540 fix(YouTube - Spoof app version): Change oldest spoof target to 19.01.34 2025-03-21 10:23:26 +01:00
LisoUseInAIKyrios
ef86438bac ci: Pull Crowdin strings less often 2025-03-21 10:21:16 +01:00
github-actions[bot]
0683cedac0 chore: Sync translations (#4626) 2025-03-21 10:18:28 +01:00
semantic-release-bot
35753410aa chore: Release v5.15.0-dev.3 [skip ci]
# [5.15.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.15.0-dev.2...v5.15.0-dev.3) (2025-03-20)

### Bug Fixes

* **YouTube:** Do not show restart prompt more than once if setting change is canceled ([df838ed](df838ed91d))
2025-03-20 11:17:31 +00:00
LisoUseInAIKyrios
df838ed91d fix(YouTube): Do not show restart prompt more than once if setting change is canceled 2025-03-20 12:14:31 +01:00
github-actions[bot]
8e494d26d4 chore: Sync translations (#4623) 2025-03-20 12:08:20 +01:00
LisoUseInAIKyrios
7d834e5421 refactor(YouTube - Spoof app version): Allow manually spoofing to 19.01 - 19.25 2025-03-20 09:57:29 +01:00
semantic-release-bot
60a31cf4e1 chore: Release v5.15.0-dev.2 [skip ci]
# [5.15.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.15.0-dev.1...v5.15.0-dev.2) (2025-03-19)

### Bug Fixes

* **YouTube - Spoof app version:** Remove broken spoof targets that YouTube no longer supports ([#4610](https://github.com/ReVanced/revanced-patches/issues/4610)) ([04a1700](04a170054e))
2025-03-19 17:19:19 +00:00
github-actions[bot]
edb8bd66bc chore: Sync translations (#4616) 2025-03-19 18:16:05 +01:00
LisoUseInAIKyrios
04a170054e fix(YouTube - Spoof app version): Remove broken spoof targets that YouTube no longer supports (#4610) 2025-03-19 18:08:51 +01:00
semantic-release-bot
79e6349a69 chore: Release v5.15.0-dev.1 [skip ci]
# [5.15.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.14.0...v5.15.0-dev.1) (2025-03-19)

### Features

* **YouTube - SponsorBlock:** Add opacity setting to category segment colors ([#4582](https://github.com/ReVanced/revanced-patches/issues/4582)) ([bbf3a34](bbf3a34a2f))
2025-03-19 17:06:12 +00:00
LisoUseInAIKyrios
bbf3a34a2f feat(YouTube - SponsorBlock): Add opacity setting to category segment colors (#4582) 2025-03-19 18:02:06 +01:00
github-actions[bot]
1db7c49514 chore: Sync translations (#4614) 2025-03-19 18:00:52 +01:00
semantic-release-bot
ef0506a4f8 chore: Release v5.14.0 [skip ci]
# [5.14.0](https://github.com/ReVanced/revanced-patches/compare/v5.13.0...v5.14.0) (2025-03-09)

### Bug Fixes

* **Boost for reddit - Client spoof:** Use a different user agent to combat Reddit's API issues ([8d0bca3](8d0bca3b03))
* **YouTube - Change form factor:** Restore Automotive form factor watch history menu, channel pages, and community posts ([#4541](https://github.com/ReVanced/revanced-patches/issues/4541)) ([e2de2d8](e2de2d8d44))
* **YouTube - Hide ads:** Hide new type of buttoned ad ([#4528](https://github.com/ReVanced/revanced-patches/issues/4528)) ([67dcd09](67dcd091c4))
* **YouTube - Hide layout components:** Do not hide Movie/Courses start page content if 'Hide horizontal shelves' is enabled ([99879f6](99879f6e0a))
* **YouTube - Theme:** Resolve dark mode startup crash with Android 9.0 ([7adfc63](7adfc637dc))
* **YouTube:** Change language settings menu to use native language names ([#4568](https://github.com/ReVanced/revanced-patches/issues/4568)) ([e9bc201](e9bc201641))
* **YouTube:** Combine `Restore old video quality menu` and `Remember video quality` into `Video quality` patch ([#4552](https://github.com/ReVanced/revanced-patches/issues/4552)) ([ee5c830](ee5c830df8))

### Features

* **Infinity for Reddit:** Add support for package name on IzzyOnDroid ([#4554](https://github.com/ReVanced/revanced-patches/issues/4554)) ([df3dc1c](df3dc1c0b2))
* **Spotify:** Add `Spoof signature` patch ([#4576](https://github.com/ReVanced/revanced-patches/issues/4576)) ([f39e70c](f39e70c648))
* **YouTube - Remember video quality:** Add separate Shorts default quality settings ([#4543](https://github.com/ReVanced/revanced-patches/issues/4543)) ([2a67c31](2a67c312e1))
2025-03-09 12:21:22 +00:00
oSumAtrIX
9b38da35ff chore: Merge branch dev to main (#4540)
Co-authored-by: ILoveOpenSourceApplications <117499019+ILoveOpenSourceApplications@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
Co-authored-by: alieRN <45766489+aliernfrog@users.noreply.github.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-03-09 13:17:57 +01:00
github-actions[bot]
afdb771066 chore: Sync translations (#4577) 2025-03-09 14:14:53 +02:00
semantic-release-bot
1b2b536d2e chore: Release v5.14.0-dev.9 [skip ci]
# [5.14.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.8...v5.14.0-dev.9) (2025-03-09)

### Features

* **Spotify:** Add `Spoof signature` patch ([#4576](https://github.com/ReVanced/revanced-patches/issues/4576)) ([f39e70c](f39e70c648))
2025-03-09 12:10:11 +00:00
oSumAtrIX
f39e70c648 feat(Spotify): Add Spoof signature patch (#4576) 2025-03-09 13:06:53 +01:00
semantic-release-bot
556acdd9c1 chore: Release v5.14.0-dev.8 [skip ci]
# [5.14.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.7...v5.14.0-dev.8) (2025-03-09)

### Bug Fixes

* **YouTube - Theme:** Resolve dark mode startup crash with Android 9.0 ([7adfc63](7adfc637dc))
2025-03-09 09:32:12 +00:00
LisoUseInAIKyrios
7adfc637dc fix(YouTube - Theme): Resolve dark mode startup crash with Android 9.0 2025-03-09 11:29:17 +02:00
github-actions[bot]
9cc0c075ad chore: Sync translations (#4575) 2025-03-09 11:28:52 +02:00
semantic-release-bot
ead11e7f46 chore: Release v5.14.0-dev.7 [skip ci]
# [5.14.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.6...v5.14.0-dev.7) (2025-03-08)

### Bug Fixes

* **YouTube:** Change language settings menu to use native language names ([#4568](https://github.com/ReVanced/revanced-patches/issues/4568)) ([e9bc201](e9bc201641))
2025-03-08 18:45:38 +00:00
LisoUseInAIKyrios
e9bc201641 fix(YouTube): Change language settings menu to use native language names (#4568) 2025-03-08 20:42:48 +02:00
github-actions[bot]
99baedf355 chore: Sync translations (#4573) 2025-03-08 20:42:13 +02:00
semantic-release-bot
0338d0acd3 chore: Release v5.14.0-dev.6 [skip ci]
# [5.14.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.5...v5.14.0-dev.6) (2025-03-07)

### Bug Fixes

* **YouTube - Hide layout components:** Do not hide Movie/Courses start page content if 'Hide horizontal shelves' is enabled ([99879f6](99879f6e0a))
2025-03-07 17:40:21 +00:00
LisoUseInAIKyrios
99879f6e0a fix(YouTube - Hide layout components): Do not hide Movie/Courses start page content if 'Hide horizontal shelves' is enabled 2025-03-07 19:37:23 +02:00
github-actions[bot]
f0c70de602 chore: Sync translations (#4562) 2025-03-07 19:35:55 +02:00
LisoUseInAIKyrios
737ae07a06 refactor(YouTube): Sort no title preference group by first sub preference title 2025-03-06 21:15:29 +02:00
semantic-release-bot
2c51de59de chore: Release v5.14.0-dev.5 [skip ci]
# [5.14.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.4...v5.14.0-dev.5) (2025-03-06)

### Features

* **Infinity for Reddit:** Add support for package name on IzzyOnDroid ([#4554](https://github.com/ReVanced/revanced-patches/issues/4554)) ([df3dc1c](df3dc1c0b2))
2025-03-06 18:27:44 +00:00
ILoveOpenSourceApplications
df3dc1c0b2 feat(Infinity for Reddit): Add support for package name on IzzyOnDroid (#4554) 2025-03-06 20:24:54 +02:00
github-actions[bot]
074c948581 chore: Sync translations (#4556) 2025-03-06 20:24:22 +02:00
semantic-release-bot
2a88b1f895 chore: Release v5.14.0-dev.4 [skip ci]
# [5.14.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.3...v5.14.0-dev.4) (2025-03-06)

### Bug Fixes

* **YouTube:** Combine `Restore old video quality menu` and `Remember video quality` into `Video quality` patch ([#4552](https://github.com/ReVanced/revanced-patches/issues/4552)) ([ee5c830](ee5c830df8))
2025-03-06 12:59:39 +00:00
LisoUseInAIKyrios
ee5c830df8 fix(YouTube): Combine Restore old video quality menu and Remember video quality into Video quality patch (#4552) 2025-03-06 14:56:32 +02:00
semantic-release-bot
e63a4b31f3 chore: Release v5.14.0-dev.3 [skip ci]
# [5.14.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.2...v5.14.0-dev.3) (2025-03-06)

### Bug Fixes

* **Boost for reddit - Client spoof:** Use a different user agent to combat Reddit's API issues ([8d0bca3](8d0bca3b03))
2025-03-06 10:36:52 +00:00
oSumAtrIX
8d0bca3b03 fix(Boost for reddit - Client spoof): Use a different user agent to combat Reddit's API issues 2025-03-06 11:33:06 +01:00
semantic-release-bot
c162d65d5b chore: Release v5.14.0-dev.2 [skip ci]
# [5.14.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.1...v5.14.0-dev.2) (2025-03-06)

### Bug Fixes

* **YouTube - Hide ads:** Hide new type of buttoned ad ([#4528](https://github.com/ReVanced/revanced-patches/issues/4528)) ([67dcd09](67dcd091c4))
2025-03-06 09:30:51 +00:00
ILoveOpenSourceApplications
67dcd091c4 fix(YouTube - Hide ads): Hide new type of buttoned ad (#4528) 2025-03-06 11:27:37 +02:00
github-actions[bot]
ac5ce2d67f chore: Sync translations (#4553) 2025-03-06 11:26:20 +02:00
LisoUseInAIKyrios
4b78d056fd ci: Pull Crowdin strings less often
Crowdin is starting to give errors and pulling less often may help.
2025-03-06 11:25:22 +02:00
semantic-release-bot
f8c901b2c1 chore: Release v5.14.0-dev.1 [skip ci]
# [5.14.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.13.1-dev.1...v5.14.0-dev.1) (2025-03-06)

### Features

* **YouTube - Remember video quality:** Add separate Shorts default quality settings ([#4543](https://github.com/ReVanced/revanced-patches/issues/4543)) ([2a67c31](2a67c312e1))
2025-03-06 06:49:39 +00:00
alieRN
2a67c312e1 feat(YouTube - Remember video quality): Add separate Shorts default quality settings (#4543) 2025-03-06 08:46:33 +02:00
semantic-release-bot
a7eed30f46 chore: Release v5.13.1-dev.1 [skip ci]
## [5.13.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.13.0...v5.13.1-dev.1) (2025-03-06)

### Bug Fixes

* **YouTube - Change form factor:** Restore Automotive form factor watch history menu, channel pages, and community posts ([#4541](https://github.com/ReVanced/revanced-patches/issues/4541)) ([e2de2d8](e2de2d8d44))
2025-03-06 06:28:57 +00:00
LisoUseInAIKyrios
e2de2d8d44 fix(YouTube - Change form factor): Restore Automotive form factor watch history menu, channel pages, and community posts (#4541) 2025-03-06 08:26:09 +02:00
github-actions[bot]
7ebbf356c0 chore: Sync translations (#4550) 2025-03-06 08:25:49 +02:00
ILoveOpenSourceApplications
2ced5c6e2a refactor(YouTube): Use more consistent strings (#4526) 2025-03-05 08:55:44 +02:00
semantic-release-bot
4a090ba659 chore: Release v5.13.0 [skip ci]
# [5.13.0](https://github.com/ReVanced/revanced-patches/compare/v5.12.0...v5.13.0) (2025-03-03)

### Bug Fixes

* **TikTok:** Resolve startup app crash ([3c52ab8](3c52ab8017))
* **TikTok:** Resolve startup app crash ([c817977](c8179776ed))
* **TikTok:** Resolve startup app crash ([d5aab3d](d5aab3d464))
* **TikTok:** Resolve startup app crash ([348f7e1](348f7e12cb))
* **YouTube - Copy video URL:** Use correct button ordering ([d77d5bf](d77d5bfbdd))
* **YouTube - Hide filter bar:** Fix `Hide in feed` not working in subscriptions feed ([#4512](https://github.com/ReVanced/revanced-patches/issues/4512)) ([1b60a72](1b60a72ede))
* **YouTube - Hide layout components:** Do not hide 'Show anyway' button in search results ([94fb367](94fb367618))
* **YouTube - Hide player components:** Show correct end video thumbnail if `Hide end screen suggested video` is enabled ([#4502](https://github.com/ReVanced/revanced-patches/issues/4502)) ([7cc939a](7cc939ab03))
* **YouTube - Hide video action buttons:** Move 'Disable Like and Subscribe glow' to action buttons settings menu ([7991c80](7991c80129))
* **YouTube - Return YouTube Dislike:** Use correct number formatting if using a different ReVanced language ([4ae1155](4ae1155e51))
* **YouTube - Spoof app version:** Force old settings menus if spoofing to older app targets ([#4490](https://github.com/ReVanced/revanced-patches/issues/4490)) ([0c0bbb8](0c0bbb8713))
* **YouTube - Spoof video streams:** Resolve playback issues with dynamic player config ([#4521](https://github.com/ReVanced/revanced-patches/issues/4521)) ([cbbf474](cbbf474c50))
* **YouTube - Swipe controls:** Adjust the overlay text size ([#4503](https://github.com/ReVanced/revanced-patches/issues/4503)) ([329f993](329f993024))
* **YouTube:** Do not hide player controls when using double tap to skip forward ([#4487](https://github.com/ReVanced/revanced-patches/issues/4487)) ([e664a24](e664a24f73))
* **YouTube:** Fix player button fade out animations ([#4469](https://github.com/ReVanced/revanced-patches/issues/4469)) ([a2c79f1](a2c79f1349))
* **YouTube:** Resolve button flickering when taping seekbar ([#4500](https://github.com/ReVanced/revanced-patches/issues/4500)) ([f5dd902](f5dd902915))

### Features

* **Infinity for Reddit:** Add support for Infinity for Reddit Plus ([#4511](https://github.com/ReVanced/revanced-patches/issues/4511)) ([fb8dbb4](fb8dbb4723))
* **NU.nl:** Add `Hide ads` and `Spoof Certificate` patch ([#4368](https://github.com/ReVanced/revanced-patches/issues/4368)) ([93ea250](93ea250bf3))
* **YouTube - Navigation buttons:** Add 'Hide notifications' setting ([#4485](https://github.com/ReVanced/revanced-patches/issues/4485)) ([d6eae01](d6eae01e12))
* **YouTube - Swipe controls:** Swipe controls UI improvements ([#4422](https://github.com/ReVanced/revanced-patches/issues/4422)) ([3548359](354835966d))
2025-03-03 07:01:16 +00:00
LisoUseInAIKyrios
cb609a6d9d chore: Merge branch dev to main (#4470) 2025-03-03 08:57:51 +02:00
github-actions[bot]
42e6de9e8f chore: Sync translations (#4525) 2025-03-03 08:55:55 +02:00
semantic-release-bot
c4a5b9a28c chore: Release v5.13.0-dev.19 [skip ci]
# [5.13.0-dev.19](https://github.com/ReVanced/revanced-patches/compare/v5.13.0-dev.18...v5.13.0-dev.19) (2025-03-02)

### Bug Fixes

* **YouTube - Spoof video streams:** Resolve playback issues with dynamic player config ([#4521](https://github.com/ReVanced/revanced-patches/issues/4521)) ([cbbf474](cbbf474c50))
2025-03-02 15:44:18 +00:00
github-actions[bot]
c86c85947f chore: Sync translations (#4523) 2025-03-02 17:40:33 +02:00
LisoUseInAIKyrios
cbbf474c50 fix(YouTube - Spoof video streams): Resolve playback issues with dynamic player config (#4521) 2025-03-02 17:38:43 +02:00
semantic-release-bot
f147b7b73d chore: Release v5.13.0-dev.18 [skip ci]
# [5.13.0-dev.18](https://github.com/ReVanced/revanced-patches/compare/v5.13.0-dev.17...v5.13.0-dev.18) (2025-02-28)

### Features

* **Infinity for Reddit:** Add support for Infinity for Reddit Plus ([#4511](https://github.com/ReVanced/revanced-patches/issues/4511)) ([fb8dbb4](fb8dbb4723))
2025-02-28 08:33:53 +00:00
tillcash
fb8dbb4723 feat(Infinity for Reddit): Add support for Infinity for Reddit Plus (#4511) 2025-02-28 10:31:02 +02:00
github-actions[bot]
1e0d27e689 chore: Sync translations (#4517) 2025-02-28 10:30:30 +02:00
166 changed files with 3340 additions and 4893 deletions

View File

@@ -2,7 +2,7 @@ name: Pull strings
on: on:
schedule: schedule:
- cron: "0 */6 * * *" - cron: "0 */12 * * *"
workflow_dispatch: workflow_dispatch:
jobs: jobs:

View File

@@ -1,3 +1,165 @@
# [5.15.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.15.0-dev.3...v5.15.0-dev.4) (2025-03-21)
### Bug Fixes
* **YouTube - Spoof app version:** Change oldest spoof target to 19.01.34 ([5012439](https://github.com/ReVanced/revanced-patches/commit/5012439a8e53b2a4ab5e85c47976e1ab28a51208))
# [5.15.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.15.0-dev.2...v5.15.0-dev.3) (2025-03-20)
### Bug Fixes
* **YouTube:** Do not show restart prompt more than once if setting change is canceled ([49797fe](https://github.com/ReVanced/revanced-patches/commit/49797fe8d0c4a0981ef621a31356c4315ae3777b))
# [5.15.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.15.0-dev.1...v5.15.0-dev.2) (2025-03-19)
### Bug Fixes
* **YouTube - Spoof app version:** Remove broken spoof targets that YouTube no longer supports ([#4610](https://github.com/ReVanced/revanced-patches/issues/4610)) ([883fbe7](https://github.com/ReVanced/revanced-patches/commit/883fbe71233c57cb1241e57c122b43f40722acc7))
# [5.15.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.14.0...v5.15.0-dev.1) (2025-03-19)
### Features
* **YouTube - SponsorBlock:** Add opacity setting to category segment colors ([#4582](https://github.com/ReVanced/revanced-patches/issues/4582)) ([6e8ffba](https://github.com/ReVanced/revanced-patches/commit/6e8ffbade9e03658f725622631e44dabf2995861))
# [5.14.0](https://github.com/ReVanced/revanced-patches/compare/v5.13.0...v5.14.0) (2025-03-09)
### Bug Fixes
* **Boost for reddit - Client spoof:** Use a different user agent to combat Reddit's API issues ([5d3c817](https://github.com/ReVanced/revanced-patches/commit/5d3c8175b34a3f6ae2732b25db0851773a8c000d))
* **YouTube - Change form factor:** Restore Automotive form factor watch history menu, channel pages, and community posts ([#4541](https://github.com/ReVanced/revanced-patches/issues/4541)) ([aa5c001](https://github.com/ReVanced/revanced-patches/commit/aa5c001968446e5270c756256724e917009612cd))
* **YouTube - Hide ads:** Hide new type of buttoned ad ([#4528](https://github.com/ReVanced/revanced-patches/issues/4528)) ([4387a7b](https://github.com/ReVanced/revanced-patches/commit/4387a7b131f49729e902e008bb4cec073635c040))
* **YouTube - Hide layout components:** Do not hide Movie/Courses start page content if 'Hide horizontal shelves' is enabled ([62a6164](https://github.com/ReVanced/revanced-patches/commit/62a6164b88b64200b517a5ba6b800d8214dbbad8))
* **YouTube - Theme:** Resolve dark mode startup crash with Android 9.0 ([741c2d5](https://github.com/ReVanced/revanced-patches/commit/741c2d59406f5d602554bb3a3c0b8982f42848b4))
* **YouTube:** Change language settings menu to use native language names ([#4568](https://github.com/ReVanced/revanced-patches/issues/4568)) ([6f3f8fd](https://github.com/ReVanced/revanced-patches/commit/6f3f8fdce05501e4fa4423c2170a916fbea3b199))
* **YouTube:** Combine `Restore old video quality menu` and `Remember video quality` into `Video quality` patch ([#4552](https://github.com/ReVanced/revanced-patches/issues/4552)) ([ee67b76](https://github.com/ReVanced/revanced-patches/commit/ee67b763d5c5947a5b1ef4420b1efa820ed6af83))
### Features
* **Infinity for Reddit:** Add support for package name on IzzyOnDroid ([#4554](https://github.com/ReVanced/revanced-patches/issues/4554)) ([cf9f959](https://github.com/ReVanced/revanced-patches/commit/cf9f959923076c10a7f0a29f6ba277f5a055ec07))
* **Spotify:** Add `Spoof signature` patch ([#4576](https://github.com/ReVanced/revanced-patches/issues/4576)) ([3646c70](https://github.com/ReVanced/revanced-patches/commit/3646c70556b67a6b7ecf9b86869ebf03c3611333))
* **YouTube - Remember video quality:** Add separate Shorts default quality settings ([#4543](https://github.com/ReVanced/revanced-patches/issues/4543)) ([88142ab](https://github.com/ReVanced/revanced-patches/commit/88142ab464192b564b1b8d56a6b45663f77f5e00))
# [5.14.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.8...v5.14.0-dev.9) (2025-03-09)
### Features
* **Spotify:** Add `Spoof signature` patch ([#4576](https://github.com/ReVanced/revanced-patches/issues/4576)) ([3646c70](https://github.com/ReVanced/revanced-patches/commit/3646c70556b67a6b7ecf9b86869ebf03c3611333))
# [5.14.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.7...v5.14.0-dev.8) (2025-03-09)
### Bug Fixes
* **YouTube - Theme:** Resolve dark mode startup crash with Android 9.0 ([741c2d5](https://github.com/ReVanced/revanced-patches/commit/741c2d59406f5d602554bb3a3c0b8982f42848b4))
# [5.14.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.6...v5.14.0-dev.7) (2025-03-08)
### Bug Fixes
* **YouTube:** Change language settings menu to use native language names ([#4568](https://github.com/ReVanced/revanced-patches/issues/4568)) ([6f3f8fd](https://github.com/ReVanced/revanced-patches/commit/6f3f8fdce05501e4fa4423c2170a916fbea3b199))
# [5.14.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.5...v5.14.0-dev.6) (2025-03-07)
### Bug Fixes
* **YouTube - Hide layout components:** Do not hide Movie/Courses start page content if 'Hide horizontal shelves' is enabled ([62a6164](https://github.com/ReVanced/revanced-patches/commit/62a6164b88b64200b517a5ba6b800d8214dbbad8))
# [5.14.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.4...v5.14.0-dev.5) (2025-03-06)
### Features
* **Infinity for Reddit:** Add support for package name on IzzyOnDroid ([#4554](https://github.com/ReVanced/revanced-patches/issues/4554)) ([cf9f959](https://github.com/ReVanced/revanced-patches/commit/cf9f959923076c10a7f0a29f6ba277f5a055ec07))
# [5.14.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.3...v5.14.0-dev.4) (2025-03-06)
### Bug Fixes
* **YouTube:** Combine `Restore old video quality menu` and `Remember video quality` into `Video quality` patch ([#4552](https://github.com/ReVanced/revanced-patches/issues/4552)) ([ee67b76](https://github.com/ReVanced/revanced-patches/commit/ee67b763d5c5947a5b1ef4420b1efa820ed6af83))
# [5.14.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.2...v5.14.0-dev.3) (2025-03-06)
### Bug Fixes
* **Boost for reddit - Client spoof:** Use a different user agent to combat Reddit's API issues ([5d3c817](https://github.com/ReVanced/revanced-patches/commit/5d3c8175b34a3f6ae2732b25db0851773a8c000d))
# [5.14.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.1...v5.14.0-dev.2) (2025-03-06)
### Bug Fixes
* **YouTube - Hide ads:** Hide new type of buttoned ad ([#4528](https://github.com/ReVanced/revanced-patches/issues/4528)) ([4387a7b](https://github.com/ReVanced/revanced-patches/commit/4387a7b131f49729e902e008bb4cec073635c040))
# [5.14.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.13.1-dev.1...v5.14.0-dev.1) (2025-03-06)
### Features
* **YouTube - Remember video quality:** Add separate Shorts default quality settings ([#4543](https://github.com/ReVanced/revanced-patches/issues/4543)) ([88142ab](https://github.com/ReVanced/revanced-patches/commit/88142ab464192b564b1b8d56a6b45663f77f5e00))
## [5.13.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.13.0...v5.13.1-dev.1) (2025-03-06)
### Bug Fixes
* **YouTube - Change form factor:** Restore Automotive form factor watch history menu, channel pages, and community posts ([#4541](https://github.com/ReVanced/revanced-patches/issues/4541)) ([aa5c001](https://github.com/ReVanced/revanced-patches/commit/aa5c001968446e5270c756256724e917009612cd))
# [5.13.0](https://github.com/ReVanced/revanced-patches/compare/v5.12.0...v5.13.0) (2025-03-03)
### Bug Fixes
* **TikTok:** Resolve startup app crash ([18c0fc2](https://github.com/ReVanced/revanced-patches/commit/18c0fc2a7f186f50a904fd25dbaa739abdd24993))
* **TikTok:** Resolve startup app crash ([6466398](https://github.com/ReVanced/revanced-patches/commit/64663983b84de1f28636205f61bf0a24c83968d1))
* **TikTok:** Resolve startup app crash ([c14bc24](https://github.com/ReVanced/revanced-patches/commit/c14bc244550de30eca975ca7c09e8eb0c47534b5))
* **TikTok:** Resolve startup app crash ([d700076](https://github.com/ReVanced/revanced-patches/commit/d7000768a5e5a688c9f4e48858ac34e352222c1e))
* **YouTube - Copy video URL:** Use correct button ordering ([5e622cc](https://github.com/ReVanced/revanced-patches/commit/5e622ccf66d34af31c6026fa7f4d332460c6ecb0))
* **YouTube - Hide filter bar:** Fix `Hide in feed` not working in subscriptions feed ([#4512](https://github.com/ReVanced/revanced-patches/issues/4512)) ([634d0ee](https://github.com/ReVanced/revanced-patches/commit/634d0ee12e31491c7ee1d4ceb002daf8366a3c15))
* **YouTube - Hide layout components:** Do not hide 'Show anyway' button in search results ([4ac8854](https://github.com/ReVanced/revanced-patches/commit/4ac8854b99808a8957f3b0b7438e1e0cdedffbaf))
* **YouTube - Hide player components:** Show correct end video thumbnail if `Hide end screen suggested video` is enabled ([#4502](https://github.com/ReVanced/revanced-patches/issues/4502)) ([6c4885a](https://github.com/ReVanced/revanced-patches/commit/6c4885a1d5dfff50100b01840b5552d92e83ee4a))
* **YouTube - Hide video action buttons:** Move 'Disable Like and Subscribe glow' to action buttons settings menu ([29b265d](https://github.com/ReVanced/revanced-patches/commit/29b265d8fdaa48502650be9623bfc518a57a0bb1))
* **YouTube - Return YouTube Dislike:** Use correct number formatting if using a different ReVanced language ([edf66f4](https://github.com/ReVanced/revanced-patches/commit/edf66f4e16d46156cb8b8e31d18cb8dbcb87737e))
* **YouTube - Spoof app version:** Force old settings menus if spoofing to older app targets ([#4490](https://github.com/ReVanced/revanced-patches/issues/4490)) ([45e7c46](https://github.com/ReVanced/revanced-patches/commit/45e7c46dd9c70c926b8b1a97ada668f90f5f6f8c))
* **YouTube - Spoof video streams:** Resolve playback issues with dynamic player config ([#4521](https://github.com/ReVanced/revanced-patches/issues/4521)) ([647e764](https://github.com/ReVanced/revanced-patches/commit/647e7642efc0c00db17ccb6a620d1c96ccf4afed))
* **YouTube - Swipe controls:** Adjust the overlay text size ([#4503](https://github.com/ReVanced/revanced-patches/issues/4503)) ([6dc4bf7](https://github.com/ReVanced/revanced-patches/commit/6dc4bf75e09ed6f05534919d7b769b720043abce))
* **YouTube:** Do not hide player controls when using double tap to skip forward ([#4487](https://github.com/ReVanced/revanced-patches/issues/4487)) ([63fe870](https://github.com/ReVanced/revanced-patches/commit/63fe870d48ca2217327b952bde241b7f16ced850))
* **YouTube:** Fix player button fade out animations ([#4469](https://github.com/ReVanced/revanced-patches/issues/4469)) ([bf8e775](https://github.com/ReVanced/revanced-patches/commit/bf8e7759f9bdbdfef419a879fb3dd7cf0dff0098))
* **YouTube:** Resolve button flickering when taping seekbar ([#4500](https://github.com/ReVanced/revanced-patches/issues/4500)) ([1f08047](https://github.com/ReVanced/revanced-patches/commit/1f08047b48cc9555a4887d16ec7219a55a77251f))
### Features
* **Infinity for Reddit:** Add support for Infinity for Reddit Plus ([#4511](https://github.com/ReVanced/revanced-patches/issues/4511)) ([d74732b](https://github.com/ReVanced/revanced-patches/commit/d74732b7596104321bde263201d95649e4bd0eee))
* **NU.nl:** Add `Hide ads` and `Spoof Certificate` patch ([#4368](https://github.com/ReVanced/revanced-patches/issues/4368)) ([f3268fb](https://github.com/ReVanced/revanced-patches/commit/f3268fb03ca25fb5465e36015b6c9dec2c84a655))
* **YouTube - Navigation buttons:** Add 'Hide notifications' setting ([#4485](https://github.com/ReVanced/revanced-patches/issues/4485)) ([506d241](https://github.com/ReVanced/revanced-patches/commit/506d2414bbc760e764e5a514b32926083d6ecb6b))
* **YouTube - Swipe controls:** Swipe controls UI improvements ([#4422](https://github.com/ReVanced/revanced-patches/issues/4422)) ([198e4d2](https://github.com/ReVanced/revanced-patches/commit/198e4d2a2315c24a09eb9ecfefbd131a75384d2c))
# [5.13.0-dev.19](https://github.com/ReVanced/revanced-patches/compare/v5.13.0-dev.18...v5.13.0-dev.19) (2025-03-02)
### Bug Fixes
* **YouTube - Spoof video streams:** Resolve playback issues with dynamic player config ([#4521](https://github.com/ReVanced/revanced-patches/issues/4521)) ([647e764](https://github.com/ReVanced/revanced-patches/commit/647e7642efc0c00db17ccb6a620d1c96ccf4afed))
# [5.13.0-dev.18](https://github.com/ReVanced/revanced-patches/compare/v5.13.0-dev.17...v5.13.0-dev.18) (2025-02-28)
### Features
* **Infinity for Reddit:** Add support for Infinity for Reddit Plus ([#4511](https://github.com/ReVanced/revanced-patches/issues/4511)) ([d74732b](https://github.com/ReVanced/revanced-patches/commit/d74732b7596104321bde263201d95649e4bd0eee))
# [5.13.0-dev.17](https://github.com/ReVanced/revanced-patches/compare/v5.13.0-dev.16...v5.13.0-dev.17) (2025-02-27) # [5.13.0-dev.17](https://github.com/ReVanced/revanced-patches/compare/v5.13.0-dev.16...v5.13.0-dev.17) (2025-02-27)

View File

@@ -362,27 +362,18 @@ public class Utils {
} }
public static void setContext(Context appContext) { public static void setContext(Context appContext) {
// Must initially set context as the language settings needs it. // Must initially set context to check the app language.
context = appContext; context = appContext;
Logger.initializationInfo(Utils.class, "Set context: " + appContext);
AppLanguage language = BaseSettings.REVANCED_LANGUAGE.get(); AppLanguage language = BaseSettings.REVANCED_LANGUAGE.get();
if (language != AppLanguage.DEFAULT) { if (language != AppLanguage.DEFAULT) {
// Create a new context with the desired language. // Create a new context with the desired language.
Logger.printDebug(() -> "Using app language: " + language);
Configuration config = appContext.getResources().getConfiguration(); Configuration config = appContext.getResources().getConfiguration();
config.setLocale(language.getLocale()); config.setLocale(language.getLocale());
context = appContext.createConfigurationContext(config); context = appContext.createConfigurationContext(config);
} }
// In some apps like TikTok, the Setting classes can load in weird orders due to cyclic class dependencies.
// Calling the regular printDebug method here can cause a Settings context null pointer exception,
// even though the context is already set before the call.
//
// The initialization logger methods do not directly or indirectly
// reference the Context or any Settings and are unaffected by this problem.
//
// Info level also helps debug if a patch hook is called before
// the context is set since debug logging is off by default.
Logger.initializationInfo(Utils.class, "Set context: " + appContext);
} }
public static void setClipboard(@NonNull String text) { public static void setClipboard(@NonNull String text) {

View File

@@ -8,6 +8,9 @@ public enum AppLanguage {
*/ */
DEFAULT, DEFAULT,
// Languages codes not included with YouTube, but are translated on Crowdin
GA,
// Language codes found in locale_config.xml // Language codes found in locale_config.xml
// All region specific variants have been removed. // All region specific variants have been removed.
AF, AF,

View File

@@ -22,12 +22,23 @@ import app.revanced.extension.shared.settings.Setting;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public abstract class AbstractPreferenceFragment extends PreferenceFragment { public abstract class AbstractPreferenceFragment extends PreferenceFragment {
/** /**
* Indicates that if a preference changes, * Indicates that if a preference changes,
* to apply the change from the Setting to the UI component. * to apply the change from the Setting to the UI component.
*/ */
public static boolean settingImportInProgress; public static boolean settingImportInProgress;
/**
* Prevents recursive calls during preference <-> UI syncing from showing extra dialogs.
*/
private static boolean updatingPreference;
/**
* Used to prevent showing reboot dialog, if user cancels a setting user dialog.
*/
private static boolean showingUserDialogMessage;
/** /**
* Confirm and restart dialog button text and title. * Confirm and restart dialog button text and title.
* Set by subclasses if Strings cannot be added as a resource. * Set by subclasses if Strings cannot be added as a resource.
@@ -35,13 +46,13 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
@Nullable @Nullable
protected static String restartDialogButtonText, restartDialogTitle, confirmDialogTitle; protected static String restartDialogButtonText, restartDialogTitle, confirmDialogTitle;
/**
* Used to prevent showing reboot dialog, if user cancels a setting user dialog.
*/
private boolean showingUserDialogMessage;
private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> { private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
try { try {
if (updatingPreference) {
Logger.printDebug(() -> "Ignoring preference change as sync is in progress");
return;
}
Setting<?> setting = Setting.getSettingFromPath(Objects.requireNonNull(str)); Setting<?> setting = Setting.getSettingFromPath(Objects.requireNonNull(str));
if (setting == null) { if (setting == null) {
return; return;
@@ -63,10 +74,13 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
} }
} }
updatingPreference = true;
// Apply 'Setting <- Preference', unless during importing when it needs to be 'Setting -> Preference'. // Apply 'Setting <- Preference', unless during importing when it needs to be 'Setting -> Preference'.
// Updating here can can cause a recursive call back into this same method.
updatePreference(pref, setting, true, settingImportInProgress); updatePreference(pref, setting, true, settingImportInProgress);
// Update any other preference availability that may now be different. // Update any other preference availability that may now be different.
updateUIAvailability(); updateUIAvailability();
updatingPreference = false;
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "OnSharedPreferenceChangeListener failure", ex); Logger.printException(() -> "OnSharedPreferenceChangeListener failure", ex);
} }
@@ -97,7 +111,9 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
if (confirmDialogTitle == null) { if (confirmDialogTitle == null) {
confirmDialogTitle = str("revanced_settings_confirm_user_dialog_title"); confirmDialogTitle = str("revanced_settings_confirm_user_dialog_title");
} }
showingUserDialogMessage = true; showingUserDialogMessage = true;
new AlertDialog.Builder(context) new AlertDialog.Builder(context)
.setTitle(confirmDialogTitle) .setTitle(confirmDialogTitle)
.setMessage(Objects.requireNonNull(setting.userDialogMessage).toString()) .setMessage(Objects.requireNonNull(setting.userDialogMessage).toString())
@@ -141,14 +157,16 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
* @return If the preference is currently set to the default value of the Setting. * @return If the preference is currently set to the default value of the Setting.
*/ */
protected boolean prefIsSetToDefault(Preference pref, Setting<?> setting) { protected boolean prefIsSetToDefault(Preference pref, Setting<?> setting) {
Object defaultValue = setting.defaultValue;
if (pref instanceof SwitchPreference switchPref) { if (pref instanceof SwitchPreference switchPref) {
return switchPref.isChecked() == (Boolean) setting.defaultValue; return switchPref.isChecked() == (Boolean) defaultValue;
} }
String defaultValueString = defaultValue.toString();
if (pref instanceof EditTextPreference editPreference) { if (pref instanceof EditTextPreference editPreference) {
return editPreference.getText().equals(setting.defaultValue.toString()); return editPreference.getText().equals(defaultValueString);
} }
if (pref instanceof ListPreference listPref) { if (pref instanceof ListPreference listPref) {
return listPref.getValue().equals(setting.defaultValue.toString()); return listPref.getValue().equals(defaultValueString);
} }
throw new IllegalStateException("Must override method to handle " throw new IllegalStateException("Must override method to handle "
@@ -158,16 +176,16 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
/** /**
* Syncs all UI Preferences to any {@link Setting} they represent. * Syncs all UI Preferences to any {@link Setting} they represent.
*/ */
private void updatePreferenceScreen(@NonNull PreferenceScreen screen, private void updatePreferenceScreen(@NonNull PreferenceGroup group,
boolean syncSettingValue, boolean syncSettingValue,
boolean applySettingToPreference) { boolean applySettingToPreference) {
// Alternatively this could iterate thru all Settings and check for any matching Preferences, // Alternatively this could iterate thru all Settings and check for any matching Preferences,
// but there are many more Settings than UI preferences so it's more efficient to only check // but there are many more Settings than UI preferences so it's more efficient to only check
// the Preferences. // the Preferences.
for (int i = 0, prefCount = screen.getPreferenceCount(); i < prefCount; i++) { for (int i = 0, prefCount = group.getPreferenceCount(); i < prefCount; i++) {
Preference pref = screen.getPreference(i); Preference pref = group.getPreference(i);
if (pref instanceof PreferenceScreen) { if (pref instanceof PreferenceGroup subGroup) {
updatePreferenceScreen((PreferenceScreen) pref, syncSettingValue, applySettingToPreference); updatePreferenceScreen(subGroup, syncSettingValue, applySettingToPreference);
} else if (pref.hasKey()) { } else if (pref.hasKey()) {
String key = pref.getKey(); String key = pref.getKey();
Setting<?> setting = Setting.getSettingFromPath(key); Setting<?> setting = Setting.getSettingFromPath(key);
@@ -255,7 +273,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
} }
} }
public static void showRestartDialog(@NonNull final Context context) { public static void showRestartDialog(Context context) {
Utils.verifyOnMainThread(); Utils.verifyOnMainThread();
if (restartDialogTitle == null) { if (restartDialogTitle == null) {
restartDialogTitle = str("revanced_settings_restart_title"); restartDialogTitle = str("revanced_settings_restart_title");
@@ -263,6 +281,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
if (restartDialogButtonText == null) { if (restartDialogButtonText == null) {
restartDialogButtonText = str("revanced_settings_restart"); restartDialogButtonText = str("revanced_settings_restart");
} }
new AlertDialog.Builder(context) new AlertDialog.Builder(context)
.setMessage(restartDialogTitle) .setMessage(restartDialogTitle)
.setPositiveButton(restartDialogButtonText, (dialog, id) .setPositiveButton(restartDialogButtonText, (dialog, id)

View File

@@ -0,0 +1,54 @@
package app.revanced.extension.shared.settings.preference;
import android.annotation.SuppressLint;
import android.content.Context;
import android.preference.PreferenceCategory;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
/**
* Empty preference category with no title, used to organize and group related preferences together.
*/
@SuppressWarnings({"unused", "deprecation"})
public class NoTitlePreferenceCategory extends PreferenceCategory {
public NoTitlePreferenceCategory(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NoTitlePreferenceCategory(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public NoTitlePreferenceCategory(Context context) {
super(context);
}
@Override
@SuppressLint("MissingSuperCall")
protected View onCreateView(ViewGroup parent) {
// Return an zero-height view to eliminate empty title space.
return new View(getContext());
}
@Override
public CharSequence getTitle() {
// Title can be used for sorting. Return the first sub preference title.
if (getPreferenceCount() > 0) {
return getPreference(0).getTitle();
}
return super.getTitle();
}
@Override
public int getTitleRes() {
if (getPreferenceCount() > 0) {
return getPreference(0).getTitleRes();
}
return super.getTitleRes();
}
}

View File

@@ -1,5 +1,7 @@
package app.revanced.extension.shared.settings.preference; package app.revanced.extension.shared.settings.preference;
import static app.revanced.extension.shared.StringRef.str;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
@@ -8,17 +10,23 @@ import android.util.AttributeSet;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import app.revanced.extension.shared.Utils; import androidx.annotation.Nullable;
import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.shared.Logger;
import java.util.Objects; import java.util.Objects;
import static app.revanced.extension.shared.StringRef.str; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.Setting;
@SuppressWarnings({"unused", "deprecation"}) @SuppressWarnings({"unused", "deprecation"})
public class ResettableEditTextPreference extends EditTextPreference { public class ResettableEditTextPreference extends EditTextPreference {
/**
* Setting to reset.
*/
@Nullable
private Setting<?> setting;
public ResettableEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { public ResettableEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes); super(context, attrs, defStyleAttr, defStyleRes);
} }
@@ -32,12 +40,22 @@ public class ResettableEditTextPreference extends EditTextPreference {
super(context); super(context);
} }
public void setSetting(@Nullable Setting<?> setting) {
this.setting = setting;
}
@Override @Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder); super.onPrepareDialogBuilder(builder);
Utils.setEditTextDialogTheme(builder); Utils.setEditTextDialogTheme(builder);
Setting<?> setting = Setting.getSettingFromPath(getKey()); if (setting == null) {
String key = getKey();
if (key != null) {
setting = Setting.getSettingFromPath(key);
}
}
if (setting != null) { if (setting != null) {
builder.setNeutralButton(str("revanced_settings_reset"), null); builder.setNeutralButton(str("revanced_settings_reset"), null);
} }
@@ -54,8 +72,7 @@ public class ResettableEditTextPreference extends EditTextPreference {
} }
button.setOnClickListener(v -> { button.setOnClickListener(v -> {
try { try {
Setting<?> setting = Objects.requireNonNull(Setting.getSettingFromPath(getKey())); String defaultStringValue = Objects.requireNonNull(setting).defaultValue.toString();
String defaultStringValue = setting.defaultValue.toString();
EditText editText = getEditText(); EditText editText = getEditText();
editText.setText(defaultStringValue); editText.setText(defaultStringValue);
editText.setSelection(defaultStringValue.length()); // move cursor to end of text editText.setSelection(defaultStringValue.length()); // move cursor to end of text

View File

@@ -107,6 +107,21 @@ public class SpoofVideoStreamsPatch {
return false; return false;
} }
/**
* Injection point.
* Turns off a feature flag that interferes with spoofing.
*/
public static boolean useMediaFetchHotConfigReplacement(boolean original) {
if (original) {
Logger.printDebug(() -> "useMediaFetchHotConfigReplacement is set on");
}
if (!SPOOF_STREAMING_DATA) {
return original;
}
return false;
}
/** /**
* Injection point. * Injection point.
*/ */

View File

@@ -1,7 +1,7 @@
package app.revanced.extension.youtube.patches; package app.revanced.extension.youtube.patches;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.PlayerType; import app.revanced.extension.youtube.shared.ShortsPlayerState;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class BackgroundPlaybackPatch { public class BackgroundPlaybackPatch {
@@ -23,16 +23,7 @@ public class BackgroundPlaybackPatch {
// 7. Close the Short // 7. Close the Short
// 8. Resume playing the regular video // 8. Resume playing the regular video
// 9. Minimize the app (PIP should appear) // 9. Minimize the app (PIP should appear)
if (!VideoInformation.lastVideoIdIsShort()) { return !ShortsPlayerState.isOpen();
return true; // Definitely is not a Short.
}
// TODO: Add better hook.
// Might be a Shorts, or might be a prior regular video on screen again after a Shorts was closed.
// This incorrectly prevents PIP if player is in WATCH_WHILE_MINIMIZED after closing a Shorts,
// But there's no way around this unless an additional hook is added to definitively detect
// the Shorts player is on screen. This use case is unusual anyways so it's not a huge concern.
return !PlayerType.getCurrent().isNoneHiddenOrMinimized();
} }
/** /**

View File

@@ -1,9 +1,17 @@
package app.revanced.extension.youtube.patches; package app.revanced.extension.youtube.patches;
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton;
import android.view.View;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import app.revanced.extension.shared.Utils; import java.util.Objects;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.NavigationBar;
import app.revanced.extension.youtube.shared.PlayerType;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class ChangeFormFactorPatch { public class ChangeFormFactorPatch {
@@ -41,14 +49,57 @@ public class ChangeFormFactorPatch {
@Nullable @Nullable
private static final Integer FORM_FACTOR_TYPE = Settings.CHANGE_FORM_FACTOR.get().formFactorType; private static final Integer FORM_FACTOR_TYPE = Settings.CHANGE_FORM_FACTOR.get().formFactorType;
private static final boolean USING_AUTOMOTIVE_TYPE = Objects.requireNonNull(
FormFactor.AUTOMOTIVE.formFactorType).equals(FORM_FACTOR_TYPE);
/** /**
* Injection point. * Injection point.
*/ */
public static int getFormFactor(int original) { public static int getFormFactor(int original) {
return FORM_FACTOR_TYPE == null if (FORM_FACTOR_TYPE == null) return original;
? original
: FORM_FACTOR_TYPE; if (USING_AUTOMOTIVE_TYPE) {
// Do not change if the player is opening or is opened,
// otherwise the video description cannot be opened.
PlayerType current = PlayerType.getCurrent();
if (current.isMaximizedOrFullscreen() || current == PlayerType.WATCH_WHILE_SLIDING_MINIMIZED_MAXIMIZED) {
Logger.printDebug(() -> "Using original form factor for player");
return original;
}
if (!NavigationBar.isSearchBarActive()) {
// Automotive type shows error 400 when opening a channel page and using some explore tab.
// This is a bug in unpatched YouTube that occurs on actual Android Automotive devices.
// Work around the issue by using the original form factor if not in search and the
// navigation back button is present.
if (NavigationBar.isBackButtonVisible()) {
Logger.printDebug(() -> "Using original form factor, as back button is visible without search present");
return original;
}
// Do not change library tab otherwise watch history is hidden.
// Do this check last since the current navigation button is required.
if (NavigationButton.getSelectedNavigationButton() == NavigationButton.LIBRARY) {
return original;
}
}
}
return FORM_FACTOR_TYPE;
} }
/**
* Injection point.
*/
public static void navigationTabCreated(NavigationButton button, View tabView) {
// On first startup of the app the navigation buttons are fetched and updated.
// If the user immediately opens the 'You' or opens a video, then the call to
// update the navigtation buttons will use the non automotive form factor
// and the explore tab is missing.
// Fixing this is not so simple because of the concurrent calls for the player and You tab.
// For now, always hide the explore tab.
if (USING_AUTOMOTIVE_TYPE && button == NavigationButton.EXPLORE) {
tabView.setVisibility(View.GONE);
}
}
} }

View File

@@ -1,7 +1,7 @@
package app.revanced.extension.youtube.patches; package app.revanced.extension.youtube.patches;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.PlayerType; import app.revanced.extension.youtube.shared.ShortsPlayerState;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class DisableAutoCaptionsPatch { public class DisableAutoCaptionsPatch {
@@ -14,7 +14,7 @@ public class DisableAutoCaptionsPatch {
public static boolean autoCaptionsEnabled() { public static boolean autoCaptionsEnabled() {
return Settings.AUTO_CAPTIONS.get() return Settings.AUTO_CAPTIONS.get()
// Do not use auto captions for Shorts. // Do not use auto captions for Shorts.
&& !PlayerType.getCurrent().isNoneHiddenOrSlidingMinimized(); && ShortsPlayerState.isOpen();
} }
} }

View File

@@ -24,7 +24,7 @@ public final class EnableDebuggingPatch {
/** /**
* Injection point. * Injection point.
*/ */
public static boolean isBooleanFeatureFlagEnabled(boolean value, long flag) { public static boolean isBooleanFeatureFlagEnabled(boolean value, Long flag) {
if (LOG_FEATURE_FLAGS && value) { if (LOG_FEATURE_FLAGS && value) {
if (featureFlags.putIfAbsent(flag, true) == null) { if (featureFlags.putIfAbsent(flag, true) == null) {
Logger.printDebug(() -> "boolean feature is enabled: " + flag); Logger.printDebug(() -> "boolean feature is enabled: " + flag);

View File

@@ -1,8 +1,11 @@
package app.revanced.extension.youtube.patches; package app.revanced.extension.youtube.patches;
import android.view.View;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import app.revanced.extension.youtube.shared.PlayerType; import app.revanced.extension.youtube.shared.PlayerType;
import app.revanced.extension.youtube.shared.ShortsPlayerState;
import app.revanced.extension.youtube.shared.VideoState; import app.revanced.extension.youtube.shared.VideoState;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@@ -24,4 +27,26 @@ public class PlayerTypeHookPatch {
VideoState.setFromString(youTubeVideoState.name()); VideoState.setFromString(youTubeVideoState.name());
} }
/**
* Injection point.
*
* Add a listener to the shorts player overlay View.
* Triggered when a shorts player is attached or detached to Windows.
*
* @param view shorts player overlay (R.id.reel_watch_player).
*/
public static void onShortsCreate(View view) {
view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(@Nullable View v) {
ShortsPlayerState.setOpen(true);
}
@Override
public void onViewDetachedFromWindow(@Nullable View v) {
ShortsPlayerState.setOpen(false);
}
});
}
} }

View File

@@ -21,7 +21,6 @@ import java.util.Objects;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.patches.components.ReturnYouTubeDislikeFilterPatch; import app.revanced.extension.youtube.patches.components.ReturnYouTubeDislikeFilterPatch;
import app.revanced.extension.youtube.patches.spoof.SpoofAppVersionPatch;
import app.revanced.extension.youtube.returnyoutubedislike.ReturnYouTubeDislike; import app.revanced.extension.youtube.returnyoutubedislike.ReturnYouTubeDislike;
import app.revanced.extension.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi; import app.revanced.extension.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
@@ -47,9 +46,6 @@ import app.revanced.extension.youtube.shared.PlayerType;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class ReturnYouTubeDislikePatch { public class ReturnYouTubeDislikePatch {
public static final boolean IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER =
SpoofAppVersionPatch.isSpoofingToLessThan("18.34.00");
/** /**
* RYD data for the current video on screen. * RYD data for the current video on screen.
*/ */
@@ -347,137 +343,6 @@ public class ReturnYouTubeDislikePatch {
} }
} }
//
// Non litho Shorts player.
//
/**
* Replacement text to use for "Dislikes" while RYD is fetching.
*/
private static final Spannable SHORTS_LOADING_SPAN = new SpannableString("-");
/**
* Dislikes TextViews used by Shorts.
*
* Multiple TextViews are loaded at once (for the prior and next videos to swipe to).
* Keep track of all of them, and later pick out the correct one based on their on screen position.
*/
private static final List<WeakReference<TextView>> shortsTextViewRefs = new ArrayList<>();
private static void clearRemovedShortsTextViews() {
shortsTextViewRefs.removeIf(ref -> ref.get() == null);
}
/**
* Injection point. Called when a Shorts dislike is updated. Always on main thread.
* Handles update asynchronously, otherwise Shorts video will be frozen while the UI thread is blocked.
*
* @return if RYD is enabled and the TextView was updated.
*/
public static boolean setShortsDislikes(@NonNull View likeDislikeView) {
try {
if (!Settings.RYD_ENABLED.get()) {
return false;
}
if (!Settings.RYD_SHORTS.get() || Settings.HIDE_SHORTS_DISLIKE_BUTTON.get()) {
// Must clear the data here, in case a new video was loaded while PlayerType
// suggested the video was not a short (can happen when spoofing to an old app version).
clearData();
return false;
}
Logger.printDebug(() -> "setShortsDislikes");
TextView textView = (TextView) likeDislikeView;
textView.setText(SHORTS_LOADING_SPAN); // Change 'Dislike' text to the loading text.
shortsTextViewRefs.add(new WeakReference<>(textView));
if (likeDislikeView.isSelected() && isShortTextViewOnScreen(textView)) {
Logger.printDebug(() -> "Shorts dislike is already selected");
ReturnYouTubeDislike videoData = currentVideoData;
if (videoData != null) videoData.setUserVote(Vote.DISLIKE);
}
// For the first short played, the Shorts dislike hook is called after the video id hook.
// But for most other times this hook is called before the video id (which is not ideal).
// Must update the TextViews here, and also after the videoId changes.
updateOnScreenShortsTextViews(false);
return true;
} catch (Exception ex) {
Logger.printException(() -> "setShortsDislikes failure", ex);
return false;
}
}
/**
* @param forceUpdate if false, then only update the 'loading text views.
* If true, update all on screen text views.
*/
private static void updateOnScreenShortsTextViews(boolean forceUpdate) {
try {
clearRemovedShortsTextViews();
if (shortsTextViewRefs.isEmpty()) {
return;
}
ReturnYouTubeDislike videoData = currentVideoData;
if (videoData == null) {
return;
}
Logger.printDebug(() -> "updateShortsTextViews");
Runnable update = () -> {
Spanned shortsDislikesSpan = videoData.getDislikeSpanForShort(SHORTS_LOADING_SPAN);
Utils.runOnMainThreadNowOrLater(() -> {
String videoId = videoData.getVideoId();
if (!videoId.equals(VideoInformation.getVideoId())) {
// User swiped to new video before fetch completed
Logger.printDebug(() -> "Ignoring stale dislikes data for short: " + videoId);
return;
}
// Update text views that appear to be visible on screen.
// Only 1 will be the actual textview for the current Short,
// but discarded and not yet garbage collected views can remain.
// So must set the dislike span on all views that match.
for (WeakReference<TextView> textViewRef : shortsTextViewRefs) {
TextView textView = textViewRef.get();
if (textView == null) {
continue;
}
if (isShortTextViewOnScreen(textView)
&& (forceUpdate || textView.getText().toString().equals(SHORTS_LOADING_SPAN.toString()))) {
Logger.printDebug(() -> "Setting Shorts TextView to: " + shortsDislikesSpan);
textView.setText(shortsDislikesSpan);
}
}
});
};
if (videoData.fetchCompleted()) {
update.run(); // Network call is completed, no need to wait on background thread.
} else {
Utils.runOnBackgroundThread(update);
}
} catch (Exception ex) {
Logger.printException(() -> "updateOnScreenShortsTextViews failure", ex);
}
}
/**
* Check if a view is within the screen bounds.
*/
private static boolean isShortTextViewOnScreen(@NonNull View view) {
final int[] location = new int[2];
view.getLocationInWindow(location);
if (location[0] <= 0 && location[1] <= 0) { // Lower bound
return false;
}
Rect windowRect = new Rect();
view.getWindowVisibleDisplayFrame(windowRect); // Upper bound
return location[0] < windowRect.width() && location[1] < windowRect.height();
}
// //
// Video Id and voting hooks (all players). // Video Id and voting hooks (all players).
// //
@@ -503,8 +368,7 @@ public class ReturnYouTubeDislikePatch {
if (videoIdIsShort && (!isShortAndOpeningOrPlaying || !Settings.RYD_SHORTS.get())) { if (videoIdIsShort && (!isShortAndOpeningOrPlaying || !Settings.RYD_SHORTS.get())) {
return; return;
} }
final boolean waitForFetchToComplete = !IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER final boolean waitForFetchToComplete = videoIdIsShort && !lastPlayerResponseWasShort;
&& videoIdIsShort && !lastPlayerResponseWasShort;
Logger.printDebug(() -> "Prefetching RYD for video: " + videoId); Logger.printDebug(() -> "Prefetching RYD for video: " + videoId);
ReturnYouTubeDislike fetch = ReturnYouTubeDislike.getFetchForVideoId(videoId); ReturnYouTubeDislike fetch = ReturnYouTubeDislike.getFetchForVideoId(videoId);
@@ -557,12 +421,6 @@ public class ReturnYouTubeDislikePatch {
data.setVideoIdIsShort(true); data.setVideoIdIsShort(true);
} }
currentVideoData = data; currentVideoData = data;
// Current video id hook can be called out of order with the non litho Shorts text view hook.
// Must manually update again here.
if (isNoneHiddenOrSlidingMinimized) {
updateOnScreenShortsTextViews(true);
}
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "newVideoLoaded failure", ex); Logger.printException(() -> "newVideoLoaded failure", ex);
} }

View File

@@ -74,6 +74,7 @@ public final class AdsFilter extends Filter {
"video_display_button_group_layout", "video_display_button_group_layout",
"landscape_image_wide_button_layout", "landscape_image_wide_button_layout",
"video_display_carousel_button_group_layout", "video_display_carousel_button_group_layout",
"video_display_full_buttoned_short_dr_layout",
"compact_landscape_image_layout", // Tablet layout search results. "compact_landscape_image_layout", // Tablet layout search results.
"text_image_no_button_layout" // Tablet layout search results. "text_image_no_button_layout" // Tablet layout search results.
); );

View File

@@ -2,20 +2,20 @@ package app.revanced.extension.youtube.patches.components;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import app.revanced.extension.youtube.patches.playback.quality.RestoreOldVideoQualityMenuPatch; import app.revanced.extension.youtube.patches.playback.quality.AdvancedVideoQualityMenuPatch;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
/** /**
* Abuse LithoFilter for {@link RestoreOldVideoQualityMenuPatch}. * Abuse LithoFilter for {@link AdvancedVideoQualityMenuPatch}.
*/ */
public final class VideoQualityMenuFilterPatch extends Filter { public final class AdvancedVideoQualityMenuFilter extends Filter {
// Must be volatile or synchronized, as litho filtering runs off main thread // Must be volatile or synchronized, as litho filtering runs off main thread
// and this field is then access from the main thread. // and this field is then access from the main thread.
public static volatile boolean isVideoQualityMenuVisible; public static volatile boolean isVideoQualityMenuVisible;
public VideoQualityMenuFilterPatch() { public AdvancedVideoQualityMenuFilter() {
addPathCallbacks(new StringFilterGroup( addPathCallbacks(new StringFilterGroup(
Settings.RESTORE_OLD_VIDEO_QUALITY_MENU, Settings.ADVANCED_VIDEO_QUALITY_MENU,
"quick_quality_sheet_content.eml-js" "quick_quality_sheet_content.eml-js"
)); ));
} }

View File

@@ -462,6 +462,12 @@ public final class LayoutComponentsFilter extends Filter {
return true; return true;
} }
// Do not hide if the navigation back button is visible,
// otherwise the content shelves in the YouTube Movie/Courses pages is hidden.
if (NavigationBar.isBackButtonVisible()) {
return false;
}
// Check navigation button last. // Check navigation button last.
// Only filter if the library tab is not selected. // Only filter if the library tab is not selected.
// This check is important as the shelf layout is used for the library tab playlists. // This check is important as the shelf layout is used for the library tab playlists.

View File

@@ -8,30 +8,30 @@ import android.widget.ListView;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.patches.components.VideoQualityMenuFilterPatch; import app.revanced.extension.youtube.patches.components.AdvancedVideoQualityMenuFilter;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
/** /**
* This patch contains the logic to show the old video quality menu. * This patch contains the logic to always open the advanced video quality menu.
* Two methods are required, because the quality menu is a RecyclerView in the new YouTube version * Two methods are required, because the quality menu is a RecyclerView in the new YouTube version
* and a ListView in the old one. * and a ListView in the old one.
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class RestoreOldVideoQualityMenuPatch { public final class AdvancedVideoQualityMenuPatch {
/** /**
* Injection point. * Injection point.
*/ */
public static void onFlyoutMenuCreate(RecyclerView recyclerView) { public static void onFlyoutMenuCreate(RecyclerView recyclerView) {
if (!Settings.RESTORE_OLD_VIDEO_QUALITY_MENU.get()) return; if (!Settings.ADVANCED_VIDEO_QUALITY_MENU.get()) return;
recyclerView.getViewTreeObserver().addOnDrawListener(() -> { recyclerView.getViewTreeObserver().addOnDrawListener(() -> {
try { try {
// Check if the current view is the quality menu. // Check if the current view is the quality menu.
if (!VideoQualityMenuFilterPatch.isVideoQualityMenuVisible || recyclerView.getChildCount() == 0) { if (!AdvancedVideoQualityMenuFilter.isVideoQualityMenuVisible || recyclerView.getChildCount() == 0) {
return; return;
} }
VideoQualityMenuFilterPatch.isVideoQualityMenuVisible = false; AdvancedVideoQualityMenuFilter.isVideoQualityMenuVisible = false;
ViewParent quickQualityViewParent = Utils.getParentView(recyclerView, 3); ViewParent quickQualityViewParent = Utils.getParentView(recyclerView, 3);
if (!(quickQualityViewParent instanceof ViewGroup)) { if (!(quickQualityViewParent instanceof ViewGroup)) {
@@ -39,16 +39,15 @@ public final class RestoreOldVideoQualityMenuPatch {
} }
View firstChild = recyclerView.getChildAt(0); View firstChild = recyclerView.getChildAt(0);
if (!(firstChild instanceof ViewGroup)) { if (!(firstChild instanceof ViewGroup firstChildGroup)) {
return; return;
} }
ViewGroup advancedQualityParentView = (ViewGroup) firstChild; if (firstChildGroup.getChildCount() < 4) {
if (advancedQualityParentView.getChildCount() < 4) {
return; return;
} }
View advancedQualityView = advancedQualityParentView.getChildAt(3); View advancedQualityView = firstChildGroup.getChildAt(3);
if (advancedQualityView == null) { if (advancedQualityView == null) {
return; return;
} }
@@ -71,7 +70,7 @@ public final class RestoreOldVideoQualityMenuPatch {
* Used to force the creation of the advanced menu item for the Shorts quality flyout. * Used to force the creation of the advanced menu item for the Shorts quality flyout.
*/ */
public static boolean forceAdvancedVideoQualityMenuCreation(boolean original) { public static boolean forceAdvancedVideoQualityMenuCreation(boolean original) {
return Settings.RESTORE_OLD_VIDEO_QUALITY_MENU.get() || original; return Settings.ADVANCED_VIDEO_QUALITY_MENU.get() || original;
} }
/** /**
@@ -79,8 +78,8 @@ public final class RestoreOldVideoQualityMenuPatch {
* *
* Used if spoofing to an old app version, and also used for the Shorts video quality flyout. * Used if spoofing to an old app version, and also used for the Shorts video quality flyout.
*/ */
public static void showOldVideoQualityMenu(final ListView listView) { public static void showAdvancedVideoQualityMenu(ListView listView) {
if (!Settings.RESTORE_OLD_VIDEO_QUALITY_MENU.get()) return; if (!Settings.ADVANCED_VIDEO_QUALITY_MENU.get()) return;
listView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() { listView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
@Override @Override

View File

@@ -12,15 +12,19 @@ import java.util.List;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BooleanSetting;
import app.revanced.extension.shared.settings.IntegerSetting; import app.revanced.extension.shared.settings.IntegerSetting;
import app.revanced.extension.youtube.patches.VideoInformation; import app.revanced.extension.youtube.patches.VideoInformation;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.ShortsPlayerState;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class RememberVideoQualityPatch { public class RememberVideoQualityPatch {
private static final int AUTOMATIC_VIDEO_QUALITY_VALUE = -2; private static final int AUTOMATIC_VIDEO_QUALITY_VALUE = -2;
private static final IntegerSetting wifiQualitySetting = Settings.VIDEO_QUALITY_DEFAULT_WIFI; private static final IntegerSetting videoQualityWifi = Settings.VIDEO_QUALITY_DEFAULT_WIFI;
private static final IntegerSetting mobileQualitySetting = Settings.VIDEO_QUALITY_DEFAULT_MOBILE; private static final IntegerSetting videoQualityMobile = Settings.VIDEO_QUALITY_DEFAULT_MOBILE;
private static final IntegerSetting shortsQualityWifi = Settings.SHORTS_QUALITY_DEFAULT_WIFI;
private static final IntegerSetting shortsQualityMobile = Settings.SHORTS_QUALITY_DEFAULT_MOBILE;
private static boolean qualityNeedsUpdating; private static boolean qualityNeedsUpdating;
@@ -41,17 +45,29 @@ public class RememberVideoQualityPatch {
@Nullable @Nullable
private static List<Integer> videoQualities; private static List<Integer> videoQualities;
private static boolean shouldRememberVideoQuality() {
BooleanSetting preference = ShortsPlayerState.isOpen() ?
Settings.REMEMBER_SHORTS_QUALITY_LAST_SELECTED
: Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED;
return preference.get();
}
private static void changeDefaultQuality(int defaultQuality) { private static void changeDefaultQuality(int defaultQuality) {
String networkTypeMessage; String networkTypeMessage;
boolean useShortsPreference = ShortsPlayerState.isOpen();
if (Utils.getNetworkType() == NetworkType.MOBILE) { if (Utils.getNetworkType() == NetworkType.MOBILE) {
mobileQualitySetting.save(defaultQuality); if (useShortsPreference) shortsQualityMobile.save(defaultQuality);
else videoQualityMobile.save(defaultQuality);
networkTypeMessage = str("revanced_remember_video_quality_mobile"); networkTypeMessage = str("revanced_remember_video_quality_mobile");
} else { } else {
wifiQualitySetting.save(defaultQuality); if (useShortsPreference) shortsQualityWifi.save(defaultQuality);
else videoQualityWifi.save(defaultQuality);
networkTypeMessage = str("revanced_remember_video_quality_wifi"); networkTypeMessage = str("revanced_remember_video_quality_wifi");
} }
Utils.showToastShort( Utils.showToastShort(str(
str("revanced_remember_video_quality_toast", networkTypeMessage, (defaultQuality + "p"))); useShortsPreference ? "revanced_remember_video_quality_toast_shorts" : "revanced_remember_video_quality_toast",
networkTypeMessage, (defaultQuality + "p")
));
} }
/** /**
@@ -62,9 +78,10 @@ public class RememberVideoQualityPatch {
*/ */
public static int setVideoQuality(Object[] qualities, final int originalQualityIndex, Object qInterface, String qIndexMethod) { public static int setVideoQuality(Object[] qualities, final int originalQualityIndex, Object qInterface, String qIndexMethod) {
try { try {
boolean useShortsPreference = ShortsPlayerState.isOpen();
final int preferredQuality = Utils.getNetworkType() == NetworkType.MOBILE final int preferredQuality = Utils.getNetworkType() == NetworkType.MOBILE
? mobileQualitySetting.get() ? (useShortsPreference ? shortsQualityMobile : videoQualityMobile).get()
: wifiQualitySetting.get(); : (useShortsPreference ? shortsQualityWifi : videoQualityWifi).get();
if (!userChangedDefaultQuality && preferredQuality == AUTOMATIC_VIDEO_QUALITY_VALUE) { if (!userChangedDefaultQuality && preferredQuality == AUTOMATIC_VIDEO_QUALITY_VALUE) {
return originalQualityIndex; // Nothing to do. return originalQualityIndex; // Nothing to do.
@@ -141,17 +158,17 @@ public class RememberVideoQualityPatch {
* Injection point. Old quality menu. * Injection point. Old quality menu.
*/ */
public static void userChangedQuality(int selectedQualityIndex) { public static void userChangedQuality(int selectedQualityIndex) {
if (!Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.get()) return; if (shouldRememberVideoQuality()) {
userSelectedQualityIndex = selectedQualityIndex;
userSelectedQualityIndex = selectedQualityIndex; userChangedDefaultQuality = true;
userChangedDefaultQuality = true; }
} }
/** /**
* Injection point. New quality menu. * Injection point. New quality menu.
*/ */
public static void userChangedQualityInNewFlyout(int selectedQuality) { public static void userChangedQualityInNewFlyout(int selectedQuality) {
if (!Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.get()) return; if (!shouldRememberVideoQuality()) return;
changeDefaultQuality(selectedQuality); // Quality is human readable resolution (ie: 1080). changeDefaultQuality(selectedQuality); // Quality is human readable resolution (ie: 1080).
} }

View File

@@ -37,7 +37,6 @@ import java.util.concurrent.*;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.ThemeHelper; import app.revanced.extension.youtube.ThemeHelper;
import app.revanced.extension.youtube.patches.spoof.SpoofAppVersionPatch;
import app.revanced.extension.youtube.returnyoutubedislike.requests.RYDVoteData; import app.revanced.extension.youtube.returnyoutubedislike.requests.RYDVoteData;
import app.revanced.extension.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi; import app.revanced.extension.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
@@ -87,9 +86,6 @@ public class ReturnYouTubeDislike {
*/ */
private static final char MIDDLE_SEPARATOR_CHARACTER = '◎'; // 'bullseye' private static final char MIDDLE_SEPARATOR_CHARACTER = '◎'; // 'bullseye'
private static final boolean IS_SPOOFING_TO_OLD_SEPARATOR_COLOR
= SpoofAppVersionPatch.isSpoofingToLessThan("18.10.00");
/** /**
* Cached lookup of all video ids. * Cached lookup of all video ids.
*/ */
@@ -184,17 +180,8 @@ public class ReturnYouTubeDislike {
* Color of the left and middle separator, based on the color of the right separator. * Color of the left and middle separator, based on the color of the right separator.
* It's unknown where YT gets the color from, and the values here are approximated by hand. * It's unknown where YT gets the color from, and the values here are approximated by hand.
* Ideally, this would be the actual color YT uses at runtime. * Ideally, this would be the actual color YT uses at runtime.
*
* Older versions before the 'Me' library tab use a slightly different color.
* If spoofing was previously used and is now turned off,
* or an old version was recently upgraded then the old colors are sometimes still used.
*/ */
private static int getSeparatorColor() { private static int getSeparatorColor() {
if (IS_SPOOFING_TO_OLD_SEPARATOR_COLOR) {
return ThemeHelper.isDarkTheme()
? 0x29AAAAAA // transparent dark gray
: 0xFFD9D9D9; // light gray
}
return ThemeHelper.isDarkTheme() return ThemeHelper.isDarkTheme()
? 0x33FFFFFF ? 0x33FFFFFF
: 0xFFD9D9D9; : 0xFFD9D9D9;

View File

@@ -3,7 +3,6 @@ package app.revanced.extension.youtube.settings;
import static java.lang.Boolean.FALSE; import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE; import static java.lang.Boolean.TRUE;
import static app.revanced.extension.shared.settings.Setting.Availability; import static app.revanced.extension.shared.settings.Setting.Availability;
import static app.revanced.extension.shared.settings.Setting.migrateFromOldPreferences;
import static app.revanced.extension.shared.settings.Setting.migrateOldSettingToNew; import static app.revanced.extension.shared.settings.Setting.migrateOldSettingToNew;
import static app.revanced.extension.shared.settings.Setting.parent; import static app.revanced.extension.shared.settings.Setting.parent;
import static app.revanced.extension.shared.settings.Setting.parentsAny; import static app.revanced.extension.shared.settings.Setting.parentsAny;
@@ -21,7 +20,6 @@ import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerT
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_4; import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_4;
import static app.revanced.extension.youtube.patches.OpenShortsInRegularPlayerPatch.ShortsPlayerType; import static app.revanced.extension.youtube.patches.OpenShortsInRegularPlayerPatch.ShortsPlayerType;
import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability; import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability;
import static app.revanced.extension.youtube.patches.VersionCheckPatch.IS_19_17_OR_GREATER;
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE;
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP;
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY;
@@ -38,7 +36,6 @@ import app.revanced.extension.shared.settings.IntegerSetting;
import app.revanced.extension.shared.settings.LongSetting; import app.revanced.extension.shared.settings.LongSetting;
import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.shared.settings.StringSetting; import app.revanced.extension.shared.settings.StringSetting;
import app.revanced.extension.shared.settings.preference.SharedPrefCategory;
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.DeArrowAvailability; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.DeArrowAvailability;
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.StillImagesAvailability; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.StillImagesAvailability;
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption;
@@ -47,11 +44,14 @@ import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
public class Settings extends BaseSettings { public class Settings extends BaseSettings {
// Video // Video
public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE);
public static final BooleanSetting RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE);
public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_last_selected", FALSE);
public static final IntegerSetting VIDEO_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_video_quality_default_wifi", -2); public static final IntegerSetting VIDEO_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_video_quality_default_wifi", -2);
public static final IntegerSetting VIDEO_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_video_quality_default_mobile", -2); public static final IntegerSetting VIDEO_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_video_quality_default_mobile", -2);
public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_last_selected", FALSE);
public static final IntegerSetting SHORTS_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_shorts_quality_default_wifi", -2, true);
public static final IntegerSetting SHORTS_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_shorts_quality_default_mobile", -2, true);
public static final BooleanSetting REMEMBER_SHORTS_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_shorts_quality_last_selected", FALSE);
public static final BooleanSetting ADVANCED_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_advanced_video_quality_menu", TRUE);
public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE);
// Speed // Speed
public static final FloatSetting SPEED_TAP_AND_HOLD = new FloatSetting("revanced_speed_tap_and_hold", 2.0f, true); public static final FloatSetting SPEED_TAP_AND_HOLD = new FloatSetting("revanced_speed_tap_and_hold", 2.0f, true);
public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_last_selected", FALSE); public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_last_selected", FALSE);
@@ -171,10 +171,10 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_COMMENTS_CHAT_SUMMARY = new BooleanSetting("revanced_hide_comments_chat_summary", FALSE); public static final BooleanSetting HIDE_COMMENTS_CHAT_SUMMARY = new BooleanSetting("revanced_hide_comments_chat_summary", FALSE);
public static final BooleanSetting HIDE_COMMENTS_BY_MEMBERS_HEADER = new BooleanSetting("revanced_hide_comments_by_members_header", FALSE); public static final BooleanSetting HIDE_COMMENTS_BY_MEMBERS_HEADER = new BooleanSetting("revanced_hide_comments_by_members_header", FALSE);
public static final BooleanSetting HIDE_COMMENTS_CREATE_A_SHORT_BUTTON = new BooleanSetting("revanced_hide_comments_create_a_short_button", TRUE); public static final BooleanSetting HIDE_COMMENTS_CREATE_A_SHORT_BUTTON = new BooleanSetting("revanced_hide_comments_create_a_short_button", TRUE);
public static final BooleanSetting HIDE_COMMENTS_TIMESTAMP_AND_EMOJI_BUTTONS = new BooleanSetting("revanced_hide_comments_timestamp_and_emoji_buttons", TRUE);
public static final BooleanSetting HIDE_COMMENTS_PREVIEW_COMMENT = new BooleanSetting("revanced_hide_comments_preview_comment", FALSE); public static final BooleanSetting HIDE_COMMENTS_PREVIEW_COMMENT = new BooleanSetting("revanced_hide_comments_preview_comment", FALSE);
public static final BooleanSetting HIDE_COMMENTS_SECTION = new BooleanSetting("revanced_hide_comments_section", FALSE); public static final BooleanSetting HIDE_COMMENTS_SECTION = new BooleanSetting("revanced_hide_comments_section", FALSE);
public static final BooleanSetting HIDE_COMMENTS_THANKS_BUTTON = new BooleanSetting("revanced_hide_comments_thanks_button", TRUE); public static final BooleanSetting HIDE_COMMENTS_THANKS_BUTTON = new BooleanSetting("revanced_hide_comments_thanks_button", TRUE);
public static final BooleanSetting HIDE_COMMENTS_TIMESTAMP_AND_EMOJI_BUTTONS = new BooleanSetting("revanced_hide_comments_timestamp_and_emoji_buttons", TRUE);
// Description // Description
public static final BooleanSetting HIDE_ATTRIBUTES_SECTION = new BooleanSetting("revanced_hide_attributes_section", FALSE); public static final BooleanSetting HIDE_ATTRIBUTES_SECTION = new BooleanSetting("revanced_hide_attributes_section", FALSE);
public static final BooleanSetting HIDE_CHAPTERS_SECTION = new BooleanSetting("revanced_hide_chapters_section", TRUE); public static final BooleanSetting HIDE_CHAPTERS_SECTION = new BooleanSetting("revanced_hide_chapters_section", TRUE);
@@ -218,7 +218,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message"); public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message");
public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true); public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true);
public static final EnumSetting<StartPage> CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.DEFAULT, true); public static final EnumSetting<StartPage> CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.DEFAULT, true);
public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", IS_19_17_OR_GREATER ? "19.26.42" : "17.33.42", true, parent(SPOOF_APP_VERSION)); public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", "19.01.34", true, parent(SPOOF_APP_VERSION));
// Custom filter // Custom filter
public static final BooleanSetting CUSTOM_FILTER = new BooleanSetting("revanced_custom_filter", FALSE); public static final BooleanSetting CUSTOM_FILTER = new BooleanSetting("revanced_custom_filter", FALSE);
public static final StringSetting CUSTOM_FILTER_STRINGS = new StringSetting("revanced_custom_filter_strings", "", true, parent(CUSTOM_FILTER)); public static final StringSetting CUSTOM_FILTER_STRINGS = new StringSetting("revanced_custom_filter_strings", "", true, parent(CUSTOM_FILTER));
@@ -362,52 +362,54 @@ public class Settings extends BaseSettings {
public static final BooleanSetting SB_SEEN_GUIDELINES = new BooleanSetting("sb_seen_guidelines", FALSE, false, false); public static final BooleanSetting SB_SEEN_GUIDELINES = new BooleanSetting("sb_seen_guidelines", FALSE, false, false);
public static final StringSetting SB_CATEGORY_SPONSOR = new StringSetting("sb_sponsor", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue); public static final StringSetting SB_CATEGORY_SPONSOR = new StringSetting("sb_sponsor", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
public static final StringSetting SB_CATEGORY_SPONSOR_COLOR = new StringSetting("sb_sponsor_color", "#00D400"); public static final StringSetting SB_CATEGORY_SPONSOR_COLOR = new StringSetting("sb_sponsor_color", "#00D400");
public static final FloatSetting SB_CATEGORY_SPONSOR_OPACITY = new FloatSetting("sb_sponsor_opacity", 0.8f);
public static final StringSetting SB_CATEGORY_SELF_PROMO = new StringSetting("sb_selfpromo", MANUAL_SKIP.reVancedKeyValue); public static final StringSetting SB_CATEGORY_SELF_PROMO = new StringSetting("sb_selfpromo", MANUAL_SKIP.reVancedKeyValue);
public static final StringSetting SB_CATEGORY_SELF_PROMO_COLOR = new StringSetting("sb_selfpromo_color", "#FFFF00"); public static final StringSetting SB_CATEGORY_SELF_PROMO_COLOR = new StringSetting("sb_selfpromo_color", "#FFFF00");
public static final FloatSetting SB_CATEGORY_SELF_PROMO_OPACITY = new FloatSetting("sb_selfpromo_opacity", 0.8f);
public static final StringSetting SB_CATEGORY_INTERACTION = new StringSetting("sb_interaction", MANUAL_SKIP.reVancedKeyValue); public static final StringSetting SB_CATEGORY_INTERACTION = new StringSetting("sb_interaction", MANUAL_SKIP.reVancedKeyValue);
public static final StringSetting SB_CATEGORY_INTERACTION_COLOR = new StringSetting("sb_interaction_color", "#CC00FF"); public static final StringSetting SB_CATEGORY_INTERACTION_COLOR = new StringSetting("sb_interaction_color", "#CC00FF");
public static final FloatSetting SB_CATEGORY_INTERACTION_OPACITY = new FloatSetting("sb_interaction_opacity", 0.8f);
public static final StringSetting SB_CATEGORY_HIGHLIGHT = new StringSetting("sb_highlight", MANUAL_SKIP.reVancedKeyValue); public static final StringSetting SB_CATEGORY_HIGHLIGHT = new StringSetting("sb_highlight", MANUAL_SKIP.reVancedKeyValue);
public static final StringSetting SB_CATEGORY_HIGHLIGHT_COLOR = new StringSetting("sb_highlight_color", "#FF1684"); public static final StringSetting SB_CATEGORY_HIGHLIGHT_COLOR = new StringSetting("sb_highlight_color", "#FF1684");
public static final FloatSetting SB_CATEGORY_HIGHLIGHT_OPACITY = new FloatSetting("sb_highlight_opacity", 0.8f);
public static final StringSetting SB_CATEGORY_INTRO = new StringSetting("sb_intro", MANUAL_SKIP.reVancedKeyValue); public static final StringSetting SB_CATEGORY_INTRO = new StringSetting("sb_intro", MANUAL_SKIP.reVancedKeyValue);
public static final StringSetting SB_CATEGORY_INTRO_COLOR = new StringSetting("sb_intro_color", "#00FFFF"); public static final StringSetting SB_CATEGORY_INTRO_COLOR = new StringSetting("sb_intro_color", "#00FFFF");
public static final FloatSetting SB_CATEGORY_INTRO_OPACITY = new FloatSetting("sb_intro_opacity", 0.8f);
public static final StringSetting SB_CATEGORY_OUTRO = new StringSetting("sb_outro", MANUAL_SKIP.reVancedKeyValue); public static final StringSetting SB_CATEGORY_OUTRO = new StringSetting("sb_outro", MANUAL_SKIP.reVancedKeyValue);
public static final StringSetting SB_CATEGORY_OUTRO_COLOR = new StringSetting("sb_outro_color", "#0202ED"); public static final StringSetting SB_CATEGORY_OUTRO_COLOR = new StringSetting("sb_outro_color", "#0202ED");
public static final FloatSetting SB_CATEGORY_OUTRO_OPACITY = new FloatSetting("sb_outro_opacity", 0.8f);
public static final StringSetting SB_CATEGORY_PREVIEW = new StringSetting("sb_preview", IGNORE.reVancedKeyValue); public static final StringSetting SB_CATEGORY_PREVIEW = new StringSetting("sb_preview", IGNORE.reVancedKeyValue);
public static final StringSetting SB_CATEGORY_PREVIEW_COLOR = new StringSetting("sb_preview_color", "#008FD6"); public static final StringSetting SB_CATEGORY_PREVIEW_COLOR = new StringSetting("sb_preview_color", "#008FD6");
public static final FloatSetting SB_CATEGORY_PREVIEW_OPACITY = new FloatSetting("sb_preview_opacity", 0.8f);
public static final StringSetting SB_CATEGORY_FILLER = new StringSetting("sb_filler", IGNORE.reVancedKeyValue); public static final StringSetting SB_CATEGORY_FILLER = new StringSetting("sb_filler", IGNORE.reVancedKeyValue);
public static final StringSetting SB_CATEGORY_FILLER_COLOR = new StringSetting("sb_filler_color", "#7300FF"); public static final StringSetting SB_CATEGORY_FILLER_COLOR = new StringSetting("sb_filler_color", "#7300FF");
public static final FloatSetting SB_CATEGORY_FILLER_OPACITY = new FloatSetting("sb_filler_opacity", 0.8f);
public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC = new StringSetting("sb_music_offtopic", MANUAL_SKIP.reVancedKeyValue); public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC = new StringSetting("sb_music_offtopic", MANUAL_SKIP.reVancedKeyValue);
public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC_COLOR = new StringSetting("sb_music_offtopic_color", "#FF9900"); public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC_COLOR = new StringSetting("sb_music_offtopic_color", "#FF9900");
public static final FloatSetting SB_CATEGORY_MUSIC_OFFTOPIC_OPACITY = new FloatSetting("sb_music_offtopic_opacity", 0.8f);
public static final StringSetting SB_CATEGORY_UNSUBMITTED = new StringSetting("sb_unsubmitted", SKIP_AUTOMATICALLY.reVancedKeyValue); public static final StringSetting SB_CATEGORY_UNSUBMITTED = new StringSetting("sb_unsubmitted", SKIP_AUTOMATICALLY.reVancedKeyValue);
public static final StringSetting SB_CATEGORY_UNSUBMITTED_COLOR = new StringSetting("sb_unsubmitted_color", "#FFFFFF"); public static final StringSetting SB_CATEGORY_UNSUBMITTED_COLOR = new StringSetting("sb_unsubmitted_color", "#FFFFFF");
public static final FloatSetting SB_CATEGORY_UNSUBMITTED_OPACITY = new FloatSetting("sb_unsubmitted_opacity", 1.0f);
// Deprecated migrations // Deprecated migrations
private static final StringSetting DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING = new StringSetting("uuid", ""); // Delete sometime in 2024
private static final BooleanSetting DEPRECATED_HIDE_PLAYER_BUTTONS = new BooleanSetting("revanced_hide_player_buttons", FALSE, true); private static final BooleanSetting DEPRECATED_HIDE_PLAYER_BUTTONS = new BooleanSetting("revanced_hide_player_buttons", FALSE, true);
private static final BooleanSetting DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_video_quality_menu_footer", FALSE); private static final BooleanSetting DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_video_quality_menu_footer", FALSE);
private static final IntegerSetting DEPRECATED_SWIPE_OVERLAY_BACKGROUND_ALPHA = new IntegerSetting("revanced_swipe_overlay_background_alpha", 127); private static final IntegerSetting DEPRECATED_SWIPE_OVERLAY_BACKGROUND_ALPHA = new IntegerSetting("revanced_swipe_overlay_background_alpha", 127);
private static final StringSetting DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY = new StringSetting("revanced_seekbar_custom_color_value", "#FF0033"); private static final StringSetting DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY = new StringSetting("revanced_seekbar_custom_color_value", "#FF0033");
private static final BooleanSetting DEPRECATED_DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE); private static final BooleanSetting DEPRECATED_DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE);
private static final BooleanSetting DEPRECATED_RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE);
static { static {
// region Migration // region Migration
// Do _not_ delete this SB private user id migration property until sometime in early 2025.
// This is the only setting that cannot be reconfigured if lost,
// and more time should be given for users who rarely upgrade.
SharedPrefCategory sbPrefs = new SharedPrefCategory("sponsor-block");
// Remove the "sb_" prefix, as old settings are saved without it.
String key = DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING.key.substring(3);
migrateFromOldPreferences(sbPrefs, DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, key);
migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID);
migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_BUTTONS, HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS); migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_BUTTONS, HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS);
migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER, HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER); migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER, HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER);
migrateOldSettingToNew(DEPRECATED_DISABLE_SUGGESTED_VIDEO_END_SCREEN, HIDE_END_SCREEN_SUGGESTED_VIDEO); migrateOldSettingToNew(DEPRECATED_DISABLE_SUGGESTED_VIDEO_END_SCREEN, HIDE_END_SCREEN_SUGGESTED_VIDEO);
migrateOldSettingToNew(DEPRECATED_RESTORE_OLD_VIDEO_QUALITY_MENU, ADVANCED_VIDEO_QUALITY_MENU);
// Migrate renamed enum. // Migrate renamed enum.
//noinspection deprecation //noinspection deprecation
if (MINIPLAYER_TYPE.get() == MiniplayerType.PHONE) { if (MINIPLAYER_TYPE.get() == MiniplayerType.PHONE) {
@@ -443,6 +445,12 @@ public class Settings extends BaseSettings {
DEPRECATED_SWIPE_OVERLAY_BACKGROUND_ALPHA.resetToDefault(); DEPRECATED_SWIPE_OVERLAY_BACKGROUND_ALPHA.resetToDefault();
} }
// Old spoof versions that no longer work.
if (SPOOF_APP_VERSION_TARGET.get().compareTo(SPOOF_APP_VERSION_TARGET.defaultValue) < 0) {
Logger.printInfo(() -> "Resetting spoof app version target");
SPOOF_APP_VERSION_TARGET.resetToDefault();
}
// endregion // endregion
// region SB import/export callbacks // region SB import/export callbacks

View File

@@ -18,8 +18,8 @@ import android.widget.TextView;
import android.widget.Toolbar; import android.widget.Toolbar;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
@@ -74,7 +74,8 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
} }
} }
Collections.sort(pairsToSort, (pair1, pair2) -> pair1.first.compareToIgnoreCase(pair2.first)); pairsToSort.sort((pair1, pair2)
-> pair1.first.compareToIgnoreCase(pair2.first));
CharSequence[] sortedEntries = new CharSequence[entrySize]; CharSequence[] sortedEntries = new CharSequence[entrySize];
CharSequence[] sortedEntryValues = new CharSequence[entrySize]; CharSequence[] sortedEntryValues = new CharSequence[entrySize];
@@ -109,6 +110,7 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
CustomPlaybackSpeedPatch.initializeListPreference(playbackPreference); CustomPlaybackSpeedPatch.initializeListPreference(playbackPreference);
} }
sortPreferenceListMenu(Settings.CHANGE_START_PAGE);
sortPreferenceListMenu(Settings.SPOOF_VIDEO_STREAMS_LANGUAGE); sortPreferenceListMenu(Settings.SPOOF_VIDEO_STREAMS_LANGUAGE);
sortPreferenceListMenu(BaseSettings.REVANCED_LANGUAGE); sortPreferenceListMenu(BaseSettings.REVANCED_LANGUAGE);
} catch (Exception ex) { } catch (Exception ex) {

View File

@@ -14,6 +14,7 @@ import android.preference.PreferenceScreen;
import android.preference.SwitchPreference; import android.preference.SwitchPreference;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.youtube.patches.ReturnYouTubeDislikePatch; import app.revanced.extension.youtube.patches.ReturnYouTubeDislikePatch;
@@ -85,9 +86,7 @@ public class ReturnYouTubeDislikePreferenceFragment extends PreferenceFragment {
shortsPreference = new SwitchPreference(context); shortsPreference = new SwitchPreference(context);
shortsPreference.setChecked(Settings.RYD_SHORTS.get()); shortsPreference.setChecked(Settings.RYD_SHORTS.get());
shortsPreference.setTitle(str("revanced_ryd_shorts_title")); shortsPreference.setTitle(str("revanced_ryd_shorts_title"));
String shortsSummary = ReturnYouTubeDislikePatch.IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER String shortsSummary = str("revanced_ryd_shorts_summary_on_disclaimer");
? str("revanced_ryd_shorts_summary_on")
: str("revanced_ryd_shorts_summary_on_disclaimer");
shortsPreference.setSummaryOn(shortsSummary); shortsPreference.setSummaryOn(shortsSummary);
shortsPreference.setSummaryOff(str("revanced_ryd_shorts_summary_off")); shortsPreference.setSummaryOff(str("revanced_ryd_shorts_summary_off"));
shortsPreference.setOnPreferenceChangeListener((pref, newValue) -> { shortsPreference.setOnPreferenceChangeListener((pref, newValue) -> {
@@ -237,6 +236,8 @@ public class ReturnYouTubeDislikePreferenceFragment extends PreferenceFragment {
"revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_non_zero_summary")); "revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_non_zero_summary"));
preferenceScreen.addPreference(statisticPreference); preferenceScreen.addPreference(statisticPreference);
} }
Utils.setPreferenceTitlesToMultiLineIfNeeded(preferenceScreen);
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "onCreate failure", ex); Logger.printException(() -> "onCreate failure", ex);
} }

View File

@@ -17,6 +17,7 @@ import androidx.annotation.Nullable;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.shared.settings.preference.ResettableEditTextPreference;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.sponsorblock.SegmentPlaybackController; import app.revanced.extension.youtube.sponsorblock.SegmentPlaybackController;
import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings; import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
@@ -44,8 +45,8 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
private SwitchPreference showTimeWithoutSegments; private SwitchPreference showTimeWithoutSegments;
private SwitchPreference toastOnConnectionError; private SwitchPreference toastOnConnectionError;
private EditTextPreference newSegmentStep; private ResettableEditTextPreference newSegmentStep;
private EditTextPreference minSegmentDuration; private ResettableEditTextPreference minSegmentDuration;
private EditTextPreference privateUserId; private EditTextPreference privateUserId;
private EditTextPreference importExport; private EditTextPreference importExport;
private Preference apiUrl; private Preference apiUrl;
@@ -159,6 +160,8 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
addAboutCategory(context, preferenceScreen); addAboutCategory(context, preferenceScreen);
Utils.setPreferenceTitlesToMultiLineIfNeeded(preferenceScreen);
updateUI(); updateUI();
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "onCreate failure", ex); Logger.printException(() -> "onCreate failure", ex);
@@ -268,7 +271,8 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
return true; return true;
}); });
newSegmentStep = new EditTextPreference(context); newSegmentStep = new ResettableEditTextPreference(context);
newSegmentStep.setSetting(Settings.SB_CREATE_NEW_SEGMENT_STEP);
newSegmentStep.setTitle(str("revanced_sb_general_adjusting")); newSegmentStep.setTitle(str("revanced_sb_general_adjusting"));
newSegmentStep.setSummary(str("revanced_sb_general_adjusting_sum")); newSegmentStep.setSummary(str("revanced_sb_general_adjusting_sum"));
newSegmentStep.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER); newSegmentStep.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER);
@@ -326,7 +330,8 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
}); });
category.addPreference(trackSkips); category.addPreference(trackSkips);
minSegmentDuration = new EditTextPreference(context); minSegmentDuration = new ResettableEditTextPreference(context);
minSegmentDuration.setSetting(Settings.SB_SEGMENT_MIN_DURATION);
minSegmentDuration.setTitle(str("revanced_sb_general_min_duration")); minSegmentDuration.setTitle(str("revanced_sb_general_min_duration"));
minSegmentDuration.setSummary(str("revanced_sb_general_min_duration_sum")); minSegmentDuration.setSummary(str("revanced_sb_general_min_duration_sum"));
minSegmentDuration.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL); minSegmentDuration.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
@@ -345,7 +350,15 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
}); });
category.addPreference(minSegmentDuration); category.addPreference(minSegmentDuration);
privateUserId = new EditTextPreference(context); privateUserId = new EditTextPreference(context) {
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
Utils.setEditTextDialogTheme(builder);
builder.setNeutralButton(str("revanced_sb_settings_copy"), (dialog, which) -> {
Utils.setClipboard(getEditText().getText().toString());
});
}
};
privateUserId.setTitle(str("revanced_sb_general_uuid")); privateUserId.setTitle(str("revanced_sb_general_uuid"));
privateUserId.setSummary(str("revanced_sb_general_uuid_sum")); privateUserId.setSummary(str("revanced_sb_general_uuid_sum"));
privateUserId.setOnPreferenceChangeListener((preference1, newValue) -> { privateUserId.setOnPreferenceChangeListener((preference1, newValue) -> {
@@ -504,7 +517,7 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
if (stats.totalSegmentCountIncludingIgnored > 0) { if (stats.totalSegmentCountIncludingIgnored > 0) {
// If user has not created any segments, there's no reason to set a username. // If user has not created any segments, there's no reason to set a username.
EditTextPreference preference = new EditTextPreference(context); EditTextPreference preference = new ResettableEditTextPreference(context);
statsCategory.addPreference(preference); statsCategory.addPreference(preference);
String userName = stats.userName; String userName = stats.userName;
preference.setTitle(fromHtml(str("revanced_sb_stats_username", userName))); preference.setTitle(fromHtml(str("revanced_sb_stats_username", userName)));

View File

@@ -73,6 +73,7 @@ public class SpoofStreamingDataSideEffectsPreference extends Preference {
if (currentClientType == clientType) { if (currentClientType == clientType) {
return; return;
} }
currentClientType = clientType;
Logger.printDebug(() -> "Updating spoof stream side effects preference"); Logger.printDebug(() -> "Updating spoof stream side effects preference");
setEnabled(BaseSettings.SPOOF_VIDEO_STREAMS.get()); setEnabled(BaseSettings.SPOOF_VIDEO_STREAMS.get());

View File

@@ -3,7 +3,9 @@ package app.revanced.extension.youtube.shared;
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton.CREATE; import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton.CREATE;
import android.app.Activity; import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.view.View; import android.view.View;
import android.widget.FrameLayout;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@@ -24,12 +26,22 @@ import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class NavigationBar { public final class NavigationBar {
/**
* Interface to call obfuscated methods in AppCompat Toolbar class.
*/
public interface AppCompatToolbarPatchInterface {
Drawable patch_getNavigationIcon();
}
// //
// Search bar // Search and toolbar.
// //
private static volatile WeakReference<View> searchBarResultsRef = new WeakReference<>(null); private static volatile WeakReference<View> searchBarResultsRef = new WeakReference<>(null);
private static volatile WeakReference<AppCompatToolbarPatchInterface> toolbarResultsRef
= new WeakReference<>(null);
/** /**
* Injection point. * Injection point.
*/ */
@@ -37,6 +49,22 @@ public final class NavigationBar {
searchBarResultsRef = new WeakReference<>(searchbarResults); searchBarResultsRef = new WeakReference<>(searchbarResults);
} }
/**
* Injection point.
*/
public static void setToolbar(FrameLayout layout) {
AppCompatToolbarPatchInterface toolbar = Utils.getChildView(layout, false, (view) ->
view instanceof AppCompatToolbarPatchInterface
);
if (toolbar == null) {
Logger.printException(() -> "Could not find navigation toolbar");
return;
}
toolbarResultsRef = new WeakReference<>(toolbar);
}
/** /**
* @return If the search bar is on screen. This includes if the player * @return If the search bar is on screen. This includes if the player
* is on screen and the search results are behind the player (and not visible). * is on screen and the search results are behind the player (and not visible).
@@ -47,8 +75,13 @@ public final class NavigationBar {
return searchbarResults != null && searchbarResults.getParent() != null; return searchbarResults != null && searchbarResults.getParent() != null;
} }
public static boolean isBackButtonVisible() {
AppCompatToolbarPatchInterface toolbar = toolbarResultsRef.get();
return toolbar != null && toolbar.patch_getNavigationIcon() != null;
}
// //
// Navigation bar buttons // Navigation bar buttons.
// //
/** /**

View File

@@ -5,7 +5,7 @@ import app.revanced.extension.youtube.Event
import app.revanced.extension.youtube.patches.VideoInformation import app.revanced.extension.youtube.patches.VideoInformation
/** /**
* Main player type. * Regular player type.
*/ */
enum class PlayerType { enum class PlayerType {
/** /**
@@ -90,8 +90,6 @@ enum class PlayerType {
* Does not include the first moment after a short is opened when a regular video is minimized on screen, * Does not include the first moment after a short is opened when a regular video is minimized on screen,
* or while watching a short with a regular video present on a spoofed 16.x version of YouTube. * or while watching a short with a regular video present on a spoofed 16.x version of YouTube.
* To include those situations instead use [isNoneHiddenOrMinimized]. * To include those situations instead use [isNoneHiddenOrMinimized].
*
* @see VideoInformation
*/ */
fun isNoneOrHidden(): Boolean { fun isNoneOrHidden(): Boolean {
return this == NONE || this == HIDDEN return this == NONE || this == HIDDEN
@@ -107,8 +105,11 @@ enum class PlayerType {
* when spoofing to an old version this will return false even * when spoofing to an old version this will return false even
* though a Short is being opened or is on screen (see [isNoneHiddenOrMinimized]). * though a Short is being opened or is on screen (see [isNoneHiddenOrMinimized]).
* *
* Instead of this method, consider using {@link ShortsPlayerState}
* which may work better for some situations.
*
* @return If nothing, a Short, or a regular video is sliding off screen to a dismissed or hidden state. * @return If nothing, a Short, or a regular video is sliding off screen to a dismissed or hidden state.
* @see VideoInformation * @see ShortsPlayerState
*/ */
fun isNoneHiddenOrSlidingMinimized(): Boolean { fun isNoneHiddenOrSlidingMinimized(): Boolean {
return isNoneOrHidden() || this == WATCH_WHILE_SLIDING_MINIMIZED_DISMISSED return isNoneOrHidden() || this == WATCH_WHILE_SLIDING_MINIMIZED_DISMISSED
@@ -125,9 +126,12 @@ enum class PlayerType {
* Typically used to detect if a Short is playing when the player cannot be in a minimized state, * Typically used to detect if a Short is playing when the player cannot be in a minimized state,
* such as the user interacting with a button or element of the player. * such as the user interacting with a button or element of the player.
* *
* Instead of this method, consider using {@link ShortsPlayerState}
* which may work better for some situations.
*
* @return If nothing, a Short, a regular video is sliding off screen to a dismissed or hidden state, * @return If nothing, a Short, a regular video is sliding off screen to a dismissed or hidden state,
* a regular video is minimized (and a new video is not being opened). * a regular video is minimized (and a new video is not being opened).
* @see VideoInformation * @see ShortsPlayerState
*/ */
fun isNoneHiddenOrMinimized(): Boolean { fun isNoneHiddenOrMinimized(): Boolean {
return isNoneHiddenOrSlidingMinimized() || this == WATCH_WHILE_MINIMIZED return isNoneHiddenOrSlidingMinimized() || this == WATCH_WHILE_MINIMIZED

View File

@@ -0,0 +1,38 @@
package app.revanced.extension.youtube.shared
import app.revanced.extension.shared.Logger
import app.revanced.extension.youtube.Event
/**
* Shorts player state.
*/
class ShortsPlayerState {
companion object {
@JvmStatic
fun setOpen(open: Boolean) {
if (isOpen != open) {
Logger.printDebug { "ShortsPlayerState open changed to: $isOpen" }
isOpen = open
onChange(open)
}
}
@Volatile
private var isOpen = false
/**
* Shorts player state change listener.
*/
@JvmStatic
val onChange = Event<Boolean>()
/**
* If the Shorts player is currently open.
*/
@JvmStatic
fun isOpen(): Boolean {
return isOpen
}
}
}

View File

@@ -136,7 +136,7 @@ public class SponsorBlockSettings {
for (SegmentCategory category : categories) { for (SegmentCategory category : categories) {
JSONObject categoryObject = new JSONObject(); JSONObject categoryObject = new JSONObject();
String categoryKey = category.keyValue; String categoryKey = category.keyValue;
categoryObject.put("color", category.colorString()); categoryObject.put("color", category.getColorString());
barTypesObject.put(categoryKey, categoryObject); barTypesObject.put(categoryKey, categoryObject);
if (category.behaviour != CategoryBehaviour.IGNORE) { if (category.behaviour != CategoryBehaviour.IGNORE) {

View File

@@ -5,7 +5,12 @@ import static app.revanced.extension.shared.StringRef.str;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.text.Html; import android.graphics.Color;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.widget.EditText; import android.widget.EditText;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@@ -33,7 +38,7 @@ import app.revanced.extension.youtube.sponsorblock.ui.SponsorBlockViewController
* Not thread safe. All fields/methods must be accessed from the main thread. * Not thread safe. All fields/methods must be accessed from the main thread.
*/ */
public class SponsorBlockUtils { public class SponsorBlockUtils {
private static final String LOCKED_COLOR = "#FFC83D"; private static final int LOCKED_COLOR = Color.parseColor("#FFC83D");
private static final String MANUAL_EDIT_TIME_TEXT_HINT = "hh:mm:ss.sss"; private static final String MANUAL_EDIT_TIME_TEXT_HINT = "hh:mm:ss.sss";
private static final Pattern manualEditTimePattern private static final Pattern manualEditTimePattern
= Pattern.compile("((\\d{1,2}):)?(\\d{1,2}):(\\d{2})(\\.(\\d{1,3}))?"); = Pattern.compile("((\\d{1,2}):)?(\\d{1,2}):(\\d{2})(\\.(\\d{1,3}))?");
@@ -160,32 +165,34 @@ public class SponsorBlockUtils {
SegmentVote[] voteOptions = (segment.category == SegmentCategory.HIGHLIGHT) SegmentVote[] voteOptions = (segment.category == SegmentCategory.HIGHLIGHT)
? SegmentVote.voteTypesWithoutCategoryChange // highlight segments cannot change category ? SegmentVote.voteTypesWithoutCategoryChange // highlight segments cannot change category
: SegmentVote.values(); : SegmentVote.values();
CharSequence[] items = new CharSequence[voteOptions.length]; final int voteOptionsLength = voteOptions.length;
final boolean userIsVip = Settings.SB_USER_IS_VIP.get();
CharSequence[] items = new CharSequence[voteOptionsLength];
for (int i = 0; i < voteOptions.length; i++) { for (int i = 0; i < voteOptionsLength; i++) {
SegmentVote voteOption = voteOptions[i]; SegmentVote voteOption = voteOptions[i];
String title = voteOption.title.toString(); CharSequence title = voteOption.title.toString();
if (Settings.SB_USER_IS_VIP.get() && segment.isLocked && voteOption.shouldHighlight) { if (userIsVip && segment.isLocked && voteOption.highlightIfVipAndVideoIsLocked) {
items[i] = Html.fromHtml(String.format("<font color=\"%s\">%s</font>", LOCKED_COLOR, title)); SpannableString coloredTitle = new SpannableString(title);
} else { coloredTitle.setSpan(new ForegroundColorSpan(LOCKED_COLOR),
items[i] = title; 0, title.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
title = coloredTitle;
} }
items[i] = title;
} }
new AlertDialog.Builder(context) new AlertDialog.Builder(context).setItems(items, (dialog1, which1) -> {
.setItems(items, (dialog1, which1) -> { SegmentVote voteOption = voteOptions[which1];
SegmentVote voteOption = voteOptions[which1]; switch (voteOption) {
switch (voteOption) { case UPVOTE:
case UPVOTE: case DOWNVOTE:
case DOWNVOTE: SBRequester.voteForSegmentOnBackgroundThread(segment, voteOption);
SBRequester.voteForSegmentOnBackgroundThread(segment, voteOption); break;
break; case CATEGORY_CHANGE:
case CATEGORY_CHANGE: onNewCategorySelect(segment, context);
onNewCategorySelect(segment, context); break;
break; }
} }).show();
})
.show();
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "segmentVoteClickListener failure", ex); Logger.printException(() -> "segmentVoteClickListener failure", ex);
} }
@@ -282,7 +289,6 @@ public class SponsorBlockUtils {
return; return;
} }
final int numberOfSegments = segments.length; final int numberOfSegments = segments.length;
CharSequence[] titles = new CharSequence[numberOfSegments]; CharSequence[] titles = new CharSequence[numberOfSegments];
for (int i = 0; i < numberOfSegments; i++) { for (int i = 0; i < numberOfSegments; i++) {
@@ -290,22 +296,33 @@ public class SponsorBlockUtils {
if (segment.category == SegmentCategory.UNSUBMITTED) { if (segment.category == SegmentCategory.UNSUBMITTED) {
continue; continue;
} }
StringBuilder htmlBuilder = new StringBuilder();
htmlBuilder.append(String.format("<b><font color=\"#%06X\">⬤</font> %s<br>", SpannableStringBuilder spannableBuilder = new SpannableStringBuilder();
segment.category.color, segment.category.title));
htmlBuilder.append(formatSegmentTime(segment.start)); spannableBuilder.append(segment.category.getTitleWithColorDot());
if (segment.category != SegmentCategory.HIGHLIGHT) { spannableBuilder.append('\n');
htmlBuilder.append(" to ").append(formatSegmentTime(segment.end));
String startTime = formatSegmentTime(segment.start);
if (segment.category == SegmentCategory.HIGHLIGHT) {
spannableBuilder.append(startTime);
} else {
String toFromString = str("revanced_sb_vote_segment_time_to_from",
startTime, formatSegmentTime(segment.end));
spannableBuilder.append(toFromString);
} }
htmlBuilder.append("</b>");
if (i + 1 != numberOfSegments) // prevents trailing new line after last segment if (i + 1 != numberOfSegments) {
htmlBuilder.append("<br>"); // prevents trailing new line after last segment
titles[i] = Html.fromHtml(htmlBuilder.toString()); spannableBuilder.append('\n');
}
spannableBuilder.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
0, spannableBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
titles[i] = spannableBuilder;
} }
new AlertDialog.Builder(context) new AlertDialog.Builder(context).setItems(titles, segmentVoteClickListener).show();
.setItems(titles, segmentVoteClickListener)
.show();
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "onVotingClicked failure", ex); Logger.printException(() -> "onVotingClicked failure", ex);
} }

View File

@@ -1,13 +1,14 @@
package app.revanced.extension.youtube.sponsorblock.objects; package app.revanced.extension.youtube.sponsorblock.objects;
import static app.revanced.extension.youtube.settings.Settings.*;
import static app.revanced.extension.shared.StringRef.sf; import static app.revanced.extension.shared.StringRef.sf;
import static app.revanced.extension.youtube.settings.Settings.*;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.text.Html; import android.text.Spannable;
import android.text.Spanned; import android.text.SpannableString;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@@ -15,43 +16,45 @@ import androidx.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.StringSetting;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.StringRef; import app.revanced.extension.shared.StringRef;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.FloatSetting;
import app.revanced.extension.shared.settings.StringSetting;
import app.revanced.extension.youtube.settings.Settings;
public enum SegmentCategory { public enum SegmentCategory {
SPONSOR("sponsor", sf("revanced_sb_segments_sponsor"), sf("revanced_sb_segments_sponsor_sum"), sf("revanced_sb_skip_button_sponsor"), sf("revanced_sb_skipped_sponsor"), SPONSOR("sponsor", sf("revanced_sb_segments_sponsor"), sf("revanced_sb_segments_sponsor_sum"), sf("revanced_sb_skip_button_sponsor"), sf("revanced_sb_skipped_sponsor"),
SB_CATEGORY_SPONSOR, SB_CATEGORY_SPONSOR_COLOR), SB_CATEGORY_SPONSOR, SB_CATEGORY_SPONSOR_COLOR, SB_CATEGORY_SPONSOR_OPACITY),
SELF_PROMO("selfpromo", sf("revanced_sb_segments_selfpromo"), sf("revanced_sb_segments_selfpromo_sum"), sf("revanced_sb_skip_button_selfpromo"), sf("revanced_sb_skipped_selfpromo"), SELF_PROMO("selfpromo", sf("revanced_sb_segments_selfpromo"), sf("revanced_sb_segments_selfpromo_sum"), sf("revanced_sb_skip_button_selfpromo"), sf("revanced_sb_skipped_selfpromo"),
SB_CATEGORY_SELF_PROMO, SB_CATEGORY_SELF_PROMO_COLOR), SB_CATEGORY_SELF_PROMO, SB_CATEGORY_SELF_PROMO_COLOR, SB_CATEGORY_SELF_PROMO_OPACITY),
INTERACTION("interaction", sf("revanced_sb_segments_interaction"), sf("revanced_sb_segments_interaction_sum"), sf("revanced_sb_skip_button_interaction"), sf("revanced_sb_skipped_interaction"), INTERACTION("interaction", sf("revanced_sb_segments_interaction"), sf("revanced_sb_segments_interaction_sum"), sf("revanced_sb_skip_button_interaction"), sf("revanced_sb_skipped_interaction"),
SB_CATEGORY_INTERACTION, SB_CATEGORY_INTERACTION_COLOR), SB_CATEGORY_INTERACTION, SB_CATEGORY_INTERACTION_COLOR, SB_CATEGORY_INTERACTION_OPACITY),
/** /**
* Unique category that is treated differently than the rest. * Unique category that is treated differently than the rest.
*/ */
HIGHLIGHT("poi_highlight", sf("revanced_sb_segments_highlight"), sf("revanced_sb_segments_highlight_sum"), sf("revanced_sb_skip_button_highlight"), sf("revanced_sb_skipped_highlight"), HIGHLIGHT("poi_highlight", sf("revanced_sb_segments_highlight"), sf("revanced_sb_segments_highlight_sum"), sf("revanced_sb_skip_button_highlight"), sf("revanced_sb_skipped_highlight"),
SB_CATEGORY_HIGHLIGHT, SB_CATEGORY_HIGHLIGHT_COLOR), SB_CATEGORY_HIGHLIGHT, SB_CATEGORY_HIGHLIGHT_COLOR, SB_CATEGORY_HIGHLIGHT_OPACITY),
INTRO("intro", sf("revanced_sb_segments_intro"), sf("revanced_sb_segments_intro_sum"), INTRO("intro", sf("revanced_sb_segments_intro"), sf("revanced_sb_segments_intro_sum"),
sf("revanced_sb_skip_button_intro_beginning"), sf("revanced_sb_skip_button_intro_middle"), sf("revanced_sb_skip_button_intro_end"), sf("revanced_sb_skip_button_intro_beginning"), sf("revanced_sb_skip_button_intro_middle"), sf("revanced_sb_skip_button_intro_end"),
sf("revanced_sb_skipped_intro_beginning"), sf("revanced_sb_skipped_intro_middle"), sf("revanced_sb_skipped_intro_end"), sf("revanced_sb_skipped_intro_beginning"), sf("revanced_sb_skipped_intro_middle"), sf("revanced_sb_skipped_intro_end"),
SB_CATEGORY_INTRO, SB_CATEGORY_INTRO_COLOR), SB_CATEGORY_INTRO, SB_CATEGORY_INTRO_COLOR, SB_CATEGORY_INTRO_OPACITY),
OUTRO("outro", sf("revanced_sb_segments_outro"), sf("revanced_sb_segments_outro_sum"), sf("revanced_sb_skip_button_outro"), sf("revanced_sb_skipped_outro"), OUTRO("outro", sf("revanced_sb_segments_outro"), sf("revanced_sb_segments_outro_sum"), sf("revanced_sb_skip_button_outro"), sf("revanced_sb_skipped_outro"),
SB_CATEGORY_OUTRO, SB_CATEGORY_OUTRO_COLOR), SB_CATEGORY_OUTRO, SB_CATEGORY_OUTRO_COLOR, SB_CATEGORY_OUTRO_OPACITY),
PREVIEW("preview", sf("revanced_sb_segments_preview"), sf("revanced_sb_segments_preview_sum"), PREVIEW("preview", sf("revanced_sb_segments_preview"), sf("revanced_sb_segments_preview_sum"),
sf("revanced_sb_skip_button_preview_beginning"), sf("revanced_sb_skip_button_preview_middle"), sf("revanced_sb_skip_button_preview_end"), sf("revanced_sb_skip_button_preview_beginning"), sf("revanced_sb_skip_button_preview_middle"), sf("revanced_sb_skip_button_preview_end"),
sf("revanced_sb_skipped_preview_beginning"), sf("revanced_sb_skipped_preview_middle"), sf("revanced_sb_skipped_preview_end"), sf("revanced_sb_skipped_preview_beginning"), sf("revanced_sb_skipped_preview_middle"), sf("revanced_sb_skipped_preview_end"),
SB_CATEGORY_PREVIEW, SB_CATEGORY_PREVIEW_COLOR), SB_CATEGORY_PREVIEW, SB_CATEGORY_PREVIEW_COLOR, SB_CATEGORY_PREVIEW_OPACITY),
FILLER("filler", sf("revanced_sb_segments_filler"), sf("revanced_sb_segments_filler_sum"), sf("revanced_sb_skip_button_filler"), sf("revanced_sb_skipped_filler"), FILLER("filler", sf("revanced_sb_segments_filler"), sf("revanced_sb_segments_filler_sum"), sf("revanced_sb_skip_button_filler"), sf("revanced_sb_skipped_filler"),
SB_CATEGORY_FILLER, SB_CATEGORY_FILLER_COLOR), SB_CATEGORY_FILLER, SB_CATEGORY_FILLER_COLOR, SB_CATEGORY_FILLER_OPACITY),
MUSIC_OFFTOPIC("music_offtopic", sf("revanced_sb_segments_nomusic"), sf("revanced_sb_segments_nomusic_sum"), sf("revanced_sb_skip_button_nomusic"), sf("revanced_sb_skipped_nomusic"), MUSIC_OFFTOPIC("music_offtopic", sf("revanced_sb_segments_nomusic"), sf("revanced_sb_segments_nomusic_sum"), sf("revanced_sb_skip_button_nomusic"), sf("revanced_sb_skipped_nomusic"),
SB_CATEGORY_MUSIC_OFFTOPIC, SB_CATEGORY_MUSIC_OFFTOPIC_COLOR), SB_CATEGORY_MUSIC_OFFTOPIC, SB_CATEGORY_MUSIC_OFFTOPIC_COLOR, SB_CATEGORY_MUSIC_OFFTOPIC_OPACITY),
UNSUBMITTED("unsubmitted", StringRef.empty, StringRef.empty, sf("revanced_sb_skip_button_unsubmitted"), sf("revanced_sb_skipped_unsubmitted"), UNSUBMITTED("unsubmitted", StringRef.empty, StringRef.empty, sf("revanced_sb_skip_button_unsubmitted"), sf("revanced_sb_skipped_unsubmitted"),
SB_CATEGORY_UNSUBMITTED, SB_CATEGORY_UNSUBMITTED_COLOR),; SB_CATEGORY_UNSUBMITTED, SB_CATEGORY_UNSUBMITTED_COLOR, SB_CATEGORY_UNSUBMITTED_OPACITY);
private static final StringRef skipSponsorTextCompact = sf("revanced_sb_skip_button_compact"); private static final StringRef skipSponsorTextCompact = sf("revanced_sb_skip_button_compact");
private static final StringRef skipSponsorTextCompactHighlight = sf("revanced_sb_skip_button_compact_highlight"); private static final StringRef skipSponsorTextCompactHighlight = sf("revanced_sb_skip_button_compact_highlight");
@@ -90,12 +93,10 @@ public enum SegmentCategory {
mValuesMap.put(value.keyValue, value); mValuesMap.put(value.keyValue, value);
} }
@NonNull
public static SegmentCategory[] categoriesWithoutUnsubmitted() { public static SegmentCategory[] categoriesWithoutUnsubmitted() {
return categoriesWithoutUnsubmitted; return categoriesWithoutUnsubmitted;
} }
@NonNull
public static SegmentCategory[] categoriesWithoutHighlights() { public static SegmentCategory[] categoriesWithoutHighlights() {
return categoriesWithoutHighlights; return categoriesWithoutHighlights;
} }
@@ -106,7 +107,7 @@ public enum SegmentCategory {
} }
/** /**
* Must be called if behavior of any category is changed * Must be called if behavior of any category is changed.
*/ */
public static void updateEnabledCategories() { public static void updateEnabledCategories() {
Utils.verifyOnMainThread(); Utils.verifyOnMainThread();
@@ -133,32 +134,33 @@ public enum SegmentCategory {
updateEnabledCategories(); updateEnabledCategories();
} }
@NonNull public static int applyOpacityToColor(int color, float opacity) {
public final String keyValue; if (opacity < 0 || opacity > 1.0f) {
@NonNull throw new IllegalArgumentException("Invalid opacity: " + opacity);
public final StringSetting behaviorSetting; }
@NonNull final int opacityInt = (int) (255 * opacity);
private final StringSetting colorSetting; return (color & 0x00FFFFFF) | (opacityInt << 24);
}
public final String keyValue;
public final StringSetting behaviorSetting; // TODO: Replace with EnumSetting.
private final StringSetting colorSetting;
private final FloatSetting opacitySetting;
@NonNull
public final StringRef title; public final StringRef title;
@NonNull
public final StringRef description; public final StringRef description;
/** /**
* Skip button text, if the skip occurs in the first quarter of the video * Skip button text, if the skip occurs in the first quarter of the video
*/ */
@NonNull
public final StringRef skipButtonTextBeginning; public final StringRef skipButtonTextBeginning;
/** /**
* Skip button text, if the skip occurs in the middle half of the video * Skip button text, if the skip occurs in the middle half of the video
*/ */
@NonNull
public final StringRef skipButtonTextMiddle; public final StringRef skipButtonTextMiddle;
/** /**
* Skip button text, if the skip occurs in the last quarter of the video * Skip button text, if the skip occurs in the last quarter of the video
*/ */
@NonNull
public final StringRef skipButtonTextEnd; public final StringRef skipButtonTextEnd;
/** /**
* Skipped segment toast, if the skip occurred in the first quarter of the video * Skipped segment toast, if the skip occurred in the first quarter of the video
@@ -179,10 +181,7 @@ public enum SegmentCategory {
@NonNull @NonNull
public final Paint paint; public final Paint paint;
/** private int color;
* Value must be changed using {@link #setColor(String)}.
*/
public int color;
/** /**
* Value must be changed using {@link #setBehaviour(CategoryBehaviour)}. * Value must be changed using {@link #setBehaviour(CategoryBehaviour)}.
@@ -194,17 +193,20 @@ public enum SegmentCategory {
SegmentCategory(String keyValue, StringRef title, StringRef description, SegmentCategory(String keyValue, StringRef title, StringRef description,
StringRef skipButtonText, StringRef skipButtonText,
StringRef skippedToastText, StringRef skippedToastText,
StringSetting behavior, StringSetting color) { StringSetting behavior,
StringSetting color, FloatSetting opacity) {
this(keyValue, title, description, this(keyValue, title, description,
skipButtonText, skipButtonText, skipButtonText, skipButtonText, skipButtonText, skipButtonText,
skippedToastText, skippedToastText, skippedToastText, skippedToastText, skippedToastText, skippedToastText,
behavior, color); behavior,
color, opacity);
} }
SegmentCategory(String keyValue, StringRef title, StringRef description, SegmentCategory(String keyValue, StringRef title, StringRef description,
StringRef skipButtonTextBeginning, StringRef skipButtonTextMiddle, StringRef skipButtonTextEnd, StringRef skipButtonTextBeginning, StringRef skipButtonTextMiddle, StringRef skipButtonTextEnd,
StringRef skippedToastBeginning, StringRef skippedToastMiddle, StringRef skippedToastEnd, StringRef skippedToastBeginning, StringRef skippedToastMiddle, StringRef skippedToastEnd,
StringSetting behavior, StringSetting color) { StringSetting behavior,
StringSetting color, FloatSetting opacity) {
this.keyValue = Objects.requireNonNull(keyValue); this.keyValue = Objects.requireNonNull(keyValue);
this.title = Objects.requireNonNull(title); this.title = Objects.requireNonNull(title);
this.description = Objects.requireNonNull(description); this.description = Objects.requireNonNull(description);
@@ -216,6 +218,7 @@ public enum SegmentCategory {
this.skippedToastEnd = Objects.requireNonNull(skippedToastEnd); this.skippedToastEnd = Objects.requireNonNull(skippedToastEnd);
this.behaviorSetting = Objects.requireNonNull(behavior); this.behaviorSetting = Objects.requireNonNull(behavior);
this.colorSetting = Objects.requireNonNull(color); this.colorSetting = Objects.requireNonNull(color);
this.opacitySetting = Objects.requireNonNull(opacity);
this.paint = new Paint(); this.paint = new Paint();
loadFromSettings(); loadFromSettings();
} }
@@ -232,11 +235,14 @@ public enum SegmentCategory {
this.behaviour = savedBehavior; this.behaviour = savedBehavior;
String colorString = colorSetting.get(); String colorString = colorSetting.get();
final float opacity = opacitySetting.get();
try { try {
setColor(colorString); setColor(colorString);
setOpacity(opacity);
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "Invalid color: " + colorString, ex); Logger.printException(() -> "Invalid color: " + colorString + " opacity: " + opacity, ex);
colorSetting.resetToDefault(); colorSetting.resetToDefault();
opacitySetting.resetToDefault();
loadFromSettings(); loadFromSettings();
} }
} }
@@ -245,45 +251,78 @@ public enum SegmentCategory {
this.behaviour = Objects.requireNonNull(behaviour); this.behaviour = Objects.requireNonNull(behaviour);
this.behaviorSetting.save(behaviour.reVancedKeyValue); this.behaviorSetting.save(behaviour.reVancedKeyValue);
} }
/**
* @return HTML color format string
*/
@NonNull
public String colorString() {
return String.format("#%06X", color);
}
public void setColor(@NonNull String colorString) throws IllegalArgumentException { private void updateColor() {
final int color = Color.parseColor(colorString) & 0xFFFFFF; color = applyOpacityToColor(color, opacitySetting.get());
this.color = color;
paint.setColor(color); paint.setColor(color);
paint.setAlpha(255);
colorSetting.save(colorString); // Save after parsing.
} }
public void resetColor() { /**
* @param opacity Segment color opacity between [0, 1].
*/
public void setOpacity(float opacity) throws IllegalArgumentException {
if (opacity < 0 || opacity > 1) {
throw new IllegalArgumentException("Invalid opacity: " + opacity);
}
opacitySetting.save(opacity);
updateColor();
}
public float getOpacity() {
return opacitySetting.get();
}
public void resetColorAndOpacity() {
setColor(colorSetting.defaultValue); setColor(colorSetting.defaultValue);
setOpacity(opacitySetting.defaultValue);
} }
@NonNull /**
private static String getCategoryColorDotHTML(int color) { * @param colorString Segment color with #RRGGBB format.
color &= 0xFFFFFF; */
return String.format("<font color=\"#%06X\">⬤</font>", color); public void setColor(String colorString) throws IllegalArgumentException {
color = Color.parseColor(colorString);
colorSetting.save(colorString);
updateColor();
} }
@NonNull /**
public static Spanned getCategoryColorDot(int color) { * @return Integer color of #RRGGBB format.
return Html.fromHtml(getCategoryColorDotHTML(color)); */
public int getColorNoOpacity() {
return color & 0x00FFFFFF;
} }
@NonNull /**
public Spanned getCategoryColorDot() { * @return Hex color string of #RRGGBB format with no opacity level.
*/
public String getColorString() {
return String.format(Locale.US, "#%06X", getColorNoOpacity());
}
private static SpannableString getCategoryColorDotSpan(String text, int color) {
SpannableString dotSpan = new SpannableString('⬤' + text);
dotSpan.setSpan(new ForegroundColorSpan(color), 0, 1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return dotSpan;
}
public static SpannableString getCategoryColorDot(int color) {
return getCategoryColorDotSpan("", color);
}
public SpannableString getCategoryColorDot() {
return getCategoryColorDot(color); return getCategoryColorDot(color);
} }
@NonNull public SpannableString getTitleWithColorDot(int categoryColor) {
public Spanned getTitleWithColorDot() { return getCategoryColorDotSpan(" " + title, categoryColor);
return Html.fromHtml(getCategoryColorDotHTML(color) + " " + title); }
public SpannableString getTitleWithColorDot() {
return getTitleWithColorDot(color);
} }
/** /**
@@ -291,7 +330,6 @@ public enum SegmentCategory {
* @param videoLength length of the video * @param videoLength length of the video
* @return the skip button text * @return the skip button text
*/ */
@NonNull
StringRef getSkipButtonText(long segmentStartTime, long videoLength) { StringRef getSkipButtonText(long segmentStartTime, long videoLength) {
if (Settings.SB_COMPACT_SKIP_BUTTON.get()) { if (Settings.SB_COMPACT_SKIP_BUTTON.get()) {
return (this == SegmentCategory.HIGHLIGHT) return (this == SegmentCategory.HIGHLIGHT)
@@ -300,7 +338,7 @@ public enum SegmentCategory {
} }
if (videoLength == 0) { if (videoLength == 0) {
return skipButtonTextBeginning; // video is still loading. Assume it's the beginning return skipButtonTextBeginning; // Video is still loading. Assume it's the beginning.
} }
final float position = segmentStartTime / (float) videoLength; final float position = segmentStartTime / (float) videoLength;
if (position < 0.25f) { if (position < 0.25f) {
@@ -316,10 +354,9 @@ public enum SegmentCategory {
* @param videoLength length of the video * @param videoLength length of the video
* @return 'skipped segment' toast message * @return 'skipped segment' toast message
*/ */
@NonNull
StringRef getSkippedToastText(long segmentStartTime, long videoLength) { StringRef getSkippedToastText(long segmentStartTime, long videoLength) {
if (videoLength == 0) { if (videoLength == 0) {
return skippedToastBeginning; // video is still loading. Assume it's the beginning return skippedToastBeginning; // Video is still loading. Assume it's the beginning.
} }
final float position = segmentStartTime / (float) videoLength; final float position = segmentStartTime / (float) videoLength;
if (position < 0.25f) { if (position < 0.25f) {

View File

@@ -1,6 +1,7 @@
package app.revanced.extension.youtube.sponsorblock.objects; package app.revanced.extension.youtube.sponsorblock.objects;
import static app.revanced.extension.shared.StringRef.str; import static app.revanced.extension.shared.StringRef.str;
import static app.revanced.extension.youtube.sponsorblock.objects.SegmentCategory.applyOpacityToColor;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
@@ -11,11 +12,10 @@ import android.text.Editable;
import android.text.InputType; import android.text.InputType;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.widget.EditText; import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.GridLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView; import android.widget.TextView;
import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
@@ -24,27 +24,38 @@ import app.revanced.extension.shared.Utils;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class SegmentCategoryListPreference extends ListPreference { public class SegmentCategoryListPreference extends ListPreference {
private final SegmentCategory category; private final SegmentCategory category;
private EditText mEditText; private TextView colorDotView;
private int mClickedDialogEntryIndex; private EditText colorEditText;
private EditText opacityEditText;
/**
* #RRGGBB
*/
private int categoryColor;
/**
* [0, 1]
*/
private float categoryOpacity;
private int selectedDialogEntryIndex;
public SegmentCategoryListPreference(Context context, SegmentCategory category) { public SegmentCategoryListPreference(Context context, SegmentCategory category) {
super(context); super(context);
final boolean isHighlightCategory = category == SegmentCategory.HIGHLIGHT;
this.category = Objects.requireNonNull(category); this.category = Objects.requireNonNull(category);
// Edit: Using preferences to sync together multiple pieces // Edit: Using preferences to sync together multiple pieces
// of code together is messy and should be rethought. // of code is messy and should be rethought.
setKey(category.behaviorSetting.key); setKey(category.behaviorSetting.key);
setDefaultValue(category.behaviorSetting.defaultValue); setDefaultValue(category.behaviorSetting.defaultValue);
final boolean isHighlightCategory = category == SegmentCategory.HIGHLIGHT;
setEntries(isHighlightCategory setEntries(isHighlightCategory
? CategoryBehaviour.getBehaviorDescriptionsWithoutSkipOnce() ? CategoryBehaviour.getBehaviorDescriptionsWithoutSkipOnce()
: CategoryBehaviour.getBehaviorDescriptions()); : CategoryBehaviour.getBehaviorDescriptions());
setEntryValues(isHighlightCategory setEntryValues(isHighlightCategory
? CategoryBehaviour.getBehaviorKeyValuesWithoutSkipOnce() ? CategoryBehaviour.getBehaviorKeyValuesWithoutSkipOnce()
: CategoryBehaviour.getBehaviorKeyValues()); : CategoryBehaviour.getBehaviorKeyValues());
setSummary(category.description.toString()); setSummary(category.description.toString());
updateTitle();
updateTitleFromCategory();
} }
@Override @Override
@@ -52,26 +63,40 @@ public class SegmentCategoryListPreference extends ListPreference {
try { try {
Utils.setEditTextDialogTheme(builder); Utils.setEditTextDialogTheme(builder);
categoryColor = category.getColorNoOpacity();
categoryOpacity = category.getOpacity();
Context context = builder.getContext(); Context context = builder.getContext();
TableLayout table = new TableLayout(context); GridLayout gridLayout = new GridLayout(context);
table.setOrientation(LinearLayout.HORIZONTAL); gridLayout.setPadding(70, 0, 150, 0); // Padding for the entire layout.
table.setPadding(70, 0, 150, 0); gridLayout.setColumnCount(3);
gridLayout.setRowCount(2);
TableRow row = new TableRow(context);
GridLayout.LayoutParams gridParams = new GridLayout.LayoutParams();
gridParams.rowSpec = GridLayout.spec(0); // First row.
gridParams.columnSpec = GridLayout.spec(0); // First column.
TextView colorTextLabel = new TextView(context); TextView colorTextLabel = new TextView(context);
colorTextLabel.setText(str("revanced_sb_color_dot_label")); colorTextLabel.setText(str("revanced_sb_color_dot_label"));
row.addView(colorTextLabel); colorTextLabel.setLayoutParams(gridParams);
gridLayout.addView(colorTextLabel);
TextView colorDotView = new TextView(context); gridParams = new GridLayout.LayoutParams();
colorDotView.setText(category.getCategoryColorDot()); gridParams.rowSpec = GridLayout.spec(0); // First row.
colorDotView.setPadding(30, 0, 30, 0); gridParams.columnSpec = GridLayout.spec(1); // Second column.
row.addView(colorDotView); gridParams.setMargins(0, 0, 10, 0);
colorDotView = new TextView(context);
colorDotView.setLayoutParams(gridParams);
gridLayout.addView(colorDotView);
updateCategoryColorDot();
mEditText = new EditText(context); gridParams = new GridLayout.LayoutParams();
mEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS); gridParams.rowSpec = GridLayout.spec(0); // First row.
mEditText.setText(category.colorString()); gridParams.columnSpec = GridLayout.spec(2); // Third column.
mEditText.addTextChangedListener(new TextWatcher() { colorEditText = new EditText(context);
colorEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
colorEditText.setTextLocale(Locale.US);
colorEditText.setText(category.getColorString());
colorEditText.addTextChangedListener(new TextWatcher() {
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { public void beforeTextChanged(CharSequence s, int start, int count, int after) {
} }
@@ -81,29 +106,94 @@ public class SegmentCategoryListPreference extends ListPreference {
} }
@Override @Override
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable edit) {
try { try {
String colorString = s.toString(); String colorString = edit.toString();
final int colorStringLength = colorString.length();
if (!colorString.startsWith("#")) { if (!colorString.startsWith("#")) {
s.insert(0, "#"); // recursively calls back into this method edit.insert(0, "#"); // Recursively calls back into this method.
return; return;
} }
if (colorString.length() > 7) {
s.delete(7, colorString.length()); final int maxColorStringLength = 7; // #RRGGBB
if (colorStringLength > maxColorStringLength) {
edit.delete(maxColorStringLength, colorStringLength);
return; return;
} }
final int color = Color.parseColor(colorString);
colorDotView.setText(SegmentCategory.getCategoryColorDot(color)); categoryColor = Color.parseColor(colorString);
updateCategoryColorDot();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// ignore // Ignore.
} }
} }
}); });
mEditText.setLayoutParams(new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 1f)); colorEditText.setLayoutParams(gridParams);
row.addView(mEditText); gridLayout.addView(colorEditText);
table.addView(row); gridParams = new GridLayout.LayoutParams();
builder.setView(table); gridParams.rowSpec = GridLayout.spec(1); // Second row.
gridParams.columnSpec = GridLayout.spec(0, 1); // First and second column.
TextView opacityLabel = new TextView(context);
opacityLabel.setText(str("revanced_sb_color_opacity_label"));
opacityLabel.setLayoutParams(gridParams);
gridLayout.addView(opacityLabel);
gridParams = new GridLayout.LayoutParams();
gridParams.rowSpec = GridLayout.spec(1); // Second row.
gridParams.columnSpec = GridLayout.spec(2); // Third column.
opacityEditText = new EditText(context);
opacityEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
opacityEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable edit) {
try {
String editString = edit.toString();
final int opacityStringLength = editString.length();
final int maxOpacityStringLength = 4; // [0.00, 1.00]
if (opacityStringLength > maxOpacityStringLength) {
edit.delete(maxOpacityStringLength, opacityStringLength);
return;
}
final float opacity = opacityStringLength == 0
? 0
: Float.parseFloat(editString);
if (opacity < 0) {
categoryOpacity = 0;
edit.replace(0, opacityStringLength, "0");
return;
} else if (opacity > 1.0f) {
categoryOpacity = 1;
edit.replace(0, opacityStringLength, "1.0");
return;
} else if (!editString.endsWith(".")) {
// Ignore "0." and "1." until the user finishes entering a valid number.
categoryOpacity = opacity;
}
updateCategoryColorDot();
} catch (NumberFormatException ex) {
// Should never happen.
Logger.printException(() -> "Could not parse opacity string", ex);
}
}
});
opacityEditText.setLayoutParams(gridParams);
gridLayout.addView(opacityEditText);
updateOpacityText();
builder.setView(gridLayout);
builder.setTitle(category.title.toString()); builder.setTitle(category.title.toString());
builder.setPositiveButton(android.R.string.ok, (dialog, which) -> { builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
@@ -111,8 +201,8 @@ public class SegmentCategoryListPreference extends ListPreference {
}); });
builder.setNeutralButton(str("revanced_sb_reset_color"), (dialog, which) -> { builder.setNeutralButton(str("revanced_sb_reset_color"), (dialog, which) -> {
try { try {
category.resetColor(); category.resetColorAndOpacity();
updateTitle(); updateTitleFromCategory();
Utils.showToastShort(str("revanced_sb_color_reset")); Utils.showToastShort(str("revanced_sb_color_reset"));
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "setNeutralButton failure", ex); Logger.printException(() -> "setNeutralButton failure", ex);
@@ -120,8 +210,9 @@ public class SegmentCategoryListPreference extends ListPreference {
}); });
builder.setNegativeButton(android.R.string.cancel, null); builder.setNegativeButton(android.R.string.cancel, null);
mClickedDialogEntryIndex = findIndexOfValue(getValue()); selectedDialogEntryIndex = findIndexOfValue(getValue());
builder.setSingleChoiceItems(getEntries(), mClickedDialogEntryIndex, (dialog, which) -> mClickedDialogEntryIndex = which); builder.setSingleChoiceItems(getEntries(), selectedDialogEntryIndex,
(dialog, which) -> selectedDialogEntryIndex = which);
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "onPrepareDialogBuilder failure", ex); Logger.printException(() -> "onPrepareDialogBuilder failure", ex);
} }
@@ -130,30 +221,51 @@ public class SegmentCategoryListPreference extends ListPreference {
@Override @Override
protected void onDialogClosed(boolean positiveResult) { protected void onDialogClosed(boolean positiveResult) {
try { try {
if (positiveResult && mClickedDialogEntryIndex >= 0 && getEntryValues() != null) { if (positiveResult && selectedDialogEntryIndex >= 0 && getEntryValues() != null) {
String value = getEntryValues()[mClickedDialogEntryIndex].toString(); String value = getEntryValues()[selectedDialogEntryIndex].toString();
if (callChangeListener(value)) { if (callChangeListener(value)) {
setValue(value); setValue(value);
category.setBehaviour(Objects.requireNonNull(CategoryBehaviour.byReVancedKeyValue(value))); category.setBehaviour(Objects.requireNonNull(CategoryBehaviour.byReVancedKeyValue(value)));
SegmentCategory.updateEnabledCategories(); SegmentCategory.updateEnabledCategories();
} }
String colorString = mEditText.getText().toString();
try { try {
if (!colorString.equals(category.colorString())) { String colorString = colorEditText.getText().toString();
if (!colorString.equals(category.getColorString()) || categoryOpacity != category.getOpacity()) {
category.setColor(colorString); category.setColor(colorString);
category.setOpacity(categoryOpacity);
Utils.showToastShort(str("revanced_sb_color_changed")); Utils.showToastShort(str("revanced_sb_color_changed"));
} }
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
Utils.showToastShort(str("revanced_sb_color_invalid")); Utils.showToastShort(str("revanced_sb_color_invalid"));
} }
updateTitle();
updateTitleFromCategory();
} }
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "onDialogClosed failure", ex); Logger.printException(() -> "onDialogClosed failure", ex);
} }
} }
private void updateTitle() { private void applyOpacityToCategoryColor() {
setTitle(category.getTitleWithColorDot()); categoryColor = applyOpacityToColor(categoryColor, categoryOpacity);
}
private void updateTitleFromCategory() {
categoryColor = category.getColorNoOpacity();
categoryOpacity = category.getOpacity();
applyOpacityToCategoryColor();
setTitle(category.getTitleWithColorDot(categoryColor));
}
private void updateCategoryColorDot() {
applyOpacityToCategoryColor();
colorDotView.setText(SegmentCategory.getCategoryColorDot(categoryColor));
}
private void updateOpacityText() {
opacityEditText.setText(String.format(Locale.US, "%.2f", categoryOpacity));
} }
} }

View File

@@ -23,12 +23,15 @@ public class SponsorSegment implements Comparable<SponsorSegment> {
@NonNull @NonNull
public final StringRef title; public final StringRef title;
public final int apiVoteType; public final int apiVoteType;
public final boolean shouldHighlight; /**
* If the option should be highlighted for VIP users.
*/
public final boolean highlightIfVipAndVideoIsLocked;
SegmentVote(@NonNull StringRef title, int apiVoteType, boolean shouldHighlight) { SegmentVote(@NonNull StringRef title, int apiVoteType, boolean highlightIfVipAndVideoIsLocked) {
this.title = title; this.title = title;
this.apiVoteType = apiVoteType; this.apiVoteType = apiVoteType;
this.shouldHighlight = shouldHighlight; this.highlightIfVipAndVideoIsLocked = highlightIfVipAndVideoIsLocked;
} }
} }

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.13.0-dev.17 version = 5.15.0-dev.4

View File

@@ -776,8 +776,8 @@ public final class app/revanced/patches/shared/misc/settings/preference/TextPref
} }
public final class app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatchKt { public final class app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatchKt {
public static final fun spoofVideoStreamsPatch (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch; public static final fun spoofVideoStreamsPatch (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch;
public static synthetic fun spoofVideoStreamsPatch$default (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch; public static synthetic fun spoofVideoStreamsPatch$default (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch;
} }
public final class app/revanced/patches/shared/misc/spoof/UserAgentClientSpoofPatchKt { public final class app/revanced/patches/shared/misc/spoof/UserAgentClientSpoofPatchKt {
@@ -816,6 +816,10 @@ public final class app/revanced/patches/spotify/lite/ondemand/OnDemandPatchKt {
public static final fun getOnDemandPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getOnDemandPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
} }
public final class app/revanced/patches/spotify/misc/fix/SpoofSignaturePatchKt {
public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/spotify/navbar/PremiumNavbarTabPatchKt { public final class app/revanced/patches/spotify/navbar/PremiumNavbarTabPatchKt {
public static final fun getPremiumNavbarTabPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getPremiumNavbarTabPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
} }
@@ -1463,6 +1467,10 @@ public final class app/revanced/patches/youtube/video/quality/RememberVideoQuali
public static final fun getRememberVideoQualityPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getRememberVideoQualityPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
} }
public final class app/revanced/patches/youtube/video/quality/VideoQualityPatchKt {
public static final fun getVideoQualityPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/video/speed/PlaybackSpeedPatchKt { public final class app/revanced/patches/youtube/video/speed/PlaybackSpeedPatchKt {
public static final fun getPlaybackSpeedPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getPlaybackSpeedPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
} }

View File

@@ -5,10 +5,10 @@ import app.revanced.patches.all.misc.transformation.IMethodCall
import app.revanced.patches.all.misc.transformation.filterMapInstruction35c import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
internal const val EXTENSION_CLASS_DESCRIPTOR_PREFIX = private const val EXTENSION_CLASS_DESCRIPTOR_PREFIX =
"Lapp/revanced/extension/all/connectivity/wifi/spoof/SpoofWifiPatch" "Lapp/revanced/extension/all/connectivity/wifi/spoof/SpoofWifiPatch"
internal const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;" private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;"
@Suppress("unused") @Suppress("unused")
val spoofWifiPatch = bytecodePatch( val spoofWifiPatch = bytecodePatch(

View File

@@ -8,9 +8,8 @@ import org.w3c.dom.Element
@Suppress("unused") @Suppress("unused")
val changeVersionCodePatch = resourcePatch( val changeVersionCodePatch = resourcePatch(
name = "Change version code", name = "Change version code",
description = "Changes the version code of the app. By default the highest version code is set. " + description = "Changes the version code of the app. This will turn off app store updates " +
"This allows older versions of an app to be installed " + "and allows downgrading an existing app install to an older app version.",
"if their version code is set to the same or a higher value and can stop app stores to update the app.",
use = false, use = false,
) { ) {
val versionCode by intOption( val versionCode by intOption(
@@ -21,7 +20,8 @@ val changeVersionCodePatch = resourcePatch(
"Highest" to Int.MAX_VALUE, "Highest" to Int.MAX_VALUE,
), ),
title = "Version code", title = "Version code",
description = "The version code to use", description = "The version code to use. Using the highest value turns off app store " +
"updates and allows downgrading an existing app install to an older app version.",
required = true, required = true,
) { versionCode -> versionCode!! >= 1 } ) { versionCode -> versionCode!! >= 1 }

View File

@@ -17,7 +17,7 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
internal const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/music/spoof/SpoofClientPatch;" "Lapp/revanced/extension/music/spoof/SpoofClientPatch;"
// TODO: Replace this patch with spoofVideoStreamsPatch once possible. // TODO: Replace this patch with spoofVideoStreamsPatch once possible.

View File

@@ -1,7 +1,10 @@
package app.revanced.patches.reddit.customclients.boostforreddit.api package app.revanced.patches.reddit.customclients.boostforreddit.api
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patches.reddit.customclients.spoofClientPatch import app.revanced.patches.reddit.customclients.spoofClientPatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
val spoofClientPatch = spoofClientPatch(redirectUri = "http://rubenmayayo.com") { clientIdOption -> val spoofClientPatch = spoofClientPatch(redirectUri = "http://rubenmayayo.com") { clientIdOption ->
compatibleWith("com.rubenmayayo.reddit") compatibleWith("com.rubenmayayo.reddit")
@@ -23,14 +26,15 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "http://rubenmayayo.com")
// region Patch user agent. // region Patch user agent.
// Use a random number as the platform in the user agent string. // Use a random user agent.
val platformName = (0..100000).random() val randomName = (0..100000).random()
val platformParameter = 0 val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
buildUserAgentFingerprint.let {
buildUserAgentFingerprint.method.addInstructions( val userAgentTemplateIndex = it.stringMatches!!.first().index
0, val register = it.method.getInstruction<OneRegisterInstruction>(userAgentTemplateIndex).registerA
"const-string p$platformParameter, \"$platformName\"",
) it.method.replaceInstruction(userAgentTemplateIndex, "const-string v$register, \"$userAgent\"")
}
// endregion // endregion
} }

View File

@@ -8,7 +8,11 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation
val spoofClientPatch = spoofClientPatch(redirectUri = "infinity://localhost") { clientIdOption -> val spoofClientPatch = spoofClientPatch(redirectUri = "infinity://localhost") { clientIdOption ->
compatibleWith("ml.docilealligator.infinityforreddit") compatibleWith(
"ml.docilealligator.infinityforreddit",
"ml.docilealligator.infinityforreddit.plus",
"ml.docilealligator.infinityforreddit.patreon"
)
val clientId by clientIdOption val clientId by clientIdOption

View File

@@ -11,7 +11,11 @@ val unlockSubscriptionPatch = bytecodePatch(
) { ) {
dependsOn(spoofClientPatch) dependsOn(spoofClientPatch)
compatibleWith("ml.docilealligator.infinityforreddit") compatibleWith(
"ml.docilealligator.infinityforreddit",
"ml.docilealligator.infinityforreddit.plus",
"ml.docilealligator.infinityforreddit.patreon"
)
execute { execute {
setOf( setOf(

View File

@@ -17,7 +17,7 @@ import org.w3c.dom.Element
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
abstract class BasePreference( abstract class BasePreference(
val key: String? = null, val key: String? = null,
val titleKey: String = "${key}_title", val titleKey: String? = "${key}_title",
val summaryKey: String? = "${key}_summary", val summaryKey: String? = "${key}_summary",
val icon: String? = null, val icon: String? = null,
val layout: String? = null, val layout: String? = null,
@@ -35,7 +35,7 @@ abstract class BasePreference(
open fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit): Element = open fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit): Element =
ownerDocument.createElement(tag).apply { ownerDocument.createElement(tag).apply {
key?.let { setAttribute("android:key", it) } key?.let { setAttribute("android:key", it) }
setAttribute("android:title", "@string/${titleKey}") titleKey?.let { setAttribute("android:title", "@string/${titleKey}") }
summaryKey?.let { addSummary(it) } summaryKey?.let { addSummary(it) }
icon?.let { icon?.let {
setAttribute("android:icon", it) setAttribute("android:icon", it)

View File

@@ -17,7 +17,7 @@ import org.w3c.dom.Document
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
open class PreferenceCategory( open class PreferenceCategory(
key: String? = null, key: String? = null,
titleKey: String = "${key}_title", titleKey: String? = "${key}_title",
icon: String? = null, icon: String? = null,
layout: String? = null, layout: String? = null,
sorting: Sorting = Sorting.BY_TITLE, sorting: Sorting = Sorting.BY_TITLE,

View File

@@ -137,3 +137,15 @@ internal val patchIncludedExtensionMethodFingerprint = fingerprint {
classDef.type == EXTENSION_CLASS_DESCRIPTOR && method.name == "isPatchIncluded" classDef.type == EXTENSION_CLASS_DESCRIPTOR && method.name == "isPatchIncluded"
} }
} }
// Feature flag that turns on Platypus programming language code compiled to native C++.
// This code appears to replace the player config after the streams are loaded.
// Flag is present in YouTube 19.34, but is missing Platypus stream replacement code until 19.43.
// Flag and Platypus code is also present in newer versions of YouTube Music.
internal const val MEDIA_FETCH_HOT_CONFIG_FEATURE_FLAG = 45645570L
internal val mediaFetchHotConfigFingerprint = fingerprint {
literal {
MEDIA_FETCH_HOT_CONFIG_FEATURE_FLAG
}
}

View File

@@ -31,10 +31,11 @@ internal const val EXTENSION_CLASS_DESCRIPTOR =
fun spoofVideoStreamsPatch( fun spoofVideoStreamsPatch(
block: BytecodePatchBuilder.() -> Unit = {}, block: BytecodePatchBuilder.() -> Unit = {},
applyMediaFetchHotConfigChanges: BytecodePatchBuilder.() -> Boolean = { false },
executeBlock: BytecodePatchContext.() -> Unit = {}, executeBlock: BytecodePatchContext.() -> Unit = {},
) = bytecodePatch( ) = bytecodePatch(
name = "Spoof video streams", name = "Spoof video streams",
description = "Spoofs the client video streams to fix playback.", description = "Adds options to spoof the client video streams to fix playback.",
) { ) {
block() block()
@@ -238,6 +239,17 @@ fun spoofVideoStreamsPatch(
// endregion // endregion
// region turn off stream config replacement feature flag.
if (applyMediaFetchHotConfigChanges()) {
mediaFetchHotConfigFingerprint.method.insertFeatureFlagBooleanOverride(
MEDIA_FETCH_HOT_CONFIG_FEATURE_FLAG,
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
)
}
// endregion
executeBlock() executeBlock()
} }
} }

View File

@@ -0,0 +1,5 @@
package app.revanced.patches.spotify.misc.fix
import app.revanced.patcher.fingerprint
internal val getAppSignatureFingerprint = fingerprint { strings("Failed to get the application signatures") }

View File

@@ -0,0 +1,33 @@
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.util.indexOfFirstInstructionReversedOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Suppress("unused")
val spoofSignaturePatch = bytecodePatch(
name = "Spoof signature",
description = "Spoofs the signature of the app to fix various functions of the app.",
) {
compatibleWith("com.spotify.music")
execute {
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

@@ -11,7 +11,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.FieldReference
internal const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/tiktok/settings/AdPersonalizationActivityHook;" "Lapp/revanced/extension/tiktok/settings/AdPersonalizationActivityHook;"
val settingsPatch = bytecodePatch( val settingsPatch = bytecodePatch(

View File

@@ -12,7 +12,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/tudortmund/lockscreen/ShowOnLockscreenPatch;" "Lapp/revanced/extension/tudortmund/lockscreen/ShowOnLockscreenPatch;"
@Suppress("unused") @Suppress("unused")

View File

@@ -11,7 +11,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 com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
internal const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/HideGetPremiumPatch;" "Lapp/revanced/extension/youtube/patches/HideGetPremiumPatch;"
val hideGetPremiumPatch = bytecodePatch( val hideGetPremiumPatch = bytecodePatch(

View File

@@ -50,7 +50,7 @@ private val downloadsResourcePatch = resourcePatch {
} }
} }
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DownloadsPatch;" private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DownloadsPatch;"
internal const val BUTTON_DESCRIPTOR = "Lapp/revanced/extension/youtube/videoplayer/ExternalDownloadButton;" internal const val BUTTON_DESCRIPTOR = "Lapp/revanced/extension/youtube/videoplayer/ExternalDownloadButton;"

View File

@@ -15,8 +15,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
val enableSeekbarTappingPatch = bytecodePatch( val enableSeekbarTappingPatch = bytecodePatch(
name = "Seekbar tapping", name = "Enable tap to seek",
description = "Adds an option to enable tap-to-seek on the seekbar of the video player.", description = "Adds an option to enable tap to seek on the seekbar of the video player.",
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,

View File

@@ -23,7 +23,7 @@ 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
internal const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/NavigationButtonsPatch;" "Lapp/revanced/extension/youtube/patches/NavigationButtonsPatch;"
val navigationButtonsPatch = bytecodePatch( val navigationButtonsPatch = bytecodePatch(

View File

@@ -43,7 +43,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
val hidePlayerOverlayButtonsPatch = bytecodePatch( val hidePlayerOverlayButtonsPatch = bytecodePatch(
name = "Hide player overlay buttons", name = "Hide player overlay buttons",
description = "Adds options to hide the player cast, autoplay, caption button and next/ previous buttons.", description = "Adds options to hide the player Cast, Autoplay, Captions, and Previous & Next buttons.",
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,

View File

@@ -6,7 +6,9 @@ import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.ListPreference import app.revanced.patches.shared.misc.settings.preference.ListPreference
import app.revanced.patches.youtube.layout.buttons.navigation.navigationButtonsPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.navigation.hookNavigationButtonCreated
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.getReference import app.revanced.util.getReference
@@ -15,7 +17,7 @@ import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.FieldReference
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/ChangeFormFactorPatch;" private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/ChangeFormFactorPatch;"
@Suppress("unused") @Suppress("unused")
val changeFormFactorPatch = bytecodePatch( val changeFormFactorPatch = bytecodePatch(
@@ -26,6 +28,7 @@ val changeFormFactorPatch = bytecodePatch(
sharedExtensionPatch, sharedExtensionPatch,
settingsPatch, settingsPatch,
addResourcesPatch, addResourcesPatch,
navigationButtonsPatch
) )
compatibleWith( compatibleWith(
@@ -50,6 +53,8 @@ val changeFormFactorPatch = bytecodePatch(
) )
) )
hookNavigationButtonCreated(EXTENSION_CLASS_DESCRIPTOR)
createPlayerRequestBodyWithModelFingerprint.method.apply { createPlayerRequestBodyWithModelFingerprint.method.apply {
val formFactorEnumClass = formFactorEnumConstructorFingerprint.originalClassDef.type val formFactorEnumClass = formFactorEnumConstructorFingerprint.originalClassDef.type

View File

@@ -49,7 +49,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
@Suppress("unused") @Suppress("unused")
val hideEndscreenCardsPatch = bytecodePatch( val hideEndscreenCardsPatch = bytecodePatch(
name = "Hide endscreen cards", name = "Hide end screen cards",
description = "Adds an option to hide suggested video cards at the end of videos.", description = "Adds an option to hide suggested video cards at the end of videos.",
) { ) {
dependsOn( dependsOn(

View File

@@ -22,7 +22,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
@Suppress("unused") @Suppress("unused")
val hideEndScreenSuggestedVideoPatch = bytecodePatch( val hideEndScreenSuggestedVideoPatch = bytecodePatch(
name = "Hide end screen suggested video", name = "Hide end screen suggested video",
description = "Adds an option to hide the recommended video at the end of each video.", description = "Adds an option to hide the suggested video at the end of videos.",
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,

View File

@@ -14,7 +14,7 @@ import app.revanced.util.indexOfFirstInstructionReversedOrThrow
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.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/DisableFullscreenAmbientModePatch;" "Lapp/revanced/extension/youtube/patches/DisableFullscreenAmbientModePatch;"
val disableFullscreenAmbientModePatch = bytecodePatch( val disableFullscreenAmbientModePatch = bytecodePatch(

View File

@@ -158,9 +158,9 @@ val hideLayoutComponentsPatch = bytecodePatch(
SwitchPreference("revanced_hide_comments_by_members_header"), SwitchPreference("revanced_hide_comments_by_members_header"),
SwitchPreference("revanced_hide_comments_section"), SwitchPreference("revanced_hide_comments_section"),
SwitchPreference("revanced_hide_comments_create_a_short_button"), SwitchPreference("revanced_hide_comments_create_a_short_button"),
SwitchPreference("revanced_hide_comments_timestamp_and_emoji_buttons"),
SwitchPreference("revanced_hide_comments_preview_comment"), SwitchPreference("revanced_hide_comments_preview_comment"),
SwitchPreference("revanced_hide_comments_thanks_button"), SwitchPreference("revanced_hide_comments_thanks_button"),
SwitchPreference("revanced_hide_comments_timestamp_and_emoji_buttons"),
), ),
sorting = PreferenceScreenPreference.Sorting.UNSORTED, sorting = PreferenceScreenPreference.Sorting.UNSORTED,
), ),

View File

@@ -159,7 +159,7 @@ private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/pat
@Suppress("unused") @Suppress("unused")
val hideShortsComponentsPatch = bytecodePatch( val hideShortsComponentsPatch = bytecodePatch(
name = "Hide Shorts components", name = "Hide Shorts components",
description = "Adds options to hide components related to YouTube Shorts.", description = "Adds options to hide components related to Shorts.",
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,

View File

@@ -134,7 +134,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/
@Suppress("unused") @Suppress("unused")
val miniplayerPatch = bytecodePatch( val miniplayerPatch = bytecodePatch(
name = "Miniplayer", name = "Miniplayer",
description = "Adds options to change the in app minimized player." description = "Adds options to change the in-app minimized player."
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,

View File

@@ -98,20 +98,6 @@ internal val rollingNumberTextViewFingerprint = fingerprint {
} }
} }
internal val shortsTextViewFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters("L", "L")
opcodes(
Opcode.INVOKE_SUPER, // first instruction of method
Opcode.IF_NEZ,
null,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
)
}
internal val textComponentConstructorFingerprint = fingerprint { internal val textComponentConstructorFingerprint = fingerprint {
accessFlags(AccessFlags.CONSTRUCTOR, AccessFlags.PRIVATE) accessFlags(AccessFlags.CONSTRUCTOR, AccessFlags.PRIVATE)
strings("TextComponent") strings("TextComponent")

View File

@@ -1,9 +1,7 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike package app.revanced.patches.youtube.layout.returnyoutubedislike
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.instructions
import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResources
@@ -169,51 +167,7 @@ val returnYouTubeDislikePatch = bytecodePatch(
// endregion // endregion
// region Hook for non-litho Short videos. // region Hook Shorts
shortsTextViewFingerprint.method.apply {
val insertIndex = shortsTextViewFingerprint.patternMatch!!.endIndex + 1
// If the field is true, the TextView is for a dislike button.
val isDisLikesBooleanInstruction = instructions.first { instruction ->
instruction.opcode == Opcode.IGET_BOOLEAN
} as ReferenceInstruction
val isDisLikesBooleanReference = isDisLikesBooleanInstruction.reference
// Like/Dislike button TextView field.
val textViewFieldInstruction = instructions.first { instruction ->
instruction.opcode == Opcode.IGET_OBJECT
} as ReferenceInstruction
val textViewFieldReference = textViewFieldInstruction.reference
// Check if the hooked TextView object is that of the dislike button.
// If RYD is disabled, or the TextView object is not that of the dislike button, the execution flow is not interrupted.
// Otherwise, the TextView object is modified, and the execution flow is interrupted to prevent it from being changed afterward.
addInstructionsWithLabels(
insertIndex,
"""
# Check, if the TextView is for a dislike button
iget-boolean v0, p0, $isDisLikesBooleanReference
if-eqz v0, :is_like
# Hook the TextView, if it is for the dislike button
iget-object v0, p0, $textViewFieldReference
invoke-static {v0}, $EXTENSION_CLASS_DESCRIPTOR->setShortsDislikes(Landroid/view/View;)Z
move-result v0
if-eqz v0, :ryd_disabled
return-void
:is_like
:ryd_disabled
nop
""",
)
}
// endregion
// region Hook for litho Shorts
// Filter that parses the video id from the UI // Filter that parses the video id from the UI
addLithoFilter(FILTER_CLASS_DESCRIPTOR) addLithoFilter(FILTER_CLASS_DESCRIPTOR)
@@ -255,22 +209,25 @@ val returnYouTubeDislikePatch = bytecodePatch(
) )
} }
// Rolling Number text views use the measured width of the raw string for layout. rollingNumberMeasureAnimatedTextFingerprint.let {
// Modify the measure text calculation to include the left drawable separator if needed. // Rolling Number text views use the measured width of the raw string for layout.
val patternMatch = rollingNumberMeasureAnimatedTextFingerprint.patternMatch!! // Modify the measure text calculation to include the left drawable separator if needed.
// Additional check to verify the opcodes are at the start of the method val patternMatch = it.patternMatch!!
if (patternMatch.startIndex != 0) throw PatchException("Unexpected opcode location") // Verify the opcodes are at the start of the method.
val endIndex = patternMatch.endIndex if (patternMatch.startIndex != 0) throw PatchException("Unexpected opcode location")
rollingNumberMeasureAnimatedTextFingerprint.method.apply { val endIndex = patternMatch.endIndex
val measuredTextWidthRegister = getInstruction<OneRegisterInstruction>(endIndex).registerA
addInstructions( it.method.apply {
endIndex + 1, val measuredTextWidthRegister = getInstruction<OneRegisterInstruction>(endIndex).registerA
"""
invoke-static {p1, v$measuredTextWidthRegister}, $EXTENSION_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F addInstructions(
move-result v$measuredTextWidthRegister endIndex + 1,
""", """
) invoke-static {p1, v$measuredTextWidthRegister}, $EXTENSION_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F
move-result v$measuredTextWidthRegister
"""
)
}
} }
// Additional text measurement method. Used if YouTube decides not to animate the likes count // Additional text measurement method. Used if YouTube decides not to animate the likes count
@@ -291,15 +248,14 @@ val returnYouTubeDislikePatch = bytecodePatch(
) )
} }
} }
// The rolling number Span is missing styling since it's initially set as a String.
// Modify the UI text view and use the styled like/dislike Span.
// Initial TextView is set in this method.
val initiallyCreatedTextViewMethod = rollingNumberTextViewFingerprint.method
// Videos less than 24 hours after uploaded, like counts will be updated in real time.
// Whenever like counts are updated, TextView is set in this method.
arrayOf( arrayOf(
initiallyCreatedTextViewMethod, // The rolling number Span is missing styling since it's initially set as a String.
// Modify the UI text view and use the styled like/dislike Span.
// Initial TextView is set in this method.
rollingNumberTextViewFingerprint.method,
// Videos less than 24 hours after uploaded, like counts will be updated in real time.
// Whenever like counts are updated, TextView is set in this method.
rollingNumberTextViewAnimationUpdateFingerprint.method, rollingNumberTextViewAnimationUpdateFingerprint.method,
).forEach { insertMethod -> ).forEach { insertMethod ->
insertMethod.apply { insertMethod.apply {
@@ -315,9 +271,9 @@ val returnYouTubeDislikePatch = bytecodePatch(
addInstructions( addInstructions(
setTextIndex, setTextIndex,
""" """
invoke-static {v$textViewRegister, v$textSpanRegister}, $EXTENSION_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; invoke-static {v$textViewRegister, v$textSpanRegister}, $EXTENSION_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$textSpanRegister move-result-object v$textSpanRegister
""", """
) )
} }
} }

View File

@@ -12,9 +12,11 @@ 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.patches.shared.misc.settings.preference.ListPreference import app.revanced.patches.shared.misc.settings.preference.ListPreference
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
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.playservice.is_19_17_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_43_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch 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
@@ -44,8 +46,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
val spoofAppVersionPatch = bytecodePatch( val spoofAppVersionPatch = bytecodePatch(
name = "Spoof app version", name = "Spoof app version",
description = "Adds an option to trick YouTube into thinking you are running an older version of the app. " + description = "Adds an option to trick YouTube into thinking you are running an older version of the app. " +
"This can be used to restore old UI elements and features. " + "This can be used to restore old UI elements and features."
"Patching 19.16.39 includes additional older spoofing targets.",
) { ) {
dependsOn( dependsOn(
spoofAppVersionResourcePatch, spoofAppVersionResourcePatch,
@@ -58,8 +59,8 @@ val spoofAppVersionPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"19.16.39", "19.16.39",
// "19.25.37", // Cannot be supported because the lowest spoof target is higher. "19.25.37",
// "19.34.42", // Cannot be supported because the lowest spoof target is higher. "19.34.42",
"19.43.41", "19.43.41",
"19.45.38", "19.45.38",
"19.46.42", "19.46.42",
@@ -71,27 +72,35 @@ val spoofAppVersionPatch = bytecodePatch(
addResources("youtube", "layout.spoofappversion.spoofAppVersionPatch") addResources("youtube", "layout.spoofappversion.spoofAppVersionPatch")
PreferenceScreen.GENERAL_LAYOUT.addPreferences( PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_spoof_app_version"), // Group the switch and list preference together, since General menu is sorted by name
if (is_19_17_or_greater) { // and the preferences can be scattered apart with non English langauges.
ListPreference( PreferenceCategory(
key = "revanced_spoof_app_version_target", titleKey = null,
summaryKey = null, sorting = Sorting.UNSORTED,
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
preferences = setOf(
SwitchPreference("revanced_spoof_app_version"),
if (is_19_43_or_greater) {
ListPreference(
key = "revanced_spoof_app_version_target",
summaryKey = null,
)
} else {
ListPreference(
key = "revanced_spoof_app_version_target",
summaryKey = null,
entriesKey = "revanced_spoof_app_version_target_legacy_entries",
entryValuesKey = "revanced_spoof_app_version_target_legacy_entry_values"
)
}
) )
} else { )
ListPreference(
key = "revanced_spoof_app_version_target",
summaryKey = null,
entriesKey = "revanced_spoof_app_version_target_legacy_entries",
entryValuesKey = "revanced_spoof_app_version_target_legacy_entry_values"
)
}
) )
/** /**
* If a user really wants to spoof to very old versions with the latest app target * If spoofing to target 19.20 or earlier the Library tab can crash due to
* they can modify the import/export spoof version. But when spoofing the 19.20.xx * missing image resources. As a workaround, do not set an image in the
* or earlier the Library tab can crash due to missing image resources trying to load. * toolbar when the enum name is UNKNOWN.
* As a temporary workaround, do not set an image in the toolbar when the enum name is UNKNOWN.
*/ */
toolBarButtonFingerprint.method.apply { toolBarButtonFingerprint.method.apply {
val getDrawableIndex = indexOfGetDrawableInstruction(this) val getDrawableIndex = indexOfGetDrawableInstruction(this)

View File

@@ -8,7 +8,10 @@ import app.revanced.patcher.patch.stringOption
import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.BasePreference
import app.revanced.patches.shared.misc.settings.preference.InputType import app.revanced.patches.shared.misc.settings.preference.InputType
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.layout.seekbar.seekbarColorPatch import app.revanced.patches.youtube.layout.seekbar.seekbarColorPatch
@@ -71,6 +74,9 @@ val themePatch = bytecodePatch(
) )
dependsOn( dependsOn(
sharedExtensionPatch,
settingsPatch,
addResourcesPatch,
lithoColorHookPatch, lithoColorHookPatch,
seekbarColorPatch, seekbarColorPatch,
versionCheckPatch, versionCheckPatch,
@@ -78,23 +84,30 @@ val themePatch = bytecodePatch(
dependsOn( dependsOn(
settingsPatch, settingsPatch,
resourceMappingPatch, resourceMappingPatch,
addResourcesPatch,
) )
execute { execute {
addResources("youtube", "layout.theme.themeResourcePatch") val preferences = mutableSetOf<BasePreference>(
PreferenceScreen.SEEKBAR.addPreferences(
SwitchPreference("revanced_seekbar_custom_color"), SwitchPreference("revanced_seekbar_custom_color"),
TextPreference("revanced_seekbar_custom_color_primary", inputType = InputType.TEXT_CAP_CHARACTERS), TextPreference("revanced_seekbar_custom_color_primary", inputType = InputType.TEXT_CAP_CHARACTERS),
) )
if (is_19_25_or_greater) { if (is_19_25_or_greater) {
PreferenceScreen.SEEKBAR.addPreferences( preferences += TextPreference(
TextPreference("revanced_seekbar_custom_color_accent", inputType = InputType.TEXT_CAP_CHARACTERS), "revanced_seekbar_custom_color_accent",
inputType = InputType.TEXT_CAP_CHARACTERS
) )
} }
PreferenceScreen.SEEKBAR.addPreferences(
PreferenceCategory(
titleKey = null,
sorting = Sorting.UNSORTED,
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
preferences = preferences
)
)
// Edit theme colors via resources. // Edit theme colors via resources.
document("res/values/colors.xml").use { document -> document("res/values/colors.xml").use { document ->
@@ -125,7 +138,6 @@ val themePatch = bytecodePatch(
colorValue: String, colorValue: String,
) { ) {
document(resourceFile).use { document -> document(resourceFile).use { document ->
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
resourcesNode.appendChild( resourcesNode.appendChild(
@@ -133,7 +145,7 @@ val themePatch = bytecodePatch(
setAttribute("name", colorName) setAttribute("name", colorName)
setAttribute("category", "color") setAttribute("category", "color")
textContent = colorValue textContent = colorValue
}, }
) )
} }
} }
@@ -152,11 +164,10 @@ val themePatch = bytecodePatch(
// Edit splash screen files and change the background color, // Edit splash screen files and change the background color,
// if the background colors are set. // if the background colors are set.
if (darkThemeBackgroundColor != null && lightThemeBackgroundColor != null) { if (darkThemeBackgroundColor != null && lightThemeBackgroundColor != null) {
val splashScreenResourceFiles = val splashScreenResourceFiles = listOf(
listOf( "res/drawable/quantum_launchscreen_youtube.xml",
"res/drawable/quantum_launchscreen_youtube.xml", "res/drawable-sw600dp/quantum_launchscreen_youtube.xml",
"res/drawable-sw600dp/quantum_launchscreen_youtube.xml", )
)
splashScreenResourceFiles.forEach editSplashScreen@{ resourceFile -> splashScreenResourceFiles.forEach editSplashScreen@{ resourceFile ->
document(resourceFile).use { document -> document(resourceFile).use { document ->
@@ -174,36 +185,34 @@ val themePatch = bytecodePatch(
// Fix the splash screen dark mode background color. // Fix the splash screen dark mode background color.
// In 19.32+ the dark mode splash screen is white and fades to black. // In 19.32+ the dark mode splash screen is white and fades to black.
// Maybe it's a bug in YT, or maybe it intentionally. Who knows. // Maybe it's a bug in YT, or maybe it intentionally. Who knows.
document("res/values-night/styles.xml").use { document -> document("res/values-night-v27/styles.xml").use { document ->
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element // Create a night mode specific override for the splash screen background.
val childNodes = resourcesNode.childNodes val style = document.createElement("style")
style.setAttribute("name", "Theme.YouTube.Home")
style.setAttribute("parent", "@style/Base.V27.Theme.YouTube.Home")
for (i in 0 until childNodes.length) { // Fix status and navigation bar showing white on some Android devices,
val node = childNodes.item(i) as? Element ?: continue // such as SDK 28 Android 10 medium tablet.
val nodeAttributeName = node.getAttribute("name") val colorSplashBackgroundColor = "@color/$splashBackgroundColor"
if (nodeAttributeName.startsWith("Theme.YouTube.Launcher")) { arrayOf(
val nodeAttributeParent = node.getAttribute("parent") "android:navigationBarColor" to colorSplashBackgroundColor,
"android:windowBackground" to colorSplashBackgroundColor,
val style = document.createElement("style") "android:colorBackground" to colorSplashBackgroundColor,
style.setAttribute("name", "Theme.YouTube.Home") "colorPrimaryDark" to colorSplashBackgroundColor,
style.setAttribute("parent", nodeAttributeParent) "android:windowLightStatusBar" to "false",
).forEach { (name, value) ->
val windowItem = document.createElement("item") val styleItem = document.createElement("item")
windowItem.setAttribute("name", "android:windowBackground") styleItem.setAttribute("name", name)
windowItem.textContent = "@color/$splashBackgroundColor" styleItem.textContent = value
style.appendChild(windowItem) style.appendChild(styleItem)
resourcesNode.removeChild(node)
resourcesNode.appendChild(style)
}
} }
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
resourcesNode.appendChild(style)
} }
} }
} }
}, }
sharedExtensionPatch,
settingsPatch,
addResourcesPatch,
) )
compatibleWith( compatibleWith(

View File

@@ -1,6 +1,7 @@
package app.revanced.patches.youtube.misc.debugging package app.revanced.patches.youtube.misc.debugging
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.all.misc.resources.addResourcesPatch
@@ -11,9 +12,11 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch 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.findInstructionIndicesReversedOrThrow
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
private const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/EnableDebuggingPatch;" "Lapp/revanced/extension/youtube/patches/EnableDebuggingPatch;"
@@ -61,19 +64,17 @@ val enableDebuggingPatch = bytecodePatch(
experimentalBooleanFeatureFlagFingerprint.match( experimentalBooleanFeatureFlagFingerprint.match(
experimentalFeatureFlagParentFingerprint.originalClassDef experimentalFeatureFlagParentFingerprint.originalClassDef
).method.apply { ).method.apply {
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT) findInstructionIndicesReversedOrThrow(Opcode.RETURN).forEach { index ->
val register = getInstruction<OneRegisterInstruction>(index).registerA
// It appears that all usage of this method has a default of 'false', addInstructions(
// so there's no need to pass in the default. index,
addInstructions( """
insertIndex, invoke-static { v$register, p1 }, $EXTENSION_CLASS_DESCRIPTOR->isBooleanFeatureFlagEnabled(ZLjava/lang/Long;)Z
""" move-result v$register
move-result v0 """
invoke-static { v0, p1, p2 }, $EXTENSION_CLASS_DESCRIPTOR->isBooleanFeatureFlagEnabled(ZJ)Z )
move-result v0 }
return v0
"""
)
} }
experimentalDoubleFeatureFlagFingerprint.match( experimentalDoubleFeatureFlagFingerprint.match(
@@ -92,7 +93,6 @@ val enableDebuggingPatch = bytecodePatch(
) )
} }
experimentalLongFeatureFlagFingerprint.match( experimentalLongFeatureFlagFingerprint.match(
experimentalFeatureFlagParentFingerprint.originalClassDef experimentalFeatureFlagParentFingerprint.originalClassDef
).method.apply { ).method.apply {
@@ -108,21 +108,22 @@ val enableDebuggingPatch = bytecodePatch(
""" """
) )
experimentalStringFeatureFlagFingerprint.match( }
experimentalFeatureFlagParentFingerprint.originalClassDef
).method.apply {
val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.MOVE_RESULT_OBJECT)
addInstructions( experimentalStringFeatureFlagFingerprint.match(
insertIndex, experimentalFeatureFlagParentFingerprint.originalClassDef
""" ).method.apply {
move-result-object v0 val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.MOVE_RESULT_OBJECT)
invoke-static { v0, p1, p2, p3 }, $EXTENSION_CLASS_DESCRIPTOR->isStringFeatureFlagEnabled(Ljava/lang/String;JLjava/lang/String;)Ljava/lang/String;
move-result-object v0 addInstructions(
return-object v0 insertIndex,
""" """
) move-result-object v0
} invoke-static { v0, p1, p2, p3 }, $EXTENSION_CLASS_DESCRIPTOR->isStringFeatureFlagEnabled(Ljava/lang/String;JLjava/lang/String;)Ljava/lang/String;
move-result-object v0
return-object v0
"""
)
} }
// There exists other experimental accessor methods for byte[] // There exists other experimental accessor methods for byte[]

View File

@@ -11,9 +11,9 @@ internal val experimentalFeatureFlagParentFingerprint = fingerprint {
} }
internal val experimentalBooleanFeatureFlagFingerprint = fingerprint { internal val experimentalBooleanFeatureFlagFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("Z") returns("Z")
parameters("J", "Z") parameters("L", "J", "Z")
} }
internal val experimentalDoubleFeatureFlagFingerprint = fingerprint { internal val experimentalDoubleFeatureFlagFingerprint = fingerprint {
@@ -33,4 +33,3 @@ internal val experimentalStringFeatureFlagFingerprint = fingerprint {
returns("Ljava/lang/String;") returns("Ljava/lang/String;")
parameters("J", "Ljava/lang/String;") parameters("J", "Ljava/lang/String;")
} }

View File

@@ -12,7 +12,7 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
val openLinksExternallyPatch = bytecodePatch( val openLinksExternallyPatch = bytecodePatch(
name = "Open links externally", name = "Open links externally",
description = "Adds an option to always open links in your browser instead of in the in-app-browser.", description = "Adds an option to always open links in your browser instead of the in-app browser.",
) { ) {
dependsOn( dependsOn(
transformInstructionsPatch( transformInstructionsPatch(

View File

@@ -27,7 +27,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
lateinit var addLithoFilter: (String) -> Unit lateinit var addLithoFilter: (String) -> Unit
private set private set
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/components/LithoFilterPatch;" private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/components/LithoFilterPatch;"
val lithoFilterPatch = bytecodePatch( val lithoFilterPatch = bytecodePatch(
description = "Hooks the method which parses the bytes into a ComponentContext to filter components.", description = "Hooks the method which parses the bytes into a ComponentContext to filter components.",

View File

@@ -16,6 +16,23 @@ internal val actionBarSearchResultsFingerprint = fingerprint {
literal { actionBarSearchResultsViewMicId } literal { actionBarSearchResultsViewMicId }
} }
internal val toolbarLayoutFingerprint = fingerprint {
accessFlags(AccessFlags.PROTECTED, AccessFlags.CONSTRUCTOR)
literal { toolbarContainerId }
}
/**
* Matches to https://android.googlesource.com/platform/frameworks/support/+/9eee6ba/v7/appcompat/src/android/support/v7/widget/Toolbar.java#963
*/
internal val appCompatToolbarBackButtonFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Landroid/graphics/drawable/Drawable;")
parameters()
custom { methodDef, classDef ->
classDef.type == "Landroid/support/v7/widget/Toolbar;"
}
}
/** /**
* Matches to the class found in [pivotBarConstructorFingerprint]. * Matches to the class found in [pivotBarConstructorFingerprint].
*/ */

View File

@@ -8,6 +8,7 @@ import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
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
@@ -18,12 +19,16 @@ import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
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.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.Instruction import com.android.tools.smali.dexlib2.iface.instruction.Instruction
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.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.iface.reference.TypeReference
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.util.MethodUtil import com.android.tools.smali.dexlib2.util.MethodUtil
internal var imageOnlyTabResourceId = -1L internal var imageOnlyTabResourceId = -1L
@@ -32,6 +37,8 @@ internal var actionBarSearchResultsViewMicId = -1L
private set private set
internal var ytFillBellId = -1L internal var ytFillBellId = -1L
private set private set
internal var toolbarContainerId = -1L
private set
private val navigationBarHookResourcePatch = resourcePatch { private val navigationBarHookResourcePatch = resourcePatch {
dependsOn(resourceMappingPatch) dependsOn(resourceMappingPatch)
@@ -40,6 +47,7 @@ private val navigationBarHookResourcePatch = resourcePatch {
imageOnlyTabResourceId = resourceMappings["layout", "image_only_tab"] imageOnlyTabResourceId = resourceMappings["layout", "image_only_tab"]
actionBarSearchResultsViewMicId = resourceMappings["layout", "action_bar_search_results_view_mic"] actionBarSearchResultsViewMicId = resourceMappings["layout", "action_bar_search_results_view_mic"]
ytFillBellId = resourceMappings["drawable", "yt_fill_bell_black_24"] ytFillBellId = resourceMappings["drawable", "yt_fill_bell_black_24"]
toolbarContainerId = resourceMappings["id", "toolbar_container"]
} }
} }
@@ -47,6 +55,8 @@ internal const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/shared/NavigationBar;" "Lapp/revanced/extension/youtube/shared/NavigationBar;"
internal const val EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR = internal const val EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR =
"Lapp/revanced/extension/youtube/shared/NavigationBar\$NavigationButton;" "Lapp/revanced/extension/youtube/shared/NavigationBar\$NavigationButton;"
private const val EXTENSION_TOOLBAR_INTERFACE =
"Lapp/revanced/extension/youtube/shared/NavigationBar${'$'}AppCompatToolbarPatchInterface;"
lateinit var hookNavigationButtonCreated: (String) -> Unit lateinit var hookNavigationButtonCreated: (String) -> Unit
@@ -143,11 +153,58 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig
) )
} }
// Hook the back button visibility.
toolbarLayoutFingerprint.method.apply {
val index = indexOfFirstInstructionOrThrow {
opcode == Opcode.CHECK_CAST && getReference<TypeReference>()?.type ==
"Lcom/google/android/apps/youtube/app/ui/actionbar/MainCollapsingToolbarLayout;"
}
val register = getInstruction<OneRegisterInstruction>(index).registerA
addInstruction(
index + 1,
"invoke-static { v$register }, ${EXTENSION_CLASS_DESCRIPTOR}->setToolbar(Landroid/widget/FrameLayout;)V"
)
}
// Add interface for extensions code to call obfuscated methods.
appCompatToolbarBackButtonFingerprint.let {
it.classDef.apply {
interfaces.add(EXTENSION_TOOLBAR_INTERFACE)
val definingClass = type
val obfuscatedMethodName = it.originalMethod.name
val returnType = "Landroid/graphics/drawable/Drawable;"
methods.add(
ImmutableMethod(
definingClass,
"patch_getNavigationIcon",
listOf(),
returnType,
AccessFlags.PUBLIC.value or AccessFlags.FINAL.value,
null,
null,
MutableMethodImplementation(2),
).toMutable().apply {
addInstructions(
0,
"""
invoke-virtual { p0 }, $definingClass->$obfuscatedMethodName()$returnType
move-result-object v0
return-object v0
"""
)
}
)
}
}
hookNavigationButtonCreated = { extensionClassDescriptor -> hookNavigationButtonCreated = { extensionClassDescriptor ->
navigationBarHookCallbackFingerprint.method.addInstruction( navigationBarHookCallbackFingerprint.method.addInstruction(
0, 0,
"invoke-static { p0, p1 }, " + "invoke-static { p0, p1 }, $extensionClassDescriptor->navigationTabCreated" +
"$extensionClassDescriptor->navigationTabCreated" +
"(${EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V", "(${EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V",
) )
} }

View File

@@ -1,6 +1,7 @@
package app.revanced.patches.youtube.misc.playertype package app.revanced.patches.youtube.misc.playertype
import app.revanced.patcher.fingerprint import app.revanced.patcher.fingerprint
import app.revanced.util.literal
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
@@ -15,6 +16,12 @@ internal val playerTypeFingerprint = fingerprint {
custom { _, classDef -> classDef.endsWith("/YouTubePlayerOverlaysLayout;") } custom { _, classDef -> classDef.endsWith("/YouTubePlayerOverlaysLayout;") }
} }
internal val reelWatchPagerFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Landroid/view/View;")
literal { reelWatchPlayerId }
}
internal val videoStateFingerprint = fingerprint { internal val videoStateFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V") returns("V")

View File

@@ -4,15 +4,34 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
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.patcher.patch.resourcePatch
import app.revanced.patches.shared.misc.mapping.get
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.mapping.resourceMappings
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/PlayerTypeHookPatch;" private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/PlayerTypeHookPatch;"
internal var reelWatchPlayerId = -1L
private set
private val playerTypeHookResourcePatch = resourcePatch {
dependsOn(resourceMappingPatch)
execute {
reelWatchPlayerId = resourceMappings["id", "reel_watch_player"]
}
}
val playerTypeHookPatch = bytecodePatch( val playerTypeHookPatch = bytecodePatch(
description = "Hook to get the current player type and video playback state.", description = "Hook to get the current player type and video playback state.",
) { ) {
dependsOn(sharedExtensionPatch) dependsOn(sharedExtensionPatch, playerTypeHookResourcePatch)
execute { execute {
playerTypeFingerprint.method.addInstruction( playerTypeFingerprint.method.addInstruction(
@@ -20,6 +39,17 @@ val playerTypeHookPatch = bytecodePatch(
"invoke-static {p1}, $EXTENSION_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V", "invoke-static {p1}, $EXTENSION_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V",
) )
reelWatchPagerFingerprint.method.apply {
val literalIndex = indexOfFirstLiteralInstructionOrThrow(reelWatchPlayerId)
val registerIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT_OBJECT)
val viewRegister = getInstruction<OneRegisterInstruction>(registerIndex).registerA
addInstruction(
registerIndex + 1,
"invoke-static { v$viewRegister }, $EXTENSION_CLASS_DESCRIPTOR->onShortsCreate(Landroid/view/View;)V"
)
}
videoStateFingerprint.method.apply { videoStateFingerprint.method.apply {
val endIndex = videoStateFingerprint.patternMatch!!.endIndex val endIndex = videoStateFingerprint.patternMatch!!.endIndex
val videoStateFieldName = getInstruction<ReferenceInstruction>(endIndex).reference val videoStateFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
@@ -27,9 +57,9 @@ val playerTypeHookPatch = bytecodePatch(
addInstructions( addInstructions(
0, 0,
""" """
iget-object v0, p1, $videoStateFieldName # copy VideoState parameter field iget-object v0, p1, $videoStateFieldName # copy VideoState parameter field
invoke-static {v0}, $EXTENSION_CLASS_DESCRIPTOR->setVideoState(Ljava/lang/Enum;)V invoke-static {v0}, $EXTENSION_CLASS_DESCRIPTOR->setVideoState(Ljava/lang/Enum;)V
""", """
) )
} }
} }

View File

@@ -20,7 +20,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
val removeTrackingQueryParameterPatch = bytecodePatch( val removeTrackingQueryParameterPatch = bytecodePatch(
name = "Remove tracking query parameter", name = "Remove tracking query parameter",
description = "Adds an option to remove the tracking info from links you share.", description = "Adds an option to remove the tracking parameter from links you share.",
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,

View File

@@ -301,11 +301,9 @@ object PreferenceScreen : BasePreferenceScreen() {
summaryKey = null, summaryKey = null,
) )
// Don't sort, because title sorting scatters the custom color preferences.
val SEEKBAR = Screen( val SEEKBAR = Screen(
key = "revanced_settings_screen_07_seekbar", key = "revanced_settings_screen_07_seekbar",
summaryKey = null, summaryKey = null,
sorting = Sorting.UNSORTED,
) )
val SWIPE_CONTROLS = Screen( val SWIPE_CONTROLS = Screen(
key = "revanced_settings_screen_08_swipe_controls", key = "revanced_settings_screen_08_swipe_controls",
@@ -323,6 +321,7 @@ object PreferenceScreen : BasePreferenceScreen() {
val VIDEO = Screen( val VIDEO = Screen(
key = "revanced_settings_screen_12_video", key = "revanced_settings_screen_12_video",
summaryKey = null, summaryKey = null,
sorting = Sorting.BY_KEY,
) )
override fun commit(screen: PreferenceScreenPreference) { override fun commit(screen: PreferenceScreenPreference) {

View File

@@ -6,6 +6,8 @@ import app.revanced.patches.shared.misc.settings.preference.NonInteractivePrefer
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.spoof.spoofVideoStreamsPatch import app.revanced.patches.shared.misc.spoof.spoofVideoStreamsPatch
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
import app.revanced.patches.youtube.misc.playservice.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
@@ -25,7 +27,10 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
dependsOn( dependsOn(
userAgentClientSpoofPatch, userAgentClientSpoofPatch,
settingsPatch, settingsPatch,
versionCheckPatch
) )
}, {
is_19_34_or_greater
}, { }, {
addResources("youtube", "misc.fix.playback.spoofVideoStreamsPatch") addResources("youtube", "misc.fix.playback.spoofVideoStreamsPatch")

View File

@@ -0,0 +1,118 @@
package app.revanced.patches.youtube.video.quality
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.mapping.get
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.mapping.resourceMappings
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.addRecyclerViewTreeHook
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.recyclerViewTreeHookPatch
import app.revanced.patches.youtube.misc.settings.settingsPatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
internal var videoQualityBottomSheetListFragmentTitle = -1L
private set
internal var videoQualityQuickMenuAdvancedMenuDescription = -1L
private set
private val advancedVideoQualityMenuResourcePatch = resourcePatch {
dependsOn(resourceMappingPatch)
execute {
// Used for the old type of the video quality menu.
videoQualityBottomSheetListFragmentTitle = resourceMappings[
"layout",
"video_quality_bottom_sheet_list_fragment_title",
]
videoQualityQuickMenuAdvancedMenuDescription = resourceMappings[
"string",
"video_quality_quick_menu_advanced_menu_description",
]
}
}
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/playback/quality/AdvancedVideoQualityMenuPatch;"
private const val FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/components/AdvancedVideoQualityMenuFilter;"
internal val advancedVideoQualityMenuPatch = bytecodePatch {
dependsOn(
advancedVideoQualityMenuResourcePatch,
sharedExtensionPatch,
settingsPatch,
addResourcesPatch,
lithoFilterPatch,
recyclerViewTreeHookPatch,
)
execute {
addResources("youtube", "video.quality.advancedVideoQualityMenuPatch")
settingsMenuVideoQualityGroup.add(
SwitchPreference("revanced_advanced_video_quality_menu")
)
// region Patch for the old type of the video quality menu.
// Used for regular videos when spoofing to old app version,
// and for the Shorts quality flyout on newer app versions.
videoQualityMenuViewInflateFingerprint.let {
it.method.apply {
val checkCastIndex = it.patternMatch!!.endIndex
val listViewRegister = getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
addInstruction(
checkCastIndex + 1,
"invoke-static { v$listViewRegister }, $EXTENSION_CLASS_DESCRIPTOR->" +
"showAdvancedVideoQualityMenu(Landroid/widget/ListView;)V",
)
}
}
// Force YT to add the 'advanced' quality menu for Shorts.
videoQualityMenuOptionsFingerprint.let {
val patternMatch = it.patternMatch!!
val startIndex = patternMatch.startIndex
val insertIndex = patternMatch.endIndex
if (startIndex != 0) throw PatchException("Unexpected opcode start index: $startIndex")
it.method.apply {
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
// A condition controls whether to show the three or four items quality menu.
// Force the four items quality menu to make the "Advanced" item visible, necessary for the patch.
addInstructions(
insertIndex,
"""
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->forceAdvancedVideoQualityMenuCreation(Z)Z
move-result v$register
"""
)
}
}
// endregion
// region Patch for the new type of the video quality menu.
addRecyclerViewTreeHook(EXTENSION_CLASS_DESCRIPTOR)
// Required to check if the video quality menu is currently shown in order to click on the "Advanced" item.
addLithoFilter(FILTER_CLASS_DESCRIPTOR)
// endregion
}
}

View File

@@ -1,6 +1,7 @@
package app.revanced.patches.youtube.video.quality package app.revanced.patches.youtube.video.quality
import app.revanced.patcher.fingerprint import app.revanced.patcher.fingerprint
import app.revanced.util.literal
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
@@ -35,3 +36,41 @@ internal val videoQualitySetterFingerprint = fingerprint {
) )
strings("menu_item_video_quality") strings("menu_item_video_quality")
} }
internal val videoQualityMenuOptionsFingerprint = fingerprint {
accessFlags(AccessFlags.STATIC)
returns("[L")
parameters("Landroid/content/Context", "L", "L")
opcodes(
Opcode.CONST_4, // First instruction of method.
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.IGET_BOOLEAN, // Use the quality menu, that contains the advanced menu.
Opcode.IF_NEZ,
)
literal { videoQualityQuickMenuAdvancedMenuDescription }
}
internal val videoQualityMenuViewInflateFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("L")
parameters("L", "L", "L")
opcodes(
Opcode.INVOKE_SUPER,
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_16,
Opcode.INVOKE_VIRTUAL,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
)
literal { videoQualityBottomSheetListFragmentTitle }
}

View File

@@ -10,7 +10,7 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.ListPreference import app.revanced.patches.shared.misc.settings.preference.ListPreference
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.settings.PreferenceScreen import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.patches.youtube.shared.newVideoQualityChangedFingerprint import app.revanced.patches.youtube.shared.newVideoQualityChangedFingerprint
import app.revanced.patches.youtube.video.information.onCreateHook import app.revanced.patches.youtube.video.information.onCreateHook
@@ -22,47 +22,47 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
private const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/playback/quality/RememberVideoQualityPatch;" "Lapp/revanced/extension/youtube/patches/playback/quality/RememberVideoQualityPatch;"
val rememberVideoQualityPatch = bytecodePatch( val rememberVideoQualityPatch = bytecodePatch {
name = "Remember video quality",
description = "Adds an option to remember the last video quality selected.",
) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,
videoInformationPatch, videoInformationPatch,
playerTypeHookPatch,
settingsPatch, settingsPatch,
addResourcesPatch, addResourcesPatch,
) )
compatibleWith(
"com.google.android.youtube"(
"19.16.39",
"19.25.37",
"19.34.42",
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)
execute { execute {
addResources("youtube", "video.quality.rememberVideoQualityPatch") addResources("youtube", "video.quality.rememberVideoQualityPatch")
PreferenceScreen.VIDEO.addPreferences( settingsMenuVideoQualityGroup.addAll(listOf(
SwitchPreference("revanced_remember_video_quality_last_selected"),
ListPreference(
key = "revanced_video_quality_default_wifi",
summaryKey = null,
entriesKey = "revanced_video_quality_default_entries",
entryValuesKey = "revanced_video_quality_default_entry_values",
),
ListPreference( ListPreference(
key = "revanced_video_quality_default_mobile", key = "revanced_video_quality_default_mobile",
summaryKey = null, summaryKey = null,
entriesKey = "revanced_video_quality_default_entries", entriesKey = "revanced_video_quality_default_entries",
entryValuesKey = "revanced_video_quality_default_entry_values", entryValuesKey = "revanced_video_quality_default_entry_values",
), ),
) ListPreference(
key = "revanced_video_quality_default_wifi",
summaryKey = null,
entriesKey = "revanced_video_quality_default_entries",
entryValuesKey = "revanced_video_quality_default_entry_values",
),
SwitchPreference("revanced_remember_video_quality_last_selected"),
ListPreference(
key = "revanced_shorts_quality_default_mobile",
summaryKey = null,
entriesKey = "revanced_video_quality_default_entries",
entryValuesKey = "revanced_video_quality_default_entry_values",
),
ListPreference(
key = "revanced_shorts_quality_default_wifi",
summaryKey = null,
entriesKey = "revanced_video_quality_default_entries",
entryValuesKey = "revanced_video_quality_default_entry_values",
),
SwitchPreference("revanced_remember_shorts_quality_last_selected")
))
/* /*
* The following code works by hooking the method which is called when the user selects a video quality * The following code works by hooking the method which is called when the user selects a video quality

View File

@@ -0,0 +1,48 @@
package app.revanced.patches.youtube.video.quality
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.shared.misc.settings.preference.BasePreference
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
/**
* Video quality settings. Used to organize all speed related settings together.
*/
internal val settingsMenuVideoQualityGroup = mutableSetOf<BasePreference>()
@Suppress("unused")
val videoQualityPatch = bytecodePatch(
name = "Video quality",
description = "Adds options to use the advanced video quality menu and set default video qualities."
) {
dependsOn(
rememberVideoQualityPatch,
advancedVideoQualityMenuPatch,
)
compatibleWith(
"com.google.android.youtube"(
"19.16.39",
"19.25.37",
"19.34.42",
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
)
)
execute {
PreferenceScreen.VIDEO.addPreferences(
// Keep the preferences organized together.
PreferenceCategory(
key = "revanced_01_video_key", // Dummy key to force the quality preferences first.
titleKey = null,
sorting = Sorting.UNSORTED,
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
preferences = settingsMenuVideoQualityGroup
)
)
}
}

View File

@@ -1,20 +1,29 @@
package app.revanced.patches.youtube.video.speed package app.revanced.patches.youtube.video.speed
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.shared.misc.settings.preference.BasePreference
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.video.speed.button.playbackSpeedButtonPatch import app.revanced.patches.youtube.video.speed.button.playbackSpeedButtonPatch
import app.revanced.patches.youtube.video.speed.custom.customPlaybackSpeedPatch import app.revanced.patches.youtube.video.speed.custom.customPlaybackSpeedPatch
import app.revanced.patches.youtube.video.speed.remember.rememberPlaybackSpeedPatch import app.revanced.patches.youtube.video.speed.remember.rememberPlaybackSpeedPatch
/**
* Speed menu settings. Used to organize all speed related settings together.
*/
internal val settingsMenuVideoSpeedGroup = mutableSetOf<BasePreference>()
@Suppress("unused") @Suppress("unused")
val playbackSpeedPatch = bytecodePatch( val playbackSpeedPatch = bytecodePatch(
name = "Playback speed", name = "Playback speed",
description = "Adds options to customize available playback speeds, remember the last playback speed selected " + description = "Adds options to customize available playback speeds, set default a playback speed, " +
"and show a speed dialog button in the video player.", "and show a speed dialog button in the video player.",
) { ) {
dependsOn( dependsOn(
playbackSpeedButtonPatch,
customPlaybackSpeedPatch, customPlaybackSpeedPatch,
rememberPlaybackSpeedPatch, rememberPlaybackSpeedPatch,
playbackSpeedButtonPatch,
) )
compatibleWith( compatibleWith(
@@ -26,6 +35,18 @@ val playbackSpeedPatch = bytecodePatch(
"19.45.38", "19.45.38",
"19.46.42", "19.46.42",
"19.47.53", "19.47.53",
), )
) )
execute {
PreferenceScreen.VIDEO.addPreferences(
PreferenceCategory(
key = "revanced_zz_video_key", // Dummy key to force the speed settings last.
titleKey = null,
sorting = Sorting.UNSORTED,
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
preferences = settingsMenuVideoSpeedGroup
)
)
}
} }

View File

@@ -5,6 +5,7 @@ import app.revanced.patcher.patch.resourcePatch
import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.all.misc.resources.addResourcesPatch
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.playercontrols.* import app.revanced.patches.youtube.misc.playercontrols.*
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
@@ -35,11 +36,12 @@ val playbackSpeedButtonPatch = bytecodePatch(
description = "Adds the option to display playback speed dialog button in the video player.", description = "Adds the option to display playback speed dialog button in the video player.",
) { ) {
dependsOn( dependsOn(
playbackSpeedButtonResourcePatch, sharedExtensionPatch,
customPlaybackSpeedPatch,
playerControlsPatch,
settingsPatch, settingsPatch,
addResourcesPatch, addResourcesPatch,
customPlaybackSpeedPatch,
playbackSpeedButtonResourcePatch,
playerControlsPatch,
) )
execute { execute {

View File

@@ -25,8 +25,8 @@ import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.addRecyclerViewTreeHook import app.revanced.patches.youtube.misc.recyclerviewtree.hook.addRecyclerViewTreeHook
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.recyclerViewTreeHookPatch import app.revanced.patches.youtube.misc.recyclerviewtree.hook.recyclerViewTreeHookPatch
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.speed.settingsMenuVideoSpeedGroup
import app.revanced.util.* import app.revanced.util.*
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
@@ -60,24 +60,29 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,
lithoFilterPatch,
settingsPatch, settingsPatch,
recyclerViewTreeHookPatch,
customPlaybackSpeedResourcePatch,
addResourcesPatch, addResourcesPatch,
versionCheckPatch lithoFilterPatch,
versionCheckPatch,
recyclerViewTreeHookPatch,
customPlaybackSpeedResourcePatch
) )
execute { execute {
addResources("youtube", "video.speed.custom.customPlaybackSpeedPatch") addResources("youtube", "video.speed.custom.customPlaybackSpeedPatch")
PreferenceScreen.VIDEO.addPreferences( settingsMenuVideoSpeedGroup.addAll(
SwitchPreference("revanced_custom_speed_menu"), listOf(
TextPreference("revanced_custom_playback_speeds", inputType = InputType.TEXT_MULTI_LINE), SwitchPreference("revanced_custom_speed_menu"),
TextPreference(
"revanced_custom_playback_speeds",
inputType = InputType.TEXT_MULTI_LINE
),
)
) )
if (is_19_25_or_greater) { if (is_19_25_or_greater) {
PreferenceScreen.VIDEO.addPreferences( settingsMenuVideoSpeedGroup.add(
TextPreference("revanced_speed_tap_and_hold", inputType = InputType.NUMBER_DECIMAL), TextPreference("revanced_speed_tap_and_hold", inputType = InputType.NUMBER_DECIMAL),
) )
} }

View File

@@ -9,10 +9,10 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.ListPreference import app.revanced.patches.shared.misc.settings.preference.ListPreference
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.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.* import app.revanced.patches.youtube.video.information.*
import app.revanced.patches.youtube.video.speed.custom.customPlaybackSpeedPatch import app.revanced.patches.youtube.video.speed.custom.customPlaybackSpeedPatch
import app.revanced.patches.youtube.video.speed.settingsMenuVideoSpeedGroup
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
private const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
@@ -22,26 +22,29 @@ internal val rememberPlaybackSpeedPatch = bytecodePatch {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,
settingsPatch, settingsPatch,
videoInformationPatch,
customPlaybackSpeedPatch,
addResourcesPatch, addResourcesPatch,
videoInformationPatch,
customPlaybackSpeedPatch
) )
execute { execute {
addResources("youtube", "video.speed.remember.rememberPlaybackSpeedPatch") addResources("youtube", "video.speed.remember.rememberPlaybackSpeedPatch")
PreferenceScreen.VIDEO.addPreferences( settingsMenuVideoSpeedGroup.addAll(
SwitchPreference("revanced_remember_playback_speed_last_selected"), listOf(
ListPreference( ListPreference(
key = "revanced_playback_speed_default", key = "revanced_playback_speed_default",
summaryKey = null, summaryKey = null,
// Entries and values are set by the extension code based on the actual speeds available. // Entries and values are set by the extension code based on the actual speeds available.
entriesKey = null, entriesKey = null,
entryValuesKey = null, entryValuesKey = null,
), ),
SwitchPreference("revanced_remember_playback_speed_last_selected")
)
) )
onCreateHook(EXTENSION_CLASS_DESCRIPTOR, "newVideoStarted") onCreateHook(EXTENSION_CLASS_DESCRIPTOR, "newVideoStarted")
userSelectedPlaybackSpeedHook( userSelectedPlaybackSpeedHook(
EXTENSION_CLASS_DESCRIPTOR, EXTENSION_CLASS_DESCRIPTOR,
"userSelectedPlaybackSpeed", "userSelectedPlaybackSpeed",

View File

@@ -1,43 +0,0 @@
package app.revanced.patches.youtube.video.videoqualitymenu
import app.revanced.patcher.fingerprint
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val videoQualityMenuOptionsFingerprint = fingerprint {
accessFlags(AccessFlags.STATIC)
returns("[L")
parameters("Landroid/content/Context", "L", "L")
opcodes(
Opcode.CONST_4, // First instruction of method.
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.IGET_BOOLEAN, // Use the quality menu, that contains the advanced menu.
Opcode.IF_NEZ,
)
literal { videoQualityQuickMenuAdvancedMenuDescription }
}
internal val videoQualityMenuViewInflateFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("L")
parameters("L", "L", "L")
opcodes(
Opcode.INVOKE_SUPER,
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_16,
Opcode.INVOKE_VIRTUAL,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
)
literal { videoQualityBottomSheetListFragmentTitle }
}

View File

@@ -1,135 +1,10 @@
package app.revanced.patches.youtube.video.videoqualitymenu package app.revanced.patches.youtube.video.videoqualitymenu
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.resourcePatch import app.revanced.patches.youtube.video.quality.videoQualityPatch
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.mapping.get
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.mapping.resourceMappings
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.addRecyclerViewTreeHook
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.recyclerViewTreeHookPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
internal var videoQualityBottomSheetListFragmentTitle = -1L
private set
internal var videoQualityQuickMenuAdvancedMenuDescription = -1L
private set
private val restoreOldVideoQualityMenuResourcePatch = resourcePatch {
dependsOn(
settingsPatch,
resourceMappingPatch,
addResourcesPatch,
)
execute {
addResources("youtube", "video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch")
PreferenceScreen.VIDEO.addPreferences(
SwitchPreference("revanced_restore_old_video_quality_menu"),
)
// Used for the old type of the video quality menu.
videoQualityBottomSheetListFragmentTitle = resourceMappings[
"layout",
"video_quality_bottom_sheet_list_fragment_title",
]
videoQualityQuickMenuAdvancedMenuDescription = resourceMappings[
"string",
"video_quality_quick_menu_advanced_menu_description",
]
}
}
private const val FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/components/VideoQualityMenuFilterPatch;"
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch;"
@Suppress("unused") @Suppress("unused")
val restoreOldVideoQualityMenuPatch = bytecodePatch( @Deprecated("Use 'Video Quality' instead.")
name = "Restore old video quality menu", val restoreOldVideoQualityMenuPatch = bytecodePatch {
description = "Adds an option to restore the old video quality menu with specific video resolution options.", dependsOn(videoQualityPatch)
}
) {
dependsOn(
sharedExtensionPatch,
restoreOldVideoQualityMenuResourcePatch,
lithoFilterPatch,
recyclerViewTreeHookPatch,
)
compatibleWith(
"com.google.android.youtube"(
"19.16.39",
"19.25.37",
"19.34.42",
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)
execute {
// region Patch for the old type of the video quality menu.
// Used for regular videos when spoofing to old app version,
// and for the Shorts quality flyout on newer app versions.
videoQualityMenuViewInflateFingerprint.method.apply {
val checkCastIndex = videoQualityMenuViewInflateFingerprint.patternMatch!!.endIndex
val listViewRegister = getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
addInstruction(
checkCastIndex + 1,
"invoke-static { v$listViewRegister }, " +
"$EXTENSION_CLASS_DESCRIPTOR->" +
"showOldVideoQualityMenu(Landroid/widget/ListView;)V",
)
}
// Force YT to add the 'advanced' quality menu for Shorts.
val patternMatch = videoQualityMenuOptionsFingerprint.patternMatch!!
val startIndex = patternMatch.startIndex
if (startIndex != 0) throw PatchException("Unexpected opcode start index: $startIndex")
val insertIndex = patternMatch.endIndex
videoQualityMenuOptionsFingerprint.method.apply {
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
// A condition controls whether to show the three or four items quality menu.
// Force the four items quality menu to make the "Advanced" item visible, necessary for the patch.
addInstructions(
insertIndex,
"""
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->forceAdvancedVideoQualityMenuCreation(Z)Z
move-result v$register
""",
)
}
// endregion
// region Patch for the new type of the video quality menu.
addRecyclerViewTreeHook(EXTENSION_CLASS_DESCRIPTOR)
// Required to check if the video quality menu is currently shown in order to click on the "Advanced" item.
addLithoFilter(FILTER_CLASS_DESCRIPTOR)
// endregion
}
}

View File

@@ -178,8 +178,7 @@ fun Method.indexOfFirstLiteralInstructionReversedOrThrow(literal: Long): Int {
* *
* @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) = fun Method.containsLiteralInstruction(literal: Long) = indexOfFirstLiteralInstruction(literal) >= 0
indexOfFirstLiteralInstruction(literal) >= 0
/** /**
* Traverse the class hierarchy starting from the given root class. * Traverse the class hierarchy starting from the given root class.
@@ -205,25 +204,22 @@ fun BytecodePatchContext.traverseClassHierarchy(targetClass: MutableClass, callb
* if the [Instruction] is not a [ReferenceInstruction] or the [Reference] is not of type [T]. * if the [Instruction] is not a [ReferenceInstruction] or the [Reference] is not of type [T].
* @see ReferenceInstruction * @see ReferenceInstruction
*/ */
inline fun <reified T : Reference> Instruction.getReference() = inline fun <reified T : Reference> Instruction.getReference() = (this as? ReferenceInstruction)?.reference as? T
(this as? ReferenceInstruction)?.reference as? T
/** /**
* @return The index of the first opcode specified, or -1 if not found. * @return The index of the first opcode specified, or -1 if not found.
* @see indexOfFirstInstructionOrThrow * @see indexOfFirstInstructionOrThrow
*/ */
fun Method.indexOfFirstInstruction(targetOpcode: Opcode): Int = fun Method.indexOfFirstInstruction(targetOpcode: Opcode): Int = indexOfFirstInstruction(0, targetOpcode)
indexOfFirstInstruction(0, targetOpcode)
/** /**
* @param startIndex Optional starting index to start searching from. * @param startIndex Optional starting index to start searching from.
* @return The index of the first opcode specified, or -1 if not found. * @return The index of the first opcode specified, or -1 if not found.
* @see indexOfFirstInstructionOrThrow * @see indexOfFirstInstructionOrThrow
*/ */
fun Method.indexOfFirstInstruction(startIndex: Int = 0, targetOpcode: Opcode): Int = fun Method.indexOfFirstInstruction(startIndex: Int = 0, targetOpcode: Opcode): Int = indexOfFirstInstruction(startIndex) {
indexOfFirstInstruction(startIndex) { opcode == targetOpcode
opcode == targetOpcode }
}
/** /**
* Get the index of the first [Instruction] that matches the predicate, starting from [startIndex]. * Get the index of the first [Instruction] that matches the predicate, starting from [startIndex].
@@ -251,23 +247,21 @@ fun Method.indexOfFirstInstruction(startIndex: Int = 0, filter: Instruction.() -
* @throws PatchException * @throws PatchException
* @see indexOfFirstInstruction * @see indexOfFirstInstruction
*/ */
fun Method.indexOfFirstInstructionOrThrow(targetOpcode: Opcode): Int = fun Method.indexOfFirstInstructionOrThrow(targetOpcode: Opcode): Int = indexOfFirstInstructionOrThrow(0, targetOpcode)
indexOfFirstInstructionOrThrow(0, targetOpcode)
/** /**
* @return The index of the first opcode specified, starting from the index specified. * @return The index of the first opcode specified, starting from the index specified.
* @throws PatchException * @throws PatchException
* @see indexOfFirstInstruction * @see indexOfFirstInstruction
*/ */
fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, targetOpcode: Opcode): Int = fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, targetOpcode: Opcode): Int = indexOfFirstInstructionOrThrow(startIndex) {
indexOfFirstInstructionOrThrow(startIndex) { opcode == targetOpcode
opcode == targetOpcode }
}
/** /**
* Get the index of the first [Instruction] that matches the predicate, starting from [startIndex]. * Get the index of the first [Instruction] that matches the predicate, starting from [startIndex].
* *
* @return the index of the instruction * @return The index of the instruction.
* @throws PatchException * @throws PatchException
* @see indexOfFirstInstruction * @see indexOfFirstInstruction
*/ */
@@ -288,10 +282,9 @@ fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, filter: Instructi
* @return -1 if the instruction is not found. * @return -1 if the instruction is not found.
* @see indexOfFirstInstructionReversedOrThrow * @see indexOfFirstInstructionReversedOrThrow
*/ */
fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, targetOpcode: Opcode): Int = fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, targetOpcode: Opcode): Int = indexOfFirstInstructionReversed(startIndex) {
indexOfFirstInstructionReversed(startIndex) { opcode == targetOpcode
opcode == targetOpcode }
}
/** /**
* Get the index of matching instruction, * Get the index of matching instruction,
@@ -316,23 +309,21 @@ fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, filter: Inst
* *
* @return -1 if the instruction is not found. * @return -1 if the instruction is not found.
*/ */
fun Method.indexOfFirstInstructionReversed(targetOpcode: Opcode): Int = fun Method.indexOfFirstInstructionReversed(targetOpcode: Opcode): Int = indexOfFirstInstructionReversed {
indexOfFirstInstructionReversed { opcode == targetOpcode
opcode == targetOpcode }
}
/** /**
* Get the index of matching instruction, * Get the index of matching instruction,
* starting from and [startIndex] and searching down. * starting from and [startIndex] and searching down.
* *
* @param startIndex Optional starting index to search down from. Searching includes the start index. * @param startIndex Optional starting index to search down from. Searching includes the start index.
* @return -1 if the instruction is not found. * @return The index of the instruction.
* @see indexOfFirstInstructionReversed * @see indexOfFirstInstructionReversed
*/ */
fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, targetOpcode: Opcode): Int = fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, targetOpcode: Opcode): Int = indexOfFirstInstructionReversedOrThrow(startIndex) {
indexOfFirstInstructionReversedOrThrow(startIndex) { opcode == targetOpcode
opcode == targetOpcode }
}
/** /**
* Get the index of matching instruction, * Get the index of matching instruction,
@@ -340,16 +331,16 @@ fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, targe
* *
* @return -1 if the instruction is not found. * @return -1 if the instruction is not found.
*/ */
fun Method.indexOfFirstInstructionReversedOrThrow(targetOpcode: Opcode): Int = fun Method.indexOfFirstInstructionReversedOrThrow(targetOpcode: Opcode): Int = indexOfFirstInstructionReversedOrThrow {
indexOfFirstInstructionReversedOrThrow { opcode == targetOpcode
opcode == targetOpcode }
}
/** /**
* Get the index of matching instruction, * Get the index of matching instruction,
* starting from and [startIndex] and searching down. * starting from and [startIndex] and searching down.
* *
* @param startIndex Optional starting index to search down from. Searching includes the start index. * @param startIndex Optional starting index to search down from. Searching includes the start index.
* @return -1 if the instruction is not found. * @return The index of the instruction.
* @see indexOfFirstInstructionReversed * @see indexOfFirstInstructionReversed
*/ */
fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, filter: Instruction.() -> Boolean): Int { fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, filter: Instruction.() -> Boolean): Int {
@@ -389,8 +380,7 @@ fun Method.findInstructionIndicesReversedOrThrow(filter: Instruction.() -> Boole
* _Returns an empty list if no indices are found_ * _Returns an empty list if no indices are found_
* @see findInstructionIndicesReversedOrThrow * @see findInstructionIndicesReversedOrThrow
*/ */
fun Method.findInstructionIndicesReversed(opcode: Opcode): List<Int> = fun Method.findInstructionIndicesReversed(opcode: Opcode): List<Int> = findInstructionIndicesReversed { this.opcode == opcode }
findInstructionIndicesReversed { this.opcode == opcode }
/** /**
* @return An immutable list of indices of the opcode in reverse order. * @return An immutable list of indices of the opcode in reverse order.
@@ -408,12 +398,18 @@ internal fun MutableMethod.insertFeatureFlagBooleanOverride(literal: Long, exten
val index = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT) val index = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
val register = getInstruction<OneRegisterInstruction>(index).registerA val register = getInstruction<OneRegisterInstruction>(index).registerA
val operation = if (register < 16) {
"invoke-static { v$register }"
} else {
"invoke-static/range { v$register .. v$register }"
}
addInstructions( addInstructions(
index + 1, index + 1,
""" """
invoke-static { v$register }, $extensionsMethod $operation, $extensionsMethod
move-result v$register move-result v$register
""" """,
) )
} }
@@ -458,7 +454,7 @@ fun MutableMethod.returnEarly(bool: Boolean = false) {
return v0 return v0
""" """
else -> throw Exception("This case should never happen.") else -> throw Exception("Return type is not supported: $this")
} }
addInstructions(0, stringInstructions) addInstructions(0, stringInstructions)

View File

@@ -156,6 +156,7 @@ Second \"item\" text"</string>
<patch id="layout.sponsorblock.sponsorBlockResourcePatch"> <patch id="layout.sponsorblock.sponsorBlockResourcePatch">
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' --> <!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. --> <!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<!-- Shown in the settings preferences, and translations can be any text length. --> <!-- Shown in the settings preferences, and translations can be any text length. -->
</patch> </patch>
<patch id="layout.formfactor.changeFormFactorPatch"> <patch id="layout.formfactor.changeFormFactorPatch">
@@ -163,7 +164,6 @@ Second \"item\" text"</string>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<!-- It is ideal, but not required, if the text here appears is alphabetically after the text used for 'revanced_spoof_app_version_title'. <!-- It is ideal, but not required, if the text here appears is alphabetically after the text used for 'revanced_spoof_app_version_title'.
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<!-- 'RYD' is 'Return YouTube Dislike' -->
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
</patch> </patch>
@@ -177,8 +177,6 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="layout.theme.themePatch"> <patch id="layout.theme.themePatch">
</patch> </patch>
<patch id="layout.theme.themeResourcePatch">
</patch>
<patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch"> <patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch">
</patch> </patch>
<patch id="layout.thumbnails.alternativeThumbnailsPatch"> <patch id="layout.thumbnails.alternativeThumbnailsPatch">
@@ -219,7 +217,7 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="video.hdr.disableHdrPatch"> <patch id="video.hdr.disableHdrPatch">
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
</patch> </patch>

View File

@@ -156,6 +156,7 @@ Second \"item\" text"</string>
<patch id="layout.sponsorblock.sponsorBlockResourcePatch"> <patch id="layout.sponsorblock.sponsorBlockResourcePatch">
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' --> <!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. --> <!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<!-- Shown in the settings preferences, and translations can be any text length. --> <!-- Shown in the settings preferences, and translations can be any text length. -->
</patch> </patch>
<patch id="layout.formfactor.changeFormFactorPatch"> <patch id="layout.formfactor.changeFormFactorPatch">
@@ -163,7 +164,6 @@ Second \"item\" text"</string>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<!-- It is ideal, but not required, if the text here appears is alphabetically after the text used for 'revanced_spoof_app_version_title'. <!-- It is ideal, but not required, if the text here appears is alphabetically after the text used for 'revanced_spoof_app_version_title'.
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<!-- 'RYD' is 'Return YouTube Dislike' -->
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
</patch> </patch>
@@ -177,8 +177,6 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="layout.theme.themePatch"> <patch id="layout.theme.themePatch">
</patch> </patch>
<patch id="layout.theme.themeResourcePatch">
</patch>
<patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch"> <patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch">
</patch> </patch>
<patch id="layout.thumbnails.alternativeThumbnailsPatch"> <patch id="layout.thumbnails.alternativeThumbnailsPatch">
@@ -219,7 +217,7 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="video.hdr.disableHdrPatch"> <patch id="video.hdr.disableHdrPatch">
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
</patch> </patch>

View File

@@ -48,57 +48,6 @@ Second \"item\" text"</string>
لترجمة لغات جديدة، تفضل بزيارة translate.revanced.app"</string> لترجمة لغات جديدة، تفضل بزيارة translate.revanced.app"</string>
<string name="revanced_language_DEFAULT">لغة التطبيق</string> <string name="revanced_language_DEFAULT">لغة التطبيق</string>
<string name="revanced_language_AR">العربية</string>
<string name="revanced_language_AZ">Azerbaijani</string>
<string name="revanced_language_BG">Bulgarian</string>
<string name="revanced_language_BN">Bengali</string>
<string name="revanced_language_CA">Catalan</string>
<string name="revanced_language_CS">Czech</string>
<string name="revanced_language_DA">Danish</string>
<string name="revanced_language_DE">German</string>
<string name="revanced_language_EL">Greek</string>
<string name="revanced_language_EN">English</string>
<string name="revanced_language_ES">Spanish</string>
<string name="revanced_language_ET">Estonian</string>
<string name="revanced_language_FA">فارسى</string>
<string name="revanced_language_FI">Finnish</string>
<string name="revanced_language_FR">French - Français</string>
<string name="revanced_language_GU">Gujarati</string>
<string name="revanced_language_HI">Hindi</string>
<string name="revanced_language_HR">Croatian</string>
<string name="revanced_language_HU">Hungarian</string>
<string name="revanced_language_ID">Indonesian</string>
<string name="revanced_language_IT">Italian</string>
<string name="revanced_language_JA">Japanese</string>
<string name="revanced_language_KK">Kazakh</string>
<string name="revanced_language_KO">Korean</string>
<string name="revanced_language_LT">Lithuanian</string>
<string name="revanced_language_LV">Latvian</string>
<string name="revanced_language_MK">Macedonian</string>
<string name="revanced_language_MN">Mongolian</string>
<string name="revanced_language_MR">Marathi</string>
<string name="revanced_language_MS">Malay</string>
<string name="revanced_language_MY">Burmese</string>
<string name="revanced_language_NL">Dutch</string>
<string name="revanced_language_OR">Odia</string>
<string name="revanced_language_PA">Punjabi</string>
<string name="revanced_language_PL">Polish</string>
<string name="revanced_language_PT">Portugese</string>
<string name="revanced_language_RO">Romanian</string>
<string name="revanced_language_RU">Russian - Русский</string>
<string name="revanced_language_SK">Slovak</string>
<string name="revanced_language_SL">Slovene</string>
<string name="revanced_language_SR">Serbian</string>
<string name="revanced_language_SV">Swedish</string>
<string name="revanced_language_SW">Swahili</string>
<string name="revanced_language_TA">Tamil</string>
<string name="revanced_language_TE">Telugu</string>
<string name="revanced_language_TH">Thai</string>
<string name="revanced_language_TR">Turkish</string>
<string name="revanced_language_UK">Ukrainian</string>
<string name="revanced_language_UR">Urdu</string>
<string name="revanced_language_VI">Vietnamese</string>
<string name="revanced_language_ZH">Chinese</string>
<string name="revanced_pref_import_export_title">استيراد / تصدير</string> <string name="revanced_pref_import_export_title">استيراد / تصدير</string>
<string name="revanced_pref_import_export_summary">استيراد / تصدير إعدادات ReVanced</string> <string name="revanced_pref_import_export_summary">استيراد / تصدير إعدادات ReVanced</string>
<!-- Settings about dialog. --> <!-- Settings about dialog. -->
@@ -301,13 +250,13 @@ Second \"item\" text"</string>
<string name="revanced_hide_description_components_screen_title">وصف الفيديو</string> <string name="revanced_hide_description_components_screen_title">وصف الفيديو</string>
<string name="revanced_hide_description_components_screen_summary">إخفاء أو عرض مكونات وصف الفيديو</string> <string name="revanced_hide_description_components_screen_summary">إخفاء أو عرض مكونات وصف الفيديو</string>
<string name="revanced_hide_filter_bar_screen_title">شريط التصفية</string> <string name="revanced_hide_filter_bar_screen_title">شريط التصفية</string>
<string name="revanced_hide_filter_bar_screen_summary">إخفاء شريط التصفية أو عرضه في الموجز والبحث الفيديوهات ذات الصلة</string> <string name="revanced_hide_filter_bar_screen_summary">إخفاء أو إظهار شريط الفلتر في الخلاصة ونتائج البحث ومقاطع الفيديو ذات الصلة</string>
<string name="revanced_hide_filter_bar_feed_in_feed_title">إخفاء في الموجز</string> <string name="revanced_hide_filter_bar_feed_in_feed_title">إخفاء في الموجز</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_on">مخفي في الموجز</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_on">مخفي في الموجز</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_off">يعرض في الموجز</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_off">يعرض في الموجز</string>
<string name="revanced_hide_filter_bar_feed_in_search_title">إخفاء في البحث</string> <string name="revanced_hide_filter_bar_feed_in_search_title">إخفاء في نتائج البحث</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_on">مخفي في البحث</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_on">مخفي في نتائج البحث</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_off">يعرض في البحث</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_off">يظهر في نتائج البحث</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">إخفاء في الفيديوهات ذات الصلة</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_title">إخفاء في الفيديوهات ذات الصلة</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">مخفي في الفيديوهات ذات الصلة</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">مخفي في الفيديوهات ذات الصلة</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">يعرض في الفيديوهات ذات الصلة</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">يعرض في الفيديوهات ذات الصلة</string>
@@ -404,7 +353,7 @@ Second \"item\" text"</string>
<string name="revanced_hide_self_sponsor_ads_title">إخفاء بطاقات الرعاية الذاتية</string> <string name="revanced_hide_self_sponsor_ads_title">إخفاء بطاقات الرعاية الذاتية</string>
<string name="revanced_hide_self_sponsor_ads_summary_on">تم إخفاء بطاقات الرعاية الذاتية</string> <string name="revanced_hide_self_sponsor_ads_summary_on">تم إخفاء بطاقات الرعاية الذاتية</string>
<string name="revanced_hide_self_sponsor_ads_summary_off">يتم عرض بطاقات الرعاية الذاتية</string> <string name="revanced_hide_self_sponsor_ads_summary_off">يتم عرض بطاقات الرعاية الذاتية</string>
<string name="revanced_hide_products_banner_title">إخفاء لافتة لعرض المنتجات</string> <string name="revanced_hide_products_banner_title">إخفاء لافتة \"عرض المنتجات\"</string>
<string name="revanced_hide_products_banner_summary_on">تم إخفاء البانر</string> <string name="revanced_hide_products_banner_summary_on">تم إخفاء البانر</string>
<string name="revanced_hide_products_banner_summary_off">يتم عرض البانر</string> <string name="revanced_hide_products_banner_summary_off">يتم عرض البانر</string>
<string name="revanced_hide_end_screen_store_banner_title">إخفاء لافتة شاشة المتجر النهائية</string> <string name="revanced_hide_end_screen_store_banner_title">إخفاء لافتة شاشة المتجر النهائية</string>
@@ -663,7 +612,7 @@ Second \"item\" text"</string>
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">يتم عرض تذييل قائمة جودة الفيديو</string> <string name="revanced_hide_player_flyout_video_quality_footer_summary_off">يتم عرض تذييل قائمة جودة الفيديو</string>
</patch> </patch>
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch"> <patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
<string name="revanced_hide_player_previous_next_buttons_title">إخفاء أزرار الفيديو السابق &amp; التالي</string> <string name="revanced_hide_player_previous_next_buttons_title">إخفاء زري \"السابق\" و \"التالي\"</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">تم إخفاء الأزرار</string> <string name="revanced_hide_player_previous_next_buttons_summary_on">تم إخفاء الأزرار</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">يتم عرض الأزرار</string> <string name="revanced_hide_player_previous_next_buttons_summary_off">يتم عرض الأزرار</string>
<string name="revanced_hide_cast_button_title">إخفاء زر البث</string> <string name="revanced_hide_cast_button_title">إخفاء زر البث</string>
@@ -856,7 +805,6 @@ Second \"item\" text"</string>
<string name="revanced_ryd_enable_summary_on">يتم عرض لم يعجبني</string> <string name="revanced_ryd_enable_summary_on">يتم عرض لم يعجبني</string>
<string name="revanced_ryd_enable_summary_off">لا يتم عرض لم يعجبني</string> <string name="revanced_ryd_enable_summary_off">لا يتم عرض لم يعجبني</string>
<string name="revanced_ryd_shorts_title">عرض لم يعجني في فيديوهات Shorts</string> <string name="revanced_ryd_shorts_title">عرض لم يعجني في فيديوهات Shorts</string>
<string name="revanced_ryd_shorts_summary_on">يتم عرض عدم الإعجاب على فيديوهات Shorts</string>
<string name="revanced_ryd_shorts_summary_on_disclaimer">"يتم عرض مرات عدم الإعجاب في فيديوهات Shorts <string name="revanced_ryd_shorts_summary_on_disclaimer">"يتم عرض مرات عدم الإعجاب في فيديوهات Shorts
التقييد: قد لا تظهر مرات عدم الإعجاب في وضع التصفح المتخفي"</string> التقييد: قد لا تظهر مرات عدم الإعجاب في وضع التصفح المتخفي"</string>
@@ -1054,6 +1002,8 @@ Second \"item\" text"</string>
<string name="revanced_sb_vote_downvote">اعتراض</string> <string name="revanced_sb_vote_downvote">اعتراض</string>
<string name="revanced_sb_vote_category">تغيير الفئة</string> <string name="revanced_sb_vote_category">تغيير الفئة</string>
<string name="revanced_sb_vote_no_segments">لا توجد مقاطع للتصويت عليها</string> <string name="revanced_sb_vote_no_segments">لا توجد مقاطع للتصويت عليها</string>
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<string name="revanced_sb_vote_segment_time_to_from">%1$s إلى %2$s</string>
<string name="revanced_sb_new_segment_choose_category">اختيار فئة المقطع</string> <string name="revanced_sb_new_segment_choose_category">اختيار فئة المقطع</string>
<string name="revanced_sb_new_segment_disabled_category">الفئة معطلة في الإعدادات. تمكين الفئة للإرسال.</string> <string name="revanced_sb_new_segment_disabled_category">الفئة معطلة في الإعدادات. تمكين الفئة للإرسال.</string>
<string name="revanced_sb_new_segment_title">مقطع SponsorBlock جديد</string> <string name="revanced_sb_new_segment_title">مقطع SponsorBlock جديد</string>
@@ -1101,6 +1051,7 @@ Second \"item\" text"</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_dot_label">اللون:</string> <string name="revanced_sb_color_dot_label">اللون:</string>
<string name="revanced_sb_color_changed">تم تغيير اللون</string> <string name="revanced_sb_color_changed">تم تغيير اللون</string>
<string name="revanced_sb_color_reset">إعادة ضبط اللون</string> <string name="revanced_sb_color_reset">إعادة ضبط اللون</string>
@@ -1116,16 +1067,14 @@ Second \"item\" text"</string>
<string name="revanced_change_form_factor_entry_2">الجوّال</string> <string name="revanced_change_form_factor_entry_2">الجوّال</string>
<string name="revanced_change_form_factor_entry_3">الجهاز اللوحي</string> <string name="revanced_change_form_factor_entry_3">الجهاز اللوحي</string>
<string name="revanced_change_form_factor_entry_4">Automotive</string> <string name="revanced_change_form_factor_entry_4">Automotive</string>
<string name="revanced_change_form_factor_user_dialog_message">"تتضمن التغييرات: <string name="revanced_change_form_factor_user_dialog_message">"التغييرات تشمل:
تخطيط الجهاز اللوحي تصميم الجهاز اللوحي
إخفاء منشورات المجتمع مشاركات المجتمع مخفية
تخطيط Automotive تصميم السيارة
إخفاء قائمة سجل المشاهدة يتم فتح Shorts في المشغل العادي
استعادة علامة التبويب \"استكشاف\" يتم تنظيم الخلاصة حسب المواضيع والقنوات"</string>
• فتح فيديوهات Shorts في المشغل العادي
• تنظيم الخلاصة حسب الموضوعات والقناة"</string>
</patch> </patch>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<string name="revanced_spoof_app_version_title">خِداع إصدار التطبيق</string> <string name="revanced_spoof_app_version_title">خِداع إصدار التطبيق</string>
@@ -1140,12 +1089,7 @@ Second \"item\" text"</string>
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<string name="revanced_spoof_app_version_target_title">الهدف من تغيير إصدار التطبيق</string> <string name="revanced_spoof_app_version_target_title">الهدف من تغيير إصدار التطبيق</string>
<string name="revanced_spoof_app_version_target_entry_1">19.35.36 - استعادة أيقونات مشغل Shorts القديمة</string> <string name="revanced_spoof_app_version_target_entry_1">19.35.36 - استعادة أيقونات مشغل Shorts القديمة</string>
<string name="revanced_spoof_app_version_target_entry_2">19.26.42 - استعادة أيقونات التنقل القديمة</string> <string name="revanced_spoof_app_version_target_entry_2">19.01.34 - استعادة أيقونات التنقل القديمة</string>
<!-- 'RYD' is 'Return YouTube Dislike' -->
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - استعادة RYD على Shorts بوضع التخفي</string>
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - استعادة قائمة سرعة الفيديو العريضة &amp; الجودة</string>
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - استعادة علامة تبويب المكتبة</string>
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - استعادة رف قائمة التشغيل القديم</string>
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
<string name="revanced_change_start_page_title">تعيين صفحة البداية</string> <string name="revanced_change_start_page_title">تعيين صفحة البداية</string>
@@ -1248,8 +1192,6 @@ Second \"item\" text"</string>
<string name="revanced_gradient_loading_screen_title">تمكين شاشة التحميل المتدرجة</string> <string name="revanced_gradient_loading_screen_title">تمكين شاشة التحميل المتدرجة</string>
<string name="revanced_gradient_loading_screen_summary_on">ستحتوي شاشة التحميل على خلفية متدرجة</string> <string name="revanced_gradient_loading_screen_summary_on">ستحتوي شاشة التحميل على خلفية متدرجة</string>
<string name="revanced_gradient_loading_screen_summary_off">ستحتوي شاشة التحميل على خلفية ثابتة</string> <string name="revanced_gradient_loading_screen_summary_off">ستحتوي شاشة التحميل على خلفية ثابتة</string>
</patch>
<patch id="layout.theme.themeResourcePatch">
<string name="revanced_seekbar_custom_color_title">تمكين لون شريط تقدم الفيديو المخصص</string> <string name="revanced_seekbar_custom_color_title">تمكين لون شريط تقدم الفيديو المخصص</string>
<string name="revanced_seekbar_custom_color_summary_on">يتم عرض لون شريط تقدم الفيديو المخصص</string> <string name="revanced_seekbar_custom_color_summary_on">يتم عرض لون شريط تقدم الفيديو المخصص</string>
<string name="revanced_seekbar_custom_color_summary_off">يتم عرض لون شريط تقدم الفيديو الاصلي</string> <string name="revanced_seekbar_custom_color_summary_off">يتم عرض لون شريط تقدم الفيديو الاصلي</string>
@@ -1341,8 +1283,8 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="misc.links.openLinksExternallyPatch"> <patch id="misc.links.openLinksExternallyPatch">
<string name="revanced_external_browser_title">فتح الروابط في المتصفح</string> <string name="revanced_external_browser_title">فتح الروابط في المتصفح</string>
<string name="revanced_external_browser_summary_on">فتح الروابط خارجيًا</string> <string name="revanced_external_browser_summary_on">فتح الروابط في متصفح خارجي</string>
<string name="revanced_external_browser_summary_off">فتح الروابط في التطبيق</string> <string name="revanced_external_browser_summary_off">فتح الروابط في متصفح داخل التطبيق</string>
</patch> </patch>
<patch id="misc.privacy.removeTrackingQueryParameterPatch"> <patch id="misc.privacy.removeTrackingQueryParameterPatch">
<string name="revanced_remove_tracking_query_parameter_title">إزالة معلمة تتبع الاستعلام</string> <string name="revanced_remove_tracking_query_parameter_title">إزالة معلمة تتبع الاستعلام</string>
@@ -1355,6 +1297,7 @@ Second \"item\" text"</string>
<string name="revanced_disable_zoom_haptics_summary_off">تم تمكين الاهتزاز</string> <string name="revanced_disable_zoom_haptics_summary_off">تم تمكين الاهتزاز</string>
</patch> </patch>
<patch id="video.audio.forceOriginalAudioPatch"> <patch id="video.audio.forceOriginalAudioPatch">
<string name="revanced_force_original_audio_title">فرض لغة الصوت الأصلية</string>
<string name="revanced_force_original_audio_summary_on">استخدام لغة الصوت الأصلية</string> <string name="revanced_force_original_audio_summary_on">استخدام لغة الصوت الأصلية</string>
<string name="revanced_force_original_audio_summary_off">استخدام الصوت الافتراضي</string> <string name="revanced_force_original_audio_summary_off">استخدام الصوت الافتراضي</string>
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title --> <!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
@@ -1368,9 +1311,15 @@ Second \"item\" text"</string>
<string name="revanced_remember_video_quality_last_selected_summary_off">تنطبق تغييرات الجودة على الفيديو الحالي فقط</string> <string name="revanced_remember_video_quality_last_selected_summary_off">تنطبق تغييرات الجودة على الفيديو الحالي فقط</string>
<string name="revanced_video_quality_default_wifi_title">جودة الفيديو الافتراضية على شبكة Wi-Fi</string> <string name="revanced_video_quality_default_wifi_title">جودة الفيديو الافتراضية على شبكة Wi-Fi</string>
<string name="revanced_video_quality_default_mobile_title">جودة الفيديو الافتراضية على شبكة الجوَّال</string> <string name="revanced_video_quality_default_mobile_title">جودة الفيديو الافتراضية على شبكة الجوَّال</string>
<string name="revanced_remember_shorts_quality_last_selected_title">تذكر تغييرات جودة Shorts</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_on">تنطبق تغييرات الجودة على جميع فيديوهات Shorts</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_off">تنطبق تغييرات الجودة فقط على فيديو Short الحالي</string>
<string name="revanced_shorts_quality_default_wifi_title">جودة Shorts الافتراضية على شبكة Wi-Fi</string>
<string name="revanced_shorts_quality_default_mobile_title">جودة Shorts الافتراضية على شبكة الجوال</string>
<string name="revanced_remember_video_quality_mobile">الجوّال</string> <string name="revanced_remember_video_quality_mobile">الجوّال</string>
<string name="revanced_remember_video_quality_wifi">Wi-Fi</string> <string name="revanced_remember_video_quality_wifi">Wi-Fi</string>
<string name="revanced_remember_video_quality_toast">تم تغيير جودة %1$s الافتراضية إلى: %2$s</string> <string name="revanced_remember_video_quality_toast">تم تغيير جودة %1$s الافتراضية إلى: %2$s</string>
<string name="revanced_remember_video_quality_toast_shorts">تم تغيير جودة Shorts %1$s إلى: %2$s</string>
</patch> </patch>
<patch id="video.speed.button.playbackSpeedButtonPatch"> <patch id="video.speed.button.playbackSpeedButtonPatch">
<string name="revanced_playback_speed_dialog_button_title">عرض زر مربع حوار السرعة</string> <string name="revanced_playback_speed_dialog_button_title">عرض زر مربع حوار السرعة</string>
@@ -1401,10 +1350,10 @@ Second \"item\" text"</string>
<string name="revanced_disable_hdr_video_summary_on">تم تعطيل فيديو HDR</string> <string name="revanced_disable_hdr_video_summary_on">تم تعطيل فيديو HDR</string>
<string name="revanced_disable_hdr_video_summary_off">تم تمكين فيديو HDR</string> <string name="revanced_disable_hdr_video_summary_off">تم تمكين فيديو HDR</string>
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
<string name="revanced_restore_old_video_quality_menu_title">استعادة قائمة جودة الفيديو القديمة</string> <string name="revanced_advanced_video_quality_menu_title">إظهار قائمة جودة الفيديو المتقدمة</string>
<string name="revanced_restore_old_video_quality_menu_summary_on">يتم عرض قائمة جودة الفيديو القديمة</string> <string name="revanced_advanced_video_quality_menu_summary_on">يتم عرض قائمة جودة الفيديو المتقدمة</string>
<string name="revanced_restore_old_video_quality_menu_summary_off">لا يتم عرض قائمة جودة الفيديو القديمة</string> <string name="revanced_advanced_video_quality_menu_summary_off">لا يتم عرض قائمة جودة الفيديو المتقدمة</string>
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
<string name="revanced_slide_to_seek_title">تمكين التمرير للتقديم أو الترجيع</string> <string name="revanced_slide_to_seek_title">تمكين التمرير للتقديم أو الترجيع</string>

View File

@@ -156,6 +156,7 @@ Second \"item\" text"</string>
<patch id="layout.sponsorblock.sponsorBlockResourcePatch"> <patch id="layout.sponsorblock.sponsorBlockResourcePatch">
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' --> <!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. --> <!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<!-- Shown in the settings preferences, and translations can be any text length. --> <!-- Shown in the settings preferences, and translations can be any text length. -->
</patch> </patch>
<patch id="layout.formfactor.changeFormFactorPatch"> <patch id="layout.formfactor.changeFormFactorPatch">
@@ -163,7 +164,6 @@ Second \"item\" text"</string>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<!-- It is ideal, but not required, if the text here appears is alphabetically after the text used for 'revanced_spoof_app_version_title'. <!-- It is ideal, but not required, if the text here appears is alphabetically after the text used for 'revanced_spoof_app_version_title'.
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<!-- 'RYD' is 'Return YouTube Dislike' -->
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
</patch> </patch>
@@ -177,8 +177,6 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="layout.theme.themePatch"> <patch id="layout.theme.themePatch">
</patch> </patch>
<patch id="layout.theme.themeResourcePatch">
</patch>
<patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch"> <patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch">
</patch> </patch>
<patch id="layout.thumbnails.alternativeThumbnailsPatch"> <patch id="layout.thumbnails.alternativeThumbnailsPatch">
@@ -221,7 +219,7 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="video.hdr.disableHdrPatch"> <patch id="video.hdr.disableHdrPatch">
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
</patch> </patch>

View File

@@ -48,57 +48,6 @@ Second \"item\" text"</string>
Yeni dilləri tərcümə etmək üçün translate.revanced.app 'ə daxil olun"</string> Yeni dilləri tərcümə etmək üçün translate.revanced.app 'ə daxil olun"</string>
<string name="revanced_language_DEFAULT">Tətbiq dili</string> <string name="revanced_language_DEFAULT">Tətbiq dili</string>
<string name="revanced_language_AR">Ərəbcə</string>
<string name="revanced_language_AZ">Azərbaycanca</string>
<string name="revanced_language_BG">Bolqarca</string>
<string name="revanced_language_BN">Benqalca</string>
<string name="revanced_language_CA">Katalan dili</string>
<string name="revanced_language_CS">Çexcə</string>
<string name="revanced_language_DA">Dan dili</string>
<string name="revanced_language_DE">Almanca</string>
<string name="revanced_language_EL">Yunanca</string>
<string name="revanced_language_EN">İngiliscə</string>
<string name="revanced_language_ES">İspanca</string>
<string name="revanced_language_ET">Estonca</string>
<string name="revanced_language_FA">Farsca</string>
<string name="revanced_language_FI">Fincə</string>
<string name="revanced_language_FR">Fransızca</string>
<string name="revanced_language_GU">Qücərat dili</string>
<string name="revanced_language_HI">Hindcə</string>
<string name="revanced_language_HR">Xorvatca</string>
<string name="revanced_language_HU">Macarca</string>
<string name="revanced_language_ID">İndoneziya dili</string>
<string name="revanced_language_IT">İtalyanca</string>
<string name="revanced_language_JA">Yaponca</string>
<string name="revanced_language_KK">Qazax dili</string>
<string name="revanced_language_KO">Koreya dili</string>
<string name="revanced_language_LT">Litva Dili</string>
<string name="revanced_language_LV">Letonca</string>
<string name="revanced_language_MK">Makedon Dili</string>
<string name="revanced_language_MN">Monqolca</string>
<string name="revanced_language_MR">Marathi dili</string>
<string name="revanced_language_MS">Malay dili</string>
<string name="revanced_language_MY">Birmanca</string>
<string name="revanced_language_NL">Hollandca</string>
<string name="revanced_language_OR">Oriya dili</string>
<string name="revanced_language_PA">Pəncabca</string>
<string name="revanced_language_PL">Polyak dili</string>
<string name="revanced_language_PT">Portuqal dili</string>
<string name="revanced_language_RO">Rumınca</string>
<string name="revanced_language_RU">Rusca</string>
<string name="revanced_language_SK">Slovak dili</string>
<string name="revanced_language_SL">Slovencə</string>
<string name="revanced_language_SR">Serbcə</string>
<string name="revanced_language_SV">İsveçcə</string>
<string name="revanced_language_SW">Suahili dili</string>
<string name="revanced_language_TA">Tamilcə</string>
<string name="revanced_language_TE">Teluqu dili</string>
<string name="revanced_language_TH">Tayca</string>
<string name="revanced_language_TR">Türkcə</string>
<string name="revanced_language_UK">Ukrayna dili</string>
<string name="revanced_language_UR">Urdu dili</string>
<string name="revanced_language_VI">Vyetnamca</string>
<string name="revanced_language_ZH">Çincə</string>
<string name="revanced_pref_import_export_title">İdxal/İxrac et</string> <string name="revanced_pref_import_export_title">İdxal/İxrac et</string>
<string name="revanced_pref_import_export_summary">ReVanced tənzimləmələrin idxal/ixrac et</string> <string name="revanced_pref_import_export_summary">ReVanced tənzimləmələrin idxal/ixrac et</string>
<!-- Settings about dialog. --> <!-- Settings about dialog. -->
@@ -278,12 +227,12 @@ Gözlənilməz hallardan xəbərdar olmayacaqsınız."</string>
<string name="revanced_hide_artist_cards_summary_on">Sənətçi kartları gizlidir</string> <string name="revanced_hide_artist_cards_summary_on">Sənətçi kartları gizlidir</string>
<string name="revanced_hide_artist_cards_summary_off">Sənətçi kartları göstərilir</string> <string name="revanced_hide_artist_cards_summary_off">Sənətçi kartları göstərilir</string>
<string name="revanced_hide_attributes_section_title">Atributları Gizlət</string> <string name="revanced_hide_attributes_section_title">Atributları Gizlət</string>
<string name="revanced_hide_attributes_section_summary_on">Seçilən məkanlar, Oyunlar, Musiqi və qeyd edilən insanlar bölmələri gizlədilir</string> <string name="revanced_hide_attributes_section_summary_on">Seçilən yerlər, Oyunlar, Musiqi və qeyd edilən insanlar bölmələri gizlədilir</string>
<string name="revanced_hide_attributes_section_summary_off">Seçilən məkanlar, Oyunlar, Musiqi və qeyd edilən insanlar bölmələri görünür</string> <string name="revanced_hide_attributes_section_summary_off">Seçilən yerlər, Oyunlar, Musiqi və qeyd edilən insanlar bölmələri görünür</string>
<string name="revanced_hide_chapters_section_title">Fəsilləri Gizlət</string> <string name="revanced_hide_chapters_section_title">Fəsilləri Gizlət</string>
<string name="revanced_hide_chapters_section_summary_on">Bölümlər bölməsi gizlidir</string> <string name="revanced_hide_chapters_section_summary_on">Bölümlər bölməsi gizlidir</string>
<string name="revanced_hide_chapters_section_summary_off">Bölümlər bölməsi göstərilir</string> <string name="revanced_hide_chapters_section_summary_off">Bölümlər bölməsi göstərilir</string>
<string name="revanced_hide_how_this_was_made_section_title">\'Bu məzmun necə hazırlanıb\'ı Gizlət</string> <string name="revanced_hide_how_this_was_made_section_title">\'Bu kontent necə hazırlanıb\'ı Gizlət</string>
<string name="revanced_hide_how_this_was_made_section_summary_on">Bu məzmunun necə hazırlandığı bölməsi gizlidir</string> <string name="revanced_hide_how_this_was_made_section_summary_on">Bu məzmunun necə hazırlandığı bölməsi gizlidir</string>
<string name="revanced_hide_how_this_was_made_section_summary_off">Bu məzmunun necə hazırlandığı bölməsi görünür</string> <string name="revanced_hide_how_this_was_made_section_summary_off">Bu məzmunun necə hazırlandığı bölməsi görünür</string>
<string name="revanced_hide_podcast_section_title">\'Podkastı araşdırın\"-ı Gizlət</string> <string name="revanced_hide_podcast_section_title">\'Podkastı araşdırın\"-ı Gizlət</string>
@@ -292,22 +241,22 @@ Gözlənilməz hallardan xəbərdar olmayacaqsınız."</string>
<string name="revanced_hide_info_cards_section_title">Məlumat Kartlarını Gizlət</string> <string name="revanced_hide_info_cards_section_title">Məlumat Kartlarını Gizlət</string>
<string name="revanced_hide_info_cards_section_summary_on">Məlumat kartları bölməsi gizlədilir</string> <string name="revanced_hide_info_cards_section_summary_on">Məlumat kartları bölməsi gizlədilir</string>
<string name="revanced_hide_info_cards_section_summary_off">Məlumat kartları bölməsi göstərilir</string> <string name="revanced_hide_info_cards_section_summary_off">Məlumat kartları bölməsi göstərilir</string>
<string name="revanced_hide_key_concepts_section_title">\"Əsas anlayışları\" gizlət</string> <string name="revanced_hide_key_concepts_section_title">\"Əsas konseptlər-i\" gizlət</string>
<string name="revanced_hide_key_concepts_section_summary_on">Əsas anlayışlar bölməsi gizlidir</string> <string name="revanced_hide_key_concepts_section_summary_on">Əsas konseptlər bölməsi gizlidir</string>
<string name="revanced_hide_key_concepts_section_summary_off">Əsas anlayışlar bölməsi görünür</string> <string name="revanced_hide_key_concepts_section_summary_off">Əsas konseptlər bölməsi görünür</string>
<string name="revanced_hide_transcript_section_title">Transkript-i Gizlət</string> <string name="revanced_hide_transcript_section_title">Transkript-i Gizlət</string>
<string name="revanced_hide_transcript_section_summary_on">Transkripsiya bölməsi gizlidir</string> <string name="revanced_hide_transcript_section_summary_on">Transkripsiya bölməsi gizlidir</string>
<string name="revanced_hide_transcript_section_summary_off">Transkripsiya bölməsi göstərilir</string> <string name="revanced_hide_transcript_section_summary_off">Transkripsiya bölməsi göstərilir</string>
<string name="revanced_hide_description_components_screen_title">Video ıqlaması</string> <string name="revanced_hide_description_components_screen_title">Video təsviri</string>
<string name="revanced_hide_description_components_screen_summary">Video ıqlaması elementlərini gizlət və ya göstər</string> <string name="revanced_hide_description_components_screen_summary">Video təsviri elementlərini gizlət və ya göstər</string>
<string name="revanced_hide_filter_bar_screen_title">Filtr çubuğu</string> <string name="revanced_hide_filter_bar_screen_title">Filtr çubuğu</string>
<string name="revanced_hide_filter_bar_screen_summary">Axında, axtarışda və əlaqəli videolardakı filtr çubuğunu gizlət və ya göstər</string> <string name="revanced_hide_filter_bar_screen_summary">Axında, axtarış nəticələrində və əlaqəli videolarda filtr cərgəsin gizlət və ya göstər</string>
<string name="revanced_hide_filter_bar_feed_in_feed_title">Axında gizlət</string> <string name="revanced_hide_filter_bar_feed_in_feed_title">Axında gizlət</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Axında gizlidir</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Axında gizlidir</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Axında göstərilir</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Axında göstərilir</string>
<string name="revanced_hide_filter_bar_feed_in_search_title">Axtarışda gizlət</string> <string name="revanced_hide_filter_bar_feed_in_search_title">Axtarış nəticələrində gizlət</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_on">Axtarışda gizlidir</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_on">Axtarış nəticələrində gizlədilib</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_off">Axtarışda görünür</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_off">Axtarış nəticələrində göstərilir</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">Əlaqəli videolarda gizlət</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_title">Əlaqəli videolarda gizlət</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Əlaqəli videolarda gizlidir</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Əlaqəli videolarda gizlidir</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">Əlaqəli videolarda görünür</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">Əlaqəli videolarda görünür</string>
@@ -404,7 +353,7 @@ Bu xüsusiyyət yalnız köhnə cihazlar üçün mövcuddur"</string>
<string name="revanced_hide_self_sponsor_ads_title">Öz-sponsorlu kartları gizlət</string> <string name="revanced_hide_self_sponsor_ads_title">Öz-sponsorlu kartları gizlət</string>
<string name="revanced_hide_self_sponsor_ads_summary_on">Özünə sponsorluq edilən kartlar gizlidir</string> <string name="revanced_hide_self_sponsor_ads_summary_on">Özünə sponsorluq edilən kartlar gizlidir</string>
<string name="revanced_hide_self_sponsor_ads_summary_off">Özünə sponsorluq edilən kartlar göstərilir</string> <string name="revanced_hide_self_sponsor_ads_summary_off">Özünə sponsorluq edilən kartlar göstərilir</string>
<string name="revanced_hide_products_banner_title">Məhsullara baxma etiketin gizlət</string> <string name="revanced_hide_products_banner_title">\"Məhsullara baxın\" etiketin gizlət</string>
<string name="revanced_hide_products_banner_summary_on">Etiket gizlədilib</string> <string name="revanced_hide_products_banner_summary_on">Etiket gizlədilib</string>
<string name="revanced_hide_products_banner_summary_off">Etiket göstərilir</string> <string name="revanced_hide_products_banner_summary_off">Etiket göstərilir</string>
<string name="revanced_hide_end_screen_store_banner_title">Son ekran mağaza etiketini gizlət</string> <string name="revanced_hide_end_screen_store_banner_title">Son ekran mağaza etiketini gizlət</string>
@@ -663,7 +612,7 @@ Bu seçimi dəyişdirmə işə düşmürsə, Gizli rejimə keçməyə çalışı
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Video keyfiyyət menyusu alt məlumatı göstərilir</string> <string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Video keyfiyyət menyusu alt məlumatı göstərilir</string>
</patch> </patch>
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch"> <patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
<string name="revanced_hide_player_previous_next_buttons_title">Əvvəlki/növbəti video düymələrin gizlət</string> <string name="revanced_hide_player_previous_next_buttons_title">Əvvəlki və Növbəti düymələrin gizlət</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Düymələr gizlidir</string> <string name="revanced_hide_player_previous_next_buttons_summary_on">Düymələr gizlidir</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Düymələr göstərilir</string> <string name="revanced_hide_player_previous_next_buttons_summary_off">Düymələr göstərilir</string>
<string name="revanced_hide_cast_button_title">Yayımla düyməsini gizlət</string> <string name="revanced_hide_cast_button_title">Yayımla düyməsini gizlət</string>
@@ -855,7 +804,6 @@ Avtomatik oynatma YouTube ayarlarında dəyişdirilə bilər: Ayarlar → Oxunu
<string name="revanced_ryd_enable_summary_on">Bəyənməmələr göstərilir</string> <string name="revanced_ryd_enable_summary_on">Bəyənməmələr göstərilir</string>
<string name="revanced_ryd_enable_summary_off">Bəyənməmələr göstərilmir</string> <string name="revanced_ryd_enable_summary_off">Bəyənməmələr göstərilmir</string>
<string name="revanced_ryd_shorts_title">\"Shorts\"da bəyənməmə sayını göstər</string> <string name="revanced_ryd_shorts_title">\"Shorts\"da bəyənməmə sayını göstər</string>
<string name="revanced_ryd_shorts_summary_on">Bəyənməmələr Shorts-da göstərilir</string>
<string name="revanced_ryd_shorts_summary_on_disclaimer">"Bəyənməmələr Shorts-da göstərilir <string name="revanced_ryd_shorts_summary_on_disclaimer">"Bəyənməmələr Shorts-da göstərilir
Məhdudiyyət: Bəyənməmələr gizli rejimdə görünməyə bilər"</string> Məhdudiyyət: Bəyənməmələr gizli rejimdə görünməyə bilər"</string>
@@ -1053,6 +1001,8 @@ Artıq mövcuddur"</string>
<string name="revanced_sb_vote_downvote">Mənfi səs</string> <string name="revanced_sb_vote_downvote">Mənfi səs</string>
<string name="revanced_sb_vote_category">Kateqoriyanı dəyişdir</string> <string name="revanced_sb_vote_category">Kateqoriyanı dəyişdir</string>
<string name="revanced_sb_vote_no_segments">Səsvermə üçün bölüm yoxdur</string> <string name="revanced_sb_vote_no_segments">Səsvermə üçün bölüm yoxdur</string>
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<string name="revanced_sb_vote_segment_time_to_from">%1$s - %2$s</string>
<string name="revanced_sb_new_segment_choose_category">Bölüm kateqoriyasını seçin</string> <string name="revanced_sb_new_segment_choose_category">Bölüm kateqoriyasını seçin</string>
<string name="revanced_sb_new_segment_disabled_category">Seçimlərdə kateqoriya qeyri-aktivdir. Göndərmək üçün kateqoriyanı aktiv et.</string> <string name="revanced_sb_new_segment_disabled_category">Seçimlərdə kateqoriya qeyri-aktivdir. Göndərmək üçün kateqoriyanı aktiv et.</string>
<string name="revanced_sb_new_segment_title">Yeni SponsorBlock bölümü</string> <string name="revanced_sb_new_segment_title">Yeni SponsorBlock bölümü</string>
@@ -1100,6 +1050,7 @@ Təqdim etməyə hazırdır?"</string>
<string name="revanced_sb_stats_saved_hour_format">%1$s saat %2$s dəqiqə</string> <string name="revanced_sb_stats_saved_hour_format">%1$s saat %2$s dəqiqə</string>
<string name="revanced_sb_stats_saved_minute_format">%1$s dəqiqə %2$s saniyə</string> <string name="revanced_sb_stats_saved_minute_format">%1$s dəqiqə %2$s saniyə</string>
<string name="revanced_sb_stats_saved_second_format">%s saniyə</string> <string name="revanced_sb_stats_saved_second_format">%s saniyə</string>
<string name="revanced_sb_color_opacity_label">Qeyri-şəffaflıq:</string>
<string name="revanced_sb_color_dot_label">Rəng:</string> <string name="revanced_sb_color_dot_label">Rəng:</string>
<string name="revanced_sb_color_changed">Rəng dəyişdirildi</string> <string name="revanced_sb_color_changed">Rəng dəyişdirildi</string>
<string name="revanced_sb_color_reset">Rəngi sıfırla</string> <string name="revanced_sb_color_reset">Rəngi sıfırla</string>
@@ -1115,16 +1066,14 @@ Təqdim etməyə hazırdır?"</string>
<string name="revanced_change_form_factor_entry_2">Telefon</string> <string name="revanced_change_form_factor_entry_2">Telefon</string>
<string name="revanced_change_form_factor_entry_3">Planşet</string> <string name="revanced_change_form_factor_entry_3">Planşet</string>
<string name="revanced_change_form_factor_entry_4">Avtomobil</string> <string name="revanced_change_form_factor_entry_4">Avtomobil</string>
<string name="revanced_change_form_factor_user_dialog_message">"Dəyişikliklərə daxildir: <string name="revanced_change_form_factor_user_dialog_message">"Dəyişikliklər ehtiva edir:
Planşet tərtibatı Planşet tərtibatı
• İcma elanları gizlidir • İcma elanları gizlədilib
Avtomobil tərtibatı Avtomobil tərtibatı
Baxış tarixçəsi seçimi gizlidir Shorts müntəzəm oynadıcıda açılır
\"Kəşf et\" bölməsi qaytarılıb Axın mövzular və kanallardan ibarətdir"</string>
• Shorts daimi oynadıcıda açılır
• Axın mövzulara və kanala görə hazırlanıb"</string>
</patch> </patch>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<string name="revanced_spoof_app_version_title">Tətbiq versiyasını saxtalaşdır</string> <string name="revanced_spoof_app_version_title">Tətbiq versiyasını saxtalaşdır</string>
@@ -1139,12 +1088,7 @@ Sonradan qapadılarsa, UI səhvlərin önləmək üçün tətbiq məlumatların
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<string name="revanced_spoof_app_version_target_title">Saxta tətbiq versiyası hədəfi</string> <string name="revanced_spoof_app_version_target_title">Saxta tətbiq versiyası hədəfi</string>
<string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Köhnə Shorts oynadıcı işarələrin bərpa et</string> <string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Köhnə Shorts oynadıcı işarələrin bərpa et</string>
<string name="revanced_spoof_app_version_target_entry_2">19.26.42 - Köhnə fəaliyyət simvolların bərpa et</string> <string name="revanced_spoof_app_version_target_entry_2">19.01.34 - Köhnə fəaliyyət simvolların bərpa et</string>
<!-- 'RYD' is 'Return YouTube Dislike' -->
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - Shorts gizli rejimində RYD-ni bərpa et</string>
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Geniş video sürəti &amp; keyfiyyət menyusunu bərpa et</string>
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - Kitabxana panelini bərpa et</string>
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - Köhnə pleylist bölməsin bərpa et</string>
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
<string name="revanced_change_start_page_title">Başlanğıc səhifəsini təyin et</string> <string name="revanced_change_start_page_title">Başlanğıc səhifəsini təyin et</string>
@@ -1194,7 +1138,7 @@ Sonradan qapadılarsa, UI səhvlərin önləmək üçün tətbiq məlumatların
</patch> </patch>
<patch id="layout.miniplayer.miniplayerPatch"> <patch id="layout.miniplayer.miniplayerPatch">
<string name="revanced_miniplayer_screen_title">Kiçik oynadıcı</string> <string name="revanced_miniplayer_screen_title">Kiçik oynadıcı</string>
<string name="revanced_miniplayer_screen_summary">Tətbiqdə kiçildilən oynadıcı üslubunu dəyişdir</string> <string name="revanced_miniplayer_screen_summary">Tətbiqdaxili kiçilən oynadıcı üslubunu dəyişdir</string>
<string name="revanced_miniplayer_type_title">Kiçik oynadıcı növü</string> <string name="revanced_miniplayer_type_title">Kiçik oynadıcı növü</string>
<string name="revanced_miniplayer_type_entry_0">Qeyri-aktivdir</string> <string name="revanced_miniplayer_type_entry_0">Qeyri-aktivdir</string>
<string name="revanced_miniplayer_type_entry_1">İlkin</string> <string name="revanced_miniplayer_type_entry_1">İlkin</string>
@@ -1247,8 +1191,6 @@ Genişləndirmək və ya bağlamaq üçün sürüşdür"</string>
<string name="revanced_gradient_loading_screen_title">Dəyişkən yükləmə ekranını aktivləşdir</string> <string name="revanced_gradient_loading_screen_title">Dəyişkən yükləmə ekranını aktivləşdir</string>
<string name="revanced_gradient_loading_screen_summary_on">Yükləmə ekranı, dəyişkən arxa plana malik olacaq</string> <string name="revanced_gradient_loading_screen_summary_on">Yükləmə ekranı, dəyişkən arxa plana malik olacaq</string>
<string name="revanced_gradient_loading_screen_summary_off">Yükləmə ekranı, vahid arxa plana malik olacaq</string> <string name="revanced_gradient_loading_screen_summary_off">Yükləmə ekranı, vahid arxa plana malik olacaq</string>
</patch>
<patch id="layout.theme.themeResourcePatch">
<string name="revanced_seekbar_custom_color_title">Fərdi irəliləmə cizgisi rəngini aktivləşdir</string> <string name="revanced_seekbar_custom_color_title">Fərdi irəliləmə cizgisi rəngini aktivləşdir</string>
<string name="revanced_seekbar_custom_color_summary_on">Fərdi irəliləmə cizgisi rəngi göstərilir</string> <string name="revanced_seekbar_custom_color_summary_on">Fərdi irəliləmə cizgisi rəngi göstərilir</string>
<string name="revanced_seekbar_custom_color_summary_off">Orijinal irəliləmə cizgisi rəngi göstərilir</string> <string name="revanced_seekbar_custom_color_summary_off">Orijinal irəliləmə cizgisi rəngi göstərilir</string>
@@ -1340,8 +1282,8 @@ Bunu aktivləşdirmə daha yüksək video keyfiyyətləri əngəlin silə bilər
</patch> </patch>
<patch id="misc.links.openLinksExternallyPatch"> <patch id="misc.links.openLinksExternallyPatch">
<string name="revanced_external_browser_title">Bağlantıları brauzerdə aç</string> <string name="revanced_external_browser_title">Bağlantıları brauzerdə aç</string>
<string name="revanced_external_browser_summary_on">Bağlantılar xarici yollaılır</string> <string name="revanced_external_browser_summary_on">Xarici brauzerdə bağlantılarınılması</string>
<string name="revanced_external_browser_summary_off">Bağlantılar tətbiqdəılır</string> <string name="revanced_external_browser_summary_off">Tətbiqdaxili brauzerdə bağlantılarınılması</string>
</patch> </patch>
<patch id="misc.privacy.removeTrackingQueryParameterPatch"> <patch id="misc.privacy.removeTrackingQueryParameterPatch">
<string name="revanced_remove_tracking_query_parameter_title">İzləmə sorğusu faktorun sil</string> <string name="revanced_remove_tracking_query_parameter_title">İzləmə sorğusu faktorun sil</string>
@@ -1368,9 +1310,15 @@ Bunu aktivləşdirmə daha yüksək video keyfiyyətləri əngəlin silə bilər
<string name="revanced_remember_video_quality_last_selected_summary_off">Keyfiyyət dəyişiklikləri yalnız cari videoya tətbiq edilir</string> <string name="revanced_remember_video_quality_last_selected_summary_off">Keyfiyyət dəyişiklikləri yalnız cari videoya tətbiq edilir</string>
<string name="revanced_video_quality_default_wifi_title">Wi-Fi şəbəkəsində ilkin video keyfiyyəti</string> <string name="revanced_video_quality_default_wifi_title">Wi-Fi şəbəkəsində ilkin video keyfiyyəti</string>
<string name="revanced_video_quality_default_mobile_title">Mobil şəbəkədə ilkin video keyfiyyəti</string> <string name="revanced_video_quality_default_mobile_title">Mobil şəbəkədə ilkin video keyfiyyəti</string>
<string name="revanced_remember_shorts_quality_last_selected_title">Shorts keyfiyyət dəyişikliklərini xatırla</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_on">Keyfiyyət dəyişiklikləri bütün Shorts-a tətbiq edilir</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_off">Keyfiyyət dəyişiklikləri yalnız cari Short-a tətbiq edilir</string>
<string name="revanced_shorts_quality_default_wifi_title">Wi-Fi şəbəkəsində ilkin Shorts keyfiyyəti</string>
<string name="revanced_shorts_quality_default_mobile_title">Mobil şəbəkədə ilkin Shorts keyfiyyəti</string>
<string name="revanced_remember_video_quality_mobile">mobil</string> <string name="revanced_remember_video_quality_mobile">mobil</string>
<string name="revanced_remember_video_quality_wifi">wi-fi</string> <string name="revanced_remember_video_quality_wifi">wi-fi</string>
<string name="revanced_remember_video_quality_toast">İlkin %1$s keyfiyyəti %2$s kimi dəyişdi</string> <string name="revanced_remember_video_quality_toast">İlkin %1$s keyfiyyəti %2$s kimi dəyişdi</string>
<string name="revanced_remember_video_quality_toast_shorts">Shorts-un %1$s keyfiyyəti %2$s olaraq dəyişdirildi</string>
</patch> </patch>
<patch id="video.speed.button.playbackSpeedButtonPatch"> <patch id="video.speed.button.playbackSpeedButtonPatch">
<string name="revanced_playback_speed_dialog_button_title">Sürət dialoq düyməsini göstər</string> <string name="revanced_playback_speed_dialog_button_title">Sürət dialoq düyməsini göstər</string>
@@ -1401,10 +1349,10 @@ Bunu aktivləşdirmə daha yüksək video keyfiyyətləri əngəlin silə bilər
<string name="revanced_disable_hdr_video_summary_on">HDR video qapalıdır</string> <string name="revanced_disable_hdr_video_summary_on">HDR video qapalıdır</string>
<string name="revanced_disable_hdr_video_summary_off">HDR video aktivdir</string> <string name="revanced_disable_hdr_video_summary_off">HDR video aktivdir</string>
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
<string name="revanced_restore_old_video_quality_menu_title">Köhnə video keyfiyyət menusun qaytar</string> <string name="revanced_advanced_video_quality_menu_title">Qabaqcıl video keyfiyyət siyahısın göstər</string>
<string name="revanced_restore_old_video_quality_menu_summary_on">Köhnə video keyfiyyət siyahısı göstərilir</string> <string name="revanced_advanced_video_quality_menu_summary_on">Qabaqcıl video keyfiyyət siyahısı göstərilir</string>
<string name="revanced_restore_old_video_quality_menu_summary_off">Köhnə video keyfiyyət siyahısırünmür</string> <string name="revanced_advanced_video_quality_menu_summary_off">Qabaqcıl video keyfiyyət siyahısıstərilmir</string>
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
<string name="revanced_slide_to_seek_title">Axtarmaq üçün sürüşdürməni aktiv et</string> <string name="revanced_slide_to_seek_title">Axtarmaq üçün sürüşdürməni aktiv et</string>

View File

@@ -48,57 +48,6 @@ Second \"item\" text"</string>
Каб дадаць новыя мовы, наведайце translate.revanced.app"</string> Каб дадаць новыя мовы, наведайце translate.revanced.app"</string>
<string name="revanced_language_DEFAULT">Мова праграмы</string> <string name="revanced_language_DEFAULT">Мова праграмы</string>
<string name="revanced_language_AR">Арабская</string>
<string name="revanced_language_AZ">Азербайджанскі</string>
<string name="revanced_language_BG">Балгарская</string>
<string name="revanced_language_BN">Бенгальская</string>
<string name="revanced_language_CA">Каталонская</string>
<string name="revanced_language_CS">Чэшскі</string>
<string name="revanced_language_DA">Дацкі</string>
<string name="revanced_language_DE">Нямецкі</string>
<string name="revanced_language_EL">Грэцкі</string>
<string name="revanced_language_EN">Англійская</string>
<string name="revanced_language_ES">Іспанская</string>
<string name="revanced_language_ET">Эстонская</string>
<string name="revanced_language_FA">Персідская</string>
<string name="revanced_language_FI">Фінская</string>
<string name="revanced_language_FR">Французская</string>
<string name="revanced_language_GU">Гуджараці</string>
<string name="revanced_language_HI">Хіндзі</string>
<string name="revanced_language_HR">Харвацкая</string>
<string name="revanced_language_HU">Венгерская</string>
<string name="revanced_language_ID">Інданезійская</string>
<string name="revanced_language_IT">Італьянская</string>
<string name="revanced_language_JA">Японская</string>
<string name="revanced_language_KK">Казахская</string>
<string name="revanced_language_KO">Карэйская</string>
<string name="revanced_language_LT">Літоўская</string>
<string name="revanced_language_LV">Латышская</string>
<string name="revanced_language_MK">Македонская</string>
<string name="revanced_language_MN">Мангольская</string>
<string name="revanced_language_MR">Малаялам</string>
<string name="revanced_language_MS">Малайская</string>
<string name="revanced_language_MY">Бірманская</string>
<string name="revanced_language_NL">Нідэрландская</string>
<string name="revanced_language_OR">Одыя</string>
<string name="revanced_language_PA">Пенджабі</string>
<string name="revanced_language_PL">Польская</string>
<string name="revanced_language_PT">Партугальская</string>
<string name="revanced_language_RO">Румынская</string>
<string name="revanced_language_RU">Руская</string>
<string name="revanced_language_SK">Славацкая</string>
<string name="revanced_language_SL">Славенская</string>
<string name="revanced_language_SR">Сербская</string>
<string name="revanced_language_SV">Шведская</string>
<string name="revanced_language_SW">Суахілі</string>
<string name="revanced_language_TA">Тамільская</string>
<string name="revanced_language_TE">Тэлугу</string>
<string name="revanced_language_TH">Тайская</string>
<string name="revanced_language_TR">Турецкая</string>
<string name="revanced_language_UK">Украінская</string>
<string name="revanced_language_UR">Урду</string>
<string name="revanced_language_VI">В\'етнамская</string>
<string name="revanced_language_ZH">Кітайская</string>
<string name="revanced_pref_import_export_title">Імпарт / Экспарт</string> <string name="revanced_pref_import_export_title">Імпарт / Экспарт</string>
<string name="revanced_pref_import_export_summary">Імпарт / Экспарт налад ReVanced</string> <string name="revanced_pref_import_export_summary">Імпарт / Экспарт налад ReVanced</string>
<!-- Settings about dialog. --> <!-- Settings about dialog. -->
@@ -301,13 +250,13 @@ Second \"item\" text"</string>
<string name="revanced_hide_description_components_screen_title">Апісанне відэа</string> <string name="revanced_hide_description_components_screen_title">Апісанне відэа</string>
<string name="revanced_hide_description_components_screen_summary">Схаваць або паказаць кампаненты апісання відэа</string> <string name="revanced_hide_description_components_screen_summary">Схаваць або паказаць кампаненты апісання відэа</string>
<string name="revanced_hide_filter_bar_screen_title">Панэль фільтраў</string> <string name="revanced_hide_filter_bar_screen_title">Панэль фільтраў</string>
<string name="revanced_hide_filter_bar_screen_summary">Схаваць або паказаць панэль фільтраў у стужцы, пошуку і звязаных відэа</string> <string name="revanced_hide_filter_bar_screen_summary">Схаваць ці паказаць панэль фільтраў у стужцы, выніках пошуку і звязаных відэа</string>
<string name="revanced_hide_filter_bar_feed_in_feed_title">Схаваць у карме</string> <string name="revanced_hide_filter_bar_feed_in_feed_title">Схаваць у карме</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Схаваны ў стужцы</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Схаваны ў стужцы</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Паказваецца ў стужцы</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Паказваецца ў стужцы</string>
<string name="revanced_hide_filter_bar_feed_in_search_title">Схавацца ў пошуку</string> <string name="revanced_hide_filter_bar_feed_in_search_title">Схаваць у выніках пошуку</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_on">Схаваны ў пошуку</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_on">Схавана ў выніках пошуку</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_off">Паказваецца ў пошуку</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_off">Паказана ў выніках пошуку</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">Схаваць у звязаных відэа</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_title">Схаваць у звязаных відэа</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Схавана ў звязаных відэа</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Схавана ў звязаных відэа</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">Паказана ў звязаных відэа</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">Паказана ў звязаных відэа</string>
@@ -404,7 +353,7 @@ Second \"item\" text"</string>
<string name="revanced_hide_self_sponsor_ads_title">Схаваць самі спансаваныя карты</string> <string name="revanced_hide_self_sponsor_ads_title">Схаваць самі спансаваныя карты</string>
<string name="revanced_hide_self_sponsor_ads_summary_on">Спонсарскія карткі схаваныя</string> <string name="revanced_hide_self_sponsor_ads_summary_on">Спонсарскія карткі схаваныя</string>
<string name="revanced_hide_self_sponsor_ads_summary_off">Паказваюцца ўласныя карты</string> <string name="revanced_hide_self_sponsor_ads_summary_off">Паказваюцца ўласныя карты</string>
<string name="revanced_hide_products_banner_title">Схаваць банер для прагляду прадуктаў</string> <string name="revanced_hide_products_banner_title">Схаваць банер «Паглядзець прадукты»</string>
<string name="revanced_hide_products_banner_summary_on">Банэр схаваны</string> <string name="revanced_hide_products_banner_summary_on">Банэр схаваны</string>
<string name="revanced_hide_products_banner_summary_off">Паказваецца банэр</string> <string name="revanced_hide_products_banner_summary_off">Паказваецца банэр</string>
<string name="revanced_hide_end_screen_store_banner_title">Схаваць банер крамы на канчатковым экране</string> <string name="revanced_hide_end_screen_store_banner_title">Схаваць банер крамы на канчатковым экране</string>
@@ -663,7 +612,7 @@ Second \"item\" text"</string>
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Паказваецца ніжні калонтытул меню якасці відэа</string> <string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Паказваецца ніжні калонтытул меню якасці відэа</string>
</patch> </patch>
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch"> <patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
<string name="revanced_hide_player_previous_next_buttons_title">Схаваць папярэдні &amp; кнопкі наступнага відэа</string> <string name="revanced_hide_player_previous_next_buttons_title">Схаваць папярэднія &amp; кнопкі «Далей»</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Кнопкі схаваныя</string> <string name="revanced_hide_player_previous_next_buttons_summary_on">Кнопкі схаваныя</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Паказваюцца кнопкі</string> <string name="revanced_hide_player_previous_next_buttons_summary_off">Паказваюцца кнопкі</string>
<string name="revanced_hide_cast_button_title">Схаваць кнопку «Трансляцыя»</string> <string name="revanced_hide_cast_button_title">Схаваць кнопку «Трансляцыя»</string>
@@ -856,7 +805,6 @@ Second \"item\" text"</string>
<string name="revanced_ryd_enable_summary_on">Дызлайкі паказаны</string> <string name="revanced_ryd_enable_summary_on">Дызлайкі паказаны</string>
<string name="revanced_ryd_enable_summary_off">Дызлайкі не паказваюцца</string> <string name="revanced_ryd_enable_summary_off">Дызлайкі не паказваюцца</string>
<string name="revanced_ryd_shorts_title">Паказвайце \"не падабаецца\" на Shorts</string> <string name="revanced_ryd_shorts_title">Паказвайце \"не падабаецца\" на Shorts</string>
<string name="revanced_ryd_shorts_summary_on">Дызлайкі на Shorts паказаныя</string>
<string name="revanced_ryd_shorts_summary_on_disclaimer">"Дызлайкі на Shorts паказаныя <string name="revanced_ryd_shorts_summary_on_disclaimer">"Дызлайкі на Shorts паказаныя
Абмежаванне: дызлайкі могуць не адлюстроўвацца ў рэжыме інкогніта"</string> Абмежаванне: дызлайкі могуць не адлюстроўвацца ў рэжыме інкогніта"</string>
@@ -1055,6 +1003,8 @@ Second \"item\" text"</string>
<string name="revanced_sb_vote_downvote">Галасаваць супраць</string> <string name="revanced_sb_vote_downvote">Галасаваць супраць</string>
<string name="revanced_sb_vote_category">Змяніць катэгорыю</string> <string name="revanced_sb_vote_category">Змяніць катэгорыю</string>
<string name="revanced_sb_vote_no_segments">Няма сегментаў для галасавання</string> <string name="revanced_sb_vote_no_segments">Няма сегментаў для галасавання</string>
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<string name="revanced_sb_vote_segment_time_to_from">%1$s да %2$s</string>
<string name="revanced_sb_new_segment_choose_category">Выберыце катэгорыю сегмента</string> <string name="revanced_sb_new_segment_choose_category">Выберыце катэгорыю сегмента</string>
<string name="revanced_sb_new_segment_disabled_category">Катэгорыя адключана ў наладах. Уключыце катэгорыю для адпраўкі.</string> <string name="revanced_sb_new_segment_disabled_category">Катэгорыя адключана ў наладах. Уключыце катэгорыю для адпраўкі.</string>
<string name="revanced_sb_new_segment_title">Новы сегмент SponsorBlock</string> <string name="revanced_sb_new_segment_title">Новы сегмент SponsorBlock</string>
@@ -1102,6 +1052,7 @@ Second \"item\" text"</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_dot_label">колер:</string> <string name="revanced_sb_color_dot_label">колер:</string>
<string name="revanced_sb_color_changed">Колер змяніўся</string> <string name="revanced_sb_color_changed">Колер змяніўся</string>
<string name="revanced_sb_color_reset">Скід колеру</string> <string name="revanced_sb_color_reset">Скід колеру</string>
@@ -1119,13 +1070,11 @@ Second \"item\" text"</string>
<string name="revanced_change_form_factor_entry_4">Аўтамабільны</string> <string name="revanced_change_form_factor_entry_4">Аўтамабільны</string>
<string name="revanced_change_form_factor_user_dialog_message">"Змены ўключаюць: <string name="revanced_change_form_factor_user_dialog_message">"Змены ўключаюць:
Раскладка планшэта Макет для планшэта
• Паведамленні супольнасці схаваны • Паведамленні супольнасці схаваныя
Раскладка аўтамабіля Аўтамабільны макет
Меню гісторыі праглядаў схавана Shorts адкрываюцца ў звычайным плэеры
• Адноўлена ўкладка «Даследаваць»
• Ролікі Shorts адкрываюцца ў звычайным прайгравальніку
• Стужка арганізавана па тэмах і каналах"</string> • Стужка арганізавана па тэмах і каналах"</string>
</patch> </patch>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
@@ -1141,12 +1090,7 @@ Second \"item\" text"</string>
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<string name="revanced_spoof_app_version_target_title">Падробка мэтавай версіі праграмы</string> <string name="revanced_spoof_app_version_target_title">Падробка мэтавай версіі праграмы</string>
<string name="revanced_spoof_app_version_target_entry_1">19.35.36 — Восстановить старые значки плеера Shorts</string> <string name="revanced_spoof_app_version_target_entry_1">19.35.36 — Восстановить старые значки плеера Shorts</string>
<string name="revanced_spoof_app_version_target_entry_2">19.26.42 - Аднаўленне старых значкоў навігацыі</string> <string name="revanced_spoof_app_version_target_entry_2">19.01.34 - Аднаўленне старых значкоў навігацыі</string>
<!-- 'RYD' is 'Return YouTube Dislike' -->
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - Аднаўленне RYD на Shorts у рэжыме інкогніта</string>
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Аднавіць хуткасць шырокага відэа &amp; якаснае меню</string>
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - Аднаўленне ўкладкі бібліятэкі</string>
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - Аднаўленне старой паліцы плэйлістоў</string>
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
<string name="revanced_change_start_page_title">Усталяваць стартавую старонку</string> <string name="revanced_change_start_page_title">Усталяваць стартавую старонку</string>
@@ -1196,7 +1140,7 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="layout.miniplayer.miniplayerPatch"> <patch id="layout.miniplayer.miniplayerPatch">
<string name="revanced_miniplayer_screen_title">Міні-плэер</string> <string name="revanced_miniplayer_screen_title">Міні-плэер</string>
<string name="revanced_miniplayer_screen_summary">Змяніце стыль мінімізаванага плэера ў праграме</string> <string name="revanced_miniplayer_screen_summary">Змяніць стыль згорнутага прайгравальніка ў праграме</string>
<string name="revanced_miniplayer_type_title">Тып мініплэера</string> <string name="revanced_miniplayer_type_title">Тып мініплэера</string>
<string name="revanced_miniplayer_type_entry_0">Інваліды</string> <string name="revanced_miniplayer_type_entry_0">Інваліды</string>
<string name="revanced_miniplayer_type_entry_1">Па змаўчанні</string> <string name="revanced_miniplayer_type_entry_1">Па змаўчанні</string>
@@ -1249,8 +1193,6 @@ Second \"item\" text"</string>
<string name="revanced_gradient_loading_screen_title">Уключыць градыентны экран загрузкі</string> <string name="revanced_gradient_loading_screen_title">Уключыць градыентны экран загрузкі</string>
<string name="revanced_gradient_loading_screen_summary_on">Экран загрузкі будзе мець градыентны фон</string> <string name="revanced_gradient_loading_screen_summary_on">Экран загрузкі будзе мець градыентны фон</string>
<string name="revanced_gradient_loading_screen_summary_off">Экран загрузкі будзе мець суцэльны фон</string> <string name="revanced_gradient_loading_screen_summary_off">Экран загрузкі будзе мець суцэльны фон</string>
</patch>
<patch id="layout.theme.themeResourcePatch">
<string name="revanced_seekbar_custom_color_title">Уключыць уласны колер панэлі пошуку</string> <string name="revanced_seekbar_custom_color_title">Уключыць уласны колер панэлі пошуку</string>
<string name="revanced_seekbar_custom_color_summary_on">Паказваецца карыстальніцкі колер панэлі пошуку</string> <string name="revanced_seekbar_custom_color_summary_on">Паказваецца карыстальніцкі колер панэлі пошуку</string>
<string name="revanced_seekbar_custom_color_summary_off">Паказаны зыходны колер панэлі пошуку</string> <string name="revanced_seekbar_custom_color_summary_off">Паказаны зыходны колер панэлі пошуку</string>
@@ -1342,8 +1284,8 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="misc.links.openLinksExternallyPatch"> <patch id="misc.links.openLinksExternallyPatch">
<string name="revanced_external_browser_title">Адкрываць спасылкі ў браўзеры</string> <string name="revanced_external_browser_title">Адкрываць спасылкі ў браўзеры</string>
<string name="revanced_external_browser_summary_on">Адкрыццё спасылак звонку</string> <string name="revanced_external_browser_summary_on">Адкрыццё спасылак у знешнім браўзеры</string>
<string name="revanced_external_browser_summary_off">Адкрыццё спасылак у праграме</string> <string name="revanced_external_browser_summary_off">Адкрыццё спасылак ва ўбудаваным браўзеры</string>
</patch> </patch>
<patch id="misc.privacy.removeTrackingQueryParameterPatch"> <patch id="misc.privacy.removeTrackingQueryParameterPatch">
<string name="revanced_remove_tracking_query_parameter_title">Выдаліць параметр запыту адсочвання</string> <string name="revanced_remove_tracking_query_parameter_title">Выдаліць параметр запыту адсочвання</string>
@@ -1370,9 +1312,15 @@ Second \"item\" text"</string>
<string name="revanced_remember_video_quality_last_selected_summary_off">Змены якасці прымяняюцца толькі да бягучага відэа</string> <string name="revanced_remember_video_quality_last_selected_summary_off">Змены якасці прымяняюцца толькі да бягучага відэа</string>
<string name="revanced_video_quality_default_wifi_title">Стандартная якасць відэа ў сетцы Wi-Fi</string> <string name="revanced_video_quality_default_wifi_title">Стандартная якасць відэа ў сетцы Wi-Fi</string>
<string name="revanced_video_quality_default_mobile_title">Стандартная якасць відэа ў мабільнай сетцы</string> <string name="revanced_video_quality_default_mobile_title">Стандартная якасць відэа ў мабільнай сетцы</string>
<string name="revanced_remember_shorts_quality_last_selected_title">Запомніць змены якасці Shorts</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_on">Змены якасці прымяняюцца да ўсіх Shorts</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_off">Змены якасці прымяняюцца толькі да бягучага Short</string>
<string name="revanced_shorts_quality_default_wifi_title">Якасць Shorts па змаўчанні ў сетцы Wi-Fi</string>
<string name="revanced_shorts_quality_default_mobile_title">Якасць Shorts па змаўчанні ў мабільнай сетцы</string>
<string name="revanced_remember_video_quality_mobile">мабільны</string> <string name="revanced_remember_video_quality_mobile">мабільны</string>
<string name="revanced_remember_video_quality_wifi">wi-fi</string> <string name="revanced_remember_video_quality_wifi">wi-fi</string>
<string name="revanced_remember_video_quality_toast">Стандартная якасць %1$s зменена на: %2$s</string> <string name="revanced_remember_video_quality_toast">Стандартная якасць %1$s зменена на: %2$s</string>
<string name="revanced_remember_video_quality_toast_shorts">Якасць Shorts %1$s зменена на: %2$s</string>
</patch> </patch>
<patch id="video.speed.button.playbackSpeedButtonPatch"> <patch id="video.speed.button.playbackSpeedButtonPatch">
<string name="revanced_playback_speed_dialog_button_title">Паказаць дыялогавую кнопку хуткасці</string> <string name="revanced_playback_speed_dialog_button_title">Паказаць дыялогавую кнопку хуткасці</string>
@@ -1403,10 +1351,10 @@ Second \"item\" text"</string>
<string name="revanced_disable_hdr_video_summary_on">Відэа ў фармаце HDR адключана</string> <string name="revanced_disable_hdr_video_summary_on">Відэа ў фармаце HDR адключана</string>
<string name="revanced_disable_hdr_video_summary_off">Відэа ў фармаце HDR уключана</string> <string name="revanced_disable_hdr_video_summary_off">Відэа ў фармаце HDR уключана</string>
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
<string name="revanced_restore_old_video_quality_menu_title">Аднавіць старое меню якасці відэа</string> <string name="revanced_advanced_video_quality_menu_title">Паказаць пашыранае меню якасці відэа</string>
<string name="revanced_restore_old_video_quality_menu_summary_on">Паказана старое меню якасці відэа</string> <string name="revanced_advanced_video_quality_menu_summary_on">Пашыранае меню якасці відэа паказана</string>
<string name="revanced_restore_old_video_quality_menu_summary_off">Старое меню якасці відэа не паказваецца</string> <string name="revanced_advanced_video_quality_menu_summary_off">Пашыранае меню якасці відэа не паказана</string>
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
<string name="revanced_slide_to_seek_title">Уключыць слайд для пошуку</string> <string name="revanced_slide_to_seek_title">Уключыць слайд для пошуку</string>

View File

@@ -48,57 +48,6 @@ Second \"item\" text"</string>
За да преведете нови езици, посетете translate.revanced.app"</string> За да преведете нови езици, посетете translate.revanced.app"</string>
<string name="revanced_language_DEFAULT">Език на приложението</string> <string name="revanced_language_DEFAULT">Език на приложението</string>
<string name="revanced_language_AR">арабски</string>
<string name="revanced_language_AZ">Азербайджански</string>
<string name="revanced_language_BG">български</string>
<string name="revanced_language_BN">бенгалски</string>
<string name="revanced_language_CA">каталонски</string>
<string name="revanced_language_CS">Чешки</string>
<string name="revanced_language_DA">Датски</string>
<string name="revanced_language_DE">Немски</string>
<string name="revanced_language_EL">Гръцки</string>
<string name="revanced_language_EN">Английски</string>
<string name="revanced_language_ES">Испански</string>
<string name="revanced_language_ET">Естонски</string>
<string name="revanced_language_FA">Персийски</string>
<string name="revanced_language_FI">Финландски</string>
<string name="revanced_language_FR">Френски</string>
<string name="revanced_language_GU">Гуджарати</string>
<string name="revanced_language_HI">Хинди</string>
<string name="revanced_language_HR">Хърватски</string>
<string name="revanced_language_HU">Унгарски</string>
<string name="revanced_language_ID">Индонезийски</string>
<string name="revanced_language_IT">Италиански</string>
<string name="revanced_language_JA">Японски</string>
<string name="revanced_language_KK">Казахски</string>
<string name="revanced_language_KO">Корейски</string>
<string name="revanced_language_LT">Литовски</string>
<string name="revanced_language_LV">Латвийски</string>
<string name="revanced_language_MK">Македонски</string>
<string name="revanced_language_MN">Монголски</string>
<string name="revanced_language_MR">Маратхи</string>
<string name="revanced_language_MS">Малайски</string>
<string name="revanced_language_MY">Бирмански</string>
<string name="revanced_language_NL">Холандски</string>
<string name="revanced_language_OR">Одия</string>
<string name="revanced_language_PA">Пенджаби</string>
<string name="revanced_language_PL">Полски</string>
<string name="revanced_language_PT">Португалски</string>
<string name="revanced_language_RO">Румънски</string>
<string name="revanced_language_RU">Руски</string>
<string name="revanced_language_SK">Словашки</string>
<string name="revanced_language_SL">Словенски</string>
<string name="revanced_language_SR">Сръбски</string>
<string name="revanced_language_SV">Шведски</string>
<string name="revanced_language_SW">Суахили</string>
<string name="revanced_language_TA">Тамилски</string>
<string name="revanced_language_TE">Телугу</string>
<string name="revanced_language_TH">Тайландски</string>
<string name="revanced_language_TR">Турски</string>
<string name="revanced_language_UK">Украински</string>
<string name="revanced_language_UR">Урду</string>
<string name="revanced_language_VI">Виетнамски</string>
<string name="revanced_language_ZH">Китайски</string>
<string name="revanced_pref_import_export_title">Импортиране / Експортиране</string> <string name="revanced_pref_import_export_title">Импортиране / Експортиране</string>
<string name="revanced_pref_import_export_summary">Импортиране / Експортиране на ReVanced настройките</string> <string name="revanced_pref_import_export_summary">Импортиране / Експортиране на ReVanced настройките</string>
<!-- Settings about dialog. --> <!-- Settings about dialog. -->
@@ -301,13 +250,13 @@ Second \"item\" text"</string>
<string name="revanced_hide_description_components_screen_title">Описание на видеото</string> <string name="revanced_hide_description_components_screen_title">Описание на видеото</string>
<string name="revanced_hide_description_components_screen_summary">Скриване или показване на компонентите за описание на видеоклиповете</string> <string name="revanced_hide_description_components_screen_summary">Скриване или показване на компонентите за описание на видеоклиповете</string>
<string name="revanced_hide_filter_bar_screen_title">Лента с филтри</string> <string name="revanced_hide_filter_bar_screen_title">Лента с филтри</string>
<string name="revanced_hide_filter_bar_screen_summary">Скриване или показване на лентата с категории в емисията, резултатите от търсенето и свързаните видеоклипове</string> <string name="revanced_hide_filter_bar_screen_summary">Скриване или показване на лентата за филтриране в емисията, резултатите от търсенето и свързаните видеоклипове</string>
<string name="revanced_hide_filter_bar_feed_in_feed_title">Скриване на горната лента с категории в емисията</string> <string name="revanced_hide_filter_bar_feed_in_feed_title">Скриване на горната лента с категории в емисията</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Скрита</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Скрита</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Показва се</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Показва се</string>
<string name="revanced_hide_filter_bar_feed_in_search_title">Филтъри на търсене</string> <string name="revanced_hide_filter_bar_feed_in_search_title">Скриване в резултатите от търсенето</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_on">Панелът с филтъри на търсене е скрит</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_on">Скрито в резултатите от търсенето</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_off">Панелът с филтъри на търсене се показва</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_off">Показано в резултатите от търсенето</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">Скриване в сродни видеоклипове</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_title">Скриване в сродни видеоклипове</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Скриване в сродни видеоклипове</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Скриване в сродни видеоклипове</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">Показано в сродни видеоклипове</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">Показано в сродни видеоклипове</string>
@@ -404,7 +353,7 @@ Second \"item\" text"</string>
<string name="revanced_hide_self_sponsor_ads_title">Скриване на самоспонсорирани карти</string> <string name="revanced_hide_self_sponsor_ads_title">Скриване на самоспонсорирани карти</string>
<string name="revanced_hide_self_sponsor_ads_summary_on">Самоспонсорираните карти са скрити</string> <string name="revanced_hide_self_sponsor_ads_summary_on">Самоспонсорираните карти са скрити</string>
<string name="revanced_hide_self_sponsor_ads_summary_off">Самоспонсорираните карти са показани</string> <string name="revanced_hide_self_sponsor_ads_summary_off">Самоспонсорираните карти са показани</string>
<string name="revanced_hide_products_banner_title">Скриване на банера за показване на продукти</string> <string name="revanced_hide_products_banner_title">Скриване на банера \"Преглед на продукти\"</string>
<string name="revanced_hide_products_banner_summary_on">Банерът е скрит</string> <string name="revanced_hide_products_banner_summary_on">Банерът е скрит</string>
<string name="revanced_hide_products_banner_summary_off">Банерът е показан</string> <string name="revanced_hide_products_banner_summary_off">Банерът е показан</string>
<string name="revanced_hide_end_screen_store_banner_title">Скрий банера за реклама в края на екрана</string> <string name="revanced_hide_end_screen_store_banner_title">Скрий банера за реклама в края на екрана</string>
@@ -663,7 +612,7 @@ Second \"item\" text"</string>
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Долният колонтитул на менюто за качество на видеото се показва</string> <string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Долният колонтитул на менюто за качество на видеото се показва</string>
</patch> </patch>
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch"> <patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
<string name="revanced_hide_player_previous_next_buttons_title">Бутони за Предишно &amp; Следващо видео</string> <string name="revanced_hide_player_previous_next_buttons_title">Скриване на бутоните \"Предишен и Следващ\"</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Бутоните са скрити</string> <string name="revanced_hide_player_previous_next_buttons_summary_on">Бутоните са скрити</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Бутоните се показват</string> <string name="revanced_hide_player_previous_next_buttons_summary_off">Бутоните се показват</string>
<string name="revanced_hide_cast_button_title">Скриване на бутона Cast</string> <string name="revanced_hide_cast_button_title">Скриване на бутона Cast</string>
@@ -856,7 +805,6 @@ Second \"item\" text"</string>
<string name="revanced_ryd_enable_summary_on">Нехаресванията се показват</string> <string name="revanced_ryd_enable_summary_on">Нехаресванията се показват</string>
<string name="revanced_ryd_enable_summary_off">Нехаресванията не се показват</string> <string name="revanced_ryd_enable_summary_off">Нехаресванията не се показват</string>
<string name="revanced_ryd_shorts_title">Пок. нехаресвания в кратките клипове</string> <string name="revanced_ryd_shorts_title">Пок. нехаресвания в кратките клипове</string>
<string name="revanced_ryd_shorts_summary_on">Нехаресванията на Shorts са показани</string>
<string name="revanced_ryd_shorts_summary_on_disclaimer">"Нехаресванията на Shorts са показани <string name="revanced_ryd_shorts_summary_on_disclaimer">"Нехаресванията на Shorts са показани
Ограничение: Нехаресванията може да не се показват в режим инкогнито"</string> Ограничение: Нехаресванията може да не се показват в режим инкогнито"</string>
@@ -1054,6 +1002,8 @@ Second \"item\" text"</string>
<string name="revanced_sb_vote_downvote">Отрицателен вот</string> <string name="revanced_sb_vote_downvote">Отрицателен вот</string>
<string name="revanced_sb_vote_category">Промяна на категорията</string> <string name="revanced_sb_vote_category">Промяна на категорията</string>
<string name="revanced_sb_vote_no_segments">Няма сегменти, за които да гласувате</string> <string name="revanced_sb_vote_no_segments">Няма сегменти, за които да гласувате</string>
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<string name="revanced_sb_vote_segment_time_to_from">%1$s до %2$s</string>
<string name="revanced_sb_new_segment_choose_category">Изберете категория сегмент</string> <string name="revanced_sb_new_segment_choose_category">Изберете категория сегмент</string>
<string name="revanced_sb_new_segment_disabled_category">Категорията е изкл. в настройките. Вкл. я за да можете да изпратите.</string> <string name="revanced_sb_new_segment_disabled_category">Категорията е изкл. в настройките. Вкл. я за да можете да изпратите.</string>
<string name="revanced_sb_new_segment_title">Нова част в SponsorBlock</string> <string name="revanced_sb_new_segment_title">Нова част в SponsorBlock</string>
@@ -1101,6 +1051,7 @@ Second \"item\" text"</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_dot_label">Цвят:</string> <string name="revanced_sb_color_dot_label">Цвят:</string>
<string name="revanced_sb_color_changed">Цветът е променен</string> <string name="revanced_sb_color_changed">Цветът е променен</string>
<string name="revanced_sb_color_reset">Възстанови цвета</string> <string name="revanced_sb_color_reset">Възстанови цвета</string>
@@ -1121,11 +1072,9 @@ Second \"item\" text"</string>
Оформление за таблет Оформление за таблет
• Публикациите на общността са скрити • Публикациите на общността са скрити
Оформление за автомобил Автомобилно оформление
• Менюто „История на гледане“ е скрито
• Разделът „Разгледай“ е възстановен
• Shorts се отварят в обикновения плейър • Shorts се отварят в обикновения плейър
Лентата е организирана по теми и канал"</string> Каналът е организиран по теми и канали"</string>
</patch> </patch>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<string name="revanced_spoof_app_version_title">Подлъгване за версията на приложението</string> <string name="revanced_spoof_app_version_title">Подлъгване за версията на приложението</string>
@@ -1140,12 +1089,7 @@ Second \"item\" text"</string>
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<string name="revanced_spoof_app_version_target_title">Подлъгване за версията на</string> <string name="revanced_spoof_app_version_target_title">Подлъгване за версията на</string>
<string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Възстановете старите икони на Shorts в плейъра</string> <string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Възстановете старите икони на Shorts в плейъра</string>
<string name="revanced_spoof_app_version_target_entry_2">19.26.42 - Възстановяване на старите икони за навигация</string> <string name="revanced_spoof_app_version_target_entry_2">19.01.34 - Възстановяване на старите икони за навигация</string>
<!-- 'RYD' is 'Return YouTube Dislike' -->
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - Възстановете RYD в режим „инкогнито“ на Shorts</string>
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Възстановяване на видео скорост &amp; в менюто за качество</string>
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - Възстановяване на таб \"Библиотека\"</string>
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - Връщане на секцията с плейлиста към стария стил</string>
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
<string name="revanced_change_start_page_title">Задай начална страница</string> <string name="revanced_change_start_page_title">Задай начална страница</string>
@@ -1195,7 +1139,7 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="layout.miniplayer.miniplayerPatch"> <patch id="layout.miniplayer.miniplayerPatch">
<string name="revanced_miniplayer_screen_title">Минимизиран екран за възпроизвеждане</string> <string name="revanced_miniplayer_screen_title">Минимизиран екран за възпроизвеждане</string>
<string name="revanced_miniplayer_screen_summary">Променете стила на минимизирания екран за възпроизвеждане</string> <string name="revanced_miniplayer_screen_summary">Промяна на стила на минимизиран плейър в приложението</string>
<string name="revanced_miniplayer_type_title">Минимизиран тип екран за гледане</string> <string name="revanced_miniplayer_type_title">Минимизиран тип екран за гледане</string>
<string name="revanced_miniplayer_type_entry_0">Деактивирано</string> <string name="revanced_miniplayer_type_entry_0">Деактивирано</string>
<string name="revanced_miniplayer_type_entry_1">По подразбиране</string> <string name="revanced_miniplayer_type_entry_1">По подразбиране</string>
@@ -1248,8 +1192,6 @@ Second \"item\" text"</string>
<string name="revanced_gradient_loading_screen_title">Фон на екрана при зареждане на видео</string> <string name="revanced_gradient_loading_screen_title">Фон на екрана при зареждане на видео</string>
<string name="revanced_gradient_loading_screen_summary_on">Екранът за зареждане ще има градиентен фон</string> <string name="revanced_gradient_loading_screen_summary_on">Екранът за зареждане ще има градиентен фон</string>
<string name="revanced_gradient_loading_screen_summary_off">Екранът за зареждане ще има плътен фон</string> <string name="revanced_gradient_loading_screen_summary_off">Екранът за зареждане ще има плътен фон</string>
</patch>
<patch id="layout.theme.themeResourcePatch">
<string name="revanced_seekbar_custom_color_title">Промяна на цвета на индикатора за време</string> <string name="revanced_seekbar_custom_color_title">Промяна на цвета на индикатора за време</string>
<string name="revanced_seekbar_custom_color_summary_on">Показва се персонализиран цвят на лентата за напредък</string> <string name="revanced_seekbar_custom_color_summary_on">Показва се персонализиран цвят на лентата за напредък</string>
<string name="revanced_seekbar_custom_color_summary_off">Показва се оригиналния цвят на лентата за напредък</string> <string name="revanced_seekbar_custom_color_summary_off">Показва се оригиналния цвят на лентата за напредък</string>
@@ -1341,8 +1283,8 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="misc.links.openLinksExternallyPatch"> <patch id="misc.links.openLinksExternallyPatch">
<string name="revanced_external_browser_title">Отваряне на връзки в браузъра</string> <string name="revanced_external_browser_title">Отваряне на връзки в браузъра</string>
<string name="revanced_external_browser_summary_on">Отваряне на външни връзки</string> <string name="revanced_external_browser_summary_on">Отваряне на връзки във външен браузър</string>
<string name="revanced_external_browser_summary_off">Отваряне на връзки в приложението</string> <string name="revanced_external_browser_summary_off">Отваряне на връзки във вграден браузър</string>
</patch> </patch>
<patch id="misc.privacy.removeTrackingQueryParameterPatch"> <patch id="misc.privacy.removeTrackingQueryParameterPatch">
<string name="revanced_remove_tracking_query_parameter_title">Премахнете параметъра на заявката за проследяване</string> <string name="revanced_remove_tracking_query_parameter_title">Премахнете параметъра на заявката за проследяване</string>
@@ -1369,9 +1311,15 @@ Second \"item\" text"</string>
<string name="revanced_remember_video_quality_last_selected_summary_off">Промените в качеството се отнасят само за текущия видеоклип</string> <string name="revanced_remember_video_quality_last_selected_summary_off">Промените в качеството се отнасят само за текущия видеоклип</string>
<string name="revanced_video_quality_default_wifi_title">Предпочитано качество при Wi-Fi</string> <string name="revanced_video_quality_default_wifi_title">Предпочитано качество при Wi-Fi</string>
<string name="revanced_video_quality_default_mobile_title">Предпочитано качество при мобилни данни</string> <string name="revanced_video_quality_default_mobile_title">Предпочитано качество при мобилни данни</string>
<string name="revanced_remember_shorts_quality_last_selected_title">Запомняне на промените в качеството на Shorts</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_on">Промените в качеството се прилагат за всички Shorts</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_off">Промените в качеството се прилагат само за текущия Short</string>
<string name="revanced_shorts_quality_default_wifi_title">Качество по подразбиране на Shorts във Wi-Fi мрежа</string>
<string name="revanced_shorts_quality_default_mobile_title">Качество по подразбиране на Shorts в мобилна мрежа</string>
<string name="revanced_remember_video_quality_mobile">мобилни данни</string> <string name="revanced_remember_video_quality_mobile">мобилни данни</string>
<string name="revanced_remember_video_quality_wifi">wi-fi</string> <string name="revanced_remember_video_quality_wifi">wi-fi</string>
<string name="revanced_remember_video_quality_toast">Променено стандартно %1$s качество на: %2$s</string> <string name="revanced_remember_video_quality_toast">Променено стандартно %1$s качество на: %2$s</string>
<string name="revanced_remember_video_quality_toast_shorts">Променено качество на Shorts %1$s на: %2$s</string>
</patch> </patch>
<patch id="video.speed.button.playbackSpeedButtonPatch"> <patch id="video.speed.button.playbackSpeedButtonPatch">
<string name="revanced_playback_speed_dialog_button_title">Показване бутон за скорост</string> <string name="revanced_playback_speed_dialog_button_title">Показване бутон за скорост</string>
@@ -1402,10 +1350,10 @@ Second \"item\" text"</string>
<string name="revanced_disable_hdr_video_summary_on">HDR видеото е деактивирано</string> <string name="revanced_disable_hdr_video_summary_on">HDR видеото е деактивирано</string>
<string name="revanced_disable_hdr_video_summary_off">HDR видеото е активирано</string> <string name="revanced_disable_hdr_video_summary_off">HDR видеото е активирано</string>
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
<string name="revanced_restore_old_video_quality_menu_title">Възстановете старото меню за качество на видеото</string> <string name="revanced_advanced_video_quality_menu_title">Показване на менюто за разширено качество на видеото</string>
<string name="revanced_restore_old_video_quality_menu_summary_on">Показва се старото меню за видео качество</string> <string name="revanced_advanced_video_quality_menu_summary_on">Показва се менюто за разширено качество на видеото</string>
<string name="revanced_restore_old_video_quality_menu_summary_off">Старото меню за видео качество е скрито</string> <string name="revanced_advanced_video_quality_menu_summary_off">Менюто за разширено качество на видеото не се показва</string>
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
<string name="revanced_slide_to_seek_title">Активиране на слайд за превъртане</string> <string name="revanced_slide_to_seek_title">Активиране на слайд за превъртане</string>

View File

@@ -48,57 +48,6 @@ Second \"item\" text"</string>
নতুন ভাষা অনুবাদ করতে translate.revanced.app দেখুন"</string> নতুন ভাষা অনুবাদ করতে translate.revanced.app দেখুন"</string>
<string name="revanced_language_DEFAULT">অ্যাপ্লিকেশনের ভাষা</string> <string name="revanced_language_DEFAULT">অ্যাপ্লিকেশনের ভাষা</string>
<string name="revanced_language_AR">আরবি</string>
<string name="revanced_language_AZ">আজারবাইজানি</string>
<string name="revanced_language_BG">বুলগেরিয়ান</string>
<string name="revanced_language_BN">বাংলা</string>
<string name="revanced_language_CA">কাতালান</string>
<string name="revanced_language_CS">চেক</string>
<string name="revanced_language_DA">ড্যানিশ</string>
<string name="revanced_language_DE">জার্মান</string>
<string name="revanced_language_EL">গ্রিক</string>
<string name="revanced_language_EN">ইংরেজি</string>
<string name="revanced_language_ES">স্প্যানিশ</string>
<string name="revanced_language_ET">এস্তোনিয়ান</string>
<string name="revanced_language_FA">ফার্সি</string>
<string name="revanced_language_FI">ফিনিশ</string>
<string name="revanced_language_FR">ফরাসি</string>
<string name="revanced_language_GU">গুজরাটি</string>
<string name="revanced_language_HI">হিন্দি</string>
<string name="revanced_language_HR">ক্রোয়েশীয়</string>
<string name="revanced_language_HU">হাঙ্গেরিয়ান</string>
<string name="revanced_language_ID">ইন্দোনেশিয়ান</string>
<string name="revanced_language_IT">ইতালীয়</string>
<string name="revanced_language_JA">জাপানি</string>
<string name="revanced_language_KK">কাজাখ</string>
<string name="revanced_language_KO">কোরিয়ান</string>
<string name="revanced_language_LT">লিথুয়ানিয়ান</string>
<string name="revanced_language_LV">লাতভিয়ান</string>
<string name="revanced_language_MK">ম্যাসেডোনিয়ান</string>
<string name="revanced_language_MN">মঙ্গোলীয়</string>
<string name="revanced_language_MR">মারাঠি</string>
<string name="revanced_language_MS">মালয়</string>
<string name="revanced_language_MY">বর্মি</string>
<string name="revanced_language_NL">ডাচ</string>
<string name="revanced_language_OR">ওড়িয়া</string>
<string name="revanced_language_PA">পাঞ্জাবি</string>
<string name="revanced_language_PL">পোলিশ</string>
<string name="revanced_language_PT">পর্তুগিজ</string>
<string name="revanced_language_RO">রোমানীয়</string>
<string name="revanced_language_RU">রুশ</string>
<string name="revanced_language_SK">স্লোভাক</string>
<string name="revanced_language_SL">স্লোভেন</string>
<string name="revanced_language_SR">সার্বিয়ান</string>
<string name="revanced_language_SV">সুইডিশ</string>
<string name="revanced_language_SW">সোয়াহিলি</string>
<string name="revanced_language_TA">তামিল</string>
<string name="revanced_language_TE">তেলুগু</string>
<string name="revanced_language_TH">থাই</string>
<string name="revanced_language_TR">তুর্কি</string>
<string name="revanced_language_UK">ইউক্রেনীয়</string>
<string name="revanced_language_UR">উর্দু</string>
<string name="revanced_language_VI">ভিয়েতনামী</string>
<string name="revanced_language_ZH">চাইনিজ</string>
<string name="revanced_pref_import_export_title">আমদানি এবং রপ্তানি</string> <string name="revanced_pref_import_export_title">আমদানি এবং রপ্তানি</string>
<string name="revanced_pref_import_export_summary">ReVanced সেটিং আমদানি বা রপ্তানি করুন</string> <string name="revanced_pref_import_export_summary">ReVanced সেটিং আমদানি বা রপ্তানি করুন</string>
<!-- Settings about dialog. --> <!-- Settings about dialog. -->
@@ -301,13 +250,12 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
<string name="revanced_hide_description_components_screen_title">ভিডিওর বিবরণ</string> <string name="revanced_hide_description_components_screen_title">ভিডিওর বিবরণ</string>
<string name="revanced_hide_description_components_screen_summary">ভিডিও বিবরণ এর উপাদান লুকান বা প্রদর্শন করুন</string> <string name="revanced_hide_description_components_screen_summary">ভিডিও বিবরণ এর উপাদান লুকান বা প্রদর্শন করুন</string>
<string name="revanced_hide_filter_bar_screen_title">ফিল্টার বার</string> <string name="revanced_hide_filter_bar_screen_title">ফিল্টার বার</string>
<string name="revanced_hide_filter_bar_screen_summary">ফিড, অনুসন্ধান এবং সম্পর্কিত ভিডিওতে ফিল্টার বার লুকান বা প্রদর্শন করুন</string>
<string name="revanced_hide_filter_bar_feed_in_feed_title">ফিডে লুকান</string> <string name="revanced_hide_filter_bar_feed_in_feed_title">ফিডে লুকান</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_on">ফিডে লুকিয়ে রয়েছে</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_on">ফিডে লুকিয়ে রয়েছে</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_off">ফিডে প্রদর্শিত হয়েছে</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_off">ফিডে প্রদর্শিত হয়েছে</string>
<string name="revanced_hide_filter_bar_feed_in_search_title">অনুসন্ধানে লুকান</string> <string name="revanced_hide_filter_bar_feed_in_search_title">অনুসন্ধান ফলাফলে লুকান</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_on">অনুসন্ধানে লুকিয়ে রয়েছে</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_on">অনুসন্ধান ফলাফলে লুকানো আছে</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_off">অনুসন্ধানে প্রদর্শিত হয়েছে</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_off">অনুসন্ধান ফলাফলে দেখানো হয়েছে</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">সম্পর্কিত ভিডিওতে লুকান</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_title">সম্পর্কিত ভিডিওতে লুকান</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">সম্পর্কিত ভিডিওতে লুকিয়ে রয়েছে</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">সম্পর্কিত ভিডিওতে লুকিয়ে রয়েছে</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">সম্পর্কিত ভিডিওতে প্রদর্শিত হয়েছে</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">সম্পর্কিত ভিডিওতে প্রদর্শিত হয়েছে</string>
@@ -404,7 +352,7 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
<string name="revanced_hide_self_sponsor_ads_title">স্ব-স্পন্সর কার্ড লুকান</string> <string name="revanced_hide_self_sponsor_ads_title">স্ব-স্পন্সর কার্ড লুকান</string>
<string name="revanced_hide_self_sponsor_ads_summary_on">স্ব-স্পন্সর কার্ড লুকিয়ে রয়েছে</string> <string name="revanced_hide_self_sponsor_ads_summary_on">স্ব-স্পন্সর কার্ড লুকিয়ে রয়েছে</string>
<string name="revanced_hide_self_sponsor_ads_summary_off">স্ব-স্পন্সর কার্ড প্রদর্শিত হয়েছে</string> <string name="revanced_hide_self_sponsor_ads_summary_off">স্ব-স্পন্সর কার্ড প্রদর্শিত হয়েছে</string>
<string name="revanced_hide_products_banner_title">প্রোডাক্ট দেখার ব্যানার লুকান</string> <string name="revanced_hide_products_banner_title">\'পণ্য দেখুন\' ব্যানার লুকান</string>
<string name="revanced_hide_products_banner_summary_on">ব্যানার লুকিয়ে রয়েছে</string> <string name="revanced_hide_products_banner_summary_on">ব্যানার লুকিয়ে রয়েছে</string>
<string name="revanced_hide_products_banner_summary_off">ব্যানার প্রদর্শিত হয়েছে</string> <string name="revanced_hide_products_banner_summary_off">ব্যানার প্রদর্শিত হয়েছে</string>
<string name="revanced_hide_end_screen_store_banner_title">শেষ পর্দার স্টোর ব্যানার লুকান</string> <string name="revanced_hide_end_screen_store_banner_title">শেষ পর্দার স্টোর ব্যানার লুকান</string>
@@ -660,7 +608,7 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">ভিডিও গুণমান মেনু ফুটার দেখানো হচ্ছে</string> <string name="revanced_hide_player_flyout_video_quality_footer_summary_off">ভিডিও গুণমান মেনু ফুটার দেখানো হচ্ছে</string>
</patch> </patch>
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch"> <patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
<string name="revanced_hide_player_previous_next_buttons_title">পূর্ববর্তী লুকান &amp; পরবর্তী ভিডিও বোতাম</string> <string name="revanced_hide_player_previous_next_buttons_title">পূর্ববর্তী লুকান &amp; পরবর্তী বোতাম</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">বোতাম লুকানো হয়</string> <string name="revanced_hide_player_previous_next_buttons_summary_on">বোতাম লুকানো হয়</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">বোতাম দেখানো হয়</string> <string name="revanced_hide_player_previous_next_buttons_summary_off">বোতাম দেখানো হয়</string>
<string name="revanced_hide_cast_button_title">কাস্ট বোতামটি লুকান</string> <string name="revanced_hide_cast_button_title">কাস্ট বোতামটি লুকান</string>
@@ -853,7 +801,6 @@ YouTube সেটিংসে অটো প্লে পরিবর্তন
<string name="revanced_ryd_enable_summary_on">অপছন্দগুলো প্রদর্শিত হয়েছে</string> <string name="revanced_ryd_enable_summary_on">অপছন্দগুলো প্রদর্শিত হয়েছে</string>
<string name="revanced_ryd_enable_summary_off">অপছন্দগুলো প্রদর্শিত হয়নি</string> <string name="revanced_ryd_enable_summary_off">অপছন্দগুলো প্রদর্শিত হয়নি</string>
<string name="revanced_ryd_shorts_title">Shorts এ অপছন্দ দেখান</string> <string name="revanced_ryd_shorts_title">Shorts এ অপছন্দ দেখান</string>
<string name="revanced_ryd_shorts_summary_on">Shorts-এ অপছন্দগুলি দেখানো হয়েছে</string>
<string name="revanced_ryd_shorts_summary_on_disclaimer">"Shorts-এ অপছন্দগুলি দেখানো হয়েছে <string name="revanced_ryd_shorts_summary_on_disclaimer">"Shorts-এ অপছন্দগুলি দেখানো হয়েছে
সীমাবদ্ধতা: ছদ্মবেশী মোডে অপছন্দগুলি নাও দেখা যেতে পারে"</string> সীমাবদ্ধতা: ছদ্মবেশী মোডে অপছন্দগুলি নাও দেখা যেতে পারে"</string>
@@ -1050,6 +997,8 @@ YouTube সেটিংসে অটো প্লে পরিবর্তন
<string name="revanced_sb_vote_downvote">ডাউন ভোট</string> <string name="revanced_sb_vote_downvote">ডাউন ভোট</string>
<string name="revanced_sb_vote_category">বিভাগ পরিবর্তন করুন</string> <string name="revanced_sb_vote_category">বিভাগ পরিবর্তন করুন</string>
<string name="revanced_sb_vote_no_segments">ভোট দেয়ার জন্য আর কোন সেগমেন্ট নেই</string> <string name="revanced_sb_vote_no_segments">ভোট দেয়ার জন্য আর কোন সেগমেন্ট নেই</string>
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<string name="revanced_sb_vote_segment_time_to_from">%1$s থেকে %2$s</string>
<string name="revanced_sb_new_segment_choose_category">সেগমেন্টের বিভাগ নির্বাচন করুন</string> <string name="revanced_sb_new_segment_choose_category">সেগমেন্টের বিভাগ নির্বাচন করুন</string>
<string name="revanced_sb_new_segment_disabled_category">সেটিং থেকে বিভাগ নিস্ক্রিয় করা হয়েছে। জমা দিতে বিভাগ সক্রিয় করুন।</string> <string name="revanced_sb_new_segment_disabled_category">সেটিং থেকে বিভাগ নিস্ক্রিয় করা হয়েছে। জমা দিতে বিভাগ সক্রিয় করুন।</string>
<string name="revanced_sb_new_segment_title">নতুন স্পন্সরব্লক সেগমেন্ট</string> <string name="revanced_sb_new_segment_title">নতুন স্পন্সরব্লক সেগমেন্ট</string>
@@ -1098,6 +1047,7 @@ YouTube সেটিংসে অটো প্লে পরিবর্তন
<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_dot_label">রং:</string> <string name="revanced_sb_color_dot_label">রং:</string>
<string name="revanced_sb_color_changed">রং পরিবর্তন করা হয়েছে</string> <string name="revanced_sb_color_changed">রং পরিবর্তন করা হয়েছে</string>
<string name="revanced_sb_color_reset">রং আবার সেট করুন</string> <string name="revanced_sb_color_reset">রং আবার সেট করুন</string>
@@ -1113,16 +1063,14 @@ YouTube সেটিংসে অটো প্লে পরিবর্তন
<string name="revanced_change_form_factor_entry_2">ফোন</string> <string name="revanced_change_form_factor_entry_2">ফোন</string>
<string name="revanced_change_form_factor_entry_3">ট্যাবলেট</string> <string name="revanced_change_form_factor_entry_3">ট্যাবলেট</string>
<string name="revanced_change_form_factor_entry_4">স্বয়ংচালিত</string> <string name="revanced_change_form_factor_entry_4">স্বয়ংচালিত</string>
<string name="revanced_change_form_factor_user_dialog_message">"পরিবর্তনগুলো হল: <string name="revanced_change_form_factor_user_dialog_message">"পরিবর্তনগুলির মধ্যে রয়েছে:
ট্যাবলেট লেআউট ট্যাবলেট লেআউট
• কমিউনিটি পোস্ট গোপন • কমিউনিটি পোস্টগুলি লুকানো আছে
স্বয়ংচালিত লেআউট অটোমোটিভ লেআউট
ঘড়ির ইতিহাস মেনু গোপন Shorts নিয়মিত প্লেয়ারে খোলে
এক্সপ্লোর ট্যাব পুনরুদ্ার করা হয়েছে ফিড বিষয় এবং চ্যানেল দ্ারা সংগঠিত"</string>
• শর্টস নিয়মিত প্লেয়ারে খোলে
• ফিড বিষয় এবং চ্যানেল দ্বারা সংগঠিত হয়"</string>
</patch> </patch>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<string name="revanced_spoof_app_version_title">অ্যাপ সংস্করণ স্পুফ করুন</string> <string name="revanced_spoof_app_version_title">অ্যাপ সংস্করণ স্পুফ করুন</string>
@@ -1137,12 +1085,7 @@ YouTube সেটিংসে অটো প্লে পরিবর্তন
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<string name="revanced_spoof_app_version_target_title">স্পুফ অ্যাপ সংস্করণ লক্ষ্য</string> <string name="revanced_spoof_app_version_target_title">স্পুফ অ্যাপ সংস্করণ লক্ষ্য</string>
<string name="revanced_spoof_app_version_target_entry_1">19.35.36 - পুরনো Shorts প্লেয়ার আইকন পুনরুদ্ধার করুন</string> <string name="revanced_spoof_app_version_target_entry_1">19.35.36 - পুরনো Shorts প্লেয়ার আইকন পুনরুদ্ধার করুন</string>
<string name="revanced_spoof_app_version_target_entry_2">19.26.42 - পুরনো নেভিগেশন আইকন পুনরুদ্ধার করুন</string> <string name="revanced_spoof_app_version_target_entry_2">19.01.34 - পুরনো নেভিগেশন আইকন পুনরুদ্ধার করুন</string>
<!-- 'RYD' is 'Return YouTube Dislike' -->
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - ছদ্মবেশি মোডে RYD পুনরুদ্ধার করে</string>
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - প্রশ্বস্ত ভিডিও স্পিড এবং গুণমান মেনু পুনরুদ্ধার করে</string>
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - লাইব্রেরি ট্যাপ পুনরুদ্ধার করে</string>
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - পুরোনো প্লেলিস্ট শেলফ পুনরুদ্ধার করে</string>
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
<string name="revanced_change_start_page_title">শুরুর পৃষ্ঠা সেট করুন</string> <string name="revanced_change_start_page_title">শুরুর পৃষ্ঠা সেট করুন</string>
@@ -1192,7 +1135,7 @@ YouTube সেটিংসে অটো প্লে পরিবর্তন
</patch> </patch>
<patch id="layout.miniplayer.miniplayerPatch"> <patch id="layout.miniplayer.miniplayerPatch">
<string name="revanced_miniplayer_screen_title">মিনিপ্লেয়ার</string> <string name="revanced_miniplayer_screen_title">মিনিপ্লেয়ার</string>
<string name="revanced_miniplayer_screen_summary">অ্যাপের মধ্যকার মিনিমাইজড প্লেয়ার এর ধরণ পরিবর্তন করুন</string> <string name="revanced_miniplayer_screen_summary">ইন-অ্যাপ মিনিমাইজড প্লেয়ারের শৈলী পরিবর্তন করুন</string>
<string name="revanced_miniplayer_type_title">মিনিপ্লেয়ার ধরণ</string> <string name="revanced_miniplayer_type_title">মিনিপ্লেয়ার ধরণ</string>
<string name="revanced_miniplayer_type_entry_0">নিষ্ক্রিয় হয়েছে</string> <string name="revanced_miniplayer_type_entry_0">নিষ্ক্রিয় হয়েছে</string>
<string name="revanced_miniplayer_type_entry_1">পূর্ব-নির্ধারিত</string> <string name="revanced_miniplayer_type_entry_1">পূর্ব-নির্ধারিত</string>
@@ -1245,8 +1188,6 @@ Miniplayer স্ক্রিন থেকে বামে বা ডানে
<string name="revanced_gradient_loading_screen_title">গ্রেডিয়েন্ট লোডিং স্ক্রিণ সক্রিয় করুন</string> <string name="revanced_gradient_loading_screen_title">গ্রেডিয়েন্ট লোডিং স্ক্রিণ সক্রিয় করুন</string>
<string name="revanced_gradient_loading_screen_summary_on">লোডিং স্ক্রিণে একটি গ্রেডিয়েন্ড ব্যাকগ্রাউন্ড থাকবে</string> <string name="revanced_gradient_loading_screen_summary_on">লোডিং স্ক্রিণে একটি গ্রেডিয়েন্ড ব্যাকগ্রাউন্ড থাকবে</string>
<string name="revanced_gradient_loading_screen_summary_off">লোডিং স্ক্রিণে একটি সলিড ব্যাকগ্রাউন্ড থাকবে</string> <string name="revanced_gradient_loading_screen_summary_off">লোডিং স্ক্রিণে একটি সলিড ব্যাকগ্রাউন্ড থাকবে</string>
</patch>
<patch id="layout.theme.themeResourcePatch">
<string name="revanced_seekbar_custom_color_title">সিকবারে নিজস্ব রং সক্রিয় করুন</string> <string name="revanced_seekbar_custom_color_title">সিকবারে নিজস্ব রং সক্রিয় করুন</string>
<string name="revanced_seekbar_custom_color_summary_on">সিকবারে নিজস্ব রং প্রদর্শিত হয়েছে</string> <string name="revanced_seekbar_custom_color_summary_on">সিকবারে নিজস্ব রং প্রদর্শিত হয়েছে</string>
<string name="revanced_seekbar_custom_color_summary_off">সিকবারে মূল রং প্রদর্শিত হয়েছে</string> <string name="revanced_seekbar_custom_color_summary_off">সিকবারে মূল রং প্রদর্শিত হয়েছে</string>
@@ -1338,8 +1279,8 @@ DeArrow সম্পর্কে আরও জানতে এখানে ট
</patch> </patch>
<patch id="misc.links.openLinksExternallyPatch"> <patch id="misc.links.openLinksExternallyPatch">
<string name="revanced_external_browser_title">লিংক ব্রাউজারে খুলুন</string> <string name="revanced_external_browser_title">লিংক ব্রাউজারে খুলুন</string>
<string name="revanced_external_browser_summary_on">লিংক বাহিরে খুলুন</string> <string name="revanced_external_browser_summary_on">বাহ্যিক ব্রাউজারে লিঙ্ক খোলা হচ্ছে</string>
<string name="revanced_external_browser_summary_off">অ্যাপের মধ্যে লিক খুলছে</string> <string name="revanced_external_browser_summary_off">ইন-অ্যাপ ব্রাউজারে লিঙ্ক খোলা হচ্ছে</string>
</patch> </patch>
<patch id="misc.privacy.removeTrackingQueryParameterPatch"> <patch id="misc.privacy.removeTrackingQueryParameterPatch">
<string name="revanced_remove_tracking_query_parameter_title">ট্র্যাকিং করার প্যারামিটার মুছুন</string> <string name="revanced_remove_tracking_query_parameter_title">ট্র্যাকিং করার প্যারামিটার মুছুন</string>
@@ -1366,9 +1307,15 @@ DeArrow সম্পর্কে আরও জানতে এখানে ট
<string name="revanced_remember_video_quality_last_selected_summary_off">গুণমান পরিবর্তন বর্তমান ভিডিওতে প্রয়োগ করা হয়েছে</string> <string name="revanced_remember_video_quality_last_selected_summary_off">গুণমান পরিবর্তন বর্তমান ভিডিওতে প্রয়োগ করা হয়েছে</string>
<string name="revanced_video_quality_default_wifi_title">ওয়াই-ফাই নেটওয়ার্কে ডিফল্ট ভিডিও গুণমান</string> <string name="revanced_video_quality_default_wifi_title">ওয়াই-ফাই নেটওয়ার্কে ডিফল্ট ভিডিও গুণমান</string>
<string name="revanced_video_quality_default_mobile_title">মোবাইল নেটওয়ার্কে ডিফল্ট ভিডিও গুণমান</string> <string name="revanced_video_quality_default_mobile_title">মোবাইল নেটওয়ার্কে ডিফল্ট ভিডিও গুণমান</string>
<string name="revanced_remember_shorts_quality_last_selected_title">Shorts গুণমান পরিবর্তনের কথা মনে রাখুন</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_on">গুণমানের পরিবর্তনগুলি সমস্ত Shorts-এর জন্য প্রযোজ্য</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_off">গুণমানের পরিবর্তনগুলি শুধুমাত্র বর্তমান Short-এর জন্য প্রযোজ্য</string>
<string name="revanced_shorts_quality_default_wifi_title">Wi-Fi নেটওয়ার্কে ডিফল্ট Shorts গুণমান</string>
<string name="revanced_shorts_quality_default_mobile_title">মোবাইল নেটওয়ার্কে ডিফল্ট Shorts গুণমান</string>
<string name="revanced_remember_video_quality_mobile">মোবাইল</string> <string name="revanced_remember_video_quality_mobile">মোবাইল</string>
<string name="revanced_remember_video_quality_wifi">ওয়াই-ফাই</string> <string name="revanced_remember_video_quality_wifi">ওয়াই-ফাই</string>
<string name="revanced_remember_video_quality_toast">ডিফল্ট %1$s গুণমান পরিবর্তন হচ্ছে: %2$s</string> <string name="revanced_remember_video_quality_toast">ডিফল্ট %1$s গুণমান পরিবর্তন হচ্ছে: %2$s</string>
<string name="revanced_remember_video_quality_toast_shorts">Shorts %1$s এর গুণমান পরিবর্তন করে: %2$s</string>
</patch> </patch>
<patch id="video.speed.button.playbackSpeedButtonPatch"> <patch id="video.speed.button.playbackSpeedButtonPatch">
<string name="revanced_playback_speed_dialog_button_title">স্পিড ডায়ালগ বোতাম দেখান</string> <string name="revanced_playback_speed_dialog_button_title">স্পিড ডায়ালগ বোতাম দেখান</string>
@@ -1399,10 +1346,10 @@ DeArrow সম্পর্কে আরও জানতে এখানে ট
<string name="revanced_disable_hdr_video_summary_on">HDR ভিডিও নিষ্ক্রিয় করা হয়েছে</string> <string name="revanced_disable_hdr_video_summary_on">HDR ভিডিও নিষ্ক্রিয় করা হয়েছে</string>
<string name="revanced_disable_hdr_video_summary_off">HDR ভিডিও সক্রিয় হয়েছে</string> <string name="revanced_disable_hdr_video_summary_off">HDR ভিডিও সক্রিয় হয়েছে</string>
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
<string name="revanced_restore_old_video_quality_menu_title">পুরোনো ভিডিও গুণমান উদ্ধার করু</string> <string name="revanced_advanced_video_quality_menu_title">উন্নত ভিডিও গুণমান মেনু দেখা</string>
<string name="revanced_restore_old_video_quality_menu_summary_on">পুরোনো ভিডিও গুণমান মেনু প্রদর্শিত হয়েছে</string> <string name="revanced_advanced_video_quality_menu_summary_on">উন্নত ভিডিও গুণমান মেনু দেখানো হয়েছে</string>
<string name="revanced_restore_old_video_quality_menu_summary_off">পুরোনো ভিডিও গুণমান মেনু প্রদর্শিত হয়নি</string> <string name="revanced_advanced_video_quality_menu_summary_off">উন্নত ভিডিও গুণমান মেনু দেখানো হয়নি</string>
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
<string name="revanced_slide_to_seek_title">ভিডিওর নির্দিষ্ট অংশে যেতে টানুন সক্রিয় করুন</string> <string name="revanced_slide_to_seek_title">ভিডিওর নির্দিষ্ট অংশে যেতে টানুন সক্রিয় করুন</string>

View File

@@ -156,6 +156,7 @@ Second \"item\" text"</string>
<patch id="layout.sponsorblock.sponsorBlockResourcePatch"> <patch id="layout.sponsorblock.sponsorBlockResourcePatch">
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' --> <!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. --> <!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<!-- Shown in the settings preferences, and translations can be any text length. --> <!-- Shown in the settings preferences, and translations can be any text length. -->
</patch> </patch>
<patch id="layout.formfactor.changeFormFactorPatch"> <patch id="layout.formfactor.changeFormFactorPatch">
@@ -163,7 +164,6 @@ Second \"item\" text"</string>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<!-- It is ideal, but not required, if the text here appears is alphabetically after the text used for 'revanced_spoof_app_version_title'. <!-- It is ideal, but not required, if the text here appears is alphabetically after the text used for 'revanced_spoof_app_version_title'.
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<!-- 'RYD' is 'Return YouTube Dislike' -->
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
</patch> </patch>
@@ -177,8 +177,6 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="layout.theme.themePatch"> <patch id="layout.theme.themePatch">
</patch> </patch>
<patch id="layout.theme.themeResourcePatch">
</patch>
<patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch"> <patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch">
</patch> </patch>
<patch id="layout.thumbnails.alternativeThumbnailsPatch"> <patch id="layout.thumbnails.alternativeThumbnailsPatch">
@@ -219,7 +217,7 @@ Second \"item\" text"</string>
</patch> </patch>
<patch id="video.hdr.disableHdrPatch"> <patch id="video.hdr.disableHdrPatch">
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
</patch> </patch>

View File

@@ -48,57 +48,6 @@ Second \"item\" text"</string>
Per traduir nous idiomes, visiteu translate.revanced.app"</string> Per traduir nous idiomes, visiteu translate.revanced.app"</string>
<string name="revanced_language_DEFAULT">Llengua de l\'aplicació</string> <string name="revanced_language_DEFAULT">Llengua de l\'aplicació</string>
<string name="revanced_language_AR">Àrab</string>
<string name="revanced_language_AZ">Azerbaidjanès</string>
<string name="revanced_language_BG">Búlgaro</string>
<string name="revanced_language_BN">Bengalí</string>
<string name="revanced_language_CA">Català</string>
<string name="revanced_language_CS">Txec</string>
<string name="revanced_language_DA">Danès</string>
<string name="revanced_language_DE">Alemany</string>
<string name="revanced_language_EL">Grec</string>
<string name="revanced_language_EN">Anglès</string>
<string name="revanced_language_ES">Espanyol</string>
<string name="revanced_language_ET">Estonià</string>
<string name="revanced_language_FA">Persa</string>
<string name="revanced_language_FI">Finès</string>
<string name="revanced_language_FR">Francès</string>
<string name="revanced_language_GU">Gujarati</string>
<string name="revanced_language_HI">Hindi</string>
<string name="revanced_language_HR">Croat</string>
<string name="revanced_language_HU">Hongarès</string>
<string name="revanced_language_ID">Indonesi</string>
<string name="revanced_language_IT">Italià</string>
<string name="revanced_language_JA">Japonès</string>
<string name="revanced_language_KK">Kazakhstanès</string>
<string name="revanced_language_KO">Coreà</string>
<string name="revanced_language_LT">Lituà</string>
<string name="revanced_language_LV">Letó</string>
<string name="revanced_language_MK">Macedoni</string>
<string name="revanced_language_MN">Mongol</string>
<string name="revanced_language_MR">Marathi</string>
<string name="revanced_language_MS">Malai</string>
<string name="revanced_language_MY">Birmà</string>
<string name="revanced_language_NL">Neerlandès</string>
<string name="revanced_language_OR">Odia</string>
<string name="revanced_language_PA">Panjabi</string>
<string name="revanced_language_PL">Polonès</string>
<string name="revanced_language_PT">Portuguès</string>
<string name="revanced_language_RO">Romanès</string>
<string name="revanced_language_RU">Rus</string>
<string name="revanced_language_SK">Eslovac</string>
<string name="revanced_language_SL">Eslovè</string>
<string name="revanced_language_SR">Serbi</string>
<string name="revanced_language_SV">Suec</string>
<string name="revanced_language_SW">Suahili</string>
<string name="revanced_language_TA">Tàmil</string>
<string name="revanced_language_TE">Telugu</string>
<string name="revanced_language_TH">Tailandès</string>
<string name="revanced_language_TR">Turc</string>
<string name="revanced_language_UK">Ucraïnès</string>
<string name="revanced_language_UR">Urdu</string>
<string name="revanced_language_VI">Vietnamita</string>
<string name="revanced_language_ZH">Xinès</string>
<string name="revanced_pref_import_export_title">Importa / Exporta</string> <string name="revanced_pref_import_export_title">Importa / Exporta</string>
<string name="revanced_pref_import_export_summary">Importa / Exporta els ajustos de ReVanced</string> <string name="revanced_pref_import_export_summary">Importa / Exporta els ajustos de ReVanced</string>
<!-- Settings about dialog. --> <!-- Settings about dialog. -->
@@ -301,13 +250,13 @@ No se t'informarà de cap esdeveniment inesperat."</string>
<string name="revanced_hide_description_components_screen_title">Descripció del vídeo</string> <string name="revanced_hide_description_components_screen_title">Descripció del vídeo</string>
<string name="revanced_hide_description_components_screen_summary">Amaga o mostra els components de descripció del vídeo</string> <string name="revanced_hide_description_components_screen_summary">Amaga o mostra els components de descripció del vídeo</string>
<string name="revanced_hide_filter_bar_screen_title">Barra de filtre</string> <string name="revanced_hide_filter_bar_screen_title">Barra de filtre</string>
<string name="revanced_hide_filter_bar_screen_summary">Mostra o amaga la barra de filtre al feed, la cerca i els vídeos relacionats</string> <string name="revanced_hide_filter_bar_screen_summary">Amaga o mostra la barra de filtre al canal, als resultats de cerca i als vídeos relacionats</string>
<string name="revanced_hide_filter_bar_feed_in_feed_title">Amaga al feed</string> <string name="revanced_hide_filter_bar_feed_in_feed_title">Amaga al feed</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Amagat al feed</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Amagat al feed</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Es mostra al feed</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Es mostra al feed</string>
<string name="revanced_hide_filter_bar_feed_in_search_title">Amaga a la cerca</string> <string name="revanced_hide_filter_bar_feed_in_search_title">Amaga als resultats de cerca</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_on">Amagat a la cerca</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_on">Amagat als resultats de cerca</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_off">Mostrat a la cerca</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_off">Mostrat als resultats de cerca</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">Amaga els vídeos relacionats</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_title">Amaga els vídeos relacionats</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Amagats als vídeos relacionats</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Amagats als vídeos relacionats</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">Es mostren els vídeos relacionats</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">Es mostren els vídeos relacionats</string>
@@ -404,7 +353,7 @@ Aquesta funció només està disponible per a dispositius antics"</string>
<string name="revanced_hide_self_sponsor_ads_title">Amaga les targetes d\'auto patrocini</string> <string name="revanced_hide_self_sponsor_ads_title">Amaga les targetes d\'auto patrocini</string>
<string name="revanced_hide_self_sponsor_ads_summary_on">Les targetes d\'autopatrocini estan magades</string> <string name="revanced_hide_self_sponsor_ads_summary_on">Les targetes d\'autopatrocini estan magades</string>
<string name="revanced_hide_self_sponsor_ads_summary_off">Es mostren les targetes d\'autopatrocini</string> <string name="revanced_hide_self_sponsor_ads_summary_off">Es mostren les targetes d\'autopatrocini</string>
<string name="revanced_hide_products_banner_title">Amaga el bàner per veure productes</string> <string name="revanced_hide_products_banner_title">Amaga el bàner «Mostra els productes»</string>
<string name="revanced_hide_products_banner_summary_on">La pancarta s\'amaga</string> <string name="revanced_hide_products_banner_summary_on">La pancarta s\'amaga</string>
<string name="revanced_hide_products_banner_summary_off">La pancarta es mostra</string> <string name="revanced_hide_products_banner_summary_off">La pancarta es mostra</string>
<string name="revanced_hide_end_screen_store_banner_title">Amaga el banner de la botiga a la pantalla final</string> <string name="revanced_hide_end_screen_store_banner_title">Amaga el banner de la botiga a la pantalla final</string>
@@ -663,7 +612,7 @@ Si canviar aquesta opció no té cap efecte, prova a canviar al mode d'incògnit
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">La part inferior del menú de qualitat del vídeo es mostra</string> <string name="revanced_hide_player_flyout_video_quality_footer_summary_off">La part inferior del menú de qualitat del vídeo es mostra</string>
</patch> </patch>
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch"> <patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
<string name="revanced_hide_player_previous_next_buttons_title">Amaga els botons de vídeo anteriors i següents</string> <string name="revanced_hide_player_previous_next_buttons_title">Amaga els botons Anterior i següent</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Els botons estan amagats</string> <string name="revanced_hide_player_previous_next_buttons_summary_on">Els botons estan amagats</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Els botons es mostren</string> <string name="revanced_hide_player_previous_next_buttons_summary_off">Els botons es mostren</string>
<string name="revanced_hide_cast_button_title">Amaga el botó Emet</string> <string name="revanced_hide_cast_button_title">Amaga el botó Emet</string>
@@ -856,7 +805,6 @@ Configuració → Reproducció → Reprodueix el vídeo següent automàticament
<string name="revanced_ryd_enable_summary_on">Els \"no m\'agrada\" es mostren</string> <string name="revanced_ryd_enable_summary_on">Els \"no m\'agrada\" es mostren</string>
<string name="revanced_ryd_enable_summary_off">Els \"no m\'agrada\" no es mostren</string> <string name="revanced_ryd_enable_summary_off">Els \"no m\'agrada\" no es mostren</string>
<string name="revanced_ryd_shorts_title">Mostrar \"no m\'agrada\" a Shorts</string> <string name="revanced_ryd_shorts_title">Mostrar \"no m\'agrada\" a Shorts</string>
<string name="revanced_ryd_shorts_summary_on">Els \"no m\'agrada\" als Shorts es mostren</string>
<string name="revanced_ryd_shorts_summary_on_disclaimer">"Els \"no m'agrada\" als Shorts es mostren <string name="revanced_ryd_shorts_summary_on_disclaimer">"Els \"no m'agrada\" als Shorts es mostren
Limitació: és possible que els \"no m'agrada\" no apareguin en mode d'incògnit"</string> Limitació: és possible que els \"no m'agrada\" no apareguin en mode d'incògnit"</string>
@@ -1053,6 +1001,8 @@ Ja existeix"</string>
<string name="revanced_sb_vote_downvote">Vota en contra</string> <string name="revanced_sb_vote_downvote">Vota en contra</string>
<string name="revanced_sb_vote_category">Canvia la categoria</string> <string name="revanced_sb_vote_category">Canvia la categoria</string>
<string name="revanced_sb_vote_no_segments">No hi ha segments per votar</string> <string name="revanced_sb_vote_no_segments">No hi ha segments per votar</string>
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<string name="revanced_sb_vote_segment_time_to_from">%1$s a %2$s</string>
<string name="revanced_sb_new_segment_choose_category">Trieu la categoria del segment</string> <string name="revanced_sb_new_segment_choose_category">Trieu la categoria del segment</string>
<string name="revanced_sb_new_segment_disabled_category">La categoria està desactivada a la configuració. Habiliteu la categoria per enviar.</string> <string name="revanced_sb_new_segment_disabled_category">La categoria està desactivada a la configuració. Habiliteu la categoria per enviar.</string>
<string name="revanced_sb_new_segment_title">Nou segment de SponsorBlock</string> <string name="revanced_sb_new_segment_title">Nou segment de SponsorBlock</string>
@@ -1100,6 +1050,7 @@ Preparat per enviar?"</string>
<string name="revanced_sb_stats_saved_hour_format">%1$s hores %2$s minuts</string> <string name="revanced_sb_stats_saved_hour_format">%1$s hores %2$s minuts</string>
<string name="revanced_sb_stats_saved_minute_format">%1$s minuts %2$s segons</string> <string name="revanced_sb_stats_saved_minute_format">%1$s minuts %2$s segons</string>
<string name="revanced_sb_stats_saved_second_format">%s segons</string> <string name="revanced_sb_stats_saved_second_format">%s segons</string>
<string name="revanced_sb_color_opacity_label">Opacitat:</string>
<string name="revanced_sb_color_dot_label">Color:</string> <string name="revanced_sb_color_dot_label">Color:</string>
<string name="revanced_sb_color_changed">Color canviat</string> <string name="revanced_sb_color_changed">Color canviat</string>
<string name="revanced_sb_color_reset">Color restablert</string> <string name="revanced_sb_color_reset">Color restablert</string>
@@ -1117,14 +1068,12 @@ Preparat per enviar?"</string>
<string name="revanced_change_form_factor_entry_4">Automoció</string> <string name="revanced_change_form_factor_entry_4">Automoció</string>
<string name="revanced_change_form_factor_user_dialog_message">"Els canvis inclouen: <string name="revanced_change_form_factor_user_dialog_message">"Els canvis inclouen:
Presentació de la tauleta Disposició de tauleta
• Les publicacions de la comunitat estan amagades • Les publicacions de la comunitat s'han ocultat
Presentació de l'automòbil Disposició per a automoció
• El menú d'historial del rellotge està ocult • Els \"Shorts\" s'obren al reproductor normal
• La pestanya Explora s'ha restaurat • La font està organitzada per temes i canals"</string>
• Els Shorts s'obren al reproductor normal
• La font d'informació s'organitza per temes i canals"</string>
</patch> </patch>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<string name="revanced_spoof_app_version_title">Falsa la versió de l\'aplicació</string> <string name="revanced_spoof_app_version_title">Falsa la versió de l\'aplicació</string>
@@ -1139,12 +1088,7 @@ Si després es desactiva, es recomana esborrar les dades de l'aplicació per evi
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<string name="revanced_spoof_app_version_target_title">Objectiu de la versió falsa de l\'aplicació</string> <string name="revanced_spoof_app_version_target_title">Objectiu de la versió falsa de l\'aplicació</string>
<string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Restaura els icones vells del reproductor de Shorts</string> <string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Restaura els icones vells del reproductor de Shorts</string>
<string name="revanced_spoof_app_version_target_entry_2">19.26.42 - Restaura les icones de navegació antigues</string> <string name="revanced_spoof_app_version_target_entry_2">19.01.34 - Restaura les icones de navegació antigues</string>
<!-- 'RYD' is 'Return YouTube Dislike' -->
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - Restaura RYD al mode d\'incògnit de Shorts</string>
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Restaura la velocitat àmplia del vídeo &amp; menú de qualitat</string>
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - Restaura la pestanya de la biblioteca</string>
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - Restaura l\'antic prestatge de la llista de reproducció</string>
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
<string name="revanced_change_start_page_title">Defineix la pàgina d\'inici</string> <string name="revanced_change_start_page_title">Defineix la pàgina d\'inici</string>
@@ -1247,8 +1191,6 @@ Desliza para ampliar o cerrar"</string>
<string name="revanced_gradient_loading_screen_title">Habilita la pantalla de càrrega amb degradació</string> <string name="revanced_gradient_loading_screen_title">Habilita la pantalla de càrrega amb degradació</string>
<string name="revanced_gradient_loading_screen_summary_on">La pantalla de càrrega tindrà un fons de degradació</string> <string name="revanced_gradient_loading_screen_summary_on">La pantalla de càrrega tindrà un fons de degradació</string>
<string name="revanced_gradient_loading_screen_summary_off">La pantalla de càrrega tindrà un fons sòlid</string> <string name="revanced_gradient_loading_screen_summary_off">La pantalla de càrrega tindrà un fons sòlid</string>
</patch>
<patch id="layout.theme.themeResourcePatch">
<string name="revanced_seekbar_custom_color_title">Habilita el color personalitzat de la barra de cerca</string> <string name="revanced_seekbar_custom_color_title">Habilita el color personalitzat de la barra de cerca</string>
<string name="revanced_seekbar_custom_color_summary_on">El color personalitzat de la barra de cerca es mostra</string> <string name="revanced_seekbar_custom_color_summary_on">El color personalitzat de la barra de cerca es mostra</string>
<string name="revanced_seekbar_custom_color_summary_off">El color original de la barra de cerca es mostra</string> <string name="revanced_seekbar_custom_color_summary_off">El color original de la barra de cerca es mostra</string>
@@ -1340,8 +1282,8 @@ Si actives aquesta opció, es poden desbloquejar qualitats de vídeo més altes"
</patch> </patch>
<patch id="misc.links.openLinksExternallyPatch"> <patch id="misc.links.openLinksExternallyPatch">
<string name="revanced_external_browser_title">Obri els enllaços al navegador</string> <string name="revanced_external_browser_title">Obri els enllaços al navegador</string>
<string name="revanced_external_browser_summary_on">Obrir els enllaços externament</string> <string name="revanced_external_browser_summary_on">Obrint enllaços en un navegador extern</string>
<string name="revanced_external_browser_summary_off">Obrir els enllaços a l\'aplicació</string> <string name="revanced_external_browser_summary_off">Obrint enllaços en un navegador integrat a l\'aplicació</string>
</patch> </patch>
<patch id="misc.privacy.removeTrackingQueryParameterPatch"> <patch id="misc.privacy.removeTrackingQueryParameterPatch">
<string name="revanced_remove_tracking_query_parameter_title">Elimina el paràmetre de consulta de seguiment</string> <string name="revanced_remove_tracking_query_parameter_title">Elimina el paràmetre de consulta de seguiment</string>
@@ -1368,9 +1310,15 @@ Si actives aquesta opció, es poden desbloquejar qualitats de vídeo més altes"
<string name="revanced_remember_video_quality_last_selected_summary_off">Els canvis de qualitat només s\'apliquen al vídeo actual</string> <string name="revanced_remember_video_quality_last_selected_summary_off">Els canvis de qualitat només s\'apliquen al vídeo actual</string>
<string name="revanced_video_quality_default_wifi_title">Qualitat de vídeo predeterminada a la xarxa Wi-Fi</string> <string name="revanced_video_quality_default_wifi_title">Qualitat de vídeo predeterminada a la xarxa Wi-Fi</string>
<string name="revanced_video_quality_default_mobile_title">Qualitat de vídeo predeterminada a la xarxa mòbil</string> <string name="revanced_video_quality_default_mobile_title">Qualitat de vídeo predeterminada a la xarxa mòbil</string>
<string name="revanced_remember_shorts_quality_last_selected_title">Recorda els canvis de qualitat de Shorts</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_on">Els canvis de qualitat s\'apliquen a tots els Shorts</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_off">Els canvis de qualitat només s\'apliquen al Short actual</string>
<string name="revanced_shorts_quality_default_wifi_title">Qualitat predeterminada de Shorts a la xarxa Wi-Fi</string>
<string name="revanced_shorts_quality_default_mobile_title">Qualitat predeterminada de Shorts a la xarxa mòbil</string>
<string name="revanced_remember_video_quality_mobile">mòbil</string> <string name="revanced_remember_video_quality_mobile">mòbil</string>
<string name="revanced_remember_video_quality_wifi">wifi</string> <string name="revanced_remember_video_quality_wifi">wifi</string>
<string name="revanced_remember_video_quality_toast">S\'ha canviat la qualitat predeterminada de %1$s a: %2$s</string> <string name="revanced_remember_video_quality_toast">S\'ha canviat la qualitat predeterminada de %1$s a: %2$s</string>
<string name="revanced_remember_video_quality_toast_shorts">S\'ha canviat la qualitat de Shorts %1$s a: %2$s</string>
</patch> </patch>
<patch id="video.speed.button.playbackSpeedButtonPatch"> <patch id="video.speed.button.playbackSpeedButtonPatch">
<string name="revanced_playback_speed_dialog_button_title">Mostra el botó del diàleg de velocitat</string> <string name="revanced_playback_speed_dialog_button_title">Mostra el botó del diàleg de velocitat</string>
@@ -1401,10 +1349,10 @@ Si actives aquesta opció, es poden desbloquejar qualitats de vídeo més altes"
<string name="revanced_disable_hdr_video_summary_on">El vídeo HDR està desactivat</string> <string name="revanced_disable_hdr_video_summary_on">El vídeo HDR està desactivat</string>
<string name="revanced_disable_hdr_video_summary_off">El vídeo HDR està activat</string> <string name="revanced_disable_hdr_video_summary_off">El vídeo HDR està activat</string>
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
<string name="revanced_restore_old_video_quality_menu_title">Restaura el menú de qualitat de vídeo antic</string> <string name="revanced_advanced_video_quality_menu_title">Mostra el menú avançat de qualitat de vídeo</string>
<string name="revanced_restore_old_video_quality_menu_summary_on">El menú de qualitat de vídeo antic es mostra</string> <string name="revanced_advanced_video_quality_menu_summary_on">Es mostra el menú avançat de qualitat de vídeo</string>
<string name="revanced_restore_old_video_quality_menu_summary_off">El menú de qualitat de vídeo antic no es mostra</string> <string name="revanced_advanced_video_quality_menu_summary_off">No es mostra el menú avançat de qualitat de vídeo</string>
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
<string name="revanced_slide_to_seek_title">Habilita lliscar per buscar</string> <string name="revanced_slide_to_seek_title">Habilita lliscar per buscar</string>

View File

@@ -23,7 +23,7 @@ Second \"item\" text"</string>
<app id="shared"> <app id="shared">
<patch id="misc.checks.checkEnvironmentPatch"> <patch id="misc.checks.checkEnvironmentPatch">
<string name="revanced_check_environment_failed_title">Kontrola proběhla neúspěšně</string> <string name="revanced_check_environment_failed_title">Kontrola proběhla neúspěšně</string>
<string name="revanced_check_environment_dialog_open_official_source_button">Otevřít oficiální webové stránky</string> <string name="revanced_check_environment_dialog_open_official_source_button">Otevřít oficiální webovou stránku</string>
<string name="revanced_check_environment_dialog_ignore_button">Ignorovat</string> <string name="revanced_check_environment_dialog_ignore_button">Ignorovat</string>
<string name="revanced_check_environment_failed_message">&lt;h5&gt;Zdá se, že jste tuto upravenou verzi aplikace nevygenerovali vy.&lt;/h5&gt;&lt;br&gt;Aplikace nemusí fungovat správně, &lt;b&gt;může být škodlivá nebo nebezpečná&lt;/b&gt;.&lt;br&gt;&lt;br&gt;Z následujících kontrol vyplývá, že úpravy této aplikace byly provedeny někým jiným:&lt;br&gt;&lt;br&gt;&lt;small&gt;%1$s&lt;/small&gt;&lt;br&gt;Je důrazně doporučeno &lt;b&gt;odinstalovat tuto aplikaci a vygenerovat ji sami&lt;/b&gt;, abyste měli jistotu, že je aplikace ověřená a bezpečná.&lt;p&gt;&lt;br&gt;Pokud zvolíte Ignorovat, toto varování se zobrazí pouze dvakrát.</string> <string name="revanced_check_environment_failed_message">&lt;h5&gt;Zdá se, že jste tuto upravenou verzi aplikace nevygenerovali vy.&lt;/h5&gt;&lt;br&gt;Aplikace nemusí fungovat správně, &lt;b&gt;může být škodlivá nebo nebezpečná&lt;/b&gt;.&lt;br&gt;&lt;br&gt;Z následujících kontrol vyplývá, že úpravy této aplikace byly provedeny někým jiným:&lt;br&gt;&lt;br&gt;&lt;small&gt;%1$s&lt;/small&gt;&lt;br&gt;Je důrazně doporučeno &lt;b&gt;odinstalovat tuto aplikaci a vygenerovat ji sami&lt;/b&gt;, abyste měli jistotu, že je aplikace ověřená a bezpečná.&lt;p&gt;&lt;br&gt;Pokud zvolíte Ignorovat, toto varování se zobrazí pouze dvakrát.</string>
<string name="revanced_check_environment_not_same_patching_device">Vygenerována na jiném zařízení</string> <string name="revanced_check_environment_not_same_patching_device">Vygenerována na jiném zařízení</string>
@@ -48,57 +48,6 @@ Second \"item\" text"</string>
Nové jazyky přeložíte na translate.revanced.app"</string> Nové jazyky přeložíte na translate.revanced.app"</string>
<string name="revanced_language_DEFAULT">Jazyk aplikace</string> <string name="revanced_language_DEFAULT">Jazyk aplikace</string>
<string name="revanced_language_AR">Arabština</string>
<string name="revanced_language_AZ">Ázerbájdžánština</string>
<string name="revanced_language_BG">Bulharština</string>
<string name="revanced_language_BN">Bengálština</string>
<string name="revanced_language_CA">Katalánština</string>
<string name="revanced_language_CS">Čeština</string>
<string name="revanced_language_DA">Dánština</string>
<string name="revanced_language_DE">Němčina</string>
<string name="revanced_language_EL">Řečtina</string>
<string name="revanced_language_EN">Angličtina</string>
<string name="revanced_language_ES">Španělština</string>
<string name="revanced_language_ET">Estonština</string>
<string name="revanced_language_FA">Perština</string>
<string name="revanced_language_FI">Finština</string>
<string name="revanced_language_FR">Francouzština</string>
<string name="revanced_language_GU">Gudžarátština</string>
<string name="revanced_language_HI">Hindština</string>
<string name="revanced_language_HR">Chorvatština</string>
<string name="revanced_language_HU">Maďarština</string>
<string name="revanced_language_ID">Indonéština</string>
<string name="revanced_language_IT">Italština</string>
<string name="revanced_language_JA">Japonština</string>
<string name="revanced_language_KK">Kazachština</string>
<string name="revanced_language_KO">Korejština</string>
<string name="revanced_language_LT">Litevština</string>
<string name="revanced_language_LV">Lotyština</string>
<string name="revanced_language_MK">Makedonština</string>
<string name="revanced_language_MN">Mongolština</string>
<string name="revanced_language_MR">Maráthština</string>
<string name="revanced_language_MS">Malajština</string>
<string name="revanced_language_MY">Barmština</string>
<string name="revanced_language_NL">Nizozemština</string>
<string name="revanced_language_OR">Uríjština</string>
<string name="revanced_language_PA">Paňdžábština</string>
<string name="revanced_language_PL">Polština</string>
<string name="revanced_language_PT">Portugalština</string>
<string name="revanced_language_RO">Rumunština</string>
<string name="revanced_language_RU">Ruština</string>
<string name="revanced_language_SK">Slovenština</string>
<string name="revanced_language_SL">Slověnština</string>
<string name="revanced_language_SR">Srbština</string>
<string name="revanced_language_SV">Švédština</string>
<string name="revanced_language_SW">Svahilština</string>
<string name="revanced_language_TA">Tamilština</string>
<string name="revanced_language_TE">Telugština</string>
<string name="revanced_language_TH">Thajština</string>
<string name="revanced_language_TR">Turečtina</string>
<string name="revanced_language_UK">Ukrajinština</string>
<string name="revanced_language_UR">Urdština</string>
<string name="revanced_language_VI">Vietnamština</string>
<string name="revanced_language_ZH">Čínština</string>
<string name="revanced_pref_import_export_title">Importovat / Exportovat</string> <string name="revanced_pref_import_export_title">Importovat / Exportovat</string>
<string name="revanced_pref_import_export_summary">Importovat/exportovat nastavení ReVanced</string> <string name="revanced_pref_import_export_summary">Importovat/exportovat nastavení ReVanced</string>
<!-- Settings about dialog. --> <!-- Settings about dialog. -->
@@ -178,20 +127,20 @@ Nebudete informováni o žádné neočekávané události."</string>
<string name="revanced_hide_floating_microphone_button_summary_on">Tlačítko mikrofonu je skryté</string> <string name="revanced_hide_floating_microphone_button_summary_on">Tlačítko mikrofonu je skryté</string>
<string name="revanced_hide_floating_microphone_button_summary_off">Tlačítko mikrofonu se zobrazuje</string> <string name="revanced_hide_floating_microphone_button_summary_off">Tlačítko mikrofonu se zobrazuje</string>
<string name="revanced_hide_channel_watermark_title">Skrýt vodoznak kanálu</string> <string name="revanced_hide_channel_watermark_title">Skrýt vodoznak kanálu</string>
<string name="revanced_hide_channel_watermark_summary_on">Vodoznak kanála je skrytý</string> <string name="revanced_hide_channel_watermark_summary_on">Vodoznak kanálu je skrytý</string>
<string name="revanced_hide_channel_watermark_summary_off">Vodoznak je zobrazen</string> <string name="revanced_hide_channel_watermark_summary_off">Vodoznak je zobrazen</string>
<string name="revanced_hide_horizontal_shelves_title">Skr horizontálne police</string> <string name="revanced_hide_horizontal_shelves_title">Skrýt horizontální police</string>
<string name="revanced_hide_horizontal_shelves_summary_on">"Police jsou skryté, například: <string name="revanced_hide_horizontal_shelves_summary_on">"Police jsou skryté, například:
• Novinky • Novinky
• Pokračovat v sledování • Pokračovat v sledování
• Prozkoumat další kanály • Prozkoumat další kanály
• Nákupy • Nákupy
• Podívat se znovu"</string> • Podívat se znovu"</string>
<string name="revanced_hide_horizontal_shelves_summary_off">Police zobrazené</string> <string name="revanced_hide_horizontal_shelves_summary_off">Police jsou zobrazené</string>
<!-- 'Join' should be translated using the same localized wording YouTube displays. <!-- 'Join' should be translated using the same localized wording YouTube displays.
This appears in the video player for certain videos. --> This appears in the video player for certain videos. -->
<string name="revanced_hide_join_membership_button_title">Skrýt tlačítko Připojit se</string> <string name="revanced_hide_join_membership_button_title">Skrýt tlačítko Připojit se</string>
<string name="revanced_hide_join_membership_button_summary_on">Tlačidlo je skryté</string> <string name="revanced_hide_join_membership_button_summary_on">Tlačitko je skryté</string>
<string name="revanced_hide_join_membership_button_summary_off">Tlačítko je zobrazeno</string> <string name="revanced_hide_join_membership_button_summary_off">Tlačítko je zobrazeno</string>
<!-- 'For you' should be translated using the same localized wording YouTube displays. --> <!-- 'For you' should be translated using the same localized wording YouTube displays. -->
<string name="revanced_hide_for_you_shelf_title">Skrýt panel „Pro vás“</string> <string name="revanced_hide_for_you_shelf_title">Skrýt panel „Pro vás“</string>
@@ -199,7 +148,7 @@ Nebudete informováni o žádné neočekávané události."</string>
<string name="revanced_hide_for_you_shelf_summary_off">Panel polic ve stránce kanálu je zobrazen</string> <string name="revanced_hide_for_you_shelf_summary_off">Panel polic ve stránce kanálu je zobrazen</string>
<!-- 'Notify me' should be translated using the same localized wording YouTube displays. <!-- 'Notify me' should be translated using the same localized wording YouTube displays.
This item appear in the subscription feed for future livestreams or unreleased videos. --> This item appear in the subscription feed for future livestreams or unreleased videos. -->
<string name="revanced_hide_notify_me_button_title">Skr tlačidlo \'Upozornite ma\'</string> <string name="revanced_hide_notify_me_button_title">Skrýt tlačitko \'Upozorněte mě\'</string>
<string name="revanced_hide_notify_me_button_summary_on">Tlačítko je skryté</string> <string name="revanced_hide_notify_me_button_summary_on">Tlačítko je skryté</string>
<string name="revanced_hide_notify_me_button_summary_off">Tlačítko je zobrazeno</string> <string name="revanced_hide_notify_me_button_summary_off">Tlačítko je zobrazeno</string>
<!-- 'People also watched' should be translated using the same localized wording YouTube displays. --> <!-- 'People also watched' should be translated using the same localized wording YouTube displays. -->
@@ -216,7 +165,7 @@ Nebudete informováni o žádné neočekávané události."</string>
<string name="revanced_hide_timed_reactions_summary_off">Reakce se zobrazují po čase</string> <string name="revanced_hide_timed_reactions_summary_off">Reakce se zobrazují po čase</string>
<string name="revanced_hide_channel_guidelines_title">Skrýt pravidla kanálu</string> <string name="revanced_hide_channel_guidelines_title">Skrýt pravidla kanálu</string>
<string name="revanced_hide_channel_guidelines_summary_on">Pokyny kanálu sa nezobrazujú</string> <string name="revanced_hide_channel_guidelines_summary_on">Pokyny kanálu sa nezobrazujú</string>
<string name="revanced_hide_channel_guidelines_summary_off">Zobrazujú sa pokyny kanálu</string> <string name="revanced_hide_channel_guidelines_summary_off">Zobrazují se pokyny kanálu</string>
<string name="revanced_hide_chips_shelf_title">Skryť police \"Ďalsej videá\"</string> <string name="revanced_hide_chips_shelf_title">Skryť police \"Ďalsej videá\"</string>
<string name="revanced_hide_chips_shelf_summary_on">Police \"Další videá\" sa nezobrazuje</string> <string name="revanced_hide_chips_shelf_summary_on">Police \"Další videá\" sa nezobrazuje</string>
<string name="revanced_hide_chips_shelf_summary_off">Zobrazuje sa polícia \"Další videá\"</string> <string name="revanced_hide_chips_shelf_summary_off">Zobrazuje sa polícia \"Další videá\"</string>
@@ -301,13 +250,13 @@ Nebudete informováni o žádné neočekávané události."</string>
<string name="revanced_hide_description_components_screen_title">Popis videa</string> <string name="revanced_hide_description_components_screen_title">Popis videa</string>
<string name="revanced_hide_description_components_screen_summary">Skrýt nebo zobrazit komponenty popisu videa</string> <string name="revanced_hide_description_components_screen_summary">Skrýt nebo zobrazit komponenty popisu videa</string>
<string name="revanced_hide_filter_bar_screen_title">Lišta filtrů</string> <string name="revanced_hide_filter_bar_screen_title">Lišta filtrů</string>
<string name="revanced_hide_filter_bar_screen_summary">Skrýt nebo zobrazit lištu filtrů ve feedu, vyhledání a souvisejících videích</string> <string name="revanced_hide_filter_bar_screen_summary">Skrýt nebo zobrazit lištu filtrů v kanálu, výsledcích hledání a souvisejících videích</string>
<string name="revanced_hide_filter_bar_feed_in_feed_title">Skrýt ve feedu</string> <string name="revanced_hide_filter_bar_feed_in_feed_title">Skrýt ve feedu</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Ve feedu skryto</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Ve feedu skryto</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Ve feedu zobrazeno</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Ve feedu zobrazeno</string>
<string name="revanced_hide_filter_bar_feed_in_search_title">Skrýt ve vyhledávání</string> <string name="revanced_hide_filter_bar_feed_in_search_title">Skrýt ve výsledcích vyhledávání</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_on">Ve vyhledávání skryto</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_on">Skryto ve výsledcích vyhledávání</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_off">Ve vyhledávání zobrazeno</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_off">Zobrazeno ve výsledcích vyhledávání</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">Skrýt v souvisejících videích</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_title">Skrýt v souvisejících videích</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">V souvisejících videích skryto</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">V souvisejících videích skryto</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">V souvisejících videích zobrazeno</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">V souvisejících videích zobrazeno</string>
@@ -404,7 +353,7 @@ Tato funkce je dostupná pouze pro starší zařízení"</string>
<string name="revanced_hide_self_sponsor_ads_title">Skrýt karty se sponzorovanými produkty</string> <string name="revanced_hide_self_sponsor_ads_title">Skrýt karty se sponzorovanými produkty</string>
<string name="revanced_hide_self_sponsor_ads_summary_on">Karty se sponzorovanými produkty jsou skryty</string> <string name="revanced_hide_self_sponsor_ads_summary_on">Karty se sponzorovanými produkty jsou skryty</string>
<string name="revanced_hide_self_sponsor_ads_summary_off">Karty se sponzorovanými produkty jsou zobrazeny</string> <string name="revanced_hide_self_sponsor_ads_summary_off">Karty se sponzorovanými produkty jsou zobrazeny</string>
<string name="revanced_hide_products_banner_title">Skrýt banner pro prohlížení produktů</string> <string name="revanced_hide_products_banner_title">Skrýt banner „Zobrazit produkty“</string>
<string name="revanced_hide_products_banner_summary_on">Banner je skryt</string> <string name="revanced_hide_products_banner_summary_on">Banner je skryt</string>
<string name="revanced_hide_products_banner_summary_off">Banner je zobrazen</string> <string name="revanced_hide_products_banner_summary_off">Banner je zobrazen</string>
<string name="revanced_hide_end_screen_store_banner_title">Skrýt koncový banner obchodu</string> <string name="revanced_hide_end_screen_store_banner_title">Skrýt koncový banner obchodu</string>
@@ -663,7 +612,7 @@ Pokud změna tohoto nastavení nemá žádný účinek, zkuste přepnout do rež
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Zápatí menu kvality videa je zobrazeno</string> <string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Zápatí menu kvality videa je zobrazeno</string>
</patch> </patch>
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch"> <patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
<string name="revanced_hide_player_previous_next_buttons_title">Skrýt tlačítka pro předchozí a další video</string> <string name="revanced_hide_player_previous_next_buttons_title">Skrýt tlačítka Předchozí a Další</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Tlačítka jsou skryta</string> <string name="revanced_hide_player_previous_next_buttons_summary_on">Tlačítka jsou skryta</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Tlačítka jsou zobrazena</string> <string name="revanced_hide_player_previous_next_buttons_summary_off">Tlačítka jsou zobrazena</string>
<string name="revanced_hide_cast_button_title">Skrýt tlačítko Odeslat</string> <string name="revanced_hide_cast_button_title">Skrýt tlačítko Odeslat</string>
@@ -856,7 +805,6 @@ Nastavení → Přehrávání → Automatické přehrávání dalšího videa"</
<string name="revanced_ryd_enable_summary_on">Nelíbí se se zobrazují</string> <string name="revanced_ryd_enable_summary_on">Nelíbí se se zobrazují</string>
<string name="revanced_ryd_enable_summary_off">Nelíbí se se nezobrazují</string> <string name="revanced_ryd_enable_summary_off">Nelíbí se se nezobrazují</string>
<string name="revanced_ryd_shorts_title">Zobrazit nelíbí se v Shorts</string> <string name="revanced_ryd_shorts_title">Zobrazit nelíbí se v Shorts</string>
<string name="revanced_ryd_shorts_summary_on">Počty „Nelíbí se mi“ u Shorts jsou zobrazeny</string>
<string name="revanced_ryd_shorts_summary_on_disclaimer">"Počty „Nelíbí se mi“ u Shorts jsou zobrazeny <string name="revanced_ryd_shorts_summary_on_disclaimer">"Počty „Nelíbí se mi“ u Shorts jsou zobrazeny
Omezení: Počty „Nelíbí se mi“ se nemusí zobrazit v anonymním režimu"</string> Omezení: Počty „Nelíbí se mi“ se nemusí zobrazit v anonymním režimu"</string>
@@ -1053,6 +1001,8 @@ Již existuje"</string>
<string name="revanced_sb_vote_downvote">Hlasovat dolů</string> <string name="revanced_sb_vote_downvote">Hlasovat dolů</string>
<string name="revanced_sb_vote_category">Změnit kategorii</string> <string name="revanced_sb_vote_category">Změnit kategorii</string>
<string name="revanced_sb_vote_no_segments">Nejsou žádné segmenty, pro které by se dalo hlasovat</string> <string name="revanced_sb_vote_no_segments">Nejsou žádné segmenty, pro které by se dalo hlasovat</string>
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<string name="revanced_sb_vote_segment_time_to_from">%1$s až %2$s</string>
<string name="revanced_sb_new_segment_choose_category">Zvolte kategorii segmentu</string> <string name="revanced_sb_new_segment_choose_category">Zvolte kategorii segmentu</string>
<string name="revanced_sb_new_segment_disabled_category">Kategorie je v nastavení zakázána. Povolte kategorii, abyste ji mohli odeslat.</string> <string name="revanced_sb_new_segment_disabled_category">Kategorie je v nastavení zakázána. Povolte kategorii, abyste ji mohli odeslat.</string>
<string name="revanced_sb_new_segment_title">Nový segment SponsorBlock</string> <string name="revanced_sb_new_segment_title">Nový segment SponsorBlock</string>
@@ -1100,6 +1050,7 @@ Jste připraveni k odeslání?"</string>
<string name="revanced_sb_stats_saved_hour_format">%1$s hodin %2$s minut</string> <string name="revanced_sb_stats_saved_hour_format">%1$s hodin %2$s minut</string>
<string name="revanced_sb_stats_saved_minute_format">%1$s minut %2$s sekund</string> <string name="revanced_sb_stats_saved_minute_format">%1$s minut %2$s sekund</string>
<string name="revanced_sb_stats_saved_second_format">%s sekund</string> <string name="revanced_sb_stats_saved_second_format">%s sekund</string>
<string name="revanced_sb_color_opacity_label">Průhlednost:</string>
<string name="revanced_sb_color_dot_label">Barva:</string> <string name="revanced_sb_color_dot_label">Barva:</string>
<string name="revanced_sb_color_changed">Barva změněna</string> <string name="revanced_sb_color_changed">Barva změněna</string>
<string name="revanced_sb_color_reset">Barva resetována</string> <string name="revanced_sb_color_reset">Barva resetována</string>
@@ -1121,10 +1072,8 @@ Rozložení tabletu
• Příspěvky komunity jsou skryté • Příspěvky komunity jsou skryté
Rozložení automobilu Rozložení automobilu
• Menu historie sledování je skryté
• Karta Prozkoumat je obnovena
• Shorts se otevírají v běžném přehrávači • Shorts se otevírají v běžném přehrávači
• Kanál je organizován podle témat a kanálu"</string> • Kanál je uspořádán podle témat a kanálů"</string>
</patch> </patch>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<string name="revanced_spoof_app_version_title">Napodobit verzi aplikace</string> <string name="revanced_spoof_app_version_title">Napodobit verzi aplikace</string>
@@ -1139,12 +1088,7 @@ Pokud bude později vypnuta, doporučujeme vymazat data aplikace, aby se zabrán
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<string name="revanced_spoof_app_version_target_title">Cíl napodobení verze aplikace</string> <string name="revanced_spoof_app_version_target_title">Cíl napodobení verze aplikace</string>
<string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Obnovuje staré ikony Shorts přehrávače</string> <string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Obnovuje staré ikony Shorts přehrávače</string>
<string name="revanced_spoof_app_version_target_entry_2">19.26.42 - Navrátit staré ikony pro navigaci</string> <string name="revanced_spoof_app_version_target_entry_2">19.01.34 - Navrátit staré ikony pro navigaci</string>
<!-- 'RYD' is 'Return YouTube Dislike' -->
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - Obnovení RYD v režimu inkognito Shorts</string>
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Obnovení široké nabídky rychlosti a kvality videa</string>
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - Obnovení karty Knihovna</string>
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - Obnovení staré police se seznamy skladeb</string>
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
<string name="revanced_change_start_page_title">Nastavit úvodní stránku</string> <string name="revanced_change_start_page_title">Nastavit úvodní stránku</string>
@@ -1247,8 +1191,6 @@ Přejeďte prstem pro rozbalení nebo zavření"</string>
<string name="revanced_gradient_loading_screen_title">Povolit přechodovou obrazovku načítání</string> <string name="revanced_gradient_loading_screen_title">Povolit přechodovou obrazovku načítání</string>
<string name="revanced_gradient_loading_screen_summary_on">Obrazovka načítání bude mít přechodové pozadí</string> <string name="revanced_gradient_loading_screen_summary_on">Obrazovka načítání bude mít přechodové pozadí</string>
<string name="revanced_gradient_loading_screen_summary_off">Obrazovka načítání bude mít pevné pozadí</string> <string name="revanced_gradient_loading_screen_summary_off">Obrazovka načítání bude mít pevné pozadí</string>
</patch>
<patch id="layout.theme.themeResourcePatch">
<string name="revanced_seekbar_custom_color_title">Povolit vlastní barvu posuvníku</string> <string name="revanced_seekbar_custom_color_title">Povolit vlastní barvu posuvníku</string>
<string name="revanced_seekbar_custom_color_summary_on">Vlasní barva posuvníku je zobrazena</string> <string name="revanced_seekbar_custom_color_summary_on">Vlasní barva posuvníku je zobrazena</string>
<string name="revanced_seekbar_custom_color_summary_off">Původní barva posuvníku je zobrazena</string> <string name="revanced_seekbar_custom_color_summary_off">Původní barva posuvníku je zobrazena</string>
@@ -1340,8 +1282,8 @@ Povolením této funkce lze odemknout vyšší kvality videa"</string>
</patch> </patch>
<patch id="misc.links.openLinksExternallyPatch"> <patch id="misc.links.openLinksExternallyPatch">
<string name="revanced_external_browser_title">Otevírat odkazy v prohlížeči</string> <string name="revanced_external_browser_title">Otevírat odkazy v prohlížeči</string>
<string name="revanced_external_browser_summary_on">Otevírání odkazů externě</string> <string name="revanced_external_browser_summary_on">Otevírání odkazů v externím prohlížeči</string>
<string name="revanced_external_browser_summary_off">Otevírání odkazů v aplikaci</string> <string name="revanced_external_browser_summary_off">Otevírání odkazů v prohlížeči v aplikaci</string>
</patch> </patch>
<patch id="misc.privacy.removeTrackingQueryParameterPatch"> <patch id="misc.privacy.removeTrackingQueryParameterPatch">
<string name="revanced_remove_tracking_query_parameter_title">Odstranit sledovací parametr dotazu</string> <string name="revanced_remove_tracking_query_parameter_title">Odstranit sledovací parametr dotazu</string>
@@ -1368,9 +1310,15 @@ Povolením této funkce lze odemknout vyšší kvality videa"</string>
<string name="revanced_remember_video_quality_last_selected_summary_off">Změny kvality se vztahují pouze na aktuální video</string> <string name="revanced_remember_video_quality_last_selected_summary_off">Změny kvality se vztahují pouze na aktuální video</string>
<string name="revanced_video_quality_default_wifi_title">Výchozí kvalita videa v síti Wi-Fi</string> <string name="revanced_video_quality_default_wifi_title">Výchozí kvalita videa v síti Wi-Fi</string>
<string name="revanced_video_quality_default_mobile_title">Výchozí kvalita videa v mobilní síti</string> <string name="revanced_video_quality_default_mobile_title">Výchozí kvalita videa v mobilní síti</string>
<string name="revanced_remember_shorts_quality_last_selected_title">Zapamatovat si změny kvality u položky Shorts</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_on">Změny kvality se vztahují na všechny {Shorts}</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_off">Změny kvality se vztahují pouze na aktuální {Shorts}</string>
<string name="revanced_shorts_quality_default_wifi_title">Výchozí kvalita Shorts v síti Wi-Fi</string>
<string name="revanced_shorts_quality_default_mobile_title">Výchozí kvalita Shorts v mobilní síti</string>
<string name="revanced_remember_video_quality_mobile">mobilní</string> <string name="revanced_remember_video_quality_mobile">mobilní</string>
<string name="revanced_remember_video_quality_wifi">Wi-Fi</string> <string name="revanced_remember_video_quality_wifi">Wi-Fi</string>
<string name="revanced_remember_video_quality_toast">Výchozí kvalita %1$s změněna na: %2$s</string> <string name="revanced_remember_video_quality_toast">Výchozí kvalita %1$s změněna na: %2$s</string>
<string name="revanced_remember_video_quality_toast_shorts">Změněna kvalita Shorts %1$s na: %2$s</string>
</patch> </patch>
<patch id="video.speed.button.playbackSpeedButtonPatch"> <patch id="video.speed.button.playbackSpeedButtonPatch">
<string name="revanced_playback_speed_dialog_button_title">Zobrazit tlačítko dialogu rychlosti</string> <string name="revanced_playback_speed_dialog_button_title">Zobrazit tlačítko dialogu rychlosti</string>
@@ -1401,10 +1349,10 @@ Povolením této funkce lze odemknout vyšší kvality videa"</string>
<string name="revanced_disable_hdr_video_summary_on">HDR video je vypnuté.</string> <string name="revanced_disable_hdr_video_summary_on">HDR video je vypnuté.</string>
<string name="revanced_disable_hdr_video_summary_off">HDR video je zapnuté.</string> <string name="revanced_disable_hdr_video_summary_off">HDR video je zapnuté.</string>
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
<string name="revanced_restore_old_video_quality_menu_title">Obnovit staré menu kvality videa</string> <string name="revanced_advanced_video_quality_menu_title">Zobrazit rozšířené menu kvality videa</string>
<string name="revanced_restore_old_video_quality_menu_summary_on">Staré menu kvality videa se zobrazuje</string> <string name="revanced_advanced_video_quality_menu_summary_on">Zobrazuje se rozšířené menu kvality videa</string>
<string name="revanced_restore_old_video_quality_menu_summary_off">Staré menu kvality videa se nezobrazuje</string> <string name="revanced_advanced_video_quality_menu_summary_off">Nezobrazuje se rozšířené menu kvality videa</string>
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
<string name="revanced_slide_to_seek_title">Povolit posun pro hledání</string> <string name="revanced_slide_to_seek_title">Povolit posun pro hledání</string>

View File

@@ -48,57 +48,6 @@ Second \"item\" text"</string>
For at oversætte til nye sprog skal du besøge translate.revanced.app"</string> For at oversætte til nye sprog skal du besøge translate.revanced.app"</string>
<string name="revanced_language_DEFAULT">App-sprog</string> <string name="revanced_language_DEFAULT">App-sprog</string>
<string name="revanced_language_AR">Arabisk</string>
<string name="revanced_language_AZ">Aserbajdsjansk</string>
<string name="revanced_language_BG">Bulgarsk</string>
<string name="revanced_language_BN">Bengalsk</string>
<string name="revanced_language_CA">Catalansk</string>
<string name="revanced_language_CS">Tjekkisk</string>
<string name="revanced_language_DA">Dansk</string>
<string name="revanced_language_DE">Tysk</string>
<string name="revanced_language_EL">Græsk</string>
<string name="revanced_language_EN">Engelsk</string>
<string name="revanced_language_ES">Spansk</string>
<string name="revanced_language_ET">Estisk</string>
<string name="revanced_language_FA">Persisk</string>
<string name="revanced_language_FI">Finsk</string>
<string name="revanced_language_FR">Fransk</string>
<string name="revanced_language_GU">Gujarati</string>
<string name="revanced_language_HI">Hindi</string>
<string name="revanced_language_HR">Kroatisk</string>
<string name="revanced_language_HU">Ungarsk</string>
<string name="revanced_language_ID">Indonesisk</string>
<string name="revanced_language_IT">Italiensk</string>
<string name="revanced_language_JA">Japansk</string>
<string name="revanced_language_KK">Kasakhisk</string>
<string name="revanced_language_KO">Koreansk</string>
<string name="revanced_language_LT">Litauisk</string>
<string name="revanced_language_LV">Lettisk</string>
<string name="revanced_language_MK">Makedonsk</string>
<string name="revanced_language_MN">Mongolsk</string>
<string name="revanced_language_MR">Marathi</string>
<string name="revanced_language_MS">Malaysisk</string>
<string name="revanced_language_MY">Burmesisk</string>
<string name="revanced_language_NL">Hollandsk</string>
<string name="revanced_language_OR">Odia</string>
<string name="revanced_language_PA">Punjabi</string>
<string name="revanced_language_PL">Polsk</string>
<string name="revanced_language_PT">Portugisisk</string>
<string name="revanced_language_RO">Rumænsk</string>
<string name="revanced_language_RU">Russisk</string>
<string name="revanced_language_SK">Slovakisk</string>
<string name="revanced_language_SL">Slovensk</string>
<string name="revanced_language_SR">Serbisk</string>
<string name="revanced_language_SV">Svensk</string>
<string name="revanced_language_SW">Swahili</string>
<string name="revanced_language_TA">Tamil</string>
<string name="revanced_language_TE">Telugu</string>
<string name="revanced_language_TH">Thai</string>
<string name="revanced_language_TR">Tyrkisk</string>
<string name="revanced_language_UK">Ukrainisk</string>
<string name="revanced_language_UR">Urdu</string>
<string name="revanced_language_VI">Vietnamesisk</string>
<string name="revanced_language_ZH">Kinesisk</string>
<string name="revanced_pref_import_export_title">Importér/Eksportér</string> <string name="revanced_pref_import_export_title">Importér/Eksportér</string>
<string name="revanced_pref_import_export_summary">Importér/Eksportér ReVanced-indstillinger</string> <string name="revanced_pref_import_export_summary">Importér/Eksportér ReVanced-indstillinger</string>
<!-- Settings about dialog. --> <!-- Settings about dialog. -->
@@ -278,13 +227,13 @@ Du modtager ikke notifikationer om uventede hændelser."</string>
<string name="revanced_hide_description_components_screen_title">Video beskrivelse</string> <string name="revanced_hide_description_components_screen_title">Video beskrivelse</string>
<string name="revanced_hide_description_components_screen_summary">Skjul eller vis komponenter til videobeskrivelse</string> <string name="revanced_hide_description_components_screen_summary">Skjul eller vis komponenter til videobeskrivelse</string>
<string name="revanced_hide_filter_bar_screen_title">Filtrer bjælke</string> <string name="revanced_hide_filter_bar_screen_title">Filtrer bjælke</string>
<string name="revanced_hide_filter_bar_screen_summary">Skjul eller vis filterbjælken i feedet, søg og relaterede videoer</string> <string name="revanced_hide_filter_bar_screen_summary">Skjul eller vis filterlinjen i feedet, søgeresultaterne og relaterede videoer</string>
<string name="revanced_hide_filter_bar_feed_in_feed_title">Skjul i feed</string> <string name="revanced_hide_filter_bar_feed_in_feed_title">Skjul i feed</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Skjult i feed</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Skjult i feed</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Vist i feed</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Vist i feed</string>
<string name="revanced_hide_filter_bar_feed_in_search_title">Skjul i søgning</string> <string name="revanced_hide_filter_bar_feed_in_search_title">Skjul i søgeresultater</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_on">Skjult i søgning</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_on">Skjult i søgeresultater</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_off">Vist i søgning</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_off">Vises i søgeresultater</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">Skjul i relaterede videoer</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_title">Skjul i relaterede videoer</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Skjult i relaterede videoer</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Skjult i relaterede videoer</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">Vist i relaterede videoer</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">Vist i relaterede videoer</string>
@@ -372,7 +321,7 @@ Denne funktion er kun tilgængelig for ældre enheder"</string>
<string name="revanced_hide_self_sponsor_ads_title">Skjul selvsponsorerede kort</string> <string name="revanced_hide_self_sponsor_ads_title">Skjul selvsponsorerede kort</string>
<string name="revanced_hide_self_sponsor_ads_summary_on">Selvsponsorerede kort er skjult</string> <string name="revanced_hide_self_sponsor_ads_summary_on">Selvsponsorerede kort er skjult</string>
<string name="revanced_hide_self_sponsor_ads_summary_off">Selvsponsorerede kort vises</string> <string name="revanced_hide_self_sponsor_ads_summary_off">Selvsponsorerede kort vises</string>
<string name="revanced_hide_products_banner_title">Skjul banner for at se produkter</string> <string name="revanced_hide_products_banner_title">Skjul banneret \"Se produkter\"</string>
<string name="revanced_hide_products_banner_summary_on">Banner er skjult</string> <string name="revanced_hide_products_banner_summary_on">Banner er skjult</string>
<string name="revanced_hide_products_banner_summary_off">Banner er vist</string> <string name="revanced_hide_products_banner_summary_off">Banner er vist</string>
<string name="revanced_hide_end_screen_store_banner_title">Skjul banner fra butikken på slutskærmen</string> <string name="revanced_hide_end_screen_store_banner_title">Skjul banner fra butikken på slutskærmen</string>
@@ -624,7 +573,7 @@ Hvis ændring af denne indstilling ikke træder i kraft, kan du prøve at skifte
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Videokvalitet menu footer er vist</string> <string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Videokvalitet menu footer er vist</string>
</patch> </patch>
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch"> <patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
<string name="revanced_hide_player_previous_next_buttons_title">Skjul forrige &amp; næste video knapper</string> <string name="revanced_hide_player_previous_next_buttons_title">Skjul Forrige &amp; Næste knapper</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Knapper er skjult</string> <string name="revanced_hide_player_previous_next_buttons_summary_on">Knapper er skjult</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Knapper vises</string> <string name="revanced_hide_player_previous_next_buttons_summary_off">Knapper vises</string>
<string name="revanced_hide_cast_button_title">Skjul Cast-knappen</string> <string name="revanced_hide_cast_button_title">Skjul Cast-knappen</string>
@@ -1001,6 +950,8 @@ Eksisterer allerede"</string>
<string name="revanced_sb_vote_downvote">Ned</string> <string name="revanced_sb_vote_downvote">Ned</string>
<string name="revanced_sb_vote_category">Skift kategori</string> <string name="revanced_sb_vote_category">Skift kategori</string>
<string name="revanced_sb_vote_no_segments">Der er ingen segmenter at stemme for</string> <string name="revanced_sb_vote_no_segments">Der er ingen segmenter at stemme for</string>
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<string name="revanced_sb_vote_segment_time_to_from">%1$s til %2$s</string>
<string name="revanced_sb_new_segment_choose_category">Vælg segmentkategori</string> <string name="revanced_sb_new_segment_choose_category">Vælg segmentkategori</string>
<string name="revanced_sb_new_segment_disabled_category">Kategori er deaktiveret i indstillinger. Aktivér kategori for at indsende.</string> <string name="revanced_sb_new_segment_disabled_category">Kategori er deaktiveret i indstillinger. Aktivér kategori for at indsende.</string>
<string name="revanced_sb_new_segment_title">Nyt SponsorBlock segment</string> <string name="revanced_sb_new_segment_title">Nyt SponsorBlock segment</string>
@@ -1044,6 +995,7 @@ Er du klar til at indsende?"</string>
<string name="revanced_sb_stats_saved_hour_format">%1$s timer %2$s minutter</string> <string name="revanced_sb_stats_saved_hour_format">%1$s timer %2$s minutter</string>
<string name="revanced_sb_stats_saved_minute_format">%1$s minutter %2$s sekunder</string> <string name="revanced_sb_stats_saved_minute_format">%1$s minutter %2$s sekunder</string>
<string name="revanced_sb_stats_saved_second_format">%s sekunder</string> <string name="revanced_sb_stats_saved_second_format">%s sekunder</string>
<string name="revanced_sb_color_opacity_label">Opacitet:</string>
<string name="revanced_sb_color_dot_label">Farve:</string> <string name="revanced_sb_color_dot_label">Farve:</string>
<string name="revanced_sb_color_changed">Farve ændret</string> <string name="revanced_sb_color_changed">Farve ændret</string>
<string name="revanced_sb_color_reset">Nulstil farve</string> <string name="revanced_sb_color_reset">Nulstil farve</string>
@@ -1062,13 +1014,11 @@ Er du klar til at indsende?"</string>
<string name="revanced_change_form_factor_user_dialog_message">"Ændringer omfatter: <string name="revanced_change_form_factor_user_dialog_message">"Ændringer omfatter:
Tabletlayout Tabletlayout
• Fællesindlæg er skjult • Fællesskabsopslag er skjulte
Bil layout Automotive-layout
• Se historik-menuen er skjult
• Udforsk-fanen er gendannet
• Shorts åbnes i den almindelige afspiller • Shorts åbnes i den almindelige afspiller
• Feedet er organiseret efter emner og kanal"</string> • Feed er organiseret efter emner og kanaler"</string>
</patch> </patch>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<string name="revanced_spoof_app_version_title">Spoof app-version</string> <string name="revanced_spoof_app_version_title">Spoof app-version</string>
@@ -1083,12 +1033,7 @@ Hvis det senere slås fra, anbefales det at rydde app-dataene for at forhindre U
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<string name="revanced_spoof_app_version_target_title">Spoof app version mål</string> <string name="revanced_spoof_app_version_target_title">Spoof app version mål</string>
<string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Gendan gamle Shorts player ikoner</string> <string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Gendan gamle Shorts player ikoner</string>
<string name="revanced_spoof_app_version_target_entry_2">19.26.42 - Gendan gamle navigationsikoner</string> <string name="revanced_spoof_app_version_target_entry_2">19.01.34 - Gendan gamle navigationsikoner</string>
<!-- 'RYD' is 'Return YouTube Dislike' -->
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - Gendan RYD på Shorts inkognitotilstand</string>
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Gendan bred video hastighed &amp; kvalitet menu</string>
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - Genopret biblioteks fane</string>
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - Gendan gammel spilleliste hylde</string>
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
<string name="revanced_change_start_page_title">Indstil startside</string> <string name="revanced_change_start_page_title">Indstil startside</string>
@@ -1138,7 +1083,7 @@ Hvis det senere slås fra, anbefales det at rydde app-dataene for at forhindre U
</patch> </patch>
<patch id="layout.miniplayer.miniplayerPatch"> <patch id="layout.miniplayer.miniplayerPatch">
<string name="revanced_miniplayer_screen_title">Mini-afspiller</string> <string name="revanced_miniplayer_screen_title">Mini-afspiller</string>
<string name="revanced_miniplayer_screen_summary">Ændre stilen for den i app minimeret afspiller</string> <string name="revanced_miniplayer_screen_summary">Skift stilen den minimerede afspiller i appen</string>
<string name="revanced_miniplayer_type_title">Type af miniplayer</string> <string name="revanced_miniplayer_type_title">Type af miniplayer</string>
<string name="revanced_miniplayer_type_entry_0">Deaktiveret</string> <string name="revanced_miniplayer_type_entry_0">Deaktiveret</string>
<string name="revanced_miniplayer_type_entry_1">Standard</string> <string name="revanced_miniplayer_type_entry_1">Standard</string>
@@ -1191,8 +1136,6 @@ Stryg for at udvide eller lukke"</string>
<string name="revanced_gradient_loading_screen_title">Aktiver gradient indlæsning af skærmen</string> <string name="revanced_gradient_loading_screen_title">Aktiver gradient indlæsning af skærmen</string>
<string name="revanced_gradient_loading_screen_summary_on">Indlæser skærmen vil have en gradient baggrund</string> <string name="revanced_gradient_loading_screen_summary_on">Indlæser skærmen vil have en gradient baggrund</string>
<string name="revanced_gradient_loading_screen_summary_off">Indlæser skærmen vil have en solid baggrund</string> <string name="revanced_gradient_loading_screen_summary_off">Indlæser skærmen vil have en solid baggrund</string>
</patch>
<patch id="layout.theme.themeResourcePatch">
<string name="revanced_seekbar_custom_color_title">Aktivér brugerdefineret søgelinjefarve</string> <string name="revanced_seekbar_custom_color_title">Aktivér brugerdefineret søgelinjefarve</string>
<string name="revanced_seekbar_custom_color_summary_on">Brugerdefineret søgelinje farve vises</string> <string name="revanced_seekbar_custom_color_summary_on">Brugerdefineret søgelinje farve vises</string>
<string name="revanced_seekbar_custom_color_summary_off">Original søgelinje farve vises</string> <string name="revanced_seekbar_custom_color_summary_off">Original søgelinje farve vises</string>
@@ -1280,8 +1223,8 @@ Aktivering af dette kan låse op for højere videokvalitet"</string>
</patch> </patch>
<patch id="misc.links.openLinksExternallyPatch"> <patch id="misc.links.openLinksExternallyPatch">
<string name="revanced_external_browser_title">Åbn links i browser</string> <string name="revanced_external_browser_title">Åbn links i browser</string>
<string name="revanced_external_browser_summary_on">Åbning af links eksternt</string> <string name="revanced_external_browser_summary_on">Åbner links i ekstern browser</string>
<string name="revanced_external_browser_summary_off">Åbner links i appen</string> <string name="revanced_external_browser_summary_off">Åbner links i browser i appen</string>
</patch> </patch>
<patch id="misc.privacy.removeTrackingQueryParameterPatch"> <patch id="misc.privacy.removeTrackingQueryParameterPatch">
<string name="revanced_remove_tracking_query_parameter_title">Fjern sporingsforespørgselsparameter</string> <string name="revanced_remove_tracking_query_parameter_title">Fjern sporingsforespørgselsparameter</string>
@@ -1308,9 +1251,15 @@ Aktivering af dette kan låse op for højere videokvalitet"</string>
<string name="revanced_remember_video_quality_last_selected_summary_off">Kvalitetsændringer gælder kun for den aktuelle video</string> <string name="revanced_remember_video_quality_last_selected_summary_off">Kvalitetsændringer gælder kun for den aktuelle video</string>
<string name="revanced_video_quality_default_wifi_title">Standard videokvalitet på Wi-Fi-netværk</string> <string name="revanced_video_quality_default_wifi_title">Standard videokvalitet på Wi-Fi-netværk</string>
<string name="revanced_video_quality_default_mobile_title">Standard videokvalitet på mobilnetværk</string> <string name="revanced_video_quality_default_mobile_title">Standard videokvalitet på mobilnetværk</string>
<string name="revanced_remember_shorts_quality_last_selected_title">Husk kvalitetsændringer for Shorts</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_on">Kvalitetsændringer gælder for alle Shorts</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_off">Kvalitetsændringer gælder kun for den aktuelle Short</string>
<string name="revanced_shorts_quality_default_wifi_title">Standard Shorts-kvalitet på Wi-Fi-netværk</string>
<string name="revanced_shorts_quality_default_mobile_title">Standard Shorts-kvalitet på mobilnetværk</string>
<string name="revanced_remember_video_quality_mobile">mobil</string> <string name="revanced_remember_video_quality_mobile">mobil</string>
<string name="revanced_remember_video_quality_wifi">Wi-Fi</string> <string name="revanced_remember_video_quality_wifi">Wi-Fi</string>
<string name="revanced_remember_video_quality_toast">Ændrede standard %1$s kvalitet til: %2$s</string> <string name="revanced_remember_video_quality_toast">Ændrede standard %1$s kvalitet til: %2$s</string>
<string name="revanced_remember_video_quality_toast_shorts">Ændrede Shorts %1$s kvalitet til: %2$s</string>
</patch> </patch>
<patch id="video.speed.button.playbackSpeedButtonPatch"> <patch id="video.speed.button.playbackSpeedButtonPatch">
<string name="revanced_playback_speed_dialog_button_title">Vis hastigheds dialogknap</string> <string name="revanced_playback_speed_dialog_button_title">Vis hastigheds dialogknap</string>
@@ -1341,10 +1290,10 @@ Aktivering af dette kan låse op for højere videokvalitet"</string>
<string name="revanced_disable_hdr_video_summary_on">HDR-video er deaktiveret</string> <string name="revanced_disable_hdr_video_summary_on">HDR-video er deaktiveret</string>
<string name="revanced_disable_hdr_video_summary_off">HDR-video er aktiveret</string> <string name="revanced_disable_hdr_video_summary_off">HDR-video er aktiveret</string>
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
<string name="revanced_restore_old_video_quality_menu_title">Gendan gamle video kvalitet menu</string> <string name="revanced_advanced_video_quality_menu_title">Vis avanceret menu for videokvalitet</string>
<string name="revanced_restore_old_video_quality_menu_summary_on">Gammel videokvalitetsmenu vises</string> <string name="revanced_advanced_video_quality_menu_summary_on">Avanceret menu for videokvalitet vises</string>
<string name="revanced_restore_old_video_quality_menu_summary_off">Gammel videokvalitetsmenu vises ikke</string> <string name="revanced_advanced_video_quality_menu_summary_off">Avanceret menu for videokvalitet vises ikke</string>
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
<string name="revanced_slide_to_seek_title">Aktivér dias for at søge</string> <string name="revanced_slide_to_seek_title">Aktivér dias for at søge</string>

View File

@@ -48,57 +48,6 @@ Second \"item\" text"</string>
Um neue Sprachen zu übersetzen, besuchen Sie translate.revanced.app"</string> Um neue Sprachen zu übersetzen, besuchen Sie translate.revanced.app"</string>
<string name="revanced_language_DEFAULT">App-Sprache</string> <string name="revanced_language_DEFAULT">App-Sprache</string>
<string name="revanced_language_AR">Arabisch</string>
<string name="revanced_language_AZ">Aserbaidschanisch</string>
<string name="revanced_language_BG">Bulgarisch</string>
<string name="revanced_language_BN">Bengali</string>
<string name="revanced_language_CA">Katalanisch</string>
<string name="revanced_language_CS">Tschechisch</string>
<string name="revanced_language_DA">Dänisch</string>
<string name="revanced_language_DE">Deutsch</string>
<string name="revanced_language_EL">Griechisch</string>
<string name="revanced_language_EN">Englisch</string>
<string name="revanced_language_ES">Spanisch</string>
<string name="revanced_language_ET">Estnisch</string>
<string name="revanced_language_FA">Persisch</string>
<string name="revanced_language_FI">Finnisch</string>
<string name="revanced_language_FR">Französisch</string>
<string name="revanced_language_GU">Gujarati</string>
<string name="revanced_language_HI">Hindi</string>
<string name="revanced_language_HR">Kroatisch</string>
<string name="revanced_language_HU">Ungarisch</string>
<string name="revanced_language_ID">Indonesisch</string>
<string name="revanced_language_IT">Italienisch</string>
<string name="revanced_language_JA">Japanisch</string>
<string name="revanced_language_KK">Kasachisch</string>
<string name="revanced_language_KO">Koreanisch</string>
<string name="revanced_language_LT">Litauisch</string>
<string name="revanced_language_LV">Lettisch</string>
<string name="revanced_language_MK">Mazedonisch</string>
<string name="revanced_language_MN">Mongolisch</string>
<string name="revanced_language_MR">Marathi</string>
<string name="revanced_language_MS">Malaiisch</string>
<string name="revanced_language_MY">Burmesisch</string>
<string name="revanced_language_NL">Niederländisch</string>
<string name="revanced_language_OR">Odia</string>
<string name="revanced_language_PA">Pandschabi</string>
<string name="revanced_language_PL">Polnisch</string>
<string name="revanced_language_PT">Portugiesisch</string>
<string name="revanced_language_RO">Rumänisch</string>
<string name="revanced_language_RU">Russisch</string>
<string name="revanced_language_SK">Slovakisch</string>
<string name="revanced_language_SL">Slowenisch</string>
<string name="revanced_language_SR">Serbisch</string>
<string name="revanced_language_SV">Schwedisch</string>
<string name="revanced_language_SW">Suaheli</string>
<string name="revanced_language_TA">Tamilisch</string>
<string name="revanced_language_TE">Telugu</string>
<string name="revanced_language_TH">Thai</string>
<string name="revanced_language_TR">Türkisch</string>
<string name="revanced_language_UK">Ukrainisch</string>
<string name="revanced_language_UR">Urdu</string>
<string name="revanced_language_VI">Vietnamesisch</string>
<string name="revanced_language_ZH">Chinesisch</string>
<string name="revanced_pref_import_export_title">Import/Export</string> <string name="revanced_pref_import_export_title">Import/Export</string>
<string name="revanced_pref_import_export_summary">ReVanced-Einstellungen importieren/exportieren</string> <string name="revanced_pref_import_export_summary">ReVanced-Einstellungen importieren/exportieren</string>
<!-- Settings about dialog. --> <!-- Settings about dialog. -->
@@ -297,13 +246,13 @@ Sie werden nicht über unerwartete Ereignisse informiert."</string>
<string name="revanced_hide_description_components_screen_title">Videobeschreibung</string> <string name="revanced_hide_description_components_screen_title">Videobeschreibung</string>
<string name="revanced_hide_description_components_screen_summary">Komponenten der Videobeschreibung ausblenden oder anzeigen</string> <string name="revanced_hide_description_components_screen_summary">Komponenten der Videobeschreibung ausblenden oder anzeigen</string>
<string name="revanced_hide_filter_bar_screen_title">Filterleiste</string> <string name="revanced_hide_filter_bar_screen_title">Filterleiste</string>
<string name="revanced_hide_filter_bar_screen_summary">Verstecke oder zeige die Filterleiste im Feed, in der Suche und verwandten Videos</string> <string name="revanced_hide_filter_bar_screen_summary">Die Filterleiste im Feed, in den Suchergebnissen und in verwandten Videos ein- oder ausblenden</string>
<string name="revanced_hide_filter_bar_feed_in_feed_title">Im Feed ausblenden</string> <string name="revanced_hide_filter_bar_feed_in_feed_title">Im Feed ausblenden</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Versteckt im Feed</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Versteckt im Feed</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Im Feed angezeigt</string> <string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Im Feed angezeigt</string>
<string name="revanced_hide_filter_bar_feed_in_search_title">In der Suche ausblenden</string> <string name="revanced_hide_filter_bar_feed_in_search_title">In Suchergebnissen ausblenden</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_on">Versteckt in der Suche</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_on">In Suchergebnissen versteckt</string>
<string name="revanced_hide_filter_bar_feed_in_search_summary_off">In der Suche angezeigt</string> <string name="revanced_hide_filter_bar_feed_in_search_summary_off">In den Suchergebnissen angezeigt</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">In verwandten Videos ausblenden</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_title">In verwandten Videos ausblenden</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Versteckt in verwandten Videos</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Versteckt in verwandten Videos</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">In verwandten Videos angezeigt</string> <string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">In verwandten Videos angezeigt</string>
@@ -399,7 +348,7 @@ Diese Funktion ist nur für ältere Geräte verfügbar"</string>
<string name="revanced_hide_self_sponsor_ads_title">Selbst gesponserte Karten ausblenden</string> <string name="revanced_hide_self_sponsor_ads_title">Selbst gesponserte Karten ausblenden</string>
<string name="revanced_hide_self_sponsor_ads_summary_on">Selbst gesponserte Karten sind ausgeblendet</string> <string name="revanced_hide_self_sponsor_ads_summary_on">Selbst gesponserte Karten sind ausgeblendet</string>
<string name="revanced_hide_self_sponsor_ads_summary_off">Selbstgesponserte Karten werden angezeigt</string> <string name="revanced_hide_self_sponsor_ads_summary_off">Selbstgesponserte Karten werden angezeigt</string>
<string name="revanced_hide_products_banner_title">Banner ausblenden, um Produkte anzuzeigen</string> <string name="revanced_hide_products_banner_title">Banner \"Produkte ansehen\" ausblenden</string>
<string name="revanced_hide_products_banner_summary_on">Banner ist ausgeblendet</string> <string name="revanced_hide_products_banner_summary_on">Banner ist ausgeblendet</string>
<string name="revanced_hide_products_banner_summary_off">Banner wird angezeigt</string> <string name="revanced_hide_products_banner_summary_off">Banner wird angezeigt</string>
<string name="revanced_hide_end_screen_store_banner_title">Endbild-Banner ausblenden</string> <string name="revanced_hide_end_screen_store_banner_title">Endbild-Banner ausblenden</string>
@@ -656,7 +605,7 @@ Wenn diese Änderung nicht wirksam wird, versuchen Sie, in den Inkognito-Modus z
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Video-Qualität Menü-Fußzeile wird angezeigt</string> <string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Video-Qualität Menü-Fußzeile wird angezeigt</string>
</patch> </patch>
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch"> <patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
<string name="revanced_hide_player_previous_next_buttons_title">Vorherige &amp; Nächste Video-Tasten ausblenden</string> <string name="revanced_hide_player_previous_next_buttons_title">Vorherige &amp; Nächste Tasten ausblenden</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Buttons sind ausgeblendet</string> <string name="revanced_hide_player_previous_next_buttons_summary_on">Buttons sind ausgeblendet</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Tasten werden angezeigt</string> <string name="revanced_hide_player_previous_next_buttons_summary_off">Tasten werden angezeigt</string>
<string name="revanced_hide_cast_button_title">Cast-Button ausblenden</string> <string name="revanced_hide_cast_button_title">Cast-Button ausblenden</string>
@@ -849,7 +798,6 @@ Einstellungen → Wiedergabe → Nächstes Video automatisch abspielen"</string>
<string name="revanced_ryd_enable_summary_on">Dislikes werden angezeigt</string> <string name="revanced_ryd_enable_summary_on">Dislikes werden angezeigt</string>
<string name="revanced_ryd_enable_summary_off">Dislikes werden nicht angezeigt</string> <string name="revanced_ryd_enable_summary_off">Dislikes werden nicht angezeigt</string>
<string name="revanced_ryd_shorts_title">Dislikes auf Shorts anzeigen</string> <string name="revanced_ryd_shorts_title">Dislikes auf Shorts anzeigen</string>
<string name="revanced_ryd_shorts_summary_on">Dislikes für Shorts werden angezeigt</string>
<string name="revanced_ryd_shorts_summary_on_disclaimer">"Dislikes für Shorts werden angezeigt <string name="revanced_ryd_shorts_summary_on_disclaimer">"Dislikes für Shorts werden angezeigt
Einschränkung: Dislikes werden möglicherweise nicht im Inkognito-Modus angezeigt"</string> Einschränkung: Dislikes werden möglicherweise nicht im Inkognito-Modus angezeigt"</string>
@@ -1047,6 +995,8 @@ Existiert bereits"</string>
<string name="revanced_sb_vote_downvote">Schlecht bewerten</string> <string name="revanced_sb_vote_downvote">Schlecht bewerten</string>
<string name="revanced_sb_vote_category">Kategorie ändern</string> <string name="revanced_sb_vote_category">Kategorie ändern</string>
<string name="revanced_sb_vote_no_segments">Es gibt keine Segmente zur Abstimmung</string> <string name="revanced_sb_vote_no_segments">Es gibt keine Segmente zur Abstimmung</string>
<!-- A segment start and end time, such as "02:10 to 03:40" -->
<string name="revanced_sb_vote_segment_time_to_from">%1$s bis %2$s</string>
<string name="revanced_sb_new_segment_choose_category">Wähle die Segmentkategorie</string> <string name="revanced_sb_new_segment_choose_category">Wähle die Segmentkategorie</string>
<string name="revanced_sb_new_segment_disabled_category">Kategorie ist in den Einstellungen deaktiviert. Aktivieren zum Senden.</string> <string name="revanced_sb_new_segment_disabled_category">Kategorie ist in den Einstellungen deaktiviert. Aktivieren zum Senden.</string>
<string name="revanced_sb_new_segment_title">Neues SponsorBlock Segment</string> <string name="revanced_sb_new_segment_title">Neues SponsorBlock Segment</string>
@@ -1094,6 +1044,7 @@ Bereit zum Einreichen?"</string>
<string name="revanced_sb_stats_saved_hour_format">%1$s Stunden %2$s Minuten</string> <string name="revanced_sb_stats_saved_hour_format">%1$s Stunden %2$s Minuten</string>
<string name="revanced_sb_stats_saved_minute_format">%1$s Minuten %2$s Sekunden</string> <string name="revanced_sb_stats_saved_minute_format">%1$s Minuten %2$s Sekunden</string>
<string name="revanced_sb_stats_saved_second_format">%s Sekunden</string> <string name="revanced_sb_stats_saved_second_format">%s Sekunden</string>
<string name="revanced_sb_color_opacity_label">Deckkraft:</string>
<string name="revanced_sb_color_dot_label">Farbe:</string> <string name="revanced_sb_color_dot_label">Farbe:</string>
<string name="revanced_sb_color_changed">Farbe geändert</string> <string name="revanced_sb_color_changed">Farbe geändert</string>
<string name="revanced_sb_color_reset">Farbe zurücksetzen</string> <string name="revanced_sb_color_reset">Farbe zurücksetzen</string>
@@ -1109,16 +1060,14 @@ Bereit zum Einreichen?"</string>
<string name="revanced_change_form_factor_entry_2">Telefon</string> <string name="revanced_change_form_factor_entry_2">Telefon</string>
<string name="revanced_change_form_factor_entry_3">Tablets</string> <string name="revanced_change_form_factor_entry_3">Tablets</string>
<string name="revanced_change_form_factor_entry_4">Automobil</string> <string name="revanced_change_form_factor_entry_4">Automobil</string>
<string name="revanced_change_form_factor_user_dialog_message">"Änderungen umfassen: <string name="revanced_change_form_factor_user_dialog_message">"Zu den Änderungen gehören:
Tablet-Layout Tablet-Layout
• Community-Beiträge werden ausgeblendet • Community-Beiträge sind ausgeblendet
Auto-Layout Automotive-Layout
Der Verlaufsmenü ist ausgeblendet Shorts werden im normalen Player geöffnet
Der Explore-Tab wird wiederhergestellt Feed ist nach Themen und Kanälen geordnet"</string>
• Shorts werden im regulären Player geöffnet
• Der Feed ist nach Themen und Kanälen organisiert"</string>
</patch> </patch>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<string name="revanced_spoof_app_version_title">Spoof-App-Version</string> <string name="revanced_spoof_app_version_title">Spoof-App-Version</string>
@@ -1133,12 +1082,7 @@ Wenn Sie die Funktion später deaktivieren, wird empfohlen, die App-Daten zu lö
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch --> This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
<string name="revanced_spoof_app_version_target_title">Spoof-App-Versionsziel</string> <string name="revanced_spoof_app_version_target_title">Spoof-App-Versionsziel</string>
<string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Alte Shorts Spielersymbole wiederherstellen</string> <string name="revanced_spoof_app_version_target_entry_1">19.35.36 - Alte Shorts Spielersymbole wiederherstellen</string>
<string name="revanced_spoof_app_version_target_entry_2">19.26.42 - Alte Navigations-Symbole wiederherstellen</string> <string name="revanced_spoof_app_version_target_entry_2">19.01.34 - Alte Navigations-Symbole wiederherstellen</string>
<!-- 'RYD' is 'Return YouTube Dislike' -->
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - RYD auf Shorts Inkognito-Modus wiederherstellen</string>
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Wiederherstellen der breiten Videogeschwindigkeit &amp; Qualitätsmenü</string>
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - Bibliotheks-Tab wiederherstellen</string>
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - Alte Wiedergabeliste wiederherstellen</string>
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
<string name="revanced_change_start_page_title">Startseite festlegen</string> <string name="revanced_change_start_page_title">Startseite festlegen</string>
@@ -1188,7 +1132,7 @@ Wenn Sie die Funktion später deaktivieren, wird empfohlen, die App-Daten zu lö
</patch> </patch>
<patch id="layout.miniplayer.miniplayerPatch"> <patch id="layout.miniplayer.miniplayerPatch">
<string name="revanced_miniplayer_screen_title">Minispieler</string> <string name="revanced_miniplayer_screen_title">Minispieler</string>
<string name="revanced_miniplayer_screen_summary">Ändere den Stil des in App minimierten Players</string> <string name="revanced_miniplayer_screen_summary">Das Aussehen des minimierten In-App-Players ändern</string>
<string name="revanced_miniplayer_type_title">Minispielertyp</string> <string name="revanced_miniplayer_type_title">Minispielertyp</string>
<string name="revanced_miniplayer_type_entry_0">Deaktiviert</string> <string name="revanced_miniplayer_type_entry_0">Deaktiviert</string>
<string name="revanced_miniplayer_type_entry_1">Standard</string> <string name="revanced_miniplayer_type_entry_1">Standard</string>
@@ -1241,8 +1185,6 @@ Wischen Sie, um zu erweitern oder zu schließen"</string>
<string name="revanced_gradient_loading_screen_title">Gradientenladebildschirm aktivieren</string> <string name="revanced_gradient_loading_screen_title">Gradientenladebildschirm aktivieren</string>
<string name="revanced_gradient_loading_screen_summary_on">Lade Bildschirm hat einen Farbverlauf Hintergrund</string> <string name="revanced_gradient_loading_screen_summary_on">Lade Bildschirm hat einen Farbverlauf Hintergrund</string>
<string name="revanced_gradient_loading_screen_summary_off">Das Laden des Bildschirms wird einen soliden Hintergrund haben</string> <string name="revanced_gradient_loading_screen_summary_off">Das Laden des Bildschirms wird einen soliden Hintergrund haben</string>
</patch>
<patch id="layout.theme.themeResourcePatch">
<string name="revanced_seekbar_custom_color_title">Eigene Suchleistenfarbe aktivieren</string> <string name="revanced_seekbar_custom_color_title">Eigene Suchleistenfarbe aktivieren</string>
<string name="revanced_seekbar_custom_color_summary_on">Angepasste Suchleistenfarbe wird angezeigt</string> <string name="revanced_seekbar_custom_color_summary_on">Angepasste Suchleistenfarbe wird angezeigt</string>
<string name="revanced_seekbar_custom_color_summary_off">Originalfarbe der Suchleiste wird angezeigt</string> <string name="revanced_seekbar_custom_color_summary_off">Originalfarbe der Suchleiste wird angezeigt</string>
@@ -1334,8 +1276,8 @@ Durch Aktivieren dieser Option können höhere Videoqualitäten freigeschaltet w
</patch> </patch>
<patch id="misc.links.openLinksExternallyPatch"> <patch id="misc.links.openLinksExternallyPatch">
<string name="revanced_external_browser_title">Links im Browser öffnen</string> <string name="revanced_external_browser_title">Links im Browser öffnen</string>
<string name="revanced_external_browser_summary_on">Links extern öffnen</string> <string name="revanced_external_browser_summary_on">Links im externen Browser öffnen</string>
<string name="revanced_external_browser_summary_off">Öffne Links in der App</string> <string name="revanced_external_browser_summary_off">Links im In-App-Browser öffnen</string>
</patch> </patch>
<patch id="misc.privacy.removeTrackingQueryParameterPatch"> <patch id="misc.privacy.removeTrackingQueryParameterPatch">
<string name="revanced_remove_tracking_query_parameter_title">Tracking-Abfrageparameter entfernen</string> <string name="revanced_remove_tracking_query_parameter_title">Tracking-Abfrageparameter entfernen</string>
@@ -1362,9 +1304,15 @@ Durch Aktivieren dieser Option können höhere Videoqualitäten freigeschaltet w
<string name="revanced_remember_video_quality_last_selected_summary_off">Qualitätsänderungen gelten nur für das aktuelle Video</string> <string name="revanced_remember_video_quality_last_selected_summary_off">Qualitätsänderungen gelten nur für das aktuelle Video</string>
<string name="revanced_video_quality_default_wifi_title">Standard-Videoqualität im Wi-Fi-Netzwerk</string> <string name="revanced_video_quality_default_wifi_title">Standard-Videoqualität im Wi-Fi-Netzwerk</string>
<string name="revanced_video_quality_default_mobile_title">Standard-Videoqualität im Mobilfunknetz</string> <string name="revanced_video_quality_default_mobile_title">Standard-Videoqualität im Mobilfunknetz</string>
<string name="revanced_remember_shorts_quality_last_selected_title">Änderungen der Shorts-Qualität speichern</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_on">Qualitätsänderungen gelten für alle Shorts</string>
<string name="revanced_remember_shorts_quality_last_selected_summary_off">Qualitätsänderungen gelten nur für den aktuellen Short</string>
<string name="revanced_shorts_quality_default_wifi_title">Standardmäßige Shorts-Qualität im WLAN</string>
<string name="revanced_shorts_quality_default_mobile_title">Standard-Shorts-Qualität im Mobilfunknetz</string>
<string name="revanced_remember_video_quality_mobile">Mobile</string> <string name="revanced_remember_video_quality_mobile">Mobile</string>
<string name="revanced_remember_video_quality_wifi">WLAN</string> <string name="revanced_remember_video_quality_wifi">WLAN</string>
<string name="revanced_remember_video_quality_toast">Standard %1$s Qualität geändert zu: %2$s</string> <string name="revanced_remember_video_quality_toast">Standard %1$s Qualität geändert zu: %2$s</string>
<string name="revanced_remember_video_quality_toast_shorts">Shorts-Qualität von %1$s geändert in: %2$s</string>
</patch> </patch>
<patch id="video.speed.button.playbackSpeedButtonPatch"> <patch id="video.speed.button.playbackSpeedButtonPatch">
<string name="revanced_playback_speed_dialog_button_title">Zeige Geschwindigkeitsdialog Taste</string> <string name="revanced_playback_speed_dialog_button_title">Zeige Geschwindigkeitsdialog Taste</string>
@@ -1395,10 +1343,10 @@ Durch Aktivieren dieser Option können höhere Videoqualitäten freigeschaltet w
<string name="revanced_disable_hdr_video_summary_on">HDR-Video ist deaktiviert</string> <string name="revanced_disable_hdr_video_summary_on">HDR-Video ist deaktiviert</string>
<string name="revanced_disable_hdr_video_summary_off">HDR-Video ist aktiviert</string> <string name="revanced_disable_hdr_video_summary_off">HDR-Video ist aktiviert</string>
</patch> </patch>
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch"> <patch id="video.quality.advancedVideoQualityMenuPatch">
<string name="revanced_restore_old_video_quality_menu_title">Altes Videoqualitätsmenü wiederherstellen</string> <string name="revanced_advanced_video_quality_menu_title">Erweitertes Videoqualitätsmenü anzeigen</string>
<string name="revanced_restore_old_video_quality_menu_summary_on">Altes Video-Qualitätsmenü wird angezeigt</string> <string name="revanced_advanced_video_quality_menu_summary_on">Erweitertes Videoqualitätsmenü wird angezeigt</string>
<string name="revanced_restore_old_video_quality_menu_summary_off">Altes Video-Qualitätsmenü wird nicht angezeigt</string> <string name="revanced_advanced_video_quality_menu_summary_off">Erweitertes Videoqualitätsmenü wird nicht angezeigt</string>
</patch> </patch>
<patch id="interaction.seekbar.enableSlideToSeekPatch"> <patch id="interaction.seekbar.enableSlideToSeekPatch">
<string name="revanced_slide_to_seek_title">Folie zum Suchen aktivieren</string> <string name="revanced_slide_to_seek_title">Folie zum Suchen aktivieren</string>

Some files were not shown because too many files have changed in this diff Show More