mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-09 02:43:57 +01:00
Compare commits
94 Commits
v5.7.0-dev
...
v5.10.0-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fdf0f85c1 | ||
|
|
1d12c4156d | ||
|
|
c43050dce8 | ||
|
|
8104bbd7d7 | ||
|
|
8487888e6b | ||
|
|
6721a284cd | ||
|
|
6cde702854 | ||
|
|
7c8efcaf41 | ||
|
|
350ee02e3b | ||
|
|
df2d070a43 | ||
|
|
8167aaccc8 | ||
|
|
f4989ed0a5 | ||
|
|
8f5a0531bc | ||
|
|
622554de14 | ||
|
|
66e330ffe6 | ||
|
|
2afcd3d63d | ||
|
|
80d7c78cf6 | ||
|
|
d85bcc3c16 | ||
|
|
21368ea696 | ||
|
|
e687d3ed37 | ||
|
|
064b859d39 | ||
|
|
89882ddaf8 | ||
|
|
41881ba161 | ||
|
|
0615990138 | ||
|
|
70532313db | ||
|
|
e5e897de77 | ||
|
|
1e57ce9658 | ||
|
|
fcad0ab5bb | ||
|
|
91471eccf9 | ||
|
|
d559f016c6 | ||
|
|
5a82d26f03 | ||
|
|
e2eae499d9 | ||
|
|
64919d6443 | ||
|
|
c6ffaf86ae | ||
|
|
3ee99b7bf1 | ||
|
|
6f9bf4873f | ||
|
|
29a73089a3 | ||
|
|
74ef1841eb | ||
|
|
0c544d28e3 | ||
|
|
b1e5b99b44 | ||
|
|
7b90baadb5 | ||
|
|
4a6f3c8555 | ||
|
|
e7c6943ca7 | ||
|
|
ae1b987c0d | ||
|
|
9496438da1 | ||
|
|
fa51631ea6 | ||
|
|
8bf7108001 | ||
|
|
030eece04a | ||
|
|
30009b723d | ||
|
|
53b25ea7e9 | ||
|
|
189e1c90c4 | ||
|
|
f01603b3f3 | ||
|
|
3db5651e5c | ||
|
|
f3c4d6fd64 | ||
|
|
29dbc9ffbf | ||
|
|
fa4aa54f0c | ||
|
|
1d89ada07f | ||
|
|
8c529abad5 | ||
|
|
4ade7c7329 | ||
|
|
f35247a872 | ||
|
|
4de768febf | ||
|
|
1a5c86db93 | ||
|
|
dbba795468 | ||
|
|
0a9320551d | ||
|
|
9fac1614e7 | ||
|
|
2de3523c59 | ||
|
|
ad1e40b130 | ||
|
|
094a6aa6de | ||
|
|
a14e03e4bb | ||
|
|
6f40b6d30f | ||
|
|
1711e1c39d | ||
|
|
25372828d1 | ||
|
|
f58245c6cd | ||
|
|
87e1c7f4c8 | ||
|
|
55d01c92d1 | ||
|
|
ca21a69550 | ||
|
|
634d0b4058 | ||
|
|
47ea8d5ec8 | ||
|
|
9509ed53f3 | ||
|
|
39542ddf55 | ||
|
|
e1741130af | ||
|
|
e54eb3ce87 | ||
|
|
0ae756b0fc | ||
|
|
77a0ac5c9c | ||
|
|
899121b9de | ||
|
|
838edb48e7 | ||
|
|
b2665c916a | ||
|
|
4b81f7009b | ||
|
|
1a4c39a2ee | ||
|
|
99334d1e53 | ||
|
|
2850a6ed4e | ||
|
|
f28eb5105b | ||
|
|
69bed4d9fa | ||
|
|
a5f1efac27 |
3
.github/workflows/pull_strings.yml
vendored
3
.github/workflows/pull_strings.yml
vendored
@@ -16,8 +16,9 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
|
||||||
ref: dev
|
ref: dev
|
||||||
|
fetch-depth: 0
|
||||||
|
clean: true
|
||||||
|
|
||||||
- name: Pull strings
|
- name: Pull strings
|
||||||
uses: crowdin/github-action@v2
|
uses: crowdin/github-action@v2
|
||||||
|
|||||||
271
CHANGELOG.md
271
CHANGELOG.md
@@ -1,3 +1,274 @@
|
|||||||
|
# [5.10.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.10.0-dev.1...v5.10.0-dev.2) (2025-01-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube:** Add patch `Disable HDR video` ([#4347](https://github.com/ReVanced/revanced-patches/issues/4347)) ([0528f7c](https://github.com/ReVanced/revanced-patches/commit/0528f7cad856a2b1347e41944167b0583fc4a3d9))
|
||||||
|
|
||||||
|
# [5.10.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.9.1-dev.4...v5.10.0-dev.1) (2025-01-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Theme:** Add option to use custom seekbar accent color ([#4337](https://github.com/ReVanced/revanced-patches/issues/4337)) ([952b4fc](https://github.com/ReVanced/revanced-patches/commit/952b4fc4c9291e1a3e71437b503857763c973dd4))
|
||||||
|
|
||||||
|
## [5.9.1-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.9.1-dev.3...v5.9.1-dev.4) (2025-01-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide layout components:** Hide new kind of community post ([#4341](https://github.com/ReVanced/revanced-patches/issues/4341)) ([02685c4](https://github.com/ReVanced/revanced-patches/commit/02685c4567aca55f22d45dc238a7d1f0ea264143))
|
||||||
|
|
||||||
|
## [5.9.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.9.1-dev.2...v5.9.1-dev.3) (2025-01-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide seekbar:** Do not hide player seekbar if hide feed seekbar is enabled ([#4333](https://github.com/ReVanced/revanced-patches/issues/4333)) ([f5cf6f2](https://github.com/ReVanced/revanced-patches/commit/f5cf6f2a445492d33815a9772f49deac2d70eba9))
|
||||||
|
|
||||||
|
## [5.9.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.9.1-dev.1...v5.9.1-dev.2) (2025-01-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Theme:** Fix 19.25 - 19.45 patch error ([5b47a5f](https://github.com/ReVanced/revanced-patches/commit/5b47a5f0f6299daaae209341064fd85f16ca18a6))
|
||||||
|
|
||||||
|
## [5.9.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.9.0...v5.9.1-dev.1) (2025-01-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Theme:** Replace custom seekbar gradient colors instead of disabling ([#4329](https://github.com/ReVanced/revanced-patches/issues/4329)) ([f03da98](https://github.com/ReVanced/revanced-patches/commit/f03da983051021e0c372557a5354d5d967409564))
|
||||||
|
|
||||||
|
# [5.9.0](https://github.com/ReVanced/revanced-patches/compare/v5.8.1...v5.9.0) (2025-01-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Spoof video streams:** Resolve playback issues after changing from cellular to wifi ([#4277](https://github.com/ReVanced/revanced-patches/issues/4277)) ([e93e1c8](https://github.com/ReVanced/revanced-patches/commit/e93e1c8ec3367e941034e9c4e3725ec1db429a60))
|
||||||
|
* **YouTube - Spoof video streams:** Update client user-agent ([#4304](https://github.com/ReVanced/revanced-patches/issues/4304)) ([7917871](https://github.com/ReVanced/revanced-patches/commit/7917871f510b6b805370ef98a0cf8a4e2df0e900))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Hide feed components:** Handle new type of surveys ([#4295](https://github.com/ReVanced/revanced-patches/issues/4295)) ([c770e03](https://github.com/ReVanced/revanced-patches/commit/c770e03f3801367cb531af860fbdfa43dca89af0))
|
||||||
|
* **YouTube - Playback speed:** Add option to change 2x tap and hold speed ([#4307](https://github.com/ReVanced/revanced-patches/issues/4307)) ([02fb26e](https://github.com/ReVanced/revanced-patches/commit/02fb26e9458fb8635d497e6e78f964055244d738))
|
||||||
|
* **YouTube - Settings:** Add option to use new Cairo settings menus ([#4305](https://github.com/ReVanced/revanced-patches/issues/4305)) ([7b8a2a2](https://github.com/ReVanced/revanced-patches/commit/7b8a2a2721ab5351f8c0251401aceddf0c5327df))
|
||||||
|
|
||||||
|
# [5.9.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.9.0-dev.3...v5.9.0-dev.4) (2025-01-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Spoof video streams:** Update client user-agent ([#4304](https://github.com/ReVanced/revanced-patches/issues/4304)) ([7917871](https://github.com/ReVanced/revanced-patches/commit/7917871f510b6b805370ef98a0cf8a4e2df0e900))
|
||||||
|
|
||||||
|
# [5.9.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.9.0-dev.2...v5.9.0-dev.3) (2025-01-19)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Settings:** Add option to use new Cairo settings menus ([#4305](https://github.com/ReVanced/revanced-patches/issues/4305)) ([7b8a2a2](https://github.com/ReVanced/revanced-patches/commit/7b8a2a2721ab5351f8c0251401aceddf0c5327df))
|
||||||
|
|
||||||
|
# [5.9.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.9.0-dev.1...v5.9.0-dev.2) (2025-01-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Playback speed:** Add option to change 2x tap and hold speed ([#4307](https://github.com/ReVanced/revanced-patches/issues/4307)) ([02fb26e](https://github.com/ReVanced/revanced-patches/commit/02fb26e9458fb8635d497e6e78f964055244d738))
|
||||||
|
|
||||||
|
# [5.9.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.8.2-dev.1...v5.9.0-dev.1) (2025-01-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Hide feed components:** Handle new type of surveys ([#4295](https://github.com/ReVanced/revanced-patches/issues/4295)) ([c770e03](https://github.com/ReVanced/revanced-patches/commit/c770e03f3801367cb531af860fbdfa43dca89af0))
|
||||||
|
|
||||||
|
## [5.8.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.8.1...v5.8.2-dev.1) (2025-01-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Spoof video streams:** Resolve playback issues after changing from cellular to wifi ([#4277](https://github.com/ReVanced/revanced-patches/issues/4277)) ([e93e1c8](https://github.com/ReVanced/revanced-patches/commit/e93e1c8ec3367e941034e9c4e3725ec1db429a60))
|
||||||
|
|
||||||
|
## [5.8.1](https://github.com/ReVanced/revanced-patches/compare/v5.8.0...v5.8.1) (2025-01-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Spoof video streams:** Add 'Android Creator' ([#4262](https://github.com/ReVanced/revanced-patches/issues/4262)) ([0479dd2](https://github.com/ReVanced/revanced-patches/commit/0479dd265e09b0accdf6ff6b00c8e938dc5b96c7))
|
||||||
|
|
||||||
|
## [5.8.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.8.0...v5.8.1-dev.1) (2025-01-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Spoof video streams:** Add 'Android Creator' ([#4262](https://github.com/ReVanced/revanced-patches/issues/4262)) ([0479dd2](https://github.com/ReVanced/revanced-patches/commit/0479dd265e09b0accdf6ff6b00c8e938dc5b96c7))
|
||||||
|
|
||||||
|
# [5.8.0](https://github.com/ReVanced/revanced-patches/compare/v5.7.2...v5.8.0) (2024-12-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **GmsCore support:** Do not show battery optimization error on Android Automotive devices (Google built-in) ([#4218](https://github.com/ReVanced/revanced-patches/issues/4218)) ([d6e389c](https://github.com/ReVanced/revanced-patches/commit/d6e389cc43bc40724f032b230f70048276349a19))
|
||||||
|
* **YouTube - Exit fullscreen mode:** Exit fullscreen mode of first video opened after cold start ([be5cf2e](https://github.com/ReVanced/revanced-patches/commit/be5cf2e834d87d51b5d3061d46bd7154d6306787))
|
||||||
|
* **YouTube - Force original audio:** If stream spoofing to Android then show a summary text why force audio is not available ([#4220](https://github.com/ReVanced/revanced-patches/issues/4220)) ([029aee8](https://github.com/ReVanced/revanced-patches/commit/029aee8023f096413fc80a2c583b4fe55ecb10ac))
|
||||||
|
* **YouTube - Spoof video streams:** Ignore harmless error toast if hide ads is disabled ([c3423bb](https://github.com/ReVanced/revanced-patches/commit/c3423bb9e531cfa52f6d28e0b98bbe8ab8684c30))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Swipe controls:** Add option to enable/disable fullscreen swipe to next video ([#4222](https://github.com/ReVanced/revanced-patches/issues/4222)) ([119092f](https://github.com/ReVanced/revanced-patches/commit/119092fafa4129849246df15fe8076ed3b491b85))
|
||||||
|
* **YouTube - Hide Shorts components:** Add option to hide Shorts in watch history ([#4214](https://github.com/ReVanced/revanced-patches/issues/4214)) ([19c2742](https://github.com/ReVanced/revanced-patches/commit/19c2742aa367367c77bb50ddad6f8a20fef8ea0a))
|
||||||
|
* **YouTube - Spoof app version:** Add 'Restore old navigation and toolbar icons' ([f84e459](https://github.com/ReVanced/revanced-patches/commit/f84e459d3d54b3001586796ab4e114ebadf09043))
|
||||||
|
* **YouTube:** Add `Change form factor` patch ([#4217](https://github.com/ReVanced/revanced-patches/issues/4217)) ([644ac5b](https://github.com/ReVanced/revanced-patches/commit/644ac5baa68b209a32300149a2efa009b776f9a7))
|
||||||
|
* **YouTube:** Add `Exit fullscreen mode` patch ([#4223](https://github.com/ReVanced/revanced-patches/issues/4223)) ([bb5d03b](https://github.com/ReVanced/revanced-patches/commit/bb5d03bd89a3f932c77e4e9de90174c374933688))
|
||||||
|
* **YouTube:** Add in app option to select a preferred language for ReVanced specific text ([#4231](https://github.com/ReVanced/revanced-patches/issues/4231)) ([3932af3](https://github.com/ReVanced/revanced-patches/commit/3932af397ae89a0b30191cd870bd6cddb7a078db))
|
||||||
|
|
||||||
|
# [5.8.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.8.0-dev.7...v5.8.0-dev.8) (2024-12-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube:** Add in app option to select a preferred language for ReVanced specific text ([#4231](https://github.com/ReVanced/revanced-patches/issues/4231)) ([3932af3](https://github.com/ReVanced/revanced-patches/commit/3932af397ae89a0b30191cd870bd6cddb7a078db))
|
||||||
|
|
||||||
|
# [5.8.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.8.0-dev.6...v5.8.0-dev.7) (2024-12-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Spoof video streams:** Ignore harmless error toast if hide ads is disabled ([c3423bb](https://github.com/ReVanced/revanced-patches/commit/c3423bb9e531cfa52f6d28e0b98bbe8ab8684c30))
|
||||||
|
|
||||||
|
# [5.8.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.8.0-dev.5...v5.8.0-dev.6) (2024-12-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Exit fullscreen mode:** Exit fullscreen mode of first video opened after cold start ([be5cf2e](https://github.com/ReVanced/revanced-patches/commit/be5cf2e834d87d51b5d3061d46bd7154d6306787))
|
||||||
|
|
||||||
|
# [5.8.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.8.0-dev.4...v5.8.0-dev.5) (2024-12-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube:** Add `Change form factor` patch ([#4217](https://github.com/ReVanced/revanced-patches/issues/4217)) ([644ac5b](https://github.com/ReVanced/revanced-patches/commit/644ac5baa68b209a32300149a2efa009b776f9a7))
|
||||||
|
|
||||||
|
# [5.8.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.8.0-dev.3...v5.8.0-dev.4) (2024-12-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **GmsCore support:** Do not show battery optimization error on Android Automotive devices (Google built-in) ([#4218](https://github.com/ReVanced/revanced-patches/issues/4218)) ([d6e389c](https://github.com/ReVanced/revanced-patches/commit/d6e389cc43bc40724f032b230f70048276349a19))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Swipe controls:** Add option to enable/disable fullscreen swipe to next video ([#4222](https://github.com/ReVanced/revanced-patches/issues/4222)) ([119092f](https://github.com/ReVanced/revanced-patches/commit/119092fafa4129849246df15fe8076ed3b491b85))
|
||||||
|
* **YouTube:** Add `Exit fullscreen mode` patch ([#4223](https://github.com/ReVanced/revanced-patches/issues/4223)) ([bb5d03b](https://github.com/ReVanced/revanced-patches/commit/bb5d03bd89a3f932c77e4e9de90174c374933688))
|
||||||
|
|
||||||
|
# [5.8.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.8.0-dev.2...v5.8.0-dev.3) (2024-12-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Force original audio:** If stream spoofing to Android then show a summary text why force audio is not available ([#4220](https://github.com/ReVanced/revanced-patches/issues/4220)) ([029aee8](https://github.com/ReVanced/revanced-patches/commit/029aee8023f096413fc80a2c583b4fe55ecb10ac))
|
||||||
|
|
||||||
|
# [5.8.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.8.0-dev.1...v5.8.0-dev.2) (2024-12-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Spoof app version:** Add 'Restore old navigation and toolbar icons' ([f84e459](https://github.com/ReVanced/revanced-patches/commit/f84e459d3d54b3001586796ab4e114ebadf09043))
|
||||||
|
|
||||||
|
# [5.8.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.7.2...v5.8.0-dev.1) (2024-12-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Hide Shorts components:** Add option to hide Shorts in watch history ([#4214](https://github.com/ReVanced/revanced-patches/issues/4214)) ([19c2742](https://github.com/ReVanced/revanced-patches/commit/19c2742aa367367c77bb50ddad6f8a20fef8ea0a))
|
||||||
|
|
||||||
|
## [5.7.2](https://github.com/ReVanced/revanced-patches/compare/v5.7.1...v5.7.2) (2024-12-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide layout components:** Don't hide Shorts channel bar when toggling for video player ([9af6412](https://github.com/ReVanced/revanced-patches/commit/9af6412d92ec31e612eaabba6578453da0fc61d6))
|
||||||
|
* **YouTube - Spoof video streams:** Add iOS TV client, restore iOS 'force AVC', show client type in stats for nerds ([#4202](https://github.com/ReVanced/revanced-patches/issues/4202)) ([ab29f80](https://github.com/ReVanced/revanced-patches/commit/ab29f808a9f55b5ab0055533c1a6de549b0631a6))
|
||||||
|
|
||||||
|
## [5.7.2-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.7.2-dev.1...v5.7.2-dev.2) (2024-12-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide layout components:** Don't hide Shorts channel bar when toggling for video player ([9af6412](https://github.com/ReVanced/revanced-patches/commit/9af6412d92ec31e612eaabba6578453da0fc61d6))
|
||||||
|
|
||||||
|
## [5.7.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.7.1...v5.7.2-dev.1) (2024-12-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Spoof video streams:** Add iOS TV client, restore iOS 'force AVC', show client type in stats for nerds ([#4202](https://github.com/ReVanced/revanced-patches/issues/4202)) ([ab29f80](https://github.com/ReVanced/revanced-patches/commit/ab29f808a9f55b5ab0055533c1a6de549b0631a6))
|
||||||
|
|
||||||
|
## [5.7.1](https://github.com/ReVanced/revanced-patches/compare/v5.7.0...v5.7.1) (2024-12-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - SponsorBlock:** Show a toast and not a dialog if segment submitted successfully ([134b189](https://github.com/ReVanced/revanced-patches/commit/134b189791113dcf1a1cb7c87b8a0954f432730c))
|
||||||
|
* **YouTube - Spoof video streams:** Use 2 letter device language code ([33ff997](https://github.com/ReVanced/revanced-patches/commit/33ff9972000581aca92262f984efb114eeeb9537))
|
||||||
|
* **YouTube - Spoof video streams:** Use Android VR authentication if using default audio language ([#4191](https://github.com/ReVanced/revanced-patches/issues/4191)) ([98773cc](https://github.com/ReVanced/revanced-patches/commit/98773cc7d46e5c9c7715b82c8006f1ccbcc5443c))
|
||||||
|
* **YouTube - Theme:** Use dark theme color for status and navigation bar ([0240efe](https://github.com/ReVanced/revanced-patches/commit/0240efe33e5444625ca2b760c861c9046d3dc836))
|
||||||
|
* **YouTube:** Do not reset playback speed to 1.0x after closing comment thread (Fixes stock YouTube bug) ([#4195](https://github.com/ReVanced/revanced-patches/issues/4195)) ([dda788c](https://github.com/ReVanced/revanced-patches/commit/dda788c58c789d4f91646ea8e8a8077f590ab6b3))
|
||||||
|
|
||||||
|
## [5.7.1-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.7.1-dev.4...v5.7.1-dev.5) (2024-12-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Spoof video streams:** Use 2 letter device language code ([33ff997](https://github.com/ReVanced/revanced-patches/commit/33ff9972000581aca92262f984efb114eeeb9537))
|
||||||
|
|
||||||
|
## [5.7.1-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.7.1-dev.3...v5.7.1-dev.4) (2024-12-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube:** Do not reset playback speed to 1.0x after closing comment thread (Fixes stock YouTube bug) ([#4195](https://github.com/ReVanced/revanced-patches/issues/4195)) ([dda788c](https://github.com/ReVanced/revanced-patches/commit/dda788c58c789d4f91646ea8e8a8077f590ab6b3))
|
||||||
|
|
||||||
|
## [5.7.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.7.1-dev.2...v5.7.1-dev.3) (2024-12-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - SponsorBlock:** Show a toast and not a dialog if segment submitted successfully ([134b189](https://github.com/ReVanced/revanced-patches/commit/134b189791113dcf1a1cb7c87b8a0954f432730c))
|
||||||
|
|
||||||
|
## [5.7.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.7.1-dev.1...v5.7.1-dev.2) (2024-12-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Theme:** Use dark theme color for status and navigation bar ([0240efe](https://github.com/ReVanced/revanced-patches/commit/0240efe33e5444625ca2b760c861c9046d3dc836))
|
||||||
|
|
||||||
|
## [5.7.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.7.0...v5.7.1-dev.1) (2024-12-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Spoof video streams:** Use Android VR authentication if using default audio language ([#4191](https://github.com/ReVanced/revanced-patches/issues/4191)) ([98773cc](https://github.com/ReVanced/revanced-patches/commit/98773cc7d46e5c9c7715b82c8006f1ccbcc5443c))
|
||||||
|
|
||||||
|
# [5.7.0](https://github.com/ReVanced/revanced-patches/compare/v5.6.0...v5.7.0) (2024-12-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Force original audio:** Use correct availability for settings UI ([a7eedcb](https://github.com/ReVanced/revanced-patches/commit/a7eedcb4cca6b7b12629c478c24c0899c80e3615))
|
||||||
|
* **YouTube - Spoof video stream:** Remove UI client type setting. Allow setting default audio language. ([#4184](https://github.com/ReVanced/revanced-patches/issues/4184)) ([99f3f29](https://github.com/ReVanced/revanced-patches/commit/99f3f29c649bf7693c05bbce2bb49bd53e05f050))
|
||||||
|
* **YouTube - Spoof video streams:** Remove iOS, add clients Android TV and Android Creator ([#4180](https://github.com/ReVanced/revanced-patches/issues/4180)) ([86abfb2](https://github.com/ReVanced/revanced-patches/commit/86abfb2b0d4675f0a1cb9ab244783075bfe89281))
|
||||||
|
* **YouTube:** Change fingerprints to support a wider range of target versions ([8a09174](https://github.com/ReVanced/revanced-patches/commit/8a09174def205a26ce49cb7815097e235069526a))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube:** Support version `19.47.53` ([#4182](https://github.com/ReVanced/revanced-patches/issues/4182)) ([2089e61](https://github.com/ReVanced/revanced-patches/commit/2089e613d36c45352db7d852aaee0087b1c3e1a4))
|
||||||
|
|
||||||
# [5.7.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.6.1-dev.4...v5.7.0-dev.1) (2024-12-21)
|
# [5.7.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.6.1-dev.4...v5.7.0-dev.1) (2024-12-21)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -106,7 +106,11 @@ public class GmsCoreSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if GmsCore is whitelisted from battery optimizations.
|
// Check if GmsCore is whitelisted from battery optimizations.
|
||||||
if (batteryOptimizationsEnabled(context)) {
|
if (isAndroidAutomotive(context)) {
|
||||||
|
// Ignore Android Automotive devices (Google built-in),
|
||||||
|
// as there is no way to disable battery optimizations.
|
||||||
|
Logger.printDebug(() -> "Device is Android Automotive");
|
||||||
|
} else if (batteryOptimizationsEnabled(context)) {
|
||||||
Logger.printInfo(() -> "GmsCore is not whitelisted from battery optimizations");
|
Logger.printInfo(() -> "GmsCore is not whitelisted from battery optimizations");
|
||||||
|
|
||||||
showBatteryOptimizationDialog(context,
|
showBatteryOptimizationDialog(context,
|
||||||
@@ -147,6 +151,10 @@ public class GmsCoreSupport {
|
|||||||
return !powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME);
|
return !powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isAndroidAutomotive(Context context) {
|
||||||
|
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
private static String getGmsCoreDownload() {
|
private static String getGmsCoreDownload() {
|
||||||
final var vendorGroupId = getGmsCoreVendorGroupId();
|
final var vendorGroupId = getGmsCoreVendorGroupId();
|
||||||
//noinspection SwitchStatementWithTooFewBranches
|
//noinspection SwitchStatementWithTooFewBranches
|
||||||
|
|||||||
@@ -40,13 +40,15 @@ import java.util.concurrent.SynchronousQueue;
|
|||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.settings.AppLanguage;
|
||||||
|
import app.revanced.extension.shared.settings.BaseSettings;
|
||||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||||
import app.revanced.extension.shared.settings.preference.ReVancedAboutPreference;
|
import app.revanced.extension.shared.settings.preference.ReVancedAboutPreference;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
private static Context context;
|
private static volatile Context context;
|
||||||
|
|
||||||
private static String versionName;
|
private static String versionName;
|
||||||
private static String applicationLabel;
|
private static String applicationLabel;
|
||||||
@@ -360,7 +362,17 @@ 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.
|
||||||
context = appContext;
|
context = appContext;
|
||||||
|
|
||||||
|
AppLanguage language = BaseSettings.REVANCED_LANGUAGE.get();
|
||||||
|
if (language != AppLanguage.DEFAULT) {
|
||||||
|
// Create a new context with the desired language.
|
||||||
|
Configuration config = appContext.getResources().getConfiguration();
|
||||||
|
config.setLocale(language.getLocale());
|
||||||
|
context = appContext.createConfigurationContext(config);
|
||||||
|
}
|
||||||
|
|
||||||
// In some apps like TikTok, the Setting classes can load in weird orders due to cyclic class dependencies.
|
// 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,
|
// Calling the regular printDebug method here can cause a Settings context null pointer exception,
|
||||||
// even though the context is already set before the call.
|
// even though the context is already set before the call.
|
||||||
@@ -523,6 +535,11 @@ public class Utils {
|
|||||||
return currentNightMode == Configuration.UI_MODE_NIGHT_YES;
|
return currentNightMode == Configuration.UI_MODE_NIGHT_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isLandscapeOrientation() {
|
||||||
|
final int orientation = context.getResources().getConfiguration().orientation;
|
||||||
|
return orientation == Configuration.ORIENTATION_LANDSCAPE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically logs any exceptions the runnable throws.
|
* Automatically logs any exceptions the runnable throws.
|
||||||
*
|
*
|
||||||
@@ -595,7 +612,7 @@ public class Utils {
|
|||||||
|| networkType == NetworkType.OTHER;
|
|| networkType == NetworkType.OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("MissingPermission") // permission already included in YouTube
|
@SuppressLint({"MissingPermission", "deprecation"}) // Permission already included in YouTube.
|
||||||
public static NetworkType getNetworkType() {
|
public static NetworkType getNetworkType() {
|
||||||
Context networkContext = getContext();
|
Context networkContext = getContext();
|
||||||
if (networkContext == null) {
|
if (networkContext == null) {
|
||||||
@@ -705,8 +722,8 @@ public class Utils {
|
|||||||
Preference preference = group.getPreference(i);
|
Preference preference = group.getPreference(i);
|
||||||
|
|
||||||
final Sort preferenceSort;
|
final Sort preferenceSort;
|
||||||
if (preference instanceof PreferenceGroup) {
|
if (preference instanceof PreferenceGroup subGroup) {
|
||||||
sortPreferenceGroups((PreferenceGroup) preference);
|
sortPreferenceGroups(subGroup);
|
||||||
preferenceSort = groupSort; // Sort value for groups is for it's content, not itself.
|
preferenceSort = groupSort; // Sort value for groups is for it's content, not itself.
|
||||||
} else {
|
} else {
|
||||||
// Allow individual preferences to set a key sorting.
|
// Allow individual preferences to set a key sorting.
|
||||||
@@ -760,8 +777,8 @@ public class Utils {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String deviceLanguage = Utils.getContext().getResources().getConfiguration().locale.getLanguage();
|
String revancedLocale = Utils.getContext().getResources().getConfiguration().locale.getLanguage();
|
||||||
if (deviceLanguage.equals("en")) {
|
if (revancedLocale.equals(Locale.ENGLISH.getLanguage())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -769,8 +786,8 @@ public class Utils {
|
|||||||
Preference pref = group.getPreference(i);
|
Preference pref = group.getPreference(i);
|
||||||
pref.setSingleLineTitle(false);
|
pref.setSingleLineTitle(false);
|
||||||
|
|
||||||
if (pref instanceof PreferenceGroup) {
|
if (pref instanceof PreferenceGroup subGroup) {
|
||||||
setPreferenceTitlesToMultiLineIfNeeded((PreferenceGroup) pref);
|
setPreferenceTitlesToMultiLineIfNeeded(subGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package app.revanced.extension.shared.settings;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public enum AppLanguage {
|
||||||
|
/**
|
||||||
|
* The current app language.
|
||||||
|
*/
|
||||||
|
DEFAULT,
|
||||||
|
|
||||||
|
// Language codes found in locale_config.xml
|
||||||
|
// All region specific variants have been removed.
|
||||||
|
AF,
|
||||||
|
AM,
|
||||||
|
AR,
|
||||||
|
AS,
|
||||||
|
AZ,
|
||||||
|
BE,
|
||||||
|
BG,
|
||||||
|
BN,
|
||||||
|
BS,
|
||||||
|
CA,
|
||||||
|
CS,
|
||||||
|
DA,
|
||||||
|
DE,
|
||||||
|
EL,
|
||||||
|
EN,
|
||||||
|
ES,
|
||||||
|
ET,
|
||||||
|
EU,
|
||||||
|
FA,
|
||||||
|
FI,
|
||||||
|
FR,
|
||||||
|
GL,
|
||||||
|
GU,
|
||||||
|
HI,
|
||||||
|
HE, // App uses obsolete 'IW' and not the modern 'HE' ISO code.
|
||||||
|
HR,
|
||||||
|
HU,
|
||||||
|
HY,
|
||||||
|
ID,
|
||||||
|
IS,
|
||||||
|
IT,
|
||||||
|
JA,
|
||||||
|
KA,
|
||||||
|
KK,
|
||||||
|
KM,
|
||||||
|
KN,
|
||||||
|
KO,
|
||||||
|
KY,
|
||||||
|
LO,
|
||||||
|
LT,
|
||||||
|
LV,
|
||||||
|
MK,
|
||||||
|
ML,
|
||||||
|
MN,
|
||||||
|
MR,
|
||||||
|
MS,
|
||||||
|
MY,
|
||||||
|
NE,
|
||||||
|
NL,
|
||||||
|
NB,
|
||||||
|
OR,
|
||||||
|
PA,
|
||||||
|
PL,
|
||||||
|
PT,
|
||||||
|
RO,
|
||||||
|
RU,
|
||||||
|
SI,
|
||||||
|
SK,
|
||||||
|
SL,
|
||||||
|
SQ,
|
||||||
|
SR,
|
||||||
|
SV,
|
||||||
|
SW,
|
||||||
|
TA,
|
||||||
|
TE,
|
||||||
|
TH,
|
||||||
|
TL,
|
||||||
|
TR,
|
||||||
|
UK,
|
||||||
|
UR,
|
||||||
|
UZ,
|
||||||
|
VI,
|
||||||
|
ZH,
|
||||||
|
ZU;
|
||||||
|
|
||||||
|
private final String language;
|
||||||
|
|
||||||
|
AppLanguage() {
|
||||||
|
language = name().toLowerCase(Locale.US);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The 2 letter ISO 639_1 language code.
|
||||||
|
*/
|
||||||
|
public String getLanguage() {
|
||||||
|
// Changing the app language does not force the app to completely restart,
|
||||||
|
// so the default needs to be the current language and not a static field.
|
||||||
|
if (this == DEFAULT) {
|
||||||
|
return Locale.getDefault().getLanguage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Locale getLocale() {
|
||||||
|
if (this == DEFAULT) {
|
||||||
|
return Locale.getDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Locale.forLanguageTag(language);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,8 +3,10 @@ package app.revanced.extension.shared.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.parent;
|
import static app.revanced.extension.shared.settings.Setting.parent;
|
||||||
|
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.AudioStreamLanguageOverrideAvailability;
|
||||||
|
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.SpoofiOSAvailability;
|
||||||
|
|
||||||
import app.revanced.extension.shared.spoof.AudioStreamLanguage;
|
import app.revanced.extension.shared.spoof.ClientType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings shared across multiple apps.
|
* Settings shared across multiple apps.
|
||||||
@@ -19,6 +21,14 @@ public class BaseSettings {
|
|||||||
|
|
||||||
public static final IntegerSetting CHECK_ENVIRONMENT_WARNINGS_ISSUED = new IntegerSetting("revanced_check_environment_warnings_issued", 0, true, false);
|
public static final IntegerSetting CHECK_ENVIRONMENT_WARNINGS_ISSUED = new IntegerSetting("revanced_check_environment_warnings_issued", 0, true, false);
|
||||||
|
|
||||||
|
public static final EnumSetting<AppLanguage> REVANCED_LANGUAGE = new EnumSetting<>("revanced_language", AppLanguage.DEFAULT, true, "revanced_language_user_dialog_message");
|
||||||
|
|
||||||
public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true, "revanced_spoof_video_streams_user_dialog_message");
|
public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true, "revanced_spoof_video_streams_user_dialog_message");
|
||||||
public static final EnumSetting<AudioStreamLanguage> SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AudioStreamLanguage.DEFAULT, parent(SPOOF_VIDEO_STREAMS));
|
public static final EnumSetting<AppLanguage> SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AppLanguage.DEFAULT, new AudioStreamLanguageOverrideAvailability());
|
||||||
|
public static final BooleanSetting SPOOF_STREAMING_DATA_STATS_FOR_NERDS = new BooleanSetting("revanced_spoof_streaming_data_stats_for_nerds", TRUE, parent(SPOOF_VIDEO_STREAMS));
|
||||||
|
public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
|
||||||
|
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofiOSAvailability());
|
||||||
|
// Client type must be last spoof setting due to cyclic references.
|
||||||
|
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,7 +153,6 @@ public abstract class Setting<T> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirmation message to display, if the user tries to change the setting from the default value.
|
* Confirmation message to display, if the user tries to change the setting from the default value.
|
||||||
* Currently this works only for Boolean setting types.
|
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public final StringRef userDialogMessage;
|
public final StringRef userDialogMessage;
|
||||||
@@ -244,6 +243,7 @@ public abstract class Setting<T> {
|
|||||||
*
|
*
|
||||||
* This method will be deleted in the future.
|
* This method will be deleted in the future.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
public static void migrateFromOldPreferences(@NonNull SharedPrefCategory oldPrefs, @NonNull Setting setting, String settingKey) {
|
public static void migrateFromOldPreferences(@NonNull SharedPrefCategory oldPrefs, @NonNull Setting setting, String settingKey) {
|
||||||
if (!oldPrefs.preferences.contains(settingKey)) {
|
if (!oldPrefs.preferences.contains(settingKey)) {
|
||||||
return; // Nothing to do.
|
return; // Nothing to do.
|
||||||
@@ -419,6 +419,7 @@ public abstract class Setting<T> {
|
|||||||
|
|
||||||
boolean rebootSettingChanged = false;
|
boolean rebootSettingChanged = false;
|
||||||
int numberOfSettingsImported = 0;
|
int numberOfSettingsImported = 0;
|
||||||
|
//noinspection rawtypes
|
||||||
for (Setting setting : SETTINGS) {
|
for (Setting setting : SETTINGS) {
|
||||||
String key = setting.getImportExportKey();
|
String key = setting.getImportExportKey();
|
||||||
if (json.has(key)) {
|
if (json.has(key)) {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
|
|
||||||
private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
|
private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
|
||||||
try {
|
try {
|
||||||
Setting<?> setting = Setting.getSettingFromPath(str);
|
Setting<?> setting = Setting.getSettingFromPath(Objects.requireNonNull(str));
|
||||||
if (setting == null) {
|
if (setting == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -52,23 +52,21 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
}
|
}
|
||||||
Logger.printDebug(() -> "Preference changed: " + setting.key);
|
Logger.printDebug(() -> "Preference changed: " + setting.key);
|
||||||
|
|
||||||
// Apply 'Setting <- Preference', unless during importing when it needs to be 'Setting -> Preference'.
|
if (!settingImportInProgress && !showingUserDialogMessage) {
|
||||||
updatePreference(pref, setting, true, settingImportInProgress);
|
if (setting.userDialogMessage != null && !prefIsSetToDefault(pref, setting)) {
|
||||||
// Update any other preference availability that may now be different.
|
// Do not change the setting yet, to allow preserving whatever
|
||||||
updateUIAvailability();
|
// list/text value was previously set if it needs to be reverted.
|
||||||
|
showSettingUserDialogConfirmation(pref, setting);
|
||||||
if (settingImportInProgress) {
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!showingUserDialogMessage) {
|
|
||||||
if (setting.userDialogMessage != null && ((SwitchPreference) pref).isChecked() != (Boolean) setting.defaultValue) {
|
|
||||||
showSettingUserDialogConfirmation((SwitchPreference) pref, (BooleanSetting) setting);
|
|
||||||
} else if (setting.rebootApp) {
|
} else if (setting.rebootApp) {
|
||||||
showRestartDialog(getContext());
|
showRestartDialog(getContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply 'Setting <- Preference', unless during importing when it needs to be 'Setting -> Preference'.
|
||||||
|
updatePreference(pref, setting, true, settingImportInProgress);
|
||||||
|
// Update any other preference availability that may now be different.
|
||||||
|
updateUIAvailability();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "OnSharedPreferenceChangeListener failure", ex);
|
Logger.printException(() -> "OnSharedPreferenceChangeListener failure", ex);
|
||||||
}
|
}
|
||||||
@@ -92,7 +90,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
Utils.setPreferenceTitlesToMultiLineIfNeeded(screen);
|
Utils.setPreferenceTitlesToMultiLineIfNeeded(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showSettingUserDialogConfirmation(SwitchPreference switchPref, BooleanSetting setting) {
|
private void showSettingUserDialogConfirmation(Preference pref, Setting<?> setting) {
|
||||||
Utils.verifyOnMainThread();
|
Utils.verifyOnMainThread();
|
||||||
|
|
||||||
final var context = getContext();
|
final var context = getContext();
|
||||||
@@ -104,12 +102,19 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
.setTitle(confirmDialogTitle)
|
.setTitle(confirmDialogTitle)
|
||||||
.setMessage(Objects.requireNonNull(setting.userDialogMessage).toString())
|
.setMessage(Objects.requireNonNull(setting.userDialogMessage).toString())
|
||||||
.setPositiveButton(android.R.string.ok, (dialog, id) -> {
|
.setPositiveButton(android.R.string.ok, (dialog, id) -> {
|
||||||
|
// User confirmed, save to the Setting.
|
||||||
|
updatePreference(pref, setting, true, false);
|
||||||
|
|
||||||
|
// Update availability of other preferences that may be changed.
|
||||||
|
updateUIAvailability();
|
||||||
|
|
||||||
if (setting.rebootApp) {
|
if (setting.rebootApp) {
|
||||||
showRestartDialog(context);
|
showRestartDialog(context);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setNegativeButton(android.R.string.cancel, (dialog, id) -> {
|
.setNegativeButton(android.R.string.cancel, (dialog, id) -> {
|
||||||
switchPref.setChecked(setting.defaultValue); // Recursive call that resets the Setting value.
|
// Restore whatever the setting was before the change.
|
||||||
|
updatePreference(pref, setting, true, true);
|
||||||
})
|
})
|
||||||
.setOnDismissListener(dialog -> {
|
.setOnDismissListener(dialog -> {
|
||||||
showingUserDialogMessage = false;
|
showingUserDialogMessage = false;
|
||||||
@@ -132,6 +137,24 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
updatePreferenceScreen(getPreferenceScreen(), false, false);
|
updatePreferenceScreen(getPreferenceScreen(), false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return If the preference is currently set to the default value of the Setting.
|
||||||
|
*/
|
||||||
|
protected boolean prefIsSetToDefault(Preference pref, Setting<?> setting) {
|
||||||
|
if (pref instanceof SwitchPreference switchPref) {
|
||||||
|
return switchPref.isChecked() == (Boolean) setting.defaultValue;
|
||||||
|
}
|
||||||
|
if (pref instanceof EditTextPreference editPreference) {
|
||||||
|
return editPreference.getText().equals(setting.defaultValue.toString());
|
||||||
|
}
|
||||||
|
if (pref instanceof ListPreference listPref) {
|
||||||
|
return listPref.getValue().equals(setting.defaultValue.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalStateException("Must override method to handle "
|
||||||
|
+ "preference type: " + pref.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syncs all UI Preferences to any {@link Setting} they represent.
|
* Syncs all UI Preferences to any {@link Setting} they represent.
|
||||||
*/
|
*/
|
||||||
@@ -170,23 +193,20 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
|||||||
protected void syncSettingWithPreference(@NonNull Preference pref,
|
protected void syncSettingWithPreference(@NonNull Preference pref,
|
||||||
@NonNull Setting<?> setting,
|
@NonNull Setting<?> setting,
|
||||||
boolean applySettingToPreference) {
|
boolean applySettingToPreference) {
|
||||||
if (pref instanceof SwitchPreference) {
|
if (pref instanceof SwitchPreference switchPref) {
|
||||||
SwitchPreference switchPref = (SwitchPreference) pref;
|
|
||||||
BooleanSetting boolSetting = (BooleanSetting) setting;
|
BooleanSetting boolSetting = (BooleanSetting) setting;
|
||||||
if (applySettingToPreference) {
|
if (applySettingToPreference) {
|
||||||
switchPref.setChecked(boolSetting.get());
|
switchPref.setChecked(boolSetting.get());
|
||||||
} else {
|
} else {
|
||||||
BooleanSetting.privateSetValue(boolSetting, switchPref.isChecked());
|
BooleanSetting.privateSetValue(boolSetting, switchPref.isChecked());
|
||||||
}
|
}
|
||||||
} else if (pref instanceof EditTextPreference) {
|
} else if (pref instanceof EditTextPreference editPreference) {
|
||||||
EditTextPreference editPreference = (EditTextPreference) pref;
|
|
||||||
if (applySettingToPreference) {
|
if (applySettingToPreference) {
|
||||||
editPreference.setText(setting.get().toString());
|
editPreference.setText(setting.get().toString());
|
||||||
} else {
|
} else {
|
||||||
Setting.privateSetValueFromString(setting, editPreference.getText());
|
Setting.privateSetValueFromString(setting, editPreference.getText());
|
||||||
}
|
}
|
||||||
} else if (pref instanceof ListPreference) {
|
} else if (pref instanceof ListPreference listPref) {
|
||||||
ListPreference listPref = (ListPreference) pref;
|
|
||||||
if (applySettingToPreference) {
|
if (applySettingToPreference) {
|
||||||
listPref.setValue(setting.get().toString());
|
listPref.setValue(setting.get().toString());
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,113 +0,0 @@
|
|||||||
package app.revanced.extension.shared.spoof;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public enum AudioStreamLanguage {
|
|
||||||
/**
|
|
||||||
* YouTube default.
|
|
||||||
* Can be the original language or can be app language,
|
|
||||||
* depending on what YouTube decides to pick as the default.
|
|
||||||
*/
|
|
||||||
DEFAULT,
|
|
||||||
|
|
||||||
// Language codes found in locale_config.xml
|
|
||||||
// Region specific variants of Chinese/English/Spanish/French have been removed.
|
|
||||||
AF,
|
|
||||||
AM,
|
|
||||||
AR,
|
|
||||||
AS,
|
|
||||||
AZ,
|
|
||||||
BE,
|
|
||||||
BG,
|
|
||||||
BN,
|
|
||||||
BS,
|
|
||||||
CA,
|
|
||||||
CS,
|
|
||||||
DA,
|
|
||||||
DE,
|
|
||||||
EL,
|
|
||||||
EN,
|
|
||||||
ES,
|
|
||||||
ET,
|
|
||||||
EU,
|
|
||||||
FA,
|
|
||||||
FI,
|
|
||||||
FR,
|
|
||||||
GL,
|
|
||||||
GU,
|
|
||||||
HI,
|
|
||||||
HE, // App uses obsolete 'IW' and 'HE' is modern ISO code.
|
|
||||||
HR,
|
|
||||||
HU,
|
|
||||||
HY,
|
|
||||||
ID,
|
|
||||||
IS,
|
|
||||||
IT,
|
|
||||||
JA,
|
|
||||||
KA,
|
|
||||||
KK,
|
|
||||||
KM,
|
|
||||||
KN,
|
|
||||||
KO,
|
|
||||||
KY,
|
|
||||||
LO,
|
|
||||||
LT,
|
|
||||||
LV,
|
|
||||||
MK,
|
|
||||||
ML,
|
|
||||||
MN,
|
|
||||||
MR,
|
|
||||||
MS,
|
|
||||||
MY,
|
|
||||||
NE,
|
|
||||||
NL,
|
|
||||||
NB,
|
|
||||||
OR,
|
|
||||||
PA,
|
|
||||||
PL,
|
|
||||||
PT_BR,
|
|
||||||
PT_PT,
|
|
||||||
RO,
|
|
||||||
RU,
|
|
||||||
SI,
|
|
||||||
SK,
|
|
||||||
SL,
|
|
||||||
SQ,
|
|
||||||
SR,
|
|
||||||
SV,
|
|
||||||
SW,
|
|
||||||
TA,
|
|
||||||
TE,
|
|
||||||
TH,
|
|
||||||
TL,
|
|
||||||
TR,
|
|
||||||
UK,
|
|
||||||
UR,
|
|
||||||
UZ,
|
|
||||||
VI,
|
|
||||||
ZH,
|
|
||||||
ZU;
|
|
||||||
|
|
||||||
private final String iso639_1;
|
|
||||||
|
|
||||||
AudioStreamLanguage() {
|
|
||||||
String name = name();
|
|
||||||
final int regionSeparatorIndex = name.indexOf('_');
|
|
||||||
if (regionSeparatorIndex >= 0) {
|
|
||||||
iso639_1 = name.substring(0, regionSeparatorIndex).toLowerCase(Locale.US)
|
|
||||||
+ name.substring(regionSeparatorIndex);
|
|
||||||
} else {
|
|
||||||
iso639_1 = name().toLowerCase(Locale.US);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIso639_1() {
|
|
||||||
// Changing the app language does not force the app to completely restart,
|
|
||||||
// so the default needs to be the current language and not a static field.
|
|
||||||
if (this == DEFAULT) {
|
|
||||||
return Locale.getDefault().toLanguageTag();
|
|
||||||
}
|
|
||||||
|
|
||||||
return iso639_1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,45 +4,119 @@ import android.os.Build;
|
|||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.shared.settings.BaseSettings;
|
||||||
|
|
||||||
public enum ClientType {
|
public enum ClientType {
|
||||||
// https://dumps.tadiphone.dev/dumps/oculus/eureka
|
// https://dumps.tadiphone.dev/dumps/oculus/eureka
|
||||||
ANDROID_VR_NO_AUTH( // Must be first so a default audio language can be set.
|
ANDROID_VR_NO_AUTH(
|
||||||
28,
|
28,
|
||||||
"ANDROID_VR",
|
"ANDROID_VR",
|
||||||
|
"com.google.android.apps.youtube.vr.oculus",
|
||||||
|
"Oculus",
|
||||||
"Quest 3",
|
"Quest 3",
|
||||||
|
"Android",
|
||||||
"12",
|
"12",
|
||||||
"com.google.android.apps.youtube.vr.oculus/1.56.21 (Linux; U; Android 12; GB) gzip",
|
// Android 12.1
|
||||||
"32", // Android 12.1
|
"32",
|
||||||
"1.56.21",
|
"SQ3A.220605.009.A1",
|
||||||
false),
|
"132.0.6808.3",
|
||||||
// Fall over to authenticated ('hl' is ignored and audio is same as language set in users Google account).
|
"1.61.48",
|
||||||
ANDROID_VR(
|
false,
|
||||||
ANDROID_VR_NO_AUTH.id,
|
false,
|
||||||
ANDROID_VR_NO_AUTH.clientName,
|
"Android VR No auth"
|
||||||
ANDROID_VR_NO_AUTH.deviceModel,
|
),
|
||||||
ANDROID_VR_NO_AUTH.osVersion,
|
// Chromecast with Google TV 4K.
|
||||||
ANDROID_VR_NO_AUTH.userAgent,
|
// https://dumps.tadiphone.dev/dumps/google/kirkwood
|
||||||
ANDROID_VR_NO_AUTH.androidSdkVersion,
|
|
||||||
ANDROID_VR_NO_AUTH.clientVersion,
|
|
||||||
true),
|
|
||||||
ANDROID_UNPLUGGED(
|
ANDROID_UNPLUGGED(
|
||||||
29,
|
29,
|
||||||
"ANDROID_UNPLUGGED",
|
"ANDROID_UNPLUGGED",
|
||||||
|
"com.google.android.apps.youtube.unplugged",
|
||||||
|
"Google",
|
||||||
"Google TV Streamer",
|
"Google TV Streamer",
|
||||||
"14",
|
|
||||||
"com.google.android.apps.youtube.unplugged/8.49.0 (Linux; U; Android 14; GB) gzip",
|
|
||||||
"34",
|
|
||||||
"8.49.0",
|
|
||||||
true), // Requires login.
|
|
||||||
ANDROID_CREATOR(
|
|
||||||
14,
|
|
||||||
"ANDROID_CREATOR",
|
|
||||||
"Android",
|
"Android",
|
||||||
"11",
|
"14",
|
||||||
"com.google.android.apps.youtube.creator/24.45.100 (Linux; U; Android 11) gzip",
|
"34",
|
||||||
"30",
|
"UTT3.240625.001.K5",
|
||||||
"24.45.100",
|
"132.0.6808.3",
|
||||||
true); // Requires login.
|
"8.49.0",
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
"Android TV"
|
||||||
|
),
|
||||||
|
// Cannot play livestreams and lacks HDR, but can play videos with music and labeled "for children".
|
||||||
|
// Google Pixel 9 Pro Fold
|
||||||
|
// https://dumps.tadiphone.dev/dumps/google/barbet
|
||||||
|
ANDROID_CREATOR(
|
||||||
|
14,
|
||||||
|
"ANDROID_CREATOR",
|
||||||
|
"com.google.android.apps.youtube.creator",
|
||||||
|
"Google",
|
||||||
|
"Pixel 9 Pro Fold",
|
||||||
|
"Android",
|
||||||
|
"15",
|
||||||
|
"35",
|
||||||
|
"AP3A.241005.015.A2",
|
||||||
|
"132.0.6779.0",
|
||||||
|
"23.47.101",
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
"Android Creator"
|
||||||
|
),
|
||||||
|
ANDROID_VR(
|
||||||
|
ANDROID_VR_NO_AUTH.id,
|
||||||
|
ANDROID_VR_NO_AUTH.clientName,
|
||||||
|
ANDROID_VR_NO_AUTH.packageName,
|
||||||
|
ANDROID_VR_NO_AUTH.deviceMake,
|
||||||
|
ANDROID_VR_NO_AUTH.deviceModel,
|
||||||
|
ANDROID_VR_NO_AUTH.osName,
|
||||||
|
ANDROID_VR_NO_AUTH.osVersion,
|
||||||
|
ANDROID_VR_NO_AUTH.androidSdkVersion,
|
||||||
|
ANDROID_VR_NO_AUTH.buildId,
|
||||||
|
ANDROID_VR_NO_AUTH.cronetVersion,
|
||||||
|
ANDROID_VR_NO_AUTH.clientVersion,
|
||||||
|
ANDROID_VR_NO_AUTH.requiresAuth,
|
||||||
|
true,
|
||||||
|
"Android VR"
|
||||||
|
),
|
||||||
|
IOS_UNPLUGGED(
|
||||||
|
33,
|
||||||
|
"IOS_UNPLUGGED",
|
||||||
|
"com.google.ios.youtubeunplugged",
|
||||||
|
"Apple",
|
||||||
|
forceAVC()
|
||||||
|
// 11 Pro Max (last device with iOS 13)
|
||||||
|
? "iPhone12,5"
|
||||||
|
// 15 Pro Max
|
||||||
|
: "iPhone16,2",
|
||||||
|
"iOS",
|
||||||
|
forceAVC()
|
||||||
|
// iOS 13 and earlier uses only AVC. 14+ adds VP9 and AV1.
|
||||||
|
? "13.7.17H35"
|
||||||
|
: "18.2.22C152",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
// Version number should be a valid iOS release.
|
||||||
|
// https://www.ipa4fun.com/history/152043/
|
||||||
|
forceAVC()
|
||||||
|
// Some newer versions can also force AVC,
|
||||||
|
// but 6.45 is the last version that supports iOS 13.
|
||||||
|
? "6.45"
|
||||||
|
: "8.49",
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
forceAVC()
|
||||||
|
? "iOS TV Force AVC"
|
||||||
|
: "iOS TV"
|
||||||
|
);
|
||||||
|
|
||||||
|
private static boolean forceAVC() {
|
||||||
|
return BaseSettings.SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC.get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* YouTube
|
* YouTube
|
||||||
@@ -53,20 +127,35 @@ public enum ClientType {
|
|||||||
public final String clientName;
|
public final String clientName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Device model, equivalent to {@link Build#MODEL} (System property: ro.product.model)
|
* App package name.
|
||||||
*/
|
*/
|
||||||
public final String deviceModel;
|
private final String packageName;
|
||||||
|
|
||||||
/**
|
|
||||||
* Device OS version.
|
|
||||||
*/
|
|
||||||
public final String osVersion;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Player user-agent.
|
* Player user-agent.
|
||||||
*/
|
*/
|
||||||
public final String userAgent;
|
public final String userAgent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Device model, equivalent to {@link Build#MANUFACTURER} (System property: ro.product.vendor.manufacturer)
|
||||||
|
*/
|
||||||
|
public final String deviceMake;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Device model, equivalent to {@link Build#MODEL} (System property: ro.product.vendor.model)
|
||||||
|
*/
|
||||||
|
public final String deviceModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Device OS name.
|
||||||
|
*/
|
||||||
|
public final String osName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Device OS version.
|
||||||
|
*/
|
||||||
|
public final String osVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Android SDK version, equivalent to {@link Build.VERSION#SDK} (System property: ro.build.version.sdk)
|
* Android SDK version, equivalent to {@link Build.VERSION#SDK} (System property: ro.build.version.sdk)
|
||||||
* Field is null if not applicable.
|
* Field is null if not applicable.
|
||||||
@@ -74,31 +163,97 @@ public enum ClientType {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public final String androidSdkVersion;
|
public final String androidSdkVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Android build id, equivalent to {@link Build#ID}.
|
||||||
|
* Field is null if not applicable.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private final String buildId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cronet release version, as found in decompiled client apk.
|
||||||
|
* Field is null if not applicable.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private final String cronetVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App version.
|
* App version.
|
||||||
*/
|
*/
|
||||||
public final String clientVersion;
|
public final String clientVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the client can access the API logged in.
|
* If this client requires authentication and does not work
|
||||||
|
* if logged out or in incognito mode.
|
||||||
*/
|
*/
|
||||||
public final boolean canLogin;
|
public final boolean requiresAuth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the client should use authentication if available.
|
||||||
|
*/
|
||||||
|
public final boolean useAuth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Friendly name displayed in stats for nerds.
|
||||||
|
*/
|
||||||
|
public final String friendlyName;
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantLocale")
|
||||||
ClientType(int id,
|
ClientType(int id,
|
||||||
String clientName,
|
String clientName,
|
||||||
|
String packageName,
|
||||||
|
String deviceMake,
|
||||||
String deviceModel,
|
String deviceModel,
|
||||||
|
String osName,
|
||||||
String osVersion,
|
String osVersion,
|
||||||
String userAgent,
|
|
||||||
@Nullable String androidSdkVersion,
|
@Nullable String androidSdkVersion,
|
||||||
|
@Nullable String buildId,
|
||||||
|
@Nullable String cronetVersion,
|
||||||
String clientVersion,
|
String clientVersion,
|
||||||
boolean canLogin) {
|
boolean requiresAuth,
|
||||||
|
boolean useAuth,
|
||||||
|
String friendlyName) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.clientName = clientName;
|
this.clientName = clientName;
|
||||||
|
this.packageName = packageName;
|
||||||
|
this.deviceMake = deviceMake;
|
||||||
this.deviceModel = deviceModel;
|
this.deviceModel = deviceModel;
|
||||||
|
this.osName = osName;
|
||||||
this.osVersion = osVersion;
|
this.osVersion = osVersion;
|
||||||
this.userAgent = userAgent;
|
|
||||||
this.androidSdkVersion = androidSdkVersion;
|
this.androidSdkVersion = androidSdkVersion;
|
||||||
|
this.buildId = buildId;
|
||||||
|
this.cronetVersion = cronetVersion;
|
||||||
this.clientVersion = clientVersion;
|
this.clientVersion = clientVersion;
|
||||||
this.canLogin = canLogin;
|
this.requiresAuth = requiresAuth;
|
||||||
|
this.useAuth = useAuth;
|
||||||
|
this.friendlyName = friendlyName;
|
||||||
|
|
||||||
|
Locale defaultLocale = Locale.getDefault();
|
||||||
|
if (androidSdkVersion == null) {
|
||||||
|
// Convert version from '18.2.22C152' into '18_2_22'
|
||||||
|
String userAgentOsVersion = osVersion
|
||||||
|
.replaceAll("(\\d+\\.\\d+\\.\\d+).*", "$1")
|
||||||
|
.replace(".", "_");
|
||||||
|
// https://github.com/mitmproxy/mitmproxy/issues/4836
|
||||||
|
this.userAgent = String.format("%s/%s (%s; U; CPU iOS %s like Mac OS X; %s)",
|
||||||
|
packageName,
|
||||||
|
clientVersion,
|
||||||
|
deviceModel,
|
||||||
|
userAgentOsVersion,
|
||||||
|
defaultLocale
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.userAgent = String.format("%s/%s (Linux; U; Android %s; %s; %s; Build/%s; Cronet/%s)",
|
||||||
|
packageName,
|
||||||
|
clientVersion,
|
||||||
|
osVersion,
|
||||||
|
defaultLocale,
|
||||||
|
deviceModel,
|
||||||
|
Objects.requireNonNull(buildId),
|
||||||
|
Objects.requireNonNull(cronetVersion)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Logger.printDebug(() -> "userAgent: " + this.userAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package app.revanced.extension.shared.spoof;
|
package app.revanced.extension.shared.spoof;
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
@@ -17,6 +18,9 @@ import app.revanced.extension.shared.spoof.requests.StreamingDataRequest;
|
|||||||
public class SpoofVideoStreamsPatch {
|
public class SpoofVideoStreamsPatch {
|
||||||
private static final boolean SPOOF_STREAMING_DATA = BaseSettings.SPOOF_VIDEO_STREAMS.get();
|
private static final boolean SPOOF_STREAMING_DATA = BaseSettings.SPOOF_VIDEO_STREAMS.get();
|
||||||
|
|
||||||
|
private static final boolean FIX_HLS_CURRENT_TIME = SPOOF_STREAMING_DATA
|
||||||
|
&& BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS_UNPLUGGED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any unreachable ip address. Used to intentionally fail requests.
|
* Any unreachable ip address. Used to intentionally fail requests.
|
||||||
*/
|
*/
|
||||||
@@ -30,15 +34,10 @@ public class SpoofVideoStreamsPatch {
|
|||||||
return false; // Modified during patching.
|
return false; // Modified during patching.
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class NotSpoofingAndroidAvailability implements Setting.Availability {
|
public static boolean notSpoofingToAndroid() {
|
||||||
@Override
|
return !isPatchIncluded()
|
||||||
public boolean isAvailable() {
|
|| !BaseSettings.SPOOF_VIDEO_STREAMS.get()
|
||||||
if (SpoofVideoStreamsPatch.isPatchIncluded()) {
|
|| BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS_UNPLUGGED;
|
||||||
return !BaseSettings.SPOOF_VIDEO_STREAMS.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,9 +77,9 @@ public class SpoofVideoStreamsPatch {
|
|||||||
String path = originalUri.getPath();
|
String path = originalUri.getPath();
|
||||||
|
|
||||||
if (path != null && path.contains("initplayback")) {
|
if (path != null && path.contains("initplayback")) {
|
||||||
Logger.printDebug(() -> "Blocking 'initplayback' by returning unreachable url");
|
Logger.printDebug(() -> "Blocking 'initplayback' by clearing query");
|
||||||
|
|
||||||
return UNREACHABLE_HOST_URI_STRING;
|
return originalUri.buildUpon().clearQuery().build().toString();
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "blockInitPlaybackRequest failure", ex);
|
Logger.printException(() -> "blockInitPlaybackRequest failure", ex);
|
||||||
@@ -97,6 +96,17 @@ public class SpoofVideoStreamsPatch {
|
|||||||
return SPOOF_STREAMING_DATA;
|
return SPOOF_STREAMING_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
* Only invoked when playing a livestream on an iOS client.
|
||||||
|
*/
|
||||||
|
public static boolean fixHLSCurrentTime(boolean original) {
|
||||||
|
if (!SPOOF_STREAMING_DATA) {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
@@ -105,20 +115,27 @@ public class SpoofVideoStreamsPatch {
|
|||||||
try {
|
try {
|
||||||
Uri uri = Uri.parse(url);
|
Uri uri = Uri.parse(url);
|
||||||
String path = uri.getPath();
|
String path = uri.getPath();
|
||||||
|
if (path == null || !path.contains("player")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'get_drm_license' has no video id and appears to happen when waiting for a paid video to start.
|
||||||
// 'heartbeat' has no video id and appears to be only after playback has started.
|
// 'heartbeat' has no video id and appears to be only after playback has started.
|
||||||
// 'refresh' has no video id and appears to happen when waiting for a livestream to start.
|
// 'refresh' has no video id and appears to happen when waiting for a livestream to start.
|
||||||
if (path != null && path.contains("player") && !path.contains("heartbeat")
|
// 'ad_break' has no video id.
|
||||||
&& !path.contains("refresh")) {
|
if (path.contains("get_drm_license") || path.contains("heartbeat")
|
||||||
String id = uri.getQueryParameter("id");
|
|| path.contains("refresh") || path.contains("ad_break")) {
|
||||||
if (id == null) {
|
Logger.printDebug(() -> "Ignoring path: " + path);
|
||||||
Logger.printException(() -> "Ignoring request that has no video id." +
|
return;
|
||||||
" Url: " + url + " headers: " + requestHeaders);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StreamingDataRequest.fetchRequest(id, requestHeaders);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String id = uri.getQueryParameter("id");
|
||||||
|
if (id == null) {
|
||||||
|
Logger.printException(() -> "Ignoring request with no id: " + url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamingDataRequest.fetchRequest(id, requestHeaders);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "buildRequest failure", ex);
|
Logger.printException(() -> "buildRequest failure", ex);
|
||||||
}
|
}
|
||||||
@@ -183,4 +200,38 @@ public class SpoofVideoStreamsPatch {
|
|||||||
|
|
||||||
return postData;
|
return postData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static String appendSpoofedClient(String videoFormat) {
|
||||||
|
try {
|
||||||
|
if (SPOOF_STREAMING_DATA && BaseSettings.SPOOF_STREAMING_DATA_STATS_FOR_NERDS.get()
|
||||||
|
&& !TextUtils.isEmpty(videoFormat)) {
|
||||||
|
// Force LTR layout, to match the same LTR video time/length layout YouTube uses for all languages.
|
||||||
|
return "\u202D" + videoFormat + "\u2009(" // u202D = left to right override
|
||||||
|
+ StreamingDataRequest.getLastSpoofedClientName() + ")";
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "appendSpoofedClient failure", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return videoFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class AudioStreamLanguageOverrideAvailability implements Setting.Availability {
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return BaseSettings.SPOOF_VIDEO_STREAMS.get()
|
||||||
|
&& BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.ANDROID_VR_NO_AUTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class SpoofiOSAvailability implements Setting.Availability {
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return BaseSettings.SPOOF_VIDEO_STREAMS.get()
|
||||||
|
&& BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS_UNPLUGGED;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.json.JSONObject;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
import app.revanced.extension.shared.requests.Requester;
|
import app.revanced.extension.shared.requests.Requester;
|
||||||
@@ -30,27 +31,39 @@ final class PlayerRoutes {
|
|||||||
private PlayerRoutes() {
|
private PlayerRoutes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static String createInnertubeBody(ClientType clientType) {
|
static String createInnertubeBody(ClientType clientType, String videoId) {
|
||||||
JSONObject innerTubeBody = new JSONObject();
|
JSONObject innerTubeBody = new JSONObject();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JSONObject context = new JSONObject();
|
JSONObject context = new JSONObject();
|
||||||
|
|
||||||
|
// Can override default language only if no login is used.
|
||||||
|
// Could use preferred audio for all clients that do not login,
|
||||||
|
// but if this is a fall over client it will set the language even though
|
||||||
|
// the audio language is not selectable in the UI.
|
||||||
|
ClientType userSelectedClient = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
|
||||||
|
Locale streamLocale = userSelectedClient == ClientType.ANDROID_VR_NO_AUTH
|
||||||
|
? BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get().getLocale()
|
||||||
|
: Locale.getDefault();
|
||||||
|
|
||||||
JSONObject client = new JSONObject();
|
JSONObject client = new JSONObject();
|
||||||
client.put("hl", BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get().getIso639_1());
|
client.put("deviceMake", clientType.deviceMake);
|
||||||
|
client.put("deviceModel", clientType.deviceModel);
|
||||||
client.put("clientName", clientType.clientName);
|
client.put("clientName", clientType.clientName);
|
||||||
client.put("clientVersion", clientType.clientVersion);
|
client.put("clientVersion", clientType.clientVersion);
|
||||||
client.put("deviceModel", clientType.deviceModel);
|
client.put("osName", clientType.osName);
|
||||||
client.put("osVersion", clientType.osVersion);
|
client.put("osVersion", clientType.osVersion);
|
||||||
if (clientType.androidSdkVersion != null) {
|
if (clientType.androidSdkVersion != null) {
|
||||||
client.put("androidSdkVersion", clientType.androidSdkVersion);
|
client.put("androidSdkVersion", clientType.androidSdkVersion);
|
||||||
}
|
}
|
||||||
|
client.put("hl", streamLocale.getLanguage());
|
||||||
|
client.put("gl", streamLocale.getCountry());
|
||||||
context.put("client", client);
|
context.put("client", client);
|
||||||
|
|
||||||
innerTubeBody.put("context", context);
|
innerTubeBody.put("context", context);
|
||||||
innerTubeBody.put("contentCheckOk", true);
|
innerTubeBody.put("contentCheckOk", true);
|
||||||
innerTubeBody.put("racyCheckOk", true);
|
innerTubeBody.put("racyCheckOk", true);
|
||||||
innerTubeBody.put("videoId", "%s");
|
innerTubeBody.put("videoId", videoId);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Logger.printException(() -> "Failed to create innerTubeBody", e);
|
Logger.printException(() -> "Failed to create innerTubeBody", e);
|
||||||
}
|
}
|
||||||
@@ -66,6 +79,9 @@ final class PlayerRoutes {
|
|||||||
|
|
||||||
connection.setRequestProperty("Content-Type", "application/json");
|
connection.setRequestProperty("Content-Type", "application/json");
|
||||||
connection.setRequestProperty("User-Agent", clientType.userAgent);
|
connection.setRequestProperty("User-Agent", clientType.userAgent);
|
||||||
|
// Not a typo. "Client-Name" uses the client type id.
|
||||||
|
connection.setRequestProperty("X-YouTube-Client-Name", String.valueOf(clientType.id));
|
||||||
|
connection.setRequestProperty("X-YouTube-Client-Version", clientType.clientVersion);
|
||||||
|
|
||||||
connection.setUseCaches(false);
|
connection.setUseCaches(false);
|
||||||
connection.setDoOutput(true);
|
connection.setDoOutput(true);
|
||||||
|
|||||||
@@ -35,21 +35,41 @@ import app.revanced.extension.shared.spoof.ClientType;
|
|||||||
*/
|
*/
|
||||||
public class StreamingDataRequest {
|
public class StreamingDataRequest {
|
||||||
|
|
||||||
private static final ClientType[] CLIENT_ORDER_TO_USE = ClientType.values();
|
private static final ClientType[] CLIENT_ORDER_TO_USE;
|
||||||
|
|
||||||
|
static {
|
||||||
|
ClientType[] allClientTypes = ClientType.values();
|
||||||
|
ClientType preferredClient = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
|
||||||
|
|
||||||
|
CLIENT_ORDER_TO_USE = new ClientType[allClientTypes.length];
|
||||||
|
CLIENT_ORDER_TO_USE[0] = preferredClient;
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
|
for (ClientType c : allClientTypes) {
|
||||||
|
if (c != preferredClient) {
|
||||||
|
CLIENT_ORDER_TO_USE[i++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final String AUTHORIZATION_HEADER = "Authorization";
|
private static final String AUTHORIZATION_HEADER = "Authorization";
|
||||||
|
|
||||||
private static final String[] REQUEST_HEADER_KEYS = {
|
private static final String[] REQUEST_HEADER_KEYS = {
|
||||||
AUTHORIZATION_HEADER, // Available only to logged-in users.
|
AUTHORIZATION_HEADER, // Available only to logged-in users.
|
||||||
"X-GOOG-API-FORMAT-VERSION",
|
"X-GOOG-API-FORMAT-VERSION",
|
||||||
"X-Goog-Visitor-Id"
|
"X-Goog-Visitor-Id"
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TCP connection and HTTP read timeout.
|
* TCP connection and HTTP read timeout.
|
||||||
*/
|
*/
|
||||||
private static final int HTTP_TIMEOUT_MILLISECONDS = 10 * 1000;
|
private static final int HTTP_TIMEOUT_MILLISECONDS = 10 * 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any arbitrarily large value, but must be at least twice {@link #HTTP_TIMEOUT_MILLISECONDS}
|
* Any arbitrarily large value, but must be at least twice {@link #HTTP_TIMEOUT_MILLISECONDS}
|
||||||
*/
|
*/
|
||||||
private static final int MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000;
|
private static final int MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000;
|
||||||
|
|
||||||
private static final Map<String, StreamingDataRequest> cache = Collections.synchronizedMap(
|
private static final Map<String, StreamingDataRequest> cache = Collections.synchronizedMap(
|
||||||
new LinkedHashMap<>(100) {
|
new LinkedHashMap<>(100) {
|
||||||
/**
|
/**
|
||||||
@@ -67,7 +87,15 @@ public class StreamingDataRequest {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
private static volatile ClientType lastSpoofedClientType;
|
||||||
|
|
||||||
|
public static String getLastSpoofedClientName() {
|
||||||
|
ClientType client = lastSpoofedClientType;
|
||||||
|
return client == null ? "Unknown" : client.friendlyName;
|
||||||
|
}
|
||||||
|
|
||||||
private final String videoId;
|
private final String videoId;
|
||||||
|
|
||||||
private final Future<ByteBuffer> future;
|
private final Future<ByteBuffer> future;
|
||||||
|
|
||||||
private StreamingDataRequest(String videoId, Map<String, String> playerHeaders) {
|
private StreamingDataRequest(String videoId, Map<String, String> playerHeaders) {
|
||||||
@@ -92,7 +120,8 @@ public class StreamingDataRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static HttpURLConnection send(ClientType clientType, String videoId,
|
private static HttpURLConnection send(ClientType clientType,
|
||||||
|
String videoId,
|
||||||
Map<String, String> playerHeaders,
|
Map<String, String> playerHeaders,
|
||||||
boolean showErrorToasts) {
|
boolean showErrorToasts) {
|
||||||
Objects.requireNonNull(clientType);
|
Objects.requireNonNull(clientType);
|
||||||
@@ -100,21 +129,24 @@ public class StreamingDataRequest {
|
|||||||
Objects.requireNonNull(playerHeaders);
|
Objects.requireNonNull(playerHeaders);
|
||||||
|
|
||||||
final long startTime = System.currentTimeMillis();
|
final long startTime = System.currentTimeMillis();
|
||||||
Logger.printDebug(() -> "Fetching video streams for: " + videoId + " using client: " + clientType);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
HttpURLConnection connection = PlayerRoutes.getPlayerResponseConnectionFromRoute(GET_STREAMING_DATA, clientType);
|
HttpURLConnection connection = PlayerRoutes.getPlayerResponseConnectionFromRoute(GET_STREAMING_DATA, clientType);
|
||||||
connection.setConnectTimeout(HTTP_TIMEOUT_MILLISECONDS);
|
connection.setConnectTimeout(HTTP_TIMEOUT_MILLISECONDS);
|
||||||
connection.setReadTimeout(HTTP_TIMEOUT_MILLISECONDS);
|
connection.setReadTimeout(HTTP_TIMEOUT_MILLISECONDS);
|
||||||
|
|
||||||
|
boolean authHeadersIncludes = false;
|
||||||
|
|
||||||
for (String key : REQUEST_HEADER_KEYS) {
|
for (String key : REQUEST_HEADER_KEYS) {
|
||||||
String value = playerHeaders.get(key);
|
String value = playerHeaders.get(key);
|
||||||
|
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
if (key.equals(AUTHORIZATION_HEADER)) {
|
if (key.equals(AUTHORIZATION_HEADER)) {
|
||||||
if (!clientType.canLogin) {
|
if (!clientType.useAuth) {
|
||||||
Logger.printDebug(() -> "Not including request header: " + key);
|
Logger.printDebug(() -> "Not including request header: " + key);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
authHeadersIncludes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.printDebug(() -> "Including request header: " + key);
|
Logger.printDebug(() -> "Including request header: " + key);
|
||||||
@@ -122,7 +154,15 @@ public class StreamingDataRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String innerTubeBody = String.format(PlayerRoutes.createInnertubeBody(clientType), videoId);
|
if (!authHeadersIncludes && clientType.requiresAuth) {
|
||||||
|
Logger.printDebug(() -> "Skipping client since user is not logged in: " + clientType
|
||||||
|
+ " videoId: " + videoId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.printDebug(() -> "Fetching video streams for: " + videoId + " using client: " + clientType);
|
||||||
|
|
||||||
|
String innerTubeBody = PlayerRoutes.createInnertubeBody(clientType, videoId);
|
||||||
byte[] requestBody = innerTubeBody.getBytes(StandardCharsets.UTF_8);
|
byte[] requestBody = innerTubeBody.getBytes(StandardCharsets.UTF_8);
|
||||||
connection.setFixedLengthStreamingMode(requestBody.length);
|
connection.setFixedLengthStreamingMode(requestBody.length);
|
||||||
connection.getOutputStream().write(requestBody);
|
connection.getOutputStream().write(requestBody);
|
||||||
@@ -154,7 +194,7 @@ public class StreamingDataRequest {
|
|||||||
// Retry with different client if empty response body is received.
|
// Retry with different client if empty response body is received.
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (ClientType clientType : CLIENT_ORDER_TO_USE) {
|
for (ClientType clientType : CLIENT_ORDER_TO_USE) {
|
||||||
// Show an error if the last client type fails, or if the debug is enabled then show for all attempts.
|
// Show an error if the last client type fails, or if debug is enabled then show for all attempts.
|
||||||
final boolean showErrorToast = (++i == CLIENT_ORDER_TO_USE.length) || debugEnabled;
|
final boolean showErrorToast = (++i == CLIENT_ORDER_TO_USE.length) || debugEnabled;
|
||||||
|
|
||||||
HttpURLConnection connection = send(clientType, videoId, playerHeaders, showErrorToast);
|
HttpURLConnection connection = send(clientType, videoId, playerHeaders, showErrorToast);
|
||||||
@@ -163,7 +203,9 @@ public class StreamingDataRequest {
|
|||||||
// gzip encoding doesn't response with content length (-1),
|
// gzip encoding doesn't response with content length (-1),
|
||||||
// but empty response body does.
|
// but empty response body does.
|
||||||
if (connection.getContentLength() == 0) {
|
if (connection.getContentLength() == 0) {
|
||||||
Logger.printDebug(() -> "Received empty response for client: " + clientType);
|
if (BaseSettings.DEBUG.get() && BaseSettings.DEBUG_TOAST_ON_ERROR.get()) {
|
||||||
|
Utils.showToastShort("Ignoring empty spoof stream client: " + clientType);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
try (InputStream inputStream = new BufferedInputStream(connection.getInputStream());
|
try (InputStream inputStream = new BufferedInputStream(connection.getInputStream());
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||||
@@ -173,6 +215,7 @@ public class StreamingDataRequest {
|
|||||||
while ((bytesRead = inputStream.read(buffer)) >= 0) {
|
while ((bytesRead = inputStream.read(buffer)) >= 0) {
|
||||||
baos.write(buffer, 0, bytesRead);
|
baos.write(buffer, 0, bytesRead);
|
||||||
}
|
}
|
||||||
|
lastSpoofedClientType = clientType;
|
||||||
|
|
||||||
return ByteBuffer.wrap(baos.toByteArray());
|
return ByteBuffer.wrap(baos.toByteArray());
|
||||||
}
|
}
|
||||||
@@ -183,7 +226,8 @@ public class StreamingDataRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleConnectionError("Could not fetch any client streams", null, debugEnabled);
|
lastSpoofedClientType = null;
|
||||||
|
handleConnectionError("Could not fetch any client streams", null, true);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,4 +90,12 @@ public class ThemeHelper {
|
|||||||
public static int getForegroundColor() {
|
public static int getForegroundColor() {
|
||||||
return isDarkTheme() ? getLightThemeColor() : getDarkThemeColor();
|
return isDarkTheme() ? getLightThemeColor() : getDarkThemeColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getToolbarBackgroundColor() {
|
||||||
|
final String colorName = isDarkTheme()
|
||||||
|
? "yt_black3"
|
||||||
|
: "yt_white1";
|
||||||
|
|
||||||
|
return getColorInt(colorName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,14 +176,13 @@ public final class AlternativeThumbnailsPatch {
|
|||||||
// Unknown tab, treat as the home tab;
|
// Unknown tab, treat as the home tab;
|
||||||
return homeOption;
|
return homeOption;
|
||||||
}
|
}
|
||||||
if (selectedNavButton == NavigationButton.HOME) {
|
|
||||||
return homeOption;
|
return switch (selectedNavButton) {
|
||||||
}
|
case SUBSCRIPTIONS, NOTIFICATIONS -> subscriptionsOption;
|
||||||
if (selectedNavButton == NavigationButton.SUBSCRIPTIONS || selectedNavButton == NavigationButton.NOTIFICATIONS) {
|
case LIBRARY -> libraryOption;
|
||||||
return subscriptionsOption;
|
// Home or explore tab.
|
||||||
}
|
default -> homeOption;
|
||||||
// A library tab variant is active.
|
};
|
||||||
return libraryOption;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Utils;
|
||||||
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class ChangeFormFactorPatch {
|
||||||
|
|
||||||
|
public enum FormFactor {
|
||||||
|
/**
|
||||||
|
* Unmodified, and same as un-patched.
|
||||||
|
*/
|
||||||
|
DEFAULT(null),
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* Some changes include:
|
||||||
|
* - Explore tab is present.
|
||||||
|
* - watch history is missing.
|
||||||
|
* - feed thumbnails fade in.
|
||||||
|
*/
|
||||||
|
UNKNOWN(0),
|
||||||
|
SMALL(1),
|
||||||
|
LARGE(2),
|
||||||
|
/**
|
||||||
|
* Cars with 'Google built-in'.
|
||||||
|
* Layout seems identical to {@link #UNKNOWN}
|
||||||
|
* even when using an Android Automotive device.
|
||||||
|
*/
|
||||||
|
AUTOMOTIVE(3),
|
||||||
|
WEARABLE(4);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
final Integer formFactorType;
|
||||||
|
|
||||||
|
FormFactor(@Nullable Integer formFactorType) {
|
||||||
|
this.formFactorType = formFactorType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static final Integer FORM_FACTOR_TYPE = Settings.CHANGE_FORM_FACTOR.get().formFactorType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static int getFormFactor(int original) {
|
||||||
|
return FORM_FACTOR_TYPE == null
|
||||||
|
? original
|
||||||
|
: FORM_FACTOR_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class DisableHdrPatch {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static boolean disableHDRVideo() {
|
||||||
|
return !Settings.DISABLE_HDR_VIDEO.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -9,14 +9,23 @@ import app.revanced.extension.shared.settings.BaseSettings;
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public final class EnableDebuggingPatch {
|
public final class EnableDebuggingPatch {
|
||||||
|
|
||||||
private static final ConcurrentMap<Long, Boolean> featureFlags
|
/**
|
||||||
= new ConcurrentHashMap<>(300, 0.75f, 1);
|
* Only log if debugging is enabled on startup.
|
||||||
|
* This prevents enabling debugging
|
||||||
|
* while the app is running then failing to restart
|
||||||
|
* resulting in an incomplete log.
|
||||||
|
*/
|
||||||
|
private static final boolean LOG_FEATURE_FLAGS = BaseSettings.DEBUG.get();
|
||||||
|
|
||||||
|
private static final ConcurrentMap<Long, Boolean> featureFlags = LOG_FEATURE_FLAGS
|
||||||
|
? new ConcurrentHashMap<>(800, 0.5f, 1)
|
||||||
|
: null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static boolean isBooleanFeatureFlagEnabled(boolean value, long flag) {
|
public static boolean isBooleanFeatureFlagEnabled(boolean value, long flag) {
|
||||||
if (value && BaseSettings.DEBUG.get()) {
|
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);
|
||||||
}
|
}
|
||||||
@@ -29,7 +38,7 @@ public final class EnableDebuggingPatch {
|
|||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static double isDoubleFeatureFlagEnabled(double value, long flag, double defaultValue) {
|
public static double isDoubleFeatureFlagEnabled(double value, long flag, double defaultValue) {
|
||||||
if (defaultValue != value && BaseSettings.DEBUG.get()) {
|
if (LOG_FEATURE_FLAGS && defaultValue != value) {
|
||||||
if (featureFlags.putIfAbsent(flag, true) == null) {
|
if (featureFlags.putIfAbsent(flag, true) == null) {
|
||||||
// Align the log outputs to make post processing easier.
|
// Align the log outputs to make post processing easier.
|
||||||
Logger.printDebug(() -> " double feature is enabled: " + flag
|
Logger.printDebug(() -> " double feature is enabled: " + flag
|
||||||
@@ -44,7 +53,7 @@ public final class EnableDebuggingPatch {
|
|||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static long isLongFeatureFlagEnabled(long value, long flag, long defaultValue) {
|
public static long isLongFeatureFlagEnabled(long value, long flag, long defaultValue) {
|
||||||
if (defaultValue != value && BaseSettings.DEBUG.get()) {
|
if (LOG_FEATURE_FLAGS && defaultValue != value) {
|
||||||
if (featureFlags.putIfAbsent(flag, true) == null) {
|
if (featureFlags.putIfAbsent(flag, true) == null) {
|
||||||
Logger.printDebug(() -> " long feature is enabled: " + flag
|
Logger.printDebug(() -> " long feature is enabled: " + flag
|
||||||
+ " value: " + value + (defaultValue == 0 ? "" : " default: " + defaultValue));
|
+ " value: " + value + (defaultValue == 0 ? "" : " default: " + defaultValue));
|
||||||
@@ -58,7 +67,7 @@ public final class EnableDebuggingPatch {
|
|||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static String isStringFeatureFlagEnabled(String value, long flag, String defaultValue) {
|
public static String isStringFeatureFlagEnabled(String value, long flag, String defaultValue) {
|
||||||
if (BaseSettings.DEBUG.get() && !defaultValue.equals(value)) {
|
if (LOG_FEATURE_FLAGS && !defaultValue.equals(value)) {
|
||||||
if (featureFlags.putIfAbsent(flag, true) == null) {
|
if (featureFlags.putIfAbsent(flag, true) == null) {
|
||||||
Logger.printDebug(() -> " string feature is enabled: " + flag
|
Logger.printDebug(() -> " string feature is enabled: " + flag
|
||||||
+ " value: " + value + (defaultValue.isEmpty() ? "" : " default: " + defaultValue));
|
+ " value: " + value + (defaultValue.isEmpty() ? "" : " default: " + defaultValue));
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.shared.Utils;
|
||||||
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
import app.revanced.extension.youtube.shared.PlayerType;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class ExitFullscreenPatch {
|
||||||
|
|
||||||
|
public enum FullscreenMode {
|
||||||
|
DISABLED,
|
||||||
|
PORTRAIT,
|
||||||
|
LANDSCAPE,
|
||||||
|
PORTRAIT_LANDSCAPE,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static void endOfVideoReached() {
|
||||||
|
try {
|
||||||
|
FullscreenMode mode = Settings.EXIT_FULLSCREEN.get();
|
||||||
|
if (mode == FullscreenMode.DISABLED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PlayerType.getCurrent() == PlayerType.WATCH_WHILE_FULLSCREEN) {
|
||||||
|
if (mode != FullscreenMode.PORTRAIT_LANDSCAPE) {
|
||||||
|
if (Utils.isLandscapeOrientation()) {
|
||||||
|
if (mode == FullscreenMode.PORTRAIT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (mode == FullscreenMode.LANDSCAPE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user cold launches the app and plays a video but does not
|
||||||
|
// tap to show the overlay controls, the fullscreen button is not
|
||||||
|
// set because the overlay controls are not attached.
|
||||||
|
// To fix this, push the perform click to the back fo the main thread,
|
||||||
|
// and by then the overlay controls will be visible since the video is now finished.
|
||||||
|
Utils.runOnMainThread(() -> {
|
||||||
|
ImageView button = PlayerControlsPatch.fullscreenButtonRef.get();
|
||||||
|
if (button == null) {
|
||||||
|
Logger.printDebug(() -> "Fullscreen button is null, cannot click");
|
||||||
|
} else {
|
||||||
|
Logger.printDebug(() -> "Clicking fullscreen button");
|
||||||
|
final boolean soundEffectsEnabled = button.isSoundEffectsEnabled();
|
||||||
|
button.setSoundEffectsEnabled(false);
|
||||||
|
button.performClick();
|
||||||
|
button.setSoundEffectsEnabled(soundEffectsEnabled);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "endOfVideoReached failure", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.youtube.shared.PlayerType;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class FixPlaybackSpeedWhilePlayingPatch {
|
||||||
|
|
||||||
|
private static final float DEFAULT_YOUTUBE_PLAYBACK_SPEED = 1.0f;
|
||||||
|
|
||||||
|
public static boolean playbackSpeedChanged(float playbackSpeed) {
|
||||||
|
if (playbackSpeed == DEFAULT_YOUTUBE_PLAYBACK_SPEED &&
|
||||||
|
PlayerType.getCurrent().isMaximizedOrFullscreen()) {
|
||||||
|
|
||||||
|
Logger.printDebug(() -> "Blocking call to change playback speed to 1.0x");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package app.revanced.extension.youtube.patches;
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.shared.settings.Setting;
|
||||||
|
import app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch;
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@@ -8,6 +10,20 @@ public class ForceOriginalAudioPatch {
|
|||||||
|
|
||||||
private static final String DEFAULT_AUDIO_TRACKS_SUFFIX = ".4";
|
private static final String DEFAULT_AUDIO_TRACKS_SUFFIX = ".4";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the conditions to use this patch were present when the app launched.
|
||||||
|
*/
|
||||||
|
public static boolean PATCH_AVAILABLE = SpoofVideoStreamsPatch.notSpoofingToAndroid();
|
||||||
|
|
||||||
|
public static final class ForceOriginalAudioAvailability implements Setting.Availability {
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
// Check conditions of launch and now. Otherwise if spoofing is changed
|
||||||
|
// without a restart the setting will show as available when it's not.
|
||||||
|
return PATCH_AVAILABLE && SpoofVideoStreamsPatch.notSpoofingToAndroid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4,15 +4,30 @@ import android.view.View;
|
|||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class PlayerControlsPatch {
|
public class PlayerControlsPatch {
|
||||||
|
|
||||||
|
public static WeakReference<ImageView> fullscreenButtonRef = new WeakReference<>(null);
|
||||||
|
|
||||||
|
private static boolean fullscreenButtonVisibilityCallbacksExist() {
|
||||||
|
return false; // Modified during patching if needed.
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static void setFullscreenCloseButton(ImageView imageButton) {
|
public static void setFullscreenCloseButton(ImageView imageButton) {
|
||||||
|
fullscreenButtonRef = new WeakReference<>(imageButton);
|
||||||
|
Logger.printDebug(() -> "Fullscreen button set");
|
||||||
|
|
||||||
|
if (!fullscreenButtonVisibilityCallbacksExist()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Add a global listener, since the protected method
|
// Add a global listener, since the protected method
|
||||||
// View#onVisibilityChanged() does not have any call backs.
|
// View#onVisibilityChanged() does not have any call backs.
|
||||||
imageButton.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
imageButton.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||||
@@ -39,7 +54,7 @@ public class PlayerControlsPatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// noinspection EmptyMethod
|
// noinspection EmptyMethod
|
||||||
public static void fullscreenButtonVisibilityChanged(boolean isVisible) {
|
private static void fullscreenButtonVisibilityChanged(boolean isVisible) {
|
||||||
// Code added during patching.
|
// Code added during patching.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
package app.revanced.extension.youtube.patches;
|
|
||||||
|
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public final class TabletLayoutPatch {
|
|
||||||
|
|
||||||
private static final boolean TABLET_LAYOUT_ENABLED = Settings.TABLET_LAYOUT.get();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Injection point.
|
|
||||||
*/
|
|
||||||
public static boolean getTabletLayoutEnabled() {
|
|
||||||
return TABLET_LAYOUT_ENABLED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -528,14 +528,13 @@ final class KeywordContentFilter extends Filter {
|
|||||||
if (selectedNavButton == null) {
|
if (selectedNavButton == null) {
|
||||||
return hideHome; // Unknown tab, treat the same as home.
|
return hideHome; // Unknown tab, treat the same as home.
|
||||||
}
|
}
|
||||||
if (selectedNavButton == NavigationButton.HOME) {
|
|
||||||
return hideHome;
|
return switch (selectedNavButton) {
|
||||||
}
|
case HOME, EXPLORE -> hideHome;
|
||||||
if (selectedNavButton == NavigationButton.SUBSCRIPTIONS) {
|
case SUBSCRIPTIONS -> hideSubscriptions;
|
||||||
return hideSubscriptions;
|
// User is in the Library or notifications.
|
||||||
}
|
default -> false;
|
||||||
// User is in the Library or Notifications tab.
|
};
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateStats(boolean videoWasHidden, @Nullable String keyword) {
|
private void updateStats(boolean videoWasHidden, @Nullable String keyword) {
|
||||||
|
|||||||
@@ -80,7 +80,8 @@ public final class LayoutComponentsFilter extends Filter {
|
|||||||
"images_post_root_slim.eml",
|
"images_post_root_slim.eml",
|
||||||
"text_post_root_slim.eml",
|
"text_post_root_slim.eml",
|
||||||
"post_base_wrapper_slim.eml",
|
"post_base_wrapper_slim.eml",
|
||||||
"poll_post_root.eml"
|
"poll_post_root.eml",
|
||||||
|
"videos_post_root.eml"
|
||||||
);
|
);
|
||||||
|
|
||||||
final var communityGuidelines = new StringFilterGroup(
|
final var communityGuidelines = new StringFilterGroup(
|
||||||
@@ -106,7 +107,8 @@ public final class LayoutComponentsFilter extends Filter {
|
|||||||
inFeedSurvey = new StringFilterGroup(
|
inFeedSurvey = new StringFilterGroup(
|
||||||
Settings.HIDE_FEED_SURVEY,
|
Settings.HIDE_FEED_SURVEY,
|
||||||
"in_feed_survey",
|
"in_feed_survey",
|
||||||
"slimline_survey"
|
"slimline_survey",
|
||||||
|
"feed_nudge"
|
||||||
);
|
);
|
||||||
|
|
||||||
final var medicalPanel = new StringFilterGroup(
|
final var medicalPanel = new StringFilterGroup(
|
||||||
@@ -161,9 +163,9 @@ public final class LayoutComponentsFilter extends Filter {
|
|||||||
"inline_expander"
|
"inline_expander"
|
||||||
);
|
);
|
||||||
|
|
||||||
final var channelBar = new StringFilterGroup(
|
final var compactChannelBar = new StringFilterGroup(
|
||||||
Settings.HIDE_CHANNEL_BAR,
|
Settings.HIDE_CHANNEL_BAR,
|
||||||
"channel_bar"
|
"compact_channel_bar"
|
||||||
);
|
);
|
||||||
|
|
||||||
final var relatedVideos = new StringFilterGroup(
|
final var relatedVideos = new StringFilterGroup(
|
||||||
@@ -252,7 +254,7 @@ public final class LayoutComponentsFilter extends Filter {
|
|||||||
inFeedSurvey,
|
inFeedSurvey,
|
||||||
notifyMe,
|
notifyMe,
|
||||||
likeSubscribeGlow,
|
likeSubscribeGlow,
|
||||||
channelBar,
|
compactChannelBar,
|
||||||
communityPosts,
|
communityPosts,
|
||||||
paidPromotion,
|
paidPromotion,
|
||||||
searchResultVideo,
|
searchResultVideo,
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ public final class ShortsFilter extends Filter {
|
|||||||
if (matchedGroup == suggestedAction) {
|
if (matchedGroup == suggestedAction) {
|
||||||
// Skip searching the buffer if all suggested actions are set to hidden.
|
// Skip searching the buffer if all suggested actions are set to hidden.
|
||||||
// This has a secondary effect of hiding all new un-identified actions
|
// This has a secondary effect of hiding all new un-identified actions
|
||||||
// under the assumption that the user wants all actions hidden.
|
// under the assumption that the user wants all suggestions hidden.
|
||||||
if (isEverySuggestedActionFilterEnabled()) {
|
if (isEverySuggestedActionFilterEnabled()) {
|
||||||
return super.isFiltered(path, identifier, protobufBufferArray, matchedGroup, contentType, contentIndex);
|
return super.isFiltered(path, identifier, protobufBufferArray, matchedGroup, contentType, contentIndex);
|
||||||
}
|
}
|
||||||
@@ -324,19 +324,22 @@ public final class ShortsFilter extends Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean shouldHideShortsFeedItems() {
|
private static boolean shouldHideShortsFeedItems() {
|
||||||
|
// Known issue if hide home is on but at least one other hide is off:
|
||||||
|
//
|
||||||
|
// Shorts suggestions will load in the background if a video is opened and
|
||||||
|
// immediately minimized before any suggestions are loaded.
|
||||||
|
// In this state the player type will show minimized, which cannot
|
||||||
|
// distinguish between Shorts suggestions loading in the player and between
|
||||||
|
// scrolling thru search/home/subscription tabs while a player is minimized.
|
||||||
final boolean hideHome = Settings.HIDE_SHORTS_HOME.get();
|
final boolean hideHome = Settings.HIDE_SHORTS_HOME.get();
|
||||||
final boolean hideSubscriptions = Settings.HIDE_SHORTS_SUBSCRIPTIONS.get();
|
final boolean hideSubscriptions = Settings.HIDE_SHORTS_SUBSCRIPTIONS.get();
|
||||||
final boolean hideSearch = Settings.HIDE_SHORTS_SEARCH.get();
|
final boolean hideSearch = Settings.HIDE_SHORTS_SEARCH.get();
|
||||||
|
final boolean hideHistory = Settings.HIDE_SHORTS_HISTORY.get();
|
||||||
|
|
||||||
if (hideHome && hideSubscriptions && hideSearch) {
|
if (!hideHome && !hideSubscriptions && !hideSearch && !hideHistory) {
|
||||||
// Shorts suggestions can load in the background if a video is opened and
|
return false;
|
||||||
// then immediately minimized before any suggestions are loaded.
|
}
|
||||||
// In this state the player type will show minimized, which makes it not possible to
|
if (hideHome && hideSubscriptions && hideSearch && hideHistory) {
|
||||||
// distinguish between Shorts suggestions loading in the player and between
|
|
||||||
// scrolling thru search/home/subscription tabs while a player is minimized.
|
|
||||||
//
|
|
||||||
// To avoid this situation for users that never want to show Shorts (all hide Shorts options are enabled)
|
|
||||||
// then hide all Shorts everywhere including the Library history and Library playlists.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,24 +355,29 @@ public final class ShortsFilter extends Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Avoid checking navigation button status if all other Shorts should show.
|
// Avoid checking navigation button status if all other Shorts should show.
|
||||||
if (!hideHome && !hideSubscriptions) {
|
if (!hideHome && !hideSubscriptions && !hideHistory) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check navigation absolutely last since the check may block this thread.
|
||||||
NavigationButton selectedNavButton = NavigationButton.getSelectedNavigationButton();
|
NavigationButton selectedNavButton = NavigationButton.getSelectedNavigationButton();
|
||||||
if (selectedNavButton == null) {
|
if (selectedNavButton == null) {
|
||||||
return hideHome; // Unknown tab, treat the same as home.
|
return hideHome; // Unknown tab, treat the same as home.
|
||||||
}
|
}
|
||||||
if (selectedNavButton == NavigationButton.HOME) {
|
|
||||||
return hideHome;
|
return switch (selectedNavButton) {
|
||||||
}
|
case HOME, EXPLORE -> hideHome;
|
||||||
if (selectedNavButton == NavigationButton.SUBSCRIPTIONS) {
|
case SUBSCRIPTIONS -> hideSubscriptions;
|
||||||
return hideSubscriptions;
|
case LIBRARY -> hideHistory;
|
||||||
}
|
default -> false;
|
||||||
// User must be in the library tab. Don't hide the history or any playlists here.
|
};
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point. Only used if patching older than 19.03.
|
||||||
|
* This hook may be obsolete even for old versions
|
||||||
|
* as they now use a litho layout like newer versions.
|
||||||
|
*/
|
||||||
public static void hideShortsShelf(final View shortsShelfView) {
|
public static void hideShortsShelf(final View shortsShelfView) {
|
||||||
if (shouldHideShortsFeedItems()) {
|
if (shouldHideShortsFeedItems()) {
|
||||||
Utils.hideViewByLayoutParams(shortsShelfView);
|
Utils.hideViewByLayoutParams(shortsShelfView);
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ public class CustomPlaybackSpeedPatch {
|
|||||||
*/
|
*/
|
||||||
public static final float PLAYBACK_SPEED_MAXIMUM = 8;
|
public static final float PLAYBACK_SPEED_MAXIMUM = 8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tap and hold speed.
|
||||||
|
*/
|
||||||
|
private static final float TAP_AND_HOLD_SPEED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom playback speeds.
|
* Custom playback speeds.
|
||||||
*/
|
*/
|
||||||
@@ -48,12 +53,27 @@ public class CustomPlaybackSpeedPatch {
|
|||||||
private static String[] preferenceListEntries, preferenceListEntryValues;
|
private static String[] preferenceListEntries, preferenceListEntryValues;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
final float holdSpeed = Settings.SPEED_TAP_AND_HOLD.get();
|
||||||
|
if (holdSpeed > 0 && holdSpeed <= PLAYBACK_SPEED_MAXIMUM) {
|
||||||
|
TAP_AND_HOLD_SPEED = holdSpeed;
|
||||||
|
} else {
|
||||||
|
showInvalidCustomSpeedToast();
|
||||||
|
Settings.SPEED_TAP_AND_HOLD.resetToDefault();
|
||||||
|
TAP_AND_HOLD_SPEED = Settings.SPEED_TAP_AND_HOLD.get();
|
||||||
|
}
|
||||||
|
|
||||||
loadCustomSpeeds();
|
loadCustomSpeeds();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void resetCustomSpeeds(@NonNull String toastMessage) {
|
/**
|
||||||
Utils.showToastLong(toastMessage);
|
* Injection point.
|
||||||
Settings.CUSTOM_PLAYBACK_SPEEDS.resetToDefault();
|
*/
|
||||||
|
public static float tapAndHoldSpeed() {
|
||||||
|
return TAP_AND_HOLD_SPEED;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void showInvalidCustomSpeedToast() {
|
||||||
|
Utils.showToastLong(str("revanced_custom_playback_speeds_invalid", PLAYBACK_SPEED_MAXIMUM));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadCustomSpeeds() {
|
private static void loadCustomSpeeds() {
|
||||||
@@ -74,17 +94,18 @@ public class CustomPlaybackSpeedPatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (speedFloat >= PLAYBACK_SPEED_MAXIMUM) {
|
if (speedFloat >= PLAYBACK_SPEED_MAXIMUM) {
|
||||||
resetCustomSpeeds(str("revanced_custom_playback_speeds_invalid", PLAYBACK_SPEED_MAXIMUM));
|
showInvalidCustomSpeedToast();
|
||||||
|
Settings.CUSTOM_PLAYBACK_SPEEDS.resetToDefault();
|
||||||
loadCustomSpeeds();
|
loadCustomSpeeds();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
customPlaybackSpeeds[i] = speedFloat;
|
customPlaybackSpeeds[i++] = speedFloat;
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printInfo(() -> "parse error", ex);
|
Logger.printInfo(() -> "parse error", ex);
|
||||||
resetCustomSpeeds(str("revanced_custom_playback_speeds_parse_exception"));
|
Utils.showToastLong(str("revanced_custom_playback_speeds_parse_exception"));
|
||||||
|
Settings.CUSTOM_PLAYBACK_SPEEDS.resetToDefault();
|
||||||
loadCustomSpeeds();
|
loadCustomSpeeds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ public final class SeekbarColorPatch {
|
|||||||
|
|
||||||
private static final boolean SEEKBAR_CUSTOM_COLOR_ENABLED = Settings.SEEKBAR_CUSTOM_COLOR.get();
|
private static final boolean SEEKBAR_CUSTOM_COLOR_ENABLED = Settings.SEEKBAR_CUSTOM_COLOR.get();
|
||||||
|
|
||||||
|
private static final boolean HIDE_SEEKBAR_THUMBNAIL_ENABLED = Settings.HIDE_SEEKBAR_THUMBNAIL.get();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default color of the litho seekbar.
|
* Default color of the litho seekbar.
|
||||||
* Differs slightly from the default custom seekbar color setting.
|
* Differs slightly from the default custom seekbar color setting.
|
||||||
@@ -25,14 +27,19 @@ public final class SeekbarColorPatch {
|
|||||||
private static final int ORIGINAL_SEEKBAR_COLOR = 0xFFFF0000;
|
private static final int ORIGINAL_SEEKBAR_COLOR = 0xFFFF0000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default colors of the gradient seekbar.
|
* Feed default colors of the gradient seekbar.
|
||||||
*/
|
*/
|
||||||
private static final int[] ORIGINAL_SEEKBAR_GRADIENT_COLORS = { 0xFFFF0033, 0xFFFF2791 };
|
private static final int[] FEED_ORIGINAL_SEEKBAR_GRADIENT_COLORS = { 0xFFFF0033, 0xFFFF2791 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default positions of the gradient seekbar.
|
* Feed default positions of the gradient seekbar.
|
||||||
*/
|
*/
|
||||||
private static final float[] ORIGINAL_SEEKBAR_GRADIENT_POSITIONS = { 0.8f, 1.0f };
|
private static final float[] FEED_ORIGINAL_SEEKBAR_GRADIENT_POSITIONS = { 0.8f, 1.0f };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty seekbar gradient, if hide seekbar in feed is enabled.
|
||||||
|
*/
|
||||||
|
private static final int[] HIDDEN_SEEKBAR_GRADIENT_COLORS = { 0x0, 0x0 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default YouTube seekbar color brightness.
|
* Default YouTube seekbar color brightness.
|
||||||
@@ -41,16 +48,21 @@ public final class SeekbarColorPatch {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* If {@link Settings#SEEKBAR_CUSTOM_COLOR} is enabled,
|
* If {@link Settings#SEEKBAR_CUSTOM_COLOR} is enabled,
|
||||||
* this is the color value of {@link Settings#SEEKBAR_CUSTOM_COLOR_VALUE}.
|
* this is the color value of {@link Settings#SEEKBAR_CUSTOM_COLOR_PRIMARY}.
|
||||||
* Otherwise this is {@link #ORIGINAL_SEEKBAR_COLOR}.
|
* Otherwise this is {@link #ORIGINAL_SEEKBAR_COLOR}.
|
||||||
*/
|
*/
|
||||||
private static int seekbarColor = ORIGINAL_SEEKBAR_COLOR;
|
private static int customSeekbarColor = ORIGINAL_SEEKBAR_COLOR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom seekbar hue, saturation, and brightness values.
|
* Custom seekbar hue, saturation, and brightness values.
|
||||||
*/
|
*/
|
||||||
private static final float[] customSeekbarColorHSV = new float[3];
|
private static final float[] customSeekbarColorHSV = new float[3];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom seekbar color, used for linear gradient replacements.
|
||||||
|
*/
|
||||||
|
private static final int[] customSeekbarColorGradient = new int[2];
|
||||||
|
|
||||||
static {
|
static {
|
||||||
float[] hsv = new float[3];
|
float[] hsv = new float[3];
|
||||||
Color.colorToHSV(ORIGINAL_SEEKBAR_COLOR, hsv);
|
Color.colorToHSV(ORIGINAL_SEEKBAR_COLOR, hsv);
|
||||||
@@ -63,26 +75,22 @@ public final class SeekbarColorPatch {
|
|||||||
|
|
||||||
private static void loadCustomSeekbarColor() {
|
private static void loadCustomSeekbarColor() {
|
||||||
try {
|
try {
|
||||||
seekbarColor = Color.parseColor(Settings.SEEKBAR_CUSTOM_COLOR_VALUE.get());
|
customSeekbarColor = Color.parseColor(Settings.SEEKBAR_CUSTOM_COLOR_PRIMARY.get());
|
||||||
Color.colorToHSV(seekbarColor, customSeekbarColorHSV);
|
Color.colorToHSV(customSeekbarColor, customSeekbarColorHSV);
|
||||||
|
|
||||||
|
customSeekbarColorGradient[0] = customSeekbarColor;
|
||||||
|
customSeekbarColorGradient[1] = Color.parseColor(Settings.SEEKBAR_CUSTOM_COLOR_ACCENT.get());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Utils.showToastShort(str("revanced_seekbar_custom_color_invalid"));
|
Utils.showToastShort(str("revanced_seekbar_custom_color_invalid"));
|
||||||
Settings.SEEKBAR_CUSTOM_COLOR_VALUE.resetToDefault();
|
Settings.SEEKBAR_CUSTOM_COLOR_PRIMARY.resetToDefault();
|
||||||
|
Settings.SEEKBAR_CUSTOM_COLOR_ACCENT.resetToDefault();
|
||||||
|
|
||||||
loadCustomSeekbarColor();
|
loadCustomSeekbarColor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getSeekbarColor() {
|
public static int getSeekbarColor() {
|
||||||
return seekbarColor;
|
return customSeekbarColor;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Injection point
|
|
||||||
*/
|
|
||||||
public static boolean playerSeekbarGradientEnabled(boolean original) {
|
|
||||||
if (SEEKBAR_CUSTOM_COLOR_ENABLED) return false;
|
|
||||||
|
|
||||||
return original;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -126,7 +134,7 @@ public final class SeekbarColorPatch {
|
|||||||
// Even if the seekbar color xml value is changed to a completely different color (such as green),
|
// Even if the seekbar color xml value is changed to a completely different color (such as green),
|
||||||
// a color filter still cannot be selectively applied when the drawable has more than 1 color.
|
// a color filter still cannot be selectively applied when the drawable has more than 1 color.
|
||||||
try {
|
try {
|
||||||
String seekbarStyle = get9BitStyleIdentifier(seekbarColor);
|
String seekbarStyle = get9BitStyleIdentifier(customSeekbarColor);
|
||||||
Logger.printDebug(() -> "Using splash seekbar style: " + seekbarStyle);
|
Logger.printDebug(() -> "Using splash seekbar style: " + seekbarStyle);
|
||||||
|
|
||||||
final int styleIdentifierDefault = Utils.getResourceIdentifier(
|
final int styleIdentifierDefault = Utils.getResourceIdentifier(
|
||||||
@@ -146,6 +154,13 @@ public final class SeekbarColorPatch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static boolean showWatchHistoryProgressDrawable(boolean original) {
|
||||||
|
return !HIDE_SEEKBAR_THUMBNAIL_ENABLED && original;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*
|
*
|
||||||
@@ -156,35 +171,61 @@ public final class SeekbarColorPatch {
|
|||||||
*/
|
*/
|
||||||
public static int getLithoColor(int colorValue) {
|
public static int getLithoColor(int colorValue) {
|
||||||
if (colorValue == ORIGINAL_SEEKBAR_COLOR) {
|
if (colorValue == ORIGINAL_SEEKBAR_COLOR) {
|
||||||
if (Settings.HIDE_SEEKBAR_THUMBNAIL.get()) {
|
if (HIDE_SEEKBAR_THUMBNAIL_ENABLED) {
|
||||||
return 0x00000000;
|
return 0x0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getSeekbarColorValue(ORIGINAL_SEEKBAR_COLOR);
|
return customSeekbarColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
return colorValue;
|
return colorValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String colorArrayToHex(int[] colors) {
|
||||||
|
final int length = colors.length;
|
||||||
|
StringBuilder builder = new StringBuilder(length * 12);
|
||||||
|
builder.append("[");
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (int color : colors) {
|
||||||
|
builder.append(String.format("#%X", color));
|
||||||
|
if (++i < length) {
|
||||||
|
builder.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static void setLinearGradient(int[] colors, float[] positions) {
|
public static int[] getPlayerLinearGradient(int[] original) {
|
||||||
final boolean hideSeekbar = Settings.HIDE_SEEKBAR_THUMBNAIL.get();
|
return SEEKBAR_CUSTOM_COLOR_ENABLED
|
||||||
|
? customSeekbarColorGradient
|
||||||
|
: original;
|
||||||
|
}
|
||||||
|
|
||||||
if (SEEKBAR_CUSTOM_COLOR_ENABLED || hideSeekbar) {
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static int[] getLithoLinearGradient(int[] colors, float[] positions) {
|
||||||
|
if (SEEKBAR_CUSTOM_COLOR_ENABLED || HIDE_SEEKBAR_THUMBNAIL_ENABLED) {
|
||||||
// Most litho usage of linear gradients is hooked here,
|
// Most litho usage of linear gradients is hooked here,
|
||||||
// so must only change if the values are those for the seekbar.
|
// so must only change if the values are those for the seekbar.
|
||||||
if (Arrays.equals(ORIGINAL_SEEKBAR_GRADIENT_COLORS, colors)
|
if ((Arrays.equals(FEED_ORIGINAL_SEEKBAR_GRADIENT_COLORS, colors)
|
||||||
&& Arrays.equals(ORIGINAL_SEEKBAR_GRADIENT_POSITIONS, positions)) {
|
&& Arrays.equals(FEED_ORIGINAL_SEEKBAR_GRADIENT_POSITIONS, positions))) {
|
||||||
Arrays.fill(colors, hideSeekbar
|
return HIDE_SEEKBAR_THUMBNAIL_ENABLED
|
||||||
? 0x00000000
|
? HIDDEN_SEEKBAR_GRADIENT_COLORS
|
||||||
: seekbarColor);
|
: customSeekbarColorGradient;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.printDebug(() -> "Ignoring gradient colors: " + Arrays.toString(colors)
|
Logger.printDebug(() -> "Ignoring gradient colors: " + colorArrayToHex(colors)
|
||||||
+ " positions: " + Arrays.toString(positions));
|
+ " positions: " + Arrays.toString(positions));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -198,7 +239,7 @@ public final class SeekbarColorPatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return colorValue == ORIGINAL_SEEKBAR_COLOR
|
return colorValue == ORIGINAL_SEEKBAR_COLOR
|
||||||
? getSeekbarColorValue(ORIGINAL_SEEKBAR_COLOR)
|
? customSeekbarColor
|
||||||
: colorValue;
|
: colorValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,11 +249,9 @@ public final class SeekbarColorPatch {
|
|||||||
* Overrides color used for the video player seekbar.
|
* Overrides color used for the video player seekbar.
|
||||||
*/
|
*/
|
||||||
public static int getVideoPlayerSeekbarColor(int originalColor) {
|
public static int getVideoPlayerSeekbarColor(int originalColor) {
|
||||||
if (!SEEKBAR_CUSTOM_COLOR_ENABLED) {
|
return SEEKBAR_CUSTOM_COLOR_ENABLED
|
||||||
return originalColor;
|
? getSeekbarColorValue(originalColor)
|
||||||
}
|
: originalColor;
|
||||||
|
|
||||||
return getSeekbarColorValue(originalColor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -221,10 +260,6 @@ public final class SeekbarColorPatch {
|
|||||||
*/
|
*/
|
||||||
private static int getSeekbarColorValue(int originalColor) {
|
private static int getSeekbarColorValue(int originalColor) {
|
||||||
try {
|
try {
|
||||||
if (!SEEKBAR_CUSTOM_COLOR_ENABLED || originalColor == seekbarColor) {
|
|
||||||
return originalColor; // nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
final int alphaDifference = Color.alpha(originalColor) - Color.alpha(ORIGINAL_SEEKBAR_COLOR);
|
final int alphaDifference = Color.alpha(originalColor) - Color.alpha(ORIGINAL_SEEKBAR_COLOR);
|
||||||
|
|
||||||
// The seekbar uses the same color but different brightness for different situations.
|
// The seekbar uses the same color but different brightness for different situations.
|
||||||
@@ -237,7 +272,7 @@ public final class SeekbarColorPatch {
|
|||||||
hsv[1] = customSeekbarColorHSV[1];
|
hsv[1] = customSeekbarColorHSV[1];
|
||||||
hsv[2] = clamp(customSeekbarColorHSV[2] + brightnessDifference, 0, 1);
|
hsv[2] = clamp(customSeekbarColorHSV[2] + brightnessDifference, 0, 1);
|
||||||
|
|
||||||
final int replacementAlpha = clamp(Color.alpha(seekbarColor) + alphaDifference, 0, 255);
|
final int replacementAlpha = clamp(Color.alpha(customSeekbarColor) + alphaDifference, 0, 255);
|
||||||
final int replacementColor = Color.HSVToColor(replacementAlpha, hsv);
|
final int replacementColor = Color.HSVToColor(replacementAlpha, hsv);
|
||||||
Logger.printDebug(() -> String.format("Original color: #%08X replacement color: #%08X",
|
Logger.printDebug(() -> String.format("Original color: #%08X replacement color: #%08X",
|
||||||
originalColor, replacementColor));
|
originalColor, replacementColor));
|
||||||
|
|||||||
@@ -1,21 +1,30 @@
|
|||||||
package app.revanced.extension.youtube.settings;
|
package app.revanced.extension.youtube.settings;
|
||||||
|
|
||||||
|
import static app.revanced.extension.shared.Utils.getResourceIdentifier;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
|
import android.util.TypedValue;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import app.revanced.extension.shared.Logger;
|
import android.widget.Toolbar;
|
||||||
import app.revanced.extension.youtube.ThemeHelper;
|
|
||||||
import app.revanced.extension.youtube.settings.preference.ReVancedPreferenceFragment;
|
import androidx.annotation.RequiresApi;
|
||||||
import app.revanced.extension.youtube.settings.preference.ReturnYouTubeDislikePreferenceFragment;
|
|
||||||
import app.revanced.extension.youtube.settings.preference.SponsorBlockPreferenceFragment;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static app.revanced.extension.shared.Utils.getChildView;
|
import app.revanced.extension.shared.Logger;
|
||||||
import static app.revanced.extension.shared.Utils.getResourceIdentifier;
|
import app.revanced.extension.shared.Utils;
|
||||||
|
import app.revanced.extension.shared.settings.AppLanguage;
|
||||||
|
import app.revanced.extension.shared.settings.BaseSettings;
|
||||||
|
import app.revanced.extension.youtube.ThemeHelper;
|
||||||
|
import app.revanced.extension.youtube.patches.VersionCheckPatch;
|
||||||
|
import app.revanced.extension.youtube.settings.preference.ReVancedPreferenceFragment;
|
||||||
|
import app.revanced.extension.youtube.settings.preference.ReturnYouTubeDislikePreferenceFragment;
|
||||||
|
import app.revanced.extension.youtube.settings.preference.SponsorBlockPreferenceFragment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hooks LicenseActivity.
|
* Hooks LicenseActivity.
|
||||||
@@ -25,17 +34,57 @@ import static app.revanced.extension.shared.Utils.getResourceIdentifier;
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class LicenseActivityHook {
|
public class LicenseActivityHook {
|
||||||
|
|
||||||
|
private static ViewGroup.LayoutParams toolbarLayoutParams;
|
||||||
|
|
||||||
|
public static void setToolbarLayoutParams(Toolbar toolbar) {
|
||||||
|
if (toolbarLayoutParams != null) {
|
||||||
|
toolbar.setLayoutParams(toolbarLayoutParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
* Overrides the ReVanced settings language.
|
||||||
|
*/
|
||||||
|
public static Context getAttachBaseContext(Context original) {
|
||||||
|
AppLanguage language = BaseSettings.REVANCED_LANGUAGE.get();
|
||||||
|
if (language == AppLanguage.DEFAULT) {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Utils.getContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static boolean useCairoSettingsFragment(boolean original) {
|
||||||
|
// Early targets have layout issues and it's better to always force off.
|
||||||
|
if (!VersionCheckPatch.IS_19_34_OR_GREATER) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Settings.RESTORE_OLD_SETTINGS_MENUS.get()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On the first launch of a clean install, forcing the cairo menu can give a
|
||||||
|
// half broken appearance because all the preference icons may not be available yet.
|
||||||
|
// 19.34+ cairo settings are always on, so it doesn't need to be forced anyway.
|
||||||
|
// Cairo setting will show on the next launch of the app.
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
* <p>
|
* <p>
|
||||||
* Hooks LicenseActivity#onCreate in order to inject our own fragment.
|
* Hooks LicenseActivity#onCreate in order to inject our own fragment.
|
||||||
*/
|
*/
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
public static void initialize(Activity licenseActivity) {
|
public static void initialize(Activity licenseActivity) {
|
||||||
try {
|
try {
|
||||||
ThemeHelper.setActivityTheme(licenseActivity);
|
ThemeHelper.setActivityTheme(licenseActivity);
|
||||||
licenseActivity.setContentView(
|
licenseActivity.setContentView(getResourceIdentifier(
|
||||||
getResourceIdentifier("revanced_settings_with_toolbar", "layout"));
|
"revanced_settings_with_toolbar", "layout"));
|
||||||
setBackButton(licenseActivity);
|
|
||||||
|
|
||||||
PreferenceFragment fragment;
|
PreferenceFragment fragment;
|
||||||
String toolbarTitleResourceName;
|
String toolbarTitleResourceName;
|
||||||
@@ -58,7 +107,7 @@ public class LicenseActivityHook {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setToolbarTitle(licenseActivity, toolbarTitleResourceName);
|
createToolbar(licenseActivity, toolbarTitleResourceName);
|
||||||
|
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
licenseActivity.getFragmentManager()
|
licenseActivity.getFragmentManager()
|
||||||
@@ -70,28 +119,36 @@ public class LicenseActivityHook {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setToolbarTitle(Activity activity, String toolbarTitleResourceName) {
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
ViewGroup toolbar = activity.findViewById(getToolbarResourceId());
|
|
||||||
TextView toolbarTextView = Objects.requireNonNull(getChildView(toolbar, false,
|
|
||||||
view -> view instanceof TextView));
|
|
||||||
toolbarTextView.setText(getResourceIdentifier(toolbarTitleResourceName, "string"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("UseCompatLoadingForDrawables")
|
@SuppressLint("UseCompatLoadingForDrawables")
|
||||||
private static void setBackButton(Activity activity) {
|
private static void createToolbar(Activity activity, String toolbarTitleResourceName) {
|
||||||
ViewGroup toolbar = activity.findViewById(getToolbarResourceId());
|
// Replace dummy placeholder toolbar.
|
||||||
ImageButton imageButton = Objects.requireNonNull(getChildView(toolbar, false,
|
// This is required to fix submenu title alignment issue with Android ASOP 15+
|
||||||
view -> view instanceof ImageButton));
|
ViewGroup toolBarParent = activity.findViewById(
|
||||||
imageButton.setImageDrawable(ReVancedPreferenceFragment.getBackButtonDrawable());
|
getResourceIdentifier("revanced_toolbar_parent", "id"));
|
||||||
imageButton.setOnClickListener(view -> activity.onBackPressed());
|
ViewGroup dummyToolbar = toolBarParent.findViewById(getResourceIdentifier(
|
||||||
}
|
"revanced_toolbar", "id"));
|
||||||
|
toolbarLayoutParams = dummyToolbar.getLayoutParams();
|
||||||
|
toolBarParent.removeView(dummyToolbar);
|
||||||
|
|
||||||
private static int getToolbarResourceId() {
|
Toolbar toolbar = new Toolbar(toolBarParent.getContext());
|
||||||
final int toolbarResourceId = getResourceIdentifier("revanced_toolbar", "id");
|
toolbar.setBackgroundColor(ThemeHelper.getToolbarBackgroundColor());
|
||||||
if (toolbarResourceId == 0) {
|
toolbar.setNavigationIcon(ReVancedPreferenceFragment.getBackButtonDrawable());
|
||||||
throw new IllegalStateException("Could not find back button resource");
|
toolbar.setNavigationOnClickListener(view -> activity.onBackPressed());
|
||||||
|
toolbar.setTitle(getResourceIdentifier(toolbarTitleResourceName, "string"));
|
||||||
|
|
||||||
|
final int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16,
|
||||||
|
Utils.getContext().getResources().getDisplayMetrics());
|
||||||
|
toolbar.setTitleMarginStart(margin);
|
||||||
|
toolbar.setTitleMarginEnd(margin);
|
||||||
|
TextView toolbarTextView = Utils.getChildView(toolbar, false,
|
||||||
|
view -> view instanceof TextView);
|
||||||
|
if (toolbarTextView != null) {
|
||||||
|
toolbarTextView.setTextColor(ThemeHelper.getForegroundColor());
|
||||||
}
|
}
|
||||||
return toolbarResourceId;
|
setToolbarLayoutParams(toolbar);
|
||||||
|
|
||||||
|
toolBarParent.addView(toolbar, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ import static app.revanced.extension.shared.settings.Setting.migrateFromOldPrefe
|
|||||||
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;
|
||||||
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.NotSpoofingAndroidAvailability;
|
import static app.revanced.extension.youtube.patches.ChangeFormFactorPatch.FormFactor;
|
||||||
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage;
|
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage;
|
||||||
|
import static app.revanced.extension.youtube.patches.ExitFullscreenPatch.FullscreenMode;
|
||||||
|
import static app.revanced.extension.youtube.patches.ForceOriginalAudioPatch.ForceOriginalAudioAvailability;
|
||||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHideExpandCloseAvailability;
|
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHideExpandCloseAvailability;
|
||||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHorizontalDragAvailability;
|
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHorizontalDragAvailability;
|
||||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType;
|
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType;
|
||||||
@@ -25,6 +27,8 @@ import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehavi
|
|||||||
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY;
|
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY;
|
||||||
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY_ONCE;
|
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY_ONCE;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
|
||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
import app.revanced.extension.shared.settings.BaseSettings;
|
import app.revanced.extension.shared.settings.BaseSettings;
|
||||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||||
@@ -43,18 +47,20 @@ 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 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 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);
|
||||||
// Speed
|
// Speed
|
||||||
|
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);
|
||||||
public static final BooleanSetting CUSTOM_SPEED_MENU = new BooleanSetting("revanced_custom_speed_menu", TRUE);
|
public static final BooleanSetting CUSTOM_SPEED_MENU = new BooleanSetting("revanced_custom_speed_menu", TRUE);
|
||||||
public static final FloatSetting PLAYBACK_SPEED_DEFAULT = new FloatSetting("revanced_playback_speed_default", -2.0f);
|
public static final FloatSetting PLAYBACK_SPEED_DEFAULT = new FloatSetting("revanced_playback_speed_default", -2.0f);
|
||||||
public static final StringSetting CUSTOM_PLAYBACK_SPEEDS = new StringSetting("revanced_custom_playback_speeds",
|
public static final StringSetting CUSTOM_PLAYBACK_SPEEDS = new StringSetting("revanced_custom_playback_speeds",
|
||||||
"0.25\n0.5\n0.75\n0.9\n0.95\n1.0\n1.05\n1.1\n1.25\n1.5\n1.75\n2.0\n3.0\n4.0\n5.0", true);
|
"0.25\n0.5\n0.75\n0.9\n0.95\n1.0\n1.05\n1.1\n1.25\n1.5\n1.75\n2.0\n3.0\n4.0\n5.0", true);
|
||||||
// Audio
|
// Audio
|
||||||
public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", FALSE, new NotSpoofingAndroidAvailability());
|
public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", FALSE, new ForceOriginalAudioAvailability());
|
||||||
|
|
||||||
// Ads
|
// Ads
|
||||||
public static final BooleanSetting HIDE_BUTTONED_ADS = new BooleanSetting("revanced_hide_buttoned_ads", TRUE);
|
public static final BooleanSetting HIDE_BUTTONED_ADS = new BooleanSetting("revanced_hide_buttoned_ads", TRUE);
|
||||||
@@ -120,6 +126,7 @@ public class Settings extends BaseSettings {
|
|||||||
public static final BooleanSetting DISABLE_LIKE_SUBSCRIBE_GLOW = new BooleanSetting("revanced_disable_like_subscribe_glow", FALSE);
|
public static final BooleanSetting DISABLE_LIKE_SUBSCRIBE_GLOW = new BooleanSetting("revanced_disable_like_subscribe_glow", FALSE);
|
||||||
public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE);
|
public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE);
|
||||||
public static final BooleanSetting DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE, true);
|
public static final BooleanSetting DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE, true);
|
||||||
|
public static final EnumSetting<FullscreenMode> EXIT_FULLSCREEN = new EnumSetting<>("revanced_exit_fullscreen", FullscreenMode.DISABLED);
|
||||||
public static final BooleanSetting HIDE_AUTOPLAY_BUTTON = new BooleanSetting("revanced_hide_autoplay_button", TRUE, true);
|
public static final BooleanSetting HIDE_AUTOPLAY_BUTTON = new BooleanSetting("revanced_hide_autoplay_button", TRUE, true);
|
||||||
public static final BooleanSetting HIDE_CAPTIONS_BUTTON = new BooleanSetting("revanced_hide_captions_button", FALSE);
|
public static final BooleanSetting HIDE_CAPTIONS_BUTTON = new BooleanSetting("revanced_hide_captions_button", FALSE);
|
||||||
public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_hide_cast_button", TRUE, true);
|
public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_hide_cast_button", TRUE, true);
|
||||||
@@ -139,10 +146,10 @@ public class Settings extends BaseSettings {
|
|||||||
public static final BooleanSetting HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES = new BooleanSetting("revanced_hide_subscribers_community_guidelines", TRUE);
|
public static final BooleanSetting HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES = new BooleanSetting("revanced_hide_subscribers_community_guidelines", TRUE);
|
||||||
public static final BooleanSetting HIDE_TIMED_REACTIONS = new BooleanSetting("revanced_hide_timed_reactions", TRUE);
|
public static final BooleanSetting HIDE_TIMED_REACTIONS = new BooleanSetting("revanced_hide_timed_reactions", TRUE);
|
||||||
public static final BooleanSetting HIDE_VIDEO_CHANNEL_WATERMARK = new BooleanSetting("revanced_hide_channel_watermark", TRUE);
|
public static final BooleanSetting HIDE_VIDEO_CHANNEL_WATERMARK = new BooleanSetting("revanced_hide_channel_watermark", TRUE);
|
||||||
public static final BooleanSetting PLAYBACK_SPEED_DIALOG_BUTTON = new BooleanSetting("revanced_playback_speed_dialog_button", FALSE);
|
|
||||||
public static final BooleanSetting PLAYER_POPUP_PANELS = new BooleanSetting("revanced_hide_player_popup_panels", FALSE);
|
|
||||||
public static final IntegerSetting PLAYER_OVERLAY_OPACITY = new IntegerSetting("revanced_player_overlay_opacity", 100, true);
|
|
||||||
public static final BooleanSetting OPEN_VIDEOS_FULLSCREEN_PORTRAIT = new BooleanSetting("revanced_open_videos_fullscreen_portrait", FALSE);
|
public static final BooleanSetting OPEN_VIDEOS_FULLSCREEN_PORTRAIT = new BooleanSetting("revanced_open_videos_fullscreen_portrait", FALSE);
|
||||||
|
public static final BooleanSetting PLAYBACK_SPEED_DIALOG_BUTTON = new BooleanSetting("revanced_playback_speed_dialog_button", FALSE);
|
||||||
|
public static final IntegerSetting PLAYER_OVERLAY_OPACITY = new IntegerSetting("revanced_player_overlay_opacity", 100, true);
|
||||||
|
public static final BooleanSetting PLAYER_POPUP_PANELS = new BooleanSetting("revanced_hide_player_popup_panels", FALSE);
|
||||||
// Miniplayer
|
// Miniplayer
|
||||||
public static final EnumSetting<MiniplayerType> MINIPLAYER_TYPE = new EnumSetting<>("revanced_miniplayer_type", MiniplayerType.DEFAULT, true);
|
public static final EnumSetting<MiniplayerType> MINIPLAYER_TYPE = new EnumSetting<>("revanced_miniplayer_type", MiniplayerType.DEFAULT, true);
|
||||||
private static final Availability MINIPLAYER_ANY_MODERN = MINIPLAYER_TYPE.availability(MODERN_1, MODERN_2, MODERN_3, MODERN_4);
|
private static final Availability MINIPLAYER_ANY_MODERN = MINIPLAYER_TYPE.availability(MODERN_1, MODERN_2, MODERN_3, MODERN_4);
|
||||||
@@ -200,15 +207,16 @@ public class Settings extends BaseSettings {
|
|||||||
public static final BooleanSetting HIDE_PLAYER_FLYOUT_WATCH_IN_VR = new BooleanSetting("revanced_hide_player_flyout_watch_in_vr", TRUE);
|
public static final BooleanSetting HIDE_PLAYER_FLYOUT_WATCH_IN_VR = new BooleanSetting("revanced_hide_player_flyout_watch_in_vr", TRUE);
|
||||||
|
|
||||||
// General layout
|
// General layout
|
||||||
|
public static final BooleanSetting RESTORE_OLD_SETTINGS_MENUS = new BooleanSetting("revanced_restore_old_settings_menus", FALSE, true);
|
||||||
|
public static final EnumSetting<FormFactor> CHANGE_FORM_FACTOR = new EnumSetting<>("revanced_change_form_factor", FormFactor.DEFAULT, true, "revanced_change_form_factor_user_dialog_message");
|
||||||
public static final BooleanSetting BYPASS_IMAGE_REGION_RESTRICTIONS = new BooleanSetting("revanced_bypass_image_region_restrictions", FALSE, true);
|
public static final BooleanSetting BYPASS_IMAGE_REGION_RESTRICTIONS = new BooleanSetting("revanced_bypass_image_region_restrictions", FALSE, true);
|
||||||
public static final BooleanSetting GRADIENT_LOADING_SCREEN = new BooleanSetting("revanced_gradient_loading_screen", FALSE, true);
|
public static final BooleanSetting GRADIENT_LOADING_SCREEN = new BooleanSetting("revanced_gradient_loading_screen", FALSE, true);
|
||||||
public static final BooleanSetting REMOVE_VIEWER_DISCRETION_DIALOG = new BooleanSetting("revanced_remove_viewer_discretion_dialog", FALSE,
|
public static final BooleanSetting REMOVE_VIEWER_DISCRETION_DIALOG = new BooleanSetting("revanced_remove_viewer_discretion_dialog", FALSE,
|
||||||
"revanced_remove_viewer_discretion_dialog_user_dialog_message");
|
"revanced_remove_viewer_discretion_dialog_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 SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message");
|
||||||
public static final BooleanSetting TABLET_LAYOUT = new BooleanSetting("revanced_tablet_layout", FALSE, true, "revanced_tablet_layout_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.35.36" : "17.33.42", true, parent(SPOOF_APP_VERSION));
|
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));
|
||||||
// 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));
|
||||||
@@ -233,6 +241,7 @@ public class Settings extends BaseSettings {
|
|||||||
public static final BooleanSetting HIDE_SHORTS_FULL_VIDEO_LINK_LABEL = new BooleanSetting("revanced_hide_shorts_full_video_link_label", FALSE);
|
public static final BooleanSetting HIDE_SHORTS_FULL_VIDEO_LINK_LABEL = new BooleanSetting("revanced_hide_shorts_full_video_link_label", FALSE);
|
||||||
public static final BooleanSetting HIDE_SHORTS_GREEN_SCREEN_BUTTON = new BooleanSetting("revanced_hide_shorts_green_screen_button", TRUE);
|
public static final BooleanSetting HIDE_SHORTS_GREEN_SCREEN_BUTTON = new BooleanSetting("revanced_hide_shorts_green_screen_button", TRUE);
|
||||||
public static final BooleanSetting HIDE_SHORTS_HASHTAG_BUTTON = new BooleanSetting("revanced_hide_shorts_hashtag_button", TRUE);
|
public static final BooleanSetting HIDE_SHORTS_HASHTAG_BUTTON = new BooleanSetting("revanced_hide_shorts_hashtag_button", TRUE);
|
||||||
|
public static final BooleanSetting HIDE_SHORTS_HISTORY = new BooleanSetting("revanced_hide_shorts_history", FALSE);
|
||||||
public static final BooleanSetting HIDE_SHORTS_HOME = new BooleanSetting("revanced_hide_shorts_home", FALSE);
|
public static final BooleanSetting HIDE_SHORTS_HOME = new BooleanSetting("revanced_hide_shorts_home", FALSE);
|
||||||
public static final BooleanSetting HIDE_SHORTS_INFO_PANEL = new BooleanSetting("revanced_hide_shorts_info_panel", TRUE);
|
public static final BooleanSetting HIDE_SHORTS_INFO_PANEL = new BooleanSetting("revanced_hide_shorts_info_panel", TRUE);
|
||||||
public static final BooleanSetting HIDE_SHORTS_JOIN_BUTTON = new BooleanSetting("revanced_hide_shorts_join_button", TRUE);
|
public static final BooleanSetting HIDE_SHORTS_JOIN_BUTTON = new BooleanSetting("revanced_hide_shorts_join_button", TRUE);
|
||||||
@@ -261,18 +270,19 @@ public class Settings extends BaseSettings {
|
|||||||
public static final BooleanSetting SHORTS_AUTOPLAY_BACKGROUND = new BooleanSetting("revanced_shorts_autoplay_background", TRUE);
|
public static final BooleanSetting SHORTS_AUTOPLAY_BACKGROUND = new BooleanSetting("revanced_shorts_autoplay_background", TRUE);
|
||||||
|
|
||||||
// Seekbar
|
// Seekbar
|
||||||
|
public static final BooleanSetting DISABLE_PRECISE_SEEKING_GESTURE = new BooleanSetting("revanced_disable_precise_seeking_gesture", FALSE);
|
||||||
public static final BooleanSetting DISABLE_PRECISE_SEEKING_GESTURE = new BooleanSetting("revanced_disable_precise_seeking_gesture", TRUE);
|
|
||||||
public static final BooleanSetting HIDE_SEEKBAR = new BooleanSetting("revanced_hide_seekbar", FALSE, true);
|
public static final BooleanSetting HIDE_SEEKBAR = new BooleanSetting("revanced_hide_seekbar", FALSE, true);
|
||||||
public static final BooleanSetting HIDE_SEEKBAR_THUMBNAIL = new BooleanSetting("revanced_hide_seekbar_thumbnail", FALSE);
|
public static final BooleanSetting HIDE_SEEKBAR_THUMBNAIL = new BooleanSetting("revanced_hide_seekbar_thumbnail", FALSE, true);
|
||||||
public static final BooleanSetting HIDE_TIMESTAMP = new BooleanSetting("revanced_hide_timestamp", FALSE);
|
public static final BooleanSetting HIDE_TIMESTAMP = new BooleanSetting("revanced_hide_timestamp", FALSE);
|
||||||
public static final BooleanSetting RESTORE_OLD_SEEKBAR_THUMBNAILS = new BooleanSetting("revanced_restore_old_seekbar_thumbnails", TRUE);
|
public static final BooleanSetting RESTORE_OLD_SEEKBAR_THUMBNAILS = new BooleanSetting("revanced_restore_old_seekbar_thumbnails", TRUE);
|
||||||
public static final BooleanSetting SEEKBAR_CUSTOM_COLOR = new BooleanSetting("revanced_seekbar_custom_color", FALSE, true);
|
public static final BooleanSetting SEEKBAR_TAPPING = new BooleanSetting("revanced_seekbar_tapping", FALSE);
|
||||||
public static final BooleanSetting SEEKBAR_TAPPING = new BooleanSetting("revanced_seekbar_tapping", TRUE);
|
|
||||||
public static final BooleanSetting SEEKBAR_THUMBNAILS_HIGH_QUALITY = new BooleanSetting("revanced_seekbar_thumbnails_high_quality", FALSE, true,
|
public static final BooleanSetting SEEKBAR_THUMBNAILS_HIGH_QUALITY = new BooleanSetting("revanced_seekbar_thumbnails_high_quality", FALSE, true,
|
||||||
"revanced_seekbar_thumbnails_high_quality_dialog_message", new SeekbarThumbnailsHighQualityAvailability());
|
"revanced_seekbar_thumbnails_high_quality_dialog_message", new SeekbarThumbnailsHighQualityAvailability());
|
||||||
public static final BooleanSetting SLIDE_TO_SEEK = new BooleanSetting("revanced_slide_to_seek", FALSE, true);
|
public static final BooleanSetting SLIDE_TO_SEEK = new BooleanSetting("revanced_slide_to_seek", FALSE, true);
|
||||||
public static final StringSetting SEEKBAR_CUSTOM_COLOR_VALUE = new StringSetting("revanced_seekbar_custom_color_value", "#FF0033", true, parent(SEEKBAR_CUSTOM_COLOR));
|
public static final BooleanSetting SEEKBAR_CUSTOM_COLOR = new BooleanSetting("revanced_seekbar_custom_color", FALSE, true);
|
||||||
|
private static final StringSetting DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY = new StringSetting("revanced_seekbar_custom_color_value", "#FF0033");
|
||||||
|
public static final StringSetting SEEKBAR_CUSTOM_COLOR_PRIMARY = new StringSetting("revanced_seekbar_custom_color_primary", "#FF0033", true, parent(SEEKBAR_CUSTOM_COLOR));
|
||||||
|
public static final StringSetting SEEKBAR_CUSTOM_COLOR_ACCENT = new StringSetting("revanced_seekbar_custom_color_accent", "#FF2791", true, parent(SEEKBAR_CUSTOM_COLOR));
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE);
|
public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE);
|
||||||
@@ -293,8 +303,9 @@ public class Settings extends BaseSettings {
|
|||||||
public static final BooleanSetting DEBUG_PROTOBUFFER = new BooleanSetting("revanced_debug_protobuffer", FALSE, parent(BaseSettings.DEBUG));
|
public static final BooleanSetting DEBUG_PROTOBUFFER = new BooleanSetting("revanced_debug_protobuffer", FALSE, parent(BaseSettings.DEBUG));
|
||||||
|
|
||||||
// Swipe controls
|
// Swipe controls
|
||||||
public static final BooleanSetting SWIPE_BRIGHTNESS = new BooleanSetting("revanced_swipe_brightness", TRUE);
|
public static final BooleanSetting SWIPE_CHANGE_VIDEO = new BooleanSetting("revanced_swipe_change_video", FALSE, true);
|
||||||
public static final BooleanSetting SWIPE_VOLUME = new BooleanSetting("revanced_swipe_volume", TRUE);
|
public static final BooleanSetting SWIPE_BRIGHTNESS = new BooleanSetting("revanced_swipe_brightness", FALSE);
|
||||||
|
public static final BooleanSetting SWIPE_VOLUME = new BooleanSetting("revanced_swipe_volume", FALSE);
|
||||||
public static final BooleanSetting SWIPE_PRESS_TO_ENGAGE = new BooleanSetting("revanced_swipe_press_to_engage", FALSE, true,
|
public static final BooleanSetting SWIPE_PRESS_TO_ENGAGE = new BooleanSetting("revanced_swipe_press_to_engage", FALSE, true,
|
||||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||||
public static final BooleanSetting SWIPE_HAPTIC_FEEDBACK = new BooleanSetting("revanced_swipe_haptic_feedback", TRUE, true,
|
public static final BooleanSetting SWIPE_HAPTIC_FEEDBACK = new BooleanSetting("revanced_swipe_haptic_feedback", TRUE, true,
|
||||||
@@ -399,6 +410,30 @@ public class Settings extends BaseSettings {
|
|||||||
MINIPLAYER_TYPE.save(MINIMAL);
|
MINIPLAYER_TYPE.save(MINIMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Migrate old single color seekbar with a slightly brighter accent color based on the primary.
|
||||||
|
// Eventually delete this logic.
|
||||||
|
if (!DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY.isSetToDefault()) {
|
||||||
|
try {
|
||||||
|
String oldPrimaryColorString = DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY.get();
|
||||||
|
final int oldPrimaryColor = Color.parseColor(oldPrimaryColorString);
|
||||||
|
SEEKBAR_CUSTOM_COLOR_PRIMARY.save(oldPrimaryColorString);
|
||||||
|
|
||||||
|
final float brightnessScale = 1.3f;
|
||||||
|
final int accentColor = Color.argb(
|
||||||
|
0, // Save without alpha channel.
|
||||||
|
Math.min(255, (int) (brightnessScale * Color.red(oldPrimaryColor))),
|
||||||
|
Math.min(255, (int) (brightnessScale * Color.green(oldPrimaryColor))),
|
||||||
|
Math.min(255, (int) (brightnessScale * Color.blue(oldPrimaryColor)))
|
||||||
|
);
|
||||||
|
|
||||||
|
SEEKBAR_CUSTOM_COLOR_ACCENT.save(String.format("#%06X", accentColor));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "Could not parse old seekbar color", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY.resetToDefault();
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region SB import/export callbacks
|
// region SB import/export callbacks
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package app.revanced.extension.youtube.settings.preference;
|
||||||
|
|
||||||
|
import static app.revanced.extension.shared.StringRef.str;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.preference.SwitchPreference;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
import app.revanced.extension.youtube.patches.ForceOriginalAudioPatch;
|
||||||
|
|
||||||
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
|
public class ForceOriginalAudioSwitchPreference extends SwitchPreference {
|
||||||
|
|
||||||
|
{
|
||||||
|
if (!ForceOriginalAudioPatch.PATCH_AVAILABLE) {
|
||||||
|
// Show why force audio is not available.
|
||||||
|
String summary = str("revanced_force_original_audio_not_available");
|
||||||
|
setSummary(summary);
|
||||||
|
setSummaryOn(summary);
|
||||||
|
setSummaryOff(summary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForceOriginalAudioSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
public ForceOriginalAudioSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
public ForceOriginalAudioSwitchPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
public ForceOriginalAudioSwitchPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,9 +25,12 @@ 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.BaseSettings;
|
||||||
|
import app.revanced.extension.shared.settings.EnumSetting;
|
||||||
import app.revanced.extension.shared.settings.preference.AbstractPreferenceFragment;
|
import app.revanced.extension.shared.settings.preference.AbstractPreferenceFragment;
|
||||||
import app.revanced.extension.youtube.ThemeHelper;
|
import app.revanced.extension.youtube.ThemeHelper;
|
||||||
import app.revanced.extension.youtube.patches.playback.speed.CustomPlaybackSpeedPatch;
|
import app.revanced.extension.youtube.patches.playback.speed.CustomPlaybackSpeedPatch;
|
||||||
|
import app.revanced.extension.youtube.settings.LicenseActivityHook;
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -109,15 +112,20 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
|
|||||||
CustomPlaybackSpeedPatch.initializeListPreference(playbackPreference);
|
CustomPlaybackSpeedPatch.initializeListPreference(playbackPreference);
|
||||||
}
|
}
|
||||||
|
|
||||||
preference = findPreference(Settings.SPOOF_VIDEO_STREAMS_LANGUAGE.key);
|
sortPreferenceListMenu(Settings.SPOOF_VIDEO_STREAMS_LANGUAGE);
|
||||||
if (preference instanceof ListPreference languagePreference) {
|
sortPreferenceListMenu(BaseSettings.REVANCED_LANGUAGE);
|
||||||
sortListPreferenceByValues(languagePreference, 1);
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "initialize failure", ex);
|
Logger.printException(() -> "initialize failure", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sortPreferenceListMenu(EnumSetting<?> setting) {
|
||||||
|
Preference preference = findPreference(setting.key);
|
||||||
|
if (preference instanceof ListPreference languagePreference) {
|
||||||
|
sortListPreferenceByValues(languagePreference, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setPreferenceScreenToolbar(PreferenceScreen parentScreen) {
|
private void setPreferenceScreenToolbar(PreferenceScreen parentScreen) {
|
||||||
for (int i = 0, preferenceCount = parentScreen.getPreferenceCount(); i < preferenceCount; i++) {
|
for (int i = 0, preferenceCount = parentScreen.getPreferenceCount(); i < preferenceCount; i++) {
|
||||||
Preference childPreference = parentScreen.getPreference(i);
|
Preference childPreference = parentScreen.getPreference(i);
|
||||||
@@ -133,9 +141,6 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
|
|||||||
.getParent();
|
.getParent();
|
||||||
|
|
||||||
// Fix required for Android 15 and YT 19.45+
|
// Fix required for Android 15 and YT 19.45+
|
||||||
// FIXME:
|
|
||||||
// On Android 15 the text layout is not aligned the same as the parent
|
|
||||||
// screen and it looks a little off. Otherwise this works.
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
rootView.setOnApplyWindowInsetsListener((v, insets) -> {
|
rootView.setOnApplyWindowInsetsListener((v, insets) -> {
|
||||||
Insets statusInsets = insets.getInsets(WindowInsets.Type.statusBars());
|
Insets statusInsets = insets.getInsets(WindowInsets.Type.statusBars());
|
||||||
@@ -162,6 +167,8 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
|
|||||||
toolbarTextView.setTextColor(ThemeHelper.getForegroundColor());
|
toolbarTextView.setTextColor(ThemeHelper.getForegroundColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LicenseActivityHook.setToolbarLayoutParams(toolbar);
|
||||||
|
|
||||||
rootView.addView(toolbar, 0);
|
rootView.addView(toolbar, 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package app.revanced.extension.youtube.settings.preference;
|
||||||
|
|
||||||
|
import static app.revanced.extension.shared.StringRef.str;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.shared.Utils;
|
||||||
|
import app.revanced.extension.shared.settings.BaseSettings;
|
||||||
|
import app.revanced.extension.shared.settings.Setting;
|
||||||
|
import app.revanced.extension.shared.spoof.ClientType;
|
||||||
|
|
||||||
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
|
public class SpoofStreamingDataSideEffectsPreference extends Preference {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private ClientType currentClientType;
|
||||||
|
|
||||||
|
private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
|
||||||
|
// Because this listener may run before the ReVanced settings fragment updates Settings,
|
||||||
|
// this could show the prior config and not the current.
|
||||||
|
//
|
||||||
|
// Push this call to the end of the main run queue,
|
||||||
|
// so all other listeners are done and Settings is up to date.
|
||||||
|
Utils.runOnMainThread(this::updateUI);
|
||||||
|
};
|
||||||
|
|
||||||
|
public SpoofStreamingDataSideEffectsPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpoofStreamingDataSideEffectsPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpoofStreamingDataSideEffectsPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpoofStreamingDataSideEffectsPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addChangeListener() {
|
||||||
|
Setting.preferences.preferences.registerOnSharedPreferenceChangeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeChangeListener() {
|
||||||
|
Setting.preferences.preferences.unregisterOnSharedPreferenceChangeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
|
||||||
|
super.onAttachedToHierarchy(preferenceManager);
|
||||||
|
updateUI();
|
||||||
|
addChangeListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPrepareForRemoval() {
|
||||||
|
super.onPrepareForRemoval();
|
||||||
|
removeChangeListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateUI() {
|
||||||
|
ClientType clientType = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
|
||||||
|
if (currentClientType == clientType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.printDebug(() -> "Updating spoof stream side effects preference");
|
||||||
|
setEnabled(BaseSettings.SPOOF_VIDEO_STREAMS.get());
|
||||||
|
|
||||||
|
String key = "revanced_spoof_video_streams_about_" +
|
||||||
|
(clientType == ClientType.IOS_UNPLUGGED
|
||||||
|
? "ios_tv"
|
||||||
|
: "android");
|
||||||
|
String title = str(key + "_title");
|
||||||
|
String summary = str(key + "_summary");
|
||||||
|
|
||||||
|
// Android VR supports AV1 but all other clients do not.
|
||||||
|
if (clientType != ClientType.ANDROID_VR && clientType != ClientType.ANDROID_VR_NO_AUTH) {
|
||||||
|
summary += '\n' + str("revanced_spoof_video_streams_about_no_av1");
|
||||||
|
}
|
||||||
|
|
||||||
|
setTitle(title);
|
||||||
|
setSummary(summary);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,12 +3,15 @@ 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.os.Build;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.EnumMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
@@ -54,20 +57,21 @@ public final class NavigationBar {
|
|||||||
* How long to wait for the set nav button latch to be released. Maximum wait time must
|
* How long to wait for the set nav button latch to be released. Maximum wait time must
|
||||||
* be as small as possible while still allowing enough time for the nav bar to update.
|
* be as small as possible while still allowing enough time for the nav bar to update.
|
||||||
*
|
*
|
||||||
* YT calls it's back button handlers out of order,
|
* YT calls it's back button handlers out of order, and litho starts filtering before the
|
||||||
* and litho starts filtering before the navigation bar is updated.
|
* navigation bar is updated. Fixing this situation and not needlessly waiting requires
|
||||||
|
* somehow detecting if a back button key/gesture will not change the active tab.
|
||||||
*
|
*
|
||||||
* Fixing this situation and not needlessly waiting requires somehow
|
* On average the time between pressing the back button and the first litho event is
|
||||||
* detecting if a back button key-press will cause a tab change.
|
* about 10-20ms. Waiting up to 75-150ms should be enough time to handle normal use cases
|
||||||
|
* and not be noticeable, since YT typically takes 100-200ms (or more) to update the view.
|
||||||
*
|
*
|
||||||
* Typically after pressing the back button, the time between the first litho event and
|
* This delay is only noticeable when the device back button/gesture will not
|
||||||
* when the nav button is updated is about 10-20ms. Using 50-100ms here should be enough time
|
* change the current navigation tab, such as backing out of the watch history.
|
||||||
* and not noticeable, since YT typically takes 100-200ms (or more) to update the view anyways.
|
|
||||||
*
|
*
|
||||||
* This issue can also be avoided on a patch by patch basis, by avoiding calls to
|
* This issue can also be avoided on a patch by patch basis, by avoiding calls to
|
||||||
* {@link NavigationButton#getSelectedNavigationButton()} unless absolutely necessary.
|
* {@link NavigationButton#getSelectedNavigationButton()} unless absolutely necessary.
|
||||||
*/
|
*/
|
||||||
private static final long LATCH_AWAIT_TIMEOUT_MILLISECONDS = 75;
|
private static final long LATCH_AWAIT_TIMEOUT_MILLISECONDS = 120;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used as a workaround to fix the issue of YT calling back button handlers out of order.
|
* Used as a workaround to fix the issue of YT calling back button handlers out of order.
|
||||||
@@ -113,7 +117,8 @@ public final class NavigationBar {
|
|||||||
// The latch is released from the main thread, and waiting from the main thread will always timeout.
|
// The latch is released from the main thread, and waiting from the main thread will always timeout.
|
||||||
// This situation has only been observed when navigating out of a submenu and not changing tabs.
|
// This situation has only been observed when navigating out of a submenu and not changing tabs.
|
||||||
// and for that use case the nav bar does not change so it's safe to return here.
|
// and for that use case the nav bar does not change so it's safe to return here.
|
||||||
Logger.printDebug(() -> "Cannot block main thread waiting for nav button. Using last known navbar button status.");
|
Logger.printDebug(() -> "Cannot block main thread waiting for nav button. " +
|
||||||
|
"Using last known navbar button status.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +136,9 @@ public final class NavigationBar {
|
|||||||
Logger.printDebug(() -> "Latch wait timed out");
|
Logger.printDebug(() -> "Latch wait timed out");
|
||||||
|
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
Logger.printException(() -> "Latch wait interrupted failure", ex); // Will never happen.
|
// Calling YouTube thread was interrupted.
|
||||||
|
Logger.printException(() -> "Latch wait interrupted", ex);
|
||||||
|
Thread.currentThread().interrupt(); // Restore interrupt status flag.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,6 +245,30 @@ public final class NavigationBar {
|
|||||||
// Code is added during patching.
|
// Code is added during patching.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the bundled non cairo filled icon instead of a custom icon.
|
||||||
|
* Use the old non cairo filled icon, which is almost identical to
|
||||||
|
* the what would be the filled cairo icon.
|
||||||
|
*/
|
||||||
|
private static final int fillBellCairoBlack = Utils.getResourceIdentifier(
|
||||||
|
"yt_fill_bell_black_24", "drawable");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
* Fixes missing drawable.
|
||||||
|
*/
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
public static void setCairoNotificationFilledIcon(EnumMap enumMap, Enum tabActivityCairo) {
|
||||||
|
if (fillBellCairoBlack != 0) {
|
||||||
|
// Show a popup informing this fix is no longer needed to those who might care.
|
||||||
|
if (BaseSettings.DEBUG.get() && enumMap.containsKey(tabActivityCairo)) {
|
||||||
|
Logger.printException(() -> "YouTube fixed the cairo notification icons");
|
||||||
|
}
|
||||||
|
enumMap.putIfAbsent(tabActivityCairo, fillBellCairoBlack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum NavigationButton {
|
public enum NavigationButton {
|
||||||
HOME("PIVOT_HOME", "TAB_HOME_CAIRO"),
|
HOME("PIVOT_HOME", "TAB_HOME_CAIRO"),
|
||||||
SHORTS("TAB_SHORTS", "TAB_SHORTS_CAIRO"),
|
SHORTS("TAB_SHORTS", "TAB_SHORTS_CAIRO"),
|
||||||
@@ -246,6 +277,10 @@ public final class NavigationBar {
|
|||||||
* This tab will never be in a selected state, even if the create video UI is on screen.
|
* This tab will never be in a selected state, even if the create video UI is on screen.
|
||||||
*/
|
*/
|
||||||
CREATE("CREATION_TAB_LARGE", "CREATION_TAB_LARGE_CAIRO"),
|
CREATE("CREATION_TAB_LARGE", "CREATION_TAB_LARGE_CAIRO"),
|
||||||
|
/**
|
||||||
|
* Only shown to automotive layout.
|
||||||
|
*/
|
||||||
|
EXPLORE("TAB_EXPLORE"),
|
||||||
SUBSCRIPTIONS("PIVOT_SUBSCRIPTIONS", "TAB_SUBSCRIPTIONS_CAIRO"),
|
SUBSCRIPTIONS("PIVOT_SUBSCRIPTIONS", "TAB_SUBSCRIPTIONS_CAIRO"),
|
||||||
/**
|
/**
|
||||||
* Notifications tab. Only present when
|
* Notifications tab. Only present when
|
||||||
@@ -283,8 +318,8 @@ public final class NavigationBar {
|
|||||||
*
|
*
|
||||||
* All code calling this method should handle a null return value.
|
* All code calling this method should handle a null return value.
|
||||||
*
|
*
|
||||||
* <b>Due to issues with how YT processes physical back button events,
|
* <b>Due to issues with how YT processes physical back button/gesture events,
|
||||||
* this patch uses workarounds that can cause this method to take up to 75ms
|
* this patch uses workarounds that can cause this method to take up to 120ms
|
||||||
* if the device back button was recently pressed.</b>
|
* if the device back button was recently pressed.</b>
|
||||||
*
|
*
|
||||||
* @return The active navigation tab.
|
* @return The active navigation tab.
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ enum class PlayerType {
|
|||||||
onChange(currentPlayerType)
|
onChange(currentPlayerType)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Volatile // value is read/write from different threads
|
@Volatile // Read/write from different threads.
|
||||||
private var currentPlayerType = NONE
|
private var currentPlayerType = NONE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ enum class VideoState {
|
|||||||
currentVideoState = value
|
currentVideoState = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Volatile // Read/write from different threads.
|
||||||
private var currentVideoState: VideoState? = null
|
private var currentVideoState: VideoState? = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,11 +150,16 @@ public class SBRequester {
|
|||||||
String end = String.format(Locale.US, TIME_TEMPLATE, endTime / 1000f);
|
String end = String.format(Locale.US, TIME_TEMPLATE, endTime / 1000f);
|
||||||
String duration = String.format(Locale.US, TIME_TEMPLATE, videoLength / 1000f);
|
String duration = String.format(Locale.US, TIME_TEMPLATE, videoLength / 1000f);
|
||||||
|
|
||||||
HttpURLConnection connection = getConnectionFromRoute(SBRoutes.SUBMIT_SEGMENTS, privateUserId, videoId, category, start, end, duration);
|
HttpURLConnection connection = getConnectionFromRoute(SBRoutes.SUBMIT_SEGMENTS,
|
||||||
|
privateUserId, videoId, category, start, end, duration);
|
||||||
final int responseCode = connection.getResponseCode();
|
final int responseCode = connection.getResponseCode();
|
||||||
|
|
||||||
String userMessage = switch (responseCode) {
|
if (responseCode == HTTP_STATUS_CODE_SUCCESS) {
|
||||||
case HTTP_STATUS_CODE_SUCCESS -> str("revanced_sb_submit_succeeded");
|
Utils.showToastLong(str("revanced_sb_submit_succeeded"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String userErrorMessage = switch (responseCode) {
|
||||||
case 409 -> str("revanced_sb_submit_failed_duplicate");
|
case 409 -> str("revanced_sb_submit_failed_duplicate");
|
||||||
case 403 -> str("revanced_sb_submit_failed_forbidden",
|
case 403 -> str("revanced_sb_submit_failed_forbidden",
|
||||||
Requester.parseErrorStringAndDisconnect(connection));
|
Requester.parseErrorStringAndDisconnect(connection));
|
||||||
@@ -167,7 +172,7 @@ public class SBRequester {
|
|||||||
|
|
||||||
// Message might be about the users account or an error too large to show in a toast.
|
// Message might be about the users account or an error too large to show in a toast.
|
||||||
// Use a dialog instead.
|
// Use a dialog instead.
|
||||||
SponsorBlockUtils.showErrorDialog(userMessage);
|
SponsorBlockUtils.showErrorDialog(userErrorMessage);
|
||||||
} catch (SocketTimeoutException ex) {
|
} catch (SocketTimeoutException ex) {
|
||||||
Logger.printDebug(() -> "Timeout", ex);
|
Logger.printDebug(() -> "Timeout", ex);
|
||||||
Utils.showToastLong(str("revanced_sb_submit_failed_timeout"));
|
Utils.showToastLong(str("revanced_sb_submit_failed_timeout"));
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import android.view.MotionEvent
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import app.revanced.extension.shared.Logger.printDebug
|
import app.revanced.extension.shared.Logger.printDebug
|
||||||
import app.revanced.extension.shared.Logger.printException
|
import app.revanced.extension.shared.Logger.printException
|
||||||
|
import app.revanced.extension.youtube.settings.Settings
|
||||||
import app.revanced.extension.youtube.shared.PlayerType
|
import app.revanced.extension.youtube.shared.PlayerType
|
||||||
import app.revanced.extension.youtube.swipecontrols.controller.AudioVolumeController
|
import app.revanced.extension.youtube.swipecontrols.controller.AudioVolumeController
|
||||||
import app.revanced.extension.youtube.swipecontrols.controller.ScreenBrightnessController
|
import app.revanced.extension.youtube.swipecontrols.controller.ScreenBrightnessController
|
||||||
@@ -232,5 +233,12 @@ class SwipeControlsHostActivity : Activity() {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
var currentHost: WeakReference<SwipeControlsHostActivity> = WeakReference(null)
|
var currentHost: WeakReference<SwipeControlsHostActivity> = WeakReference(null)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
@Suppress("unused")
|
||||||
|
@JvmStatic
|
||||||
|
fun allowSwipeChangeVideo(original: Boolean): Boolean = Settings.SWIPE_CHANGE_VIDEO.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
package com.google.protos.youtube.api.innertube;
|
|
||||||
|
|
||||||
public class InnertubeContext$ClientInfo {
|
|
||||||
public int r;
|
|
||||||
}
|
|
||||||
@@ -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.7.0-dev.1
|
version = 5.10.0-dev.2
|
||||||
|
|||||||
@@ -461,10 +461,6 @@ public final class app/revanced/patches/reddit/customclients/joeyforreddit/detec
|
|||||||
public static final fun getDisablePiracyDetectionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getDisablePiracyDetectionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/reddit/customclients/redditisfun/api/FingerprintsKt {
|
|
||||||
public static final fun baseClientIdFingerprint (Ljava/lang/String;)Lapp/revanced/patcher/Fingerprint;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class app/revanced/patches/reddit/customclients/redditisfun/api/SpoofClientPatchKt {
|
public final class app/revanced/patches/reddit/customclients/redditisfun/api/SpoofClientPatchKt {
|
||||||
public static final fun getSpoofClientPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSpoofClientPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
@@ -548,7 +544,6 @@ public final class app/revanced/patches/shared/misc/checks/BaseCheckEnvironmentP
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/shared/misc/extension/ExtensionHook {
|
public final class app/revanced/patches/shared/misc/extension/ExtensionHook {
|
||||||
public final fun getFingerprint ()Lapp/revanced/patcher/Fingerprint;
|
|
||||||
public final fun invoke (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;)V
|
public final fun invoke (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,16 +603,19 @@ public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/shared/misc/settings/SettingsPatchKt {
|
public final class app/revanced/patches/shared/misc/settings/SettingsPatchKt {
|
||||||
|
public static final fun settingsPatch (Ljava/util/List;Ljava/util/Set;)Lapp/revanced/patcher/patch/ResourcePatch;
|
||||||
public static final fun settingsPatch (Lkotlin/Pair;Ljava/util/Set;)Lapp/revanced/patcher/patch/ResourcePatch;
|
public static final fun settingsPatch (Lkotlin/Pair;Ljava/util/Set;)Lapp/revanced/patcher/patch/ResourcePatch;
|
||||||
public static synthetic fun settingsPatch$default (Lkotlin/Pair;Ljava/util/Set;ILjava/lang/Object;)Lapp/revanced/patcher/patch/ResourcePatch;
|
public static synthetic fun settingsPatch$default (Ljava/util/List;Ljava/util/Set;ILjava/lang/Object;)Lapp/revanced/patcher/patch/ResourcePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
public abstract class app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
||||||
public static final field Companion Lapp/revanced/patches/shared/misc/settings/preference/BasePreference$Companion;
|
public static final field Companion Lapp/revanced/patches/shared/misc/settings/preference/BasePreference$Companion;
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public fun equals (Ljava/lang/Object;)Z
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getIcon ()Ljava/lang/String;
|
||||||
public final fun getKey ()Ljava/lang/String;
|
public final fun getKey ()Ljava/lang/String;
|
||||||
|
public final fun getLayout ()Ljava/lang/String;
|
||||||
public final fun getSummaryKey ()Ljava/lang/String;
|
public final fun getSummaryKey ()Ljava/lang/String;
|
||||||
public final fun getTag ()Ljava/lang/String;
|
public final fun getTag ()Ljava/lang/String;
|
||||||
public final fun getTitleKey ()Ljava/lang/String;
|
public final fun getTitleKey ()Ljava/lang/String;
|
||||||
@@ -640,17 +638,19 @@ public abstract class app/revanced/patches/shared/misc/settings/preference/BaseP
|
|||||||
|
|
||||||
public abstract class app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$BasePreferenceCollection {
|
public abstract class app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$BasePreferenceCollection {
|
||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public final fun getIcon ()Ljava/lang/String;
|
||||||
public final fun getKey ()Ljava/lang/String;
|
public final fun getKey ()Ljava/lang/String;
|
||||||
|
public final fun getLayout ()Ljava/lang/String;
|
||||||
public final fun getPreferences ()Ljava/util/Set;
|
public final fun getPreferences ()Ljava/util/Set;
|
||||||
public final fun getTitleKey ()Ljava/lang/String;
|
public final fun getTitleKey ()Ljava/lang/String;
|
||||||
public abstract fun transform ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;
|
public abstract fun transform ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen : app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$BasePreferenceCollection {
|
public class app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen : app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$BasePreferenceCollection {
|
||||||
public fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;)V
|
public fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;)V
|
||||||
public synthetic fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public final fun addPreferences ([Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;)V
|
public final fun addPreferences ([Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;)V
|
||||||
public final fun getCategories ()Ljava/util/Set;
|
public final fun getCategories ()Ljava/util/Set;
|
||||||
public synthetic fun transform ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;
|
public synthetic fun transform ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;
|
||||||
@@ -658,8 +658,8 @@ public class app/revanced/patches/shared/misc/settings/preference/BasePreference
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen$Category : app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$BasePreferenceCollection {
|
public class app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen$Category : app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$BasePreferenceCollection {
|
||||||
public fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;)V
|
public fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;)V
|
||||||
public synthetic fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public final fun addPreferences ([Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;)V
|
public final fun addPreferences ([Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;)V
|
||||||
public synthetic fun transform ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;
|
public synthetic fun transform ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;
|
||||||
public fun transform ()Lapp/revanced/patches/shared/misc/settings/preference/PreferenceCategory;
|
public fun transform ()Lapp/revanced/patches/shared/misc/settings/preference/PreferenceCategory;
|
||||||
@@ -667,6 +667,7 @@ public class app/revanced/patches/shared/misc/settings/preference/BasePreference
|
|||||||
|
|
||||||
public final class app/revanced/patches/shared/misc/settings/preference/InputType : java/lang/Enum {
|
public final class app/revanced/patches/shared/misc/settings/preference/InputType : java/lang/Enum {
|
||||||
public static final field NUMBER Lapp/revanced/patches/shared/misc/settings/preference/InputType;
|
public static final field NUMBER Lapp/revanced/patches/shared/misc/settings/preference/InputType;
|
||||||
|
public static final field NUMBER_DECIMAL Lapp/revanced/patches/shared/misc/settings/preference/InputType;
|
||||||
public static final field TEXT Lapp/revanced/patches/shared/misc/settings/preference/InputType;
|
public static final field TEXT Lapp/revanced/patches/shared/misc/settings/preference/InputType;
|
||||||
public static final field TEXT_CAP_CHARACTERS Lapp/revanced/patches/shared/misc/settings/preference/InputType;
|
public static final field TEXT_CAP_CHARACTERS Lapp/revanced/patches/shared/misc/settings/preference/InputType;
|
||||||
public static final field TEXT_MULTI_LINE Lapp/revanced/patches/shared/misc/settings/preference/InputType;
|
public static final field TEXT_MULTI_LINE Lapp/revanced/patches/shared/misc/settings/preference/InputType;
|
||||||
@@ -677,8 +678,8 @@ public final class app/revanced/patches/shared/misc/settings/preference/InputTyp
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/shared/misc/settings/preference/IntentPreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
public final class app/revanced/patches/shared/misc/settings/preference/IntentPreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/IntentPreference$Intent;)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/IntentPreference$Intent;)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/IntentPreference$Intent;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/IntentPreference$Intent;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public fun equals (Ljava/lang/Object;)Z
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
public final fun getIntent ()Lapp/revanced/patches/shared/misc/settings/preference/IntentPreference$Intent;
|
public final fun getIntent ()Lapp/revanced/patches/shared/misc/settings/preference/IntentPreference$Intent;
|
||||||
public fun hashCode ()I
|
public fun hashCode ()I
|
||||||
@@ -698,8 +699,8 @@ public final class app/revanced/patches/shared/misc/settings/preference/ListPref
|
|||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/util/resource/ArrayResource;Lapp/revanced/util/resource/ArrayResource;)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/util/resource/ArrayResource;Lapp/revanced/util/resource/ArrayResource;)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/util/resource/ArrayResource;Lapp/revanced/util/resource/ArrayResource;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/util/resource/ArrayResource;Lapp/revanced/util/resource/ArrayResource;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public final fun getEntries ()Lapp/revanced/util/resource/ArrayResource;
|
public final fun getEntries ()Lapp/revanced/util/resource/ArrayResource;
|
||||||
public final fun getEntriesKey ()Ljava/lang/String;
|
public final fun getEntriesKey ()Ljava/lang/String;
|
||||||
public final fun getEntryValues ()Lapp/revanced/util/resource/ArrayResource;
|
public final fun getEntryValues ()Lapp/revanced/util/resource/ArrayResource;
|
||||||
@@ -708,22 +709,22 @@ public final class app/revanced/patches/shared/misc/settings/preference/ListPref
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/shared/misc/settings/preference/NonInteractivePreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
public final class app/revanced/patches/shared/misc/settings/preference/NonInteractivePreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public final fun getSelectable ()Z
|
public final fun getSelectable ()Z
|
||||||
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class app/revanced/patches/shared/misc/settings/preference/PreferenceCategory : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
public class app/revanced/patches/shared/misc/settings/preference/PreferenceCategory : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;Ljava/lang/String;Ljava/util/Set;)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public final fun getPreferences ()Ljava/util/Set;
|
public final fun getPreferences ()Ljava/util/Set;
|
||||||
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class app/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
public class app/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;Ljava/lang/String;Ljava/util/Set;)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;Ljava/lang/String;Ljava/util/Set;)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public final fun getPreferences ()Ljava/util/Set;
|
public final fun getPreferences ()Ljava/util/Set;
|
||||||
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
||||||
}
|
}
|
||||||
@@ -732,6 +733,7 @@ public final class app/revanced/patches/shared/misc/settings/preference/Preferen
|
|||||||
public static final field BY_KEY Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;
|
public static final field BY_KEY Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;
|
||||||
public static final field BY_TITLE Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;
|
public static final field BY_TITLE Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;
|
||||||
public static final field UNSORTED Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;
|
public static final field UNSORTED Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;
|
||||||
|
public final fun appendSortType (Ljava/lang/String;)Ljava/lang/String;
|
||||||
public static fun getEntries ()Lkotlin/enums/EnumEntries;
|
public static fun getEntries ()Lkotlin/enums/EnumEntries;
|
||||||
public final fun getKeySuffix ()Ljava/lang/String;
|
public final fun getKeySuffix ()Ljava/lang/String;
|
||||||
public static fun valueOf (Ljava/lang/String;)Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;
|
public static fun valueOf (Ljava/lang/String;)Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference$Sorting;
|
||||||
@@ -750,8 +752,8 @@ public final class app/revanced/patches/shared/misc/settings/preference/SummaryT
|
|||||||
|
|
||||||
public final class app/revanced/patches/shared/misc/settings/preference/SwitchPreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
public final class app/revanced/patches/shared/misc/settings/preference/SwitchPreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public final fun getSummaryOffKey ()Ljava/lang/String;
|
public final fun getSummaryOffKey ()Ljava/lang/String;
|
||||||
public final fun getSummaryOnKey ()Ljava/lang/String;
|
public final fun getSummaryOnKey ()Ljava/lang/String;
|
||||||
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
||||||
@@ -759,8 +761,8 @@ public final class app/revanced/patches/shared/misc/settings/preference/SwitchPr
|
|||||||
|
|
||||||
public final class app/revanced/patches/shared/misc/settings/preference/TextPreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
public final class app/revanced/patches/shared/misc/settings/preference/TextPreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/InputType;)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/InputType;)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/InputType;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/InputType;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public final fun getInputType ()Lapp/revanced/patches/shared/misc/settings/preference/InputType;
|
public final fun getInputType ()Lapp/revanced/patches/shared/misc/settings/preference/InputType;
|
||||||
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
||||||
}
|
}
|
||||||
@@ -1106,6 +1108,10 @@ public final class app/revanced/patches/youtube/layout/buttons/overlay/HidePlaye
|
|||||||
public static final fun getHidePlayerOverlayButtonsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getHidePlayerOverlayButtonsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatchKt {
|
||||||
|
public static final fun getChangeFormFactorPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatchKt {
|
public final class app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatchKt {
|
||||||
public static final fun getHideEndscreenCardsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getHideEndscreenCardsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
@@ -1235,7 +1241,6 @@ public final class app/revanced/patches/youtube/layout/startupshortsreset/Disabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/layout/tablet/EnableTabletLayoutPatchKt {
|
public final class app/revanced/patches/youtube/layout/tablet/EnableTabletLayoutPatchKt {
|
||||||
public static final field EXTENSION_CLASS_DESCRIPTOR Ljava/lang/String;
|
|
||||||
public static final fun getEnableTabletLayoutPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getEnableTabletLayoutPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1268,10 +1273,6 @@ public final class app/revanced/patches/youtube/misc/backgroundplayback/Backgrou
|
|||||||
public static final fun getBackgroundPlaybackPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getBackgroundPlaybackPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/misc/check/CheckEnvironmentPatchKt {
|
|
||||||
public static final fun getCheckEnvironmentPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatchKt {
|
public final class app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatchKt {
|
||||||
public static final fun getEnableDebuggingPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getEnableDebuggingPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
@@ -1296,6 +1297,10 @@ public final class app/revanced/patches/youtube/misc/fix/playback/UserAgentClien
|
|||||||
public static final fun getUserAgentClientSpoofPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getUserAgentClientSpoofPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/youtube/misc/fix/playbackspeed/FIxPlaybackSpeedWhilePlayingPatchKt {
|
||||||
|
public static final fun getFixPlaybackSpeedWhilePlayingPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatchKt {
|
public final class app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatchKt {
|
||||||
public static final fun getGmsCoreSupportPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getGmsCoreSupportPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
@@ -1360,6 +1365,7 @@ public final class app/revanced/patches/youtube/misc/playservice/VersionCheckPat
|
|||||||
public static final fun is_19_43_or_greater ()Z
|
public static final fun is_19_43_or_greater ()Z
|
||||||
public static final fun is_19_46_or_greater ()Z
|
public static final fun is_19_46_or_greater ()Z
|
||||||
public static final fun is_19_47_or_greater ()Z
|
public static final fun is_19_47_or_greater ()Z
|
||||||
|
public static final fun is_19_49_or_greater ()Z
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatchKt {
|
public final class app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatchKt {
|
||||||
@@ -1404,14 +1410,14 @@ public final class app/revanced/patches/youtube/misc/zoomhaptics/ZoomHapticsPatc
|
|||||||
public static final fun getZoomHapticsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getZoomHapticsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/shared/FingerprintsKt {
|
|
||||||
public static final fun getRollingNumberTextViewAnimationUpdateFingerprint ()Lapp/revanced/patcher/Fingerprint;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatchKt {
|
public final class app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatchKt {
|
||||||
public static final fun getForceOriginalAudioPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getForceOriginalAudioPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/youtube/video/hdr/DisableHdrPatchKt {
|
||||||
|
public static final fun getDisableHdrPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/video/information/VideoInformationPatchKt {
|
public final class app/revanced/patches/youtube/video/information/VideoInformationPatchKt {
|
||||||
public static final fun getVideoInformationPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getVideoInformationPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
public static final fun userSelectedPlaybackSpeedHook (Ljava/lang/String;Ljava/lang/String;)V
|
public static final fun userSelectedPlaybackSpeedHook (Ljava/lang/String;Ljava/lang/String;)V
|
||||||
@@ -1453,10 +1459,6 @@ public final class app/revanced/patches/youtube/video/speed/button/PlaybackSpeed
|
|||||||
public static final fun getPlaybackSpeedButtonPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getPlaybackSpeedButtonPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatchKt {
|
|
||||||
public static final fun getSpeedUnavailableId ()J
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/video/videoid/VideoIdPatchKt {
|
public final class app/revanced/patches/youtube/video/videoid/VideoIdPatchKt {
|
||||||
public static final fun getVideoIdPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getVideoIdPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
public static final fun hookBackgroundPlayVideoId (Ljava/lang/String;)V
|
public static final fun hookBackgroundPlayVideoId (Ljava/lang/String;)V
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint
|
|||||||
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
|
||||||
|
|
||||||
fun baseClientIdFingerprint(string: String) = fingerprint {
|
internal fun baseClientIdFingerprint(string: String) = fingerprint {
|
||||||
strings("yyOCBp.RHJhDKd", string)
|
strings("yyOCBp.RHJhDKd", string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ fun sharedExtensionPatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ExtensionHook internal constructor(
|
class ExtensionHook internal constructor(
|
||||||
val fingerprint: Fingerprint,
|
private val fingerprint: Fingerprint,
|
||||||
private val insertIndexResolver: ((Method) -> Int),
|
private val insertIndexResolver: ((Method) -> Int),
|
||||||
private val contextRegisterResolver: (Method) -> String,
|
private val contextRegisterResolver: (Method) -> String,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package app.revanced.patches.shared.misc.settings
|
package app.revanced.patches.shared.misc.settings
|
||||||
|
|
||||||
|
import app.revanced.patcher.patch.PatchException
|
||||||
import app.revanced.patcher.patch.resourcePatch
|
import app.revanced.patcher.patch.resourcePatch
|
||||||
import app.revanced.patches.all.misc.resources.addResource
|
import app.revanced.patches.all.misc.resources.addResource
|
||||||
import app.revanced.patches.all.misc.resources.addResources
|
import app.revanced.patches.all.misc.resources.addResources
|
||||||
@@ -12,15 +13,22 @@ import app.revanced.util.getNode
|
|||||||
import app.revanced.util.insertFirst
|
import app.revanced.util.insertFirst
|
||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
|
|
||||||
|
// TODO: Delete this on next major version bump.
|
||||||
|
@Deprecated("Use non deprecated settings patch function")
|
||||||
|
fun settingsPatch (
|
||||||
|
rootPreference: Pair<IntentPreference, String>,
|
||||||
|
preferences: Set<BasePreference>,
|
||||||
|
) = settingsPatch(listOf(rootPreference), preferences)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A resource patch that adds settings to a settings fragment.
|
* A resource patch that adds settings to a settings fragment.
|
||||||
*
|
*
|
||||||
* @param rootPreference A pair of an intent preference and the name of the fragment file to add it to.
|
* @param rootPreferences List of intent preferences and the name of the fragment file to add it to.
|
||||||
* If null, no preference will be added.
|
* File names that do not exist are ignored and not processed.
|
||||||
* @param preferences A set of preferences to add to the ReVanced fragment.
|
* @param preferences A set of preferences to add to the ReVanced fragment.
|
||||||
*/
|
*/
|
||||||
fun settingsPatch(
|
fun settingsPatch (
|
||||||
rootPreference: Pair<IntentPreference, String>? = null,
|
rootPreferences: List<Pair<BasePreference, String>>? = null,
|
||||||
preferences: Set<BasePreference>,
|
preferences: Set<BasePreference>,
|
||||||
) = resourcePatch {
|
) = resourcePatch {
|
||||||
dependsOn(addResourcesPatch)
|
dependsOn(addResourcesPatch)
|
||||||
@@ -46,10 +54,20 @@ fun settingsPatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the root preference to an existing fragment if needed.
|
// Add the root preference to an existing fragment if needed.
|
||||||
rootPreference?.let { (intentPreference, fragment) ->
|
rootPreferences?.let {
|
||||||
document("res/xml/$fragment.xml").use { document ->
|
var modified = false
|
||||||
document.getNode("PreferenceScreen").addPreference(intentPreference, true)
|
|
||||||
|
it.forEach { (intent, fileName) ->
|
||||||
|
val preferenceFileName = "res/xml/$fileName.xml"
|
||||||
|
if (get(preferenceFileName).exists()) {
|
||||||
|
document(preferenceFileName).use { document ->
|
||||||
|
document.getNode("PreferenceScreen").addPreference(intent, true)
|
||||||
|
}
|
||||||
|
modified = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!modified) throw PatchException("No declared preference files exists: $rootPreferences")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all preferences to the ReVanced fragment.
|
// Add all preferences to the ReVanced fragment.
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import org.w3c.dom.Element
|
|||||||
*
|
*
|
||||||
* @param key The key of the preference. If null, other parameters must be specified.
|
* @param key The key of the preference. If null, other parameters must be specified.
|
||||||
* @param titleKey The key of the preference title.
|
* @param titleKey The key of the preference title.
|
||||||
|
* @param icon The preference icon resource name.
|
||||||
|
* @param layout Layout declaration.
|
||||||
* @param summaryKey The key of the preference summary.
|
* @param summaryKey The key of the preference summary.
|
||||||
* @param tag The tag or full class name of the preference.
|
* @param tag The tag or full class name of the preference.
|
||||||
*/
|
*/
|
||||||
@@ -17,6 +19,8 @@ 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 layout: String? = null,
|
||||||
val tag: String
|
val tag: String
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
@@ -33,6 +37,11 @@ abstract class BasePreference(
|
|||||||
key?.let { setAttribute("android:key", it) }
|
key?.let { setAttribute("android:key", it) }
|
||||||
setAttribute("android:title", "@string/${titleKey}")
|
setAttribute("android:title", "@string/${titleKey}")
|
||||||
summaryKey?.let { addSummary(it) }
|
summaryKey?.let { addSummary(it) }
|
||||||
|
icon?.let {
|
||||||
|
setAttribute("android:icon", it)
|
||||||
|
setAttribute("app:iconSpaceReserved", "true")
|
||||||
|
}
|
||||||
|
layout?.let { setAttribute("android:layout", layout) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
|
|||||||
@@ -24,16 +24,20 @@ abstract class BasePreferenceScreen(
|
|||||||
key: String? = null,
|
key: String? = null,
|
||||||
titleKey: String = "${key}_title",
|
titleKey: String = "${key}_title",
|
||||||
private val summaryKey: String? = "${key}_summary",
|
private val summaryKey: String? = "${key}_summary",
|
||||||
|
icon: String? = null,
|
||||||
|
layout: String? = null,
|
||||||
preferences: MutableSet<BasePreference> = mutableSetOf(),
|
preferences: MutableSet<BasePreference> = mutableSetOf(),
|
||||||
val categories: MutableSet<Category> = mutableSetOf(),
|
val categories: MutableSet<Category> = mutableSetOf(),
|
||||||
private val sorting: Sorting = Sorting.BY_TITLE,
|
private val sorting: Sorting = Sorting.BY_TITLE,
|
||||||
) : BasePreferenceCollection(key, titleKey, preferences) {
|
) : BasePreferenceCollection(key, titleKey, icon, layout, preferences) {
|
||||||
|
|
||||||
override fun transform(): PreferenceScreenPreference {
|
override fun transform(): PreferenceScreenPreference {
|
||||||
return PreferenceScreenPreference(
|
return PreferenceScreenPreference(
|
||||||
key,
|
key,
|
||||||
titleKey,
|
titleKey,
|
||||||
summaryKey,
|
summaryKey,
|
||||||
|
icon,
|
||||||
|
layout,
|
||||||
sorting,
|
sorting,
|
||||||
// Screens and preferences are sorted at runtime by extension code,
|
// Screens and preferences are sorted at runtime by extension code,
|
||||||
// so title sorting uses the localized language in use.
|
// so title sorting uses the localized language in use.
|
||||||
@@ -56,12 +60,17 @@ abstract class BasePreferenceScreen(
|
|||||||
open inner class Category(
|
open inner class Category(
|
||||||
key: String? = null,
|
key: String? = null,
|
||||||
titleKey: String = "${key}_title",
|
titleKey: String = "${key}_title",
|
||||||
|
icon: String? = null,
|
||||||
|
layout: String? = null,
|
||||||
preferences: MutableSet<BasePreference> = mutableSetOf(),
|
preferences: MutableSet<BasePreference> = mutableSetOf(),
|
||||||
) : BasePreferenceCollection(key, titleKey, preferences) {
|
) : BasePreferenceCollection(key, titleKey, icon, layout, preferences) {
|
||||||
override fun transform(): PreferenceCategory {
|
override fun transform(): PreferenceCategory {
|
||||||
return PreferenceCategory(
|
return PreferenceCategory(
|
||||||
key,
|
key,
|
||||||
titleKey,
|
titleKey,
|
||||||
|
icon,
|
||||||
|
layout,
|
||||||
|
sorting,
|
||||||
preferences = preferences,
|
preferences = preferences,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -82,6 +91,8 @@ abstract class BasePreferenceScreen(
|
|||||||
abstract class BasePreferenceCollection(
|
abstract class BasePreferenceCollection(
|
||||||
val key: String? = null,
|
val key: String? = null,
|
||||||
val titleKey: String = "${key}_title",
|
val titleKey: String = "${key}_title",
|
||||||
|
val icon: String? = null,
|
||||||
|
val layout: String? = null,
|
||||||
val preferences: MutableSet<BasePreference> = mutableSetOf(),
|
val preferences: MutableSet<BasePreference> = mutableSetOf(),
|
||||||
) {
|
) {
|
||||||
abstract fun transform(): BasePreference
|
abstract fun transform(): BasePreference
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ enum class InputType(val type: String) {
|
|||||||
TEXT_CAP_CHARACTERS("textCapCharacters"),
|
TEXT_CAP_CHARACTERS("textCapCharacters"),
|
||||||
TEXT_MULTI_LINE("textMultiLine"),
|
TEXT_MULTI_LINE("textMultiLine"),
|
||||||
NUMBER("number"),
|
NUMBER("number"),
|
||||||
|
NUMBER_DECIMAL("numberDecimal"),
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,8 @@ import org.w3c.dom.Document
|
|||||||
* @param key Optional preference key.
|
* @param key Optional preference key.
|
||||||
* @param titleKey The preference title key.
|
* @param titleKey The preference title key.
|
||||||
* @param summaryKey The preference summary key.
|
* @param summaryKey The preference summary key.
|
||||||
|
* @param icon The preference icon resource name.
|
||||||
|
* @param layout Layout declaration.
|
||||||
* @param tag The preference tag.
|
* @param tag The preference tag.
|
||||||
* @param intent The intent to open.
|
* @param intent The intent to open.
|
||||||
*/
|
*/
|
||||||
@@ -16,9 +18,11 @@ class IntentPreference(
|
|||||||
key: String? = null,
|
key: String? = null,
|
||||||
titleKey: String = "${key}_title",
|
titleKey: String = "${key}_title",
|
||||||
summaryKey: String? = "${key}_summary",
|
summaryKey: String? = "${key}_summary",
|
||||||
|
icon: String? = null,
|
||||||
|
layout: String? = null,
|
||||||
tag: String = "Preference",
|
tag: String = "Preference",
|
||||||
val intent: Intent,
|
val intent: Intent,
|
||||||
) : BasePreference(key, titleKey, summaryKey, tag) {
|
) : BasePreference(key, titleKey, summaryKey, icon, layout, tag) {
|
||||||
|
|
||||||
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
||||||
super.serialize(ownerDocument, resourceCallback).apply {
|
super.serialize(ownerDocument, resourceCallback).apply {
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import org.w3c.dom.Document
|
|||||||
* @param key The preference key. If null, other parameters must be specified.
|
* @param key The preference key. If null, other parameters must be specified.
|
||||||
* @param titleKey The preference title key.
|
* @param titleKey The preference title key.
|
||||||
* @param summaryKey The preference summary key.
|
* @param summaryKey The preference summary key.
|
||||||
|
* @param icon The preference icon resource name.
|
||||||
|
* @param layout Layout declaration.
|
||||||
* @param tag The preference tag.
|
* @param tag The preference tag.
|
||||||
* @param entriesKey The entries array key.
|
* @param entriesKey The entries array key.
|
||||||
* @param entryValuesKey The entry values array key.
|
* @param entryValuesKey The entry values array key.
|
||||||
@@ -19,10 +21,12 @@ class ListPreference(
|
|||||||
key: String? = null,
|
key: String? = null,
|
||||||
titleKey: String = "${key}_title",
|
titleKey: String = "${key}_title",
|
||||||
summaryKey: String? = "${key}_summary",
|
summaryKey: String? = "${key}_summary",
|
||||||
|
icon: String? = null,
|
||||||
|
layout: String? = null,
|
||||||
tag: String = "ListPreference",
|
tag: String = "ListPreference",
|
||||||
val entriesKey: String? = "${key}_entries",
|
val entriesKey: String? = "${key}_entries",
|
||||||
val entryValuesKey: String? = "${key}_entry_values"
|
val entryValuesKey: String? = "${key}_entry_values"
|
||||||
) : BasePreference(key, titleKey, summaryKey, tag) {
|
) : BasePreference(key, titleKey, summaryKey, icon, layout, tag) {
|
||||||
var entries: ArrayResource? = null
|
var entries: ArrayResource? = null
|
||||||
private set
|
private set
|
||||||
var entryValues: ArrayResource? = null
|
var entryValues: ArrayResource? = null
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import org.w3c.dom.Document
|
|||||||
*
|
*
|
||||||
* @param key The preference key.
|
* @param key The preference key.
|
||||||
* @param summaryKey The preference summary key.
|
* @param summaryKey The preference summary key.
|
||||||
|
* @param icon The preference icon resource name.
|
||||||
|
* @param layout Layout declaration.
|
||||||
* @param tag The tag or full class name of the preference.
|
* @param tag The tag or full class name of the preference.
|
||||||
* @param selectable If the preference is selectable and responds to tap events.
|
* @param selectable If the preference is selectable and responds to tap events.
|
||||||
*/
|
*/
|
||||||
@@ -18,9 +20,11 @@ class NonInteractivePreference(
|
|||||||
key: String,
|
key: String,
|
||||||
titleKey: String = "${key}_title",
|
titleKey: String = "${key}_title",
|
||||||
summaryKey: String? = "${key}_summary",
|
summaryKey: String? = "${key}_summary",
|
||||||
|
icon: String? = null,
|
||||||
|
layout: String? = null,
|
||||||
tag: String = "Preference",
|
tag: String = "Preference",
|
||||||
val selectable: Boolean = false,
|
val selectable: Boolean = false,
|
||||||
) : BasePreference(key, titleKey, summaryKey, tag) {
|
) : BasePreference(key, titleKey, summaryKey, icon, layout, tag) {
|
||||||
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
||||||
super.serialize(ownerDocument, resourceCallback).apply {
|
super.serialize(ownerDocument, resourceCallback).apply {
|
||||||
setAttribute("android:selectable", selectable.toString())
|
setAttribute("android:selectable", selectable.toString())
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package app.revanced.patches.shared.misc.settings.preference
|
package app.revanced.patches.shared.misc.settings.preference
|
||||||
|
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
|
||||||
import app.revanced.util.resource.BaseResource
|
import app.revanced.util.resource.BaseResource
|
||||||
import org.w3c.dom.Document
|
import org.w3c.dom.Document
|
||||||
|
|
||||||
@@ -8,6 +9,8 @@ import org.w3c.dom.Document
|
|||||||
*
|
*
|
||||||
* @param key The key of the preference. If null, other parameters must be specified.
|
* @param key The key of the preference. If null, other parameters must be specified.
|
||||||
* @param titleKey The key of the preference title.
|
* @param titleKey The key of the preference title.
|
||||||
|
* @param icon The preference icon resource name.
|
||||||
|
* @param layout Layout declaration.
|
||||||
* @param tag The tag or full class name of the preference.
|
* @param tag The tag or full class name of the preference.
|
||||||
* @param preferences The preferences in this category.
|
* @param preferences The preferences in this category.
|
||||||
*/
|
*/
|
||||||
@@ -15,9 +18,12 @@ import org.w3c.dom.Document
|
|||||||
open class PreferenceCategory(
|
open class PreferenceCategory(
|
||||||
key: String? = null,
|
key: String? = null,
|
||||||
titleKey: String = "${key}_title",
|
titleKey: String = "${key}_title",
|
||||||
|
icon: String? = null,
|
||||||
|
layout: String? = null,
|
||||||
|
sorting: Sorting = Sorting.BY_TITLE,
|
||||||
tag: String = "PreferenceCategory",
|
tag: String = "PreferenceCategory",
|
||||||
val preferences: Set<BasePreference>
|
val preferences: Set<BasePreference>
|
||||||
) : BasePreference(key, titleKey, null, tag) {
|
) : BasePreference(sorting.appendSortType(key), titleKey, null, icon, layout, tag) {
|
||||||
|
|
||||||
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
||||||
super.serialize(ownerDocument, resourceCallback).apply {
|
super.serialize(ownerDocument, resourceCallback).apply {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import org.w3c.dom.Document
|
|||||||
* @param key The key of the preference. If null, other parameters must be specified.
|
* @param key The key of the preference. If null, other parameters must be specified.
|
||||||
* @param titleKey The key of the preference title.
|
* @param titleKey The key of the preference title.
|
||||||
* @param summaryKey The key of the preference summary.
|
* @param summaryKey The key of the preference summary.
|
||||||
|
* @param icon The preference icon resource name.
|
||||||
|
* @param layout Layout declaration.
|
||||||
* @param sorting Sorting to use. If the sorting is not [Sorting.UNSORTED],
|
* @param sorting Sorting to use. If the sorting is not [Sorting.UNSORTED],
|
||||||
* then the key parameter will be modified to include the sort type.
|
* then the key parameter will be modified to include the sort type.
|
||||||
* @param tag The tag or full class name of the preference.
|
* @param tag The tag or full class name of the preference.
|
||||||
@@ -19,6 +21,8 @@ open class PreferenceScreenPreference(
|
|||||||
key: String? = null,
|
key: String? = null,
|
||||||
titleKey: String = "${key}_title",
|
titleKey: String = "${key}_title",
|
||||||
summaryKey: String? = "${key}_summary",
|
summaryKey: String? = "${key}_summary",
|
||||||
|
icon: String? = null,
|
||||||
|
layout: String? = null,
|
||||||
sorting: Sorting = Sorting.BY_TITLE,
|
sorting: Sorting = Sorting.BY_TITLE,
|
||||||
tag: String = "PreferenceScreen",
|
tag: String = "PreferenceScreen",
|
||||||
val preferences: Set<BasePreference>,
|
val preferences: Set<BasePreference>,
|
||||||
@@ -28,7 +32,7 @@ open class PreferenceScreenPreference(
|
|||||||
// or adding new attributes to the attrs.xml file.
|
// or adding new attributes to the attrs.xml file.
|
||||||
// Since the key value is not currently used by the extensions,
|
// Since the key value is not currently used by the extensions,
|
||||||
// for now it's much simpler to modify the key to include the sort parameter.
|
// for now it's much simpler to modify the key to include the sort parameter.
|
||||||
) : BasePreference(if (sorting == Sorting.UNSORTED) key else (key + sorting.keySuffix), titleKey, summaryKey, tag) {
|
) : BasePreference(sorting.appendSortType(key), titleKey, summaryKey, icon, layout, tag) {
|
||||||
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
||||||
super.serialize(ownerDocument, resourceCallback).apply {
|
super.serialize(ownerDocument, resourceCallback).apply {
|
||||||
preferences.forEach {
|
preferences.forEach {
|
||||||
@@ -53,6 +57,16 @@ open class PreferenceScreenPreference(
|
|||||||
/**
|
/**
|
||||||
* Unspecified sorting.
|
* Unspecified sorting.
|
||||||
*/
|
*/
|
||||||
UNSORTED("_sort_by_unsorted"),
|
UNSORTED("_sort_by_unsorted");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The key with this sort type appended to to the end,
|
||||||
|
* or if key is null then null is returned.
|
||||||
|
*/
|
||||||
|
fun appendSortType(key: String?): String? {
|
||||||
|
if (key == null) return null
|
||||||
|
if (this == UNSORTED) return key
|
||||||
|
return key + keySuffix
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import org.w3c.dom.Document
|
|||||||
*
|
*
|
||||||
* @param key The preference key. If null, other parameters must be specified.
|
* @param key The preference key. If null, other parameters must be specified.
|
||||||
* @param titleKey The preference title key.
|
* @param titleKey The preference title key.
|
||||||
|
* @param icon The preference icon resource name.
|
||||||
|
* @param layout Layout declaration.
|
||||||
* @param tag The preference tag.
|
* @param tag The preference tag.
|
||||||
* @param summaryOnKey The preference summary-on key.
|
* @param summaryOnKey The preference summary-on key.
|
||||||
* @param summaryOffKey The preference summary-off key.
|
* @param summaryOffKey The preference summary-off key.
|
||||||
@@ -17,9 +19,11 @@ class SwitchPreference(
|
|||||||
key: String? = null,
|
key: String? = null,
|
||||||
titleKey: String = "${key}_title",
|
titleKey: String = "${key}_title",
|
||||||
tag: String = "SwitchPreference",
|
tag: String = "SwitchPreference",
|
||||||
|
icon: String? = null,
|
||||||
|
layout: String? = null,
|
||||||
val summaryOnKey: String = "${key}_summary_on",
|
val summaryOnKey: String = "${key}_summary_on",
|
||||||
val summaryOffKey: String = "${key}_summary_off"
|
val summaryOffKey: String = "${key}_summary_off"
|
||||||
) : BasePreference(key, titleKey, null, tag) {
|
) : BasePreference(key, titleKey, null, icon, layout, tag) {
|
||||||
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
||||||
super.serialize(ownerDocument, resourceCallback).apply {
|
super.serialize(ownerDocument, resourceCallback).apply {
|
||||||
addSummary(summaryOnKey, SummaryType.ON)
|
addSummary(summaryOnKey, SummaryType.ON)
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import org.w3c.dom.Document
|
|||||||
* @param key The preference key. If null, other parameters must be specified.
|
* @param key The preference key. If null, other parameters must be specified.
|
||||||
* @param titleKey The preference title key.
|
* @param titleKey The preference title key.
|
||||||
* @param summaryKey The preference summary key.
|
* @param summaryKey The preference summary key.
|
||||||
|
* @param icon The preference icon resource name.
|
||||||
|
* @param layout Layout declaration.
|
||||||
* @param tag The preference tag.
|
* @param tag The preference tag.
|
||||||
* @param inputType The preference input type.
|
* @param inputType The preference input type.
|
||||||
*/
|
*/
|
||||||
@@ -17,9 +19,11 @@ class TextPreference(
|
|||||||
key: String? = null,
|
key: String? = null,
|
||||||
titleKey: String = "${key}_title",
|
titleKey: String = "${key}_title",
|
||||||
summaryKey: String? = "${key}_summary",
|
summaryKey: String? = "${key}_summary",
|
||||||
|
icon: String? = null,
|
||||||
|
layout: String? = null,
|
||||||
tag: String = "app.revanced.extension.shared.settings.preference.ResettableEditTextPreference",
|
tag: String = "app.revanced.extension.shared.settings.preference.ResettableEditTextPreference",
|
||||||
val inputType: InputType = InputType.TEXT
|
val inputType: InputType = InputType.TEXT
|
||||||
) : BasePreference(key, titleKey, summaryKey, tag) {
|
) : BasePreference(key, titleKey, summaryKey, icon, layout, tag) {
|
||||||
|
|
||||||
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
||||||
super.serialize(ownerDocument, resourceCallback).apply {
|
super.serialize(ownerDocument, resourceCallback).apply {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package app.revanced.patches.shared.misc.spoof
|
package app.revanced.patches.shared.misc.spoof
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
@@ -111,6 +112,23 @@ internal val buildMediaDataSourceFingerprint = fingerprint {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal const val HLS_CURRENT_TIME_FEATURE_FLAG = 45355374L
|
||||||
|
|
||||||
|
internal val hlsCurrentTimeFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
parameters("Z", "L")
|
||||||
|
literal {
|
||||||
|
HLS_CURRENT_TIME_FEATURE_FLAG
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val nerdsStatsVideoFormatBuilderFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||||
|
returns("Ljava/lang/String;")
|
||||||
|
parameters("L")
|
||||||
|
strings("codecs=\"")
|
||||||
|
}
|
||||||
|
|
||||||
internal val patchIncludedExtensionMethodFingerprint = fingerprint {
|
internal val patchIncludedExtensionMethodFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||||
returns("Z")
|
returns("Z")
|
||||||
|
|||||||
@@ -10,8 +10,10 @@ import app.revanced.patcher.patch.BytecodePatchContext
|
|||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||||
|
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
|
import app.revanced.util.insertFeatureFlagBooleanOverride
|
||||||
import app.revanced.util.returnEarly
|
import app.revanced.util.returnEarly
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
@@ -206,6 +208,34 @@ fun spoofVideoStreamsPatch(
|
|||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Append spoof info.
|
||||||
|
|
||||||
|
nerdsStatsVideoFormatBuilderFingerprint.method.apply {
|
||||||
|
findInstructionIndicesReversedOrThrow(Opcode.RETURN_OBJECT).forEach { index ->
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
index,
|
||||||
|
"""
|
||||||
|
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->appendSpoofedClient(Ljava/lang/String;)Ljava/lang/String;
|
||||||
|
move-result-object v$register
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Fix iOS livestream current time.
|
||||||
|
|
||||||
|
hlsCurrentTimeFingerprint.method.insertFeatureFlagBooleanOverride(
|
||||||
|
HLS_CURRENT_TIME_FEATURE_FLAG,
|
||||||
|
"$EXTENSION_CLASS_DESCRIPTOR->fixHLSCurrentTime(Z)Z"
|
||||||
|
)
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
executeBlock()
|
executeBlock()
|
||||||
|
|||||||
@@ -1,12 +1,23 @@
|
|||||||
package app.revanced.patches.youtube.interaction.swipecontrols
|
package app.revanced.patches.youtube.interaction.swipecontrols
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
internal val swipeControlsHostActivityFingerprint = fingerprint {
|
internal val swipeControlsHostActivityFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||||
parameters()
|
parameters()
|
||||||
custom { method, _ ->
|
custom { method, _ ->
|
||||||
method.definingClass == "Lapp/revanced/extension/youtube/swipecontrols/SwipeControlsHostActivity;"
|
method.definingClass == EXTENSION_CLASS_DESCRIPTOR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal const val SWIPE_CHANGE_VIDEO_FEATURE_FLAG = 45631116L
|
||||||
|
|
||||||
|
internal val swipeChangeVideoFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||||
|
parameters("L")
|
||||||
|
literal {
|
||||||
|
SWIPE_CHANGE_VIDEO_FEATURE_FLAG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ 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.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_43_or_greater
|
||||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
import app.revanced.patches.youtube.shared.mainActivityFingerprint
|
import app.revanced.patches.youtube.shared.mainActivityFingerprint
|
||||||
@@ -17,6 +18,8 @@ import app.revanced.util.*
|
|||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||||
|
|
||||||
|
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/swipecontrols/SwipeControlsHostActivity;"
|
||||||
|
|
||||||
private val swipeControlsResourcePatch = resourcePatch {
|
private val swipeControlsResourcePatch = resourcePatch {
|
||||||
dependsOn(
|
dependsOn(
|
||||||
settingsPatch,
|
settingsPatch,
|
||||||
@@ -26,6 +29,12 @@ private val swipeControlsResourcePatch = resourcePatch {
|
|||||||
execute {
|
execute {
|
||||||
addResources("youtube", "interaction.swipecontrols.swipeControlsResourcePatch")
|
addResources("youtube", "interaction.swipecontrols.swipeControlsResourcePatch")
|
||||||
|
|
||||||
|
if (is_19_43_or_greater) {
|
||||||
|
PreferenceScreen.SWIPE_CONTROLS.addPreferences(
|
||||||
|
SwitchPreference("revanced_swipe_change_video")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
PreferenceScreen.SWIPE_CONTROLS.addPreferences(
|
PreferenceScreen.SWIPE_CONTROLS.addPreferences(
|
||||||
SwitchPreference("revanced_swipe_brightness"),
|
SwitchPreference("revanced_swipe_brightness"),
|
||||||
SwitchPreference("revanced_swipe_volume"),
|
SwitchPreference("revanced_swipe_volume"),
|
||||||
@@ -101,5 +110,16 @@ val swipeControlsPatch = bytecodePatch(
|
|||||||
).toMutable()
|
).toMutable()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// region patch to enable/disable swipe to change video.
|
||||||
|
|
||||||
|
if (is_19_43_or_greater) {
|
||||||
|
swipeChangeVideoFingerprint.method.insertFeatureFlagBooleanOverride(
|
||||||
|
SWIPE_CHANGE_VIDEO_FEATURE_FLAG,
|
||||||
|
"$EXTENSION_CLASS_DESCRIPTOR->allowSwipeChangeVideo(Z)Z"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,9 +65,12 @@ val navigationButtonsPatch = bytecodePatch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (is_19_25_or_greater) {
|
if (is_19_25_or_greater) {
|
||||||
preferences += SwitchPreference("revanced_disable_translucent_status_bar")
|
|
||||||
preferences += SwitchPreference("revanced_disable_translucent_navigation_bar_light")
|
preferences += SwitchPreference("revanced_disable_translucent_navigation_bar_light")
|
||||||
preferences += SwitchPreference("revanced_disable_translucent_navigation_bar_dark")
|
preferences += SwitchPreference("revanced_disable_translucent_navigation_bar_dark")
|
||||||
|
|
||||||
|
PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
||||||
|
SwitchPreference("revanced_disable_translucent_status_bar")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.formfactor
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.all.misc.resources.addResources
|
||||||
|
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||||
|
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.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
|
|
||||||
|
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/ChangeFormFactorPatch;"
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val changeFormFactorPatch = bytecodePatch(
|
||||||
|
name = "Change form factor",
|
||||||
|
description = "Adds an option to change the UI appearance to a phone, tablet, or automotive device.",
|
||||||
|
) {
|
||||||
|
dependsOn(
|
||||||
|
sharedExtensionPatch,
|
||||||
|
settingsPatch,
|
||||||
|
addResourcesPatch,
|
||||||
|
)
|
||||||
|
|
||||||
|
compatibleWith(
|
||||||
|
"com.google.android.youtube"(
|
||||||
|
"18.38.44",
|
||||||
|
"18.49.37",
|
||||||
|
"19.16.39",
|
||||||
|
"19.25.37",
|
||||||
|
"19.34.42",
|
||||||
|
"19.43.41",
|
||||||
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
|
"19.47.53",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
addResources("youtube", "layout.formfactor.changeFormFactorPatch")
|
||||||
|
|
||||||
|
PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
||||||
|
ListPreference(
|
||||||
|
"revanced_change_form_factor",
|
||||||
|
summaryKey = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
createPlayerRequestBodyWithModelFingerprint.method.apply {
|
||||||
|
val formFactorEnumClass = formFactorEnumConstructorFingerprint.originalClassDef.type
|
||||||
|
|
||||||
|
val index = indexOfFirstInstructionOrThrow {
|
||||||
|
val reference = getReference<FieldReference>()
|
||||||
|
opcode == Opcode.IGET &&
|
||||||
|
reference?.definingClass == formFactorEnumClass &&
|
||||||
|
reference.type == "I"
|
||||||
|
}
|
||||||
|
val register = getInstruction<TwoRegisterInstruction>(index).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
index + 1,
|
||||||
|
"""
|
||||||
|
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getFormFactor(I)I
|
||||||
|
move-result v$register
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.formfactor
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
|
|
||||||
|
internal val formFactorEnumConstructorFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
|
||||||
|
strings(
|
||||||
|
"UNKNOWN_FORM_FACTOR",
|
||||||
|
"SMALL_FORM_FACTOR",
|
||||||
|
"LARGE_FORM_FACTOR",
|
||||||
|
"AUTOMOTIVE_FORM_FACTOR"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val createPlayerRequestBodyWithModelFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
returns("L")
|
||||||
|
parameters()
|
||||||
|
opcodes(Opcode.OR_INT_LIT16)
|
||||||
|
custom { method, _ ->
|
||||||
|
method.indexOfModelInstruction() >= 0 &&
|
||||||
|
method.indexOfReleaseInstruction() >= 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Method.indexOfModelInstruction() =
|
||||||
|
indexOfFirstInstruction {
|
||||||
|
val reference = getReference<FieldReference>()
|
||||||
|
|
||||||
|
reference?.definingClass == "Landroid/os/Build;" &&
|
||||||
|
reference.name == "MODEL" &&
|
||||||
|
reference.type == "Ljava/lang/String;"
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun Method.indexOfReleaseInstruction(): Int =
|
||||||
|
indexOfFirstInstruction {
|
||||||
|
val reference = getReference<FieldReference>()
|
||||||
|
|
||||||
|
reference?.definingClass == "Landroid/os/Build${'$'}VERSION;" &&
|
||||||
|
reference.name == "RELEASE" &&
|
||||||
|
reference.type == "Ljava/lang/String;"
|
||||||
|
}
|
||||||
|
|
||||||
@@ -71,6 +71,7 @@ private val hideShortsComponentsResourcePatch = resourcePatch {
|
|||||||
SwitchPreference("revanced_hide_shorts_home"),
|
SwitchPreference("revanced_hide_shorts_home"),
|
||||||
SwitchPreference("revanced_hide_shorts_subscriptions"),
|
SwitchPreference("revanced_hide_shorts_subscriptions"),
|
||||||
SwitchPreference("revanced_hide_shorts_search"),
|
SwitchPreference("revanced_hide_shorts_search"),
|
||||||
|
SwitchPreference("revanced_hide_shorts_history"),
|
||||||
|
|
||||||
PreferenceScreenPreference(
|
PreferenceScreenPreference(
|
||||||
key = "revanced_shorts_player_screen",
|
key = "revanced_shorts_player_screen",
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.player.fullscreen
|
||||||
|
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.all.misc.resources.addResources
|
||||||
|
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||||
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playercontrols.playerControlsPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
||||||
|
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||||
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
|
import app.revanced.patches.youtube.shared.autoRepeatFingerprint
|
||||||
|
import app.revanced.patches.youtube.shared.autoRepeatParentFingerprint
|
||||||
|
import app.revanced.util.addInstructionsAtControlFlowLabel
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
internal val exitFullscreenPatch = bytecodePatch(
|
||||||
|
name = "Exit fullscreen mode",
|
||||||
|
description = "Adds options to automatically exit fullscreen mode when a video reaches the end."
|
||||||
|
) {
|
||||||
|
|
||||||
|
compatibleWith(
|
||||||
|
"com.google.android.youtube"(
|
||||||
|
"18.38.44",
|
||||||
|
"18.49.37",
|
||||||
|
"19.16.39",
|
||||||
|
"19.25.37",
|
||||||
|
"19.34.42",
|
||||||
|
"19.43.41",
|
||||||
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
|
"19.47.53",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
dependsOn(
|
||||||
|
sharedExtensionPatch,
|
||||||
|
settingsPatch,
|
||||||
|
addResourcesPatch,
|
||||||
|
playerTypeHookPatch,
|
||||||
|
playerControlsPatch
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cannot declare as top level since this patch is in the same package as
|
||||||
|
// other patches that declare same constant name with internal visibility.
|
||||||
|
@Suppress("LocalVariableName")
|
||||||
|
val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/extension/youtube/patches/ExitFullscreenPatch;"
|
||||||
|
|
||||||
|
execute {
|
||||||
|
addResources("youtube", "layout.player.fullscreen.exitFullscreenPatch")
|
||||||
|
|
||||||
|
PreferenceScreen.PLAYER.addPreferences(
|
||||||
|
ListPreference(
|
||||||
|
"revanced_exit_fullscreen",
|
||||||
|
summaryKey = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
autoRepeatFingerprint.match(autoRepeatParentFingerprint.originalClassDef).method.apply {
|
||||||
|
addInstructionsAtControlFlowLabel(
|
||||||
|
implementation!!.instructions.lastIndex,
|
||||||
|
"invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->endOfVideoReached()V",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,13 +34,17 @@ internal val shortsSeekbarColorFingerprint = fingerprint {
|
|||||||
literal { reelTimeBarPlayedColorId }
|
literal { reelTimeBarPlayedColorId }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal const val PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG = 45617850L
|
internal val playerSeekbarHandleColorFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||||
|
parameters("Landroid/content/Context;")
|
||||||
|
literal { ytStaticBrandRedId }
|
||||||
|
}
|
||||||
|
|
||||||
internal val playerSeekbarGradientConfigFingerprint = fingerprint {
|
internal val watchHistoryMenuUseProgressDrawableFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
returns("Z")
|
returns("V")
|
||||||
parameters()
|
parameters("L")
|
||||||
literal { PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG }
|
literal { -1712394514 }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val lithoLinearGradientFingerprint = fingerprint {
|
internal val lithoLinearGradientFingerprint = fingerprint {
|
||||||
@@ -49,6 +53,49 @@ internal val lithoLinearGradientFingerprint = fingerprint {
|
|||||||
parameters("F", "F", "F", "F", "[I", "[F")
|
parameters("F", "F", "F", "F", "[I", "[F")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 19.49+
|
||||||
|
*/
|
||||||
|
internal val playerLinearGradientFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||||
|
parameters("I", "I", "I", "I", "Landroid/content/Context;", "I")
|
||||||
|
returns("Landroid/graphics/LinearGradient;")
|
||||||
|
opcodes(
|
||||||
|
Opcode.FILLED_NEW_ARRAY,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT
|
||||||
|
)
|
||||||
|
literal { ytYoutubeMagentaColorId }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 19.46 - 19.47
|
||||||
|
*/
|
||||||
|
internal val playerLinearGradientLegacy1946Fingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
parameters("I", "I", "I", "I")
|
||||||
|
returns("V")
|
||||||
|
opcodes(
|
||||||
|
Opcode.FILLED_NEW_ARRAY,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT
|
||||||
|
)
|
||||||
|
custom { method, _ ->
|
||||||
|
method.name == "setBounds" && method.containsLiteralInstruction(ytYoutubeMagentaColorId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 19.25 - 19.45
|
||||||
|
*/
|
||||||
|
internal val playerLinearGradientLegacy1925Fingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||||
|
parameters("Landroid/content/Context;")
|
||||||
|
opcodes(
|
||||||
|
Opcode.FILLED_NEW_ARRAY,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT
|
||||||
|
)
|
||||||
|
literal { ytYoutubeMagentaColorId }
|
||||||
|
}
|
||||||
|
|
||||||
internal const val launchScreenLayoutTypeLotteFeatureFlag = 268507948L
|
internal const val launchScreenLayoutTypeLotteFeatureFlag = 268507948L
|
||||||
|
|
||||||
internal val launchScreenLayoutTypeFingerprint = fingerprint {
|
internal val launchScreenLayoutTypeFingerprint = fingerprint {
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import app.revanced.patches.youtube.layout.theme.lithoColorHookPatch
|
|||||||
import app.revanced.patches.youtube.layout.theme.lithoColorOverrideHook
|
import app.revanced.patches.youtube.layout.theme.lithoColorOverrideHook
|
||||||
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_25_or_greater
|
import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
|
||||||
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
|
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_49_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.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||||
@@ -39,6 +41,10 @@ internal var inlineTimeBarColorizedBarPlayedColorDarkId = -1L
|
|||||||
private set
|
private set
|
||||||
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
|
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
|
||||||
private set
|
private set
|
||||||
|
internal var ytYoutubeMagentaColorId = -1L
|
||||||
|
private set
|
||||||
|
internal var ytStaticBrandRedId = -1L
|
||||||
|
private set
|
||||||
|
|
||||||
internal const val splashSeekbarColorAttributeName = "splash_custom_seekbar_color"
|
internal const val splashSeekbarColorAttributeName = "splash_custom_seekbar_color"
|
||||||
|
|
||||||
@@ -83,6 +89,15 @@ private val seekbarColorResourcePatch = resourcePatch {
|
|||||||
return@execute
|
return@execute
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ytYoutubeMagentaColorId = resourceMappings[
|
||||||
|
"color",
|
||||||
|
"yt_youtube_magenta",
|
||||||
|
]
|
||||||
|
ytStaticBrandRedId = resourceMappings[
|
||||||
|
"attr",
|
||||||
|
"ytStaticBrandRed",
|
||||||
|
]
|
||||||
|
|
||||||
// Add attribute and styles for splash screen custom color.
|
// Add attribute and styles for splash screen custom color.
|
||||||
// Using a style is the only way to selectively change just the seekbar fill color.
|
// Using a style is the only way to selectively change just the seekbar fill color.
|
||||||
//
|
//
|
||||||
@@ -182,28 +197,31 @@ val seekbarColorPatch = bytecodePatch(
|
|||||||
sharedExtensionPatch,
|
sharedExtensionPatch,
|
||||||
lithoColorHookPatch,
|
lithoColorHookPatch,
|
||||||
seekbarColorResourcePatch,
|
seekbarColorResourcePatch,
|
||||||
|
versionCheckPatch
|
||||||
)
|
)
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
fun MutableMethod.addColorChangeInstructions(resourceId: Long) {
|
fun MutableMethod.addColorChangeInstructions(resourceId: Long, methodName: String) {
|
||||||
val registerIndex = indexOfFirstLiteralInstructionOrThrow(resourceId) + 2
|
val index = indexOfFirstLiteralInstructionOrThrow(resourceId)
|
||||||
val colorRegister = getInstruction<OneRegisterInstruction>(registerIndex).registerA
|
val insertIndex = indexOfFirstInstructionOrThrow(index, Opcode.MOVE_RESULT)
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
registerIndex + 1,
|
insertIndex + 1,
|
||||||
|
"""
|
||||||
|
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->$methodName(I)I
|
||||||
|
move-result v$register
|
||||||
"""
|
"""
|
||||||
invoke-static { v$colorRegister }, $EXTENSION_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I
|
|
||||||
move-result v$colorRegister
|
|
||||||
""",
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
playerSeekbarColorFingerprint.method.apply {
|
playerSeekbarColorFingerprint.method.apply {
|
||||||
addColorChangeInstructions(inlineTimeBarColorizedBarPlayedColorDarkId)
|
addColorChangeInstructions(inlineTimeBarColorizedBarPlayedColorDarkId, "getVideoPlayerSeekbarColor")
|
||||||
addColorChangeInstructions(inlineTimeBarPlayedNotHighlightedColorId)
|
addColorChangeInstructions(inlineTimeBarPlayedNotHighlightedColorId, "getVideoPlayerSeekbarColor")
|
||||||
}
|
}
|
||||||
|
|
||||||
shortsSeekbarColorFingerprint.method.apply {
|
shortsSeekbarColorFingerprint.method.apply {
|
||||||
addColorChangeInstructions(reelTimeBarPlayedColorId)
|
addColorChangeInstructions(reelTimeBarPlayedColorId, "getVideoPlayerSeekbarColor")
|
||||||
}
|
}
|
||||||
|
|
||||||
setSeekbarClickedColorFingerprint.originalMethod.let {
|
setSeekbarClickedColorFingerprint.originalMethod.let {
|
||||||
@@ -229,16 +247,63 @@ val seekbarColorPatch = bytecodePatch(
|
|||||||
|
|
||||||
// 19.25+ changes
|
// 19.25+ changes
|
||||||
|
|
||||||
playerSeekbarGradientConfigFingerprint.method.insertFeatureFlagBooleanOverride(
|
playerSeekbarHandleColorFingerprint.method.apply {
|
||||||
PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG,
|
addColorChangeInstructions(ytStaticBrandRedId, "getVideoPlayerSeekbarColor")
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->playerSeekbarGradientEnabled(Z)Z"
|
}
|
||||||
)
|
|
||||||
|
|
||||||
lithoLinearGradientFingerprint.method.addInstruction(
|
// If hiding feed seekbar thumbnails, then turn off the cairo gradient
|
||||||
|
// of the watch history menu items as they use the same gradient as the
|
||||||
|
// player and there is no easy way to distinguish which to use a transparent color.
|
||||||
|
if (is_19_34_or_greater) {
|
||||||
|
watchHistoryMenuUseProgressDrawableFingerprint.method.apply {
|
||||||
|
val progressIndex = indexOfFirstInstructionOrThrow {
|
||||||
|
val reference = getReference<MethodReference>()
|
||||||
|
reference?.definingClass == "Landroid/widget/ProgressBar;" && reference.name == "setMax"
|
||||||
|
}
|
||||||
|
val index = indexOfFirstInstructionOrThrow(progressIndex, Opcode.MOVE_RESULT)
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
index + 1,
|
||||||
|
"""
|
||||||
|
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->showWatchHistoryProgressDrawable(Z)Z
|
||||||
|
move-result v$register
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lithoLinearGradientFingerprint.method.addInstructions(
|
||||||
0,
|
0,
|
||||||
"invoke-static/range { p4 .. p5 }, $EXTENSION_CLASS_DESCRIPTOR->setLinearGradient([I[F)V"
|
"""
|
||||||
|
invoke-static/range { p4 .. p5 }, $EXTENSION_CLASS_DESCRIPTOR->getLithoLinearGradient([I[F)[I
|
||||||
|
move-result-object p4
|
||||||
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val playerFingerprint =
|
||||||
|
if (is_19_49_or_greater) {
|
||||||
|
playerLinearGradientFingerprint
|
||||||
|
} else if (is_19_46_or_greater) {
|
||||||
|
playerLinearGradientLegacy1946Fingerprint
|
||||||
|
} else {
|
||||||
|
playerLinearGradientLegacy1925Fingerprint
|
||||||
|
}
|
||||||
|
|
||||||
|
playerFingerprint.let {
|
||||||
|
it.method.apply {
|
||||||
|
val index = it.patternMatch!!.endIndex
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
index + 1,
|
||||||
|
"""
|
||||||
|
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getPlayerLinearGradient([I)[I
|
||||||
|
move-result-object v$register
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// region apply seekbar custom color to splash screen animation.
|
// region apply seekbar custom color to splash screen animation.
|
||||||
|
|
||||||
|
|||||||
@@ -1,66 +1,9 @@
|
|||||||
package app.revanced.patches.youtube.layout.tablet
|
package app.revanced.patches.youtube.layout.tablet
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.instructions
|
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patches.youtube.layout.formfactor.changeFormFactorPatch
|
||||||
import app.revanced.patches.all.misc.resources.addResources
|
|
||||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
|
||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
|
||||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
|
||||||
|
|
||||||
const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/TabletLayoutPatch;"
|
@Deprecated("Use 'Change form factor' instead.")
|
||||||
|
val enableTabletLayoutPatch = bytecodePatch {
|
||||||
val enableTabletLayoutPatch = bytecodePatch(
|
dependsOn(changeFormFactorPatch)
|
||||||
name = "Enable tablet layout",
|
}
|
||||||
description = "Adds an option to enable tablet layout.",
|
|
||||||
) {
|
|
||||||
dependsOn(
|
|
||||||
sharedExtensionPatch,
|
|
||||||
settingsPatch,
|
|
||||||
addResourcesPatch,
|
|
||||||
)
|
|
||||||
|
|
||||||
compatibleWith(
|
|
||||||
"com.google.android.youtube"(
|
|
||||||
"18.38.44",
|
|
||||||
"18.49.37",
|
|
||||||
"19.16.39",
|
|
||||||
"19.25.37",
|
|
||||||
"19.34.42",
|
|
||||||
"19.43.41",
|
|
||||||
"19.45.38",
|
|
||||||
"19.46.42",
|
|
||||||
"19.47.53",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
execute {
|
|
||||||
addResources("youtube", "layout.tablet.enableTabletLayoutPatch")
|
|
||||||
|
|
||||||
PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
|
||||||
SwitchPreference("revanced_tablet_layout"),
|
|
||||||
)
|
|
||||||
|
|
||||||
getFormFactorFingerprint.method.apply {
|
|
||||||
val returnIsLargeFormFactorIndex = instructions.lastIndex - 4
|
|
||||||
val returnIsLargeFormFactorLabel = getInstruction(returnIsLargeFormFactorIndex)
|
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
|
||||||
0,
|
|
||||||
"""
|
|
||||||
invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->getTabletLayoutEnabled()Z
|
|
||||||
move-result v0
|
|
||||||
if-nez v0, :is_large_form_factor
|
|
||||||
""",
|
|
||||||
ExternalLabel(
|
|
||||||
"is_large_form_factor",
|
|
||||||
returnIsLargeFormFactorLabel,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.layout.tablet
|
|
||||||
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
import app.revanced.patcher.fingerprint
|
|
||||||
|
|
||||||
internal val getFormFactorFingerprint = fingerprint {
|
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
|
||||||
returns("L")
|
|
||||||
parameters("Landroid/content/Context;", "Ljava/util/List;")
|
|
||||||
opcodes(
|
|
||||||
Opcode.SGET_OBJECT,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.MOVE_RESULT,
|
|
||||||
Opcode.IF_EQZ,
|
|
||||||
Opcode.SGET_OBJECT,
|
|
||||||
Opcode.RETURN_OBJECT,
|
|
||||||
Opcode.INVOKE_STATIC,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
|
||||||
Opcode.RETURN_OBJECT,
|
|
||||||
)
|
|
||||||
strings("")
|
|
||||||
}
|
|
||||||
@@ -13,6 +13,8 @@ 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
|
||||||
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_25_or_greater
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
import app.revanced.util.forEachChildElement
|
import app.revanced.util.forEachChildElement
|
||||||
@@ -71,6 +73,7 @@ val themePatch = bytecodePatch(
|
|||||||
dependsOn(
|
dependsOn(
|
||||||
lithoColorHookPatch,
|
lithoColorHookPatch,
|
||||||
seekbarColorPatch,
|
seekbarColorPatch,
|
||||||
|
versionCheckPatch,
|
||||||
resourcePatch {
|
resourcePatch {
|
||||||
dependsOn(
|
dependsOn(
|
||||||
settingsPatch,
|
settingsPatch,
|
||||||
@@ -83,9 +86,15 @@ val themePatch = bytecodePatch(
|
|||||||
|
|
||||||
PreferenceScreen.SEEKBAR.addPreferences(
|
PreferenceScreen.SEEKBAR.addPreferences(
|
||||||
SwitchPreference("revanced_seekbar_custom_color"),
|
SwitchPreference("revanced_seekbar_custom_color"),
|
||||||
TextPreference("revanced_seekbar_custom_color_value", inputType = InputType.TEXT_CAP_CHARACTERS),
|
TextPreference("revanced_seekbar_custom_color_primary", inputType = InputType.TEXT_CAP_CHARACTERS),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (is_19_25_or_greater) {
|
||||||
|
PreferenceScreen.SEEKBAR.addPreferences(
|
||||||
|
TextPreference("revanced_seekbar_custom_color_accent", inputType = InputType.TEXT_CAP_CHARACTERS),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Edit theme colors via resources.
|
// Edit theme colors via resources.
|
||||||
document("res/values/colors.xml").use { document ->
|
document("res/values/colors.xml").use { document ->
|
||||||
|
|
||||||
@@ -163,22 +172,31 @@ val themePatch = bytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fix the splash screen dark mode background color.
|
// Fix the splash screen dark mode background color.
|
||||||
// In earlier versions of the app this is white and makes no sense for dark mode.
|
// In 19.32+ the dark mode splash screen is white and fades to black.
|
||||||
// This is only required for 19.32 and greater, but is applied to all targets.
|
// Maybe it's a bug in YT, or maybe it intentionally. Who knows.
|
||||||
// Only dark mode needs this fix as light mode correctly uses the custom color.
|
|
||||||
document("res/values-night/styles.xml").use { document ->
|
document("res/values-night/styles.xml").use { document ->
|
||||||
// Create a night mode specific override for the splash screen background.
|
|
||||||
val style = document.createElement("style")
|
|
||||||
style.setAttribute("name", "Theme.YouTube.Home")
|
|
||||||
style.setAttribute("parent", "@style/Base.V23.Theme.YouTube.Home")
|
|
||||||
|
|
||||||
val windowItem = document.createElement("item")
|
|
||||||
windowItem.setAttribute("name", "android:windowBackground")
|
|
||||||
windowItem.textContent = "@color/$splashBackgroundColor"
|
|
||||||
style.appendChild(windowItem)
|
|
||||||
|
|
||||||
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
||||||
resourcesNode.appendChild(style)
|
val childNodes = resourcesNode.childNodes
|
||||||
|
|
||||||
|
for (i in 0 until childNodes.length) {
|
||||||
|
val node = childNodes.item(i) as? Element ?: continue
|
||||||
|
val nodeAttributeName = node.getAttribute("name")
|
||||||
|
if (nodeAttributeName.startsWith("Theme.YouTube.Launcher")) {
|
||||||
|
val nodeAttributeParent = node.getAttribute("parent")
|
||||||
|
|
||||||
|
val style = document.createElement("style")
|
||||||
|
style.setAttribute("name", "Theme.YouTube.Home")
|
||||||
|
style.setAttribute("parent", nodeAttributeParent)
|
||||||
|
|
||||||
|
val windowItem = document.createElement("item")
|
||||||
|
windowItem.setAttribute("name", "android:windowBackground")
|
||||||
|
windowItem.textContent = "@color/$splashBackgroundColor"
|
||||||
|
style.appendChild(windowItem)
|
||||||
|
|
||||||
|
resourcesNode.removeChild(node)
|
||||||
|
resourcesNode.appendChild(style)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import app.revanced.patches.shared.misc.checks.checkEnvironmentPatch
|
|||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||||
|
|
||||||
val checkEnvironmentPatch = checkEnvironmentPatch(
|
internal val checkEnvironmentPatch = checkEnvironmentPatch(
|
||||||
mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint,
|
mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint,
|
||||||
extensionPatch = sharedExtensionPatch,
|
extensionPatch = sharedExtensionPatch,
|
||||||
"com.google.android.youtube",
|
"com.google.android.youtube",
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
|||||||
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
|
||||||
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
@@ -13,7 +14,10 @@ val checkWatchHistoryDomainNameResolutionPatch = bytecodePatch(
|
|||||||
name = "Check watch history domain name resolution",
|
name = "Check watch history domain name resolution",
|
||||||
description = "Checks if the device DNS server is preventing user watch history from being saved.",
|
description = "Checks if the device DNS server is preventing user watch history from being saved.",
|
||||||
) {
|
) {
|
||||||
dependsOn(addResourcesPatch)
|
dependsOn(
|
||||||
|
sharedExtensionPatch,
|
||||||
|
addResourcesPatch
|
||||||
|
)
|
||||||
|
|
||||||
compatibleWith(
|
compatibleWith(
|
||||||
"com.google.android.youtube"(
|
"com.google.android.youtube"(
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.misc.fix.cairo
|
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
|
||||||
import app.revanced.patches.youtube.misc.backgroundplayback.backgroundPlaybackPatch
|
|
||||||
import app.revanced.patches.youtube.misc.playservice.is_19_04_or_greater
|
|
||||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
|
||||||
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
|
|
||||||
|
|
||||||
internal val disableCairoSettingsPatch = bytecodePatch(
|
|
||||||
description = "Disables Cairo Fragment from being used.",
|
|
||||||
) {
|
|
||||||
dependsOn(versionCheckPatch)
|
|
||||||
|
|
||||||
execute {
|
|
||||||
if (!is_19_04_or_greater) {
|
|
||||||
return@execute
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* Cairo Fragment was added since YouTube v19.04.38.
|
|
||||||
*
|
|
||||||
* Disable this for the following reasons:
|
|
||||||
* 1. [backgroundPlaybackPatch] does not activate the Minimized playback setting of Cairo Fragment.
|
|
||||||
* 2. Some patches do not yet support Cairo Fragments (ie: custom Seekbar color).
|
|
||||||
* 3. Settings preferences added by ReVanced are missing.
|
|
||||||
*
|
|
||||||
* Screenshots of the Cairo Fragment:
|
|
||||||
* <a href="https://github.com/qnblackcat/uYouPlus/issues/1468">uYouPlus#1468</a>.
|
|
||||||
*/
|
|
||||||
cairoFragmentConfigFingerprint.method.apply {
|
|
||||||
val literalIndex = indexOfFirstLiteralInstructionOrThrow(CAIRO_CONFIG_LITERAL_VALUE)
|
|
||||||
val resultIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
|
|
||||||
val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
resultIndex + 1,
|
|
||||||
"const/16 v$register, 0x0",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.misc.fix.cairo
|
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint
|
|
||||||
import app.revanced.util.literal
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Added in YouTube v19.04.38.
|
|
||||||
*
|
|
||||||
* When this value is true, Cairo Fragment is used.
|
|
||||||
* In this case, some of the patches may be broken, so set this value to FALSE.
|
|
||||||
*/
|
|
||||||
internal const val CAIRO_CONFIG_LITERAL_VALUE = 45532100L
|
|
||||||
|
|
||||||
internal val cairoFragmentConfigFingerprint = fingerprint {
|
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
|
||||||
returns("Z")
|
|
||||||
literal { CAIRO_CONFIG_LITERAL_VALUE }
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.fix.playbackspeed
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||||
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
|
||||||
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/extension/youtube/patches/FixPlaybackSpeedWhilePlayingPatch;"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fixes a bug in YouTube 19.34+ where the playback speed
|
||||||
|
* can incorrectly reset to 1.0x under certain conditions.
|
||||||
|
*
|
||||||
|
* Reproduction steps using 19.34+
|
||||||
|
* 1. Open a video and start playback
|
||||||
|
* 2. Change the speed to any value that is not 1.0x.
|
||||||
|
* 3. Open the comments panel.
|
||||||
|
* 4. Tap any "N more replies" link at the bottom of a comment, or tap on a timestamp of a comment.
|
||||||
|
* 5. Pause the video
|
||||||
|
* 6. Resume the video
|
||||||
|
* 7. Playback speed will incorrectly change to 1.0x.
|
||||||
|
*/
|
||||||
|
@Suppress("unused")
|
||||||
|
val fixPlaybackSpeedWhilePlayingPatch = bytecodePatch{
|
||||||
|
dependsOn(
|
||||||
|
sharedExtensionPatch,
|
||||||
|
playerTypeHookPatch,
|
||||||
|
versionCheckPatch,
|
||||||
|
)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
if (!is_19_34_or_greater) {
|
||||||
|
return@execute
|
||||||
|
}
|
||||||
|
|
||||||
|
playbackSpeedInFeedsFingerprint.method.apply {
|
||||||
|
val freeRegister = implementation!!.registerCount - parameters.size - 2
|
||||||
|
val playbackSpeedIndex = indexOfGetPlaybackSpeedInstruction(this)
|
||||||
|
val playbackSpeedRegister = getInstruction<TwoRegisterInstruction>(playbackSpeedIndex).registerA
|
||||||
|
val returnIndex = indexOfFirstInstructionOrThrow(playbackSpeedIndex, Opcode.RETURN_VOID)
|
||||||
|
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
playbackSpeedIndex + 1,
|
||||||
|
"""
|
||||||
|
invoke-static { v$playbackSpeedRegister }, $EXTENSION_CLASS_DESCRIPTOR->playbackSpeedChanged(F)Z
|
||||||
|
move-result v$freeRegister
|
||||||
|
if-nez v$freeRegister, :do_not_change
|
||||||
|
""",
|
||||||
|
ExternalLabel("do_not_change", getInstruction(returnIndex))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.fix.playbackspeed
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstructionReversed
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is usually used to set the initial speed (1.0x) when playback starts from the feed.
|
||||||
|
* For some reason, in the latest YouTube, it is invoked even after the video has already started.
|
||||||
|
*/
|
||||||
|
internal val playbackSpeedInFeedsFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
returns("V")
|
||||||
|
parameters("L")
|
||||||
|
opcodes(
|
||||||
|
Opcode.IGET,
|
||||||
|
Opcode.MUL_INT_LIT16,
|
||||||
|
Opcode.IGET_WIDE,
|
||||||
|
Opcode.CONST_WIDE_16,
|
||||||
|
Opcode.CMP_LONG,
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
Opcode.IF_LEZ,
|
||||||
|
Opcode.SUB_LONG_2ADDR,
|
||||||
|
)
|
||||||
|
custom { method, _ ->
|
||||||
|
indexOfGetPlaybackSpeedInstruction(method) >= 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun indexOfGetPlaybackSpeedInstruction(method: Method) =
|
||||||
|
method.indexOfFirstInstructionReversed {
|
||||||
|
opcode == Opcode.IGET &&
|
||||||
|
getReference<FieldReference>()?.type == "F"
|
||||||
|
}
|
||||||
@@ -105,3 +105,15 @@ internal val pivotBarConstructorFingerprint = fingerprint {
|
|||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||||
strings("com.google.android.apps.youtube.app.endpoint.flags")
|
strings("com.google.android.apps.youtube.app.endpoint.flags")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val imageEnumConstructorFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
|
||||||
|
strings("TAB_ACTIVITY_CAIRO")
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val setEnumMapFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||||
|
literal {
|
||||||
|
ytFillBellId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package app.revanced.patches.youtube.misc.navigation
|
package app.revanced.patches.youtube.misc.navigation
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.instructions
|
import app.revanced.patcher.extensions.InstructionExtensions.instructions
|
||||||
import app.revanced.patcher.patch.PatchException
|
import app.revanced.patcher.patch.PatchException
|
||||||
@@ -12,13 +13,16 @@ 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.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_35_or_greater
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
|
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||||
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
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.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
|
|
||||||
@@ -26,6 +30,8 @@ internal var imageOnlyTabResourceId = -1L
|
|||||||
private set
|
private set
|
||||||
internal var actionBarSearchResultsViewMicId = -1L
|
internal var actionBarSearchResultsViewMicId = -1L
|
||||||
private set
|
private set
|
||||||
|
internal var ytFillBellId = -1L
|
||||||
|
private set
|
||||||
|
|
||||||
private val navigationBarHookResourcePatch = resourcePatch {
|
private val navigationBarHookResourcePatch = resourcePatch {
|
||||||
dependsOn(resourceMappingPatch)
|
dependsOn(resourceMappingPatch)
|
||||||
@@ -33,6 +39,7 @@ private val navigationBarHookResourcePatch = resourcePatch {
|
|||||||
execute {
|
execute {
|
||||||
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"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +151,36 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig
|
|||||||
"(${EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V",
|
"(${EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix YT bug of notification tab missing the filled icon.
|
||||||
|
if (is_19_35_or_greater) {
|
||||||
|
val cairoNotificationEnumReference = with(imageEnumConstructorFingerprint) {
|
||||||
|
val stringIndex = stringMatches!!.first().index
|
||||||
|
val cairoNotificationEnumIndex = method.indexOfFirstInstructionOrThrow(stringIndex) {
|
||||||
|
opcode == Opcode.SPUT_OBJECT
|
||||||
|
}
|
||||||
|
method.getInstruction<ReferenceInstruction>(cairoNotificationEnumIndex).reference
|
||||||
|
}
|
||||||
|
|
||||||
|
setEnumMapFingerprint.method.apply {
|
||||||
|
val enumMapIndex = indexOfFirstInstructionReversedOrThrow {
|
||||||
|
val reference = getReference<MethodReference>()
|
||||||
|
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||||
|
reference?.definingClass == "Ljava/util/EnumMap;" &&
|
||||||
|
reference.name == "put" &&
|
||||||
|
reference.parameterTypes.firstOrNull() == "Ljava/lang/Enum;"
|
||||||
|
}
|
||||||
|
val instruction = getInstruction<FiveRegisterInstruction>(enumMapIndex)
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
enumMapIndex + 1,
|
||||||
|
"""
|
||||||
|
sget-object v${instruction.registerD}, $cairoNotificationEnumReference
|
||||||
|
invoke-static { v${instruction.registerC}, v${instruction.registerD} }, $EXTENSION_CLASS_DESCRIPTOR->setCairoNotificationFilledIcon(Ljava/util/EnumMap;Ljava/lang/Enum;)V
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,13 +12,23 @@ internal val playerTopControlsInflateFingerprint = fingerprint {
|
|||||||
literal { controlsLayoutStub }
|
literal { controlsLayoutStub }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val playerControlsExtensionHookListenersExistFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||||
|
returns("Z")
|
||||||
|
parameters()
|
||||||
|
custom { methodDef, classDef ->
|
||||||
|
methodDef.name == "fullscreenButtonVisibilityCallbacksExist" &&
|
||||||
|
classDef.type == EXTENSION_CLASS_DESCRIPTOR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal val playerControlsExtensionHookFingerprint = fingerprint {
|
internal val playerControlsExtensionHookFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||||
returns("V")
|
returns("V")
|
||||||
parameters("Z")
|
parameters("Z")
|
||||||
custom { methodDef, classDef ->
|
custom { methodDef, classDef ->
|
||||||
methodDef.name == "fullscreenButtonVisibilityChanged" &&
|
methodDef.name == "fullscreenButtonVisibilityChanged" &&
|
||||||
classDef.type == "Lapp/revanced/extension/youtube/patches/PlayerControlsPatch;"
|
classDef.type == EXTENSION_CLASS_DESCRIPTOR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -189,13 +189,18 @@ fun injectVisibilityCheckCall(descriptor: String) {
|
|||||||
"invoke-static { p1 , p2 }, $descriptor->changeVisibility(ZZ)V",
|
"invoke-static { p1 , p2 }, $descriptor->changeVisibility(ZZ)V",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!visibilityImmediateCallbacksExistModified) {
|
||||||
|
visibilityImmediateCallbacksExistModified = true
|
||||||
|
visibilityImmediateCallbacksExistMethod.returnEarly(true)
|
||||||
|
}
|
||||||
|
|
||||||
visibilityImmediateMethod.addInstruction(
|
visibilityImmediateMethod.addInstruction(
|
||||||
visibilityImmediateInsertIndex++,
|
visibilityImmediateInsertIndex++,
|
||||||
"invoke-static { p0 }, $descriptor->changeVisibilityImmediate(Z)V",
|
"invoke-static { p0 }, $descriptor->changeVisibilityImmediate(Z)V",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
"Lapp/revanced/extension/youtube/patches/PlayerControlsPatch;"
|
"Lapp/revanced/extension/youtube/patches/PlayerControlsPatch;"
|
||||||
|
|
||||||
private lateinit var inflateTopControlMethod: MutableMethod
|
private lateinit var inflateTopControlMethod: MutableMethod
|
||||||
@@ -209,6 +214,9 @@ private var inflateBottomControlRegister: Int = -1
|
|||||||
private lateinit var visibilityMethod: MutableMethod
|
private lateinit var visibilityMethod: MutableMethod
|
||||||
private var visibilityInsertIndex: Int = 0
|
private var visibilityInsertIndex: Int = 0
|
||||||
|
|
||||||
|
private var visibilityImmediateCallbacksExistModified = false
|
||||||
|
private lateinit var visibilityImmediateCallbacksExistMethod : MutableMethod
|
||||||
|
|
||||||
private lateinit var visibilityImmediateMethod: MutableMethod
|
private lateinit var visibilityImmediateMethod: MutableMethod
|
||||||
private var visibilityImmediateInsertIndex: Int = 0
|
private var visibilityImmediateInsertIndex: Int = 0
|
||||||
|
|
||||||
@@ -266,6 +274,7 @@ val playerControlsPatch = bytecodePatch(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
visibilityImmediateCallbacksExistMethod = playerControlsExtensionHookListenersExistFingerprint.method
|
||||||
visibilityImmediateMethod = playerControlsExtensionHookFingerprint.method
|
visibilityImmediateMethod = playerControlsExtensionHookFingerprint.method
|
||||||
|
|
||||||
// A/B test for a slightly different bottom overlay controls,
|
// A/B test for a slightly different bottom overlay controls,
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ var is_19_46_or_greater = false
|
|||||||
private set
|
private set
|
||||||
var is_19_47_or_greater = false
|
var is_19_47_or_greater = false
|
||||||
private set
|
private set
|
||||||
|
var is_19_49_or_greater = false
|
||||||
|
private set
|
||||||
|
|
||||||
val versionCheckPatch = resourcePatch(
|
val versionCheckPatch = resourcePatch(
|
||||||
description = "Uses the Play Store service version to find the major/minor version of the YouTube target app.",
|
description = "Uses the Play Store service version to find the major/minor version of the YouTube target app.",
|
||||||
@@ -74,5 +76,6 @@ val versionCheckPatch = resourcePatch(
|
|||||||
is_19_43_or_greater = 244405000 <= playStoreServicesVersion
|
is_19_43_or_greater = 244405000 <= playStoreServicesVersion
|
||||||
is_19_46_or_greater = 244705000 <= playStoreServicesVersion
|
is_19_46_or_greater = 244705000 <= playStoreServicesVersion
|
||||||
is_19_47_or_greater = 244799000 <= playStoreServicesVersion
|
is_19_47_or_greater = 244799000 <= playStoreServicesVersion
|
||||||
|
is_19_49_or_greater = 245005000 <= playStoreServicesVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,3 +21,14 @@ internal val setThemeFingerprint = fingerprint {
|
|||||||
opcodes(Opcode.RETURN_OBJECT)
|
opcodes(Opcode.RETURN_OBJECT)
|
||||||
literal { appearanceStringId }
|
literal { appearanceStringId }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Added in YouTube v19.04.38.
|
||||||
|
*/
|
||||||
|
internal const val CAIRO_CONFIG_LITERAL_VALUE = 45532100L
|
||||||
|
|
||||||
|
internal val cairoFragmentConfigFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
returns("Z")
|
||||||
|
literal { CAIRO_CONFIG_LITERAL_VALUE }
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
|||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
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.Companion.toMutable
|
||||||
import app.revanced.patches.all.misc.packagename.setOrGetFallbackPackageName
|
import app.revanced.patches.all.misc.packagename.setOrGetFallbackPackageName
|
||||||
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
|
||||||
@@ -17,10 +18,17 @@ import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPref
|
|||||||
import app.revanced.patches.shared.misc.settings.settingsPatch
|
import app.revanced.patches.shared.misc.settings.settingsPatch
|
||||||
import app.revanced.patches.youtube.misc.check.checkEnvironmentPatch
|
import app.revanced.patches.youtube.misc.check.checkEnvironmentPatch
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.misc.fix.cairo.disableCairoSettingsPatch
|
import app.revanced.patches.youtube.misc.fix.playbackspeed.fixPlaybackSpeedWhilePlayingPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_04_or_greater
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||||
import app.revanced.util.*
|
import app.revanced.util.*
|
||||||
|
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.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||||
|
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
|
|
||||||
// Used by a fingerprint() from SettingsPatch.
|
// Used by a fingerprint() from SettingsPatch.
|
||||||
@@ -37,13 +45,28 @@ private val settingsResourcePatch = resourcePatch {
|
|||||||
dependsOn(
|
dependsOn(
|
||||||
resourceMappingPatch,
|
resourceMappingPatch,
|
||||||
settingsPatch(
|
settingsPatch(
|
||||||
rootPreference = IntentPreference(
|
listOf(
|
||||||
titleKey = "revanced_settings_title",
|
IntentPreference(
|
||||||
summaryKey = null,
|
titleKey = "revanced_settings_title",
|
||||||
intent = newIntent("revanced_settings_intent"),
|
summaryKey = null,
|
||||||
) to "settings_fragment",
|
intent = newIntent("revanced_settings_intent"),
|
||||||
preferences,
|
) to "settings_fragment",
|
||||||
),
|
PreferenceCategory(
|
||||||
|
titleKey = "revanced_settings_title",
|
||||||
|
layout = "@layout/preference_group_title",
|
||||||
|
preferences = setOf(
|
||||||
|
IntentPreference(
|
||||||
|
titleKey = "revanced_settings_submenu_title",
|
||||||
|
summaryKey = null,
|
||||||
|
icon = "@drawable/revanced_settings_icon",
|
||||||
|
layout = "@layout/preference_with_icon",
|
||||||
|
intent = newIntent("revanced_settings_intent"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) to "settings_fragment_cairo",
|
||||||
|
),
|
||||||
|
preferences
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
@@ -51,6 +74,7 @@ private val settingsResourcePatch = resourcePatch {
|
|||||||
appearanceStringId = resourceMappings["string", "app_theme_appearance_dark"]
|
appearanceStringId = resourceMappings["string", "app_theme_appearance_dark"]
|
||||||
|
|
||||||
arrayOf(
|
arrayOf(
|
||||||
|
ResourceGroup("drawable", "revanced_settings_icon.xml"),
|
||||||
ResourceGroup("layout", "revanced_settings_with_toolbar.xml"),
|
ResourceGroup("layout", "revanced_settings_with_toolbar.xml"),
|
||||||
).forEach { resourceGroup ->
|
).forEach { resourceGroup ->
|
||||||
copyResources("settings", resourceGroup)
|
copyResources("settings", resourceGroup)
|
||||||
@@ -73,7 +97,6 @@ private val settingsResourcePatch = resourcePatch {
|
|||||||
// Remove horizontal divider from the settings Preferences
|
// Remove horizontal divider from the settings Preferences
|
||||||
// To better match the appearance of the stock YouTube settings.
|
// To better match the appearance of the stock YouTube settings.
|
||||||
document("res/values/styles.xml").use { document ->
|
document("res/values/styles.xml").use { document ->
|
||||||
|
|
||||||
arrayOf(
|
arrayOf(
|
||||||
"Theme.YouTube.Settings",
|
"Theme.YouTube.Settings",
|
||||||
"Theme.YouTube.Settings.Dark",
|
"Theme.YouTube.Settings.Dark",
|
||||||
@@ -93,7 +116,6 @@ private val settingsResourcePatch = resourcePatch {
|
|||||||
// Some devices freak out if undeclared data is passed to an intent,
|
// Some devices freak out if undeclared data is passed to an intent,
|
||||||
// and this change appears to fix the issue.
|
// and this change appears to fix the issue.
|
||||||
document("AndroidManifest.xml").use { document ->
|
document("AndroidManifest.xml").use { document ->
|
||||||
|
|
||||||
val licenseElement = document.childNodes.findElementByAttributeValueOrThrow(
|
val licenseElement = document.childNodes.findElementByAttributeValueOrThrow(
|
||||||
"android:name",
|
"android:name",
|
||||||
"com.google.android.libraries.social.licenses.LicenseActivity",
|
"com.google.android.libraries.social.licenses.LicenseActivity",
|
||||||
@@ -117,7 +139,8 @@ val settingsPatch = bytecodePatch(
|
|||||||
sharedExtensionPatch,
|
sharedExtensionPatch,
|
||||||
settingsResourcePatch,
|
settingsResourcePatch,
|
||||||
addResourcesPatch,
|
addResourcesPatch,
|
||||||
disableCairoSettingsPatch,
|
versionCheckPatch,
|
||||||
|
fixPlaybackSpeedWhilePlayingPatch,
|
||||||
// Currently there is no easy way to make a mandatory patch,
|
// Currently there is no easy way to make a mandatory patch,
|
||||||
// so for now this is a dependent of this patch.
|
// so for now this is a dependent of this patch.
|
||||||
checkEnvironmentPatch,
|
checkEnvironmentPatch,
|
||||||
@@ -140,6 +163,12 @@ val settingsPatch = bytecodePatch(
|
|||||||
selectable = true,
|
selectable = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (is_19_34_or_greater) {
|
||||||
|
PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
||||||
|
SwitchPreference("revanced_restore_old_settings_menus")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
PreferenceScreen.MISC.addPreferences(
|
PreferenceScreen.MISC.addPreferences(
|
||||||
TextPreference(
|
TextPreference(
|
||||||
key = null,
|
key = null,
|
||||||
@@ -148,6 +177,10 @@ val settingsPatch = bytecodePatch(
|
|||||||
inputType = InputType.TEXT_MULTI_LINE,
|
inputType = InputType.TEXT_MULTI_LINE,
|
||||||
tag = "app.revanced.extension.shared.settings.preference.ImportExportPreference",
|
tag = "app.revanced.extension.shared.settings.preference.ImportExportPreference",
|
||||||
),
|
),
|
||||||
|
ListPreference(
|
||||||
|
key = "revanced_language",
|
||||||
|
summaryKey = null
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
setThemeFingerprint.method.let { setThemeMethod ->
|
setThemeFingerprint.method.let { setThemeMethod ->
|
||||||
@@ -187,6 +220,40 @@ val settingsPatch = bytecodePatch(
|
|||||||
licenseActivityOnCreateFingerprint.classDef.apply {
|
licenseActivityOnCreateFingerprint.classDef.apply {
|
||||||
methods.removeIf { it.name != "onCreate" && !MethodUtil.isConstructor(it) }
|
methods.removeIf { it.name != "onCreate" && !MethodUtil.isConstructor(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add context override to force a specific settings language.
|
||||||
|
licenseActivityOnCreateFingerprint.classDef.apply {
|
||||||
|
val attachBaseContext = ImmutableMethod(
|
||||||
|
type,
|
||||||
|
"attachBaseContext",
|
||||||
|
listOf(ImmutableMethodParameter("Landroid/content/Context;", null, null)),
|
||||||
|
"V",
|
||||||
|
AccessFlags.PROTECTED.value,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
MutableMethodImplementation(3),
|
||||||
|
).toMutable().apply {
|
||||||
|
addInstructions(
|
||||||
|
"""
|
||||||
|
invoke-static { p1 }, $activityHookClassDescriptor->getAttachBaseContext(Landroid/content/Context;)Landroid/content/Context;
|
||||||
|
move-result-object p1
|
||||||
|
invoke-super { p0, p1 }, $superclass->attachBaseContext(Landroid/content/Context;)V
|
||||||
|
return-void
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
methods.add(attachBaseContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add setting to force cairo settings fragment on/off.
|
||||||
|
if (is_19_04_or_greater) {
|
||||||
|
cairoFragmentConfigFingerprint.method.insertFeatureFlagBooleanOverride(
|
||||||
|
CAIRO_CONFIG_LITERAL_VALUE,
|
||||||
|
"$activityHookClassDescriptor->useCairoSettingsFragment(Z)Z"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
finalize {
|
finalize {
|
||||||
@@ -222,17 +289,15 @@ object PreferenceScreen : BasePreferenceScreen() {
|
|||||||
key = "revanced_settings_screen_03_feed",
|
key = "revanced_settings_screen_03_feed",
|
||||||
summaryKey = null,
|
summaryKey = null,
|
||||||
)
|
)
|
||||||
val PLAYER = Screen(
|
val GENERAL_LAYOUT = Screen(
|
||||||
key = "revanced_settings_screen_04_player",
|
key = "revanced_settings_screen_04_general",
|
||||||
summaryKey = null,
|
summaryKey = null,
|
||||||
)
|
)
|
||||||
val GENERAL_LAYOUT = Screen(
|
val PLAYER = Screen(
|
||||||
key = "revanced_settings_screen_05_general",
|
key = "revanced_settings_screen_05_player",
|
||||||
summaryKey = null,
|
summaryKey = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Don't sort, as related preferences are scattered apart.
|
|
||||||
// Can use title sorting after PreferenceCategory support is added.
|
|
||||||
val SHORTS = Screen(
|
val SHORTS = Screen(
|
||||||
key = "revanced_settings_screen_06_shorts",
|
key = "revanced_settings_screen_06_shorts",
|
||||||
summaryKey = null,
|
summaryKey = null,
|
||||||
|
|||||||
@@ -38,10 +38,23 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
|
|||||||
preferences = setOf(
|
preferences = setOf(
|
||||||
SwitchPreference("revanced_spoof_video_streams"),
|
SwitchPreference("revanced_spoof_video_streams"),
|
||||||
ListPreference(
|
ListPreference(
|
||||||
"revanced_spoof_video_streams_language",
|
"revanced_spoof_video_streams_client_type",
|
||||||
summaryKey = null
|
summaryKey = null,
|
||||||
),
|
),
|
||||||
NonInteractivePreference("revanced_spoof_video_streams_about")
|
NonInteractivePreference(
|
||||||
|
// Requires a key and title but the actual text is chosen at runtime.
|
||||||
|
key = "revanced_spoof_video_streams_about_android",
|
||||||
|
tag = "app.revanced.extension.youtube.settings.preference.SpoofStreamingDataSideEffectsPreference"
|
||||||
|
),
|
||||||
|
ListPreference(
|
||||||
|
key = "revanced_spoof_video_streams_language",
|
||||||
|
summaryKey = null,
|
||||||
|
// Language strings are declared in Setting patch.
|
||||||
|
entriesKey = "revanced_language_entries",
|
||||||
|
entryValuesKey = "revanced_language_entry_values"
|
||||||
|
),
|
||||||
|
SwitchPreference("revanced_spoof_video_streams_ios_force_avc"),
|
||||||
|
SwitchPreference("revanced_spoof_streaming_data_stats_for_nerds"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ internal val mainActivityOnCreateFingerprint = fingerprint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val rollingNumberTextViewAnimationUpdateFingerprint = fingerprint {
|
internal val rollingNumberTextViewAnimationUpdateFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
returns("V")
|
returns("V")
|
||||||
parameters("Landroid/graphics/Bitmap;")
|
parameters("Landroid/graphics/Bitmap;")
|
||||||
|
|||||||
@@ -31,8 +31,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val forceOriginalAudioPatch = bytecodePatch(
|
val forceOriginalAudioPatch = bytecodePatch(
|
||||||
name = "Force original audio",
|
name = "Force original audio",
|
||||||
description = "Adds an option to always use the original audio track. " +
|
description = "Adds an option to always use the original audio track.",
|
||||||
"This patch does nothing if 'Spoof video streams' is enabled.",
|
|
||||||
) {
|
) {
|
||||||
dependsOn(
|
dependsOn(
|
||||||
sharedExtensionPatch,
|
sharedExtensionPatch,
|
||||||
@@ -58,7 +57,10 @@ val forceOriginalAudioPatch = bytecodePatch(
|
|||||||
addResources("youtube", "video.audio.forceOriginalAudioPatch")
|
addResources("youtube", "video.audio.forceOriginalAudioPatch")
|
||||||
|
|
||||||
PreferenceScreen.VIDEO.addPreferences(
|
PreferenceScreen.VIDEO.addPreferences(
|
||||||
SwitchPreference("revanced_force_original_audio")
|
SwitchPreference(
|
||||||
|
key = "revanced_force_original_audio",
|
||||||
|
tag = "app.revanced.extension.youtube.settings.preference.ForceOriginalAudioSwitchPreference"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
fun Method.firstFormatStreamingModelCall(
|
fun Method.firstFormatStreamingModelCall(
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package app.revanced.patches.youtube.video.hdr
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.all.misc.resources.addResources
|
||||||
|
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
|
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||||
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/extension/youtube/patches/DisableHdrPatch;"
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val disableHdrPatch = bytecodePatch(
|
||||||
|
name = "Disable HDR video",
|
||||||
|
description = "Adds an option to disable video HDR.",
|
||||||
|
) {
|
||||||
|
dependsOn(
|
||||||
|
sharedExtensionPatch,
|
||||||
|
settingsPatch,
|
||||||
|
addResourcesPatch,
|
||||||
|
)
|
||||||
|
|
||||||
|
compatibleWith(
|
||||||
|
"com.google.android.youtube"(
|
||||||
|
"18.38.44",
|
||||||
|
"18.49.37",
|
||||||
|
"19.16.39",
|
||||||
|
"19.25.37",
|
||||||
|
"19.34.42",
|
||||||
|
"19.43.41",
|
||||||
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
|
"19.47.53",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
addResources("youtube", "video.hdr.disableHdrPatch")
|
||||||
|
|
||||||
|
PreferenceScreen.VIDEO.addPreferences(
|
||||||
|
SwitchPreference("revanced_disable_hdr_video")
|
||||||
|
)
|
||||||
|
|
||||||
|
hdrCapabilityFingerprint.let {
|
||||||
|
it.originalMethod.apply {
|
||||||
|
val stringIndex = it.stringMatches!!.first().index
|
||||||
|
val navigateIndex = indexOfFirstInstructionOrThrow(stringIndex) {
|
||||||
|
val reference = getReference<MethodReference>()
|
||||||
|
reference?.parameterTypes == listOf("I", "Landroid/view/Display;") &&
|
||||||
|
reference.returnType == "Z"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify the HDR lookup method (Method is in the same class as the fingerprint).
|
||||||
|
navigate(this).to(navigateIndex).stop().addInstructionsWithLabels(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->disableHDRVideo()Z
|
||||||
|
move-result v0
|
||||||
|
if-nez v0, :useHdr
|
||||||
|
return v0
|
||||||
|
:useHdr
|
||||||
|
nop
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package app.revanced.patches.youtube.video.hdr
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal val hdrCapabilityFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
strings(
|
||||||
|
"av1_profile_main_10_hdr_10_plus_supported",
|
||||||
|
"video/av01"
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -17,22 +17,26 @@ import app.revanced.patches.shared.misc.mapping.resourceMappings
|
|||||||
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.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.interaction.seekbar.disableFastForwardNoticeFingerprint
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
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.addLithoFilter
|
||||||
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
|
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
|
||||||
|
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.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.PreferenceScreen
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
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.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
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
|
||||||
import com.android.tools.smali.dexlib2.immutable.ImmutableField
|
import com.android.tools.smali.dexlib2.immutable.ImmutableField
|
||||||
|
|
||||||
var speedUnavailableId = -1L
|
internal var speedUnavailableId = -1L
|
||||||
internal set
|
private set
|
||||||
|
|
||||||
private val customPlaybackSpeedResourcePatch = resourcePatch {
|
private val customPlaybackSpeedResourcePatch = resourcePatch {
|
||||||
dependsOn(resourceMappingPatch)
|
dependsOn(resourceMappingPatch)
|
||||||
@@ -61,6 +65,7 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
|
|||||||
recyclerViewTreeHookPatch,
|
recyclerViewTreeHookPatch,
|
||||||
customPlaybackSpeedResourcePatch,
|
customPlaybackSpeedResourcePatch,
|
||||||
addResourcesPatch,
|
addResourcesPatch,
|
||||||
|
versionCheckPatch
|
||||||
)
|
)
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
@@ -71,6 +76,12 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
|
|||||||
TextPreference("revanced_custom_playback_speeds", inputType = InputType.TEXT_MULTI_LINE),
|
TextPreference("revanced_custom_playback_speeds", inputType = InputType.TEXT_MULTI_LINE),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (is_19_25_or_greater) {
|
||||||
|
PreferenceScreen.VIDEO.addPreferences(
|
||||||
|
TextPreference("revanced_speed_tap_and_hold", inputType = InputType.NUMBER_DECIMAL),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Replace the speeds float array with custom speeds.
|
// Replace the speeds float array with custom speeds.
|
||||||
speedArrayGeneratorFingerprint.method.apply {
|
speedArrayGeneratorFingerprint.method.apply {
|
||||||
val sizeCallIndex = indexOfFirstInstructionOrThrow { getReference<MethodReference>()?.name == "size" }
|
val sizeCallIndex = indexOfFirstInstructionOrThrow { getReference<MethodReference>()?.name == "size" }
|
||||||
@@ -166,5 +177,27 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
|
|||||||
addLithoFilter(FILTER_CLASS_DESCRIPTOR)
|
addLithoFilter(FILTER_CLASS_DESCRIPTOR)
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
|
||||||
|
// region Custom tap and hold 2x speed.
|
||||||
|
|
||||||
|
if (is_19_25_or_greater) {
|
||||||
|
disableFastForwardNoticeFingerprint.method.apply {
|
||||||
|
val index = indexOfFirstInstructionOrThrow {
|
||||||
|
(this as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits()
|
||||||
|
}
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
index + 1,
|
||||||
|
"""
|
||||||
|
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->tapAndHoldSpeed()F
|
||||||
|
move-result v$register
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,31 +24,31 @@ class StringResource(
|
|||||||
if (value.startsWith('"') && value.endsWith('"')) {
|
if (value.startsWith('"') && value.endsWith('"')) {
|
||||||
// Raw strings allow unescaped single quote but not double quote.
|
// Raw strings allow unescaped single quote but not double quote.
|
||||||
if (!value.substring(1, value.length - 1).contains(Regex("(?<!\\\\)[\"]"))) {
|
if (!value.substring(1, value.length - 1).contains(Regex("(?<!\\\\)[\"]"))) {
|
||||||
return this;
|
return this
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (value.contains('\n')) {
|
if (value.contains('\n')) {
|
||||||
// Don't throw an exception, otherwise unnoticed mistakes
|
// Don't throw an exception, otherwise unnoticed mistakes
|
||||||
// in Crowdin can cause patching failures.
|
// in Crowdin can cause patching failures.
|
||||||
// Incorrectly escaped strings still work but do not display as intended.
|
// Incorrectly escaped strings still work but do not display as intended.
|
||||||
Logger.getLogger(StringResource.javaClass.name).severe(
|
Logger.getLogger(StringResource.javaClass.name).warning(
|
||||||
"String $name is not raw but contains encoded new line characters: $value")
|
"String $name is not raw but contains encoded new line characters: $value")
|
||||||
}
|
}
|
||||||
if (!value.contains(Regex("(?<!\\\\)['\"]"))) {
|
if (!value.contains(Regex("(?<!\\\\)['\"]"))) {
|
||||||
return this;
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.getLogger(StringResource.javaClass.name).severe(
|
Logger.getLogger(StringResource.javaClass.name).warning(
|
||||||
"String $name cannot contain unescaped quotes in value: $value")
|
"String $name cannot contain unescaped quotes in value: $value")
|
||||||
|
|
||||||
return this;
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the string is un-formatted, explicitly add the formatted attribute
|
// if the string is un-formatted, explicitly add the formatted attribute
|
||||||
if (!formatted) setAttribute("formatted", "false")
|
if (!formatted) setAttribute("formatted", "false")
|
||||||
|
|
||||||
textContent = value.validateAndroidStringEscaping();
|
textContent = value.validateAndroidStringEscaping()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -136,6 +136,8 @@ Second \"item\" text"</string>
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.panels.popup.playerPopupPanelsPatch">
|
<patch id="layout.panels.popup.playerPopupPanelsPatch">
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.player.fullscreen.exitFullscreenPatch">
|
||||||
|
</patch>
|
||||||
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.player.overlay.customPlayerOverlayOpacityResourcePatch">
|
<patch id="layout.player.overlay.customPlayerOverlayOpacityResourcePatch">
|
||||||
@@ -155,6 +157,8 @@ Second \"item\" text"</string>
|
|||||||
<!-- 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. -->
|
||||||
<!-- 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>
|
||||||
<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 -->
|
||||||
@@ -168,8 +172,6 @@ Second \"item\" text"</string>
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
|
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.tablet.enableTabletLayoutPatch">
|
|
||||||
</patch>
|
|
||||||
<patch id="layout.miniplayer.miniplayerPatch">
|
<patch id="layout.miniplayer.miniplayerPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.theme.themePatch">
|
<patch id="layout.theme.themePatch">
|
||||||
@@ -218,6 +220,7 @@ Second \"item\" text"</string>
|
|||||||
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
|
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
|
||||||
|
<!-- 'no auth' means no authentication -->
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -136,6 +136,8 @@ Second \"item\" text"</string>
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.panels.popup.playerPopupPanelsPatch">
|
<patch id="layout.panels.popup.playerPopupPanelsPatch">
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.player.fullscreen.exitFullscreenPatch">
|
||||||
|
</patch>
|
||||||
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.player.overlay.customPlayerOverlayOpacityResourcePatch">
|
<patch id="layout.player.overlay.customPlayerOverlayOpacityResourcePatch">
|
||||||
@@ -155,6 +157,8 @@ Second \"item\" text"</string>
|
|||||||
<!-- 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. -->
|
||||||
<!-- 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>
|
||||||
<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 -->
|
||||||
@@ -168,8 +172,6 @@ Second \"item\" text"</string>
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
|
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.tablet.enableTabletLayoutPatch">
|
|
||||||
</patch>
|
|
||||||
<patch id="layout.miniplayer.miniplayerPatch">
|
<patch id="layout.miniplayer.miniplayerPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.theme.themePatch">
|
<patch id="layout.theme.themePatch">
|
||||||
@@ -218,6 +220,7 @@ Second \"item\" text"</string>
|
|||||||
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
|
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
|
||||||
|
<!-- 'no auth' means no authentication -->
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -43,6 +43,62 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_settings_import_reset">إعادة تعيين إعدادات ReVanced إلى الوضع الافتراضي</string>
|
<string name="revanced_settings_import_reset">إعادة تعيين إعدادات ReVanced إلى الوضع الافتراضي</string>
|
||||||
<string name="revanced_settings_import_success">تم استيراد %d إعدادات</string>
|
<string name="revanced_settings_import_success">تم استيراد %d إعدادات</string>
|
||||||
<string name="revanced_settings_import_failure_parse">فشل الاستيراد: %s</string>
|
<string name="revanced_settings_import_failure_parse">فشل الاستيراد: %s</string>
|
||||||
|
<string name="revanced_language_title">لغة ReVanced</string>
|
||||||
|
<string name="revanced_language_user_dialog_message">"قد تكون الترجمات لبعض اللغات مفقودة أو غير مكتملة.
|
||||||
|
|
||||||
|
لترجمة لغات جديدة، تفضل بزيارة translate.revanced.app"</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. -->
|
||||||
@@ -77,12 +133,13 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_settings_screen_01_ads_title">الإعلانات</string>
|
<string name="revanced_settings_screen_01_ads_title">الإعلانات</string>
|
||||||
<string name="revanced_settings_screen_02_alt_thumbnails_title">مُصغَّرات فيديو بديلة</string>
|
<string name="revanced_settings_screen_02_alt_thumbnails_title">مُصغَّرات فيديو بديلة</string>
|
||||||
<string name="revanced_settings_screen_03_feed_title">الموجز</string>
|
<string name="revanced_settings_screen_03_feed_title">الموجز</string>
|
||||||
<string name="revanced_settings_screen_04_player_title">المشغل</string>
|
<string name="revanced_settings_screen_04_general_title">عام</string>
|
||||||
<string name="revanced_settings_screen_05_general_title">التصميم العام</string>
|
<string name="revanced_settings_screen_05_player_title">مشغل</string>
|
||||||
<string name="revanced_settings_screen_07_seekbar_title">شريط تقدم الفيديو</string>
|
<string name="revanced_settings_screen_07_seekbar_title">شريط تقدم الفيديو</string>
|
||||||
<string name="revanced_settings_screen_08_swipe_controls_title">التحكم عن طريق إيماءة التمرير</string>
|
<string name="revanced_settings_screen_08_swipe_controls_title">التحكم عن طريق إيماءة التمرير</string>
|
||||||
<string name="revanced_settings_screen_11_misc_title">إعدادات متنوعة</string>
|
<string name="revanced_settings_screen_11_misc_title">متنوع</string>
|
||||||
<string name="revanced_settings_screen_12_video_title">الفيديو</string>
|
<string name="revanced_settings_screen_12_video_title">الفيديو</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_title">إعادة قوائم إعدادات قديمة</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
||||||
<string name="revanced_shorts_disable_background_playback_title">تعطيل تشغيل فيديوهات Shorts في الخلفية</string>
|
<string name="revanced_shorts_disable_background_playback_title">تعطيل تشغيل فيديوهات Shorts في الخلفية</string>
|
||||||
@@ -138,12 +195,12 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_join_membership_button_summary_on">تم إخفاء الزر</string>
|
<string name="revanced_hide_join_membership_button_summary_on">تم إخفاء الزر</string>
|
||||||
<string name="revanced_hide_join_membership_button_summary_off">يتم عرض الزر</string>
|
<string name="revanced_hide_join_membership_button_summary_off">يتم عرض الزر</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">إخفاء رف \"من أجلك\" في صفحة القناة</string>
|
<string name="revanced_hide_for_you_shelf_title">إخفاء رف \"لـك\" في صفحة القناة</string>
|
||||||
<string name="revanced_hide_for_you_shelf_summary_on">تم إخفاء الرف</string>
|
<string name="revanced_hide_for_you_shelf_summary_on">تم إخفاء الرف</string>
|
||||||
<string name="revanced_hide_for_you_shelf_summary_off">يتم عرض الرف</string>
|
<string name="revanced_hide_for_you_shelf_summary_off">يتم عرض الرف</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">إخفاء زر \'نبهني\'</string>
|
<string name="revanced_hide_notify_me_button_title">إخفاء زر \'تنبيهي\'</string>
|
||||||
<string name="revanced_hide_notify_me_button_summary_on">تم إخفاء الزر</string>
|
<string name="revanced_hide_notify_me_button_summary_on">تم إخفاء الزر</string>
|
||||||
<string name="revanced_hide_notify_me_button_summary_off">يتم عرض الزر</string>
|
<string name="revanced_hide_notify_me_button_summary_off">يتم عرض الزر</string>
|
||||||
<!-- 'People also watch' should be translated using the same localized wording YouTube displays. -->
|
<!-- 'People also watch' should be translated using the same localized wording YouTube displays. -->
|
||||||
@@ -164,9 +221,9 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_chips_shelf_title">إخفاء رف الشرائح</string>
|
<string name="revanced_hide_chips_shelf_title">إخفاء رف الشرائح</string>
|
||||||
<string name="revanced_hide_chips_shelf_summary_on">تم إخفاء رف الشرائح</string>
|
<string name="revanced_hide_chips_shelf_summary_on">تم إخفاء رف الشرائح</string>
|
||||||
<string name="revanced_hide_chips_shelf_summary_off">يتم عرض رف الشرائح</string>
|
<string name="revanced_hide_chips_shelf_summary_off">يتم عرض رف الشرائح</string>
|
||||||
<string name="revanced_hide_expandable_chip_title">إخفاء الشريحة القابلة للتوسيع تحت مقاطع الفيديو</string>
|
<string name="revanced_hide_expandable_chip_title">إخفاء الشريحة القابلة للتوسيع تحت الفيديوهات</string>
|
||||||
<string name="revanced_hide_expandable_chip_summary_on">تم إخفاء الرقائق القابلة للتوسيع</string>
|
<string name="revanced_hide_expandable_chip_summary_on">تم إخفاء الشرائح القابلة للتوسيع</string>
|
||||||
<string name="revanced_hide_expandable_chip_summary_off">يتم عرض الرقائق القابلة للتوسيع</string>
|
<string name="revanced_hide_expandable_chip_summary_off">يتم عرض الشرائح القابلة للتوسيع</string>
|
||||||
<string name="revanced_hide_community_posts_title">إخفاء مشاركات المجتمع</string>
|
<string name="revanced_hide_community_posts_title">إخفاء مشاركات المجتمع</string>
|
||||||
<string name="revanced_hide_community_posts_summary_on">تم إخفاء مشاركات المجتمع</string>
|
<string name="revanced_hide_community_posts_summary_on">تم إخفاء مشاركات المجتمع</string>
|
||||||
<string name="revanced_hide_community_posts_summary_off">يتم عرض مشاركات المجتمع</string>
|
<string name="revanced_hide_community_posts_summary_off">يتم عرض مشاركات المجتمع</string>
|
||||||
@@ -207,8 +264,8 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_quick_actions_summary_on">تم إخفاء الإجراءات السريعة</string>
|
<string name="revanced_hide_quick_actions_summary_on">تم إخفاء الإجراءات السريعة</string>
|
||||||
<string name="revanced_hide_quick_actions_summary_off">يتم عرض الإجراءات السريعة</string>
|
<string name="revanced_hide_quick_actions_summary_off">يتم عرض الإجراءات السريعة</string>
|
||||||
<string name="revanced_hide_related_videos_title">إخفاء الفيديوهات ذات الصلة في الإجراءات السريعة</string>
|
<string name="revanced_hide_related_videos_title">إخفاء الفيديوهات ذات الصلة في الإجراءات السريعة</string>
|
||||||
<string name="revanced_hide_related_videos_summary_on">تم إخفاء مقاطع الفيديو ذات الصلة</string>
|
<string name="revanced_hide_related_videos_summary_on">تم إخفاء الفيديوهات ذات الصلة</string>
|
||||||
<string name="revanced_hide_related_videos_summary_off">يتم عرض مقاطع الفيديو ذات الصلة</string>
|
<string name="revanced_hide_related_videos_summary_off">يتم عرض الفيديوهات ذات الصلة</string>
|
||||||
<string name="revanced_hide_image_shelf_title">إخفاء رفوف الصور في نتائج البحث</string>
|
<string name="revanced_hide_image_shelf_title">إخفاء رفوف الصور في نتائج البحث</string>
|
||||||
<string name="revanced_hide_image_shelf_summary_on">تم إخفاء رفوف الصورة</string>
|
<string name="revanced_hide_image_shelf_summary_on">تم إخفاء رفوف الصورة</string>
|
||||||
<string name="revanced_hide_image_shelf_summary_off">يتم عرض رفوف الصورة</string>
|
<string name="revanced_hide_image_shelf_summary_off">يتم عرض رفوف الصورة</string>
|
||||||
@@ -242,7 +299,7 @@ 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>
|
||||||
@@ -293,10 +350,10 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_custom_filter_toast_invalid_syntax">فلتر مخصص غير صالح: %s</string>
|
<string name="revanced_custom_filter_toast_invalid_syntax">فلتر مخصص غير صالح: %s</string>
|
||||||
<string name="revanced_hide_keyword_content_screen_title">إخفاء محتوى الكلمات الرئيسية</string>
|
<string name="revanced_hide_keyword_content_screen_title">إخفاء محتوى الكلمات الرئيسية</string>
|
||||||
<string name="revanced_hide_keyword_content_screen_summary">إخفاء فيديوهات البحث والموجز باستخدام فلاتر الكلمات المفتاحية</string>
|
<string name="revanced_hide_keyword_content_screen_summary">إخفاء فيديوهات البحث والموجز باستخدام فلاتر الكلمات المفتاحية</string>
|
||||||
<string name="revanced_hide_keyword_content_home_title">إخفاء مقاطع فيديو الصفحة الرئيسية بواسطة الكلمات المفتاحية</string>
|
<string name="revanced_hide_keyword_content_home_title">إخفاء فيديوهات الصفحة الرئيسية بواسطة الكلمات المفتاحية</string>
|
||||||
<string name="revanced_hide_keyword_content_home_summary_on">تتم تصفية مقاطع الفيديو في علامة التبويب \"الصفحة الرئيسية\" حسب الكلمات المفتاحية</string>
|
<string name="revanced_hide_keyword_content_home_summary_on">تتم تصفية الفيديوهات في علامة التبويب \"الصفحة الرئيسية\" حسب الكلمات المفتاحية</string>
|
||||||
<string name="revanced_hide_keyword_content_home_summary_off">لا تتم تصفية مقاطع الفيديو في علامة التبويب \"الصفحة الرئيسية\" حسب الكلمات المفتاحية</string>
|
<string name="revanced_hide_keyword_content_home_summary_off">لا تتم تصفية الفيديوهات في علامة التبويب \"الصفحة الرئيسية\" حسب الكلمات المفتاحية</string>
|
||||||
<string name="revanced_hide_keyword_content_subscriptions_title">إخفاء مقاطع الفيديو الخاصة بالاشتراك عن طريق الكلمات المفتاحية</string>
|
<string name="revanced_hide_keyword_content_subscriptions_title">إخفاء الفيديوهات الخاصة بالاشتراك عن طريق الكلمات المفتاحية</string>
|
||||||
<string name="revanced_hide_keyword_content_subscriptions_summary_on">يتم تصفية الفيديوهات في علامة التبويب الاشتراكات حسب الكلمات المفتاحية</string>
|
<string name="revanced_hide_keyword_content_subscriptions_summary_on">يتم تصفية الفيديوهات في علامة التبويب الاشتراكات حسب الكلمات المفتاحية</string>
|
||||||
<string name="revanced_hide_keyword_content_subscriptions_summary_off">لا يتم تصفية الفيديوهات في علامة التبويب الاشتراكات حسب الكلمات المفتاحية</string>
|
<string name="revanced_hide_keyword_content_subscriptions_summary_off">لا يتم تصفية الفيديوهات في علامة التبويب الاشتراكات حسب الكلمات المفتاحية</string>
|
||||||
<string name="revanced_hide_keyword_content_search_title">إخفاء نتائج البحث عن طريق الكلمات المفتاحية</string>
|
<string name="revanced_hide_keyword_content_search_title">إخفاء نتائج البحث عن طريق الكلمات المفتاحية</string>
|
||||||
@@ -445,6 +502,9 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_swipe_overlay_background_alpha_summary">قيمة شفافية خلفية واجهة التمرير</string>
|
<string name="revanced_swipe_overlay_background_alpha_summary">قيمة شفافية خلفية واجهة التمرير</string>
|
||||||
<string name="revanced_swipe_threshold_title">مقدار حد التمرير</string>
|
<string name="revanced_swipe_threshold_title">مقدار حد التمرير</string>
|
||||||
<string name="revanced_swipe_threshold_summary">الحد الأدنى من التمرير قبل اكتشاف الإيماءة</string>
|
<string name="revanced_swipe_threshold_summary">الحد الأدنى من التمرير قبل اكتشاف الإيماءة</string>
|
||||||
|
<string name="revanced_swipe_change_video_title">تمكين إيماءة التمرير لتغيير الفيديو</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_on">سيؤدي التمرير في وضع ملء الشاشة إلى التغيير للفيديو التالي/السابق</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_off">لن يؤدي التمرير في وضع ملء الشاشة إلى التغيير للفيديو التالي/السابق</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.autocaptions.autoCaptionsPatch">
|
<patch id="layout.autocaptions.autoCaptionsPatch">
|
||||||
<string name="revanced_auto_captions_title">تعطيل التَّرْجَمَة التلقائية</string>
|
<string name="revanced_auto_captions_title">تعطيل التَّرْجَمَة التلقائية</string>
|
||||||
@@ -516,14 +576,14 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_navigation_button_labels_summary_on">تم إخفاء التسميات</string>
|
<string name="revanced_hide_navigation_button_labels_summary_on">تم إخفاء التسميات</string>
|
||||||
<string name="revanced_hide_navigation_button_labels_summary_off">يتم عرض التسميات</string>
|
<string name="revanced_hide_navigation_button_labels_summary_off">يتم عرض التسميات</string>
|
||||||
<string name="revanced_disable_translucent_status_bar_title">تعطيل شريط الحالة الشفاف</string>
|
<string name="revanced_disable_translucent_status_bar_title">تعطيل شريط الحالة الشفاف</string>
|
||||||
<string name="revanced_disable_translucent_status_bar_summary_on">شريط الحالة غير معتمة</string>
|
<string name="revanced_disable_translucent_status_bar_summary_on">شريط الحالة غير شفاف</string>
|
||||||
<string name="revanced_disable_translucent_status_bar_summary_off">شريط الحالة غير شفافة أو عميقة</string>
|
<string name="revanced_disable_translucent_status_bar_summary_off">شريط الحالة معتم أو شفاف</string>
|
||||||
<string name="revanced_disable_translucent_navigation_bar_light_title">تعطيل شريط التنقل الشفاف الفاتح</string>
|
<string name="revanced_disable_translucent_navigation_bar_light_title">تعطيل الشريط الشفاف الفاتح</string>
|
||||||
<string name="revanced_disable_translucent_navigation_bar_light_summary_on">شريط التنقل في الوضع الفاتح معتم</string>
|
<string name="revanced_disable_translucent_navigation_bar_light_summary_on">شريط التنقل في الوضع الفاتح غير شفاف</string>
|
||||||
<string name="revanced_disable_translucent_navigation_bar_light_summary_off">يكون شريط التنقل في الوضع الفاتح معتمًا أو نصف شفاف</string>
|
<string name="revanced_disable_translucent_navigation_bar_light_summary_off">شريط التنقل في الوضع الفاتح معتم او شفاف</string>
|
||||||
<string name="revanced_disable_translucent_navigation_bar_dark_title">تعطيل الشريط الداكنة</string>
|
<string name="revanced_disable_translucent_navigation_bar_dark_title">تعطيل الشريط الشفاف الداكن</string>
|
||||||
<string name="revanced_disable_translucent_navigation_bar_dark_summary_on">شريط التنقل في الوضع الداكن معتم</string>
|
<string name="revanced_disable_translucent_navigation_bar_dark_summary_on">شريط التنقل في الوضع الداكن غير شفاف</string>
|
||||||
<string name="revanced_disable_translucent_navigation_bar_dark_summary_off">شريط التطبيق المصوري الشفاف غير عميقة أو عميقة</string>
|
<string name="revanced_disable_translucent_navigation_bar_dark_summary_off">شريط التنقل في الوضع الداكن معتم او شفاف</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.hide.player.flyoutmenupanel.hidePlayerFlyoutMenuPatch">
|
<patch id="layout.hide.player.flyoutmenupanel.hidePlayerFlyoutMenuPatch">
|
||||||
<string name="revanced_hide_player_flyout_title">القائمة المنبثقة</string>
|
<string name="revanced_hide_player_flyout_title">القائمة المنبثقة</string>
|
||||||
@@ -628,15 +688,18 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_shorts_player_screen_summary">إخفاء أو عرض المكونات في مشغل Shorts</string>
|
<string name="revanced_shorts_player_screen_summary">إخفاء أو عرض المكونات في مشغل Shorts</string>
|
||||||
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
||||||
<string name="revanced_hide_shorts_home_title">إخفاء Shorts في موجز الصفحة الرئيسية</string>
|
<string name="revanced_hide_shorts_home_title">إخفاء Shorts في موجز الصفحة الرئيسية</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_on">تم إخفاء Shorts في موجز الصفحة الرئيسية</string>
|
<string name="revanced_hide_shorts_home_summary_on">مخفية في الصفحة الرئيسية والفيديوهات ذات الصلة</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_off">يتم عرض Shorts في موجز الصفحة الرئيسية</string>
|
<string name="revanced_hide_shorts_home_summary_off">تعرض في الصفحة الرئيسية والفيديوهات ذات الصلة</string>
|
||||||
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
||||||
<string name="revanced_hide_shorts_subscriptions_title">إخفاء Shorts في موجز الاشتراكات</string>
|
<string name="revanced_hide_shorts_subscriptions_title">إخفاء Shorts في موجز الاشتراكات</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_on">تم إخفاء Shorts في موجز الاشتراكات</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_on">مخفية في موجز الاشتراكات</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_off">يتم عرض Shorts في موجز الاشتراكات</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_off">تعرض في موجز الاشتراكات</string>
|
||||||
<string name="revanced_hide_shorts_search_title">إخفاء Shorts في نتائج البحث</string>
|
<string name="revanced_hide_shorts_search_title">إخفاء Shorts في نتائج البحث</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_on">تم إخفاء Shorts في نتائج البحث</string>
|
<string name="revanced_hide_shorts_search_summary_on">مخفية في نتائج البحث</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_off">يتم عرض Shorts في نتائج البحث</string>
|
<string name="revanced_hide_shorts_search_summary_off">تعرض في نتائج البحث</string>
|
||||||
|
<string name="revanced_hide_shorts_history_title">إخفاء Shorts في سجل المشاهدة</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_on">مخفية في سجل المشاهدة</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_off">تعرض في سجل المشاهدة</string>
|
||||||
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
||||||
<string name="revanced_hide_shorts_join_button_title">إخفاء زر الانضمام</string>
|
<string name="revanced_hide_shorts_join_button_title">إخفاء زر الانضمام</string>
|
||||||
<string name="revanced_hide_shorts_join_button_summary_on">تم إخفاء زر الانضمام</string>
|
<string name="revanced_hide_shorts_join_button_summary_on">تم إخفاء زر الانضمام</string>
|
||||||
@@ -738,8 +801,15 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_player_popup_panels_summary_on">تم إخفاء لوحات المشغل المنبثقة</string>
|
<string name="revanced_hide_player_popup_panels_summary_on">تم إخفاء لوحات المشغل المنبثقة</string>
|
||||||
<string name="revanced_hide_player_popup_panels_summary_off">يتم عرض لوحات المشغل المنبثقة</string>
|
<string name="revanced_hide_player_popup_panels_summary_off">يتم عرض لوحات المشغل المنبثقة</string>
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.player.fullscreen.exitFullscreenPatch">
|
||||||
|
<string name="revanced_exit_fullscreen_title">الخروج من وضع ملء الشاشة عند انتهاء الفيديو</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_1">معطل</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_2">بالطول</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_3">بالعرض</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_4">بالطول والعرض</string>
|
||||||
|
</patch>
|
||||||
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_title">فتح مقاطع الفيديو في ملء الشاشة</string>
|
<string name="revanced_open_videos_fullscreen_portrait_title">فتح الفيديوهات في ملء الشاشة</string>
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_summary_on">يتم فتح الفيديوهات في وضع ملء الشاشة</string>
|
<string name="revanced_open_videos_fullscreen_portrait_summary_on">يتم فتح الفيديوهات في وضع ملء الشاشة</string>
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_summary_off">لا يتم فتح الفيديوهات في وضع ملء الشاشة</string>
|
<string name="revanced_open_videos_fullscreen_portrait_summary_off">لا يتم فتح الفيديوهات في وضع ملء الشاشة</string>
|
||||||
</patch>
|
</patch>
|
||||||
@@ -758,12 +828,12 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_ryd_failure_ryd_enabled_while_playing_video_then_user_voted">أعد تحميل الفيديو للتصويت بـ Return YouTube Dislike</string>
|
<string name="revanced_ryd_failure_ryd_enabled_while_playing_video_then_user_voted">أعد تحميل الفيديو للتصويت بـ Return YouTube Dislike</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">يتم عرض لم يعجني في فيديوهات Shorts</string>
|
||||||
<string name="revanced_ryd_shorts_summary_on_disclaimer">"إبداءات لم يعجبني التي تظهر على فيديوهات Shorts
|
<string name="revanced_ryd_shorts_summary_on_disclaimer">"إبداءات لم يعجبني التي تظهر على فيديوهات Shorts
|
||||||
|
|
||||||
التقييد: قد لا تظهر إبداءات لم يعجبني في وضع التصفح المتخفي"</string>
|
التقييد: قد لا تظهر إبداءات لم يعجبني في وضع التصفح المتخفي"</string>
|
||||||
<string name="revanced_ryd_shorts_summary_off">تم إخفاء لم يعجني في مقاطع Shorts</string>
|
<string name="revanced_ryd_shorts_summary_off">تم إخفاء لم يعجني في فيديوهات Shorts</string>
|
||||||
<string name="revanced_ryd_dislike_percentage_title">لم يعجبني كــ نسبة مئوية</string>
|
<string name="revanced_ryd_dislike_percentage_title">لم يعجبني كــ نسبة مئوية</string>
|
||||||
<string name="revanced_ryd_dislike_percentage_summary_on">يعرض عدد لم يعجبني كـ نسبة مئوية</string>
|
<string name="revanced_ryd_dislike_percentage_summary_on">يعرض عدد لم يعجبني كـ نسبة مئوية</string>
|
||||||
<string name="revanced_ryd_dislike_percentage_summary_off">يعرض عدد لم يعجبني كـ رَقَم</string>
|
<string name="revanced_ryd_dislike_percentage_summary_off">يعرض عدد لم يعجبني كـ رَقَم</string>
|
||||||
@@ -816,7 +886,7 @@ Second \"item\" text"</string>
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.sponsorblock.sponsorBlockResourcePatch">
|
<patch id="layout.sponsorblock.sponsorBlockResourcePatch">
|
||||||
<string name="revanced_sb_enable_sb">تمكين SponsorBlock</string>
|
<string name="revanced_sb_enable_sb">تمكين SponsorBlock</string>
|
||||||
<string name="revanced_sb_enable_sb_sum">مانِع الرُعَاة هو نظام جماعي لتخطي الأجزاء المُمِلَّة في مقاطع YouTube</string>
|
<string name="revanced_sb_enable_sb_sum">SponsorBlock مانِع الرُعَاة هو نظام جماعي لتخطي الأجزاء المُمِلَّة في مقاطع YouTube</string>
|
||||||
<string name="revanced_sb_appearance_category">المظهر</string>
|
<string name="revanced_sb_appearance_category">المظهر</string>
|
||||||
<string name="revanced_sb_enable_voting">عرض زر التصويت</string>
|
<string name="revanced_sb_enable_voting">عرض زر التصويت</string>
|
||||||
<string name="revanced_sb_enable_voting_sum_on">يتم عرض زر التصويت على المقطع</string>
|
<string name="revanced_sb_enable_voting_sum_on">يتم عرض زر التصويت على المقطع</string>
|
||||||
@@ -895,7 +965,7 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_sb_segments_filler">خارج الموضوع/النكات</string>
|
<string name="revanced_sb_segments_filler">خارج الموضوع/النكات</string>
|
||||||
<string name="revanced_sb_segments_filler_sum">تم إضافة مشاهد ملتقطة خارج الموضوع أو الفكاهة التي ليست مطلوبة لفهم المحتوى الرئيسي للفيديو. لا تتضمن مقاطع توفر تَعبِير أو تفاصيل الخلفية</string>
|
<string name="revanced_sb_segments_filler_sum">تم إضافة مشاهد ملتقطة خارج الموضوع أو الفكاهة التي ليست مطلوبة لفهم المحتوى الرئيسي للفيديو. لا تتضمن مقاطع توفر تَعبِير أو تفاصيل الخلفية</string>
|
||||||
<string name="revanced_sb_segments_nomusic">الموسيقى: مقطع غير موسيقي</string>
|
<string name="revanced_sb_segments_nomusic">الموسيقى: مقطع غير موسيقي</string>
|
||||||
<string name="revanced_sb_segments_nomusic_sum">فقط للاستخدام في مقاطع الفيديو الموسيقية. أقسام مقاطع الفيديو الموسيقية بدون موسيقى، والتي لم يتم تغطيتها بالفعل من قبل فئة أخرى</string>
|
<string name="revanced_sb_segments_nomusic_sum">فقط للاستخدام في المقاطع الموسيقية. أقسام المقاطع الموسيقية بدون موسيقى، والتي لم يتم تغطيتها بالفعل من قبل فئة أخرى</string>
|
||||||
<string name="revanced_sb_skip_button_compact">تخطي</string>
|
<string name="revanced_sb_skip_button_compact">تخطي</string>
|
||||||
<string name="revanced_sb_skip_button_compact_highlight">الأبرز</string>
|
<string name="revanced_sb_skip_button_compact_highlight">الأبرز</string>
|
||||||
<string name="revanced_sb_skip_button_sponsor">تخطي الراعي</string>
|
<string name="revanced_sb_skip_button_sponsor">تخطي الراعي</string>
|
||||||
@@ -1006,6 +1076,23 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_sb_reset">إعادة التعيين</string>
|
<string name="revanced_sb_reset">إعادة التعيين</string>
|
||||||
<string name="revanced_sb_about">لمحة</string>
|
<string name="revanced_sb_about">لمحة</string>
|
||||||
<string name="revanced_sb_about_api_sum">يتم توفير البيانات بواسطة SponsorBlock API. انقر هنا لمعرفة المزيد ومشاهدة التنزيلات لمنصات أخرى</string>
|
<string name="revanced_sb_about_api_sum">يتم توفير البيانات بواسطة SponsorBlock API. انقر هنا لمعرفة المزيد ومشاهدة التنزيلات لمنصات أخرى</string>
|
||||||
|
</patch>
|
||||||
|
<patch id="layout.formfactor.changeFormFactorPatch">
|
||||||
|
<string name="revanced_change_form_factor_title">شكل نموذج التخطيط</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_1">الافتراضي</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_4">Automotive</string>
|
||||||
|
<string name="revanced_change_form_factor_user_dialog_message">"تتضمن التغييرات:
|
||||||
|
|
||||||
|
تخطيط الجهاز اللوحي
|
||||||
|
• إخفاء منشورات المجتمع
|
||||||
|
|
||||||
|
تخطيط Automotive
|
||||||
|
• إخفاء قائمة سجل المشاهدة
|
||||||
|
• استعادة علامة التبويب \"استكشاف\"
|
||||||
|
• فتح فيديوهات 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>
|
||||||
@@ -1020,6 +1107,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>
|
||||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
<!-- '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_1">18.33.40 - استعادة RYD على Shorts بوضع التخفي</string>
|
||||||
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - استعادة قائمة سرعة الفيديو العريضة & الجودة</string>
|
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - استعادة قائمة سرعة الفيديو العريضة & الجودة</string>
|
||||||
@@ -1050,10 +1138,10 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_disable_resuming_shorts_player_summary_off">سيتم استئناف تشغيل مشغل Shorts عند بدء تشغيل التطبيق</string>
|
<string name="revanced_disable_resuming_shorts_player_summary_off">سيتم استئناف تشغيل مشغل Shorts عند بدء تشغيل التطبيق</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
|
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
|
||||||
<string name="revanced_shorts_player_type_title">فتح مقاطع الـShorts باستخدام</string>
|
<string name="revanced_shorts_player_type_title">فتح فيديوهات Shorts باستخدام</string>
|
||||||
<string name="revanced_shorts_player_type_shorts">مشغل Shorts</string>
|
<string name="revanced_shorts_player_type_shorts">مشغل Shorts</string>
|
||||||
<string name="revanced_shorts_player_type_regular_player">مشغل عادي</string>
|
<string name="revanced_shorts_player_type_regular_player">المشغل العادي</string>
|
||||||
<string name="revanced_shorts_player_type_regular_player_fullscreen">شاشة كاملة - مشغل عادي</string>
|
<string name="revanced_shorts_player_type_regular_player_fullscreen">المشغل العادي في وضع ملء الشاشة</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
|
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
|
||||||
<string name="revanced_shorts_autoplay_title">التشغيل التلقائي لفيديوهات Shorts</string>
|
<string name="revanced_shorts_autoplay_title">التشغيل التلقائي لفيديوهات Shorts</string>
|
||||||
@@ -1063,12 +1151,6 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_shorts_autoplay_background_summary_on">سيتم تشغيل فيديوهات Shorts تلقائيًا في الخلفية</string>
|
<string name="revanced_shorts_autoplay_background_summary_on">سيتم تشغيل فيديوهات Shorts تلقائيًا في الخلفية</string>
|
||||||
<string name="revanced_shorts_autoplay_background_summary_off">سيتم تكرار فيديوهات Shorts في الخلفية</string>
|
<string name="revanced_shorts_autoplay_background_summary_off">سيتم تكرار فيديوهات Shorts في الخلفية</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.tablet.enableTabletLayoutPatch">
|
|
||||||
<string name="revanced_tablet_layout_title">تمكين تصميم الجهاز اللوحي</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_on">تم تمكين تصميم الجهاز اللوحي</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_off">تم تعطيل تصميم الجهاز اللوحي</string>
|
|
||||||
<string name="revanced_tablet_layout_user_dialog_message">لا تظهر منشورات المجتمع على تخطيطات الجهاز اللوحي</string>
|
|
||||||
</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>
|
||||||
@@ -1166,7 +1248,7 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_alt_thumbnail_stills_about_title">لقطات الفيديو الثابتة</string>
|
<string name="revanced_alt_thumbnail_stills_about_title">لقطات الفيديو الثابتة</string>
|
||||||
<string name="revanced_alt_thumbnail_stills_about_summary">يتم التقاط اللقطات الثابتة من بداية/وسط/نهاية كل فيديو. هذه الصور مدمجة في YouTube ولا يتم استخدام أي واجهة برمجة تطبيقات خارجية</string>
|
<string name="revanced_alt_thumbnail_stills_about_summary">يتم التقاط اللقطات الثابتة من بداية/وسط/نهاية كل فيديو. هذه الصور مدمجة في YouTube ولا يتم استخدام أي واجهة برمجة تطبيقات خارجية</string>
|
||||||
<string name="revanced_alt_thumbnail_stills_fast_title">استخدم اللقطات الثابتة السريعة</string>
|
<string name="revanced_alt_thumbnail_stills_fast_title">استخدم اللقطات الثابتة السريعة</string>
|
||||||
<string name="revanced_alt_thumbnail_stills_fast_summary_on">استخدام اللقطات متوسطة الجودة. سيتم تحميل المُصغَّرات بشكل أسرع، ولكن البث المباشر و المقاطع التي لم يتم إصدارها أو القديمة جدًا قد تعرض مُصغَّرات فارغة</string>
|
<string name="revanced_alt_thumbnail_stills_fast_summary_on">استخدام اللقطات متوسطة الجودة. سيتم تحميل المُصغَّرات بشكل أسرع، ولكن البث المباشر و الفيديوهات التي لم يتم إصدارها أو القديمة جدًا قد تعرض مُصغَّرات فارغة</string>
|
||||||
<string name="revanced_alt_thumbnail_stills_fast_summary_off">استخدام لقطات الفيديو الثابتة بجودة عالية</string>
|
<string name="revanced_alt_thumbnail_stills_fast_summary_off">استخدام لقطات الفيديو الثابتة بجودة عالية</string>
|
||||||
<string name="revanced_alt_thumbnail_stills_time_title">وقت الفيديو لأخذ اللقطات الثابتة منه</string>
|
<string name="revanced_alt_thumbnail_stills_time_title">وقت الفيديو لأخذ اللقطات الثابتة منه</string>
|
||||||
<string name="revanced_alt_thumbnail_stills_time_entry_1">بداية الفيديو</string>
|
<string name="revanced_alt_thumbnail_stills_time_entry_1">بداية الفيديو</string>
|
||||||
@@ -1232,12 +1314,13 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_force_original_audio_title">فرض الصوت الأصلي</string>
|
<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>
|
||||||
|
<string name="revanced_force_original_audio_not_available">لاستخدام هذه الميزة، قم بتغيير محاكاة بث المحتوى إلى نوع العميل iOS</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
<string name="revanced_video_quality_default_entry_1">تلقائي</string>
|
<string name="revanced_video_quality_default_entry_1">تلقائي</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_title">تذكر تغييرات جودة الفيديو</string>
|
<string name="revanced_remember_video_quality_last_selected_title">تذكر تغييرات جودة الفيديو</string>
|
||||||
<string name="revanced_remember_video_quality_last_selected_summary_on">تنطبق تغييرات الجودة على جميع مقاطع الفيديو</string>
|
<string name="revanced_remember_video_quality_last_selected_summary_on">تنطبق تغييرات الجودة على جميع الفيديوهات</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>
|
||||||
@@ -1259,6 +1342,8 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_custom_playback_speeds_invalid">يجب أن تكون سرعات التشغيل المخصصة أقل من %s</string>
|
<string name="revanced_custom_playback_speeds_invalid">يجب أن تكون سرعات التشغيل المخصصة أقل من %s</string>
|
||||||
<string name="revanced_custom_playback_speeds_parse_exception">سرعة التشغيل المخصصة غير صالحة</string>
|
<string name="revanced_custom_playback_speeds_parse_exception">سرعة التشغيل المخصصة غير صالحة</string>
|
||||||
<string name="revanced_custom_playback_speeds_auto">تلقائي</string>
|
<string name="revanced_custom_playback_speeds_auto">تلقائي</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_title">\"سرعة النقر مع الاستمرار المخصصة\"</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_summary">سرعة التشغيل بين 0-8</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
||||||
<string name="revanced_remember_playback_speed_last_selected_title">تذكر التغيرات في سرعة التشغيل</string>
|
<string name="revanced_remember_playback_speed_last_selected_title">تذكر التغيرات في سرعة التشغيل</string>
|
||||||
@@ -1287,74 +1372,27 @@ Second \"item\" text"</string>
|
|||||||
قد لا يعمل تشغيل الفيديو"</string>
|
قد لا يعمل تشغيل الفيديو"</string>
|
||||||
<string name="revanced_spoof_video_streams_user_dialog_message">إيقاف تشغيل هذا الإعداد قد يسبب مشاكل في تشغيل الفيديو.</string>
|
<string name="revanced_spoof_video_streams_user_dialog_message">إيقاف تشغيل هذا الإعداد قد يسبب مشاكل في تشغيل الفيديو.</string>
|
||||||
<string name="revanced_spoof_video_streams_client_type_title">العميل الافتراضي</string>
|
<string name="revanced_spoof_video_streams_client_type_title">العميل الافتراضي</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">فرض AVC (H.264)</string>
|
<!-- 'no auth' means no authentication -->
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">تم فرض ترميز الفيديو على AVC (H.264)</string>
|
<string name="revanced_spoof_video_streams_client_type_android_vr_no_auth">Android VR (بدون مصادقة)</string>
|
||||||
|
<string name="revanced_spoof_video_streams_ios_force_avc_title">فرض iOS AVC (H.264)</string>
|
||||||
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">يتم فرض ترميز فيديو على AVC (H.264)</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">يتم تحديد ترميز الفيديو تلقائيًا</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">يتم تحديد ترميز الفيديو تلقائيًا</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"قد يؤدي تمكين هذا إلى تحسين عمر البطارية وإصلاح مشكلة تقطيع التشغيل.
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"قد يؤدي تمكين هذا إلى تحسين عمر البطارية وإصلاح تقطيع التشغيل.
|
||||||
|
|
||||||
يتمتع تنسيق AVC بدقة قصوى تبلغ 1080P، برنامج ترميز الصوت Opus غير متوفر، وسيستخدم تشغيل الفيديو المزيد من بيانات الإنترنت مقارنةً بتنسيق VP9 أو AV1."</string>
|
AVC لديه حد أقصى للدقة 1080p، لا يتوفر ترميز الصوت Opus، وسوف يستخدم تشغيل الفيديو بيانات إنترنت أكثر من VP9 أو AV1."</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">التأثيرات الجانبية لمحاكاة iOS</string>
|
<string name="revanced_spoof_video_streams_about_ios_tv_title">الآثار الجانبية لمحاكاة هوية iOS</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">"• لا يمكن تشغيل مقاطع فيديو الأطفال الخاصة.
|
<string name="revanced_spoof_video_streams_about_ios_tv_summary">"• قد لا يتم تشغيل الأفلام أو الفيديوهات المدفوعة
|
||||||
• تنتهي مقاطع الفيديو مبكرًا بمقدار 1 ثانية."</string>
|
• مستوى الصوت الثابت غير متوفر
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">التأثيرات الجانبية لمحاكاة Android VR</string>
|
• تنتهي الفيديوهات قبل ب 1 ثانية"</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• مقطع فيديو الأطفال لتعمل تشغيل
|
<string name="revanced_spoof_video_streams_about_android_title">الآثار الجانبية لمحاكاة هوية Android</string>
|
||||||
• قائمة قائمة الصوت مفقودة
|
<string name="revanced_spoof_video_streams_about_android_summary">"• قائمة المقطع الصوتي مفقودة
|
||||||
• لا يتوفر بستوي متوفر
|
• مستوى الصوت الثابت غير متاح
|
||||||
• لا يتوفر بالصوت الأصلي لا يتوفر الأصلي"</string>
|
• فرض الصوت الأصلي غير متوفر"</string>
|
||||||
<string name="revanced_spoof_video_streams_language_title">لغة البث الصوتي الافتراضية</string>
|
<string name="revanced_spoof_video_streams_about_no_av1">• لا يوجد ترميز الفيديو AV1</string>
|
||||||
<string name="revanced_spoof_video_streams_language_DEFAULT">لغة التطبيق</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_title">عرض في إحصاءات تقنية</string>
|
||||||
<string name="revanced_spoof_video_streams_language_AR">العربية</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_on">يتم عرض نوع العميل في إحصاءات تقنية</string>
|
||||||
<string name="revanced_spoof_video_streams_language_AZ">Azerbaijani</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">تم إخفاء نوع العميل في إحصاءات تقنية</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BG">Bulgarian</string>
|
<string name="revanced_spoof_video_streams_language_title">لغة البث الصوتي الافتراضية للواقع الافتراضي VR</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BN">Bengali</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_CA">Catalan</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_CS">Czech</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_DA">Danish</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_DE">German</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EL">Greek</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EN">English</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ES">Spanish</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ET">Estonian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FA">فارسى</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FI">Finnish</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FR">French</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_GU">Gujarati</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HI">Hindi</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HR">Croatian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HU">Hungarian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ID"> Indonesian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_IT">Italian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_JA">Japanese</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KK">Kazakh</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KO">Korean</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LT">Lithuanian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LV">Latvian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MK">Macedonian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MN">Mongolian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MR">Marathi</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MS">Malay</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MY">Burmese</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_NL">Dutch</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_OR">Odia</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PA">Punjabi</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PL">Polish</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_BR">Portuguese (Brazil)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_PT">Portuguese (Portugal)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RO">Romanian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RU">Russian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SK">Slovak</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SL">Slovene</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SR">Serbian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SV">Swedish</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SW">Swahili</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TA">Tamil</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TE">Telugu</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TH">Thai</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TR">Turkish</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UK">Ukrainian</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UR">Urdu</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_VI">Vietnamese</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ZH">Chinese</string>
|
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -136,6 +136,8 @@ Second \"item\" text"</string>
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.panels.popup.playerPopupPanelsPatch">
|
<patch id="layout.panels.popup.playerPopupPanelsPatch">
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.player.fullscreen.exitFullscreenPatch">
|
||||||
|
</patch>
|
||||||
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.player.overlay.customPlayerOverlayOpacityResourcePatch">
|
<patch id="layout.player.overlay.customPlayerOverlayOpacityResourcePatch">
|
||||||
@@ -155,6 +157,8 @@ Second \"item\" text"</string>
|
|||||||
<!-- 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. -->
|
||||||
<!-- 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>
|
||||||
<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 -->
|
||||||
@@ -168,8 +172,6 @@ Second \"item\" text"</string>
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
|
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.tablet.enableTabletLayoutPatch">
|
|
||||||
</patch>
|
|
||||||
<patch id="layout.miniplayer.miniplayerPatch">
|
<patch id="layout.miniplayer.miniplayerPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.theme.themePatch">
|
<patch id="layout.theme.themePatch">
|
||||||
@@ -220,6 +222,7 @@ Second \"item\" text"</string>
|
|||||||
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
|
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
|
||||||
|
<!-- 'no auth' means no authentication -->
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -22,8 +22,8 @@ Second \"item\" text"</string>
|
|||||||
<resources>
|
<resources>
|
||||||
<app id="shared">
|
<app id="shared">
|
||||||
<patch id="misc.checks.checkEnvironmentPatch">
|
<patch id="misc.checks.checkEnvironmentPatch">
|
||||||
<string name="revanced_check_environment_failed_title">\"Правядзенне праверкі асяроддзя не ўдалося\"</string>
|
<string name="revanced_check_environment_failed_title">Праверкі не пройдзены</string>
|
||||||
<string name="revanced_check_environment_dialog_open_official_source_button">\"Адкрыць афіцыйны вэб-сайт\"</string>
|
<string name="revanced_check_environment_dialog_open_official_source_button">Адкрыць афіцыйны вэб-сайт</string>
|
||||||
<string name="revanced_check_environment_dialog_ignore_button">Ігнараваць</string>
|
<string name="revanced_check_environment_dialog_ignore_button">Ігнараваць</string>
|
||||||
<string name="revanced_check_environment_failed_message"><h5>Гэта дадатак відавочна не з\'яўляецца патчам.</h5><br>Гэта дадатак можа працаваць няправільна, а таксама можа быць <b>небяспечным або нават небяспечным у выкарыстанні</b>.<br><br>Гэтыя праверкі азначаюць, што гэта дадатак было загаддзя перароблена або атрымана ад кагосьці іншага:<br><br><small>%1$s</small><br>Настойліва рэкамендуецца <b>выдаліць гэты дадатак і перарабіць яго самастойна</b>, каб пераканацца, што вы выкарыстоўваеце правераны і бяспечны дадатак.<p><br>Калі ігнараваць, гэта папярэджанне будзе паказана толькі два разы.</string>
|
<string name="revanced_check_environment_failed_message"><h5>Гэта дадатак відавочна не з\'яўляецца патчам.</h5><br>Гэта дадатак можа працаваць няправільна, а таксама можа быць <b>небяспечным або нават небяспечным у выкарыстанні</b>.<br><br>Гэтыя праверкі азначаюць, што гэта дадатак было загаддзя перароблена або атрымана ад кагосьці іншага:<br><br><small>%1$s</small><br>Настойліва рэкамендуецца <b>выдаліць гэты дадатак і перарабіць яго самастойна</b>, каб пераканацца, што вы выкарыстоўваеце правераны і бяспечны дадатак.<p><br>Калі ігнараваць, гэта папярэджанне будзе паказана толькі два разы.</string>
|
||||||
<string name="revanced_check_environment_not_same_patching_device">Адкарэктавана на іншай прыладзе</string>
|
<string name="revanced_check_environment_not_same_patching_device">Адкарэктавана на іншай прыладзе</string>
|
||||||
@@ -33,6 +33,7 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_check_environment_not_near_patch_time_invalid">Дата стварэння APK пашкоджана</string>
|
<string name="revanced_check_environment_not_near_patch_time_invalid">Дата стварэння APK пашкоджана</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.settings.settingsResourcePatch">
|
<patch id="misc.settings.settingsResourcePatch">
|
||||||
|
<string name="revanced_settings_submenu_title">Налады</string>
|
||||||
<string name="revanced_settings_title">ReVanced</string>
|
<string name="revanced_settings_title">ReVanced</string>
|
||||||
<string name="revanced_settings_confirm_user_dialog_title">Вы хочаце працягнуць?</string>
|
<string name="revanced_settings_confirm_user_dialog_title">Вы хочаце працягнуць?</string>
|
||||||
<string name="revanced_settings_reset">Скінуць</string>
|
<string name="revanced_settings_reset">Скінуць</string>
|
||||||
@@ -43,6 +44,62 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_settings_import_reset">Налады ReVanced скінуты да стандартных</string>
|
<string name="revanced_settings_import_reset">Налады ReVanced скінуты да стандартных</string>
|
||||||
<string name="revanced_settings_import_success">Імпартавана %d налад</string>
|
<string name="revanced_settings_import_success">Імпартавана %d налад</string>
|
||||||
<string name="revanced_settings_import_failure_parse">Памылка імпарту: %s</string>
|
<string name="revanced_settings_import_failure_parse">Памылка імпарту: %s</string>
|
||||||
|
<string name="revanced_language_title">Мова ReVanced</string>
|
||||||
|
<string name="revanced_language_user_dialog_message">"Пераклады для некаторых моў могуць быць адсутнымі або няпоўнымі.
|
||||||
|
|
||||||
|
Каб дадаць новыя мовы, наведайце translate.revanced.app"</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. -->
|
||||||
@@ -77,13 +134,16 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_settings_screen_01_ads_title">Аб\"явы</string>
|
<string name="revanced_settings_screen_01_ads_title">Аб\"явы</string>
|
||||||
<string name="revanced_settings_screen_02_alt_thumbnails_title">Альтэрнатыўныя мініяцюры</string>
|
<string name="revanced_settings_screen_02_alt_thumbnails_title">Альтэрнатыўныя мініяцюры</string>
|
||||||
<string name="revanced_settings_screen_03_feed_title">Карміць</string>
|
<string name="revanced_settings_screen_03_feed_title">Карміць</string>
|
||||||
<string name="revanced_settings_screen_04_player_title">Гулец</string>
|
<string name="revanced_settings_screen_04_general_title">Агульнае</string>
|
||||||
<string name="revanced_settings_screen_05_general_title">Генеральная планіроўка</string>
|
<string name="revanced_settings_screen_05_player_title">Плэер</string>
|
||||||
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
||||||
<string name="revanced_settings_screen_07_seekbar_title">Панэль пошуку</string>
|
<string name="revanced_settings_screen_07_seekbar_title">Панэль пошуку</string>
|
||||||
<string name="revanced_settings_screen_08_swipe_controls_title">Элементы кіравання пальцам</string>
|
<string name="revanced_settings_screen_08_swipe_controls_title">Элементы кіравання пальцам</string>
|
||||||
<string name="revanced_settings_screen_11_misc_title">Рознае</string>
|
<string name="revanced_settings_screen_11_misc_title">Рознае</string>
|
||||||
<string name="revanced_settings_screen_12_video_title">Відэа</string>
|
<string name="revanced_settings_screen_12_video_title">Відэа</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_title">Аднавіць старое меню налад</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_summary_on">Старыя меню налад паказваюцца</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_summary_off">Старыя меню налад не паказваюцца</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
||||||
<string name="revanced_shorts_disable_background_playback_title">Адключыць прайграванне Shorts у фонавым</string>
|
<string name="revanced_shorts_disable_background_playback_title">Адключыць прайграванне Shorts у фонавым</string>
|
||||||
@@ -446,6 +506,9 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_swipe_overlay_background_alpha_summary">Бачнасць фону накладання пальцам</string>
|
<string name="revanced_swipe_overlay_background_alpha_summary">Бачнасць фону накладання пальцам</string>
|
||||||
<string name="revanced_swipe_threshold_title">Парог велічыні пальцам</string>
|
<string name="revanced_swipe_threshold_title">Парог велічыні пальцам</string>
|
||||||
<string name="revanced_swipe_threshold_summary">Велічыня парогавага значэння для правядзення пальцам</string>
|
<string name="revanced_swipe_threshold_summary">Велічыня парогавага значэння для правядзення пальцам</string>
|
||||||
|
<string name="revanced_swipe_change_video_title">Уключыць зьмену відэа праз правядзенне пальцам</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_on">Правядзенне пальцам у рэжыме поўнага экрана зьменіць відэа на наступнае/папярэдняе</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_off">Правядзенне пальцам у рэжыме поўнага экрана не зьменіць відэа на наступнае/папярэдняе</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.autocaptions.autoCaptionsPatch">
|
<patch id="layout.autocaptions.autoCaptionsPatch">
|
||||||
<string name="revanced_auto_captions_title">Адключыць аўтаматычныя цітры</string>
|
<string name="revanced_auto_captions_title">Адключыць аўтаматычныя цітры</string>
|
||||||
@@ -629,15 +692,18 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_shorts_player_screen_summary">Схаваць або паказаць кампаненты ў прайгравальніку Shorts</string>
|
<string name="revanced_shorts_player_screen_summary">Схаваць або паказаць кампаненты ў прайгравальніку Shorts</string>
|
||||||
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
||||||
<string name="revanced_hide_shorts_home_title">Схаваць шорты ў хатняй стужцы</string>
|
<string name="revanced_hide_shorts_home_title">Схаваць шорты ў хатняй стужцы</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_on">Shorts у стужцы хатняй старонкі схаваны</string>
|
<string name="revanced_hide_shorts_home_summary_on">Схаваны ў стужцы і звязаных відэа</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_off">Shorts у стужцы хатняй старонкі паказаны</string>
|
<string name="revanced_hide_shorts_home_summary_off">Паказаны ў стужцы і звязаных відэа</string>
|
||||||
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
||||||
<string name="revanced_hide_shorts_subscriptions_title">Схаваць Shorts у стужцы падпіскі</string>
|
<string name="revanced_hide_shorts_subscriptions_title">Схаваць Shorts у стужцы падпіскі</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_on">Shorts у стужцы падпіскі схаваны</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_on">Схавана ў стужцы падпісак</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_off">Shorts у стужцы падпіскі паказаны</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_off">Паказана ў стужцы падпісак</string>
|
||||||
<string name="revanced_hide_shorts_search_title">Схаваць Shorts у выніках пошуку</string>
|
<string name="revanced_hide_shorts_search_title">Схаваць Shorts у выніках пошуку</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_on">Shorts у выніках пошуку схаваны</string>
|
<string name="revanced_hide_shorts_search_summary_on">Схаваны ў выніках пошуку</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_off">Shorts у выніках пошуку паказаны</string>
|
<string name="revanced_hide_shorts_search_summary_off">Паказана ў выніках пошуку</string>
|
||||||
|
<string name="revanced_hide_shorts_history_title">Схаваць Shorts з гісторыі праглядаў</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_on">Схавана ў гісторыі праглядаў</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_off">Паказаны ў гісторыі праглядаў</string>
|
||||||
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
||||||
<string name="revanced_hide_shorts_join_button_title">Схаваць кнопку далучыцца</string>
|
<string name="revanced_hide_shorts_join_button_title">Схаваць кнопку далучыцца</string>
|
||||||
<string name="revanced_hide_shorts_join_button_summary_on">Кнопка «Далучыцца» схавана</string>
|
<string name="revanced_hide_shorts_join_button_summary_on">Кнопка «Далучыцца» схавана</string>
|
||||||
@@ -668,8 +734,8 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_shorts_use_template_button_summary_on">Кнопка выкарыстання шаблону схавана</string>
|
<string name="revanced_hide_shorts_use_template_button_summary_on">Кнопка выкарыстання шаблону схавана</string>
|
||||||
<string name="revanced_hide_shorts_use_template_button_summary_off">Кнопка выкарыстання шаблону паказана</string>
|
<string name="revanced_hide_shorts_use_template_button_summary_off">Кнопка выкарыстання шаблону паказана</string>
|
||||||
<string name="revanced_hide_shorts_upcoming_button_title">Схаваць кнопку будучых</string>
|
<string name="revanced_hide_shorts_upcoming_button_title">Схаваць кнопку будучых</string>
|
||||||
<string name="revanced_hide_shorts_upcoming_button_summary_on">Кнопка ⬆️Будущие ролики⬆️ скрыта</string>
|
<string name="revanced_hide_shorts_upcoming_button_summary_on">Кнопка Будущие ролики скрыта</string>
|
||||||
<string name="revanced_hide_shorts_upcoming_button_summary_off">Кнопка ⬆️Будущие ролики⬆️ отображается</string>
|
<string name="revanced_hide_shorts_upcoming_button_summary_off">Кнопка Будущие ролики отображается</string>
|
||||||
<string name="revanced_hide_shorts_green_screen_button_title">Скрыть кнопку с зелёным экраном Shorts</string>
|
<string name="revanced_hide_shorts_green_screen_button_title">Скрыть кнопку с зелёным экраном Shorts</string>
|
||||||
<string name="revanced_hide_shorts_green_screen_button_summary_on">Кнопка с зелёным экраном Shorts скрыта</string>
|
<string name="revanced_hide_shorts_green_screen_button_summary_on">Кнопка с зелёным экраном Shorts скрыта</string>
|
||||||
<string name="revanced_hide_shorts_green_screen_button_summary_off">Кнопка с зелёным экраном Shorts отображается</string>
|
<string name="revanced_hide_shorts_green_screen_button_summary_off">Кнопка с зелёным экраном Shorts отображается</string>
|
||||||
@@ -739,6 +805,13 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_player_popup_panels_summary_on">Усплывальныя панэлі прайгравальніка схаваныя</string>
|
<string name="revanced_hide_player_popup_panels_summary_on">Усплывальныя панэлі прайгравальніка схаваныя</string>
|
||||||
<string name="revanced_hide_player_popup_panels_summary_off">Паказваюцца ўсплывальныя панэлі прайгравальніка</string>
|
<string name="revanced_hide_player_popup_panels_summary_off">Паказваюцца ўсплывальныя панэлі прайгравальніка</string>
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.player.fullscreen.exitFullscreenPatch">
|
||||||
|
<string name="revanced_exit_fullscreen_title">Выйсці з поўнаэкраннага рэжыму ў канцы відэа</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_1">Адключана</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_2">Партрэт</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_3">Ландшафт</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_4">Партрэт і ландшафт</string>
|
||||||
|
</patch>
|
||||||
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_title">Открывать видео на весь экран в портретном режиме</string>
|
<string name="revanced_open_videos_fullscreen_portrait_title">Открывать видео на весь экран в портретном режиме</string>
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_summary_on">Видео открываются на весь экран</string>
|
<string name="revanced_open_videos_fullscreen_portrait_summary_on">Видео открываются на весь экран</string>
|
||||||
@@ -1008,6 +1081,23 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_sb_reset">Скінуць</string>
|
<string name="revanced_sb_reset">Скінуць</string>
|
||||||
<string name="revanced_sb_about">Пра праграму</string>
|
<string name="revanced_sb_about">Пра праграму</string>
|
||||||
<string name="revanced_sb_about_api_sum">Дадзеныя прадастаўляюцца API SponsorBlock. Націсніце тут, каб даведацца больш і паглядзець спампоўкі для іншых платформаў</string>
|
<string name="revanced_sb_about_api_sum">Дадзеныя прадастаўляюцца API SponsorBlock. Націсніце тут, каб даведацца больш і паглядзець спампоўкі для іншых платформаў</string>
|
||||||
|
</patch>
|
||||||
|
<patch id="layout.formfactor.changeFormFactorPatch">
|
||||||
|
<string name="revanced_change_form_factor_title">Фармат экрана</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_1">Па змаўчанню</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_4">Аўтамабільны</string>
|
||||||
|
<string name="revanced_change_form_factor_user_dialog_message">"Змены ўключаюць:
|
||||||
|
|
||||||
|
Раскладка планшэта
|
||||||
|
• Паведамленні супольнасці схаваны
|
||||||
|
|
||||||
|
Раскладка аўтамабіля
|
||||||
|
• Меню гісторыі праглядаў схавана
|
||||||
|
• Адноўлена ўкладка «Даследаваць»
|
||||||
|
• Ролікі Shorts адкрываюцца ў звычайным прайгравальніку
|
||||||
|
• Стужка арганізавана па тэмах і каналах"</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.spoofappversion.spoofAppVersionPatch">
|
<patch id="layout.spoofappversion.spoofAppVersionPatch">
|
||||||
<string name="revanced_spoof_app_version_title">Версія праграмы Spoof</string>
|
<string name="revanced_spoof_app_version_title">Версія праграмы Spoof</string>
|
||||||
@@ -1022,6 +1112,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>
|
||||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
<!-- '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_1">18.33.40 - Аднаўленне RYD на Shorts у рэжыме інкогніта</string>
|
||||||
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Аднавіць хуткасць шырокага відэа & якаснае меню</string>
|
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Аднавіць хуткасць шырокага відэа & якаснае меню</string>
|
||||||
@@ -1065,12 +1156,6 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_shorts_autoplay_background_summary_on">Shorts в фоновом режиме будут воспроизводиться автоматически</string>
|
<string name="revanced_shorts_autoplay_background_summary_on">Shorts в фоновом режиме будут воспроизводиться автоматически</string>
|
||||||
<string name="revanced_shorts_autoplay_background_summary_off">Shorts в фоновом режиме будут повторяться</string>
|
<string name="revanced_shorts_autoplay_background_summary_off">Shorts в фоновом режиме будут повторяться</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.tablet.enableTabletLayoutPatch">
|
|
||||||
<string name="revanced_tablet_layout_title">Уключыць макет планшэта</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_on">Макет планшэта ўключаны</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_off">Макет планшэта адключаны</string>
|
|
||||||
<string name="revanced_tablet_layout_user_dialog_message">Паведамленні ў супольнасці не адлюстроўваюцца на планшэце</string>
|
|
||||||
</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>
|
||||||
@@ -1234,6 +1319,7 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_force_original_audio_title">Вымушанае арыгінальнае аўдыё</string>
|
<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>
|
||||||
|
<string name="revanced_force_original_audio_not_available">Каб выкарыстоўваць гэтую функцыю, зменіце спафінг патоку на тып кліента iOS</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
@@ -1261,6 +1347,8 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_custom_playback_speeds_invalid">Нестандартныя хуткасці павінны быць менш за %s</string>
|
<string name="revanced_custom_playback_speeds_invalid">Нестандартныя хуткасці павінны быць менш за %s</string>
|
||||||
<string name="revanced_custom_playback_speeds_parse_exception">Несапраўдныя нестандартныя хуткасці прайгравання</string>
|
<string name="revanced_custom_playback_speeds_parse_exception">Несапраўдныя нестандартныя хуткасці прайгравання</string>
|
||||||
<string name="revanced_custom_playback_speeds_auto">Аўто</string>
|
<string name="revanced_custom_playback_speeds_auto">Аўто</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_title">Уласны хуткасць націску і ўтрымання</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_summary">Хуткасць прайгравання між 0-8</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
||||||
<string name="revanced_remember_playback_speed_last_selected_title">Запомніце змены хуткасці прайгравання</string>
|
<string name="revanced_remember_playback_speed_last_selected_title">Запомніце змены хуткасці прайгравання</string>
|
||||||
@@ -1289,74 +1377,27 @@ Second \"item\" text"</string>
|
|||||||
Прайграванне відэа можа не працаваць"</string>
|
Прайграванне відэа можа не працаваць"</string>
|
||||||
<string name="revanced_spoof_video_streams_user_dialog_message">Адключэнне гэтай налады можа выклікаць праблемы з прайграваннем відэа.</string>
|
<string name="revanced_spoof_video_streams_user_dialog_message">Адключэнне гэтай налады можа выклікаць праблемы з прайграваннем відэа.</string>
|
||||||
<string name="revanced_spoof_video_streams_client_type_title">Клиент по умолчанию</string>
|
<string name="revanced_spoof_video_streams_client_type_title">Клиент по умолчанию</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">Принудительно AVC (H.264)</string>
|
<!-- 'no auth' means no authentication -->
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Видеокодек принудительно установлен в AVC (H.264)</string>
|
<string name="revanced_spoof_video_streams_client_type_android_vr_no_auth">Android VR (няма аўтэнтыфікацыі)</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Видеокодек определяется автоматически</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_title">Вымусіць iOS AVC (H.264)</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Уключэнне гэтага можа палепшыць тэрмін службы батарэі і выправіць заіканне відэа.
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Відэакaдэк зафіксаваны ў AVC (H.264)</string>
|
||||||
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Відэакaдэк вызначаецца аўтаматычна</string>
|
||||||
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Уключэнне гэтага можа палепшыць час аўтаномнай працы і выправіць заіканне прайгравання.
|
||||||
|
|
||||||
AVC мае максімальную раздзяляльнасць 1080p, аўдыякадэкар Opus недаступны, і відэа будзе выкарыстоўваць больш Інтэрнэт-даных, чым VP9 або AV1."</string>
|
AVC мае максімальнае дазвол 1080p, аўдыёкадэк Opus недаступны, а прайграванне відэа будзе выкарыстоўваць больш інтэрнэт-даных, чым VP9 або AV1."</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">Пабочныя эфекты падмены iOS</string>
|
<string name="revanced_spoof_video_streams_about_ios_tv_title">Пабочныя эфекты падробкі iOS</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">"• Прыватныя дзіцячыя відэа могуць не прайгравацца
|
<string name="revanced_spoof_video_streams_about_ios_tv_summary">"• Фільмы або платныя відэа могуць не прайгравацца
|
||||||
|
• Стабільная гучнасць недаступная
|
||||||
• Відэа заканчваюцца на 1 секунду раней"</string>
|
• Відэа заканчваюцца на 1 секунду раней"</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Побочные эффекты подмены Android VR</string>
|
<string name="revanced_spoof_video_streams_about_android_title">Побічныя эфекты падробкі Android</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Дзіцячыя відэа могуць не прайгравацца
|
<string name="revanced_spoof_video_streams_about_android_summary">"• Меню гукавой дарожкі адсутнічае
|
||||||
• Меню гукавых дарожак адсутнічае
|
|
||||||
• Стабільны гук недаступны
|
• Стабільны гук недаступны
|
||||||
• Прымусовае выкарыстанне арыгінальнага аўдыё недаступна"</string>
|
• Прымусовае арыгінальнае аўдыё недаступна"</string>
|
||||||
<string name="revanced_spoof_video_streams_language_title">Язык потока аудио по умолчанию</string>
|
<string name="revanced_spoof_video_streams_about_no_av1">• Няма відэакідавання AV1</string>
|
||||||
<string name="revanced_spoof_video_streams_language_DEFAULT">Язык приложения</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_title">Паказаць у статыстыцы для спецыялістаў</string>
|
||||||
<string name="revanced_spoof_video_streams_language_AR">Арабский</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_on">Тып кліента адлюстроўваецца ў статыстыцы для спецыялістаў</string>
|
||||||
<string name="revanced_spoof_video_streams_language_AZ">Азербайджанский</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">Кліент схаваны ў статыстыцы для спецыялістаў</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BG">Болгарский</string>
|
<string name="revanced_spoof_video_streams_language_title">Мова гукавой дарожкі па змаўчанні для VR</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BN">Бенгальский</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_CA">Каталонский</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_CS">Чешский</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_DA">Датский</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_DE">Немецкий</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EL">Греческий</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EN">Англійская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ES">Іспанская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ET">Эстонская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FA">Фарсі</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FI">Фінская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FR">Французская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_GU">Гуяраті</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HI">Хянді</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HR">Хорватская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HU">Венгерская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ID">Инданезійская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_IT">Итальянская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_JA">Японская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KK">Казахская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KO">Корэйская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LT">Літоуская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LV">Латышская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MK">Македонская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MN">Монгольская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MR">Маратхі</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MS">Малайская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MY">Брыманская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_NL">Нідрландский</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_OR">Орія</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PA">Панджабский</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PL">Польская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_BR">Партугальская (Бразілія)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_PT">Партугальская (Партугалія)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RO">Румынская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RU">Русская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SK">Словацкия</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SL">Словенская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SR">Сербская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SV">Швецкая</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SW">Суахілі</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TA">Тамільская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TE">Тэлугу</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TH">Тайская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TR">Турэцкая</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UK">Украёнская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UR">Урду</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_VI">Віетнамская</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ZH">Кітайская</string>
|
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_check_environment_not_near_patch_time_invalid">Датата на компилация на APK е повредена</string>
|
<string name="revanced_check_environment_not_near_patch_time_invalid">Датата на компилация на APK е повредена</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.settings.settingsResourcePatch">
|
<patch id="misc.settings.settingsResourcePatch">
|
||||||
|
<string name="revanced_settings_submenu_title">Настройки</string>
|
||||||
<string name="revanced_settings_title">ReVanced</string>
|
<string name="revanced_settings_title">ReVanced</string>
|
||||||
<string name="revanced_settings_confirm_user_dialog_title">Искате ли да продължите?</string>
|
<string name="revanced_settings_confirm_user_dialog_title">Искате ли да продължите?</string>
|
||||||
<string name="revanced_settings_reset">Възстанови</string>
|
<string name="revanced_settings_reset">Възстанови</string>
|
||||||
@@ -43,6 +44,62 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_settings_import_reset">Настройките на ReVanced бяха нулирани</string>
|
<string name="revanced_settings_import_reset">Настройките на ReVanced бяха нулирани</string>
|
||||||
<string name="revanced_settings_import_success">Следните настройки бяха импортирани успешно: %d</string>
|
<string name="revanced_settings_import_success">Следните настройки бяха импортирани успешно: %d</string>
|
||||||
<string name="revanced_settings_import_failure_parse">Импортирането беше неуспешно: %s</string>
|
<string name="revanced_settings_import_failure_parse">Импортирането беше неуспешно: %s</string>
|
||||||
|
<string name="revanced_language_title">Език на ReVanced</string>
|
||||||
|
<string name="revanced_language_user_dialog_message">"Преводите на някои езици може да липсват или да са непълни.
|
||||||
|
|
||||||
|
За да преведете нови езици, посетете translate.revanced.app"</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. -->
|
||||||
@@ -77,12 +134,15 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_settings_screen_01_ads_title">Реклами</string>
|
<string name="revanced_settings_screen_01_ads_title">Реклами</string>
|
||||||
<string name="revanced_settings_screen_02_alt_thumbnails_title">Алтернативни миниатюри</string>
|
<string name="revanced_settings_screen_02_alt_thumbnails_title">Алтернативни миниатюри</string>
|
||||||
<string name="revanced_settings_screen_03_feed_title">Поток</string>
|
<string name="revanced_settings_screen_03_feed_title">Поток</string>
|
||||||
<string name="revanced_settings_screen_04_player_title">Плейър</string>
|
<string name="revanced_settings_screen_04_general_title">Общ</string>
|
||||||
<string name="revanced_settings_screen_05_general_title">Общо оформление</string>
|
<string name="revanced_settings_screen_05_player_title">Плеър</string>
|
||||||
<string name="revanced_settings_screen_07_seekbar_title">Лента за прогрес на видеото</string>
|
<string name="revanced_settings_screen_07_seekbar_title">Лента за прогрес на видеото</string>
|
||||||
<string name="revanced_settings_screen_08_swipe_controls_title">Контроли с плъзгане</string>
|
<string name="revanced_settings_screen_08_swipe_controls_title">Контроли с плъзгане</string>
|
||||||
<string name="revanced_settings_screen_11_misc_title">Разни</string>
|
<string name="revanced_settings_screen_11_misc_title">Разни</string>
|
||||||
<string name="revanced_settings_screen_12_video_title">Видео</string>
|
<string name="revanced_settings_screen_12_video_title">Видео</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_title">Възстановяване на старите менюта за настройки</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_summary_on">Старите менюта с настройки се показват</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_summary_off">Старите менюта с настройки не се показват</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
||||||
<string name="revanced_shorts_disable_background_playback_title">Възпроизвеждане на Shorts в фонов режим</string>
|
<string name="revanced_shorts_disable_background_playback_title">Възпроизвеждане на Shorts в фонов режим</string>
|
||||||
@@ -445,6 +505,9 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_swipe_overlay_background_alpha_summary">Видимостта на фона на плъзгащите контроли.</string>
|
<string name="revanced_swipe_overlay_background_alpha_summary">Видимостта на фона на плъзгащите контроли.</string>
|
||||||
<string name="revanced_swipe_threshold_title">Праг на величината на плъзгане</string>
|
<string name="revanced_swipe_threshold_title">Праг на величината на плъзгане</string>
|
||||||
<string name="revanced_swipe_threshold_summary">Праг преди да се осъществи плъзгането</string>
|
<string name="revanced_swipe_threshold_summary">Праг преди да се осъществи плъзгането</string>
|
||||||
|
<string name="revanced_swipe_change_video_title">Включване на превключване на видеото чрез плъзване</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_on">Плъзването в режим на цял екран ще превключи към следващото/предишно видео</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_off">Плъзването в режим на цял екран няма да превключи към следващото/предишно видео</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.autocaptions.autoCaptionsPatch">
|
<patch id="layout.autocaptions.autoCaptionsPatch">
|
||||||
<string name="revanced_auto_captions_title">Автоматични Субтитри</string>
|
<string name="revanced_auto_captions_title">Автоматични Субтитри</string>
|
||||||
@@ -628,15 +691,18 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_shorts_player_screen_summary">Скриване или показване на компоненти в Shorts плейъра</string>
|
<string name="revanced_shorts_player_screen_summary">Скриване или показване на компоненти в Shorts плейъра</string>
|
||||||
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
||||||
<string name="revanced_hide_shorts_home_title">Скриване на Shorts в началната лента</string>
|
<string name="revanced_hide_shorts_home_title">Скриване на Shorts в началната лента</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_on">Shorts в началната лента са скрити</string>
|
<string name="revanced_hide_shorts_home_summary_on">Скрит в началния канал и свързани видеоклипове</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_off">Shorts в началната лента са показани</string>
|
<string name="revanced_hide_shorts_home_summary_off">Показан в началния канал и свързани видеоклипове</string>
|
||||||
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
||||||
<string name="revanced_hide_shorts_subscriptions_title">Shorts в раздел „Абонаменти“</string>
|
<string name="revanced_hide_shorts_subscriptions_title">Shorts в раздел „Абонаменти“</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_on">Shorts в раздел „Абонаменти“ са скрити</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_on">Скрито в абонаментната емисия</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_off">Shorts в раздел „Абонаменти“ се показват</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_off">Показано в абонаментната емисия</string>
|
||||||
<string name="revanced_hide_shorts_search_title">Shorts в резултатите от търсенето</string>
|
<string name="revanced_hide_shorts_search_title">Shorts в резултатите от търсенето</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_on">Shorts в резултатите от търсенето са скрити</string>
|
<string name="revanced_hide_shorts_search_summary_on">Скрити в резултатите от търсенето</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_off">Shorts в резултатите от търсенето се показват</string>
|
<string name="revanced_hide_shorts_search_summary_off">Показано в резултатите от търсенето</string>
|
||||||
|
<string name="revanced_hide_shorts_history_title">Скриване на шортите в историята на гледане</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_on">Скрито в историята на гледане</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_off">Показва се в историята на гледане</string>
|
||||||
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
||||||
<string name="revanced_hide_shorts_join_button_title">Бутон за присъединяване</string>
|
<string name="revanced_hide_shorts_join_button_title">Бутон за присъединяване</string>
|
||||||
<string name="revanced_hide_shorts_join_button_summary_on">Бутона за присъединяване е скрит</string>
|
<string name="revanced_hide_shorts_join_button_summary_on">Бутона за присъединяване е скрит</string>
|
||||||
@@ -738,6 +804,13 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_hide_player_popup_panels_summary_on">Изскачащите панели на плейъра са скрити</string>
|
<string name="revanced_hide_player_popup_panels_summary_on">Изскачащите панели на плейъра са скрити</string>
|
||||||
<string name="revanced_hide_player_popup_panels_summary_off">Изскачащите панели на плейъра се показват</string>
|
<string name="revanced_hide_player_popup_panels_summary_off">Изскачащите панели на плейъра се показват</string>
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.player.fullscreen.exitFullscreenPatch">
|
||||||
|
<string name="revanced_exit_fullscreen_title">Изход от режим на цял екран в края на видеото</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_1">Деактивирано</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_2">Портрет</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_3">Пейзаж</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_4">Портрет и пейзаж</string>
|
||||||
|
</patch>
|
||||||
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_title">Отваряне на видеоклипове в портретен режим на цял екран</string>
|
<string name="revanced_open_videos_fullscreen_portrait_title">Отваряне на видеоклипове в портретен режим на цял екран</string>
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_summary_on">Видеоклиповете се отварят на цял екран</string>
|
<string name="revanced_open_videos_fullscreen_portrait_summary_on">Видеоклиповете се отварят на цял екран</string>
|
||||||
@@ -1006,6 +1079,23 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_sb_reset">Възстанови</string>
|
<string name="revanced_sb_reset">Възстанови</string>
|
||||||
<string name="revanced_sb_about">За програмата</string>
|
<string name="revanced_sb_about">За програмата</string>
|
||||||
<string name="revanced_sb_about_api_sum">Данните са предоставени от SponsorBlock API. Докоснете тук за повече информация и изтеглияния</string>
|
<string name="revanced_sb_about_api_sum">Данните са предоставени от SponsorBlock API. Докоснете тук за повече информация и изтеглияния</string>
|
||||||
|
</patch>
|
||||||
|
<patch id="layout.formfactor.changeFormFactorPatch">
|
||||||
|
<string name="revanced_change_form_factor_title">Формат на екрана /Таблет, Телфон, .../</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_1">По подразбиране</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_4">Автомобил</string>
|
||||||
|
<string name="revanced_change_form_factor_user_dialog_message">"Промените включват:
|
||||||
|
|
||||||
|
Оформление за таблет
|
||||||
|
• Публикациите на общността са скрити
|
||||||
|
|
||||||
|
Оформление за автомобил
|
||||||
|
• Менюто „История на гледане“ е скрито
|
||||||
|
• Разделът „Разгледай“ е възстановен
|
||||||
|
• 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>
|
||||||
@@ -1020,6 +1110,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>
|
||||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
<!-- '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_1">18.33.40 - Възстановете RYD в режим „инкогнито“ на Shorts</string>
|
||||||
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Възстановяване на видео скорост & в менюто за качество</string>
|
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Възстановяване на видео скорост & в менюто за качество</string>
|
||||||
@@ -1063,12 +1154,6 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_shorts_autoplay_background_summary_on">Shorts ще се възпроизвеждат автоматично един след друг във фонов режим</string>
|
<string name="revanced_shorts_autoplay_background_summary_on">Shorts ще се възпроизвеждат автоматично един след друг във фонов режим</string>
|
||||||
<string name="revanced_shorts_autoplay_background_summary_off">Shorts ще се повтори във фонов режим</string>
|
<string name="revanced_shorts_autoplay_background_summary_off">Shorts ще се повтори във фонов режим</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.tablet.enableTabletLayoutPatch">
|
|
||||||
<string name="revanced_tablet_layout_title">Включи режим за таблет</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_on">Режим за таблет е вкл.</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_off">Режим за таблет е изкл.</string>
|
|
||||||
<string name="revanced_tablet_layout_user_dialog_message">Публикациите в общността не се показват на оформления за таблет</string>
|
|
||||||
</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>
|
||||||
@@ -1232,6 +1317,7 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_force_original_audio_title">Принудително оригинално аудио</string>
|
<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>
|
||||||
|
<string name="revanced_force_original_audio_not_available">За да използвате тази функция, променете имитацията на поточно предаване на тип клиент на iOS</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
@@ -1259,6 +1345,8 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_custom_playback_speeds_invalid">Персонализираните скорости трябва да са по-малки от %s</string>
|
<string name="revanced_custom_playback_speeds_invalid">Персонализираните скорости трябва да са по-малки от %s</string>
|
||||||
<string name="revanced_custom_playback_speeds_parse_exception">Невалидни персонализирани скорости на възпроизвеждане</string>
|
<string name="revanced_custom_playback_speeds_parse_exception">Невалидни персонализирани скорости на възпроизвеждане</string>
|
||||||
<string name="revanced_custom_playback_speeds_auto">Авто</string>
|
<string name="revanced_custom_playback_speeds_auto">Авто</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_title">Персонализирана скорост при докосване и задържане</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_summary">Скорост на възпроизвеждане между 0-8</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
||||||
<string name="revanced_remember_playback_speed_last_selected_title">Запомни промените в скоростта на възпроизвеждане</string>
|
<string name="revanced_remember_playback_speed_last_selected_title">Запомни промените в скоростта на възпроизвеждане</string>
|
||||||
@@ -1287,74 +1375,27 @@ Second \"item\" text"</string>
|
|||||||
Възпроизвеждането на видеоклипове може да не работи"</string>
|
Възпроизвеждането на видеоклипове може да не работи"</string>
|
||||||
<string name="revanced_spoof_video_streams_user_dialog_message">Деактивирането на тази настройка ще доведе до проблеми с възпроизвеждането на видео.</string>
|
<string name="revanced_spoof_video_streams_user_dialog_message">Деактивирането на тази настройка ще доведе до проблеми с възпроизвеждането на видео.</string>
|
||||||
<string name="revanced_spoof_video_streams_client_type_title">Клиент по подразбиране</string>
|
<string name="revanced_spoof_video_streams_client_type_title">Клиент по подразбиране</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">Принудително AVC (H.264)</string>
|
<!-- 'no auth' means no authentication -->
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Видео кодек по подразбиране AVC (H.264)</string>
|
<string name="revanced_spoof_video_streams_client_type_android_vr_no_auth">Android VR (bez avtorizaciq)</string>
|
||||||
|
<string name="revanced_spoof_video_streams_ios_force_avc_title">Принудително използване на AVC (H.264) на iOS</string>
|
||||||
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Видео кодекът е принудително зададен на AVC (H.264)</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Видео кодекът се определя автоматично</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Видео кодекът се определя автоматично</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Активирането на това може да подобри живота на батерията и да поправи заекването на възпроизвеждането.
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Включването на това може да подобри живота на батерията и да поправи заекването при възпроизвеждане.
|
||||||
|
|
||||||
AVC има максимална разделителна способност от 1080p, аудио кодекът Opus не е наличен, а видеовъзпроизвеждането ще използва повече интернет данни от VP9 или AV1."</string>
|
AVC има максимална резолюция от 1080p, Opus аудио кодек не е наличен и възпроизвеждането на видео ще използва повече интернет данни от VP9 или AV1."</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">Cтранични ефекти от подмяната на iOS</string>
|
<string name="revanced_spoof_video_streams_about_ios_tv_title">Ефекти на измамата в iOS</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">"• Възможно е частните детски видеоклипове да не се възпроизвеждат
|
<string name="revanced_spoof_video_streams_about_ios_tv_summary">"• Филми или платени видеоклипове може да не се възпроизвеждат
|
||||||
|
• Стабилен звук не е наличен
|
||||||
• Видеоклиповете завършват 1 секунда по-рано"</string>
|
• Видеоклиповете завършват 1 секунда по-рано"</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Странични ефекти от подправяне на Android VR</string>
|
<string name="revanced_spoof_video_streams_about_android_title">Strani4ni efekti na fal6ivoto predstavqne na Android</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Може да възникнат проблеми при възпроизвеждане на детски видеоклипове
|
<string name="revanced_spoof_video_streams_about_android_summary">"• Lipsva menju za audio pisti
|
||||||
• Липсва меню за аудио песни
|
• Ne e nali4na stabilna glasnost
|
||||||
• Не е налично стабилно ниво на звука
|
• Ne e nali4na forsirana originalna audio pista"</string>
|
||||||
• Не е налична опция за оригинално аудио"</string>
|
<string name="revanced_spoof_video_streams_about_no_av1">• Без AV1 видео кодек</string>
|
||||||
<string name="revanced_spoof_video_streams_language_title">Език по подразбиране на аудио потока</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_title">Poka6i v Statistiki za nerds</string>
|
||||||
<string name="revanced_spoof_video_streams_language_DEFAULT">Език на приложението</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_on">Tipът na klienta se poka6va v Statistiki za nerds</string>
|
||||||
<string name="revanced_spoof_video_streams_language_AR">Арабски</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">Klientът e skriт v Statistiki za nerds</string>
|
||||||
<string name="revanced_spoof_video_streams_language_AZ">Азербайджански</string>
|
<string name="revanced_spoof_video_streams_language_title">Ezik po подразбиране za audio potok v VR</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BG">Български</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_BN">Бенгалски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_CA">Каталонски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_CS">Чешки</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_DA">Датски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_DE">Немски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EL">Гръцки</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EN">Английски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ES">Испански</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ET">Естонски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FA">Персийски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FI">Финландски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FR">Френски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_GU">Гуджарати</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HI">Хинди</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HR">Хърватски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HU">Унгарски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ID">Индонезийски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_IT">Италиански</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_JA">Японски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KK">Казахски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KO">Корейски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LT">Литовски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LV">Латвийски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MK">Македонски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MN">Монголски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MR">Маратхи</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MS">Малайски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MY">Бирмански</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_NL">Холандски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_OR">Ория</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PA">Пенджабски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PL">Полски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_BR">Португалски (Бразилия)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_PT">Португалски (Португалия)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RO">Румънски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RU">Руски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SK">Словашки</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SL">Словенски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SR">Сръбски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SV">Шведски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SW">Суахили</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TA">Тамилски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TE">Телугу</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TH">Тайландски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TR">Турски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UK">Украински</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UR">Урду</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_VI">Виетнамски</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ZH">Китайски</string>
|
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_check_environment_not_near_patch_time_invalid">APK তৈরির তারিখ ত্রুটিপূর্ণ</string>
|
<string name="revanced_check_environment_not_near_patch_time_invalid">APK তৈরির তারিখ ত্রুটিপূর্ণ</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.settings.settingsResourcePatch">
|
<patch id="misc.settings.settingsResourcePatch">
|
||||||
|
<string name="revanced_settings_submenu_title">সেটিংস</string>
|
||||||
<string name="revanced_settings_title">ReVanced</string>
|
<string name="revanced_settings_title">ReVanced</string>
|
||||||
<string name="revanced_settings_confirm_user_dialog_title">আপনি কি এগিয়ে যেতে ইচ্ছুক?</string>
|
<string name="revanced_settings_confirm_user_dialog_title">আপনি কি এগিয়ে যেতে ইচ্ছুক?</string>
|
||||||
<string name="revanced_settings_reset">আবার সেট করুন</string>
|
<string name="revanced_settings_reset">আবার সেট করুন</string>
|
||||||
@@ -43,6 +44,62 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_settings_import_reset">ReVanced সেটিং ডিফল্ট সেট করা হয়েছে</string>
|
<string name="revanced_settings_import_reset">ReVanced সেটিং ডিফল্ট সেট করা হয়েছে</string>
|
||||||
<string name="revanced_settings_import_success">%d সেটিং আমদানি হয়েছে</string>
|
<string name="revanced_settings_import_success">%d সেটিং আমদানি হয়েছে</string>
|
||||||
<string name="revanced_settings_import_failure_parse">আমদানি করা যায়নি: %s</string>
|
<string name="revanced_settings_import_failure_parse">আমদানি করা যায়নি: %s</string>
|
||||||
|
<string name="revanced_language_title">ReVanced ভাষা</string>
|
||||||
|
<string name="revanced_language_user_dialog_message">"কিছু ভাষার জন্য অনুবাদ অনুপস্থিত বা অসম্পূর্ণ হতে পারে।
|
||||||
|
|
||||||
|
নতুন ভাষা অনুবাদ করতে translate.revanced.app দেখুন"</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. -->
|
||||||
@@ -77,13 +134,16 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
|
|||||||
<string name="revanced_settings_screen_01_ads_title">বিজ্ঞাপন</string>
|
<string name="revanced_settings_screen_01_ads_title">বিজ্ঞাপন</string>
|
||||||
<string name="revanced_settings_screen_02_alt_thumbnails_title">বিকল্প থাম্বনেইল</string>
|
<string name="revanced_settings_screen_02_alt_thumbnails_title">বিকল্প থাম্বনেইল</string>
|
||||||
<string name="revanced_settings_screen_03_feed_title">ফিড</string>
|
<string name="revanced_settings_screen_03_feed_title">ফিড</string>
|
||||||
<string name="revanced_settings_screen_04_player_title">প্লেয়ার</string>
|
<string name="revanced_settings_screen_04_general_title">সাধারণ</string>
|
||||||
<string name="revanced_settings_screen_05_general_title">সাধারণ লে-আউট</string>
|
<string name="revanced_settings_screen_05_player_title">প্লেয়ার</string>
|
||||||
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
||||||
<string name="revanced_settings_screen_07_seekbar_title">সিকবার</string>
|
<string name="revanced_settings_screen_07_seekbar_title">সিকবার</string>
|
||||||
<string name="revanced_settings_screen_08_swipe_controls_title">সোয়াইপ কন্ট্রোল</string>
|
<string name="revanced_settings_screen_08_swipe_controls_title">সোয়াইপ কন্ট্রোল</string>
|
||||||
<string name="revanced_settings_screen_11_misc_title">বিবিধ</string>
|
<string name="revanced_settings_screen_11_misc_title">বিবিধ</string>
|
||||||
<string name="revanced_settings_screen_12_video_title">ভিডিও</string>
|
<string name="revanced_settings_screen_12_video_title">ভিডিও</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_title">পুরানো সেটিংস মেনু পুনরুদ্ধার করুন</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_summary_on">পুরাতন সেটিংস মেনু দেখানো হচ্ছে</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_summary_off">পুরাতন সেটিংস মেনু দেখানো হচ্ছে না</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
||||||
<string name="revanced_shorts_disable_background_playback_title">Shorts ব্যাকগ্রাউন্ড প্লে অক্ষম করুন</string>
|
<string name="revanced_shorts_disable_background_playback_title">Shorts ব্যাকগ্রাউন্ড প্লে অক্ষম করুন</string>
|
||||||
@@ -446,6 +506,9 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
|
|||||||
<string name="revanced_swipe_overlay_background_alpha_summary">সোয়াইপ ওভারলে ব্যাকগ্রাউন্ডের দৃশ্যমানতা</string>
|
<string name="revanced_swipe_overlay_background_alpha_summary">সোয়াইপ ওভারলে ব্যাকগ্রাউন্ডের দৃশ্যমানতা</string>
|
||||||
<string name="revanced_swipe_threshold_title">সোয়াইপ থ্রেশহোল্ড এর মাত্রা</string>
|
<string name="revanced_swipe_threshold_title">সোয়াইপ থ্রেশহোল্ড এর মাত্রা</string>
|
||||||
<string name="revanced_swipe_threshold_summary">সোয়াইপ করার থ্রেশহোল্ডের পরিমাণ</string>
|
<string name="revanced_swipe_threshold_summary">সোয়াইপ করার থ্রেশহোল্ডের পরিমাণ</string>
|
||||||
|
<string name="revanced_swipe_change_video_title">ভিডিও পরিবর্তন করতে সোয়াইপ করে সক্ষম করুন</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_on">ফুলস্ক্রিন মোডে সোয়াইপ করলে পরবর্তী/পূর্ববর্তী ভিডিওতে পরিবর্তন হবে</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_off">ফুলস্ক্রিন মোডে সোয়াইপ করলে পরবর্তী /পূর্ববর্তী ভিডিওতে পরিবর্তন হবে না</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.autocaptions.autoCaptionsPatch">
|
<patch id="layout.autocaptions.autoCaptionsPatch">
|
||||||
<string name="revanced_auto_captions_title">স্বয়ংক্রিয় ক্যাপশন বন্ধ করুন</string>
|
<string name="revanced_auto_captions_title">স্বয়ংক্রিয় ক্যাপশন বন্ধ করুন</string>
|
||||||
@@ -629,15 +692,18 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
|
|||||||
<string name="revanced_shorts_player_screen_summary">Shorts প্লেয়ারে উপাদান লুকানো বা দেখানো</string>
|
<string name="revanced_shorts_player_screen_summary">Shorts প্লেয়ারে উপাদান লুকানো বা দেখানো</string>
|
||||||
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
||||||
<string name="revanced_hide_shorts_home_title">প্রধান ফিডে Shorts লুকান</string>
|
<string name="revanced_hide_shorts_home_title">প্রধান ফিডে Shorts লুকান</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_on">প্রধান ফিডে Shorts লুকিয়ে রয়েছে</string>
|
<string name="revanced_hide_shorts_home_summary_on">বাড়ির ফিড এবং সম্পর্কিত ভিডিওতে লুকানো হয়েছে</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_off">প্রধান ফিডে Shorts প্রদর্শিত হয়েছে</string>
|
<string name="revanced_hide_shorts_home_summary_off">বাড়ির ফিড এবং সম্পর্কিত ভিডিওতে দেখানো হয়েছে</string>
|
||||||
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
||||||
<string name="revanced_hide_shorts_subscriptions_title">সদস্যতা ফিডে Shorts লুকান</string>
|
<string name="revanced_hide_shorts_subscriptions_title">সদস্যতা ফিডে Shorts লুকান</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_on">সদস্যতা ফিডে Shorts লুকিয়ে রয়েছে</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_on">সাবস্ক্রিপশন ফিডে লুকানো আছে</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_off">সদস্যতা ফিডে Shorts প্রদর্শিত হয়েছে</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_off">সাবস্ক্রিপশন ফিডে দেখানো হয়েছে</string>
|
||||||
<string name="revanced_hide_shorts_search_title">অনুসন্ধান ফলাফলে Shorts লুকান</string>
|
<string name="revanced_hide_shorts_search_title">অনুসন্ধান ফলাফলে Shorts লুকান</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_on">অনুসন্ধান ফলাফলে Shorts লুকিয়ে রয়েছে</string>
|
<string name="revanced_hide_shorts_search_summary_on">অনুসন্ধান ফলাফলে লুকানো</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_off">অনুসন্ধান ফলাফলে Shorts প্রদর্শিত হয়েছে</string>
|
<string name="revanced_hide_shorts_search_summary_off">সার্চ রেজাল্টে দেখানো হয়েছে</string>
|
||||||
|
<string name="revanced_hide_shorts_history_title">Shortsগুলিকে ওয়াচ ইতিহাসে লুকান</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_on">ওয়াচ হিস্ট্রিতে লুকানো</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_off">ওয়াচ ইতিহাসে দেখানো</string>
|
||||||
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
||||||
<string name="revanced_hide_shorts_join_button_title">জয়েন করুন বোতাম লুকান</string>
|
<string name="revanced_hide_shorts_join_button_title">জয়েন করুন বোতাম লুকান</string>
|
||||||
<string name="revanced_hide_shorts_join_button_summary_on">জয়েন করুন বোতাম লুকিয়ে রয়েছে</string>
|
<string name="revanced_hide_shorts_join_button_summary_on">জয়েন করুন বোতাম লুকিয়ে রয়েছে</string>
|
||||||
@@ -739,6 +805,13 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
|
|||||||
<string name="revanced_hide_player_popup_panels_summary_on">প্লেয়ার পপআপ প্যানেলগুলো লুকিয়ে রয়েছে</string>
|
<string name="revanced_hide_player_popup_panels_summary_on">প্লেয়ার পপআপ প্যানেলগুলো লুকিয়ে রয়েছে</string>
|
||||||
<string name="revanced_hide_player_popup_panels_summary_off">প্লেয়ার পপআপ প্যানেলগুলো প্রদর্শিত হয়েছে</string>
|
<string name="revanced_hide_player_popup_panels_summary_off">প্লেয়ার পপআপ প্যানেলগুলো প্রদর্শিত হয়েছে</string>
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.player.fullscreen.exitFullscreenPatch">
|
||||||
|
<string name="revanced_exit_fullscreen_title">ভিডিও শেষ হওয়ার সময় পূর্ণ পর্দা মোড থেকে বেরিয়ে যান</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_1">নিষ্ক্রিয়</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_2">আনুভূমিক</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_3">ল্যান্ডস্কেপ</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_4">আনুভূমিক এবং ল্যান্ডস্কেপ</string>
|
||||||
|
</patch>
|
||||||
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_title">পূর্ণ পর্দায় ভিডিও খুলুন</string>
|
<string name="revanced_open_videos_fullscreen_portrait_title">পূর্ণ পর্দায় ভিডিও খুলুন</string>
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_summary_on">ভিডিও পূর্ণ পর্দায় খুলবে</string>
|
<string name="revanced_open_videos_fullscreen_portrait_summary_on">ভিডিও পূর্ণ পর্দায় খুলবে</string>
|
||||||
@@ -1007,6 +1080,23 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
|
|||||||
<string name="revanced_sb_reset">পুনরায় সেট করুন</string>
|
<string name="revanced_sb_reset">পুনরায় সেট করুন</string>
|
||||||
<string name="revanced_sb_about">সম্পর্কিত</string>
|
<string name="revanced_sb_about">সম্পর্কিত</string>
|
||||||
<string name="revanced_sb_about_api_sum">ডেটা SponsorBlock API দ্বারা সরবরাহ করা হয়। আরও জানতে এবং অন্যান্য প্ল্যাটফর্মের ডাউনলোড দেখতে এখানে ট্যাপ করুন</string>
|
<string name="revanced_sb_about_api_sum">ডেটা SponsorBlock API দ্বারা সরবরাহ করা হয়। আরও জানতে এবং অন্যান্য প্ল্যাটফর্মের ডাউনলোড দেখতে এখানে ট্যাপ করুন</string>
|
||||||
|
</patch>
|
||||||
|
<patch id="layout.formfactor.changeFormFactorPatch">
|
||||||
|
<string name="revanced_change_form_factor_title">লেআউট ফর্ম ফ্যাক্টর</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_1">ডিফল্ট</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_4">স্বয়ংচালিত</string>
|
||||||
|
<string name="revanced_change_form_factor_user_dialog_message">"পরিবর্তনগুলো হল:
|
||||||
|
|
||||||
|
ট্যাবলেট লেআউট
|
||||||
|
• কমিউনিটি পোস্ট গোপন
|
||||||
|
|
||||||
|
স্বয়ংচালিত লেআউট
|
||||||
|
• ঘড়ির ইতিহাস মেনু গোপন
|
||||||
|
• এক্সপ্লোর ট্যাব পুনরুদ্ধার করা হয়েছে
|
||||||
|
• শর্টস নিয়মিত প্লেয়ারে খোলে
|
||||||
|
• ফিড বিষয় এবং চ্যানেল দ্বারা সংগঠিত হয়"</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>
|
||||||
@@ -1021,6 +1111,7 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
|
|||||||
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>
|
||||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
<!-- '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_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_2">18.20.39 - প্রশ্বস্ত ভিডিও স্পিড এবং গুণমান মেনু পুনরুদ্ধার করে</string>
|
||||||
@@ -1064,12 +1155,6 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
|
|||||||
<string name="revanced_shorts_autoplay_background_summary_on">পটভূমিতে Shorts অটোপ্লে হবে</string>
|
<string name="revanced_shorts_autoplay_background_summary_on">পটভূমিতে Shorts অটোপ্লে হবে</string>
|
||||||
<string name="revanced_shorts_autoplay_background_summary_off">পটভূমিতে Shorts পুনরাবৃত্তি হবে</string>
|
<string name="revanced_shorts_autoplay_background_summary_off">পটভূমিতে Shorts পুনরাবৃত্তি হবে</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.tablet.enableTabletLayoutPatch">
|
|
||||||
<string name="revanced_tablet_layout_title">ট্যাবলেট লেআউট সক্রিয় করুন</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_on">ট্যাবলেট লেআউট সক্রিয় হয়েছে</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_off">ট্যাবলেট লেআউট নিষ্ক্রিয় হয়েছে</string>
|
|
||||||
<string name="revanced_tablet_layout_user_dialog_message">ট্যাবলেট লেআউটে কমিউনিটি পোস্ট দেখাবে না</string>
|
|
||||||
</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>
|
||||||
@@ -1234,6 +1319,7 @@ DeArrow সম্পর্কে আরও জানতে এখানে ট
|
|||||||
<string name="revanced_force_original_audio_title">মূল অডিও বলপূর্বক চালু করুন</string>
|
<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>
|
||||||
|
<string name="revanced_force_original_audio_not_available">এই বৈশিষ্ট্যটি ব্যবহার করার জন্য, iOS ক্লায়েন্ট প্রকারে স্ট্রিম স্পুফিং পরিবর্তন করুন</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
@@ -1261,6 +1347,8 @@ DeArrow সম্পর্কে আরও জানতে এখানে ট
|
|||||||
<string name="revanced_custom_playback_speeds_invalid">কাস্টম গতি %s এর চেয়ে কম হতে হবে</string>
|
<string name="revanced_custom_playback_speeds_invalid">কাস্টম গতি %s এর চেয়ে কম হতে হবে</string>
|
||||||
<string name="revanced_custom_playback_speeds_parse_exception">অবৈধ কাস্টম প্লেব্যাক গতি</string>
|
<string name="revanced_custom_playback_speeds_parse_exception">অবৈধ কাস্টম প্লেব্যাক গতি</string>
|
||||||
<string name="revanced_custom_playback_speeds_auto">স্বতস্ফূর্তভাবে</string>
|
<string name="revanced_custom_playback_speeds_auto">স্বতস্ফূর্তভাবে</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_title">কাস্টম ট্যাপ এন্ড হোল্ড স্পিড</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_summary">০-৮ এর মধ্যে প্লেব্যাক স্পিড</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
||||||
<string name="revanced_remember_playback_speed_last_selected_title">প্লেব্যাকের স্পিড পরিবর্তন মনে রাখুন</string>
|
<string name="revanced_remember_playback_speed_last_selected_title">প্লেব্যাকের স্পিড পরিবর্তন মনে রাখুন</string>
|
||||||
@@ -1289,73 +1377,27 @@ DeArrow সম্পর্কে আরও জানতে এখানে ট
|
|||||||
ভিডিও প্লেব্যাক কাজ নাও করতে পারে"</string>
|
ভিডিও প্লেব্যাক কাজ নাও করতে পারে"</string>
|
||||||
<string name="revanced_spoof_video_streams_user_dialog_message">এই সেটিংটি বন্ধ করার ফলে ভিডিও প্লেব্যাক ত্রুটি হতে পারে।</string>
|
<string name="revanced_spoof_video_streams_user_dialog_message">এই সেটিংটি বন্ধ করার ফলে ভিডিও প্লেব্যাক ত্রুটি হতে পারে।</string>
|
||||||
<string name="revanced_spoof_video_streams_client_type_title">ডিফল্ট ক্লায়েন্ট</string>
|
<string name="revanced_spoof_video_streams_client_type_title">ডিফল্ট ক্লায়েন্ট</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">AVC (H.264) ফোর্স করুন</string>
|
<!-- 'no auth' means no authentication -->
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">ভিডিও কোডেক AVC (H.264) তে বাধ্য করা হয়েছে</string>
|
<string name="revanced_spoof_video_streams_client_type_android_vr_no_auth">Android VR (স্বীকৃতি ছাড়া)</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">ভিডিও কোডেক স্বয়ংক্রিয়ভাবে নির্ধারিত হচ্ছে</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_title">iOS AVC (H.264) বাধ্যতামূলক করুন</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"এটি সক্রিয় করা ব্যাটারি লাইফ উন্নত করতে পারে এবং প্লেব্যাক হোঁচট খাওয়া ঠিক করতে পারে।
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">ভিডিও কোডেক AVC (H.264) এ বাধ্যতামূলক করা হয়েছে</string>
|
||||||
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">ভিডিও কোডেক স্বয়ংক্রিয়ভাবে নির্ধারিত হয়</string>
|
||||||
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"এটি সক্ষম করলে ব্যাটারি লাইফ উন্নত হতে পারে এবং প্লেব্যাক স্টাটারিং সমস্যা সমাধান হতে পারে।
|
||||||
|
|
||||||
AVC-এর সর্বোচ্চ রেজোলিউশন 1080p, Opus অডিও কোডেক উপলব্ধ নয় এবং ভিডিও প্লেব্যাক VP9 বা AV1 এর তুলনায় আরও ইন্টারনেট ডেটা ব্যবহার করবে।"</string>
|
AVC-এর সর্বোচ্চ রেজোলিউশন হল 1080p, Opus অডিও কোডেক পাওয়া যায় না এবং VP9 বা AV1-এর তুলনায় ভিডিও প্লেব্যাকে বেশি ইন্টারনেট ডেটা ব্যবহার করা হবে。"</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">iOS স্পুফিং এর পার্শ্ব প্রতিক্রিয়া</string>
|
<string name="revanced_spoof_video_streams_about_ios_tv_title">আইওএস স্পুফিংয়ের পার্শ্ব প্রতিক্রিয়া</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">"• বেসরকারি শিশু ভিডিও চলতে নাও পারে<br>• ভিডিওগুলি 1 সেকেন্ড আগে শেষ হয়"</string>
|
<string name="revanced_spoof_video_streams_about_ios_tv_summary">"• মুভি বা অর্থ প্রদানের ভিডিও চালু নাও হতে পারে
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR স্পুফিং এর পার্শ্ব প্রতিক্রিয়া</string>
|
• স্থির ভলিউম পাওয়া যায় না
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• শিশুদের ভিডিও চালু নাও হতে পারে
|
• ভিডিওগুলি 1 সেকেন্ড আগে শেষ হয়ে যায়"</string>
|
||||||
• অডিও ট্র্যাক মেনু অনুপস্থিত
|
<string name="revanced_spoof_video_streams_about_android_title">Android স্পুফিংয়ের পার্শ্বপ্রতিক্রিয়া</string>
|
||||||
• স্থিতিশীল ভলিউম পাওয়া যাচ্ছে না
|
<string name="revanced_spoof_video_streams_about_android_summary">"• অডিও ট্র্যাক মেনু নেই
|
||||||
• আসল অডিও জোরপূর্বক পাওয়া যাচ্ছে না"</string>
|
• স্থির ভলিউম পাওয়া যায় না
|
||||||
<string name="revanced_spoof_video_streams_language_title">ডিফল্ট অডিও স্ট্রিম ভাষা</string>
|
• মূল অডিও জোর করে চালু করা যায় না"</string>
|
||||||
<string name="revanced_spoof_video_streams_language_DEFAULT">অ্যাপ ভাষা</string>
|
<string name="revanced_spoof_video_streams_about_no_av1">• কোনো AV1 ভিডিও কোডেক নেই</string>
|
||||||
<string name="revanced_spoof_video_streams_language_AR">আরবি</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_title">স্ট্যাটস ফর নার্ডসে দেখান</string>
|
||||||
<string name="revanced_spoof_video_streams_language_AZ">আজারবাইজানি</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_on">স্ট্যাটস ফর নার্ডসে ক্লায়েন্ট প্রকার দেখানো হবে</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BG">বুলগেরিয়ান</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">স্ট্যাটস ফর নার্ডসে ক্লায়েন্ট লুকানো হবে</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BN">বাংলা</string>
|
<string name="revanced_spoof_video_streams_language_title">VR ডিফল্ট অডিও স্ট্রিম ভাষা</string>
|
||||||
<string name="revanced_spoof_video_streams_language_CA">কাতালান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_CS">চেক</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_DA">ডেনিশ</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_DE">জার্মান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EL">গ্রীক</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EN">ইংরেজি</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ES">স্প্যানিশ</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ET">এস্তোনিয়ান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FA">ফার্সি</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FI">ফিনল্যান্ড</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FR">ফরাসি</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_GU">গুজরাটি</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HI">হিন্দি</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HR">ক্রোয়েশিয়ান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HU">হাঙ্গেরিয়ান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ID">ইন্দোনেশিয়ান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_IT">ইতালীয়</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_JA">জাপানি</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KK">কাজাখ</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KO">কোরিয়ান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LT">লিথুয়ানিয়ান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LV">লাতভিয়ান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MK">ম্যাসেডোনিয়ান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MN">মঙ্গোলিয়ান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MR">মারাঠি</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MS">মালয়</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MY">বার্মিজ</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_NL">ডাচ</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_OR">ওড়িয়া</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PA">পঞ্জাবি</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PL">পোলিশ</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_BR">পর্তুগিজ (ব্রাজিল)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_PT">পর্তুগিজ (পর্তুগাল)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RO">রোমানীয়</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RU">রাশিয়ান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SK">স্লোভাক</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SL">স্লোভেনিয়ান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SR">সার্বিয়ান</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SV">সুইডিশ</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SW">সোয়াহিলি</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TA">তামিল</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TE">তেলুগু</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TH">থাই</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TR">তুর্কি</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UK">ইউক্রেনীয়</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UR">উর্দু</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_VI">ভিয়েতনামি</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ZH">চীনা</string>
|
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -136,6 +136,8 @@ Second \"item\" text"</string>
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.panels.popup.playerPopupPanelsPatch">
|
<patch id="layout.panels.popup.playerPopupPanelsPatch">
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.player.fullscreen.exitFullscreenPatch">
|
||||||
|
</patch>
|
||||||
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.player.overlay.customPlayerOverlayOpacityResourcePatch">
|
<patch id="layout.player.overlay.customPlayerOverlayOpacityResourcePatch">
|
||||||
@@ -155,6 +157,8 @@ Second \"item\" text"</string>
|
|||||||
<!-- 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. -->
|
||||||
<!-- 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>
|
||||||
<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 -->
|
||||||
@@ -168,8 +172,6 @@ Second \"item\" text"</string>
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
|
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.tablet.enableTabletLayoutPatch">
|
|
||||||
</patch>
|
|
||||||
<patch id="layout.miniplayer.miniplayerPatch">
|
<patch id="layout.miniplayer.miniplayerPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.theme.themePatch">
|
<patch id="layout.theme.themePatch">
|
||||||
@@ -218,6 +220,7 @@ Second \"item\" text"</string>
|
|||||||
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
|
<patch id="misc.fix.playback.spoofVideoStreamsPatch">
|
||||||
|
<!-- 'no auth' means no authentication -->
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_check_environment_not_near_patch_time_invalid">La data de creació de l\'APK està corrupta</string>
|
<string name="revanced_check_environment_not_near_patch_time_invalid">La data de creació de l\'APK està corrupta</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.settings.settingsResourcePatch">
|
<patch id="misc.settings.settingsResourcePatch">
|
||||||
|
<string name="revanced_settings_submenu_title">Configuració</string>
|
||||||
<string name="revanced_settings_title">ReVanced</string>
|
<string name="revanced_settings_title">ReVanced</string>
|
||||||
<string name="revanced_settings_confirm_user_dialog_title">Vols continuar?</string>
|
<string name="revanced_settings_confirm_user_dialog_title">Vols continuar?</string>
|
||||||
<string name="revanced_settings_reset">Restablir</string>
|
<string name="revanced_settings_reset">Restablir</string>
|
||||||
@@ -43,6 +44,62 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_settings_import_reset">La configuració de ReVanced s\'ha restablert als valors predeterminats</string>
|
<string name="revanced_settings_import_reset">La configuració de ReVanced s\'ha restablert als valors predeterminats</string>
|
||||||
<string name="revanced_settings_import_success">S\'han importat %d configuracions</string>
|
<string name="revanced_settings_import_success">S\'han importat %d configuracions</string>
|
||||||
<string name="revanced_settings_import_failure_parse">No s\'ha pogut importar: %s</string>
|
<string name="revanced_settings_import_failure_parse">No s\'ha pogut importar: %s</string>
|
||||||
|
<string name="revanced_language_title">Llenguatge de ReVanced</string>
|
||||||
|
<string name="revanced_language_user_dialog_message">"Les traduccions per a algunes llengües poden faltar o ser incompletes.
|
||||||
|
|
||||||
|
Per traduir nous idiomes, visiteu translate.revanced.app"</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">Kazakh</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">Punjabi</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">Swahili</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. -->
|
||||||
@@ -77,13 +134,16 @@ Toca el botó Continua i permet els canvis d'optimització."</string>
|
|||||||
<string name="revanced_settings_screen_01_ads_title">Anuncis</string>
|
<string name="revanced_settings_screen_01_ads_title">Anuncis</string>
|
||||||
<string name="revanced_settings_screen_02_alt_thumbnails_title">Miniatures alternatives</string>
|
<string name="revanced_settings_screen_02_alt_thumbnails_title">Miniatures alternatives</string>
|
||||||
<string name="revanced_settings_screen_03_feed_title">Canal</string>
|
<string name="revanced_settings_screen_03_feed_title">Canal</string>
|
||||||
<string name="revanced_settings_screen_04_player_title">Reproductor</string>
|
<string name="revanced_settings_screen_04_general_title">General</string>
|
||||||
<string name="revanced_settings_screen_05_general_title">Disposició general</string>
|
<string name="revanced_settings_screen_05_player_title">Reproductor</string>
|
||||||
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
||||||
<string name="revanced_settings_screen_07_seekbar_title">Barra de cerca</string>
|
<string name="revanced_settings_screen_07_seekbar_title">Barra de cerca</string>
|
||||||
<string name="revanced_settings_screen_08_swipe_controls_title">Controls de gestos</string>
|
<string name="revanced_settings_screen_08_swipe_controls_title">Controls de gestos</string>
|
||||||
<string name="revanced_settings_screen_11_misc_title">Misc</string>
|
<string name="revanced_settings_screen_11_misc_title">Altres</string>
|
||||||
<string name="revanced_settings_screen_12_video_title">Vídeo</string>
|
<string name="revanced_settings_screen_12_video_title">Vídeo</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_title">Restaurar els menús de configuració antics</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_summary_on">Es mostren els menús de configuració antics</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_summary_off">No es mostren els menús de configuració antics</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
||||||
<string name="revanced_shorts_disable_background_playback_title">Desactivar la reproducció en segon pla de Shorts</string>
|
<string name="revanced_shorts_disable_background_playback_title">Desactivar la reproducció en segon pla de Shorts</string>
|
||||||
@@ -446,6 +506,9 @@ Aquesta funció només està disponible per a dispositius antics"</string>
|
|||||||
<string name="revanced_swipe_overlay_background_alpha_summary">La visibilitat del fons de la superposició lliscant</string>
|
<string name="revanced_swipe_overlay_background_alpha_summary">La visibilitat del fons de la superposició lliscant</string>
|
||||||
<string name="revanced_swipe_threshold_title">Llindar de magnitud de lliscament</string>
|
<string name="revanced_swipe_threshold_title">Llindar de magnitud de lliscament</string>
|
||||||
<string name="revanced_swipe_threshold_summary">La quantitat de llindar per a què es produeixi el desplaçament</string>
|
<string name="revanced_swipe_threshold_summary">La quantitat de llindar per a què es produeixi el desplaçament</string>
|
||||||
|
<string name="revanced_swipe_change_video_title">Activa la funció de lliscament per canviar vídeos</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_on">Lliscar en mode de pantalla completa canviarà al vídeo següent/anterior</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_off">Lliscar en mode de pantalla completa no canviarà al vídeo següent/anterior</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.autocaptions.autoCaptionsPatch">
|
<patch id="layout.autocaptions.autoCaptionsPatch">
|
||||||
<string name="revanced_auto_captions_title">Desactiva els subtítols automàtics</string>
|
<string name="revanced_auto_captions_title">Desactiva els subtítols automàtics</string>
|
||||||
@@ -629,15 +692,18 @@ Nota: si actives aquesta opció, també s'amaguen els anuncis de vídeo per for
|
|||||||
<string name="revanced_shorts_player_screen_summary">Amaga o mostra components al reproductor de Shorts</string>
|
<string name="revanced_shorts_player_screen_summary">Amaga o mostra components al reproductor de Shorts</string>
|
||||||
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
||||||
<string name="revanced_hide_shorts_home_title">Amaga els Shorts al feed d\'inici</string>
|
<string name="revanced_hide_shorts_home_title">Amaga els Shorts al feed d\'inici</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_on">Els Shorts al feed d\'inici estan ocults</string>
|
<string name="revanced_hide_shorts_home_summary_on">Amagat al feed d\'inici i als vídeos relacionats</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_off">Els Shorts al feed d\'inici es mostren</string>
|
<string name="revanced_hide_shorts_home_summary_off">Es mostra al feed d\'inici i als vídeos relacionats</string>
|
||||||
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
||||||
<string name="revanced_hide_shorts_subscriptions_title">Amaga Shorts al feed de subscripcions</string>
|
<string name="revanced_hide_shorts_subscriptions_title">Amaga Shorts al feed de subscripcions</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_on">Els Shorts al feed de subscripcions estan ocults</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_on">Amagat al feed de subscripcions</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_off">Els Shorts al feed de subscripcions es mostren</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_off">Es mostra al feed de subscripcions</string>
|
||||||
<string name="revanced_hide_shorts_search_title">Amaga Shorts als resultats de la cerca</string>
|
<string name="revanced_hide_shorts_search_title">Amaga Shorts als resultats de la cerca</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_on">Els Shorts als resultats de la cerca estan ocults</string>
|
<string name="revanced_hide_shorts_search_summary_on">Ocult als resultats de la cerca</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_off">Els Shorts als resultats de la cerca es mostren</string>
|
<string name="revanced_hide_shorts_search_summary_off">Es mostra als resultats de la cerca</string>
|
||||||
|
<string name="revanced_hide_shorts_history_title">Amaga els curts a l\'historial de visualitzacions</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_on">Amagat a l\'historial de visualitzacions</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_off">Es mostra a l\'historial de visualitzacions</string>
|
||||||
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
||||||
<string name="revanced_hide_shorts_join_button_title">Amaga el botó d\'unió</string>
|
<string name="revanced_hide_shorts_join_button_title">Amaga el botó d\'unió</string>
|
||||||
<string name="revanced_hide_shorts_join_button_summary_on">El botó d\'unió està ocult</string>
|
<string name="revanced_hide_shorts_join_button_summary_on">El botó d\'unió està ocult</string>
|
||||||
@@ -739,6 +805,13 @@ Nota: si actives aquesta opció, també s'amaguen els anuncis de vídeo per for
|
|||||||
<string name="revanced_hide_player_popup_panels_summary_on">Els panells emergents del reproductor estan ocults</string>
|
<string name="revanced_hide_player_popup_panels_summary_on">Els panells emergents del reproductor estan ocults</string>
|
||||||
<string name="revanced_hide_player_popup_panels_summary_off">Els panells emergents del reproductor estan visibles</string>
|
<string name="revanced_hide_player_popup_panels_summary_off">Els panells emergents del reproductor estan visibles</string>
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.player.fullscreen.exitFullscreenPatch">
|
||||||
|
<string name="revanced_exit_fullscreen_title">Surt del mode de pantalla completa al final del vídeo</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_1">Desactivat</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_2">Vertical</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_3">Horitzontal</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_4">Vertical i horitzontal</string>
|
||||||
|
</patch>
|
||||||
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_title">Obrir vídeos en pantalla completa en format vertical</string>
|
<string name="revanced_open_videos_fullscreen_portrait_title">Obrir vídeos en pantalla completa en format vertical</string>
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_summary_on">Els vídeos s\'obren en pantalla completa</string>
|
<string name="revanced_open_videos_fullscreen_portrait_summary_on">Els vídeos s\'obren en pantalla completa</string>
|
||||||
@@ -1006,6 +1079,23 @@ Preparat per enviar?"</string>
|
|||||||
<string name="revanced_sb_reset">Restablir</string>
|
<string name="revanced_sb_reset">Restablir</string>
|
||||||
<string name="revanced_sb_about">Quant a</string>
|
<string name="revanced_sb_about">Quant a</string>
|
||||||
<string name="revanced_sb_about_api_sum">Les dades són proporcionades per l\'API de SponsorBlock. Toca aquí per a saber-ne més i veure les descàrregues per a altres plataformes</string>
|
<string name="revanced_sb_about_api_sum">Les dades són proporcionades per l\'API de SponsorBlock. Toca aquí per a saber-ne més i veure les descàrregues per a altres plataformes</string>
|
||||||
|
</patch>
|
||||||
|
<patch id="layout.formfactor.changeFormFactorPatch">
|
||||||
|
<string name="revanced_change_form_factor_title">Factor de forma del disseny</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_1">Predeterminat</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_2">Telèfon</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_3">Tauleta</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_4">Automoció</string>
|
||||||
|
<string name="revanced_change_form_factor_user_dialog_message">"Els canvis inclouen:
|
||||||
|
|
||||||
|
Presentació de la tauleta
|
||||||
|
• Les publicacions de la comunitat estan amagades
|
||||||
|
|
||||||
|
Presentació de l'automòbil
|
||||||
|
• El menú d'historial del rellotge està ocult
|
||||||
|
• La pestanya Explora s'ha restaurat
|
||||||
|
• Els curts 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>
|
||||||
@@ -1020,6 +1110,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">26.19.42 - restaura les icones de navegació antigues</string>
|
||||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
<!-- '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_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 & menú de qualitat</string>
|
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Restaura la velocitat àmplia del vídeo & menú de qualitat</string>
|
||||||
@@ -1063,12 +1154,6 @@ Si després es desactiva, es recomana esborrar les dades de l'aplicació per evi
|
|||||||
<string name="revanced_shorts_autoplay_background_summary_on">La reproducció en segon pla dels Shorts es reproduirà automàticament</string>
|
<string name="revanced_shorts_autoplay_background_summary_on">La reproducció en segon pla dels Shorts es reproduirà automàticament</string>
|
||||||
<string name="revanced_shorts_autoplay_background_summary_off">La reproducció en segon pla dels Shorts es repetirà</string>
|
<string name="revanced_shorts_autoplay_background_summary_off">La reproducció en segon pla dels Shorts es repetirà</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.tablet.enableTabletLayoutPatch">
|
|
||||||
<string name="revanced_tablet_layout_title">Habilita el disseny de tauleta</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_on">El disseny de tauleta està habilitat</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_off">El disseny de tauleta està deshabilitat</string>
|
|
||||||
<string name="revanced_tablet_layout_user_dialog_message">Les publicacions de la comunitat no apareixen en els dissenys de tauleta</string>
|
|
||||||
</patch>
|
|
||||||
<patch id="layout.miniplayer.miniplayerPatch">
|
<patch id="layout.miniplayer.miniplayerPatch">
|
||||||
<string name="revanced_miniplayer_screen_title">Minireproductor</string>
|
<string name="revanced_miniplayer_screen_title">Minireproductor</string>
|
||||||
<string name="revanced_miniplayer_screen_summary">Canvia l\'estil del reproductor minimitzat a l\'aplicació</string>
|
<string name="revanced_miniplayer_screen_summary">Canvia l\'estil del reproductor minimitzat a l\'aplicació</string>
|
||||||
@@ -1233,6 +1318,7 @@ Si actives aquesta opció, es poden desbloquejar qualitats de vídeo més altes"
|
|||||||
<string name="revanced_force_original_audio_title">Forçar àudio original</string>
|
<string name="revanced_force_original_audio_title">Forçar àudio original</string>
|
||||||
<string name="revanced_force_original_audio_summary_on">Utilitzant àudio original</string>
|
<string name="revanced_force_original_audio_summary_on">Utilitzant àudio original</string>
|
||||||
<string name="revanced_force_original_audio_summary_off">Utilitzant àudio predeterminat</string>
|
<string name="revanced_force_original_audio_summary_off">Utilitzant àudio predeterminat</string>
|
||||||
|
<string name="revanced_force_original_audio_not_available">Per utilitzar aquesta funció, canvia la suplantació de flux al tipus de client iOS</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
@@ -1260,6 +1346,8 @@ Si actives aquesta opció, es poden desbloquejar qualitats de vídeo més altes"
|
|||||||
<string name="revanced_custom_playback_speeds_invalid">Les velocitats personalitzades han de ser inferiors a %s</string>
|
<string name="revanced_custom_playback_speeds_invalid">Les velocitats personalitzades han de ser inferiors a %s</string>
|
||||||
<string name="revanced_custom_playback_speeds_parse_exception">Velocitats de reproducció personalitzades no vàlides</string>
|
<string name="revanced_custom_playback_speeds_parse_exception">Velocitats de reproducció personalitzades no vàlides</string>
|
||||||
<string name="revanced_custom_playback_speeds_auto">Automàtic</string>
|
<string name="revanced_custom_playback_speeds_auto">Automàtic</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_title">Velocitat personalitzada de mantenir premut</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_summary">Velocitat de reproducció entre 0 i 8</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
||||||
<string name="revanced_remember_playback_speed_last_selected_title">Recorda els canvis de velocitat de reproducció</string>
|
<string name="revanced_remember_playback_speed_last_selected_title">Recorda els canvis de velocitat de reproducció</string>
|
||||||
@@ -1288,74 +1376,27 @@ Si actives aquesta opció, es poden desbloquejar qualitats de vídeo més altes"
|
|||||||
La reproducció de vídeo pot no funcionar"</string>
|
La reproducció de vídeo pot no funcionar"</string>
|
||||||
<string name="revanced_spoof_video_streams_user_dialog_message">Desactivar aquesta configuració pot causar problemes de reproducció de vídeo.</string>
|
<string name="revanced_spoof_video_streams_user_dialog_message">Desactivar aquesta configuració pot causar problemes de reproducció de vídeo.</string>
|
||||||
<string name="revanced_spoof_video_streams_client_type_title">Client predeterminat</string>
|
<string name="revanced_spoof_video_streams_client_type_title">Client predeterminat</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">Força AVC (H.264)</string>
|
<!-- 'no auth' means no authentication -->
|
||||||
|
<string name="revanced_spoof_video_streams_client_type_android_vr_no_auth">Android VR (sense autorització)</string>
|
||||||
|
<string name="revanced_spoof_video_streams_ios_force_avc_title">Forza iOS AVC (H.264)</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">El còdec de vídeo es força a AVC (H.264)</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">El còdec de vídeo es força a AVC (H.264)</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">El còdec de vídeo es determina automàticament</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">El còdec de vídeo es determina automàticament.</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Si actives aquesta opció, és possible que millori la durada de la bateria i es solucioni el tartamudeig de la reproducció.
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"L'activació d'aquesta opció podria millorar la vida útil de la bateria i resoldre els problemes de reproducció irregular.
|
||||||
|
|
||||||
AVC té una resolució màxima de 1080p, el còdec d'àudio Opus no està disponible i la reproducció de vídeo utilitzarà més dades d'Internet que VP9 o AV1."</string>
|
L'AVC té una resolució màxima de 1080p, el còdec d'àudio Opus no està disponible i la reproducció de vídeo utilitzarà més dades d'Internet que VP9 o AV1."</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">Efectes secundaris de la falsificació d\'iOS</string>
|
<string name="revanced_spoof_video_streams_about_ios_tv_title">Efectes secundaris de suplantació d\'iOS</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">"• Els vídeos privats per a nens potser no es reprodueixen
|
<string name="revanced_spoof_video_streams_about_ios_tv_summary">"• Les pel·lícules o vídeos de pagament poden no reproduir-se
|
||||||
• Els vídeos finalitzen 1 segon abans"</string>
|
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Efecte secundaris de la suplantació d\'Android VR</string>
|
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• És possible que els vídeos infantils no es reprodueixin
|
|
||||||
• El menú de pistes d'àudio no està disponible
|
|
||||||
• El volum estable no està disponible
|
• El volum estable no està disponible
|
||||||
• L'opció Forçar àudio original no està disponible"</string>
|
• Els vídeos s'aturen 1 segon abans"</string>
|
||||||
<string name="revanced_spoof_video_streams_language_title">Idioma de la transmissió d\'àudio per defecte</string>
|
<string name="revanced_spoof_video_streams_about_android_title">Efectes secundaris de la suplantació d\'Android</string>
|
||||||
<string name="revanced_spoof_video_streams_language_DEFAULT">Idioma de l\'aplicació</string>
|
<string name="revanced_spoof_video_streams_about_android_summary">"• Menú de pistes d'àudio no disponible
|
||||||
<string name="revanced_spoof_video_streams_language_AR">Àrab</string>
|
• El volum estable no està disponible
|
||||||
<string name="revanced_spoof_video_streams_language_AZ">Azerbaidjanès</string>
|
• Forçar l'àudio original no està disponible"</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BG">Búlgar</string>
|
<string name="revanced_spoof_video_streams_about_no_av1">• Sense còdec de vídeo AV1</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BN">Bengalí</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_title">Mostra a l\'apartat \'Dades per a experts\'</string>
|
||||||
<string name="revanced_spoof_video_streams_language_CA">Català</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_on">El tipus de client es mostra a l\'apartat \'Dades per a experts\'</string>
|
||||||
<string name="revanced_spoof_video_streams_language_CS">Txec</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">El client s\'amaga a l\'apartat \'Dades per a experts\'</string>
|
||||||
<string name="revanced_spoof_video_streams_language_DA">Danès</string>
|
<string name="revanced_spoof_video_streams_language_title">Idioma de l\'àudio per defecte a VR</string>
|
||||||
<string name="revanced_spoof_video_streams_language_DE">Alemany</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EL">Grec</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EN">Anglès</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ES">Espanyol</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ET">Estonià</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FA">Persa</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FI">Finès</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FR">Francès</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_GU">Gujarati</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HI">Hindi</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HR">Croat</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HU">Hongarès</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ID">Indonesi</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_IT">Italià</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_JA">Japonès</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KK">Kazakhstanès</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KO">Coreà</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LT">Lituà</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LV">Letó</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MK">Macedoni</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MN">Mongol</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MR">Marathi</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MS">Malai</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MY">Birmano</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_NL">Neerlandès</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_OR">Odia</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PA">Punjabi</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PL">Polonès</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_BR">Portuguès (Brasil)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_PT">Portuguès (Portugal)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RO">Romanès</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RU">Rus</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SK">Eslovac</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SL">Eslovè</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SR">Serbi</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SV">Suec</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SW">Suahili</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TA">Tàmils</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TE">Telugu</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TH">Tailandès</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TR">Turc</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UK">Ucraïnès</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UR">Urdu</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_VI">Vietnamita</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ZH">Xinès</string>
|
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_check_environment_not_near_patch_time_invalid">Datum sestavení souboru APK je poškozeno</string>
|
<string name="revanced_check_environment_not_near_patch_time_invalid">Datum sestavení souboru APK je poškozeno</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.settings.settingsResourcePatch">
|
<patch id="misc.settings.settingsResourcePatch">
|
||||||
|
<string name="revanced_settings_submenu_title">Nastavení</string>
|
||||||
<string name="revanced_settings_title">ReVanced</string>
|
<string name="revanced_settings_title">ReVanced</string>
|
||||||
<string name="revanced_settings_confirm_user_dialog_title">Přejete si pokračovat?</string>
|
<string name="revanced_settings_confirm_user_dialog_title">Přejete si pokračovat?</string>
|
||||||
<string name="revanced_settings_reset">Výchozí</string>
|
<string name="revanced_settings_reset">Výchozí</string>
|
||||||
@@ -43,6 +44,62 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_settings_import_reset">Nastavení ReVanced obnoveno do výchozího stavu</string>
|
<string name="revanced_settings_import_reset">Nastavení ReVanced obnoveno do výchozího stavu</string>
|
||||||
<string name="revanced_settings_import_success">Importováno %d nastavení</string>
|
<string name="revanced_settings_import_success">Importováno %d nastavení</string>
|
||||||
<string name="revanced_settings_import_failure_parse">Importováni selhalo: %s</string>
|
<string name="revanced_settings_import_failure_parse">Importováni selhalo: %s</string>
|
||||||
|
<string name="revanced_language_title">Jazyk ReVanced</string>
|
||||||
|
<string name="revanced_language_user_dialog_message">"Překlady pro některé jazyky mohou chybět nebo být neúplné.
|
||||||
|
|
||||||
|
Nové jazyky přeložíte na translate.revanced.app"</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">Gujarati</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. -->
|
||||||
@@ -77,13 +134,16 @@ Klepněte na tlačítko Pokračovat a povolte změny optimalizace."</string>
|
|||||||
<string name="revanced_settings_screen_01_ads_title">Reklamy</string>
|
<string name="revanced_settings_screen_01_ads_title">Reklamy</string>
|
||||||
<string name="revanced_settings_screen_02_alt_thumbnails_title">Alternativní náhledy</string>
|
<string name="revanced_settings_screen_02_alt_thumbnails_title">Alternativní náhledy</string>
|
||||||
<string name="revanced_settings_screen_03_feed_title">Přísun</string>
|
<string name="revanced_settings_screen_03_feed_title">Přísun</string>
|
||||||
<string name="revanced_settings_screen_04_player_title">Přehrávač</string>
|
<string name="revanced_settings_screen_04_general_title">Obecné</string>
|
||||||
<string name="revanced_settings_screen_05_general_title">Celkové rozložení</string>
|
<string name="revanced_settings_screen_05_player_title">Přehrávač</string>
|
||||||
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
||||||
<string name="revanced_settings_screen_07_seekbar_title">Lišta</string>
|
<string name="revanced_settings_screen_07_seekbar_title">Lišta</string>
|
||||||
<string name="revanced_settings_screen_08_swipe_controls_title">Ovládání gesty</string>
|
<string name="revanced_settings_screen_08_swipe_controls_title">Ovládání gesty</string>
|
||||||
<string name="revanced_settings_screen_11_misc_title">Ostatní</string>
|
<string name="revanced_settings_screen_11_misc_title">Různé</string>
|
||||||
<string name="revanced_settings_screen_12_video_title">Video</string>
|
<string name="revanced_settings_screen_12_video_title">Video</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_title">Obnovit staré menu nastavení</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_summary_on">Staré menu nastavení se zobrazují</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_summary_off">Staré menu nastavení se nezobrazují</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
||||||
<string name="revanced_shorts_disable_background_playback_title">Zakázat automatické přehrávání Shorts v pozadí</string>
|
<string name="revanced_shorts_disable_background_playback_title">Zakázat automatické přehrávání Shorts v pozadí</string>
|
||||||
@@ -446,6 +506,9 @@ Tato funkce je dostupná pouze pro starší zařízení"</string>
|
|||||||
<string name="revanced_swipe_overlay_background_alpha_summary">Viditelnost pozadí překrytí gesta</string>
|
<string name="revanced_swipe_overlay_background_alpha_summary">Viditelnost pozadí překrytí gesta</string>
|
||||||
<string name="revanced_swipe_threshold_title">Práh vynucení gesta</string>
|
<string name="revanced_swipe_threshold_title">Práh vynucení gesta</string>
|
||||||
<string name="revanced_swipe_threshold_summary">Velikost prahu pro provedení gesta</string>
|
<string name="revanced_swipe_threshold_summary">Velikost prahu pro provedení gesta</string>
|
||||||
|
<string name="revanced_swipe_change_video_title">Povolit přejetí prstem pro změnu videa</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_on">Přejetí prstem v režimu celé obrazovky změní video na další/předchozí</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_off">Přejetí prstem v režimu celé obrazovky nebude video měnit na další/předchozí</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.autocaptions.autoCaptionsPatch">
|
<patch id="layout.autocaptions.autoCaptionsPatch">
|
||||||
<string name="revanced_auto_captions_title">Zakázat automatické titulky</string>
|
<string name="revanced_auto_captions_title">Zakázat automatické titulky</string>
|
||||||
@@ -629,15 +692,18 @@ Poznámka: Povolení této funkce také vynuceně skryje video reklamy"</string>
|
|||||||
<string name="revanced_shorts_player_screen_summary">Skrýt nebo zobrazit komponenty v přehrávači Shorts</string>
|
<string name="revanced_shorts_player_screen_summary">Skrýt nebo zobrazit komponenty v přehrávači Shorts</string>
|
||||||
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
||||||
<string name="revanced_hide_shorts_home_title">Skrýt Shorts v Domů</string>
|
<string name="revanced_hide_shorts_home_title">Skrýt Shorts v Domů</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_on">Shorts jsou schovány v Domů</string>
|
<string name="revanced_hide_shorts_home_summary_on">Skryto v domovskom kanáli a súvisiacich videách</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_off">Shorts jsou zobrazeny v Domů</string>
|
<string name="revanced_hide_shorts_home_summary_off">Zobrazené v domovskom kanáli a súvisiacich videách</string>
|
||||||
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
||||||
<string name="revanced_hide_shorts_subscriptions_title">Schovat Shorts v odběrovém feedu</string>
|
<string name="revanced_hide_shorts_subscriptions_title">Schovat Shorts v odběrovém feedu</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_on">Shorts jsou v odběrovém feedu schovány</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_on">Skryté v odběrech</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_off">Shorts jsou v odběrovém feedu zobazeny</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_off">Zobrazeno v odběrech</string>
|
||||||
<string name="revanced_hide_shorts_search_title">Skrýt Shorts ve výsledcích vyhledávání</string>
|
<string name="revanced_hide_shorts_search_title">Skrýt Shorts ve výsledcích vyhledávání</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_on">Shorts jsou ve výsledcích vyhledávání skryté</string>
|
<string name="revanced_hide_shorts_search_summary_on">Skryté ve výsledcích vyhledávání</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_off">Shorts jsou ve výsledcích vyhledávání viditelné</string>
|
<string name="revanced_hide_shorts_search_summary_off">Zobrazeno ve výsledcích vyhledávání</string>
|
||||||
|
<string name="revanced_hide_shorts_history_title">Skrýt Shorts z historie sledování</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_on">Skryté v historii sledování</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_off">Zobrazené v historii sledování</string>
|
||||||
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
||||||
<string name="revanced_hide_shorts_join_button_title">Skrýt tlačítko Připojit se</string>
|
<string name="revanced_hide_shorts_join_button_title">Skrýt tlačítko Připojit se</string>
|
||||||
<string name="revanced_hide_shorts_join_button_summary_on">Tlačítko Připojit se je skryto</string>
|
<string name="revanced_hide_shorts_join_button_summary_on">Tlačítko Připojit se je skryto</string>
|
||||||
@@ -739,6 +805,13 @@ Poznámka: Povolení této funkce také vynuceně skryje video reklamy"</string>
|
|||||||
<string name="revanced_hide_player_popup_panels_summary_on">Vyskakovací panely přehrávače jsou skryté</string>
|
<string name="revanced_hide_player_popup_panels_summary_on">Vyskakovací panely přehrávače jsou skryté</string>
|
||||||
<string name="revanced_hide_player_popup_panels_summary_off">Vyskakovací panely přehrávače jsou zobrazeny</string>
|
<string name="revanced_hide_player_popup_panels_summary_off">Vyskakovací panely přehrávače jsou zobrazeny</string>
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.player.fullscreen.exitFullscreenPatch">
|
||||||
|
<string name="revanced_exit_fullscreen_title">Ukončete režim celé obrazovky na konci videa</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_1">Zakázáno</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_2">Na výšku</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_3">Na šířku</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_4">Na výšku i na šířku</string>
|
||||||
|
</patch>
|
||||||
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_title">Otevřít videa v režimu na celou obrazovku na výšku</string>
|
<string name="revanced_open_videos_fullscreen_portrait_title">Otevřít videa v režimu na celou obrazovku na výšku</string>
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_summary_on">Videa se otevírají na celou obrazovku</string>
|
<string name="revanced_open_videos_fullscreen_portrait_summary_on">Videa se otevírají na celou obrazovku</string>
|
||||||
@@ -1006,6 +1079,23 @@ Jste připraveni k odeslání?"</string>
|
|||||||
<string name="revanced_sb_reset">Výchozí</string>
|
<string name="revanced_sb_reset">Výchozí</string>
|
||||||
<string name="revanced_sb_about">O aplikaci</string>
|
<string name="revanced_sb_about">O aplikaci</string>
|
||||||
<string name="revanced_sb_about_api_sum">Data poskytuje rozhraní API SponsorBlock. Klepněte zde, abyste se dozvěděli více a zobrazili si soubory ke stažení pro další platformy</string>
|
<string name="revanced_sb_about_api_sum">Data poskytuje rozhraní API SponsorBlock. Klepněte zde, abyste se dozvěděli více a zobrazili si soubory ke stažení pro další platformy</string>
|
||||||
|
</patch>
|
||||||
|
<patch id="layout.formfactor.changeFormFactorPatch">
|
||||||
|
<string name="revanced_change_form_factor_title">Rozvržení formuláře</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_1">Výchozí</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_2">Telefon</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_3">Tablet</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_4">Automobilový</string>
|
||||||
|
<string name="revanced_change_form_factor_user_dialog_message">"Změny zahrnují:
|
||||||
|
|
||||||
|
Rozložení tabletu
|
||||||
|
• Příspěvky komunity jsou skryté
|
||||||
|
|
||||||
|
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
|
||||||
|
• Kanál je organizován podle témat a kanálu"</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>
|
||||||
@@ -1020,6 +1110,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 - Obnovit ikony staré navigace a panelu nástrojů</string>
|
||||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
<!-- '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_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_2">18.20.39 - Obnovení široké nabídky rychlosti a kvality videa</string>
|
||||||
@@ -1063,12 +1154,6 @@ Pokud bude později vypnuta, doporučujeme vymazat data aplikace, aby se zabrán
|
|||||||
<string name="revanced_shorts_autoplay_background_summary_on">Přehrávání Shorts v pozadí se bude automaticky přehrávat</string>
|
<string name="revanced_shorts_autoplay_background_summary_on">Přehrávání Shorts v pozadí se bude automaticky přehrávat</string>
|
||||||
<string name="revanced_shorts_autoplay_background_summary_off">Přehrávání Shorts v pozadí se bude opakovat</string>
|
<string name="revanced_shorts_autoplay_background_summary_off">Přehrávání Shorts v pozadí se bude opakovat</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.tablet.enableTabletLayoutPatch">
|
|
||||||
<string name="revanced_tablet_layout_title">Povolit rozvržení tabletu</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_on">Rozvržení tabletu je povoleno</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_off">Rozvržení tabletu je zakázáno</string>
|
|
||||||
<string name="revanced_tablet_layout_user_dialog_message">Příspěvky komunity se v rozvržení tabletu nezobrazují</string>
|
|
||||||
</patch>
|
|
||||||
<patch id="layout.miniplayer.miniplayerPatch">
|
<patch id="layout.miniplayer.miniplayerPatch">
|
||||||
<string name="revanced_miniplayer_screen_title">Mini přehrávač</string>
|
<string name="revanced_miniplayer_screen_title">Mini přehrávač</string>
|
||||||
<string name="revanced_miniplayer_screen_summary">Změnit styl minimalizovaného přehrávače v aplikaci</string>
|
<string name="revanced_miniplayer_screen_summary">Změnit styl minimalizovaného přehrávače v aplikaci</string>
|
||||||
@@ -1232,6 +1317,7 @@ Povolením této funkce lze odemknout vyšší kvality videa"</string>
|
|||||||
<string name="revanced_force_original_audio_title">Vynutit původní zvuk</string>
|
<string name="revanced_force_original_audio_title">Vynutit původní zvuk</string>
|
||||||
<string name="revanced_force_original_audio_summary_on">Používání původního zvuku</string>
|
<string name="revanced_force_original_audio_summary_on">Používání původního zvuku</string>
|
||||||
<string name="revanced_force_original_audio_summary_off">Používání výchozího zvuku</string>
|
<string name="revanced_force_original_audio_summary_off">Používání výchozího zvuku</string>
|
||||||
|
<string name="revanced_force_original_audio_not_available">Pro použití této funkce změňte typ klienta streamu na iOS</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
@@ -1259,6 +1345,8 @@ Povolením této funkce lze odemknout vyšší kvality videa"</string>
|
|||||||
<string name="revanced_custom_playback_speeds_invalid">Vlastní rychlosti musí být menší než %s</string>
|
<string name="revanced_custom_playback_speeds_invalid">Vlastní rychlosti musí být menší než %s</string>
|
||||||
<string name="revanced_custom_playback_speeds_parse_exception">Neplatné vlastní rychlosti přehrávání</string>
|
<string name="revanced_custom_playback_speeds_parse_exception">Neplatné vlastní rychlosti přehrávání</string>
|
||||||
<string name="revanced_custom_playback_speeds_auto">Automaticky</string>
|
<string name="revanced_custom_playback_speeds_auto">Automaticky</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_title">Vlastní rychlost stisknutí a podržení</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_summary">Rychlost přehrávání 0 až 8</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
||||||
<string name="revanced_remember_playback_speed_last_selected_title">Pamatovat si změny rychlosti přehrávání</string>
|
<string name="revanced_remember_playback_speed_last_selected_title">Pamatovat si změny rychlosti přehrávání</string>
|
||||||
@@ -1287,74 +1375,27 @@ Povolením této funkce lze odemknout vyšší kvality videa"</string>
|
|||||||
Přehrávání videa nemusí fungovat"</string>
|
Přehrávání videa nemusí fungovat"</string>
|
||||||
<string name="revanced_spoof_video_streams_user_dialog_message">Vypnutí tohoto nastavení může způsobit problémy s přehráváním videa.</string>
|
<string name="revanced_spoof_video_streams_user_dialog_message">Vypnutí tohoto nastavení může způsobit problémy s přehráváním videa.</string>
|
||||||
<string name="revanced_spoof_video_streams_client_type_title">Výchozí klient</string>
|
<string name="revanced_spoof_video_streams_client_type_title">Výchozí klient</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">Vynutit AVC (H.264)</string>
|
<!-- 'no auth' means no authentication -->
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video kodek je vynucen na AVC (H.264)</string>
|
<string name="revanced_spoof_video_streams_client_type_android_vr_no_auth">Android VR (bez ověření)</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video kodek je určen automaticky</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_title">Vynucení kodeku iOS AVC (H.264)</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Povolením této funkce se může zlepšit výdrž baterie a opravit zadrhávání přehrávání.
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Kodek videa je vynucen na AVC (H.264)</string>
|
||||||
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Kodek videa je určen automaticky</string>
|
||||||
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Povolení této funkce může zlepšit výdrž baterie a opravit sekání videa.
|
||||||
|
|
||||||
AVC má maximální rozlišení 1080p, audio kodek Opus není dostupný a přehrávání videa bude používat více internetových dat než VP9 nebo AV1."</string>
|
AVC má maximální rozlišení 1080p, zvukový kodek Opus není dostupný a přehrávání videa bude používat více dat než VP9 nebo AV1."</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">Vedlejší účinky napodobování iOS</string>
|
<string name="revanced_spoof_video_streams_about_ios_tv_title">iOS spoofing vedlejší účinky</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">"• Soukromá dětská videa se nemusí přehrávat
|
<string name="revanced_spoof_video_streams_about_ios_tv_summary">"• Filmy nebo placená videa se nemusí přehrávat
|
||||||
|
• Stabilní hlasitost není k dispozici
|
||||||
• Videa končí o 1 sekundu dříve"</string>
|
• Videa končí o 1 sekundu dříve"</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Vedlejší účinky napodobování Android VR</string>
|
<string name="revanced_spoof_video_streams_about_android_title">Vedlejší účinky spoofingu Androidu</string>
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Dětská videa se nemusí přehrávat
|
<string name="revanced_spoof_video_streams_about_android_summary">"• Chybí nabídka zvukových stop
|
||||||
• Chybí nabídka zvukových stop
|
|
||||||
• Není k dispozici stabilní hlasitost
|
• Není k dispozici stabilní hlasitost
|
||||||
• Není k dispozici vynucení původního zvuku"</string>
|
• Není k dispozici možnost vynucení originálního zvuku"</string>
|
||||||
<string name="revanced_spoof_video_streams_language_title">Výchozí jazyk zvukového streamu</string>
|
<string name="revanced_spoof_video_streams_about_no_av1">• Žádný video kodek AV1</string>
|
||||||
<string name="revanced_spoof_video_streams_language_DEFAULT">Jazyk aplikace</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_title">Zobrazit ve statistikách pro nadšence</string>
|
||||||
<string name="revanced_spoof_video_streams_language_AR">Arabsky</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_on">Typ klienta se zobrazuje ve statistikách pro nadšence</string>
|
||||||
<string name="revanced_spoof_video_streams_language_AZ">Ázerbájdžánsky</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">Klient je skrytý ve statistikách pro nadšence</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BG">Bulharsky</string>
|
<string name="revanced_spoof_video_streams_language_title">Výchozí jazyk zvukového streamu ve VR</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BN">Bengálsky</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_CA">Katalánsky</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_CS">Česky</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_DA">Dánsky</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_DE">Německy</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EL">Řecky</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EN">Angličtina</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ES">Španělsky</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ET">Estonsky</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FA">Peršsky</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FI">Finský</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FR">Francouzština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_GU">Gudžarátština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HI">Hindština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HR">Chorvatština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HU">Maďarština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ID">Indonéština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_IT">Italština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_JA">Japonština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KK">Kazaština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KO">Korejština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LT">Litevština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LV">Lotyština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MK">Makedonština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MN">Mongolština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MR">Maráthština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MS">Malajština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MY">Barmánština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_NL">Nizozemština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_OR">Odijština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PA">Paňdžábština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PL">Polština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_BR">Portugalština (Brazílie)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_PT">Portugalština (Portugalsko)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RO">Rumunština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RU">Ruština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SK">Slovenština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SL">Slovinština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SR">Srbština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SV">Švédština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SW">Svahilština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TA">Tamilština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TE">Telugu</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TH">Thajština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TR">Turečtina</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UK">Ukrajinština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UR">Urdu</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_VI">Vietnamština</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ZH">Čínština</string>
|
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_check_environment_not_near_patch_time_invalid">APK byggedato er ødelagt</string>
|
<string name="revanced_check_environment_not_near_patch_time_invalid">APK byggedato er ødelagt</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.settings.settingsResourcePatch">
|
<patch id="misc.settings.settingsResourcePatch">
|
||||||
|
<string name="revanced_settings_submenu_title">Indstillinger</string>
|
||||||
<string name="revanced_settings_title">ReVanced</string>
|
<string name="revanced_settings_title">ReVanced</string>
|
||||||
<string name="revanced_settings_confirm_user_dialog_title">Ønsker du at fortsætte?</string>
|
<string name="revanced_settings_confirm_user_dialog_title">Ønsker du at fortsætte?</string>
|
||||||
<string name="revanced_settings_reset">Nulstil</string>
|
<string name="revanced_settings_reset">Nulstil</string>
|
||||||
@@ -43,6 +44,62 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_settings_import_reset">ReVanced indstillinger nulstillet til standard</string>
|
<string name="revanced_settings_import_reset">ReVanced indstillinger nulstillet til standard</string>
|
||||||
<string name="revanced_settings_import_success">Importerede %d indstillinger</string>
|
<string name="revanced_settings_import_success">Importerede %d indstillinger</string>
|
||||||
<string name="revanced_settings_import_failure_parse">Import mislykkedes: %s</string>
|
<string name="revanced_settings_import_failure_parse">Import mislykkedes: %s</string>
|
||||||
|
<string name="revanced_language_title">ReVanced-sprog</string>
|
||||||
|
<string name="revanced_language_user_dialog_message">"Oversættelser for nogle sprog mangler muligvis eller er ufuldstændige.
|
||||||
|
|
||||||
|
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_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">Katalansk</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">Kiswahili</string>
|
||||||
|
<string name="revanced_language_TA">Kithamil</string>
|
||||||
|
<string name="revanced_language_TE">Telugu</string>
|
||||||
|
<string name="revanced_language_TH">Thailandsk</string>
|
||||||
|
<string name="revanced_language_TR">Tyrkisk</string>
|
||||||
|
<string name="revanced_language_UK">Ukrainsk</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 / Eksport</string>
|
<string name="revanced_pref_import_export_title">Import / Eksport</string>
|
||||||
<string name="revanced_pref_import_export_summary">Importer / Eksport ReVanced indstillinger</string>
|
<string name="revanced_pref_import_export_summary">Importer / Eksport ReVanced indstillinger</string>
|
||||||
<!-- Settings about dialog. -->
|
<!-- Settings about dialog. -->
|
||||||
@@ -77,13 +134,16 @@ Tryk på fortsætknappen, og tillad ændringer af optimering."</string>
|
|||||||
<string name="revanced_settings_screen_01_ads_title">Annoncer</string>
|
<string name="revanced_settings_screen_01_ads_title">Annoncer</string>
|
||||||
<string name="revanced_settings_screen_02_alt_thumbnails_title">Alternative miniaturer</string>
|
<string name="revanced_settings_screen_02_alt_thumbnails_title">Alternative miniaturer</string>
|
||||||
<string name="revanced_settings_screen_03_feed_title">Fodring</string>
|
<string name="revanced_settings_screen_03_feed_title">Fodring</string>
|
||||||
<string name="revanced_settings_screen_04_player_title">Spiller</string>
|
<string name="revanced_settings_screen_04_general_title">Generelt</string>
|
||||||
<string name="revanced_settings_screen_05_general_title">Generelt layout</string>
|
<string name="revanced_settings_screen_05_player_title">Afspiller</string>
|
||||||
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
||||||
<string name="revanced_settings_screen_07_seekbar_title">Søgebjælke</string>
|
<string name="revanced_settings_screen_07_seekbar_title">Søgebjælke</string>
|
||||||
<string name="revanced_settings_screen_08_swipe_controls_title">Stryg kontrolelementer</string>
|
<string name="revanced_settings_screen_08_swipe_controls_title">Stryg kontrolelementer</string>
|
||||||
<string name="revanced_settings_screen_11_misc_title">Diverse</string>
|
<string name="revanced_settings_screen_11_misc_title">Diverse</string>
|
||||||
<string name="revanced_settings_screen_12_video_title">Videoer</string>
|
<string name="revanced_settings_screen_12_video_title">Videoer</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_title">Gendan gamle indstillingsmenuer</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_summary_on">Gamle indstillingsmenuer vises</string>
|
||||||
|
<string name="revanced_restore_old_settings_menus_summary_off">Gamle indstillingsmenuer vises ikke</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
<patch id="misc.backgroundplayback.backgroundPlaybackPatch">
|
||||||
<string name="revanced_shorts_disable_background_playback_title">Deaktiver afspilning af Shorts i baggrunden</string>
|
<string name="revanced_shorts_disable_background_playback_title">Deaktiver afspilning af Shorts i baggrunden</string>
|
||||||
@@ -446,6 +506,9 @@ Denne funktion er kun tilgængelig for ældre enheder"</string>
|
|||||||
<string name="revanced_swipe_overlay_background_alpha_summary">Synligheden af swipe overlay baggrund</string>
|
<string name="revanced_swipe_overlay_background_alpha_summary">Synligheden af swipe overlay baggrund</string>
|
||||||
<string name="revanced_swipe_threshold_title">Stryg størrelse tærskel</string>
|
<string name="revanced_swipe_threshold_title">Stryg størrelse tærskel</string>
|
||||||
<string name="revanced_swipe_threshold_summary">Beløbet for tærskelværdi for stryg der skal ske</string>
|
<string name="revanced_swipe_threshold_summary">Beløbet for tærskelværdi for stryg der skal ske</string>
|
||||||
|
<string name="revanced_swipe_change_video_title">Aktivér swipe for at skifte videoer</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_on">Strygning i fuldskærmstilstand vil ændre til den næste/forrige video</string>
|
||||||
|
<string name="revanced_swipe_change_video_summary_off">Strygning i fuldskærmstilstand vil ikke ændre til den næste/forrige video</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.autocaptions.autoCaptionsPatch">
|
<patch id="layout.autocaptions.autoCaptionsPatch">
|
||||||
<string name="revanced_auto_captions_title">Deaktivér auto-billedtekster</string>
|
<string name="revanced_auto_captions_title">Deaktivér auto-billedtekster</string>
|
||||||
@@ -629,15 +692,18 @@ Bemærk: Aktivering af dette skjuler også videoannoncer"</string>
|
|||||||
<string name="revanced_shorts_player_screen_summary">Skjul eller vis komponenter i Shorts-afspilleren</string>
|
<string name="revanced_shorts_player_screen_summary">Skjul eller vis komponenter i Shorts-afspilleren</string>
|
||||||
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
<!-- 'home' should be translated using the same localized wording YouTube displays for the home tab. -->
|
||||||
<string name="revanced_hide_shorts_home_title">Skjul Shorts i hjemmefeed</string>
|
<string name="revanced_hide_shorts_home_title">Skjul Shorts i hjemmefeed</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_on">Shorts i hjemmet feed er skjult</string>
|
<string name="revanced_hide_shorts_home_summary_on">Skjult i startsiden og relaterede videoer</string>
|
||||||
<string name="revanced_hide_shorts_home_summary_off">Shorts i hjemmet feed er vist</string>
|
<string name="revanced_hide_shorts_home_summary_off">Vises i startsiden og relaterede videoer</string>
|
||||||
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
<!-- 'subscription' should be translated using the same localized wording YouTube displays for the subscription tab. -->
|
||||||
<string name="revanced_hide_shorts_subscriptions_title">Skjul Shorts i abonnementsfeed</string>
|
<string name="revanced_hide_shorts_subscriptions_title">Skjul Shorts i abonnementsfeed</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_on">Shorts i abonnementsfeed er skjult</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_on">Skjult i abonnementsfeedet</string>
|
||||||
<string name="revanced_hide_shorts_subscriptions_summary_off">Shorts i abonnementsfeed vises</string>
|
<string name="revanced_hide_shorts_subscriptions_summary_off">Vises i abonnementsfeedet</string>
|
||||||
<string name="revanced_hide_shorts_search_title">Skjul Shorts i søgeresultater</string>
|
<string name="revanced_hide_shorts_search_title">Skjul Shorts i søgeresultater</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_on">Shorts i søgeresultater er skjult</string>
|
<string name="revanced_hide_shorts_search_summary_on">Skjult i søgeresultater</string>
|
||||||
<string name="revanced_hide_shorts_search_summary_off">Korte i søgeresultater vises</string>
|
<string name="revanced_hide_shorts_search_summary_off">Vises i søgeresultater</string>
|
||||||
|
<string name="revanced_hide_shorts_history_title">Skjul shorts i historik</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_on">Skjult i historikken</string>
|
||||||
|
<string name="revanced_hide_shorts_history_summary_off">Vises i historik</string>
|
||||||
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
<!-- 'join' should be translated using the same localized wording YouTube displays for the button. -->
|
||||||
<string name="revanced_hide_shorts_join_button_title">Skjul tilmeldingsknap</string>
|
<string name="revanced_hide_shorts_join_button_title">Skjul tilmeldingsknap</string>
|
||||||
<string name="revanced_hide_shorts_join_button_summary_on">Deltag-knappen er skjult</string>
|
<string name="revanced_hide_shorts_join_button_summary_on">Deltag-knappen er skjult</string>
|
||||||
@@ -739,6 +805,13 @@ Bemærk: Aktivering af dette skjuler også videoannoncer"</string>
|
|||||||
<string name="revanced_hide_player_popup_panels_summary_on">Spiller popup paneler er skjult</string>
|
<string name="revanced_hide_player_popup_panels_summary_on">Spiller popup paneler er skjult</string>
|
||||||
<string name="revanced_hide_player_popup_panels_summary_off">Spiller popup paneler vises</string>
|
<string name="revanced_hide_player_popup_panels_summary_off">Spiller popup paneler vises</string>
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.player.fullscreen.exitFullscreenPatch">
|
||||||
|
<string name="revanced_exit_fullscreen_title">Afslut fuldskærmstilstand ved videoens afslutning</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_1">Deaktiveret</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_2">Portræt</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_3">Landskab</string>
|
||||||
|
<string name="revanced_exit_fullscreen_entry_4">Portræt og landskab</string>
|
||||||
|
</patch>
|
||||||
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
<patch id="layout.player.fullscreen.openVideosFullscreen">
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_title">Åbn videoer i fuldskærm portræt</string>
|
<string name="revanced_open_videos_fullscreen_portrait_title">Åbn videoer i fuldskærm portræt</string>
|
||||||
<string name="revanced_open_videos_fullscreen_portrait_summary_on">Videoer åbne fuld skærm</string>
|
<string name="revanced_open_videos_fullscreen_portrait_summary_on">Videoer åbne fuld skærm</string>
|
||||||
@@ -1007,6 +1080,23 @@ Er du klar til at indsende?"</string>
|
|||||||
<string name="revanced_sb_reset">Nulstil</string>
|
<string name="revanced_sb_reset">Nulstil</string>
|
||||||
<string name="revanced_sb_about">Om</string>
|
<string name="revanced_sb_about">Om</string>
|
||||||
<string name="revanced_sb_about_api_sum">Data leveres af SponsorBlock API. Tryk her for at få flere oplysninger og se downloads til andre platforme</string>
|
<string name="revanced_sb_about_api_sum">Data leveres af SponsorBlock API. Tryk her for at få flere oplysninger og se downloads til andre platforme</string>
|
||||||
|
</patch>
|
||||||
|
<patch id="layout.formfactor.changeFormFactorPatch">
|
||||||
|
<string name="revanced_change_form_factor_title">Layout-formfaktor</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_1">Standard</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_2">Telefon</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_3">Tablet</string>
|
||||||
|
<string name="revanced_change_form_factor_entry_4">Bil</string>
|
||||||
|
<string name="revanced_change_form_factor_user_dialog_message">"Ændringer omfatter:
|
||||||
|
|
||||||
|
Tabletlayout
|
||||||
|
• Fællesindlæg er skjult
|
||||||
|
|
||||||
|
Bil layout
|
||||||
|
• Se historik-menuen er skjult
|
||||||
|
• Udforsk-fanen er gendannet
|
||||||
|
• Shorts åbnes i den almindelige afspiller
|
||||||
|
• Feedet er organiseret efter emner og kanal"</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>
|
||||||
@@ -1021,6 +1111,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 navigations- og værktøjslinjeikoner</string>
|
||||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
<!-- '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_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 & kvalitet menu</string>
|
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Gendan bred video hastighed & kvalitet menu</string>
|
||||||
@@ -1064,12 +1155,6 @@ Hvis det senere slås fra, anbefales det at rydde app-dataene for at forhindre U
|
|||||||
<string name="revanced_shorts_autoplay_background_summary_on">Shorts i baggrunden afspilles automatisk</string>
|
<string name="revanced_shorts_autoplay_background_summary_on">Shorts i baggrunden afspilles automatisk</string>
|
||||||
<string name="revanced_shorts_autoplay_background_summary_off">Shorts i baggrunden gentages</string>
|
<string name="revanced_shorts_autoplay_background_summary_off">Shorts i baggrunden gentages</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.tablet.enableTabletLayoutPatch">
|
|
||||||
<string name="revanced_tablet_layout_title">Aktivér tabletlayout</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_on">Tablet layout er aktiveret</string>
|
|
||||||
<string name="revanced_tablet_layout_summary_off">Tablet layout er deaktiveret</string>
|
|
||||||
<string name="revanced_tablet_layout_user_dialog_message">Fællesskabsindlæg vises ikke på tabletlayouts</string>
|
|
||||||
</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">Ændre stilen for den i app minimeret afspiller</string>
|
||||||
@@ -1233,6 +1318,7 @@ Aktivering af dette kan låse op for højere videokvalitet"</string>
|
|||||||
<string name="revanced_force_original_audio_title">Tving original lyd</string>
|
<string name="revanced_force_original_audio_title">Tving original lyd</string>
|
||||||
<string name="revanced_force_original_audio_summary_on">Brug original lyd</string>
|
<string name="revanced_force_original_audio_summary_on">Brug original lyd</string>
|
||||||
<string name="revanced_force_original_audio_summary_off">Brug standard lyd</string>
|
<string name="revanced_force_original_audio_summary_off">Brug standard lyd</string>
|
||||||
|
<string name="revanced_force_original_audio_not_available">Tilføj musik til denne historie</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.quality.rememberVideoQualityPatch">
|
<patch id="video.quality.rememberVideoQualityPatch">
|
||||||
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
<!-- Translations should use the same text as revanced_custom_playback_speeds_auto -->
|
||||||
@@ -1260,6 +1346,8 @@ Aktivering af dette kan låse op for højere videokvalitet"</string>
|
|||||||
<string name="revanced_custom_playback_speeds_invalid">Brugerdefinerede hastigheder skal være mindre end %s</string>
|
<string name="revanced_custom_playback_speeds_invalid">Brugerdefinerede hastigheder skal være mindre end %s</string>
|
||||||
<string name="revanced_custom_playback_speeds_parse_exception">Ugyldige brugerdefinerede afspilningshastigheder</string>
|
<string name="revanced_custom_playback_speeds_parse_exception">Ugyldige brugerdefinerede afspilningshastigheder</string>
|
||||||
<string name="revanced_custom_playback_speeds_auto">Automatisk</string>
|
<string name="revanced_custom_playback_speeds_auto">Automatisk</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_title">Brugerdefineret hastighed, når du holder den nede</string>
|
||||||
|
<string name="revanced_speed_tap_and_hold_summary">Afspilningshastighed mellem 0-8</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
<patch id="video.speed.remember.rememberPlaybackSpeedPatch">
|
||||||
<string name="revanced_remember_playback_speed_last_selected_title">Husk ændringer i afspilningshastighed</string>
|
<string name="revanced_remember_playback_speed_last_selected_title">Husk ændringer i afspilningshastighed</string>
|
||||||
@@ -1288,74 +1376,25 @@ Aktivering af dette kan låse op for højere videokvalitet"</string>
|
|||||||
Videoafspilning virker muligvis ikke"</string>
|
Videoafspilning virker muligvis ikke"</string>
|
||||||
<string name="revanced_spoof_video_streams_user_dialog_message">At slå denne indstilling fra kan forårsage problemer med videoafspilning.</string>
|
<string name="revanced_spoof_video_streams_user_dialog_message">At slå denne indstilling fra kan forårsage problemer med videoafspilning.</string>
|
||||||
<string name="revanced_spoof_video_streams_client_type_title">Standard klient</string>
|
<string name="revanced_spoof_video_streams_client_type_title">Standard klient</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">Gennemtving AVC (H.264)</string>
|
<!-- 'no auth' means no authentication -->
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video-codec er tvunget til AVC (H.264)</string>
|
<string name="revanced_spoof_video_streams_client_type_android_vr_no_auth">Android VR (ingen godkendelse)</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video-codec bestemmes automatisk</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_title">Forceer iOS AVC (H.264)</string>
|
||||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Aktivering af dette kan forbedre batterilevetiden og løse afspilningshakkethed.
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Videokodec er tvunget til AVC (H.264)</string>
|
||||||
|
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Videokodec bestemmes automatisk</string>
|
||||||
AVC har en maksimal opløsning på 1080p, Opus lydcodec er ikke tilgængelig, og videoafspilning bruger mere internetdata end VP9 eller AV1."</string>
|
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Aktivering af dette kan forbedre batterilevetiden og rette afspilningshakken.\n\nAVC har en maksimal opløsning på 1080p, Opus-lydkodec er ikke tilgængelig, og videoafspilning vil bruge mere internetdata end VP9 eller AV1."</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_title">iOS forfalskning bivirkninger</string>
|
<string name="revanced_spoof_video_streams_about_ios_tv_title">iOS-spoofing kan have følgende bivirkninger</string>
|
||||||
<string name="revanced_spoof_video_streams_about_ios_summary">"• Private børnevideoer kan muligvis ikke afspilles
|
<string name="revanced_spoof_video_streams_about_ios_tv_summary">"• Film eller betalte videoer afspilles muligvis ikke
|
||||||
• Videoer slutter 1 sekund før"</string>
|
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR spoofing bivirkninger</string>
|
|
||||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Børnevideoer afspilles muligvis ikke
|
|
||||||
• Lydspormenuen mangler
|
|
||||||
• Stabil lydstyrke er ikke tilgængelig
|
• Stabil lydstyrke er ikke tilgængelig
|
||||||
• Tving original lyd er ikke tilgængelig"</string>
|
• Videoer slutter 1 sekund for tidligt"</string>
|
||||||
<string name="revanced_spoof_video_streams_language_title">Standard lyd-stream sprog</string>
|
<string name="revanced_spoof_video_streams_about_android_title">Bivirkninger ved Android-spoofing</string>
|
||||||
<string name="revanced_spoof_video_streams_language_DEFAULT">App sprog</string>
|
<string name="revanced_spoof_video_streams_about_android_summary">"• Lydspormenu mangler
|
||||||
<string name="revanced_spoof_video_streams_language_AR">Arabisk</string>
|
• Stabil lydstyrke er ikke tilgængelig
|
||||||
<string name="revanced_spoof_video_streams_language_AZ">Aserbajdsjansk</string>
|
• Gennemtving original lyd er ikke tilgængelig"</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BG">Bulgarsk</string>
|
<string name="revanced_spoof_video_streams_about_no_av1">• Intet AV1-videokodek</string>
|
||||||
<string name="revanced_spoof_video_streams_language_BN">Bengalsk</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_title">Vis i Statistik for nørder</string>
|
||||||
<string name="revanced_spoof_video_streams_language_CA">Catalansk</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_on">Klienttypen vises i Statistik for nørder</string>
|
||||||
<string name="revanced_spoof_video_streams_language_CS">Tjekkisk</string>
|
<string name="revanced_spoof_streaming_data_stats_for_nerds_summary_off">Klienten er skjult i Statistik for nørder</string>
|
||||||
<string name="revanced_spoof_video_streams_language_DA">Dansk</string>
|
<string name="revanced_spoof_video_streams_language_title">VR-standardsprog for lydstrømme</string>
|
||||||
<string name="revanced_spoof_video_streams_language_DE">Tysk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EL">Græsk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_EN">Engelsk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ES">Spansk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ET">Estisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FA">Persisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FI">Finsk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_FR">Fransk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_GU">Gujarati</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HI">Hindi</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HR">Kroatisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_HU">Ungarsk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ID">Indonesisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_IT">Italiensk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_JA">Japansk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KK">Kasakhisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_KO">Koreansk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LT">Litauisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_LV">Lettisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MK">Makedonsk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MN">Mongolsk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MR">Marathisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MS">Malaysisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_MY">Burmesisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_NL">Hollandsk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_OR">Odia</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PA">Punjabi</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PL">Polsk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_BR">Portugisisk (Brasilien)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_PT_PT">Portugisisk (Portugal)</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RO">Rumænsk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_RU">Russisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SK">Slovakisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SL">Slovensk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SR">Serbisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SV">Svensk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_SW">Swahili</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TA">Tamil</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TE">Telugu</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TH">Thailandsk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_TR">Tyrkisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UK">Ukrainsk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_UR">Urdu</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_VI">Vietnamesisk</string>
|
|
||||||
<string name="revanced_spoof_video_streams_language_ZH">Kinesisk</string>
|
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="twitch">
|
<app id="twitch">
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user