mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-26 10:54:07 +01:00
Compare commits
67 Commits
v5.13.0-de
...
v5.16.2-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e67f390e2b | ||
|
|
4d910fea93 | ||
|
|
72adbe5519 | ||
|
|
54d49b774e | ||
|
|
283bb31567 | ||
|
|
2724fcbd27 | ||
|
|
7c28193579 | ||
|
|
cd1ee814c4 | ||
|
|
d9ccd73b5f | ||
|
|
5c5a1e4b8b | ||
|
|
66a2ee2416 | ||
|
|
d8c276cf96 | ||
|
|
d5845abd08 | ||
|
|
54eef22ce7 | ||
|
|
e287bdc59d | ||
|
|
20a82ef956 | ||
|
|
1e29da9e06 | ||
|
|
56e6a90a90 | ||
|
|
76d32e21c2 | ||
|
|
54a7afa540 | ||
|
|
ef86438bac | ||
|
|
0683cedac0 | ||
|
|
35753410aa | ||
|
|
df838ed91d | ||
|
|
8e494d26d4 | ||
|
|
7d834e5421 | ||
|
|
60a31cf4e1 | ||
|
|
edb8bd66bc | ||
|
|
04a170054e | ||
|
|
79e6349a69 | ||
|
|
bbf3a34a2f | ||
|
|
1db7c49514 | ||
|
|
ef0506a4f8 | ||
|
|
9b38da35ff | ||
|
|
afdb771066 | ||
|
|
1b2b536d2e | ||
|
|
f39e70c648 | ||
|
|
556acdd9c1 | ||
|
|
7adfc637dc | ||
|
|
9cc0c075ad | ||
|
|
ead11e7f46 | ||
|
|
e9bc201641 | ||
|
|
99baedf355 | ||
|
|
0338d0acd3 | ||
|
|
99879f6e0a | ||
|
|
f0c70de602 | ||
|
|
737ae07a06 | ||
|
|
2c51de59de | ||
|
|
df3dc1c0b2 | ||
|
|
074c948581 | ||
|
|
2a88b1f895 | ||
|
|
ee5c830df8 | ||
|
|
e63a4b31f3 | ||
|
|
8d0bca3b03 | ||
|
|
c162d65d5b | ||
|
|
67dcd091c4 | ||
|
|
ac5ce2d67f | ||
|
|
4b78d056fd | ||
|
|
f8c901b2c1 | ||
|
|
2a67c312e1 | ||
|
|
a7eed30f46 | ||
|
|
e2de2d8d44 | ||
|
|
7ebbf356c0 | ||
|
|
2ced5c6e2a | ||
|
|
4a090ba659 | ||
|
|
cb609a6d9d | ||
|
|
42e6de9e8f |
2
.github/workflows/pull_strings.yml
vendored
2
.github/workflows/pull_strings.yml
vendored
@@ -2,7 +2,7 @@ name: Pull strings
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 */6 * * *"
|
||||
- cron: "0 */12 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
217
CHANGELOG.md
217
CHANGELOG.md
@@ -1,3 +1,220 @@
|
||||
## [5.16.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.16.1...v5.16.2-dev.1) (2025-03-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Facebook - Hide 'Sponsored Stories':** Constrain patch to latest compatible version ([#4657](https://github.com/ReVanced/revanced-patches/issues/4657)) ([46bd1c8](https://github.com/ReVanced/revanced-patches/commit/46bd1c829acd5f83600025e0ceb7d482ae80be69))
|
||||
|
||||
## [5.16.1](https://github.com/ReVanced/revanced-patches/compare/v5.16.0...v5.16.1) (2025-03-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Spotify - Unlock Premium:** Override streaming attribute attempting to fix streaming issues ([06be36c](https://github.com/ReVanced/revanced-patches/commit/06be36cddf3430b4179dff696b3d15718cd6963b))
|
||||
|
||||
## [5.16.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.16.0...v5.16.1-dev.1) (2025-03-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Spotify - Unlock Premium:** Override streaming attribute attempting to fix streaming issues ([06be36c](https://github.com/ReVanced/revanced-patches/commit/06be36cddf3430b4179dff696b3d15718cd6963b))
|
||||
|
||||
# [5.16.0](https://github.com/ReVanced/revanced-patches/compare/v5.15.0...v5.16.0) (2025-03-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Settings:** System navigation bar is located above the settings ui on Android 15+ ([f7497be](https://github.com/ReVanced/revanced-patches/commit/f7497be2c5e4abcde6eb55b84955124a28f55cae))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Spotify:** Add `Unlock premium` patch ([#4644](https://github.com/ReVanced/revanced-patches/issues/4644)) ([f048c50](https://github.com/ReVanced/revanced-patches/commit/f048c50e56fc1f5a5c607860be4206ef83b528fe))
|
||||
* **YouTube - Comments:** Add `Hide AI Comments summary` ([#4634](https://github.com/ReVanced/revanced-patches/issues/4634)) ([e9b7f26](https://github.com/ReVanced/revanced-patches/commit/e9b7f263f739bd130f6ea79913851a52355977c5))
|
||||
* **YouTube - Video description:** Add `Hide AI-generated video summary` ([#4636](https://github.com/ReVanced/revanced-patches/issues/4636)) ([521fd48](https://github.com/ReVanced/revanced-patches/commit/521fd48602432ab436d8711c19d7130b2b05af12))
|
||||
|
||||
# [5.16.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.16.0-dev.1...v5.16.0-dev.2) (2025-03-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Spotify:** Add `Unlock premium` patch ([#4644](https://github.com/ReVanced/revanced-patches/issues/4644)) ([f048c50](https://github.com/ReVanced/revanced-patches/commit/f048c50e56fc1f5a5c607860be4206ef83b528fe))
|
||||
|
||||
# [5.16.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.15.0...v5.16.0-dev.1) (2025-03-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Settings:** System navigation bar is located above the settings ui on Android 15+ ([f7497be](https://github.com/ReVanced/revanced-patches/commit/f7497be2c5e4abcde6eb55b84955124a28f55cae))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - Comments:** Add `Hide AI Comments summary` ([#4634](https://github.com/ReVanced/revanced-patches/issues/4634)) ([e9b7f26](https://github.com/ReVanced/revanced-patches/commit/e9b7f263f739bd130f6ea79913851a52355977c5))
|
||||
* **YouTube - Video description:** Add `Hide AI-generated video summary` ([#4636](https://github.com/ReVanced/revanced-patches/issues/4636)) ([521fd48](https://github.com/ReVanced/revanced-patches/commit/521fd48602432ab436d8711c19d7130b2b05af12))
|
||||
|
||||
# [5.15.0](https://github.com/ReVanced/revanced-patches/compare/v5.14.0...v5.15.0) (2025-03-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Spoof app version:** Change oldest spoof target to 19.01.34 ([5012439](https://github.com/ReVanced/revanced-patches/commit/5012439a8e53b2a4ab5e85c47976e1ab28a51208))
|
||||
* **YouTube - Spoof app version:** Remove broken spoof targets that YouTube no longer supports ([#4610](https://github.com/ReVanced/revanced-patches/issues/4610)) ([883fbe7](https://github.com/ReVanced/revanced-patches/commit/883fbe71233c57cb1241e57c122b43f40722acc7))
|
||||
* **YouTube:** Do not show restart prompt more than once if setting change is canceled ([49797fe](https://github.com/ReVanced/revanced-patches/commit/49797fe8d0c4a0981ef621a31356c4315ae3777b))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - SponsorBlock:** Add opacity setting to category segment colors ([#4582](https://github.com/ReVanced/revanced-patches/issues/4582)) ([6e8ffba](https://github.com/ReVanced/revanced-patches/commit/6e8ffbade9e03658f725622631e44dabf2995861))
|
||||
|
||||
# [5.15.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.15.0-dev.3...v5.15.0-dev.4) (2025-03-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Spoof app version:** Change oldest spoof target to 19.01.34 ([5012439](https://github.com/ReVanced/revanced-patches/commit/5012439a8e53b2a4ab5e85c47976e1ab28a51208))
|
||||
|
||||
# [5.15.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.15.0-dev.2...v5.15.0-dev.3) (2025-03-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube:** Do not show restart prompt more than once if setting change is canceled ([49797fe](https://github.com/ReVanced/revanced-patches/commit/49797fe8d0c4a0981ef621a31356c4315ae3777b))
|
||||
|
||||
# [5.15.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.15.0-dev.1...v5.15.0-dev.2) (2025-03-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Spoof app version:** Remove broken spoof targets that YouTube no longer supports ([#4610](https://github.com/ReVanced/revanced-patches/issues/4610)) ([883fbe7](https://github.com/ReVanced/revanced-patches/commit/883fbe71233c57cb1241e57c122b43f40722acc7))
|
||||
|
||||
# [5.15.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.14.0...v5.15.0-dev.1) (2025-03-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - SponsorBlock:** Add opacity setting to category segment colors ([#4582](https://github.com/ReVanced/revanced-patches/issues/4582)) ([6e8ffba](https://github.com/ReVanced/revanced-patches/commit/6e8ffbade9e03658f725622631e44dabf2995861))
|
||||
|
||||
# [5.14.0](https://github.com/ReVanced/revanced-patches/compare/v5.13.0...v5.14.0) (2025-03-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Boost for reddit - Client spoof:** Use a different user agent to combat Reddit's API issues ([5d3c817](https://github.com/ReVanced/revanced-patches/commit/5d3c8175b34a3f6ae2732b25db0851773a8c000d))
|
||||
* **YouTube - Change form factor:** Restore Automotive form factor watch history menu, channel pages, and community posts ([#4541](https://github.com/ReVanced/revanced-patches/issues/4541)) ([aa5c001](https://github.com/ReVanced/revanced-patches/commit/aa5c001968446e5270c756256724e917009612cd))
|
||||
* **YouTube - Hide ads:** Hide new type of buttoned ad ([#4528](https://github.com/ReVanced/revanced-patches/issues/4528)) ([4387a7b](https://github.com/ReVanced/revanced-patches/commit/4387a7b131f49729e902e008bb4cec073635c040))
|
||||
* **YouTube - Hide layout components:** Do not hide Movie/Courses start page content if 'Hide horizontal shelves' is enabled ([62a6164](https://github.com/ReVanced/revanced-patches/commit/62a6164b88b64200b517a5ba6b800d8214dbbad8))
|
||||
* **YouTube - Theme:** Resolve dark mode startup crash with Android 9.0 ([741c2d5](https://github.com/ReVanced/revanced-patches/commit/741c2d59406f5d602554bb3a3c0b8982f42848b4))
|
||||
* **YouTube:** Change language settings menu to use native language names ([#4568](https://github.com/ReVanced/revanced-patches/issues/4568)) ([6f3f8fd](https://github.com/ReVanced/revanced-patches/commit/6f3f8fdce05501e4fa4423c2170a916fbea3b199))
|
||||
* **YouTube:** Combine `Restore old video quality menu` and `Remember video quality` into `Video quality` patch ([#4552](https://github.com/ReVanced/revanced-patches/issues/4552)) ([ee67b76](https://github.com/ReVanced/revanced-patches/commit/ee67b763d5c5947a5b1ef4420b1efa820ed6af83))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Infinity for Reddit:** Add support for package name on IzzyOnDroid ([#4554](https://github.com/ReVanced/revanced-patches/issues/4554)) ([cf9f959](https://github.com/ReVanced/revanced-patches/commit/cf9f959923076c10a7f0a29f6ba277f5a055ec07))
|
||||
* **Spotify:** Add `Spoof signature` patch ([#4576](https://github.com/ReVanced/revanced-patches/issues/4576)) ([3646c70](https://github.com/ReVanced/revanced-patches/commit/3646c70556b67a6b7ecf9b86869ebf03c3611333))
|
||||
* **YouTube - Remember video quality:** Add separate Shorts default quality settings ([#4543](https://github.com/ReVanced/revanced-patches/issues/4543)) ([88142ab](https://github.com/ReVanced/revanced-patches/commit/88142ab464192b564b1b8d56a6b45663f77f5e00))
|
||||
|
||||
# [5.14.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.8...v5.14.0-dev.9) (2025-03-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Spotify:** Add `Spoof signature` patch ([#4576](https://github.com/ReVanced/revanced-patches/issues/4576)) ([3646c70](https://github.com/ReVanced/revanced-patches/commit/3646c70556b67a6b7ecf9b86869ebf03c3611333))
|
||||
|
||||
# [5.14.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.7...v5.14.0-dev.8) (2025-03-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Theme:** Resolve dark mode startup crash with Android 9.0 ([741c2d5](https://github.com/ReVanced/revanced-patches/commit/741c2d59406f5d602554bb3a3c0b8982f42848b4))
|
||||
|
||||
# [5.14.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.6...v5.14.0-dev.7) (2025-03-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube:** Change language settings menu to use native language names ([#4568](https://github.com/ReVanced/revanced-patches/issues/4568)) ([6f3f8fd](https://github.com/ReVanced/revanced-patches/commit/6f3f8fdce05501e4fa4423c2170a916fbea3b199))
|
||||
|
||||
# [5.14.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.5...v5.14.0-dev.6) (2025-03-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Hide layout components:** Do not hide Movie/Courses start page content if 'Hide horizontal shelves' is enabled ([62a6164](https://github.com/ReVanced/revanced-patches/commit/62a6164b88b64200b517a5ba6b800d8214dbbad8))
|
||||
|
||||
# [5.14.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.4...v5.14.0-dev.5) (2025-03-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Infinity for Reddit:** Add support for package name on IzzyOnDroid ([#4554](https://github.com/ReVanced/revanced-patches/issues/4554)) ([cf9f959](https://github.com/ReVanced/revanced-patches/commit/cf9f959923076c10a7f0a29f6ba277f5a055ec07))
|
||||
|
||||
# [5.14.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.3...v5.14.0-dev.4) (2025-03-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube:** Combine `Restore old video quality menu` and `Remember video quality` into `Video quality` patch ([#4552](https://github.com/ReVanced/revanced-patches/issues/4552)) ([ee67b76](https://github.com/ReVanced/revanced-patches/commit/ee67b763d5c5947a5b1ef4420b1efa820ed6af83))
|
||||
|
||||
# [5.14.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.2...v5.14.0-dev.3) (2025-03-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Boost for reddit - Client spoof:** Use a different user agent to combat Reddit's API issues ([5d3c817](https://github.com/ReVanced/revanced-patches/commit/5d3c8175b34a3f6ae2732b25db0851773a8c000d))
|
||||
|
||||
# [5.14.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.14.0-dev.1...v5.14.0-dev.2) (2025-03-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Hide ads:** Hide new type of buttoned ad ([#4528](https://github.com/ReVanced/revanced-patches/issues/4528)) ([4387a7b](https://github.com/ReVanced/revanced-patches/commit/4387a7b131f49729e902e008bb4cec073635c040))
|
||||
|
||||
# [5.14.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.13.1-dev.1...v5.14.0-dev.1) (2025-03-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - Remember video quality:** Add separate Shorts default quality settings ([#4543](https://github.com/ReVanced/revanced-patches/issues/4543)) ([88142ab](https://github.com/ReVanced/revanced-patches/commit/88142ab464192b564b1b8d56a6b45663f77f5e00))
|
||||
|
||||
## [5.13.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.13.0...v5.13.1-dev.1) (2025-03-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Change form factor:** Restore Automotive form factor watch history menu, channel pages, and community posts ([#4541](https://github.com/ReVanced/revanced-patches/issues/4541)) ([aa5c001](https://github.com/ReVanced/revanced-patches/commit/aa5c001968446e5270c756256724e917009612cd))
|
||||
|
||||
# [5.13.0](https://github.com/ReVanced/revanced-patches/compare/v5.12.0...v5.13.0) (2025-03-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **TikTok:** Resolve startup app crash ([18c0fc2](https://github.com/ReVanced/revanced-patches/commit/18c0fc2a7f186f50a904fd25dbaa739abdd24993))
|
||||
* **TikTok:** Resolve startup app crash ([6466398](https://github.com/ReVanced/revanced-patches/commit/64663983b84de1f28636205f61bf0a24c83968d1))
|
||||
* **TikTok:** Resolve startup app crash ([c14bc24](https://github.com/ReVanced/revanced-patches/commit/c14bc244550de30eca975ca7c09e8eb0c47534b5))
|
||||
* **TikTok:** Resolve startup app crash ([d700076](https://github.com/ReVanced/revanced-patches/commit/d7000768a5e5a688c9f4e48858ac34e352222c1e))
|
||||
* **YouTube - Copy video URL:** Use correct button ordering ([5e622cc](https://github.com/ReVanced/revanced-patches/commit/5e622ccf66d34af31c6026fa7f4d332460c6ecb0))
|
||||
* **YouTube - Hide filter bar:** Fix `Hide in feed` not working in subscriptions feed ([#4512](https://github.com/ReVanced/revanced-patches/issues/4512)) ([634d0ee](https://github.com/ReVanced/revanced-patches/commit/634d0ee12e31491c7ee1d4ceb002daf8366a3c15))
|
||||
* **YouTube - Hide layout components:** Do not hide 'Show anyway' button in search results ([4ac8854](https://github.com/ReVanced/revanced-patches/commit/4ac8854b99808a8957f3b0b7438e1e0cdedffbaf))
|
||||
* **YouTube - Hide player components:** Show correct end video thumbnail if `Hide end screen suggested video` is enabled ([#4502](https://github.com/ReVanced/revanced-patches/issues/4502)) ([6c4885a](https://github.com/ReVanced/revanced-patches/commit/6c4885a1d5dfff50100b01840b5552d92e83ee4a))
|
||||
* **YouTube - Hide video action buttons:** Move 'Disable Like and Subscribe glow' to action buttons settings menu ([29b265d](https://github.com/ReVanced/revanced-patches/commit/29b265d8fdaa48502650be9623bfc518a57a0bb1))
|
||||
* **YouTube - Return YouTube Dislike:** Use correct number formatting if using a different ReVanced language ([edf66f4](https://github.com/ReVanced/revanced-patches/commit/edf66f4e16d46156cb8b8e31d18cb8dbcb87737e))
|
||||
* **YouTube - Spoof app version:** Force old settings menus if spoofing to older app targets ([#4490](https://github.com/ReVanced/revanced-patches/issues/4490)) ([45e7c46](https://github.com/ReVanced/revanced-patches/commit/45e7c46dd9c70c926b8b1a97ada668f90f5f6f8c))
|
||||
* **YouTube - Spoof video streams:** Resolve playback issues with dynamic player config ([#4521](https://github.com/ReVanced/revanced-patches/issues/4521)) ([647e764](https://github.com/ReVanced/revanced-patches/commit/647e7642efc0c00db17ccb6a620d1c96ccf4afed))
|
||||
* **YouTube - Swipe controls:** Adjust the overlay text size ([#4503](https://github.com/ReVanced/revanced-patches/issues/4503)) ([6dc4bf7](https://github.com/ReVanced/revanced-patches/commit/6dc4bf75e09ed6f05534919d7b769b720043abce))
|
||||
* **YouTube:** Do not hide player controls when using double tap to skip forward ([#4487](https://github.com/ReVanced/revanced-patches/issues/4487)) ([63fe870](https://github.com/ReVanced/revanced-patches/commit/63fe870d48ca2217327b952bde241b7f16ced850))
|
||||
* **YouTube:** Fix player button fade out animations ([#4469](https://github.com/ReVanced/revanced-patches/issues/4469)) ([bf8e775](https://github.com/ReVanced/revanced-patches/commit/bf8e7759f9bdbdfef419a879fb3dd7cf0dff0098))
|
||||
* **YouTube:** Resolve button flickering when taping seekbar ([#4500](https://github.com/ReVanced/revanced-patches/issues/4500)) ([1f08047](https://github.com/ReVanced/revanced-patches/commit/1f08047b48cc9555a4887d16ec7219a55a77251f))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Infinity for Reddit:** Add support for Infinity for Reddit Plus ([#4511](https://github.com/ReVanced/revanced-patches/issues/4511)) ([d74732b](https://github.com/ReVanced/revanced-patches/commit/d74732b7596104321bde263201d95649e4bd0eee))
|
||||
* **NU.nl:** Add `Hide ads` and `Spoof Certificate` patch ([#4368](https://github.com/ReVanced/revanced-patches/issues/4368)) ([f3268fb](https://github.com/ReVanced/revanced-patches/commit/f3268fb03ca25fb5465e36015b6c9dec2c84a655))
|
||||
* **YouTube - Navigation buttons:** Add 'Hide notifications' setting ([#4485](https://github.com/ReVanced/revanced-patches/issues/4485)) ([506d241](https://github.com/ReVanced/revanced-patches/commit/506d2414bbc760e764e5a514b32926083d6ecb6b))
|
||||
* **YouTube - Swipe controls:** Swipe controls UI improvements ([#4422](https://github.com/ReVanced/revanced-patches/issues/4422)) ([198e4d2](https://github.com/ReVanced/revanced-patches/commit/198e4d2a2315c24a09eb9ecfefbd131a75384d2c))
|
||||
|
||||
# [5.13.0-dev.19](https://github.com/ReVanced/revanced-patches/compare/v5.13.0-dev.18...v5.13.0-dev.19) (2025-03-02)
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@ public enum AppLanguage {
|
||||
*/
|
||||
DEFAULT,
|
||||
|
||||
// Languages codes not included with YouTube, but are translated on Crowdin
|
||||
GA,
|
||||
|
||||
// Language codes found in locale_config.xml
|
||||
// All region specific variants have been removed.
|
||||
AF,
|
||||
|
||||
@@ -22,12 +22,23 @@ import app.revanced.extension.shared.settings.Setting;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
||||
|
||||
/**
|
||||
* Indicates that if a preference changes,
|
||||
* to apply the change from the Setting to the UI component.
|
||||
*/
|
||||
public static boolean settingImportInProgress;
|
||||
|
||||
/**
|
||||
* Prevents recursive calls during preference <-> UI syncing from showing extra dialogs.
|
||||
*/
|
||||
private static boolean updatingPreference;
|
||||
|
||||
/**
|
||||
* Used to prevent showing reboot dialog, if user cancels a setting user dialog.
|
||||
*/
|
||||
private static boolean showingUserDialogMessage;
|
||||
|
||||
/**
|
||||
* Confirm and restart dialog button text and title.
|
||||
* Set by subclasses if Strings cannot be added as a resource.
|
||||
@@ -35,13 +46,13 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
||||
@Nullable
|
||||
protected static String restartDialogButtonText, restartDialogTitle, confirmDialogTitle;
|
||||
|
||||
/**
|
||||
* Used to prevent showing reboot dialog, if user cancels a setting user dialog.
|
||||
*/
|
||||
private boolean showingUserDialogMessage;
|
||||
|
||||
private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
|
||||
try {
|
||||
if (updatingPreference) {
|
||||
Logger.printDebug(() -> "Ignoring preference change as sync is in progress");
|
||||
return;
|
||||
}
|
||||
|
||||
Setting<?> setting = Setting.getSettingFromPath(Objects.requireNonNull(str));
|
||||
if (setting == null) {
|
||||
return;
|
||||
@@ -63,10 +74,13 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
||||
}
|
||||
}
|
||||
|
||||
updatingPreference = true;
|
||||
// Apply 'Setting <- Preference', unless during importing when it needs to be 'Setting -> Preference'.
|
||||
// Updating here can can cause a recursive call back into this same method.
|
||||
updatePreference(pref, setting, true, settingImportInProgress);
|
||||
// Update any other preference availability that may now be different.
|
||||
updateUIAvailability();
|
||||
updatingPreference = false;
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "OnSharedPreferenceChangeListener failure", ex);
|
||||
}
|
||||
@@ -97,7 +111,9 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
||||
if (confirmDialogTitle == null) {
|
||||
confirmDialogTitle = str("revanced_settings_confirm_user_dialog_title");
|
||||
}
|
||||
|
||||
showingUserDialogMessage = true;
|
||||
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(confirmDialogTitle)
|
||||
.setMessage(Objects.requireNonNull(setting.userDialogMessage).toString())
|
||||
@@ -141,14 +157,16 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
||||
* @return If the preference is currently set to the default value of the Setting.
|
||||
*/
|
||||
protected boolean prefIsSetToDefault(Preference pref, Setting<?> setting) {
|
||||
Object defaultValue = setting.defaultValue;
|
||||
if (pref instanceof SwitchPreference switchPref) {
|
||||
return switchPref.isChecked() == (Boolean) setting.defaultValue;
|
||||
return switchPref.isChecked() == (Boolean) defaultValue;
|
||||
}
|
||||
String defaultValueString = defaultValue.toString();
|
||||
if (pref instanceof EditTextPreference editPreference) {
|
||||
return editPreference.getText().equals(setting.defaultValue.toString());
|
||||
return editPreference.getText().equals(defaultValueString);
|
||||
}
|
||||
if (pref instanceof ListPreference listPref) {
|
||||
return listPref.getValue().equals(setting.defaultValue.toString());
|
||||
return listPref.getValue().equals(defaultValueString);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Must override method to handle "
|
||||
@@ -158,16 +176,16 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
||||
/**
|
||||
* Syncs all UI Preferences to any {@link Setting} they represent.
|
||||
*/
|
||||
private void updatePreferenceScreen(@NonNull PreferenceScreen screen,
|
||||
private void updatePreferenceScreen(@NonNull PreferenceGroup group,
|
||||
boolean syncSettingValue,
|
||||
boolean applySettingToPreference) {
|
||||
// Alternatively this could iterate thru all Settings and check for any matching Preferences,
|
||||
// but there are many more Settings than UI preferences so it's more efficient to only check
|
||||
// the Preferences.
|
||||
for (int i = 0, prefCount = screen.getPreferenceCount(); i < prefCount; i++) {
|
||||
Preference pref = screen.getPreference(i);
|
||||
if (pref instanceof PreferenceScreen) {
|
||||
updatePreferenceScreen((PreferenceScreen) pref, syncSettingValue, applySettingToPreference);
|
||||
for (int i = 0, prefCount = group.getPreferenceCount(); i < prefCount; i++) {
|
||||
Preference pref = group.getPreference(i);
|
||||
if (pref instanceof PreferenceGroup subGroup) {
|
||||
updatePreferenceScreen(subGroup, syncSettingValue, applySettingToPreference);
|
||||
} else if (pref.hasKey()) {
|
||||
String key = pref.getKey();
|
||||
Setting<?> setting = Setting.getSettingFromPath(key);
|
||||
@@ -255,7 +273,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
||||
}
|
||||
}
|
||||
|
||||
public static void showRestartDialog(@NonNull final Context context) {
|
||||
public static void showRestartDialog(Context context) {
|
||||
Utils.verifyOnMainThread();
|
||||
if (restartDialogTitle == null) {
|
||||
restartDialogTitle = str("revanced_settings_restart_title");
|
||||
@@ -263,6 +281,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
|
||||
if (restartDialogButtonText == null) {
|
||||
restartDialogButtonText = str("revanced_settings_restart");
|
||||
}
|
||||
|
||||
new AlertDialog.Builder(context)
|
||||
.setMessage(restartDialogTitle)
|
||||
.setPositiveButton(restartDialogButtonText, (dialog, id)
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package app.revanced.extension.shared.settings.preference;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* Empty preference category with no title, used to organize and group related preferences together.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "deprecation"})
|
||||
public class NoTitlePreferenceCategory extends PreferenceCategory {
|
||||
|
||||
public NoTitlePreferenceCategory(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public NoTitlePreferenceCategory(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public NoTitlePreferenceCategory(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("MissingSuperCall")
|
||||
protected View onCreateView(ViewGroup parent) {
|
||||
// Return an zero-height view to eliminate empty title space.
|
||||
return new View(getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle() {
|
||||
// Title can be used for sorting. Return the first sub preference title.
|
||||
if (getPreferenceCount() > 0) {
|
||||
return getPreference(0).getTitle();
|
||||
}
|
||||
|
||||
return super.getTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTitleRes() {
|
||||
if (getPreferenceCount() > 0) {
|
||||
return getPreference(0).getTitleRes();
|
||||
}
|
||||
|
||||
return super.getTitleRes();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package app.revanced.extension.shared.settings.preference;
|
||||
|
||||
import static app.revanced.extension.shared.StringRef.str;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
@@ -8,17 +10,23 @@ import android.util.AttributeSet;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.settings.Setting;
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static app.revanced.extension.shared.StringRef.str;
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.settings.Setting;
|
||||
|
||||
@SuppressWarnings({"unused", "deprecation"})
|
||||
public class ResettableEditTextPreference extends EditTextPreference {
|
||||
|
||||
/**
|
||||
* Setting to reset.
|
||||
*/
|
||||
@Nullable
|
||||
private Setting<?> setting;
|
||||
|
||||
public ResettableEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
@@ -32,12 +40,22 @@ public class ResettableEditTextPreference extends EditTextPreference {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public void setSetting(@Nullable Setting<?> setting) {
|
||||
this.setting = setting;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
||||
super.onPrepareDialogBuilder(builder);
|
||||
Utils.setEditTextDialogTheme(builder);
|
||||
|
||||
Setting<?> setting = Setting.getSettingFromPath(getKey());
|
||||
if (setting == null) {
|
||||
String key = getKey();
|
||||
if (key != null) {
|
||||
setting = Setting.getSettingFromPath(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (setting != null) {
|
||||
builder.setNeutralButton(str("revanced_settings_reset"), null);
|
||||
}
|
||||
@@ -54,8 +72,7 @@ public class ResettableEditTextPreference extends EditTextPreference {
|
||||
}
|
||||
button.setOnClickListener(v -> {
|
||||
try {
|
||||
Setting<?> setting = Objects.requireNonNull(Setting.getSettingFromPath(getKey()));
|
||||
String defaultStringValue = setting.defaultValue.toString();
|
||||
String defaultStringValue = Objects.requireNonNull(setting).defaultValue.toString();
|
||||
EditText editText = getEditText();
|
||||
editText.setText(defaultStringValue);
|
||||
editText.setSelection(defaultStringValue.length()); // move cursor to end of text
|
||||
|
||||
3
extensions/spotify/build.gradle.kts
Normal file
3
extensions/spotify/build.gradle.kts
Normal file
@@ -0,0 +1,3 @@
|
||||
dependencies {
|
||||
compileOnly(project(":extensions:spotify:stub"))
|
||||
}
|
||||
1
extensions/spotify/src/main/AndroidManifest.xml
Normal file
1
extensions/spotify/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1 @@
|
||||
<manifest/>
|
||||
17
extensions/spotify/stub/build.gradle.kts
Normal file
17
extensions/spotify/stub/build.gradle.kts
Normal file
@@ -0,0 +1,17 @@
|
||||
plugins {
|
||||
id(libs.plugins.android.library.get().pluginId)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "app.revanced.extension"
|
||||
compileSdk = 34
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 26
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
1
extensions/spotify/stub/src/main/AndroidManifest.xml
Normal file
1
extensions/spotify/stub/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1 @@
|
||||
<manifest/>
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.spotify.remoteconfig.internal;
|
||||
|
||||
public final class AccountAttribute {
|
||||
public Object value_;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package app.revanced.extension.youtube.patches;
|
||||
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.shared.PlayerType;
|
||||
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class BackgroundPlaybackPatch {
|
||||
@@ -23,16 +23,7 @@ public class BackgroundPlaybackPatch {
|
||||
// 7. Close the Short
|
||||
// 8. Resume playing the regular video
|
||||
// 9. Minimize the app (PIP should appear)
|
||||
if (!VideoInformation.lastVideoIdIsShort()) {
|
||||
return true; // Definitely is not a Short.
|
||||
}
|
||||
|
||||
// TODO: Add better hook.
|
||||
// Might be a Shorts, or might be a prior regular video on screen again after a Shorts was closed.
|
||||
// This incorrectly prevents PIP if player is in WATCH_WHILE_MINIMIZED after closing a Shorts,
|
||||
// But there's no way around this unless an additional hook is added to definitively detect
|
||||
// the Shorts player is on screen. This use case is unusual anyways so it's not a huge concern.
|
||||
return !PlayerType.getCurrent().isNoneHiddenOrMinimized();
|
||||
return !ShortsPlayerState.isOpen();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package app.revanced.extension.youtube.patches;
|
||||
|
||||
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import java.util.Objects;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.shared.NavigationBar;
|
||||
import app.revanced.extension.youtube.shared.PlayerType;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class ChangeFormFactorPatch {
|
||||
@@ -41,14 +49,57 @@ public class ChangeFormFactorPatch {
|
||||
|
||||
@Nullable
|
||||
private static final Integer FORM_FACTOR_TYPE = Settings.CHANGE_FORM_FACTOR.get().formFactorType;
|
||||
private static final boolean USING_AUTOMOTIVE_TYPE = Objects.requireNonNull(
|
||||
FormFactor.AUTOMOTIVE.formFactorType).equals(FORM_FACTOR_TYPE);
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static int getFormFactor(int original) {
|
||||
return FORM_FACTOR_TYPE == null
|
||||
? original
|
||||
: FORM_FACTOR_TYPE;
|
||||
if (FORM_FACTOR_TYPE == null) return original;
|
||||
|
||||
if (USING_AUTOMOTIVE_TYPE) {
|
||||
// Do not change if the player is opening or is opened,
|
||||
// otherwise the video description cannot be opened.
|
||||
PlayerType current = PlayerType.getCurrent();
|
||||
if (current.isMaximizedOrFullscreen() || current == PlayerType.WATCH_WHILE_SLIDING_MINIMIZED_MAXIMIZED) {
|
||||
Logger.printDebug(() -> "Using original form factor for player");
|
||||
return original;
|
||||
}
|
||||
|
||||
if (!NavigationBar.isSearchBarActive()) {
|
||||
// Automotive type shows error 400 when opening a channel page and using some explore tab.
|
||||
// This is a bug in unpatched YouTube that occurs on actual Android Automotive devices.
|
||||
// Work around the issue by using the original form factor if not in search and the
|
||||
// navigation back button is present.
|
||||
if (NavigationBar.isBackButtonVisible()) {
|
||||
Logger.printDebug(() -> "Using original form factor, as back button is visible without search present");
|
||||
return original;
|
||||
}
|
||||
|
||||
// Do not change library tab otherwise watch history is hidden.
|
||||
// Do this check last since the current navigation button is required.
|
||||
if (NavigationButton.getSelectedNavigationButton() == NavigationButton.LIBRARY) {
|
||||
return original;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FORM_FACTOR_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void navigationTabCreated(NavigationButton button, View tabView) {
|
||||
// On first startup of the app the navigation buttons are fetched and updated.
|
||||
// If the user immediately opens the 'You' or opens a video, then the call to
|
||||
// update the navigtation buttons will use the non automotive form factor
|
||||
// and the explore tab is missing.
|
||||
// Fixing this is not so simple because of the concurrent calls for the player and You tab.
|
||||
// For now, always hide the explore tab.
|
||||
if (USING_AUTOMOTIVE_TYPE && button == NavigationButton.EXPLORE) {
|
||||
tabView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package app.revanced.extension.youtube.patches;
|
||||
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.shared.PlayerType;
|
||||
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class DisableAutoCaptionsPatch {
|
||||
@@ -14,7 +14,7 @@ public class DisableAutoCaptionsPatch {
|
||||
public static boolean autoCaptionsEnabled() {
|
||||
return Settings.AUTO_CAPTIONS.get()
|
||||
// Do not use auto captions for Shorts.
|
||||
&& !PlayerType.getCurrent().isNoneHiddenOrSlidingMinimized();
|
||||
&& ShortsPlayerState.isOpen();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package app.revanced.extension.youtube.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.extension.youtube.shared.PlayerType;
|
||||
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||
import app.revanced.extension.youtube.shared.VideoState;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@@ -24,4 +27,26 @@ public class PlayerTypeHookPatch {
|
||||
|
||||
VideoState.setFromString(youTubeVideoState.name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*
|
||||
* Add a listener to the shorts player overlay View.
|
||||
* Triggered when a shorts player is attached or detached to Windows.
|
||||
*
|
||||
* @param view shorts player overlay (R.id.reel_watch_player).
|
||||
*/
|
||||
public static void onShortsCreate(View view) {
|
||||
view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
|
||||
@Override
|
||||
public void onViewAttachedToWindow(@Nullable View v) {
|
||||
ShortsPlayerState.setOpen(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(@Nullable View v) {
|
||||
ShortsPlayerState.setOpen(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.util.Objects;
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.youtube.patches.components.ReturnYouTubeDislikeFilterPatch;
|
||||
import app.revanced.extension.youtube.patches.spoof.SpoofAppVersionPatch;
|
||||
import app.revanced.extension.youtube.returnyoutubedislike.ReturnYouTubeDislike;
|
||||
import app.revanced.extension.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
@@ -47,9 +46,6 @@ import app.revanced.extension.youtube.shared.PlayerType;
|
||||
@SuppressWarnings("unused")
|
||||
public class ReturnYouTubeDislikePatch {
|
||||
|
||||
public static final boolean IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER =
|
||||
SpoofAppVersionPatch.isSpoofingToLessThan("18.34.00");
|
||||
|
||||
/**
|
||||
* RYD data for the current video on screen.
|
||||
*/
|
||||
@@ -347,137 +343,6 @@ public class ReturnYouTubeDislikePatch {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Non litho Shorts player.
|
||||
//
|
||||
|
||||
/**
|
||||
* Replacement text to use for "Dislikes" while RYD is fetching.
|
||||
*/
|
||||
private static final Spannable SHORTS_LOADING_SPAN = new SpannableString("-");
|
||||
|
||||
/**
|
||||
* Dislikes TextViews used by Shorts.
|
||||
*
|
||||
* Multiple TextViews are loaded at once (for the prior and next videos to swipe to).
|
||||
* Keep track of all of them, and later pick out the correct one based on their on screen position.
|
||||
*/
|
||||
private static final List<WeakReference<TextView>> shortsTextViewRefs = new ArrayList<>();
|
||||
|
||||
private static void clearRemovedShortsTextViews() {
|
||||
shortsTextViewRefs.removeIf(ref -> ref.get() == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point. Called when a Shorts dislike is updated. Always on main thread.
|
||||
* Handles update asynchronously, otherwise Shorts video will be frozen while the UI thread is blocked.
|
||||
*
|
||||
* @return if RYD is enabled and the TextView was updated.
|
||||
*/
|
||||
public static boolean setShortsDislikes(@NonNull View likeDislikeView) {
|
||||
try {
|
||||
if (!Settings.RYD_ENABLED.get()) {
|
||||
return false;
|
||||
}
|
||||
if (!Settings.RYD_SHORTS.get() || Settings.HIDE_SHORTS_DISLIKE_BUTTON.get()) {
|
||||
// Must clear the data here, in case a new video was loaded while PlayerType
|
||||
// suggested the video was not a short (can happen when spoofing to an old app version).
|
||||
clearData();
|
||||
return false;
|
||||
}
|
||||
Logger.printDebug(() -> "setShortsDislikes");
|
||||
|
||||
TextView textView = (TextView) likeDislikeView;
|
||||
textView.setText(SHORTS_LOADING_SPAN); // Change 'Dislike' text to the loading text.
|
||||
shortsTextViewRefs.add(new WeakReference<>(textView));
|
||||
|
||||
if (likeDislikeView.isSelected() && isShortTextViewOnScreen(textView)) {
|
||||
Logger.printDebug(() -> "Shorts dislike is already selected");
|
||||
ReturnYouTubeDislike videoData = currentVideoData;
|
||||
if (videoData != null) videoData.setUserVote(Vote.DISLIKE);
|
||||
}
|
||||
|
||||
// For the first short played, the Shorts dislike hook is called after the video id hook.
|
||||
// But for most other times this hook is called before the video id (which is not ideal).
|
||||
// Must update the TextViews here, and also after the videoId changes.
|
||||
updateOnScreenShortsTextViews(false);
|
||||
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "setShortsDislikes failure", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param forceUpdate if false, then only update the 'loading text views.
|
||||
* If true, update all on screen text views.
|
||||
*/
|
||||
private static void updateOnScreenShortsTextViews(boolean forceUpdate) {
|
||||
try {
|
||||
clearRemovedShortsTextViews();
|
||||
if (shortsTextViewRefs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ReturnYouTubeDislike videoData = currentVideoData;
|
||||
if (videoData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.printDebug(() -> "updateShortsTextViews");
|
||||
|
||||
Runnable update = () -> {
|
||||
Spanned shortsDislikesSpan = videoData.getDislikeSpanForShort(SHORTS_LOADING_SPAN);
|
||||
Utils.runOnMainThreadNowOrLater(() -> {
|
||||
String videoId = videoData.getVideoId();
|
||||
if (!videoId.equals(VideoInformation.getVideoId())) {
|
||||
// User swiped to new video before fetch completed
|
||||
Logger.printDebug(() -> "Ignoring stale dislikes data for short: " + videoId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update text views that appear to be visible on screen.
|
||||
// Only 1 will be the actual textview for the current Short,
|
||||
// but discarded and not yet garbage collected views can remain.
|
||||
// So must set the dislike span on all views that match.
|
||||
for (WeakReference<TextView> textViewRef : shortsTextViewRefs) {
|
||||
TextView textView = textViewRef.get();
|
||||
if (textView == null) {
|
||||
continue;
|
||||
}
|
||||
if (isShortTextViewOnScreen(textView)
|
||||
&& (forceUpdate || textView.getText().toString().equals(SHORTS_LOADING_SPAN.toString()))) {
|
||||
Logger.printDebug(() -> "Setting Shorts TextView to: " + shortsDislikesSpan);
|
||||
textView.setText(shortsDislikesSpan);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
if (videoData.fetchCompleted()) {
|
||||
update.run(); // Network call is completed, no need to wait on background thread.
|
||||
} else {
|
||||
Utils.runOnBackgroundThread(update);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "updateOnScreenShortsTextViews failure", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a view is within the screen bounds.
|
||||
*/
|
||||
private static boolean isShortTextViewOnScreen(@NonNull View view) {
|
||||
final int[] location = new int[2];
|
||||
view.getLocationInWindow(location);
|
||||
if (location[0] <= 0 && location[1] <= 0) { // Lower bound
|
||||
return false;
|
||||
}
|
||||
Rect windowRect = new Rect();
|
||||
view.getWindowVisibleDisplayFrame(windowRect); // Upper bound
|
||||
return location[0] < windowRect.width() && location[1] < windowRect.height();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Video Id and voting hooks (all players).
|
||||
//
|
||||
@@ -503,8 +368,7 @@ public class ReturnYouTubeDislikePatch {
|
||||
if (videoIdIsShort && (!isShortAndOpeningOrPlaying || !Settings.RYD_SHORTS.get())) {
|
||||
return;
|
||||
}
|
||||
final boolean waitForFetchToComplete = !IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER
|
||||
&& videoIdIsShort && !lastPlayerResponseWasShort;
|
||||
final boolean waitForFetchToComplete = videoIdIsShort && !lastPlayerResponseWasShort;
|
||||
|
||||
Logger.printDebug(() -> "Prefetching RYD for video: " + videoId);
|
||||
ReturnYouTubeDislike fetch = ReturnYouTubeDislike.getFetchForVideoId(videoId);
|
||||
@@ -557,12 +421,6 @@ public class ReturnYouTubeDislikePatch {
|
||||
data.setVideoIdIsShort(true);
|
||||
}
|
||||
currentVideoData = data;
|
||||
|
||||
// Current video id hook can be called out of order with the non litho Shorts text view hook.
|
||||
// Must manually update again here.
|
||||
if (isNoneHiddenOrSlidingMinimized) {
|
||||
updateOnScreenShortsTextViews(true);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "newVideoLoaded failure", ex);
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ public final class AdsFilter extends Filter {
|
||||
"video_display_button_group_layout",
|
||||
"landscape_image_wide_button_layout",
|
||||
"video_display_carousel_button_group_layout",
|
||||
"video_display_full_buttoned_short_dr_layout",
|
||||
"compact_landscape_image_layout", // Tablet layout search results.
|
||||
"text_image_no_button_layout" // Tablet layout search results.
|
||||
);
|
||||
|
||||
@@ -2,20 +2,20 @@ package app.revanced.extension.youtube.patches.components;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.extension.youtube.patches.playback.quality.RestoreOldVideoQualityMenuPatch;
|
||||
import app.revanced.extension.youtube.patches.playback.quality.AdvancedVideoQualityMenuPatch;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
|
||||
/**
|
||||
* Abuse LithoFilter for {@link RestoreOldVideoQualityMenuPatch}.
|
||||
* Abuse LithoFilter for {@link AdvancedVideoQualityMenuPatch}.
|
||||
*/
|
||||
public final class VideoQualityMenuFilterPatch extends Filter {
|
||||
public final class AdvancedVideoQualityMenuFilter extends Filter {
|
||||
// Must be volatile or synchronized, as litho filtering runs off main thread
|
||||
// and this field is then access from the main thread.
|
||||
public static volatile boolean isVideoQualityMenuVisible;
|
||||
|
||||
public VideoQualityMenuFilterPatch() {
|
||||
public AdvancedVideoQualityMenuFilter() {
|
||||
addPathCallbacks(new StringFilterGroup(
|
||||
Settings.RESTORE_OLD_VIDEO_QUALITY_MENU,
|
||||
Settings.ADVANCED_VIDEO_QUALITY_MENU,
|
||||
"quick_quality_sheet_content.eml-js"
|
||||
));
|
||||
}
|
||||
@@ -12,10 +12,12 @@ final class CommentsFilter extends Filter {
|
||||
|
||||
private final StringFilterGroup commentComposer;
|
||||
private final ByteArrayFilterGroup emojiPickerBufferGroup;
|
||||
private final StringFilterGroup filterChipBar;
|
||||
private final ByteArrayFilterGroup aiCommentsSummary;
|
||||
|
||||
public CommentsFilter() {
|
||||
var chatSummary = new StringFilterGroup(
|
||||
Settings.HIDE_COMMENTS_CHAT_SUMMARY,
|
||||
Settings.HIDE_COMMENTS_AI_CHAT_SUMMARY,
|
||||
"live_chat_summary_banner.eml"
|
||||
);
|
||||
|
||||
@@ -58,6 +60,16 @@ final class CommentsFilter extends Filter {
|
||||
"id.comment.quick_emoji.button"
|
||||
);
|
||||
|
||||
filterChipBar = new StringFilterGroup(
|
||||
Settings.HIDE_COMMENTS_AI_SUMMARY,
|
||||
"filter_chip_bar.eml"
|
||||
);
|
||||
|
||||
aiCommentsSummary = new ByteArrayFilterGroup(
|
||||
null,
|
||||
"yt_fill_spark_"
|
||||
);
|
||||
|
||||
addPathCallbacks(
|
||||
chatSummary,
|
||||
commentsByMembers,
|
||||
@@ -65,7 +77,8 @@ final class CommentsFilter extends Filter {
|
||||
createAShort,
|
||||
previewComment,
|
||||
thanksButton,
|
||||
commentComposer
|
||||
commentComposer,
|
||||
filterChipBar
|
||||
);
|
||||
}
|
||||
|
||||
@@ -84,6 +97,13 @@ final class CommentsFilter extends Filter {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (matchedGroup == filterChipBar) {
|
||||
if (aiCommentsSummary.check(protobufBufferArray).isFiltered()) {
|
||||
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,11 @@ final class DescriptionComponentsFilter extends Filter {
|
||||
"metadata"
|
||||
);
|
||||
|
||||
final StringFilterGroup aiGeneratedVideoSummarySection = new StringFilterGroup(
|
||||
Settings.HIDE_AI_GENERATED_VIDEO_SUMMARY_SECTION,
|
||||
"cell_expandable_metadata.eml"
|
||||
);
|
||||
|
||||
final StringFilterGroup attributesSection = new StringFilterGroup(
|
||||
Settings.HIDE_ATTRIBUTES_SECTION,
|
||||
"gaming_section",
|
||||
@@ -67,6 +72,7 @@ final class DescriptionComponentsFilter extends Filter {
|
||||
);
|
||||
|
||||
addPathCallbacks(
|
||||
aiGeneratedVideoSummarySection,
|
||||
attributesSection,
|
||||
infoCardsSection,
|
||||
howThisWasMadeSection,
|
||||
|
||||
@@ -462,6 +462,12 @@ public final class LayoutComponentsFilter extends Filter {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Do not hide if the navigation back button is visible,
|
||||
// otherwise the content shelves in the YouTube Movie/Courses pages is hidden.
|
||||
if (NavigationBar.isBackButtonVisible()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check navigation button last.
|
||||
// Only filter if the library tab is not selected.
|
||||
// This check is important as the shelf layout is used for the library tab playlists.
|
||||
|
||||
@@ -8,30 +8,30 @@ import android.widget.ListView;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.youtube.patches.components.VideoQualityMenuFilterPatch;
|
||||
import app.revanced.extension.youtube.patches.components.AdvancedVideoQualityMenuFilter;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
|
||||
/**
|
||||
* This patch contains the logic to show the old video quality menu.
|
||||
* This patch contains the logic to always open the advanced video quality menu.
|
||||
* Two methods are required, because the quality menu is a RecyclerView in the new YouTube version
|
||||
* and a ListView in the old one.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public final class RestoreOldVideoQualityMenuPatch {
|
||||
public final class AdvancedVideoQualityMenuPatch {
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void onFlyoutMenuCreate(RecyclerView recyclerView) {
|
||||
if (!Settings.RESTORE_OLD_VIDEO_QUALITY_MENU.get()) return;
|
||||
if (!Settings.ADVANCED_VIDEO_QUALITY_MENU.get()) return;
|
||||
|
||||
recyclerView.getViewTreeObserver().addOnDrawListener(() -> {
|
||||
try {
|
||||
// Check if the current view is the quality menu.
|
||||
if (!VideoQualityMenuFilterPatch.isVideoQualityMenuVisible || recyclerView.getChildCount() == 0) {
|
||||
if (!AdvancedVideoQualityMenuFilter.isVideoQualityMenuVisible || recyclerView.getChildCount() == 0) {
|
||||
return;
|
||||
}
|
||||
VideoQualityMenuFilterPatch.isVideoQualityMenuVisible = false;
|
||||
AdvancedVideoQualityMenuFilter.isVideoQualityMenuVisible = false;
|
||||
|
||||
ViewParent quickQualityViewParent = Utils.getParentView(recyclerView, 3);
|
||||
if (!(quickQualityViewParent instanceof ViewGroup)) {
|
||||
@@ -39,16 +39,15 @@ public final class RestoreOldVideoQualityMenuPatch {
|
||||
}
|
||||
|
||||
View firstChild = recyclerView.getChildAt(0);
|
||||
if (!(firstChild instanceof ViewGroup)) {
|
||||
if (!(firstChild instanceof ViewGroup firstChildGroup)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ViewGroup advancedQualityParentView = (ViewGroup) firstChild;
|
||||
if (advancedQualityParentView.getChildCount() < 4) {
|
||||
if (firstChildGroup.getChildCount() < 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
View advancedQualityView = advancedQualityParentView.getChildAt(3);
|
||||
View advancedQualityView = firstChildGroup.getChildAt(3);
|
||||
if (advancedQualityView == null) {
|
||||
return;
|
||||
}
|
||||
@@ -71,7 +70,7 @@ public final class RestoreOldVideoQualityMenuPatch {
|
||||
* Used to force the creation of the advanced menu item for the Shorts quality flyout.
|
||||
*/
|
||||
public static boolean forceAdvancedVideoQualityMenuCreation(boolean original) {
|
||||
return Settings.RESTORE_OLD_VIDEO_QUALITY_MENU.get() || original;
|
||||
return Settings.ADVANCED_VIDEO_QUALITY_MENU.get() || original;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,8 +78,8 @@ public final class RestoreOldVideoQualityMenuPatch {
|
||||
*
|
||||
* Used if spoofing to an old app version, and also used for the Shorts video quality flyout.
|
||||
*/
|
||||
public static void showOldVideoQualityMenu(final ListView listView) {
|
||||
if (!Settings.RESTORE_OLD_VIDEO_QUALITY_MENU.get()) return;
|
||||
public static void showAdvancedVideoQualityMenu(ListView listView) {
|
||||
if (!Settings.ADVANCED_VIDEO_QUALITY_MENU.get()) return;
|
||||
|
||||
listView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
|
||||
@Override
|
||||
@@ -12,15 +12,19 @@ import java.util.List;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||
import app.revanced.extension.shared.settings.IntegerSetting;
|
||||
import app.revanced.extension.youtube.patches.VideoInformation;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class RememberVideoQualityPatch {
|
||||
private static final int AUTOMATIC_VIDEO_QUALITY_VALUE = -2;
|
||||
private static final IntegerSetting wifiQualitySetting = Settings.VIDEO_QUALITY_DEFAULT_WIFI;
|
||||
private static final IntegerSetting mobileQualitySetting = Settings.VIDEO_QUALITY_DEFAULT_MOBILE;
|
||||
private static final IntegerSetting videoQualityWifi = Settings.VIDEO_QUALITY_DEFAULT_WIFI;
|
||||
private static final IntegerSetting videoQualityMobile = Settings.VIDEO_QUALITY_DEFAULT_MOBILE;
|
||||
private static final IntegerSetting shortsQualityWifi = Settings.SHORTS_QUALITY_DEFAULT_WIFI;
|
||||
private static final IntegerSetting shortsQualityMobile = Settings.SHORTS_QUALITY_DEFAULT_MOBILE;
|
||||
|
||||
private static boolean qualityNeedsUpdating;
|
||||
|
||||
@@ -41,17 +45,29 @@ public class RememberVideoQualityPatch {
|
||||
@Nullable
|
||||
private static List<Integer> videoQualities;
|
||||
|
||||
private static boolean shouldRememberVideoQuality() {
|
||||
BooleanSetting preference = ShortsPlayerState.isOpen() ?
|
||||
Settings.REMEMBER_SHORTS_QUALITY_LAST_SELECTED
|
||||
: Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED;
|
||||
return preference.get();
|
||||
}
|
||||
|
||||
private static void changeDefaultQuality(int defaultQuality) {
|
||||
String networkTypeMessage;
|
||||
boolean useShortsPreference = ShortsPlayerState.isOpen();
|
||||
if (Utils.getNetworkType() == NetworkType.MOBILE) {
|
||||
mobileQualitySetting.save(defaultQuality);
|
||||
if (useShortsPreference) shortsQualityMobile.save(defaultQuality);
|
||||
else videoQualityMobile.save(defaultQuality);
|
||||
networkTypeMessage = str("revanced_remember_video_quality_mobile");
|
||||
} else {
|
||||
wifiQualitySetting.save(defaultQuality);
|
||||
if (useShortsPreference) shortsQualityWifi.save(defaultQuality);
|
||||
else videoQualityWifi.save(defaultQuality);
|
||||
networkTypeMessage = str("revanced_remember_video_quality_wifi");
|
||||
}
|
||||
Utils.showToastShort(
|
||||
str("revanced_remember_video_quality_toast", networkTypeMessage, (defaultQuality + "p")));
|
||||
Utils.showToastShort(str(
|
||||
useShortsPreference ? "revanced_remember_video_quality_toast_shorts" : "revanced_remember_video_quality_toast",
|
||||
networkTypeMessage, (defaultQuality + "p")
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,9 +78,10 @@ public class RememberVideoQualityPatch {
|
||||
*/
|
||||
public static int setVideoQuality(Object[] qualities, final int originalQualityIndex, Object qInterface, String qIndexMethod) {
|
||||
try {
|
||||
boolean useShortsPreference = ShortsPlayerState.isOpen();
|
||||
final int preferredQuality = Utils.getNetworkType() == NetworkType.MOBILE
|
||||
? mobileQualitySetting.get()
|
||||
: wifiQualitySetting.get();
|
||||
? (useShortsPreference ? shortsQualityMobile : videoQualityMobile).get()
|
||||
: (useShortsPreference ? shortsQualityWifi : videoQualityWifi).get();
|
||||
|
||||
if (!userChangedDefaultQuality && preferredQuality == AUTOMATIC_VIDEO_QUALITY_VALUE) {
|
||||
return originalQualityIndex; // Nothing to do.
|
||||
@@ -141,17 +158,17 @@ public class RememberVideoQualityPatch {
|
||||
* Injection point. Old quality menu.
|
||||
*/
|
||||
public static void userChangedQuality(int selectedQualityIndex) {
|
||||
if (!Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.get()) return;
|
||||
|
||||
userSelectedQualityIndex = selectedQualityIndex;
|
||||
userChangedDefaultQuality = true;
|
||||
if (shouldRememberVideoQuality()) {
|
||||
userSelectedQualityIndex = selectedQualityIndex;
|
||||
userChangedDefaultQuality = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point. New quality menu.
|
||||
*/
|
||||
public static void userChangedQualityInNewFlyout(int selectedQuality) {
|
||||
if (!Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.get()) return;
|
||||
if (!shouldRememberVideoQuality()) return;
|
||||
|
||||
changeDefaultQuality(selectedQuality); // Quality is human readable resolution (ie: 1080).
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ import java.util.concurrent.*;
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.youtube.ThemeHelper;
|
||||
import app.revanced.extension.youtube.patches.spoof.SpoofAppVersionPatch;
|
||||
import app.revanced.extension.youtube.returnyoutubedislike.requests.RYDVoteData;
|
||||
import app.revanced.extension.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
@@ -87,9 +86,6 @@ public class ReturnYouTubeDislike {
|
||||
*/
|
||||
private static final char MIDDLE_SEPARATOR_CHARACTER = 'â'; // 'bullseye'
|
||||
|
||||
private static final boolean IS_SPOOFING_TO_OLD_SEPARATOR_COLOR
|
||||
= SpoofAppVersionPatch.isSpoofingToLessThan("18.10.00");
|
||||
|
||||
/**
|
||||
* Cached lookup of all video ids.
|
||||
*/
|
||||
@@ -184,17 +180,8 @@ public class ReturnYouTubeDislike {
|
||||
* Color of the left and middle separator, based on the color of the right separator.
|
||||
* It's unknown where YT gets the color from, and the values here are approximated by hand.
|
||||
* Ideally, this would be the actual color YT uses at runtime.
|
||||
*
|
||||
* Older versions before the 'Me' library tab use a slightly different color.
|
||||
* If spoofing was previously used and is now turned off,
|
||||
* or an old version was recently upgraded then the old colors are sometimes still used.
|
||||
*/
|
||||
private static int getSeparatorColor() {
|
||||
if (IS_SPOOFING_TO_OLD_SEPARATOR_COLOR) {
|
||||
return ThemeHelper.isDarkTheme()
|
||||
? 0x29AAAAAA // transparent dark gray
|
||||
: 0xFFD9D9D9; // light gray
|
||||
}
|
||||
return ThemeHelper.isDarkTheme()
|
||||
? 0x33FFFFFF
|
||||
: 0xFFD9D9D9;
|
||||
|
||||
@@ -3,7 +3,6 @@ package app.revanced.extension.youtube.settings;
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static app.revanced.extension.shared.settings.Setting.Availability;
|
||||
import static app.revanced.extension.shared.settings.Setting.migrateFromOldPreferences;
|
||||
import static app.revanced.extension.shared.settings.Setting.migrateOldSettingToNew;
|
||||
import static app.revanced.extension.shared.settings.Setting.parent;
|
||||
import static app.revanced.extension.shared.settings.Setting.parentsAny;
|
||||
@@ -21,7 +20,6 @@ import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerT
|
||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_4;
|
||||
import static app.revanced.extension.youtube.patches.OpenShortsInRegularPlayerPatch.ShortsPlayerType;
|
||||
import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability;
|
||||
import static app.revanced.extension.youtube.patches.VersionCheckPatch.IS_19_17_OR_GREATER;
|
||||
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE;
|
||||
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP;
|
||||
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY;
|
||||
@@ -38,7 +36,6 @@ import app.revanced.extension.shared.settings.IntegerSetting;
|
||||
import app.revanced.extension.shared.settings.LongSetting;
|
||||
import app.revanced.extension.shared.settings.Setting;
|
||||
import app.revanced.extension.shared.settings.StringSetting;
|
||||
import app.revanced.extension.shared.settings.preference.SharedPrefCategory;
|
||||
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.DeArrowAvailability;
|
||||
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.StillImagesAvailability;
|
||||
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption;
|
||||
@@ -47,11 +44,14 @@ import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
|
||||
|
||||
public class Settings extends BaseSettings {
|
||||
// Video
|
||||
public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE);
|
||||
public static final BooleanSetting RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE);
|
||||
public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_last_selected", FALSE);
|
||||
public static final IntegerSetting VIDEO_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_video_quality_default_wifi", -2);
|
||||
public static final IntegerSetting VIDEO_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_video_quality_default_mobile", -2);
|
||||
public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_last_selected", FALSE);
|
||||
public static final IntegerSetting SHORTS_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_shorts_quality_default_wifi", -2, true);
|
||||
public static final IntegerSetting SHORTS_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_shorts_quality_default_mobile", -2, true);
|
||||
public static final BooleanSetting REMEMBER_SHORTS_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_shorts_quality_last_selected", FALSE);
|
||||
public static final BooleanSetting ADVANCED_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_advanced_video_quality_menu", TRUE);
|
||||
public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE);
|
||||
// Speed
|
||||
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);
|
||||
@@ -168,14 +168,16 @@ public class Settings extends BaseSettings {
|
||||
public static final StringSetting EXTERNAL_DOWNLOADER_PACKAGE_NAME = new StringSetting("revanced_external_downloader_name",
|
||||
"org.schabi.newpipe" /* NewPipe */, parentsAny(EXTERNAL_DOWNLOADER, EXTERNAL_DOWNLOADER_ACTION_BUTTON));
|
||||
// Comments
|
||||
public static final BooleanSetting HIDE_COMMENTS_CHAT_SUMMARY = new BooleanSetting("revanced_hide_comments_chat_summary", FALSE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_AI_CHAT_SUMMARY = new BooleanSetting("revanced_hide_comments_ai_chat_summary", FALSE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_AI_SUMMARY = new BooleanSetting("revanced_hide_comments_ai_summary", FALSE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_BY_MEMBERS_HEADER = new BooleanSetting("revanced_hide_comments_by_members_header", FALSE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_CREATE_A_SHORT_BUTTON = new BooleanSetting("revanced_hide_comments_create_a_short_button", TRUE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_TIMESTAMP_AND_EMOJI_BUTTONS = new BooleanSetting("revanced_hide_comments_timestamp_and_emoji_buttons", TRUE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_PREVIEW_COMMENT = new BooleanSetting("revanced_hide_comments_preview_comment", FALSE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_SECTION = new BooleanSetting("revanced_hide_comments_section", FALSE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_THANKS_BUTTON = new BooleanSetting("revanced_hide_comments_thanks_button", TRUE);
|
||||
public static final BooleanSetting HIDE_COMMENTS_TIMESTAMP_AND_EMOJI_BUTTONS = new BooleanSetting("revanced_hide_comments_timestamp_and_emoji_buttons", TRUE);
|
||||
// Description
|
||||
public static final BooleanSetting HIDE_AI_GENERATED_VIDEO_SUMMARY_SECTION = new BooleanSetting("revanced_hide_ai_generated_video_summary_section", FALSE);
|
||||
public static final BooleanSetting HIDE_ATTRIBUTES_SECTION = new BooleanSetting("revanced_hide_attributes_section", FALSE);
|
||||
public static final BooleanSetting HIDE_CHAPTERS_SECTION = new BooleanSetting("revanced_hide_chapters_section", TRUE);
|
||||
public static final BooleanSetting HIDE_HOW_THIS_WAS_MADE_SECTION = new BooleanSetting("revanced_hide_how_this_was_made_section", FALSE);
|
||||
@@ -218,7 +220,7 @@ public class Settings extends BaseSettings {
|
||||
public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message");
|
||||
public static final BooleanSetting 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 StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", IS_19_17_OR_GREATER ? "19.26.42" : "17.33.42", true, parent(SPOOF_APP_VERSION));
|
||||
public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", "19.01.34", true, parent(SPOOF_APP_VERSION));
|
||||
// Custom filter
|
||||
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));
|
||||
@@ -362,52 +364,54 @@ public class Settings extends BaseSettings {
|
||||
public static final BooleanSetting SB_SEEN_GUIDELINES = new BooleanSetting("sb_seen_guidelines", FALSE, false, false);
|
||||
public static final StringSetting SB_CATEGORY_SPONSOR = new StringSetting("sb_sponsor", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_SPONSOR_COLOR = new StringSetting("sb_sponsor_color", "#00D400");
|
||||
public static final FloatSetting SB_CATEGORY_SPONSOR_OPACITY = new FloatSetting("sb_sponsor_opacity", 0.8f);
|
||||
public static final StringSetting SB_CATEGORY_SELF_PROMO = new StringSetting("sb_selfpromo", MANUAL_SKIP.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_SELF_PROMO_COLOR = new StringSetting("sb_selfpromo_color", "#FFFF00");
|
||||
public static final FloatSetting SB_CATEGORY_SELF_PROMO_OPACITY = new FloatSetting("sb_selfpromo_opacity", 0.8f);
|
||||
public static final StringSetting SB_CATEGORY_INTERACTION = new StringSetting("sb_interaction", MANUAL_SKIP.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_INTERACTION_COLOR = new StringSetting("sb_interaction_color", "#CC00FF");
|
||||
public static final FloatSetting SB_CATEGORY_INTERACTION_OPACITY = new FloatSetting("sb_interaction_opacity", 0.8f);
|
||||
public static final StringSetting SB_CATEGORY_HIGHLIGHT = new StringSetting("sb_highlight", MANUAL_SKIP.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_HIGHLIGHT_COLOR = new StringSetting("sb_highlight_color", "#FF1684");
|
||||
public static final FloatSetting SB_CATEGORY_HIGHLIGHT_OPACITY = new FloatSetting("sb_highlight_opacity", 0.8f);
|
||||
public static final StringSetting SB_CATEGORY_INTRO = new StringSetting("sb_intro", MANUAL_SKIP.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_INTRO_COLOR = new StringSetting("sb_intro_color", "#00FFFF");
|
||||
public static final FloatSetting SB_CATEGORY_INTRO_OPACITY = new FloatSetting("sb_intro_opacity", 0.8f);
|
||||
public static final StringSetting SB_CATEGORY_OUTRO = new StringSetting("sb_outro", MANUAL_SKIP.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_OUTRO_COLOR = new StringSetting("sb_outro_color", "#0202ED");
|
||||
public static final FloatSetting SB_CATEGORY_OUTRO_OPACITY = new FloatSetting("sb_outro_opacity", 0.8f);
|
||||
public static final StringSetting SB_CATEGORY_PREVIEW = new StringSetting("sb_preview", IGNORE.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_PREVIEW_COLOR = new StringSetting("sb_preview_color", "#008FD6");
|
||||
public static final FloatSetting SB_CATEGORY_PREVIEW_OPACITY = new FloatSetting("sb_preview_opacity", 0.8f);
|
||||
public static final StringSetting SB_CATEGORY_FILLER = new StringSetting("sb_filler", IGNORE.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_FILLER_COLOR = new StringSetting("sb_filler_color", "#7300FF");
|
||||
public static final FloatSetting SB_CATEGORY_FILLER_OPACITY = new FloatSetting("sb_filler_opacity", 0.8f);
|
||||
public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC = new StringSetting("sb_music_offtopic", MANUAL_SKIP.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC_COLOR = new StringSetting("sb_music_offtopic_color", "#FF9900");
|
||||
public static final FloatSetting SB_CATEGORY_MUSIC_OFFTOPIC_OPACITY = new FloatSetting("sb_music_offtopic_opacity", 0.8f);
|
||||
public static final StringSetting SB_CATEGORY_UNSUBMITTED = new StringSetting("sb_unsubmitted", SKIP_AUTOMATICALLY.reVancedKeyValue);
|
||||
public static final StringSetting SB_CATEGORY_UNSUBMITTED_COLOR = new StringSetting("sb_unsubmitted_color", "#FFFFFF");
|
||||
public static final FloatSetting SB_CATEGORY_UNSUBMITTED_OPACITY = new FloatSetting("sb_unsubmitted_opacity", 1.0f);
|
||||
|
||||
// Deprecated migrations
|
||||
private static final StringSetting DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING = new StringSetting("uuid", ""); // Delete sometime in 2024
|
||||
private static final BooleanSetting DEPRECATED_HIDE_PLAYER_BUTTONS = new BooleanSetting("revanced_hide_player_buttons", FALSE, true);
|
||||
private static final BooleanSetting DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_video_quality_menu_footer", FALSE);
|
||||
private static final IntegerSetting DEPRECATED_SWIPE_OVERLAY_BACKGROUND_ALPHA = new IntegerSetting("revanced_swipe_overlay_background_alpha", 127);
|
||||
private static final StringSetting DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY = new StringSetting("revanced_seekbar_custom_color_value", "#FF0033");
|
||||
private static final BooleanSetting DEPRECATED_DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE);
|
||||
private static final BooleanSetting DEPRECATED_RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE);
|
||||
|
||||
static {
|
||||
// region Migration
|
||||
|
||||
// Do _not_ delete this SB private user id migration property until sometime in early 2025.
|
||||
// This is the only setting that cannot be reconfigured if lost,
|
||||
// and more time should be given for users who rarely upgrade.
|
||||
SharedPrefCategory sbPrefs = new SharedPrefCategory("sponsor-block");
|
||||
// Remove the "sb_" prefix, as old settings are saved without it.
|
||||
String key = DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING.key.substring(3);
|
||||
migrateFromOldPreferences(sbPrefs, DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, key);
|
||||
|
||||
migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID);
|
||||
|
||||
migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_BUTTONS, HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS);
|
||||
|
||||
migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER, HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER);
|
||||
|
||||
migrateOldSettingToNew(DEPRECATED_DISABLE_SUGGESTED_VIDEO_END_SCREEN, HIDE_END_SCREEN_SUGGESTED_VIDEO);
|
||||
|
||||
migrateOldSettingToNew(DEPRECATED_RESTORE_OLD_VIDEO_QUALITY_MENU, ADVANCED_VIDEO_QUALITY_MENU);
|
||||
|
||||
// Migrate renamed enum.
|
||||
//noinspection deprecation
|
||||
if (MINIPLAYER_TYPE.get() == MiniplayerType.PHONE) {
|
||||
@@ -443,6 +447,12 @@ public class Settings extends BaseSettings {
|
||||
DEPRECATED_SWIPE_OVERLAY_BACKGROUND_ALPHA.resetToDefault();
|
||||
}
|
||||
|
||||
// Old spoof versions that no longer work.
|
||||
if (SPOOF_APP_VERSION_TARGET.get().compareTo(SPOOF_APP_VERSION_TARGET.defaultValue) < 0) {
|
||||
Logger.printInfo(() -> "Resetting spoof app version target");
|
||||
SPOOF_APP_VERSION_TARGET.resetToDefault();
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region SB import/export callbacks
|
||||
|
||||
@@ -18,7 +18,6 @@ import android.widget.TextView;
|
||||
import android.widget.Toolbar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
@@ -74,7 +73,8 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(pairsToSort, (pair1, pair2) -> pair1.first.compareToIgnoreCase(pair2.first));
|
||||
pairsToSort.sort((pair1, pair2)
|
||||
-> pair1.first.compareToIgnoreCase(pair2.first));
|
||||
|
||||
CharSequence[] sortedEntries = new CharSequence[entrySize];
|
||||
CharSequence[] sortedEntryValues = new CharSequence[entrySize];
|
||||
@@ -109,6 +109,7 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
|
||||
CustomPlaybackSpeedPatch.initializeListPreference(playbackPreference);
|
||||
}
|
||||
|
||||
sortPreferenceListMenu(Settings.CHANGE_START_PAGE);
|
||||
sortPreferenceListMenu(Settings.SPOOF_VIDEO_STREAMS_LANGUAGE);
|
||||
sortPreferenceListMenu(BaseSettings.REVANCED_LANGUAGE);
|
||||
} catch (Exception ex) {
|
||||
@@ -137,11 +138,13 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
|
||||
.findViewById(android.R.id.content)
|
||||
.getParent();
|
||||
|
||||
// Fix required for Android 15 and YT 19.45+
|
||||
// Fix edge-to-edge screen with Android 15 and YT 19.45+
|
||||
// https://developer.android.com/develop/ui/views/layout/edge-to-edge#system-bars-insets
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
rootView.setOnApplyWindowInsetsListener((v, insets) -> {
|
||||
Insets statusInsets = insets.getInsets(WindowInsets.Type.statusBars());
|
||||
v.setPadding(0, statusInsets.top, 0, 0);
|
||||
Insets navInsets = insets.getInsets(WindowInsets.Type.navigationBars());
|
||||
v.setPadding(0, statusInsets.top, 0, navInsets.bottom);
|
||||
return insets;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import android.preference.PreferenceScreen;
|
||||
import android.preference.SwitchPreference;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.settings.Setting;
|
||||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
import app.revanced.extension.youtube.patches.ReturnYouTubeDislikePatch;
|
||||
@@ -85,9 +86,7 @@ public class ReturnYouTubeDislikePreferenceFragment extends PreferenceFragment {
|
||||
shortsPreference = new SwitchPreference(context);
|
||||
shortsPreference.setChecked(Settings.RYD_SHORTS.get());
|
||||
shortsPreference.setTitle(str("revanced_ryd_shorts_title"));
|
||||
String shortsSummary = ReturnYouTubeDislikePatch.IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER
|
||||
? str("revanced_ryd_shorts_summary_on")
|
||||
: str("revanced_ryd_shorts_summary_on_disclaimer");
|
||||
String shortsSummary = str("revanced_ryd_shorts_summary_on_disclaimer");
|
||||
shortsPreference.setSummaryOn(shortsSummary);
|
||||
shortsPreference.setSummaryOff(str("revanced_ryd_shorts_summary_off"));
|
||||
shortsPreference.setOnPreferenceChangeListener((pref, newValue) -> {
|
||||
@@ -237,6 +236,8 @@ public class ReturnYouTubeDislikePreferenceFragment extends PreferenceFragment {
|
||||
"revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_non_zero_summary"));
|
||||
preferenceScreen.addPreference(statisticPreference);
|
||||
}
|
||||
|
||||
Utils.setPreferenceTitlesToMultiLineIfNeeded(preferenceScreen);
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "onCreate failure", ex);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import androidx.annotation.Nullable;
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.settings.Setting;
|
||||
import app.revanced.extension.shared.settings.preference.ResettableEditTextPreference;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.sponsorblock.SegmentPlaybackController;
|
||||
import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
|
||||
@@ -44,8 +45,8 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
|
||||
private SwitchPreference showTimeWithoutSegments;
|
||||
private SwitchPreference toastOnConnectionError;
|
||||
|
||||
private EditTextPreference newSegmentStep;
|
||||
private EditTextPreference minSegmentDuration;
|
||||
private ResettableEditTextPreference newSegmentStep;
|
||||
private ResettableEditTextPreference minSegmentDuration;
|
||||
private EditTextPreference privateUserId;
|
||||
private EditTextPreference importExport;
|
||||
private Preference apiUrl;
|
||||
@@ -159,6 +160,8 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
|
||||
|
||||
addAboutCategory(context, preferenceScreen);
|
||||
|
||||
Utils.setPreferenceTitlesToMultiLineIfNeeded(preferenceScreen);
|
||||
|
||||
updateUI();
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "onCreate failure", ex);
|
||||
@@ -268,7 +271,8 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
|
||||
return true;
|
||||
});
|
||||
|
||||
newSegmentStep = new EditTextPreference(context);
|
||||
newSegmentStep = new ResettableEditTextPreference(context);
|
||||
newSegmentStep.setSetting(Settings.SB_CREATE_NEW_SEGMENT_STEP);
|
||||
newSegmentStep.setTitle(str("revanced_sb_general_adjusting"));
|
||||
newSegmentStep.setSummary(str("revanced_sb_general_adjusting_sum"));
|
||||
newSegmentStep.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
@@ -326,7 +330,8 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
|
||||
});
|
||||
category.addPreference(trackSkips);
|
||||
|
||||
minSegmentDuration = new EditTextPreference(context);
|
||||
minSegmentDuration = new ResettableEditTextPreference(context);
|
||||
minSegmentDuration.setSetting(Settings.SB_SEGMENT_MIN_DURATION);
|
||||
minSegmentDuration.setTitle(str("revanced_sb_general_min_duration"));
|
||||
minSegmentDuration.setSummary(str("revanced_sb_general_min_duration_sum"));
|
||||
minSegmentDuration.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
|
||||
@@ -345,7 +350,15 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
|
||||
});
|
||||
category.addPreference(minSegmentDuration);
|
||||
|
||||
privateUserId = new EditTextPreference(context);
|
||||
privateUserId = new EditTextPreference(context) {
|
||||
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
||||
Utils.setEditTextDialogTheme(builder);
|
||||
|
||||
builder.setNeutralButton(str("revanced_sb_settings_copy"), (dialog, which) -> {
|
||||
Utils.setClipboard(getEditText().getText().toString());
|
||||
});
|
||||
}
|
||||
};
|
||||
privateUserId.setTitle(str("revanced_sb_general_uuid"));
|
||||
privateUserId.setSummary(str("revanced_sb_general_uuid_sum"));
|
||||
privateUserId.setOnPreferenceChangeListener((preference1, newValue) -> {
|
||||
@@ -504,7 +517,7 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment {
|
||||
|
||||
if (stats.totalSegmentCountIncludingIgnored > 0) {
|
||||
// If user has not created any segments, there's no reason to set a username.
|
||||
EditTextPreference preference = new EditTextPreference(context);
|
||||
EditTextPreference preference = new ResettableEditTextPreference(context);
|
||||
statsCategory.addPreference(preference);
|
||||
String userName = stats.userName;
|
||||
preference.setTitle(fromHtml(str("revanced_sb_stats_username", userName)));
|
||||
|
||||
@@ -73,6 +73,7 @@ public class SpoofStreamingDataSideEffectsPreference extends Preference {
|
||||
if (currentClientType == clientType) {
|
||||
return;
|
||||
}
|
||||
currentClientType = clientType;
|
||||
|
||||
Logger.printDebug(() -> "Updating spoof stream side effects preference");
|
||||
setEnabled(BaseSettings.SPOOF_VIDEO_STREAMS.get());
|
||||
|
||||
@@ -3,7 +3,9 @@ package app.revanced.extension.youtube.shared;
|
||||
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton.CREATE;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -24,12 +26,22 @@ import app.revanced.extension.youtube.settings.Settings;
|
||||
@SuppressWarnings("unused")
|
||||
public final class NavigationBar {
|
||||
|
||||
/**
|
||||
* Interface to call obfuscated methods in AppCompat Toolbar class.
|
||||
*/
|
||||
public interface AppCompatToolbarPatchInterface {
|
||||
Drawable patch_getNavigationIcon();
|
||||
}
|
||||
|
||||
//
|
||||
// Search bar
|
||||
// Search and toolbar.
|
||||
//
|
||||
|
||||
private static volatile WeakReference<View> searchBarResultsRef = new WeakReference<>(null);
|
||||
|
||||
private static volatile WeakReference<AppCompatToolbarPatchInterface> toolbarResultsRef
|
||||
= new WeakReference<>(null);
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
@@ -37,6 +49,22 @@ public final class NavigationBar {
|
||||
searchBarResultsRef = new WeakReference<>(searchbarResults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void setToolbar(FrameLayout layout) {
|
||||
AppCompatToolbarPatchInterface toolbar = Utils.getChildView(layout, false, (view) ->
|
||||
view instanceof AppCompatToolbarPatchInterface
|
||||
);
|
||||
|
||||
if (toolbar == null) {
|
||||
Logger.printException(() -> "Could not find navigation toolbar");
|
||||
return;
|
||||
}
|
||||
|
||||
toolbarResultsRef = new WeakReference<>(toolbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If the search bar is on screen. This includes if the player
|
||||
* is on screen and the search results are behind the player (and not visible).
|
||||
@@ -47,8 +75,13 @@ public final class NavigationBar {
|
||||
return searchbarResults != null && searchbarResults.getParent() != null;
|
||||
}
|
||||
|
||||
public static boolean isBackButtonVisible() {
|
||||
AppCompatToolbarPatchInterface toolbar = toolbarResultsRef.get();
|
||||
return toolbar != null && toolbar.patch_getNavigationIcon() != null;
|
||||
}
|
||||
|
||||
//
|
||||
// Navigation bar buttons
|
||||
// Navigation bar buttons.
|
||||
//
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ import app.revanced.extension.youtube.Event
|
||||
import app.revanced.extension.youtube.patches.VideoInformation
|
||||
|
||||
/**
|
||||
* Main player type.
|
||||
* Regular player type.
|
||||
*/
|
||||
enum class PlayerType {
|
||||
/**
|
||||
@@ -90,8 +90,6 @@ enum class PlayerType {
|
||||
* Does not include the first moment after a short is opened when a regular video is minimized on screen,
|
||||
* or while watching a short with a regular video present on a spoofed 16.x version of YouTube.
|
||||
* To include those situations instead use [isNoneHiddenOrMinimized].
|
||||
*
|
||||
* @see VideoInformation
|
||||
*/
|
||||
fun isNoneOrHidden(): Boolean {
|
||||
return this == NONE || this == HIDDEN
|
||||
@@ -107,8 +105,11 @@ enum class PlayerType {
|
||||
* when spoofing to an old version this will return false even
|
||||
* though a Short is being opened or is on screen (see [isNoneHiddenOrMinimized]).
|
||||
*
|
||||
* Instead of this method, consider using {@link ShortsPlayerState}
|
||||
* which may work better for some situations.
|
||||
*
|
||||
* @return If nothing, a Short, or a regular video is sliding off screen to a dismissed or hidden state.
|
||||
* @see VideoInformation
|
||||
* @see ShortsPlayerState
|
||||
*/
|
||||
fun isNoneHiddenOrSlidingMinimized(): Boolean {
|
||||
return isNoneOrHidden() || this == WATCH_WHILE_SLIDING_MINIMIZED_DISMISSED
|
||||
@@ -125,9 +126,12 @@ enum class PlayerType {
|
||||
* Typically used to detect if a Short is playing when the player cannot be in a minimized state,
|
||||
* such as the user interacting with a button or element of the player.
|
||||
*
|
||||
* Instead of this method, consider using {@link ShortsPlayerState}
|
||||
* which may work better for some situations.
|
||||
*
|
||||
* @return If nothing, a Short, a regular video is sliding off screen to a dismissed or hidden state,
|
||||
* a regular video is minimized (and a new video is not being opened).
|
||||
* @see VideoInformation
|
||||
* @see ShortsPlayerState
|
||||
*/
|
||||
fun isNoneHiddenOrMinimized(): Boolean {
|
||||
return isNoneHiddenOrSlidingMinimized() || this == WATCH_WHILE_MINIMIZED
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package app.revanced.extension.youtube.shared
|
||||
|
||||
import app.revanced.extension.shared.Logger
|
||||
import app.revanced.extension.youtube.Event
|
||||
|
||||
/**
|
||||
* Shorts player state.
|
||||
*/
|
||||
class ShortsPlayerState {
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
fun setOpen(open: Boolean) {
|
||||
if (isOpen != open) {
|
||||
Logger.printDebug { "ShortsPlayerState open changed to: $isOpen" }
|
||||
isOpen = open
|
||||
onChange(open)
|
||||
}
|
||||
}
|
||||
|
||||
@Volatile
|
||||
private var isOpen = false
|
||||
|
||||
/**
|
||||
* Shorts player state change listener.
|
||||
*/
|
||||
@JvmStatic
|
||||
val onChange = Event<Boolean>()
|
||||
|
||||
/**
|
||||
* If the Shorts player is currently open.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun isOpen(): Boolean {
|
||||
return isOpen
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,7 +136,7 @@ public class SponsorBlockSettings {
|
||||
for (SegmentCategory category : categories) {
|
||||
JSONObject categoryObject = new JSONObject();
|
||||
String categoryKey = category.keyValue;
|
||||
categoryObject.put("color", category.colorString());
|
||||
categoryObject.put("color", category.getColorString());
|
||||
barTypesObject.put(categoryKey, categoryObject);
|
||||
|
||||
if (category.behaviour != CategoryBehaviour.IGNORE) {
|
||||
|
||||
@@ -5,7 +5,12 @@ import static app.revanced.extension.shared.StringRef.str;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.text.Html;
|
||||
import android.graphics.Color;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -33,7 +38,7 @@ import app.revanced.extension.youtube.sponsorblock.ui.SponsorBlockViewController
|
||||
* Not thread safe. All fields/methods must be accessed from the main thread.
|
||||
*/
|
||||
public class SponsorBlockUtils {
|
||||
private static final String LOCKED_COLOR = "#FFC83D";
|
||||
private static final int LOCKED_COLOR = Color.parseColor("#FFC83D");
|
||||
private static final String MANUAL_EDIT_TIME_TEXT_HINT = "hh:mm:ss.sss";
|
||||
private static final Pattern manualEditTimePattern
|
||||
= Pattern.compile("((\\d{1,2}):)?(\\d{1,2}):(\\d{2})(\\.(\\d{1,3}))?");
|
||||
@@ -160,32 +165,34 @@ public class SponsorBlockUtils {
|
||||
SegmentVote[] voteOptions = (segment.category == SegmentCategory.HIGHLIGHT)
|
||||
? SegmentVote.voteTypesWithoutCategoryChange // highlight segments cannot change category
|
||||
: SegmentVote.values();
|
||||
CharSequence[] items = new CharSequence[voteOptions.length];
|
||||
final int voteOptionsLength = voteOptions.length;
|
||||
final boolean userIsVip = Settings.SB_USER_IS_VIP.get();
|
||||
CharSequence[] items = new CharSequence[voteOptionsLength];
|
||||
|
||||
for (int i = 0; i < voteOptions.length; i++) {
|
||||
for (int i = 0; i < voteOptionsLength; i++) {
|
||||
SegmentVote voteOption = voteOptions[i];
|
||||
String title = voteOption.title.toString();
|
||||
if (Settings.SB_USER_IS_VIP.get() && segment.isLocked && voteOption.shouldHighlight) {
|
||||
items[i] = Html.fromHtml(String.format("<font color=\"%s\">%s</font>", LOCKED_COLOR, title));
|
||||
} else {
|
||||
items[i] = title;
|
||||
CharSequence title = voteOption.title.toString();
|
||||
if (userIsVip && segment.isLocked && voteOption.highlightIfVipAndVideoIsLocked) {
|
||||
SpannableString coloredTitle = new SpannableString(title);
|
||||
coloredTitle.setSpan(new ForegroundColorSpan(LOCKED_COLOR),
|
||||
0, title.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
title = coloredTitle;
|
||||
}
|
||||
items[i] = title;
|
||||
}
|
||||
|
||||
new AlertDialog.Builder(context)
|
||||
.setItems(items, (dialog1, which1) -> {
|
||||
SegmentVote voteOption = voteOptions[which1];
|
||||
switch (voteOption) {
|
||||
case UPVOTE:
|
||||
case DOWNVOTE:
|
||||
SBRequester.voteForSegmentOnBackgroundThread(segment, voteOption);
|
||||
break;
|
||||
case CATEGORY_CHANGE:
|
||||
onNewCategorySelect(segment, context);
|
||||
break;
|
||||
}
|
||||
})
|
||||
.show();
|
||||
new AlertDialog.Builder(context).setItems(items, (dialog1, which1) -> {
|
||||
SegmentVote voteOption = voteOptions[which1];
|
||||
switch (voteOption) {
|
||||
case UPVOTE:
|
||||
case DOWNVOTE:
|
||||
SBRequester.voteForSegmentOnBackgroundThread(segment, voteOption);
|
||||
break;
|
||||
case CATEGORY_CHANGE:
|
||||
onNewCategorySelect(segment, context);
|
||||
break;
|
||||
}
|
||||
}).show();
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "segmentVoteClickListener failure", ex);
|
||||
}
|
||||
@@ -282,7 +289,6 @@ public class SponsorBlockUtils {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final int numberOfSegments = segments.length;
|
||||
CharSequence[] titles = new CharSequence[numberOfSegments];
|
||||
for (int i = 0; i < numberOfSegments; i++) {
|
||||
@@ -290,22 +296,33 @@ public class SponsorBlockUtils {
|
||||
if (segment.category == SegmentCategory.UNSUBMITTED) {
|
||||
continue;
|
||||
}
|
||||
StringBuilder htmlBuilder = new StringBuilder();
|
||||
htmlBuilder.append(String.format("<b><font color=\"#%06X\">âŦ¤</font> %s<br>",
|
||||
segment.category.color, segment.category.title));
|
||||
htmlBuilder.append(formatSegmentTime(segment.start));
|
||||
if (segment.category != SegmentCategory.HIGHLIGHT) {
|
||||
htmlBuilder.append(" to ").append(formatSegmentTime(segment.end));
|
||||
|
||||
SpannableStringBuilder spannableBuilder = new SpannableStringBuilder();
|
||||
|
||||
spannableBuilder.append(segment.category.getTitleWithColorDot());
|
||||
spannableBuilder.append('\n');
|
||||
|
||||
String startTime = formatSegmentTime(segment.start);
|
||||
if (segment.category == SegmentCategory.HIGHLIGHT) {
|
||||
spannableBuilder.append(startTime);
|
||||
} else {
|
||||
String toFromString = str("revanced_sb_vote_segment_time_to_from",
|
||||
startTime, formatSegmentTime(segment.end));
|
||||
spannableBuilder.append(toFromString);
|
||||
}
|
||||
htmlBuilder.append("</b>");
|
||||
if (i + 1 != numberOfSegments) // prevents trailing new line after last segment
|
||||
htmlBuilder.append("<br>");
|
||||
titles[i] = Html.fromHtml(htmlBuilder.toString());
|
||||
|
||||
if (i + 1 != numberOfSegments) {
|
||||
// prevents trailing new line after last segment
|
||||
spannableBuilder.append('\n');
|
||||
}
|
||||
|
||||
spannableBuilder.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
|
||||
0, spannableBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
titles[i] = spannableBuilder;
|
||||
}
|
||||
|
||||
new AlertDialog.Builder(context)
|
||||
.setItems(titles, segmentVoteClickListener)
|
||||
.show();
|
||||
new AlertDialog.Builder(context).setItems(titles, segmentVoteClickListener).show();
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "onVotingClicked failure", ex);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package app.revanced.extension.youtube.sponsorblock.objects;
|
||||
|
||||
import static app.revanced.extension.youtube.settings.Settings.*;
|
||||
import static app.revanced.extension.shared.StringRef.sf;
|
||||
import static app.revanced.extension.youtube.settings.Settings.*;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.text.Html;
|
||||
import android.text.Spanned;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -15,43 +16,45 @@ import androidx.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.settings.StringSetting;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.StringRef;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.settings.FloatSetting;
|
||||
import app.revanced.extension.shared.settings.StringSetting;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
|
||||
public enum SegmentCategory {
|
||||
SPONSOR("sponsor", sf("revanced_sb_segments_sponsor"), sf("revanced_sb_segments_sponsor_sum"), sf("revanced_sb_skip_button_sponsor"), sf("revanced_sb_skipped_sponsor"),
|
||||
SB_CATEGORY_SPONSOR, SB_CATEGORY_SPONSOR_COLOR),
|
||||
SB_CATEGORY_SPONSOR, SB_CATEGORY_SPONSOR_COLOR, SB_CATEGORY_SPONSOR_OPACITY),
|
||||
SELF_PROMO("selfpromo", sf("revanced_sb_segments_selfpromo"), sf("revanced_sb_segments_selfpromo_sum"), sf("revanced_sb_skip_button_selfpromo"), sf("revanced_sb_skipped_selfpromo"),
|
||||
SB_CATEGORY_SELF_PROMO, SB_CATEGORY_SELF_PROMO_COLOR),
|
||||
SB_CATEGORY_SELF_PROMO, SB_CATEGORY_SELF_PROMO_COLOR, SB_CATEGORY_SELF_PROMO_OPACITY),
|
||||
INTERACTION("interaction", sf("revanced_sb_segments_interaction"), sf("revanced_sb_segments_interaction_sum"), sf("revanced_sb_skip_button_interaction"), sf("revanced_sb_skipped_interaction"),
|
||||
SB_CATEGORY_INTERACTION, SB_CATEGORY_INTERACTION_COLOR),
|
||||
SB_CATEGORY_INTERACTION, SB_CATEGORY_INTERACTION_COLOR, SB_CATEGORY_INTERACTION_OPACITY),
|
||||
/**
|
||||
* Unique category that is treated differently than the rest.
|
||||
*/
|
||||
HIGHLIGHT("poi_highlight", sf("revanced_sb_segments_highlight"), sf("revanced_sb_segments_highlight_sum"), sf("revanced_sb_skip_button_highlight"), sf("revanced_sb_skipped_highlight"),
|
||||
SB_CATEGORY_HIGHLIGHT, SB_CATEGORY_HIGHLIGHT_COLOR),
|
||||
SB_CATEGORY_HIGHLIGHT, SB_CATEGORY_HIGHLIGHT_COLOR, SB_CATEGORY_HIGHLIGHT_OPACITY),
|
||||
INTRO("intro", sf("revanced_sb_segments_intro"), sf("revanced_sb_segments_intro_sum"),
|
||||
sf("revanced_sb_skip_button_intro_beginning"), sf("revanced_sb_skip_button_intro_middle"), sf("revanced_sb_skip_button_intro_end"),
|
||||
sf("revanced_sb_skipped_intro_beginning"), sf("revanced_sb_skipped_intro_middle"), sf("revanced_sb_skipped_intro_end"),
|
||||
SB_CATEGORY_INTRO, SB_CATEGORY_INTRO_COLOR),
|
||||
SB_CATEGORY_INTRO, SB_CATEGORY_INTRO_COLOR, SB_CATEGORY_INTRO_OPACITY),
|
||||
OUTRO("outro", sf("revanced_sb_segments_outro"), sf("revanced_sb_segments_outro_sum"), sf("revanced_sb_skip_button_outro"), sf("revanced_sb_skipped_outro"),
|
||||
SB_CATEGORY_OUTRO, SB_CATEGORY_OUTRO_COLOR),
|
||||
SB_CATEGORY_OUTRO, SB_CATEGORY_OUTRO_COLOR, SB_CATEGORY_OUTRO_OPACITY),
|
||||
PREVIEW("preview", sf("revanced_sb_segments_preview"), sf("revanced_sb_segments_preview_sum"),
|
||||
sf("revanced_sb_skip_button_preview_beginning"), sf("revanced_sb_skip_button_preview_middle"), sf("revanced_sb_skip_button_preview_end"),
|
||||
sf("revanced_sb_skipped_preview_beginning"), sf("revanced_sb_skipped_preview_middle"), sf("revanced_sb_skipped_preview_end"),
|
||||
SB_CATEGORY_PREVIEW, SB_CATEGORY_PREVIEW_COLOR),
|
||||
SB_CATEGORY_PREVIEW, SB_CATEGORY_PREVIEW_COLOR, SB_CATEGORY_PREVIEW_OPACITY),
|
||||
FILLER("filler", sf("revanced_sb_segments_filler"), sf("revanced_sb_segments_filler_sum"), sf("revanced_sb_skip_button_filler"), sf("revanced_sb_skipped_filler"),
|
||||
SB_CATEGORY_FILLER, SB_CATEGORY_FILLER_COLOR),
|
||||
SB_CATEGORY_FILLER, SB_CATEGORY_FILLER_COLOR, SB_CATEGORY_FILLER_OPACITY),
|
||||
MUSIC_OFFTOPIC("music_offtopic", sf("revanced_sb_segments_nomusic"), sf("revanced_sb_segments_nomusic_sum"), sf("revanced_sb_skip_button_nomusic"), sf("revanced_sb_skipped_nomusic"),
|
||||
SB_CATEGORY_MUSIC_OFFTOPIC, SB_CATEGORY_MUSIC_OFFTOPIC_COLOR),
|
||||
SB_CATEGORY_MUSIC_OFFTOPIC, SB_CATEGORY_MUSIC_OFFTOPIC_COLOR, SB_CATEGORY_MUSIC_OFFTOPIC_OPACITY),
|
||||
UNSUBMITTED("unsubmitted", StringRef.empty, StringRef.empty, sf("revanced_sb_skip_button_unsubmitted"), sf("revanced_sb_skipped_unsubmitted"),
|
||||
SB_CATEGORY_UNSUBMITTED, SB_CATEGORY_UNSUBMITTED_COLOR),;
|
||||
SB_CATEGORY_UNSUBMITTED, SB_CATEGORY_UNSUBMITTED_COLOR, SB_CATEGORY_UNSUBMITTED_OPACITY);
|
||||
|
||||
private static final StringRef skipSponsorTextCompact = sf("revanced_sb_skip_button_compact");
|
||||
private static final StringRef skipSponsorTextCompactHighlight = sf("revanced_sb_skip_button_compact_highlight");
|
||||
@@ -90,12 +93,10 @@ public enum SegmentCategory {
|
||||
mValuesMap.put(value.keyValue, value);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static SegmentCategory[] categoriesWithoutUnsubmitted() {
|
||||
return categoriesWithoutUnsubmitted;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static SegmentCategory[] categoriesWithoutHighlights() {
|
||||
return categoriesWithoutHighlights;
|
||||
}
|
||||
@@ -106,7 +107,7 @@ public enum SegmentCategory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called if behavior of any category is changed
|
||||
* Must be called if behavior of any category is changed.
|
||||
*/
|
||||
public static void updateEnabledCategories() {
|
||||
Utils.verifyOnMainThread();
|
||||
@@ -133,32 +134,33 @@ public enum SegmentCategory {
|
||||
updateEnabledCategories();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public final String keyValue;
|
||||
@NonNull
|
||||
public final StringSetting behaviorSetting;
|
||||
@NonNull
|
||||
private final StringSetting colorSetting;
|
||||
public static int applyOpacityToColor(int color, float opacity) {
|
||||
if (opacity < 0 || opacity > 1.0f) {
|
||||
throw new IllegalArgumentException("Invalid opacity: " + opacity);
|
||||
}
|
||||
final int opacityInt = (int) (255 * opacity);
|
||||
return (color & 0x00FFFFFF) | (opacityInt << 24);
|
||||
}
|
||||
|
||||
public final String keyValue;
|
||||
public final StringSetting behaviorSetting; // TODO: Replace with EnumSetting.
|
||||
private final StringSetting colorSetting;
|
||||
private final FloatSetting opacitySetting;
|
||||
|
||||
@NonNull
|
||||
public final StringRef title;
|
||||
@NonNull
|
||||
public final StringRef description;
|
||||
|
||||
/**
|
||||
* Skip button text, if the skip occurs in the first quarter of the video
|
||||
*/
|
||||
@NonNull
|
||||
public final StringRef skipButtonTextBeginning;
|
||||
/**
|
||||
* Skip button text, if the skip occurs in the middle half of the video
|
||||
*/
|
||||
@NonNull
|
||||
public final StringRef skipButtonTextMiddle;
|
||||
/**
|
||||
* Skip button text, if the skip occurs in the last quarter of the video
|
||||
*/
|
||||
@NonNull
|
||||
public final StringRef skipButtonTextEnd;
|
||||
/**
|
||||
* Skipped segment toast, if the skip occurred in the first quarter of the video
|
||||
@@ -179,10 +181,7 @@ public enum SegmentCategory {
|
||||
@NonNull
|
||||
public final Paint paint;
|
||||
|
||||
/**
|
||||
* Value must be changed using {@link #setColor(String)}.
|
||||
*/
|
||||
public int color;
|
||||
private int color;
|
||||
|
||||
/**
|
||||
* Value must be changed using {@link #setBehaviour(CategoryBehaviour)}.
|
||||
@@ -194,17 +193,20 @@ public enum SegmentCategory {
|
||||
SegmentCategory(String keyValue, StringRef title, StringRef description,
|
||||
StringRef skipButtonText,
|
||||
StringRef skippedToastText,
|
||||
StringSetting behavior, StringSetting color) {
|
||||
StringSetting behavior,
|
||||
StringSetting color, FloatSetting opacity) {
|
||||
this(keyValue, title, description,
|
||||
skipButtonText, skipButtonText, skipButtonText,
|
||||
skippedToastText, skippedToastText, skippedToastText,
|
||||
behavior, color);
|
||||
behavior,
|
||||
color, opacity);
|
||||
}
|
||||
|
||||
SegmentCategory(String keyValue, StringRef title, StringRef description,
|
||||
StringRef skipButtonTextBeginning, StringRef skipButtonTextMiddle, StringRef skipButtonTextEnd,
|
||||
StringRef skippedToastBeginning, StringRef skippedToastMiddle, StringRef skippedToastEnd,
|
||||
StringSetting behavior, StringSetting color) {
|
||||
StringSetting behavior,
|
||||
StringSetting color, FloatSetting opacity) {
|
||||
this.keyValue = Objects.requireNonNull(keyValue);
|
||||
this.title = Objects.requireNonNull(title);
|
||||
this.description = Objects.requireNonNull(description);
|
||||
@@ -216,6 +218,7 @@ public enum SegmentCategory {
|
||||
this.skippedToastEnd = Objects.requireNonNull(skippedToastEnd);
|
||||
this.behaviorSetting = Objects.requireNonNull(behavior);
|
||||
this.colorSetting = Objects.requireNonNull(color);
|
||||
this.opacitySetting = Objects.requireNonNull(opacity);
|
||||
this.paint = new Paint();
|
||||
loadFromSettings();
|
||||
}
|
||||
@@ -232,11 +235,14 @@ public enum SegmentCategory {
|
||||
this.behaviour = savedBehavior;
|
||||
|
||||
String colorString = colorSetting.get();
|
||||
final float opacity = opacitySetting.get();
|
||||
try {
|
||||
setColor(colorString);
|
||||
setOpacity(opacity);
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "Invalid color: " + colorString, ex);
|
||||
Logger.printException(() -> "Invalid color: " + colorString + " opacity: " + opacity, ex);
|
||||
colorSetting.resetToDefault();
|
||||
opacitySetting.resetToDefault();
|
||||
loadFromSettings();
|
||||
}
|
||||
}
|
||||
@@ -245,45 +251,78 @@ public enum SegmentCategory {
|
||||
this.behaviour = Objects.requireNonNull(behaviour);
|
||||
this.behaviorSetting.save(behaviour.reVancedKeyValue);
|
||||
}
|
||||
/**
|
||||
* @return HTML color format string
|
||||
*/
|
||||
@NonNull
|
||||
public String colorString() {
|
||||
return String.format("#%06X", color);
|
||||
}
|
||||
|
||||
public void setColor(@NonNull String colorString) throws IllegalArgumentException {
|
||||
final int color = Color.parseColor(colorString) & 0xFFFFFF;
|
||||
this.color = color;
|
||||
private void updateColor() {
|
||||
color = applyOpacityToColor(color, opacitySetting.get());
|
||||
paint.setColor(color);
|
||||
paint.setAlpha(255);
|
||||
colorSetting.save(colorString); // Save after parsing.
|
||||
}
|
||||
|
||||
public void resetColor() {
|
||||
/**
|
||||
* @param opacity Segment color opacity between [0, 1].
|
||||
*/
|
||||
public void setOpacity(float opacity) throws IllegalArgumentException {
|
||||
if (opacity < 0 || opacity > 1) {
|
||||
throw new IllegalArgumentException("Invalid opacity: " + opacity);
|
||||
}
|
||||
|
||||
opacitySetting.save(opacity);
|
||||
updateColor();
|
||||
}
|
||||
|
||||
public float getOpacity() {
|
||||
return opacitySetting.get();
|
||||
}
|
||||
|
||||
public void resetColorAndOpacity() {
|
||||
setColor(colorSetting.defaultValue);
|
||||
setOpacity(opacitySetting.defaultValue);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static String getCategoryColorDotHTML(int color) {
|
||||
color &= 0xFFFFFF;
|
||||
return String.format("<font color=\"#%06X\">âŦ¤</font>", color);
|
||||
/**
|
||||
* @param colorString Segment color with #RRGGBB format.
|
||||
*/
|
||||
public void setColor(String colorString) throws IllegalArgumentException {
|
||||
color = Color.parseColor(colorString);
|
||||
colorSetting.save(colorString);
|
||||
|
||||
updateColor();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Spanned getCategoryColorDot(int color) {
|
||||
return Html.fromHtml(getCategoryColorDotHTML(color));
|
||||
/**
|
||||
* @return Integer color of #RRGGBB format.
|
||||
*/
|
||||
public int getColorNoOpacity() {
|
||||
return color & 0x00FFFFFF;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Spanned getCategoryColorDot() {
|
||||
/**
|
||||
* @return Hex color string of #RRGGBB format with no opacity level.
|
||||
*/
|
||||
public String getColorString() {
|
||||
return String.format(Locale.US, "#%06X", getColorNoOpacity());
|
||||
}
|
||||
|
||||
private static SpannableString getCategoryColorDotSpan(String text, int color) {
|
||||
SpannableString dotSpan = new SpannableString('âŦ¤' + text);
|
||||
dotSpan.setSpan(new ForegroundColorSpan(color), 0, 1,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
return dotSpan;
|
||||
}
|
||||
|
||||
public static SpannableString getCategoryColorDot(int color) {
|
||||
return getCategoryColorDotSpan("", color);
|
||||
}
|
||||
|
||||
public SpannableString getCategoryColorDot() {
|
||||
return getCategoryColorDot(color);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Spanned getTitleWithColorDot() {
|
||||
return Html.fromHtml(getCategoryColorDotHTML(color) + " " + title);
|
||||
public SpannableString getTitleWithColorDot(int categoryColor) {
|
||||
return getCategoryColorDotSpan(" " + title, categoryColor);
|
||||
}
|
||||
|
||||
public SpannableString getTitleWithColorDot() {
|
||||
return getTitleWithColorDot(color);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -291,7 +330,6 @@ public enum SegmentCategory {
|
||||
* @param videoLength length of the video
|
||||
* @return the skip button text
|
||||
*/
|
||||
@NonNull
|
||||
StringRef getSkipButtonText(long segmentStartTime, long videoLength) {
|
||||
if (Settings.SB_COMPACT_SKIP_BUTTON.get()) {
|
||||
return (this == SegmentCategory.HIGHLIGHT)
|
||||
@@ -300,7 +338,7 @@ public enum SegmentCategory {
|
||||
}
|
||||
|
||||
if (videoLength == 0) {
|
||||
return skipButtonTextBeginning; // video is still loading. Assume it's the beginning
|
||||
return skipButtonTextBeginning; // Video is still loading. Assume it's the beginning.
|
||||
}
|
||||
final float position = segmentStartTime / (float) videoLength;
|
||||
if (position < 0.25f) {
|
||||
@@ -316,10 +354,9 @@ public enum SegmentCategory {
|
||||
* @param videoLength length of the video
|
||||
* @return 'skipped segment' toast message
|
||||
*/
|
||||
@NonNull
|
||||
StringRef getSkippedToastText(long segmentStartTime, long videoLength) {
|
||||
if (videoLength == 0) {
|
||||
return skippedToastBeginning; // video is still loading. Assume it's the beginning
|
||||
return skippedToastBeginning; // Video is still loading. Assume it's the beginning.
|
||||
}
|
||||
final float position = segmentStartTime / (float) videoLength;
|
||||
if (position < 0.25f) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package app.revanced.extension.youtube.sponsorblock.objects;
|
||||
|
||||
import static app.revanced.extension.shared.StringRef.str;
|
||||
import static app.revanced.extension.youtube.sponsorblock.objects.SegmentCategory.applyOpacityToColor;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
@@ -11,11 +12,10 @@ import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.TableRow;
|
||||
import android.widget.GridLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
@@ -24,27 +24,38 @@ import app.revanced.extension.shared.Utils;
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SegmentCategoryListPreference extends ListPreference {
|
||||
private final SegmentCategory category;
|
||||
private EditText mEditText;
|
||||
private int mClickedDialogEntryIndex;
|
||||
private TextView colorDotView;
|
||||
private EditText colorEditText;
|
||||
private EditText opacityEditText;
|
||||
/**
|
||||
* #RRGGBB
|
||||
*/
|
||||
private int categoryColor;
|
||||
/**
|
||||
* [0, 1]
|
||||
*/
|
||||
private float categoryOpacity;
|
||||
private int selectedDialogEntryIndex;
|
||||
|
||||
public SegmentCategoryListPreference(Context context, SegmentCategory category) {
|
||||
super(context);
|
||||
final boolean isHighlightCategory = category == SegmentCategory.HIGHLIGHT;
|
||||
this.category = Objects.requireNonNull(category);
|
||||
|
||||
// Edit: Using preferences to sync together multiple pieces
|
||||
// of code together is messy and should be rethought.
|
||||
// of code is messy and should be rethought.
|
||||
setKey(category.behaviorSetting.key);
|
||||
setDefaultValue(category.behaviorSetting.defaultValue);
|
||||
|
||||
final boolean isHighlightCategory = category == SegmentCategory.HIGHLIGHT;
|
||||
setEntries(isHighlightCategory
|
||||
? CategoryBehaviour.getBehaviorDescriptionsWithoutSkipOnce()
|
||||
: CategoryBehaviour.getBehaviorDescriptions());
|
||||
setEntryValues(isHighlightCategory
|
||||
? CategoryBehaviour.getBehaviorKeyValuesWithoutSkipOnce()
|
||||
: CategoryBehaviour.getBehaviorKeyValues());
|
||||
|
||||
setSummary(category.description.toString());
|
||||
updateTitle();
|
||||
|
||||
updateTitleFromCategory();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,26 +63,40 @@ public class SegmentCategoryListPreference extends ListPreference {
|
||||
try {
|
||||
Utils.setEditTextDialogTheme(builder);
|
||||
|
||||
categoryColor = category.getColorNoOpacity();
|
||||
categoryOpacity = category.getOpacity();
|
||||
|
||||
Context context = builder.getContext();
|
||||
TableLayout table = new TableLayout(context);
|
||||
table.setOrientation(LinearLayout.HORIZONTAL);
|
||||
table.setPadding(70, 0, 150, 0);
|
||||
|
||||
TableRow row = new TableRow(context);
|
||||
GridLayout gridLayout = new GridLayout(context);
|
||||
gridLayout.setPadding(70, 0, 150, 0); // Padding for the entire layout.
|
||||
gridLayout.setColumnCount(3);
|
||||
gridLayout.setRowCount(2);
|
||||
|
||||
GridLayout.LayoutParams gridParams = new GridLayout.LayoutParams();
|
||||
gridParams.rowSpec = GridLayout.spec(0); // First row.
|
||||
gridParams.columnSpec = GridLayout.spec(0); // First column.
|
||||
TextView colorTextLabel = new TextView(context);
|
||||
colorTextLabel.setText(str("revanced_sb_color_dot_label"));
|
||||
row.addView(colorTextLabel);
|
||||
colorTextLabel.setLayoutParams(gridParams);
|
||||
gridLayout.addView(colorTextLabel);
|
||||
|
||||
TextView colorDotView = new TextView(context);
|
||||
colorDotView.setText(category.getCategoryColorDot());
|
||||
colorDotView.setPadding(30, 0, 30, 0);
|
||||
row.addView(colorDotView);
|
||||
gridParams = new GridLayout.LayoutParams();
|
||||
gridParams.rowSpec = GridLayout.spec(0); // First row.
|
||||
gridParams.columnSpec = GridLayout.spec(1); // Second column.
|
||||
gridParams.setMargins(0, 0, 10, 0);
|
||||
colorDotView = new TextView(context);
|
||||
colorDotView.setLayoutParams(gridParams);
|
||||
gridLayout.addView(colorDotView);
|
||||
updateCategoryColorDot();
|
||||
|
||||
mEditText = new EditText(context);
|
||||
mEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
|
||||
mEditText.setText(category.colorString());
|
||||
mEditText.addTextChangedListener(new TextWatcher() {
|
||||
gridParams = new GridLayout.LayoutParams();
|
||||
gridParams.rowSpec = GridLayout.spec(0); // First row.
|
||||
gridParams.columnSpec = GridLayout.spec(2); // Third column.
|
||||
colorEditText = new EditText(context);
|
||||
colorEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
|
||||
colorEditText.setTextLocale(Locale.US);
|
||||
colorEditText.setText(category.getColorString());
|
||||
colorEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
@@ -81,29 +106,94 @@ public class SegmentCategoryListPreference extends ListPreference {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
public void afterTextChanged(Editable edit) {
|
||||
try {
|
||||
String colorString = s.toString();
|
||||
String colorString = edit.toString();
|
||||
final int colorStringLength = colorString.length();
|
||||
|
||||
if (!colorString.startsWith("#")) {
|
||||
s.insert(0, "#"); // recursively calls back into this method
|
||||
edit.insert(0, "#"); // Recursively calls back into this method.
|
||||
return;
|
||||
}
|
||||
if (colorString.length() > 7) {
|
||||
s.delete(7, colorString.length());
|
||||
|
||||
final int maxColorStringLength = 7; // #RRGGBB
|
||||
if (colorStringLength > maxColorStringLength) {
|
||||
edit.delete(maxColorStringLength, colorStringLength);
|
||||
return;
|
||||
}
|
||||
final int color = Color.parseColor(colorString);
|
||||
colorDotView.setText(SegmentCategory.getCategoryColorDot(color));
|
||||
|
||||
categoryColor = Color.parseColor(colorString);
|
||||
updateCategoryColorDot();
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// ignore
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
});
|
||||
mEditText.setLayoutParams(new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 1f));
|
||||
row.addView(mEditText);
|
||||
colorEditText.setLayoutParams(gridParams);
|
||||
gridLayout.addView(colorEditText);
|
||||
|
||||
table.addView(row);
|
||||
builder.setView(table);
|
||||
gridParams = new GridLayout.LayoutParams();
|
||||
gridParams.rowSpec = GridLayout.spec(1); // Second row.
|
||||
gridParams.columnSpec = GridLayout.spec(0, 1); // First and second column.
|
||||
TextView opacityLabel = new TextView(context);
|
||||
opacityLabel.setText(str("revanced_sb_color_opacity_label"));
|
||||
opacityLabel.setLayoutParams(gridParams);
|
||||
gridLayout.addView(opacityLabel);
|
||||
|
||||
gridParams = new GridLayout.LayoutParams();
|
||||
gridParams.rowSpec = GridLayout.spec(1); // Second row.
|
||||
gridParams.columnSpec = GridLayout.spec(2); // Third column.
|
||||
opacityEditText = new EditText(context);
|
||||
opacityEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
|
||||
opacityEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable edit) {
|
||||
try {
|
||||
String editString = edit.toString();
|
||||
final int opacityStringLength = editString.length();
|
||||
|
||||
final int maxOpacityStringLength = 4; // [0.00, 1.00]
|
||||
if (opacityStringLength > maxOpacityStringLength) {
|
||||
edit.delete(maxOpacityStringLength, opacityStringLength);
|
||||
return;
|
||||
}
|
||||
|
||||
final float opacity = opacityStringLength == 0
|
||||
? 0
|
||||
: Float.parseFloat(editString);
|
||||
if (opacity < 0) {
|
||||
categoryOpacity = 0;
|
||||
edit.replace(0, opacityStringLength, "0");
|
||||
return;
|
||||
} else if (opacity > 1.0f) {
|
||||
categoryOpacity = 1;
|
||||
edit.replace(0, opacityStringLength, "1.0");
|
||||
return;
|
||||
} else if (!editString.endsWith(".")) {
|
||||
// Ignore "0." and "1." until the user finishes entering a valid number.
|
||||
categoryOpacity = opacity;
|
||||
}
|
||||
|
||||
updateCategoryColorDot();
|
||||
} catch (NumberFormatException ex) {
|
||||
// Should never happen.
|
||||
Logger.printException(() -> "Could not parse opacity string", ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
opacityEditText.setLayoutParams(gridParams);
|
||||
gridLayout.addView(opacityEditText);
|
||||
updateOpacityText();
|
||||
|
||||
builder.setView(gridLayout);
|
||||
builder.setTitle(category.title.toString());
|
||||
|
||||
builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
||||
@@ -111,8 +201,8 @@ public class SegmentCategoryListPreference extends ListPreference {
|
||||
});
|
||||
builder.setNeutralButton(str("revanced_sb_reset_color"), (dialog, which) -> {
|
||||
try {
|
||||
category.resetColor();
|
||||
updateTitle();
|
||||
category.resetColorAndOpacity();
|
||||
updateTitleFromCategory();
|
||||
Utils.showToastShort(str("revanced_sb_color_reset"));
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "setNeutralButton failure", ex);
|
||||
@@ -120,8 +210,9 @@ public class SegmentCategoryListPreference extends ListPreference {
|
||||
});
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
|
||||
mClickedDialogEntryIndex = findIndexOfValue(getValue());
|
||||
builder.setSingleChoiceItems(getEntries(), mClickedDialogEntryIndex, (dialog, which) -> mClickedDialogEntryIndex = which);
|
||||
selectedDialogEntryIndex = findIndexOfValue(getValue());
|
||||
builder.setSingleChoiceItems(getEntries(), selectedDialogEntryIndex,
|
||||
(dialog, which) -> selectedDialogEntryIndex = which);
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "onPrepareDialogBuilder failure", ex);
|
||||
}
|
||||
@@ -130,30 +221,51 @@ public class SegmentCategoryListPreference extends ListPreference {
|
||||
@Override
|
||||
protected void onDialogClosed(boolean positiveResult) {
|
||||
try {
|
||||
if (positiveResult && mClickedDialogEntryIndex >= 0 && getEntryValues() != null) {
|
||||
String value = getEntryValues()[mClickedDialogEntryIndex].toString();
|
||||
if (positiveResult && selectedDialogEntryIndex >= 0 && getEntryValues() != null) {
|
||||
String value = getEntryValues()[selectedDialogEntryIndex].toString();
|
||||
if (callChangeListener(value)) {
|
||||
setValue(value);
|
||||
category.setBehaviour(Objects.requireNonNull(CategoryBehaviour.byReVancedKeyValue(value)));
|
||||
SegmentCategory.updateEnabledCategories();
|
||||
}
|
||||
String colorString = mEditText.getText().toString();
|
||||
|
||||
try {
|
||||
if (!colorString.equals(category.colorString())) {
|
||||
String colorString = colorEditText.getText().toString();
|
||||
if (!colorString.equals(category.getColorString()) || categoryOpacity != category.getOpacity()) {
|
||||
category.setColor(colorString);
|
||||
category.setOpacity(categoryOpacity);
|
||||
Utils.showToastShort(str("revanced_sb_color_changed"));
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Utils.showToastShort(str("revanced_sb_color_invalid"));
|
||||
}
|
||||
updateTitle();
|
||||
|
||||
updateTitleFromCategory();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.printException(() -> "onDialogClosed failure", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTitle() {
|
||||
setTitle(category.getTitleWithColorDot());
|
||||
private void applyOpacityToCategoryColor() {
|
||||
categoryColor = applyOpacityToColor(categoryColor, categoryOpacity);
|
||||
}
|
||||
|
||||
private void updateTitleFromCategory() {
|
||||
categoryColor = category.getColorNoOpacity();
|
||||
categoryOpacity = category.getOpacity();
|
||||
applyOpacityToCategoryColor();
|
||||
|
||||
setTitle(category.getTitleWithColorDot(categoryColor));
|
||||
}
|
||||
|
||||
private void updateCategoryColorDot() {
|
||||
applyOpacityToCategoryColor();
|
||||
|
||||
colorDotView.setText(SegmentCategory.getCategoryColorDot(categoryColor));
|
||||
}
|
||||
|
||||
private void updateOpacityText() {
|
||||
opacityEditText.setText(String.format(Locale.US, "%.2f", categoryOpacity));
|
||||
}
|
||||
}
|
||||
@@ -23,12 +23,15 @@ public class SponsorSegment implements Comparable<SponsorSegment> {
|
||||
@NonNull
|
||||
public final StringRef title;
|
||||
public final int apiVoteType;
|
||||
public final boolean shouldHighlight;
|
||||
/**
|
||||
* If the option should be highlighted for VIP users.
|
||||
*/
|
||||
public final boolean highlightIfVipAndVideoIsLocked;
|
||||
|
||||
SegmentVote(@NonNull StringRef title, int apiVoteType, boolean shouldHighlight) {
|
||||
SegmentVote(@NonNull StringRef title, int apiVoteType, boolean highlightIfVipAndVideoIsLocked) {
|
||||
this.title = title;
|
||||
this.apiVoteType = apiVoteType;
|
||||
this.shouldHighlight = shouldHighlight;
|
||||
this.highlightIfVipAndVideoIsLocked = highlightIfVipAndVideoIsLocked;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
|
||||
org.gradle.parallel = true
|
||||
android.useAndroidX = true
|
||||
kotlin.code.style = official
|
||||
version = 5.13.0-dev.19
|
||||
version = 5.16.2-dev.1
|
||||
|
||||
@@ -816,6 +816,14 @@ public final class app/revanced/patches/spotify/lite/ondemand/OnDemandPatchKt {
|
||||
public static final fun getOnDemandPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/spotify/misc/UnlockPremiumPatchKt {
|
||||
public static final fun getUnlockPremiumPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/spotify/misc/fix/SpoofSignaturePatchKt {
|
||||
public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/spotify/navbar/PremiumNavbarTabPatchKt {
|
||||
public static final fun getPremiumNavbarTabPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
@@ -1463,6 +1471,10 @@ public final class app/revanced/patches/youtube/video/quality/RememberVideoQuali
|
||||
public static final fun getRememberVideoQualityPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/video/quality/VideoQualityPatchKt {
|
||||
public static final fun getVideoQualityPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/video/speed/PlaybackSpeedPatchKt {
|
||||
public static final fun getPlaybackSpeedPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ import app.revanced.patches.all.misc.transformation.IMethodCall
|
||||
import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
|
||||
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR_PREFIX =
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR_PREFIX =
|
||||
"Lapp/revanced/extension/all/connectivity/wifi/spoof/SpoofWifiPatch"
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;"
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;"
|
||||
|
||||
@Suppress("unused")
|
||||
val spoofWifiPatch = bytecodePatch(
|
||||
|
||||
@@ -8,9 +8,8 @@ import org.w3c.dom.Element
|
||||
@Suppress("unused")
|
||||
val changeVersionCodePatch = resourcePatch(
|
||||
name = "Change version code",
|
||||
description = "Changes the version code of the app. By default the highest version code is set. " +
|
||||
"This allows older versions of an app to be installed " +
|
||||
"if their version code is set to the same or a higher value and can stop app stores to update the app.",
|
||||
description = "Changes the version code of the app. This will turn off app store updates " +
|
||||
"and allows downgrading an existing app install to an older app version.",
|
||||
use = false,
|
||||
) {
|
||||
val versionCode by intOption(
|
||||
@@ -21,7 +20,8 @@ val changeVersionCodePatch = resourcePatch(
|
||||
"Highest" to Int.MAX_VALUE,
|
||||
),
|
||||
title = "Version code",
|
||||
description = "The version code to use",
|
||||
description = "The version code to use. Using the highest value turns off app store " +
|
||||
"updates and allows downgrading an existing app install to an older app version.",
|
||||
required = true,
|
||||
) { versionCode -> versionCode!! >= 1 }
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
val hideSponsoredStoriesPatch = bytecodePatch(
|
||||
name = "Hide 'Sponsored Stories'",
|
||||
) {
|
||||
compatibleWith("com.facebook.katana")
|
||||
compatibleWith("com.facebook.katana"("490.0.0.63.82"))
|
||||
|
||||
execute {
|
||||
val sponsoredDataModelTemplateMethod = getSponsoredDataModelTemplateFingerprint.originalMethod
|
||||
|
||||
@@ -17,7 +17,7 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/music/spoof/SpoofClientPatch;"
|
||||
|
||||
// TODO: Replace this patch with spoofVideoStreamsPatch once possible.
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package app.revanced.patches.reddit.customclients.boostforreddit.api
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "http://rubenmayayo.com") { clientIdOption ->
|
||||
compatibleWith("com.rubenmayayo.reddit")
|
||||
@@ -23,14 +26,15 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "http://rubenmayayo.com")
|
||||
|
||||
// region Patch user agent.
|
||||
|
||||
// Use a random number as the platform in the user agent string.
|
||||
val platformName = (0..100000).random()
|
||||
val platformParameter = 0
|
||||
|
||||
buildUserAgentFingerprint.method.addInstructions(
|
||||
0,
|
||||
"const-string p$platformParameter, \"$platformName\"",
|
||||
)
|
||||
// Use a random user agent.
|
||||
val randomName = (0..100000).random()
|
||||
val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
|
||||
buildUserAgentFingerprint.let {
|
||||
val userAgentTemplateIndex = it.stringMatches!!.first().index
|
||||
val register = it.method.getInstruction<OneRegisterInstruction>(userAgentTemplateIndex).registerA
|
||||
|
||||
it.method.replaceInstruction(userAgentTemplateIndex, "const-string v$register, \"$userAgent\"")
|
||||
}
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
||||
@@ -8,7 +8,11 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation
|
||||
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "infinity://localhost") { clientIdOption ->
|
||||
compatibleWith("ml.docilealligator.infinityforreddit", "ml.docilealligator.infinityforreddit.plus")
|
||||
compatibleWith(
|
||||
"ml.docilealligator.infinityforreddit",
|
||||
"ml.docilealligator.infinityforreddit.plus",
|
||||
"ml.docilealligator.infinityforreddit.patreon"
|
||||
)
|
||||
|
||||
val clientId by clientIdOption
|
||||
|
||||
|
||||
@@ -11,7 +11,11 @@ val unlockSubscriptionPatch = bytecodePatch(
|
||||
) {
|
||||
dependsOn(spoofClientPatch)
|
||||
|
||||
compatibleWith("ml.docilealligator.infinityforreddit", "ml.docilealligator.infinityforreddit.plus")
|
||||
compatibleWith(
|
||||
"ml.docilealligator.infinityforreddit",
|
||||
"ml.docilealligator.infinityforreddit.plus",
|
||||
"ml.docilealligator.infinityforreddit.patreon"
|
||||
)
|
||||
|
||||
execute {
|
||||
setOf(
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.w3c.dom.Element
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
abstract class BasePreference(
|
||||
val key: String? = null,
|
||||
val titleKey: String = "${key}_title",
|
||||
val titleKey: String? = "${key}_title",
|
||||
val summaryKey: String? = "${key}_summary",
|
||||
val icon: String? = null,
|
||||
val layout: String? = null,
|
||||
@@ -35,7 +35,7 @@ abstract class BasePreference(
|
||||
open fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit): Element =
|
||||
ownerDocument.createElement(tag).apply {
|
||||
key?.let { setAttribute("android:key", it) }
|
||||
setAttribute("android:title", "@string/${titleKey}")
|
||||
titleKey?.let { setAttribute("android:title", "@string/${titleKey}") }
|
||||
summaryKey?.let { addSummary(it) }
|
||||
icon?.let {
|
||||
setAttribute("android:icon", it)
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.w3c.dom.Document
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
open class PreferenceCategory(
|
||||
key: String? = null,
|
||||
titleKey: String = "${key}_title",
|
||||
titleKey: String? = "${key}_title",
|
||||
icon: String? = null,
|
||||
layout: String? = null,
|
||||
sorting: Sorting = Sorting.BY_TITLE,
|
||||
|
||||
@@ -35,7 +35,7 @@ fun spoofVideoStreamsPatch(
|
||||
executeBlock: BytecodePatchContext.() -> Unit = {},
|
||||
) = bytecodePatch(
|
||||
name = "Spoof video streams",
|
||||
description = "Spoofs the client video streams to fix playback.",
|
||||
description = "Adds options to spoof the client video streams to fix playback.",
|
||||
) {
|
||||
block()
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package app.revanced.patches.spotify.misc
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
|
||||
internal val accountAttributeFingerprint = fingerprint {
|
||||
custom { _, c -> c.endsWith("internal/AccountAttribute;") }
|
||||
}
|
||||
|
||||
internal val productStateProtoFingerprint = fingerprint {
|
||||
returns("Ljava/util/Map;")
|
||||
custom { _, classDef ->
|
||||
classDef.endsWith("ProductStateProto;")
|
||||
}
|
||||
}
|
||||
|
||||
internal val buildQueryParametersFingerprint = fingerprint {
|
||||
strings("trackRows", "device_type:tablet")
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package app.revanced.patches.spotify.misc.fix
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
|
||||
internal val getAppSignatureFingerprint = fingerprint { strings("Failed to get the application signatures") }
|
||||
@@ -0,0 +1,33 @@
|
||||
package app.revanced.patches.spotify.misc.fix
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@Suppress("unused")
|
||||
val spoofSignaturePatch = bytecodePatch(
|
||||
name = "Spoof signature",
|
||||
description = "Spoofs the signature of the app to fix various functions of the app.",
|
||||
) {
|
||||
compatibleWith("com.spotify.music")
|
||||
|
||||
execute {
|
||||
getAppSignatureFingerprint.method.apply {
|
||||
val failedToGetSignaturesStringMatch = getAppSignatureFingerprint.stringMatches!!.first()
|
||||
|
||||
val concatSignaturesIndex = indexOfFirstInstructionReversedOrThrow(
|
||||
failedToGetSignaturesStringMatch.index,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
)
|
||||
|
||||
val register = getInstruction<OneRegisterInstruction>(concatSignaturesIndex).registerA
|
||||
|
||||
val expectedSignature = "d6a6dced4a85f24204bf9505ccc1fce114cadb32"
|
||||
|
||||
replaceInstruction(concatSignaturesIndex, "const-string v$register, \"$expectedSignature\"")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package app.revanced.patches.spotify.navbar
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.util.literal
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val addNavBarItemFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("V")
|
||||
literal { showBottomNavigationItemsTextId }
|
||||
}
|
||||
@@ -1,50 +1,12 @@
|
||||
package app.revanced.patches.spotify.navbar
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patches.shared.misc.mapping.get
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||
|
||||
internal var showBottomNavigationItemsTextId = -1L
|
||||
private set
|
||||
internal var premiumTabId = -1L
|
||||
private set
|
||||
|
||||
private val premiumNavbarTabResourcePatch = resourcePatch {
|
||||
dependsOn(resourceMappingPatch)
|
||||
|
||||
execute {
|
||||
premiumTabId = resourceMappings["id", "premium_tab"]
|
||||
|
||||
showBottomNavigationItemsTextId = resourceMappings[
|
||||
"bool",
|
||||
"show_bottom_navigation_items_text",
|
||||
]
|
||||
}
|
||||
}
|
||||
import app.revanced.patches.spotify.misc.unlockPremiumPatch
|
||||
|
||||
@Deprecated("Superseded by unlockPremiumPatch", ReplaceWith("unlockPremiumPatch"))
|
||||
@Suppress("unused")
|
||||
val premiumNavbarTabPatch = bytecodePatch(
|
||||
name = "Premium navbar tab",
|
||||
description = "Hides the premium tab from the navigation bar.",
|
||||
) {
|
||||
dependsOn(premiumNavbarTabResourcePatch)
|
||||
|
||||
compatibleWith("com.spotify.music")
|
||||
|
||||
// If the navigation bar item is the premium tab, do not add it.
|
||||
execute {
|
||||
addNavBarItemFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const v1, $premiumTabId
|
||||
if-ne p5, v1, :continue
|
||||
return-void
|
||||
:continue
|
||||
nop
|
||||
""",
|
||||
)
|
||||
}
|
||||
dependsOn(unlockPremiumPatch)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/tiktok/settings/AdPersonalizationActivityHook;"
|
||||
|
||||
val settingsPatch = bytecodePatch(
|
||||
|
||||
@@ -12,7 +12,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/tudortmund/lockscreen/ShowOnLockscreenPatch;"
|
||||
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -11,7 +11,7 @@ import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/HideGetPremiumPatch;"
|
||||
|
||||
val hideGetPremiumPatch = bytecodePatch(
|
||||
|
||||
@@ -50,7 +50,7 @@ private val downloadsResourcePatch = resourcePatch {
|
||||
}
|
||||
}
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DownloadsPatch;"
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DownloadsPatch;"
|
||||
|
||||
internal const val BUTTON_DESCRIPTOR = "Lapp/revanced/extension/youtube/videoplayer/ExternalDownloadButton;"
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
val enableSeekbarTappingPatch = bytecodePatch(
|
||||
name = "Seekbar tapping",
|
||||
description = "Adds an option to enable tap-to-seek on the seekbar of the video player.",
|
||||
name = "Enable tap to seek",
|
||||
description = "Adds an option to enable tap to seek on the seekbar of the video player.",
|
||||
) {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
|
||||
@@ -23,7 +23,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/NavigationButtonsPatch;"
|
||||
|
||||
val navigationButtonsPatch = bytecodePatch(
|
||||
|
||||
@@ -43,7 +43,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
|
||||
val hidePlayerOverlayButtonsPatch = bytecodePatch(
|
||||
name = "Hide player overlay buttons",
|
||||
description = "Adds options to hide the player cast, autoplay, caption button and next/ previous buttons.",
|
||||
description = "Adds options to hide the player Cast, Autoplay, Captions, and Previous & Next buttons.",
|
||||
) {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
|
||||
@@ -6,7 +6,9 @@ import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||
import app.revanced.patches.youtube.layout.buttons.navigation.navigationButtonsPatch
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.navigation.hookNavigationButtonCreated
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.util.getReference
|
||||
@@ -15,7 +17,7 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/ChangeFormFactorPatch;"
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/ChangeFormFactorPatch;"
|
||||
|
||||
@Suppress("unused")
|
||||
val changeFormFactorPatch = bytecodePatch(
|
||||
@@ -26,6 +28,7 @@ val changeFormFactorPatch = bytecodePatch(
|
||||
sharedExtensionPatch,
|
||||
settingsPatch,
|
||||
addResourcesPatch,
|
||||
navigationButtonsPatch
|
||||
)
|
||||
|
||||
compatibleWith(
|
||||
@@ -50,6 +53,8 @@ val changeFormFactorPatch = bytecodePatch(
|
||||
)
|
||||
)
|
||||
|
||||
hookNavigationButtonCreated(EXTENSION_CLASS_DESCRIPTOR)
|
||||
|
||||
createPlayerRequestBodyWithModelFingerprint.method.apply {
|
||||
val formFactorEnumClass = formFactorEnumConstructorFingerprint.originalClassDef.type
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
|
||||
@Suppress("unused")
|
||||
val hideEndscreenCardsPatch = bytecodePatch(
|
||||
name = "Hide endscreen cards",
|
||||
name = "Hide end screen cards",
|
||||
description = "Adds an option to hide suggested video cards at the end of videos.",
|
||||
) {
|
||||
dependsOn(
|
||||
|
||||
@@ -22,7 +22,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
@Suppress("unused")
|
||||
val hideEndScreenSuggestedVideoPatch = bytecodePatch(
|
||||
name = "Hide end screen suggested video",
|
||||
description = "Adds an option to hide the recommended video at the end of each video.",
|
||||
description = "Adds an option to hide the suggested video at the end of videos.",
|
||||
) {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
|
||||
@@ -14,7 +14,7 @@ import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/DisableFullscreenAmbientModePatch;"
|
||||
|
||||
val disableFullscreenAmbientModePatch = bytecodePatch(
|
||||
|
||||
@@ -142,6 +142,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
|
||||
PreferenceScreenPreference(
|
||||
key = "revanced_hide_description_components_screen",
|
||||
preferences = setOf(
|
||||
SwitchPreference("revanced_hide_ai_generated_video_summary_section"),
|
||||
SwitchPreference("revanced_hide_attributes_section"),
|
||||
SwitchPreference("revanced_hide_chapters_section"),
|
||||
SwitchPreference("revanced_hide_info_cards_section"),
|
||||
@@ -154,13 +155,14 @@ val hideLayoutComponentsPatch = bytecodePatch(
|
||||
PreferenceScreenPreference(
|
||||
"revanced_comments_screen",
|
||||
preferences = setOf(
|
||||
SwitchPreference("revanced_hide_comments_chat_summary"),
|
||||
SwitchPreference("revanced_hide_comments_ai_chat_summary"),
|
||||
SwitchPreference("revanced_hide_comments_ai_summary"),
|
||||
SwitchPreference("revanced_hide_comments_by_members_header"),
|
||||
SwitchPreference("revanced_hide_comments_section"),
|
||||
SwitchPreference("revanced_hide_comments_create_a_short_button"),
|
||||
SwitchPreference("revanced_hide_comments_timestamp_and_emoji_buttons"),
|
||||
SwitchPreference("revanced_hide_comments_preview_comment"),
|
||||
SwitchPreference("revanced_hide_comments_thanks_button"),
|
||||
SwitchPreference("revanced_hide_comments_timestamp_and_emoji_buttons"),
|
||||
),
|
||||
sorting = PreferenceScreenPreference.Sorting.UNSORTED,
|
||||
),
|
||||
|
||||
@@ -159,7 +159,7 @@ private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/pat
|
||||
@Suppress("unused")
|
||||
val hideShortsComponentsPatch = bytecodePatch(
|
||||
name = "Hide Shorts components",
|
||||
description = "Adds options to hide components related to YouTube Shorts.",
|
||||
description = "Adds options to hide components related to Shorts.",
|
||||
) {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
|
||||
@@ -134,7 +134,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/
|
||||
@Suppress("unused")
|
||||
val miniplayerPatch = bytecodePatch(
|
||||
name = "Miniplayer",
|
||||
description = "Adds options to change the in app minimized player."
|
||||
description = "Adds options to change the in-app minimized player."
|
||||
) {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
|
||||
@@ -98,20 +98,6 @@ internal val rollingNumberTextViewFingerprint = fingerprint {
|
||||
}
|
||||
}
|
||||
|
||||
internal val shortsTextViewFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("V")
|
||||
parameters("L", "L")
|
||||
opcodes(
|
||||
Opcode.INVOKE_SUPER, // first instruction of method
|
||||
Opcode.IF_NEZ,
|
||||
null,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
)
|
||||
}
|
||||
|
||||
internal val textComponentConstructorFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.CONSTRUCTOR, AccessFlags.PRIVATE)
|
||||
strings("TextComponent")
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.instructions
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
@@ -169,51 +167,7 @@ val returnYouTubeDislikePatch = bytecodePatch(
|
||||
|
||||
// endregion
|
||||
|
||||
// region Hook for non-litho Short videos.
|
||||
shortsTextViewFingerprint.method.apply {
|
||||
val insertIndex = shortsTextViewFingerprint.patternMatch!!.endIndex + 1
|
||||
|
||||
// If the field is true, the TextView is for a dislike button.
|
||||
val isDisLikesBooleanInstruction = instructions.first { instruction ->
|
||||
instruction.opcode == Opcode.IGET_BOOLEAN
|
||||
} as ReferenceInstruction
|
||||
|
||||
val isDisLikesBooleanReference = isDisLikesBooleanInstruction.reference
|
||||
|
||||
// Like/Dislike button TextView field.
|
||||
val textViewFieldInstruction = instructions.first { instruction ->
|
||||
instruction.opcode == Opcode.IGET_OBJECT
|
||||
} as ReferenceInstruction
|
||||
|
||||
val textViewFieldReference = textViewFieldInstruction.reference
|
||||
|
||||
// Check if the hooked TextView object is that of the dislike button.
|
||||
// If RYD is disabled, or the TextView object is not that of the dislike button, the execution flow is not interrupted.
|
||||
// Otherwise, the TextView object is modified, and the execution flow is interrupted to prevent it from being changed afterward.
|
||||
addInstructionsWithLabels(
|
||||
insertIndex,
|
||||
"""
|
||||
# Check, if the TextView is for a dislike button
|
||||
iget-boolean v0, p0, $isDisLikesBooleanReference
|
||||
if-eqz v0, :is_like
|
||||
|
||||
# Hook the TextView, if it is for the dislike button
|
||||
iget-object v0, p0, $textViewFieldReference
|
||||
invoke-static {v0}, $EXTENSION_CLASS_DESCRIPTOR->setShortsDislikes(Landroid/view/View;)Z
|
||||
move-result v0
|
||||
if-eqz v0, :ryd_disabled
|
||||
return-void
|
||||
|
||||
:is_like
|
||||
:ryd_disabled
|
||||
nop
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Hook for litho Shorts
|
||||
// region Hook Shorts
|
||||
|
||||
// Filter that parses the video id from the UI
|
||||
addLithoFilter(FILTER_CLASS_DESCRIPTOR)
|
||||
@@ -255,22 +209,25 @@ val returnYouTubeDislikePatch = bytecodePatch(
|
||||
)
|
||||
}
|
||||
|
||||
// Rolling Number text views use the measured width of the raw string for layout.
|
||||
// Modify the measure text calculation to include the left drawable separator if needed.
|
||||
val patternMatch = rollingNumberMeasureAnimatedTextFingerprint.patternMatch!!
|
||||
// Additional check to verify the opcodes are at the start of the method
|
||||
if (patternMatch.startIndex != 0) throw PatchException("Unexpected opcode location")
|
||||
val endIndex = patternMatch.endIndex
|
||||
rollingNumberMeasureAnimatedTextFingerprint.method.apply {
|
||||
val measuredTextWidthRegister = getInstruction<OneRegisterInstruction>(endIndex).registerA
|
||||
rollingNumberMeasureAnimatedTextFingerprint.let {
|
||||
// Rolling Number text views use the measured width of the raw string for layout.
|
||||
// Modify the measure text calculation to include the left drawable separator if needed.
|
||||
val patternMatch = it.patternMatch!!
|
||||
// Verify the opcodes are at the start of the method.
|
||||
if (patternMatch.startIndex != 0) throw PatchException("Unexpected opcode location")
|
||||
val endIndex = patternMatch.endIndex
|
||||
|
||||
addInstructions(
|
||||
endIndex + 1,
|
||||
"""
|
||||
invoke-static {p1, v$measuredTextWidthRegister}, $EXTENSION_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F
|
||||
move-result v$measuredTextWidthRegister
|
||||
""",
|
||||
)
|
||||
it.method.apply {
|
||||
val measuredTextWidthRegister = getInstruction<OneRegisterInstruction>(endIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
endIndex + 1,
|
||||
"""
|
||||
invoke-static {p1, v$measuredTextWidthRegister}, $EXTENSION_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F
|
||||
move-result v$measuredTextWidthRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Additional text measurement method. Used if YouTube decides not to animate the likes count
|
||||
@@ -291,15 +248,14 @@ val returnYouTubeDislikePatch = bytecodePatch(
|
||||
)
|
||||
}
|
||||
}
|
||||
// The rolling number Span is missing styling since it's initially set as a String.
|
||||
// Modify the UI text view and use the styled like/dislike Span.
|
||||
// Initial TextView is set in this method.
|
||||
val initiallyCreatedTextViewMethod = rollingNumberTextViewFingerprint.method
|
||||
|
||||
// Videos less than 24 hours after uploaded, like counts will be updated in real time.
|
||||
// Whenever like counts are updated, TextView is set in this method.
|
||||
arrayOf(
|
||||
initiallyCreatedTextViewMethod,
|
||||
// The rolling number Span is missing styling since it's initially set as a String.
|
||||
// Modify the UI text view and use the styled like/dislike Span.
|
||||
// Initial TextView is set in this method.
|
||||
rollingNumberTextViewFingerprint.method,
|
||||
// Videos less than 24 hours after uploaded, like counts will be updated in real time.
|
||||
// Whenever like counts are updated, TextView is set in this method.
|
||||
rollingNumberTextViewAnimationUpdateFingerprint.method,
|
||||
).forEach { insertMethod ->
|
||||
insertMethod.apply {
|
||||
@@ -315,9 +271,9 @@ val returnYouTubeDislikePatch = bytecodePatch(
|
||||
addInstructions(
|
||||
setTextIndex,
|
||||
"""
|
||||
invoke-static {v$textViewRegister, v$textSpanRegister}, $EXTENSION_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
|
||||
move-result-object v$textSpanRegister
|
||||
""",
|
||||
invoke-static {v$textViewRegister, v$textSpanRegister}, $EXTENSION_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
|
||||
move-result-object v$textSpanRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/WideSearchbarPatch;"
|
||||
|
||||
val wideSearchbarPatch = bytecodePatch(
|
||||
name = "Wide searchbar",
|
||||
name = "Wide search bar",
|
||||
description = "Adds an option to replace the search icon with a wide search bar. This will hide the YouTube logo when active.",
|
||||
) {
|
||||
dependsOn(
|
||||
|
||||
@@ -12,9 +12,11 @@ import app.revanced.patches.shared.misc.mapping.get
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_17_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_43_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
@@ -44,8 +46,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
val spoofAppVersionPatch = bytecodePatch(
|
||||
name = "Spoof app version",
|
||||
description = "Adds an option to trick YouTube into thinking you are running an older version of the app. " +
|
||||
"This can be used to restore old UI elements and features. " +
|
||||
"Patching 19.16.39 includes additional older spoofing targets.",
|
||||
"This can be used to restore old UI elements and features."
|
||||
) {
|
||||
dependsOn(
|
||||
spoofAppVersionResourcePatch,
|
||||
@@ -58,8 +59,8 @@ val spoofAppVersionPatch = bytecodePatch(
|
||||
compatibleWith(
|
||||
"com.google.android.youtube"(
|
||||
"19.16.39",
|
||||
// "19.25.37", // Cannot be supported because the lowest spoof target is higher.
|
||||
// "19.34.42", // Cannot be supported because the lowest spoof target is higher.
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
@@ -71,27 +72,35 @@ val spoofAppVersionPatch = bytecodePatch(
|
||||
addResources("youtube", "layout.spoofappversion.spoofAppVersionPatch")
|
||||
|
||||
PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
||||
SwitchPreference("revanced_spoof_app_version"),
|
||||
if (is_19_17_or_greater) {
|
||||
ListPreference(
|
||||
key = "revanced_spoof_app_version_target",
|
||||
summaryKey = null,
|
||||
// Group the switch and list preference together, since General menu is sorted by name
|
||||
// and the preferences can be scattered apart with non English langauges.
|
||||
PreferenceCategory(
|
||||
titleKey = null,
|
||||
sorting = Sorting.UNSORTED,
|
||||
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
|
||||
preferences = setOf(
|
||||
SwitchPreference("revanced_spoof_app_version"),
|
||||
if (is_19_43_or_greater) {
|
||||
ListPreference(
|
||||
key = "revanced_spoof_app_version_target",
|
||||
summaryKey = null,
|
||||
)
|
||||
} else {
|
||||
ListPreference(
|
||||
key = "revanced_spoof_app_version_target",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_spoof_app_version_target_legacy_entries",
|
||||
entryValuesKey = "revanced_spoof_app_version_target_legacy_entry_values"
|
||||
)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
ListPreference(
|
||||
key = "revanced_spoof_app_version_target",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_spoof_app_version_target_legacy_entries",
|
||||
entryValuesKey = "revanced_spoof_app_version_target_legacy_entry_values"
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* If a user really wants to spoof to very old versions with the latest app target
|
||||
* they can modify the import/export spoof version. But when spoofing the 19.20.xx
|
||||
* or earlier the Library tab can crash due to missing image resources trying to load.
|
||||
* As a temporary workaround, do not set an image in the toolbar when the enum name is UNKNOWN.
|
||||
* If spoofing to target 19.20 or earlier the Library tab can crash due to
|
||||
* missing image resources. As a workaround, do not set an image in the
|
||||
* toolbar when the enum name is UNKNOWN.
|
||||
*/
|
||||
toolBarButtonFingerprint.method.apply {
|
||||
val getDrawableIndex = indexOfGetDrawableInstruction(this)
|
||||
|
||||
@@ -8,7 +8,10 @@ import app.revanced.patcher.patch.stringOption
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.BasePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.InputType
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.TextPreference
|
||||
import app.revanced.patches.youtube.layout.seekbar.seekbarColorPatch
|
||||
@@ -71,6 +74,9 @@ val themePatch = bytecodePatch(
|
||||
)
|
||||
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
settingsPatch,
|
||||
addResourcesPatch,
|
||||
lithoColorHookPatch,
|
||||
seekbarColorPatch,
|
||||
versionCheckPatch,
|
||||
@@ -78,23 +84,30 @@ val themePatch = bytecodePatch(
|
||||
dependsOn(
|
||||
settingsPatch,
|
||||
resourceMappingPatch,
|
||||
addResourcesPatch,
|
||||
)
|
||||
|
||||
execute {
|
||||
addResources("youtube", "layout.theme.themeResourcePatch")
|
||||
|
||||
PreferenceScreen.SEEKBAR.addPreferences(
|
||||
val preferences = mutableSetOf<BasePreference>(
|
||||
SwitchPreference("revanced_seekbar_custom_color"),
|
||||
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),
|
||||
preferences += TextPreference(
|
||||
"revanced_seekbar_custom_color_accent",
|
||||
inputType = InputType.TEXT_CAP_CHARACTERS
|
||||
)
|
||||
}
|
||||
|
||||
PreferenceScreen.SEEKBAR.addPreferences(
|
||||
PreferenceCategory(
|
||||
titleKey = null,
|
||||
sorting = Sorting.UNSORTED,
|
||||
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
|
||||
preferences = preferences
|
||||
)
|
||||
)
|
||||
|
||||
// Edit theme colors via resources.
|
||||
document("res/values/colors.xml").use { document ->
|
||||
|
||||
@@ -125,7 +138,6 @@ val themePatch = bytecodePatch(
|
||||
colorValue: String,
|
||||
) {
|
||||
document(resourceFile).use { document ->
|
||||
|
||||
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
||||
|
||||
resourcesNode.appendChild(
|
||||
@@ -133,7 +145,7 @@ val themePatch = bytecodePatch(
|
||||
setAttribute("name", colorName)
|
||||
setAttribute("category", "color")
|
||||
textContent = colorValue
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -152,11 +164,10 @@ val themePatch = bytecodePatch(
|
||||
// Edit splash screen files and change the background color,
|
||||
// if the background colors are set.
|
||||
if (darkThemeBackgroundColor != null && lightThemeBackgroundColor != null) {
|
||||
val splashScreenResourceFiles =
|
||||
listOf(
|
||||
"res/drawable/quantum_launchscreen_youtube.xml",
|
||||
"res/drawable-sw600dp/quantum_launchscreen_youtube.xml",
|
||||
)
|
||||
val splashScreenResourceFiles = listOf(
|
||||
"res/drawable/quantum_launchscreen_youtube.xml",
|
||||
"res/drawable-sw600dp/quantum_launchscreen_youtube.xml",
|
||||
)
|
||||
|
||||
splashScreenResourceFiles.forEach editSplashScreen@{ resourceFile ->
|
||||
document(resourceFile).use { document ->
|
||||
@@ -174,36 +185,34 @@ val themePatch = bytecodePatch(
|
||||
// Fix the splash screen dark mode background color.
|
||||
// In 19.32+ the dark mode splash screen is white and fades to black.
|
||||
// Maybe it's a bug in YT, or maybe it intentionally. Who knows.
|
||||
document("res/values-night/styles.xml").use { document ->
|
||||
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
||||
val childNodes = resourcesNode.childNodes
|
||||
document("res/values-night-v27/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.V27.Theme.YouTube.Home")
|
||||
|
||||
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)
|
||||
}
|
||||
// Fix status and navigation bar showing white on some Android devices,
|
||||
// such as SDK 28 Android 10 medium tablet.
|
||||
val colorSplashBackgroundColor = "@color/$splashBackgroundColor"
|
||||
arrayOf(
|
||||
"android:navigationBarColor" to colorSplashBackgroundColor,
|
||||
"android:windowBackground" to colorSplashBackgroundColor,
|
||||
"android:colorBackground" to colorSplashBackgroundColor,
|
||||
"colorPrimaryDark" to colorSplashBackgroundColor,
|
||||
"android:windowLightStatusBar" to "false",
|
||||
).forEach { (name, value) ->
|
||||
val styleItem = document.createElement("item")
|
||||
styleItem.setAttribute("name", name)
|
||||
styleItem.textContent = value
|
||||
style.appendChild(styleItem)
|
||||
}
|
||||
|
||||
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
||||
resourcesNode.appendChild(style)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
sharedExtensionPatch,
|
||||
settingsPatch,
|
||||
addResourcesPatch,
|
||||
}
|
||||
)
|
||||
|
||||
compatibleWith(
|
||||
|
||||
@@ -12,7 +12,7 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
|
||||
val openLinksExternallyPatch = bytecodePatch(
|
||||
name = "Open links externally",
|
||||
description = "Adds an option to always open links in your browser instead of in the in-app-browser.",
|
||||
description = "Adds an option to always open links in your browser instead of the in-app browser.",
|
||||
) {
|
||||
dependsOn(
|
||||
transformInstructionsPatch(
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
lateinit var addLithoFilter: (String) -> Unit
|
||||
private set
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/components/LithoFilterPatch;"
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/components/LithoFilterPatch;"
|
||||
|
||||
val lithoFilterPatch = bytecodePatch(
|
||||
description = "Hooks the method which parses the bytes into a ComponentContext to filter components.",
|
||||
|
||||
@@ -16,6 +16,23 @@ internal val actionBarSearchResultsFingerprint = fingerprint {
|
||||
literal { actionBarSearchResultsViewMicId }
|
||||
}
|
||||
|
||||
internal val toolbarLayoutFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PROTECTED, AccessFlags.CONSTRUCTOR)
|
||||
literal { toolbarContainerId }
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches to https://android.googlesource.com/platform/frameworks/support/+/9eee6ba/v7/appcompat/src/android/support/v7/widget/Toolbar.java#963
|
||||
*/
|
||||
internal val appCompatToolbarBackButtonFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("Landroid/graphics/drawable/Drawable;")
|
||||
parameters()
|
||||
custom { methodDef, classDef ->
|
||||
classDef.type == "Landroid/support/v7/widget/Toolbar;"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches to the class found in [pivotBarConstructorFingerprint].
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,7 @@ import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patches.shared.misc.mapping.get
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||
@@ -18,12 +19,16 @@ import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
|
||||
internal var imageOnlyTabResourceId = -1L
|
||||
@@ -32,6 +37,8 @@ internal var actionBarSearchResultsViewMicId = -1L
|
||||
private set
|
||||
internal var ytFillBellId = -1L
|
||||
private set
|
||||
internal var toolbarContainerId = -1L
|
||||
private set
|
||||
|
||||
private val navigationBarHookResourcePatch = resourcePatch {
|
||||
dependsOn(resourceMappingPatch)
|
||||
@@ -40,6 +47,7 @@ private val navigationBarHookResourcePatch = resourcePatch {
|
||||
imageOnlyTabResourceId = resourceMappings["layout", "image_only_tab"]
|
||||
actionBarSearchResultsViewMicId = resourceMappings["layout", "action_bar_search_results_view_mic"]
|
||||
ytFillBellId = resourceMappings["drawable", "yt_fill_bell_black_24"]
|
||||
toolbarContainerId = resourceMappings["id", "toolbar_container"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +55,8 @@ internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/shared/NavigationBar;"
|
||||
internal const val EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/shared/NavigationBar\$NavigationButton;"
|
||||
private const val EXTENSION_TOOLBAR_INTERFACE =
|
||||
"Lapp/revanced/extension/youtube/shared/NavigationBar${'$'}AppCompatToolbarPatchInterface;"
|
||||
|
||||
lateinit var hookNavigationButtonCreated: (String) -> Unit
|
||||
|
||||
@@ -143,11 +153,58 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig
|
||||
)
|
||||
}
|
||||
|
||||
// Hook the back button visibility.
|
||||
|
||||
toolbarLayoutFingerprint.method.apply {
|
||||
val index = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.CHECK_CAST && getReference<TypeReference>()?.type ==
|
||||
"Lcom/google/android/apps/youtube/app/ui/actionbar/MainCollapsingToolbarLayout;"
|
||||
}
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
addInstruction(
|
||||
index + 1,
|
||||
"invoke-static { v$register }, ${EXTENSION_CLASS_DESCRIPTOR}->setToolbar(Landroid/widget/FrameLayout;)V"
|
||||
)
|
||||
}
|
||||
|
||||
// Add interface for extensions code to call obfuscated methods.
|
||||
appCompatToolbarBackButtonFingerprint.let {
|
||||
it.classDef.apply {
|
||||
interfaces.add(EXTENSION_TOOLBAR_INTERFACE)
|
||||
|
||||
val definingClass = type
|
||||
val obfuscatedMethodName = it.originalMethod.name
|
||||
val returnType = "Landroid/graphics/drawable/Drawable;"
|
||||
|
||||
methods.add(
|
||||
ImmutableMethod(
|
||||
definingClass,
|
||||
"patch_getNavigationIcon",
|
||||
listOf(),
|
||||
returnType,
|
||||
AccessFlags.PUBLIC.value or AccessFlags.FINAL.value,
|
||||
null,
|
||||
null,
|
||||
MutableMethodImplementation(2),
|
||||
).toMutable().apply {
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-virtual { p0 }, $definingClass->$obfuscatedMethodName()$returnType
|
||||
move-result-object v0
|
||||
return-object v0
|
||||
"""
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
hookNavigationButtonCreated = { extensionClassDescriptor ->
|
||||
navigationBarHookCallbackFingerprint.method.addInstruction(
|
||||
0,
|
||||
"invoke-static { p0, p1 }, " +
|
||||
"$extensionClassDescriptor->navigationTabCreated" +
|
||||
"invoke-static { p0, p1 }, $extensionClassDescriptor->navigationTabCreated" +
|
||||
"(${EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package app.revanced.patches.youtube.misc.playertype
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.util.literal
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
@@ -15,6 +16,12 @@ internal val playerTypeFingerprint = fingerprint {
|
||||
custom { _, classDef -> classDef.endsWith("/YouTubePlayerOverlaysLayout;") }
|
||||
}
|
||||
|
||||
internal val reelWatchPagerFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("Landroid/view/View;")
|
||||
literal { reelWatchPlayerId }
|
||||
}
|
||||
|
||||
internal val videoStateFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("V")
|
||||
|
||||
@@ -4,15 +4,34 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patches.shared.misc.mapping.get
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/PlayerTypeHookPatch;"
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/PlayerTypeHookPatch;"
|
||||
|
||||
internal var reelWatchPlayerId = -1L
|
||||
private set
|
||||
|
||||
private val playerTypeHookResourcePatch = resourcePatch {
|
||||
dependsOn(resourceMappingPatch)
|
||||
|
||||
execute {
|
||||
reelWatchPlayerId = resourceMappings["id", "reel_watch_player"]
|
||||
}
|
||||
}
|
||||
|
||||
val playerTypeHookPatch = bytecodePatch(
|
||||
description = "Hook to get the current player type and video playback state.",
|
||||
) {
|
||||
dependsOn(sharedExtensionPatch)
|
||||
dependsOn(sharedExtensionPatch, playerTypeHookResourcePatch)
|
||||
|
||||
execute {
|
||||
playerTypeFingerprint.method.addInstruction(
|
||||
@@ -20,6 +39,17 @@ val playerTypeHookPatch = bytecodePatch(
|
||||
"invoke-static {p1}, $EXTENSION_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V",
|
||||
)
|
||||
|
||||
reelWatchPagerFingerprint.method.apply {
|
||||
val literalIndex = indexOfFirstLiteralInstructionOrThrow(reelWatchPlayerId)
|
||||
val registerIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||
val viewRegister = getInstruction<OneRegisterInstruction>(registerIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
registerIndex + 1,
|
||||
"invoke-static { v$viewRegister }, $EXTENSION_CLASS_DESCRIPTOR->onShortsCreate(Landroid/view/View;)V"
|
||||
)
|
||||
}
|
||||
|
||||
videoStateFingerprint.method.apply {
|
||||
val endIndex = videoStateFingerprint.patternMatch!!.endIndex
|
||||
val videoStateFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
|
||||
@@ -27,9 +57,9 @@ val playerTypeHookPatch = bytecodePatch(
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
iget-object v0, p1, $videoStateFieldName # copy VideoState parameter field
|
||||
invoke-static {v0}, $EXTENSION_CLASS_DESCRIPTOR->setVideoState(Ljava/lang/Enum;)V
|
||||
""",
|
||||
iget-object v0, p1, $videoStateFieldName # copy VideoState parameter field
|
||||
invoke-static {v0}, $EXTENSION_CLASS_DESCRIPTOR->setVideoState(Ljava/lang/Enum;)V
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
|
||||
val removeTrackingQueryParameterPatch = bytecodePatch(
|
||||
name = "Remove tracking query parameter",
|
||||
description = "Adds an option to remove the tracking info from links you share.",
|
||||
description = "Adds an option to remove the tracking parameter from links you share.",
|
||||
) {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
|
||||
@@ -301,11 +301,9 @@ object PreferenceScreen : BasePreferenceScreen() {
|
||||
summaryKey = null,
|
||||
)
|
||||
|
||||
// Don't sort, because title sorting scatters the custom color preferences.
|
||||
val SEEKBAR = Screen(
|
||||
key = "revanced_settings_screen_07_seekbar",
|
||||
summaryKey = null,
|
||||
sorting = Sorting.UNSORTED,
|
||||
)
|
||||
val SWIPE_CONTROLS = Screen(
|
||||
key = "revanced_settings_screen_08_swipe_controls",
|
||||
@@ -323,6 +321,7 @@ object PreferenceScreen : BasePreferenceScreen() {
|
||||
val VIDEO = Screen(
|
||||
key = "revanced_settings_screen_12_video",
|
||||
summaryKey = null,
|
||||
sorting = Sorting.BY_KEY,
|
||||
)
|
||||
|
||||
override fun commit(screen: PreferenceScreenPreference) {
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package app.revanced.patches.youtube.video.quality
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.mapping.get
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter
|
||||
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
|
||||
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.addRecyclerViewTreeHook
|
||||
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.recyclerViewTreeHookPatch
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
internal var videoQualityBottomSheetListFragmentTitle = -1L
|
||||
private set
|
||||
internal var videoQualityQuickMenuAdvancedMenuDescription = -1L
|
||||
private set
|
||||
|
||||
private val advancedVideoQualityMenuResourcePatch = resourcePatch {
|
||||
dependsOn(resourceMappingPatch)
|
||||
|
||||
execute {
|
||||
// Used for the old type of the video quality menu.
|
||||
videoQualityBottomSheetListFragmentTitle = resourceMappings[
|
||||
"layout",
|
||||
"video_quality_bottom_sheet_list_fragment_title",
|
||||
]
|
||||
|
||||
videoQualityQuickMenuAdvancedMenuDescription = resourceMappings[
|
||||
"string",
|
||||
"video_quality_quick_menu_advanced_menu_description",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/playback/quality/AdvancedVideoQualityMenuPatch;"
|
||||
|
||||
private const val FILTER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/components/AdvancedVideoQualityMenuFilter;"
|
||||
|
||||
internal val advancedVideoQualityMenuPatch = bytecodePatch {
|
||||
dependsOn(
|
||||
advancedVideoQualityMenuResourcePatch,
|
||||
sharedExtensionPatch,
|
||||
settingsPatch,
|
||||
addResourcesPatch,
|
||||
lithoFilterPatch,
|
||||
recyclerViewTreeHookPatch,
|
||||
)
|
||||
|
||||
execute {
|
||||
addResources("youtube", "video.quality.advancedVideoQualityMenuPatch")
|
||||
|
||||
settingsMenuVideoQualityGroup.add(
|
||||
SwitchPreference("revanced_advanced_video_quality_menu")
|
||||
)
|
||||
|
||||
// region Patch for the old type of the video quality menu.
|
||||
// Used for regular videos when spoofing to old app version,
|
||||
// and for the Shorts quality flyout on newer app versions.
|
||||
|
||||
videoQualityMenuViewInflateFingerprint.let {
|
||||
it.method.apply {
|
||||
val checkCastIndex = it.patternMatch!!.endIndex
|
||||
val listViewRegister = getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
checkCastIndex + 1,
|
||||
"invoke-static { v$listViewRegister }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
||||
"showAdvancedVideoQualityMenu(Landroid/widget/ListView;)V",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Force YT to add the 'advanced' quality menu for Shorts.
|
||||
videoQualityMenuOptionsFingerprint.let {
|
||||
val patternMatch = it.patternMatch!!
|
||||
val startIndex = patternMatch.startIndex
|
||||
val insertIndex = patternMatch.endIndex
|
||||
if (startIndex != 0) throw PatchException("Unexpected opcode start index: $startIndex")
|
||||
|
||||
it.method.apply {
|
||||
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
// A condition controls whether to show the three or four items quality menu.
|
||||
// Force the four items quality menu to make the "Advanced" item visible, necessary for the patch.
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->forceAdvancedVideoQualityMenuCreation(Z)Z
|
||||
move-result v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Patch for the new type of the video quality menu.
|
||||
|
||||
addRecyclerViewTreeHook(EXTENSION_CLASS_DESCRIPTOR)
|
||||
|
||||
// Required to check if the video quality menu is currently shown in order to click on the "Advanced" item.
|
||||
addLithoFilter(FILTER_CLASS_DESCRIPTOR)
|
||||
|
||||
// endregion
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package app.revanced.patches.youtube.video.quality
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.util.literal
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
@@ -35,3 +36,41 @@ internal val videoQualitySetterFingerprint = fingerprint {
|
||||
)
|
||||
strings("menu_item_video_quality")
|
||||
}
|
||||
|
||||
|
||||
internal val videoQualityMenuOptionsFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.STATIC)
|
||||
returns("[L")
|
||||
parameters("Landroid/content/Context", "L", "L")
|
||||
opcodes(
|
||||
Opcode.CONST_4, // First instruction of method.
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.IGET_BOOLEAN, // Use the quality menu, that contains the advanced menu.
|
||||
Opcode.IF_NEZ,
|
||||
)
|
||||
literal { videoQualityQuickMenuAdvancedMenuDescription }
|
||||
}
|
||||
|
||||
internal val videoQualityMenuViewInflateFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("L")
|
||||
parameters("L", "L", "L")
|
||||
opcodes(
|
||||
Opcode.INVOKE_SUPER,
|
||||
Opcode.CONST,
|
||||
Opcode.CONST_4,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CONST,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CONST_16,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.CONST,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
)
|
||||
literal { videoQualityBottomSheetListFragmentTitle }
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.shared.newVideoQualityChangedFingerprint
|
||||
import app.revanced.patches.youtube.video.information.onCreateHook
|
||||
@@ -22,47 +22,47 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/playback/quality/RememberVideoQualityPatch;"
|
||||
|
||||
val rememberVideoQualityPatch = bytecodePatch(
|
||||
name = "Remember video quality",
|
||||
description = "Adds an option to remember the last video quality selected.",
|
||||
) {
|
||||
val rememberVideoQualityPatch = bytecodePatch {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
videoInformationPatch,
|
||||
playerTypeHookPatch,
|
||||
settingsPatch,
|
||||
addResourcesPatch,
|
||||
)
|
||||
|
||||
compatibleWith(
|
||||
"com.google.android.youtube"(
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
),
|
||||
)
|
||||
|
||||
execute {
|
||||
addResources("youtube", "video.quality.rememberVideoQualityPatch")
|
||||
|
||||
PreferenceScreen.VIDEO.addPreferences(
|
||||
SwitchPreference("revanced_remember_video_quality_last_selected"),
|
||||
ListPreference(
|
||||
key = "revanced_video_quality_default_wifi",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_video_quality_default_entries",
|
||||
entryValuesKey = "revanced_video_quality_default_entry_values",
|
||||
),
|
||||
settingsMenuVideoQualityGroup.addAll(listOf(
|
||||
ListPreference(
|
||||
key = "revanced_video_quality_default_mobile",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_video_quality_default_entries",
|
||||
entryValuesKey = "revanced_video_quality_default_entry_values",
|
||||
),
|
||||
)
|
||||
ListPreference(
|
||||
key = "revanced_video_quality_default_wifi",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_video_quality_default_entries",
|
||||
entryValuesKey = "revanced_video_quality_default_entry_values",
|
||||
),
|
||||
SwitchPreference("revanced_remember_video_quality_last_selected"),
|
||||
|
||||
ListPreference(
|
||||
key = "revanced_shorts_quality_default_mobile",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_video_quality_default_entries",
|
||||
entryValuesKey = "revanced_video_quality_default_entry_values",
|
||||
),
|
||||
ListPreference(
|
||||
key = "revanced_shorts_quality_default_wifi",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_video_quality_default_entries",
|
||||
entryValuesKey = "revanced_video_quality_default_entry_values",
|
||||
),
|
||||
SwitchPreference("revanced_remember_shorts_quality_last_selected")
|
||||
))
|
||||
|
||||
/*
|
||||
* The following code works by hooking the method which is called when the user selects a video quality
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package app.revanced.patches.youtube.video.quality
|
||||
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.BasePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
|
||||
/**
|
||||
* Video quality settings. Used to organize all speed related settings together.
|
||||
*/
|
||||
internal val settingsMenuVideoQualityGroup = mutableSetOf<BasePreference>()
|
||||
|
||||
@Suppress("unused")
|
||||
val videoQualityPatch = bytecodePatch(
|
||||
name = "Video quality",
|
||||
description = "Adds options to use the advanced video quality menu and set default video qualities."
|
||||
) {
|
||||
dependsOn(
|
||||
rememberVideoQualityPatch,
|
||||
advancedVideoQualityMenuPatch,
|
||||
)
|
||||
|
||||
compatibleWith(
|
||||
"com.google.android.youtube"(
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
)
|
||||
)
|
||||
|
||||
execute {
|
||||
PreferenceScreen.VIDEO.addPreferences(
|
||||
// Keep the preferences organized together.
|
||||
PreferenceCategory(
|
||||
key = "revanced_01_video_key", // Dummy key to force the quality preferences first.
|
||||
titleKey = null,
|
||||
sorting = Sorting.UNSORTED,
|
||||
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
|
||||
preferences = settingsMenuVideoQualityGroup
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,29 @@
|
||||
package app.revanced.patches.youtube.video.speed
|
||||
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.BasePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.video.speed.button.playbackSpeedButtonPatch
|
||||
import app.revanced.patches.youtube.video.speed.custom.customPlaybackSpeedPatch
|
||||
import app.revanced.patches.youtube.video.speed.remember.rememberPlaybackSpeedPatch
|
||||
|
||||
/**
|
||||
* Speed menu settings. Used to organize all speed related settings together.
|
||||
*/
|
||||
internal val settingsMenuVideoSpeedGroup = mutableSetOf<BasePreference>()
|
||||
|
||||
@Suppress("unused")
|
||||
val playbackSpeedPatch = bytecodePatch(
|
||||
name = "Playback speed",
|
||||
description = "Adds options to customize available playback speeds, remember the last playback speed selected " +
|
||||
description = "Adds options to customize available playback speeds, set default a playback speed, " +
|
||||
"and show a speed dialog button in the video player.",
|
||||
) {
|
||||
dependsOn(
|
||||
playbackSpeedButtonPatch,
|
||||
customPlaybackSpeedPatch,
|
||||
rememberPlaybackSpeedPatch,
|
||||
playbackSpeedButtonPatch,
|
||||
)
|
||||
|
||||
compatibleWith(
|
||||
@@ -26,6 +35,18 @@ val playbackSpeedPatch = bytecodePatch(
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
execute {
|
||||
PreferenceScreen.VIDEO.addPreferences(
|
||||
PreferenceCategory(
|
||||
key = "revanced_zz_video_key", // Dummy key to force the speed settings last.
|
||||
titleKey = null,
|
||||
sorting = Sorting.UNSORTED,
|
||||
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
|
||||
preferences = settingsMenuVideoSpeedGroup
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.playercontrols.*
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
@@ -35,11 +36,12 @@ val playbackSpeedButtonPatch = bytecodePatch(
|
||||
description = "Adds the option to display playback speed dialog button in the video player.",
|
||||
) {
|
||||
dependsOn(
|
||||
playbackSpeedButtonResourcePatch,
|
||||
customPlaybackSpeedPatch,
|
||||
playerControlsPatch,
|
||||
sharedExtensionPatch,
|
||||
settingsPatch,
|
||||
addResourcesPatch,
|
||||
customPlaybackSpeedPatch,
|
||||
playbackSpeedButtonResourcePatch,
|
||||
playerControlsPatch,
|
||||
)
|
||||
|
||||
execute {
|
||||
|
||||
@@ -25,8 +25,8 @@ import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.addRecyclerViewTreeHook
|
||||
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.recyclerViewTreeHookPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.video.speed.settingsMenuVideoSpeedGroup
|
||||
import app.revanced.util.*
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||
@@ -60,24 +60,29 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
|
||||
) {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
lithoFilterPatch,
|
||||
settingsPatch,
|
||||
recyclerViewTreeHookPatch,
|
||||
customPlaybackSpeedResourcePatch,
|
||||
addResourcesPatch,
|
||||
versionCheckPatch
|
||||
lithoFilterPatch,
|
||||
versionCheckPatch,
|
||||
recyclerViewTreeHookPatch,
|
||||
customPlaybackSpeedResourcePatch
|
||||
)
|
||||
|
||||
execute {
|
||||
addResources("youtube", "video.speed.custom.customPlaybackSpeedPatch")
|
||||
|
||||
PreferenceScreen.VIDEO.addPreferences(
|
||||
SwitchPreference("revanced_custom_speed_menu"),
|
||||
TextPreference("revanced_custom_playback_speeds", inputType = InputType.TEXT_MULTI_LINE),
|
||||
settingsMenuVideoSpeedGroup.addAll(
|
||||
listOf(
|
||||
SwitchPreference("revanced_custom_speed_menu"),
|
||||
TextPreference(
|
||||
"revanced_custom_playback_speeds",
|
||||
inputType = InputType.TEXT_MULTI_LINE
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
if (is_19_25_or_greater) {
|
||||
PreferenceScreen.VIDEO.addPreferences(
|
||||
settingsMenuVideoSpeedGroup.add(
|
||||
TextPreference("revanced_speed_tap_and_hold", inputType = InputType.NUMBER_DECIMAL),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.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.patches.youtube.video.information.*
|
||||
import app.revanced.patches.youtube.video.speed.custom.customPlaybackSpeedPatch
|
||||
import app.revanced.patches.youtube.video.speed.settingsMenuVideoSpeedGroup
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
@@ -22,26 +22,29 @@ internal val rememberPlaybackSpeedPatch = bytecodePatch {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
settingsPatch,
|
||||
videoInformationPatch,
|
||||
customPlaybackSpeedPatch,
|
||||
addResourcesPatch,
|
||||
videoInformationPatch,
|
||||
customPlaybackSpeedPatch
|
||||
)
|
||||
|
||||
execute {
|
||||
addResources("youtube", "video.speed.remember.rememberPlaybackSpeedPatch")
|
||||
|
||||
PreferenceScreen.VIDEO.addPreferences(
|
||||
SwitchPreference("revanced_remember_playback_speed_last_selected"),
|
||||
ListPreference(
|
||||
key = "revanced_playback_speed_default",
|
||||
summaryKey = null,
|
||||
// Entries and values are set by the extension code based on the actual speeds available.
|
||||
entriesKey = null,
|
||||
entryValuesKey = null,
|
||||
),
|
||||
settingsMenuVideoSpeedGroup.addAll(
|
||||
listOf(
|
||||
ListPreference(
|
||||
key = "revanced_playback_speed_default",
|
||||
summaryKey = null,
|
||||
// Entries and values are set by the extension code based on the actual speeds available.
|
||||
entriesKey = null,
|
||||
entryValuesKey = null,
|
||||
),
|
||||
SwitchPreference("revanced_remember_playback_speed_last_selected")
|
||||
)
|
||||
)
|
||||
|
||||
onCreateHook(EXTENSION_CLASS_DESCRIPTOR, "newVideoStarted")
|
||||
|
||||
userSelectedPlaybackSpeedHook(
|
||||
EXTENSION_CLASS_DESCRIPTOR,
|
||||
"userSelectedPlaybackSpeed",
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
package app.revanced.patches.youtube.video.videoqualitymenu
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.util.literal
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val videoQualityMenuOptionsFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.STATIC)
|
||||
returns("[L")
|
||||
parameters("Landroid/content/Context", "L", "L")
|
||||
opcodes(
|
||||
Opcode.CONST_4, // First instruction of method.
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.IGET_BOOLEAN, // Use the quality menu, that contains the advanced menu.
|
||||
Opcode.IF_NEZ,
|
||||
)
|
||||
literal { videoQualityQuickMenuAdvancedMenuDescription }
|
||||
}
|
||||
|
||||
internal val videoQualityMenuViewInflateFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("L")
|
||||
parameters("L", "L", "L")
|
||||
opcodes(
|
||||
Opcode.INVOKE_SUPER,
|
||||
Opcode.CONST,
|
||||
Opcode.CONST_4,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CONST,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CONST_16,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.CONST,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
)
|
||||
literal { videoQualityBottomSheetListFragmentTitle }
|
||||
}
|
||||
@@ -1,135 +1,10 @@
|
||||
package app.revanced.patches.youtube.video.videoqualitymenu
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.mapping.get
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter
|
||||
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
|
||||
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.addRecyclerViewTreeHook
|
||||
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.recyclerViewTreeHookPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
internal var videoQualityBottomSheetListFragmentTitle = -1L
|
||||
private set
|
||||
internal var videoQualityQuickMenuAdvancedMenuDescription = -1L
|
||||
private set
|
||||
|
||||
private val restoreOldVideoQualityMenuResourcePatch = resourcePatch {
|
||||
dependsOn(
|
||||
settingsPatch,
|
||||
resourceMappingPatch,
|
||||
addResourcesPatch,
|
||||
)
|
||||
|
||||
execute {
|
||||
addResources("youtube", "video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch")
|
||||
|
||||
PreferenceScreen.VIDEO.addPreferences(
|
||||
SwitchPreference("revanced_restore_old_video_quality_menu"),
|
||||
)
|
||||
|
||||
// Used for the old type of the video quality menu.
|
||||
videoQualityBottomSheetListFragmentTitle = resourceMappings[
|
||||
"layout",
|
||||
"video_quality_bottom_sheet_list_fragment_title",
|
||||
]
|
||||
|
||||
videoQualityQuickMenuAdvancedMenuDescription = resourceMappings[
|
||||
"string",
|
||||
"video_quality_quick_menu_advanced_menu_description",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private const val FILTER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/components/VideoQualityMenuFilterPatch;"
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch;"
|
||||
import app.revanced.patches.youtube.video.quality.videoQualityPatch
|
||||
|
||||
@Suppress("unused")
|
||||
val restoreOldVideoQualityMenuPatch = bytecodePatch(
|
||||
name = "Restore old video quality menu",
|
||||
description = "Adds an option to restore the old video quality menu with specific video resolution options.",
|
||||
|
||||
) {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
restoreOldVideoQualityMenuResourcePatch,
|
||||
lithoFilterPatch,
|
||||
recyclerViewTreeHookPatch,
|
||||
)
|
||||
|
||||
compatibleWith(
|
||||
"com.google.android.youtube"(
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
"19.43.41",
|
||||
"19.45.38",
|
||||
"19.46.42",
|
||||
"19.47.53",
|
||||
),
|
||||
)
|
||||
|
||||
execute {
|
||||
// region Patch for the old type of the video quality menu.
|
||||
// Used for regular videos when spoofing to old app version,
|
||||
// and for the Shorts quality flyout on newer app versions.
|
||||
|
||||
videoQualityMenuViewInflateFingerprint.method.apply {
|
||||
val checkCastIndex = videoQualityMenuViewInflateFingerprint.patternMatch!!.endIndex
|
||||
val listViewRegister = getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
checkCastIndex + 1,
|
||||
"invoke-static { v$listViewRegister }, " +
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->" +
|
||||
"showOldVideoQualityMenu(Landroid/widget/ListView;)V",
|
||||
)
|
||||
}
|
||||
|
||||
// Force YT to add the 'advanced' quality menu for Shorts.
|
||||
val patternMatch = videoQualityMenuOptionsFingerprint.patternMatch!!
|
||||
val startIndex = patternMatch.startIndex
|
||||
if (startIndex != 0) throw PatchException("Unexpected opcode start index: $startIndex")
|
||||
val insertIndex = patternMatch.endIndex
|
||||
|
||||
videoQualityMenuOptionsFingerprint.method.apply {
|
||||
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
// A condition controls whether to show the three or four items quality menu.
|
||||
// Force the four items quality menu to make the "Advanced" item visible, necessary for the patch.
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->forceAdvancedVideoQualityMenuCreation(Z)Z
|
||||
move-result v$register
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Patch for the new type of the video quality menu.
|
||||
|
||||
addRecyclerViewTreeHook(EXTENSION_CLASS_DESCRIPTOR)
|
||||
|
||||
// Required to check if the video quality menu is currently shown in order to click on the "Advanced" item.
|
||||
addLithoFilter(FILTER_CLASS_DESCRIPTOR)
|
||||
|
||||
// endregion
|
||||
}
|
||||
}
|
||||
@Deprecated("Use 'Video Quality' instead.")
|
||||
val restoreOldVideoQualityMenuPatch = bytecodePatch {
|
||||
dependsOn(videoQualityPatch)
|
||||
}
|
||||
@@ -178,8 +178,7 @@ fun Method.indexOfFirstLiteralInstructionReversedOrThrow(literal: Long): Int {
|
||||
*
|
||||
* @return if the method contains a literal with the given value.
|
||||
*/
|
||||
fun Method.containsLiteralInstruction(literal: Long) =
|
||||
indexOfFirstLiteralInstruction(literal) >= 0
|
||||
fun Method.containsLiteralInstruction(literal: Long) = indexOfFirstLiteralInstruction(literal) >= 0
|
||||
|
||||
/**
|
||||
* Traverse the class hierarchy starting from the given root class.
|
||||
@@ -205,25 +204,22 @@ fun BytecodePatchContext.traverseClassHierarchy(targetClass: MutableClass, callb
|
||||
* if the [Instruction] is not a [ReferenceInstruction] or the [Reference] is not of type [T].
|
||||
* @see ReferenceInstruction
|
||||
*/
|
||||
inline fun <reified T : Reference> Instruction.getReference() =
|
||||
(this as? ReferenceInstruction)?.reference as? T
|
||||
inline fun <reified T : Reference> Instruction.getReference() = (this as? ReferenceInstruction)?.reference as? T
|
||||
|
||||
/**
|
||||
* @return The index of the first opcode specified, or -1 if not found.
|
||||
* @see indexOfFirstInstructionOrThrow
|
||||
*/
|
||||
fun Method.indexOfFirstInstruction(targetOpcode: Opcode): Int =
|
||||
indexOfFirstInstruction(0, targetOpcode)
|
||||
fun Method.indexOfFirstInstruction(targetOpcode: Opcode): Int = indexOfFirstInstruction(0, targetOpcode)
|
||||
|
||||
/**
|
||||
* @param startIndex Optional starting index to start searching from.
|
||||
* @return The index of the first opcode specified, or -1 if not found.
|
||||
* @see indexOfFirstInstructionOrThrow
|
||||
*/
|
||||
fun Method.indexOfFirstInstruction(startIndex: Int = 0, targetOpcode: Opcode): Int =
|
||||
indexOfFirstInstruction(startIndex) {
|
||||
opcode == targetOpcode
|
||||
}
|
||||
fun Method.indexOfFirstInstruction(startIndex: Int = 0, targetOpcode: Opcode): Int = indexOfFirstInstruction(startIndex) {
|
||||
opcode == targetOpcode
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the first [Instruction] that matches the predicate, starting from [startIndex].
|
||||
@@ -251,23 +247,21 @@ fun Method.indexOfFirstInstruction(startIndex: Int = 0, filter: Instruction.() -
|
||||
* @throws PatchException
|
||||
* @see indexOfFirstInstruction
|
||||
*/
|
||||
fun Method.indexOfFirstInstructionOrThrow(targetOpcode: Opcode): Int =
|
||||
indexOfFirstInstructionOrThrow(0, targetOpcode)
|
||||
fun Method.indexOfFirstInstructionOrThrow(targetOpcode: Opcode): Int = indexOfFirstInstructionOrThrow(0, targetOpcode)
|
||||
|
||||
/**
|
||||
* @return The index of the first opcode specified, starting from the index specified.
|
||||
* @throws PatchException
|
||||
* @see indexOfFirstInstruction
|
||||
*/
|
||||
fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, targetOpcode: Opcode): Int =
|
||||
indexOfFirstInstructionOrThrow(startIndex) {
|
||||
opcode == targetOpcode
|
||||
}
|
||||
fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, targetOpcode: Opcode): Int = indexOfFirstInstructionOrThrow(startIndex) {
|
||||
opcode == targetOpcode
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the first [Instruction] that matches the predicate, starting from [startIndex].
|
||||
*
|
||||
* @return the index of the instruction
|
||||
* @return The index of the instruction.
|
||||
* @throws PatchException
|
||||
* @see indexOfFirstInstruction
|
||||
*/
|
||||
@@ -288,10 +282,9 @@ fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, filter: Instructi
|
||||
* @return -1 if the instruction is not found.
|
||||
* @see indexOfFirstInstructionReversedOrThrow
|
||||
*/
|
||||
fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, targetOpcode: Opcode): Int =
|
||||
indexOfFirstInstructionReversed(startIndex) {
|
||||
opcode == targetOpcode
|
||||
}
|
||||
fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, targetOpcode: Opcode): Int = indexOfFirstInstructionReversed(startIndex) {
|
||||
opcode == targetOpcode
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of matching instruction,
|
||||
@@ -316,23 +309,21 @@ fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, filter: Inst
|
||||
*
|
||||
* @return -1 if the instruction is not found.
|
||||
*/
|
||||
fun Method.indexOfFirstInstructionReversed(targetOpcode: Opcode): Int =
|
||||
indexOfFirstInstructionReversed {
|
||||
opcode == targetOpcode
|
||||
}
|
||||
fun Method.indexOfFirstInstructionReversed(targetOpcode: Opcode): Int = indexOfFirstInstructionReversed {
|
||||
opcode == targetOpcode
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of matching instruction,
|
||||
* starting from and [startIndex] and searching down.
|
||||
*
|
||||
* @param startIndex Optional starting index to search down from. Searching includes the start index.
|
||||
* @return -1 if the instruction is not found.
|
||||
* @return The index of the instruction.
|
||||
* @see indexOfFirstInstructionReversed
|
||||
*/
|
||||
fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, targetOpcode: Opcode): Int =
|
||||
indexOfFirstInstructionReversedOrThrow(startIndex) {
|
||||
opcode == targetOpcode
|
||||
}
|
||||
fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, targetOpcode: Opcode): Int = indexOfFirstInstructionReversedOrThrow(startIndex) {
|
||||
opcode == targetOpcode
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of matching instruction,
|
||||
@@ -340,16 +331,16 @@ fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, targe
|
||||
*
|
||||
* @return -1 if the instruction is not found.
|
||||
*/
|
||||
fun Method.indexOfFirstInstructionReversedOrThrow(targetOpcode: Opcode): Int =
|
||||
indexOfFirstInstructionReversedOrThrow {
|
||||
opcode == targetOpcode
|
||||
}
|
||||
fun Method.indexOfFirstInstructionReversedOrThrow(targetOpcode: Opcode): Int = indexOfFirstInstructionReversedOrThrow {
|
||||
opcode == targetOpcode
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of matching instruction,
|
||||
* starting from and [startIndex] and searching down.
|
||||
*
|
||||
* @param startIndex Optional starting index to search down from. Searching includes the start index.
|
||||
* @return -1 if the instruction is not found.
|
||||
* @return The index of the instruction.
|
||||
* @see indexOfFirstInstructionReversed
|
||||
*/
|
||||
fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, filter: Instruction.() -> Boolean): Int {
|
||||
@@ -389,8 +380,7 @@ fun Method.findInstructionIndicesReversedOrThrow(filter: Instruction.() -> Boole
|
||||
* _Returns an empty list if no indices are found_
|
||||
* @see findInstructionIndicesReversedOrThrow
|
||||
*/
|
||||
fun Method.findInstructionIndicesReversed(opcode: Opcode): List<Int> =
|
||||
findInstructionIndicesReversed { this.opcode == opcode }
|
||||
fun Method.findInstructionIndicesReversed(opcode: Opcode): List<Int> = findInstructionIndicesReversed { this.opcode == opcode }
|
||||
|
||||
/**
|
||||
* @return An immutable list of indices of the opcode in reverse order.
|
||||
@@ -408,15 +398,18 @@ internal fun MutableMethod.insertFeatureFlagBooleanOverride(literal: Long, exten
|
||||
val index = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
val operation = if (register < 16) "invoke-static { v$register }"
|
||||
else "invoke-static/range { v$register .. v$register }"
|
||||
val operation = if (register < 16) {
|
||||
"invoke-static { v$register }"
|
||||
} else {
|
||||
"invoke-static/range { v$register .. v$register }"
|
||||
}
|
||||
|
||||
addInstructions(
|
||||
index + 1,
|
||||
"""
|
||||
$operation, $extensionsMethod
|
||||
move-result v$register
|
||||
"""
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -50,9 +50,9 @@ Second \"item\" text"</string>
|
||||
This button usually appears when searching for a YT creator. -->
|
||||
<!-- https://logos.fandom.com/wiki/YouTube/Yoodles -->
|
||||
<!-- 'Component path builder strings' is the technical name for identifying the Litho UI layout items to hide. This is an advanced feature and most users will never use this. -->
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
<!-- For localization, it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc.) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
<patch id="ad.general.hideAdsResourcePatch">
|
||||
@@ -156,6 +156,7 @@ Second \"item\" text"</string>
|
||||
<patch id="layout.sponsorblock.sponsorBlockResourcePatch">
|
||||
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<!-- A segment start and end time, such as "02:10 to 03:40" -->
|
||||
<!-- Shown in the settings preferences, and translations can be any text length. -->
|
||||
</patch>
|
||||
<patch id="layout.formfactor.changeFormFactorPatch">
|
||||
@@ -163,7 +164,6 @@ Second \"item\" text"</string>
|
||||
<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'.
|
||||
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
|
||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
||||
</patch>
|
||||
<patch id="layout.startpage.changeStartPagePatch">
|
||||
</patch>
|
||||
@@ -177,8 +177,6 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="layout.theme.themePatch">
|
||||
</patch>
|
||||
<patch id="layout.theme.themeResourcePatch">
|
||||
</patch>
|
||||
<patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch">
|
||||
</patch>
|
||||
<patch id="layout.thumbnails.alternativeThumbnailsPatch">
|
||||
@@ -219,7 +217,7 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="video.hdr.disableHdrPatch">
|
||||
</patch>
|
||||
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch">
|
||||
<patch id="video.quality.advancedVideoQualityMenuPatch">
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
||||
</patch>
|
||||
|
||||
@@ -50,9 +50,9 @@ Second \"item\" text"</string>
|
||||
This button usually appears when searching for a YT creator. -->
|
||||
<!-- https://logos.fandom.com/wiki/YouTube/Yoodles -->
|
||||
<!-- 'Component path builder strings' is the technical name for identifying the Litho UI layout items to hide. This is an advanced feature and most users will never use this. -->
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
<!-- For localization, it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc.) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
<patch id="ad.general.hideAdsResourcePatch">
|
||||
@@ -156,6 +156,7 @@ Second \"item\" text"</string>
|
||||
<patch id="layout.sponsorblock.sponsorBlockResourcePatch">
|
||||
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<!-- A segment start and end time, such as "02:10 to 03:40" -->
|
||||
<!-- Shown in the settings preferences, and translations can be any text length. -->
|
||||
</patch>
|
||||
<patch id="layout.formfactor.changeFormFactorPatch">
|
||||
@@ -163,7 +164,6 @@ Second \"item\" text"</string>
|
||||
<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'.
|
||||
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
|
||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
||||
</patch>
|
||||
<patch id="layout.startpage.changeStartPagePatch">
|
||||
</patch>
|
||||
@@ -177,8 +177,6 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="layout.theme.themePatch">
|
||||
</patch>
|
||||
<patch id="layout.theme.themeResourcePatch">
|
||||
</patch>
|
||||
<patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch">
|
||||
</patch>
|
||||
<patch id="layout.thumbnails.alternativeThumbnailsPatch">
|
||||
@@ -219,7 +217,7 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="video.hdr.disableHdrPatch">
|
||||
</patch>
|
||||
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch">
|
||||
<patch id="video.quality.advancedVideoQualityMenuPatch">
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
||||
</patch>
|
||||
|
||||
@@ -48,57 +48,6 @@ Second \"item\" text"</string>
|
||||
|
||||
ŲØĒØąØŦŲ
ØŠ ب稧ØĒ ØŦØ¯ŲØ¯ØŠØ ØĒŲØļŲ Ø¨Ø˛ŲØ§ØąØŠ 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_summary">Ø§ØŗØĒŲØąØ§Ø¯ / ØĒØĩØ¯ŲØą ØĨؚداداØĒ ReVanced</string>
|
||||
<!-- Settings about dialog. -->
|
||||
@@ -277,6 +226,9 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_artist_cards_title">ØĨØŽŲØ§ØĄ Ø¨ØˇØ§ŲØ§ØĒ اŲŲŲØ§Ų</string>
|
||||
<string name="revanced_hide_artist_cards_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ø¨ØˇØ§ŲØ§ØĒ اŲŲŲØ§Ų</string>
|
||||
<string name="revanced_hide_artist_cards_summary_off">ŲØĒŲ
ØšØąØļ Ø¨ØˇØ§ŲØ§ØĒ اŲŲŲØ§Ų</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_title">ØĨØŽŲØ§ØĄ \"Ų
ŲØŽØĩ اŲŲŲØ¯ŲŲ Ø§ŲØ°Ų ØĒŲ
ØĨŲØ´Ø§Ø¤Ų Ø¨ŲØ§ØŗØˇØŠ Ø§ŲØ°ŲØ§ØĄ Ø§ŲØ§ØĩØˇŲØ§ØšŲ\"</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ŲØŗŲ
Ų
ŲØŽØĩ اŲŲŲØ¯ŲŲ</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_summary_off">ŲØĒŲ
ØšØąØļ ŲØŗŲ
Ų
ŲØŽØĩ اŲŲŲØ¯ŲŲ</string>
|
||||
<string name="revanced_hide_attributes_section_title">ØĨØŽŲØ§ØĄ Ø§ŲØĩŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_attributes_section_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ØŖŲØŗØ§Ų
Ø§ŲØŖŲ
اŲŲ Ø§ŲŲ
Ų
ŲØ˛ØŠØ Ø§ŲØŖŲØšØ§Ø¨Ø Ø§ŲŲ
ŲØŗŲŲŲ ŲØ§ŲØŖØ´ØŽØ§Øĩ اŲŲ
ذŲŲØąŲŲ</string>
|
||||
<string name="revanced_hide_attributes_section_summary_off">ŲØĒŲ
ØšØąØļ ØŖŲØŗØ§Ų
Ø§ŲØŖŲ
اŲŲ Ø§ŲŲ
Ų
ŲØ˛ØŠØ Ø§ŲØŖŲØšØ§Ø¨Ø Ø§ŲŲ
ŲØŗŲŲŲ ŲØ§ŲØŖØ´ØŽØ§Øĩ اŲŲ
ذŲŲØąŲŲ</string>
|
||||
@@ -313,9 +265,12 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">ŲØšØąØļ ŲŲ Ø§ŲŲŲØ¯ŲŲŲØ§ØĒ ذاØĒ Ø§ŲØĩŲØŠ</string>
|
||||
<string name="revanced_comments_screen_title">Ø§ŲØĒØšŲŲŲØ§ØĒ</string>
|
||||
<string name="revanced_comments_screen_summary">ØĨØŽŲØ§ØĄ ØŖŲ ØšØąØļ Ų
ŲŲŲØ§ØĒ ŲØŗŲ
Ø§ŲØĒØšŲŲŲØ§ØĒ</string>
|
||||
<string name="revanced_hide_comments_chat_summary_title">ØĨØŽŲØ§ØĄ \'Ų
ŲØŽØĩ اŲŲ
ØØ§Ø¯ØĢØŠ\'</string>
|
||||
<string name="revanced_hide_comments_chat_summary_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ų
ŲØŽØĩ اŲŲ
ØØ§Ø¯ØĢاØĒ</string>
|
||||
<string name="revanced_hide_comments_chat_summary_summary_off">ŲØĒŲ
ØšØąØļ Ų
ŲØŽØĩ اŲŲ
ØØ§Ø¯ØĢاØĒ</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_title">ØĨØŽŲØ§ØĄ Ų
ŲØŽØĩ Ø¯ØąØ¯Ø´ØŠ Ø§ŲØ°ŲØ§ØĄ Ø§ŲØ§ØĩØˇŲØ§ØšŲ</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ų
ŲØŽØĩ اŲŲ
ØØ§Ø¯ØĢاØĒ</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_off">ŲØĒŲ
ØšØąØļ Ų
ŲØŽØĩ اŲŲ
ØØ§Ø¯ØĢاØĒ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_title">ØĨØŽŲØ§ØĄ Ų
ŲØŽØĩ ØĒØšŲŲŲØ§ØĒ Ø§ŲØ°ŲØ§ØĄ Ø§ŲØ§ØĩØˇŲØ§ØšŲ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_on">Ų
ŲØŽØĩ Ø§ŲØĒØšŲŲŲØ§ØĒ Ų
ØŽŲŲ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_off">Ų
ŲØŽØĩ Ø§ŲØĒØšŲŲŲØ§ØĒ Ų
ØšØąŲØļ</string>
|
||||
<string name="revanced_hide_comments_by_members_header_title">ØĨØŽŲØ§ØĄ ØąØŖØŗ \'ØĒØšŲŲŲØ§ØĒ Ø§ŲØŖØšØļØ§ØĄ\'</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ ØšŲØ§Ų
ØŠ ØĒØšŲŲŲØ§ØĒ Ų
Ų Ø§ŲØŖØšØļØ§ØĄ</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_off">ŲØĒŲ
ØšØąØļ ØšŲØ§Ų
ØŠ ØĒØšŲŲŲØ§ØĒ Ų
Ų Ø§ŲØŖØšØļØ§ØĄ</string>
|
||||
@@ -362,7 +317,7 @@ Second \"item\" text"</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_phrases_title">اŲŲŲŲ
اØĒ اŲŲ
ŲØĒØ§ØŲØŠ اŲŲ
ØąØ§Ø¯ ØĨØŽŲØ§Ø¤Ųا</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
<!-- For localization, it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">"اŲŲŲŲ
اØĒ ŲØ§ŲØšØ¨Ø§ØąØ§ØĒ Ø§ŲØĒŲ ØĒØąŲØ¯ ØĨØŽŲØ§ØĄŲØ§Ø Ų
ŲØĩŲŲØŠ Ø¨ØŗØˇŲØą ØŦØ¯ŲØ¯ØŠ
|
||||
|
||||
@@ -377,7 +332,7 @@ Second \"item\" text"</string>
|
||||
âĸ ŲØ¯ ŲØ§ ŲØĒŲ
ØĨØŽŲØ§ØĄ بؚØļ Ų
ŲŲŲØ§ØĒ ŲØ§ØŦŲØŠ Ø§ŲŲ
ØŗØĒ؎دŲ
|
||||
âĸ Ø§ŲØ¨ØØĢ ØšŲ ŲŲŲ
ØŠ Ų
ا ŲØ¯ ŲØ§ ŲØšØˇŲ ŲØĒØ§ØĻØŦ"</string>
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_title">Ų
ØˇØ§Ø¨ŲØŠ Ø§ŲŲŲŲ
اØĒ Ø¨ØŖŲŲ
ŲŲØ§</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc.) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_summary">ØŗŲØ¤Ø¯Ų ŲØļØš ØšŲØ§Ų
ØŠ Ø§ŲØĒØ¨Ø§Øŗ Ų
Ø˛Ø¯ŲØŦØŠ ØŲŲ ŲŲŲ
ØŠ ØąØĻŲØŗŲØŠ/ØšØ¨Ø§ØąØŠ ØĨŲŲ Ų
ب𠨧بǨˇØ§Ø¨ŲاØĒ Ø§ŲØŦØ˛ØĻŲØŠ ŲØšŲاŲŲŲ Ø§ŲŲŲØ¯ŲŲ ŲØŖØŗŲ
Ø§ØĄ اŲŲŲŲØ§ØĒ.<br><br>ØšŲŲ ØŗØ¨ŲŲ Ø§ŲŲ
ØĢØ§ŲØ<br><b>\"ai\"</b> ØŗŲØŽŲŲ Ø§ŲŲŲØ¯ŲŲ: <b>How does AI work?</b><br>ŲŲŲŲ ŲŲ ŲØŽŲŲ: <b>What does fair use mean?</b></string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">ŲØ§ ŲŲ
ŲŲ Ø§ØŗØĒ؎داŲ
اŲŲŲŲ
ØŠ Ø§ŲØąØĻŲØŗŲØŠ: %s</string>
|
||||
@@ -404,7 +359,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_title">ØĨØŽŲØ§ØĄ Ø¨ØˇØ§ŲØ§ØĒ Ø§ŲØąØšØ§ŲØŠ Ø§ŲØ°Ø§ØĒŲØŠ</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ø¨ØˇØ§ŲØ§ØĒ Ø§ŲØąØšØ§ŲØŠ Ø§ŲØ°Ø§ØĒŲØŠ</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_off">ŲØĒŲ
ØšØąØļ Ø¨ØˇØ§ŲØ§ØĒ Ø§ŲØąØšØ§ŲØŠ Ø§ŲØ°Ø§ØĒŲØŠ</string>
|
||||
<string name="revanced_hide_products_banner_title">ØĨØŽŲØ§ØĄ ŲØ§ŲØĒØŠ ŲØšØąØļ Ø§ŲŲ
ŲØĒØŦاØĒ</string>
|
||||
<string name="revanced_hide_products_banner_title">ØĨØŽŲØ§ØĄ ŲØ§ŲØĒØŠ \"ØšØąØļ اŲŲ
ŲØĒØŦاØĒ\"</string>
|
||||
<string name="revanced_hide_products_banner_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ø§ŲØ¨Ø§ŲØą</string>
|
||||
<string name="revanced_hide_products_banner_summary_off">ŲØĒŲ
ØšØąØļ Ø§ŲØ¨Ø§ŲØą</string>
|
||||
<string name="revanced_hide_end_screen_store_banner_title">ØĨØŽŲØ§ØĄ ŲØ§ŲØĒØŠ شاش؊ اŲŲ
ØĒØŦØą اŲŲŲØ§ØĻŲØŠ</string>
|
||||
@@ -475,9 +430,9 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_disable_precise_seeking_gesture_summary_off">ØĒŲ
ØĒŲ
ŲŲŲ Ø§ŲØĨŲŲ
Ø§ØĄØŠ</string>
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSeekbarTappingPatch">
|
||||
<string name="revanced_seekbar_tapping_title">ØĒŲ
ŲŲŲ Ø§ŲŲŲØą ØšŲŲ Ø´ØąŲØˇ اŲŲŲØĒ</string>
|
||||
<string name="revanced_seekbar_tapping_summary_on">ØĒŲ
ØĒŲ
ŲŲŲ Ø§ŲŲŲØą ØšŲŲ Ø´ØąŲØˇ اŲŲŲØĒ (Ø´ØąŲØˇ ØĒŲØ¯Ų
اŲŲŲØ¯ŲŲ)</string>
|
||||
<string name="revanced_seekbar_tapping_summary_off">ØĒŲ
ØĒØšØˇŲŲ Ø§ŲŲŲØą ØšŲŲ Ø´ØąŲØˇ اŲŲŲØĒ (Ø´ØąŲØˇ ØĒŲØ¯Ų
اŲŲŲØ¯ŲŲ)</string>
|
||||
<string name="revanced_seekbar_tapping_title">ØĒŲ
ŲŲŲ Ø§ŲŲŲØą ŲŲØ¨ØØĢ</string>
|
||||
<string name="revanced_seekbar_tapping_summary_on">ØĒŲ
ØĒŲ
ŲŲŲ Ø§ŲŲŲØą ŲŲØĒŲŲŲ</string>
|
||||
<string name="revanced_seekbar_tapping_summary_off">ØĒŲ
ØĒØšØˇŲŲ Ø§ŲŲŲØą ŲŲØ¨ØØĢ</string>
|
||||
</patch>
|
||||
<patch id="interaction.swipecontrols.swipeControlsResourcePatch">
|
||||
<string name="revanced_swipe_brightness_title">Ø§ŲØĒØŲŲ
Ø¨Ø§ŲØŗØˇŲØš ØšŲ ØˇØąŲŲ Ø§ŲŲ
Ø§ØĄØŠ Ø§ŲØĒŲ
ØąŲØą</string>
|
||||
@@ -490,9 +445,9 @@ Second \"item\" text"</string>
|
||||
|
||||
اØļØ¨Øˇ Ų
ØŗØĒŲŲ Ø§ŲØĩŲØĒ ØšŲ ØˇØąŲŲ Ø§ŲØĒŲ
ØąŲØą ØšŲ
ŲØ¯ŲŲØ§ ØšŲŲ Ø§ŲØŦØ§ŲØ¨ Ø§ŲØŖŲŲ
Ų Ų
Ų Ø§ŲØ´Ø§Ø´ØŠ"</string>
|
||||
<string name="revanced_swipe_volume_summary_off">ØĒŲ
ØĒØšØˇŲŲ Ø§ŲØĒŲ
ØąŲØą Ø§ŲØŗØąŲØš ŲØļØ¨Øˇ Ų
ØŗØĒŲŲ Ø§ŲØĩŲØĒ ŲŲ ŲØļØš Ų
ŲØĄ Ø§ŲØ´Ø§Ø´ØŠ</string>
|
||||
<string name="revanced_swipe_press_to_engage_title">ØĒŲ
ŲŲŲ ØĨŲŲ
Ø§ØĄØŠ Ø§ŲØļØēØˇ ŲŲØĒŲ
ØąŲØą</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_on">ŲØĒŲ
ØĒŲØ´ŲØˇ ØšŲØ§ØĩØą Ø§ŲØĒØŲŲ
ØšŲ ØˇØąŲŲ ØĨŲŲ
Ø§ØĄØŠ Ø§ŲØĒŲ
ØąŲØą ŲŲØˇ بØļØēØˇØŠ ØˇŲŲŲØŠ</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_off">ØĒŲØ´ŲØˇ ØšŲØ§ØĩØą Ø§ŲØĒØŲŲ
ØšŲ ØˇØąŲŲ ØĨŲŲ
Ø§ØĄØŠ Ø§ŲØĒŲ
ØąŲØą ØšŲد Ø§ŲØļØēØˇ Ų
Ø¨Ø§Ø´ØąØŠ</string>
|
||||
<string name="revanced_swipe_press_to_engage_title">ØĒŲ
ŲŲŲ Ø§ŲØļØēØˇ ØšŲŲ ØĨŲŲ
Ø§ØĄØŠ Ø§ŲØĒŲ
ØąŲØą Ø§ŲØŗØąŲØš</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_on">ØĒŲ
ØĒŲ
ŲŲŲ Ø§ŲØļØēØˇ ŲŲØĒŲ
ØąŲØą Ø§ŲØŗØąŲØš</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_off">ØĒŲ
ØĒØšØˇŲŲ Ø§ŲØļØēØˇ ŲŲØĒŲ
ØąŲØą Ø§ŲØŗØąŲØš</string>
|
||||
<string name="revanced_swipe_haptic_feedback_title">Ø§ŲØ§ŲØĒØ˛Ø§Ø˛ ØšŲØ¯ Ø§ŲØļØēØˇ</string>
|
||||
<string name="revanced_swipe_haptic_feedback_summary_on">ØĒŲ
ØĒŲ
ŲŲŲ Ø§ŲØ§ŲØĒØ˛Ø§Ø˛ ØšŲØ¯ Ø§ŲØļØēØˇ</string>
|
||||
<string name="revanced_swipe_haptic_feedback_summary_off">ØĒŲ
ØĒØšØˇŲŲ Ø§ŲØ§ŲØĒØ˛Ø§Ø˛ ØšŲØ¯ Ø§ŲØļØēØˇ</string>
|
||||
@@ -663,7 +618,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">ŲØĒŲ
ØšØąØļ ØĒذŲŲŲ ŲØ§ØĻŲ
ØŠ ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ</string>
|
||||
</patch>
|
||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||
<string name="revanced_hide_player_previous_next_buttons_title">ØĨØŽŲØ§ØĄ ØŖØ˛ØąØ§Øą اŲŲŲØ¯ŲŲ Ø§ŲØŗØ§Ø¨Ų & Ø§ŲØĒØ§ŲŲ</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_title">ØĨØŽŲØ§ØĄ Ø˛ØąŲ \"Ø§ŲØŗØ§Ø¨Ų\" Ų \"Ø§ŲØĒØ§ŲŲ\"</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_summary_on">ØĒŲ
ØĨØŽŲØ§ØĄ Ø§ŲØŖØ˛ØąØ§Øą</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_summary_off">ŲØĒŲ
ØšØąØļ Ø§ŲØŖØ˛ØąØ§Øą</string>
|
||||
<string name="revanced_hide_cast_button_title">ØĨØŽŲØ§ØĄ Ø˛Øą Ø§ŲØ¨ØĢ</string>
|
||||
@@ -856,7 +811,6 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_ryd_enable_summary_on">ŲØĒŲ
ØšØąØļ ŲŲ
ŲØšØŦبŲŲ</string>
|
||||
<string name="revanced_ryd_enable_summary_off">ŲØ§ ŲØĒŲ
ØšØąØļ ŲŲ
ŲØšØŦبŲŲ</string>
|
||||
<string name="revanced_ryd_shorts_title">ØšØąØļ ŲŲ
ŲØšØŦŲŲ ŲŲ ŲŲØ¯ŲŲŲØ§ØĒ Shorts</string>
|
||||
<string name="revanced_ryd_shorts_summary_on">ŲØĒŲ
ØšØąØļ ؚدŲ
Ø§ŲØĨØšØŦاب ØšŲŲ ŲŲØ¯ŲŲŲØ§ØĒ Shorts</string>
|
||||
<string name="revanced_ryd_shorts_summary_on_disclaimer">"ŲØĒŲ
ØšØąØļ Ų
ØąØ§ØĒ ؚدŲ
Ø§ŲØĨØšØŦاب ŲŲ ŲŲØ¯ŲŲŲØ§ØĒ Shorts
|
||||
|
||||
Ø§ŲØĒŲŲŲØ¯: ŲØ¯ ŲØ§ ØĒØ¸ŲØą Ų
ØąØ§ØĒ ؚدŲ
Ø§ŲØĨØšØŦاب ŲŲ ŲØļØš Ø§ŲØĒØĩŲØ اŲŲ
ØĒØŽŲŲ"</string>
|
||||
@@ -1054,6 +1008,8 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_sb_vote_downvote">اؚØĒØąØ§Øļ</string>
|
||||
<string name="revanced_sb_vote_category">ØĒØēŲŲØą Ø§ŲŲØĻØŠ</string>
|
||||
<string name="revanced_sb_vote_no_segments">ŲØ§ ØĒŲØŦد Ų
ŲØ§ØˇØš ŲŲØĒØĩŲŲØĒ ØšŲŲŲØ§</string>
|
||||
<!-- A segment start and end time, such as "02:10 to 03:40" -->
|
||||
<string name="revanced_sb_vote_segment_time_to_from">%1$s ØĨŲŲ %2$s</string>
|
||||
<string name="revanced_sb_new_segment_choose_category">ا؎ØĒŲØ§Øą ŲØĻØŠ Ø§ŲŲ
ŲØˇØš</string>
|
||||
<string name="revanced_sb_new_segment_disabled_category">اŲŲØĻØŠ Ų
ØšØˇŲØŠ ŲŲ Ø§ŲØĨؚداداØĒ. ØĒŲ
ŲŲŲ Ø§ŲŲØĻØŠ ŲŲØĨØąØŗØ§Ų.</string>
|
||||
<string name="revanced_sb_new_segment_title">Ų
ŲØˇØš SponsorBlock ØŦØ¯ŲØ¯</string>
|
||||
@@ -1101,6 +1057,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_sb_stats_saved_hour_format">%1$s ØŗØ§ØšØŠ %2$s دŲŲŲØŠ</string>
|
||||
<string name="revanced_sb_stats_saved_minute_format">%1$s دŲŲŲØŠ %2$s ØĢاŲŲØŠ</string>
|
||||
<string name="revanced_sb_stats_saved_second_format">%s ØĢاŲŲØŠ</string>
|
||||
<string name="revanced_sb_color_opacity_label">Ø§ŲØ´ŲاŲŲØŠ:</string>
|
||||
<string name="revanced_sb_color_dot_label">اŲŲŲŲ:</string>
|
||||
<string name="revanced_sb_color_changed">ØĒŲ
ØĒØēŲŲØą Ø§ŲŲŲŲ</string>
|
||||
<string name="revanced_sb_color_reset">ØĨؚاد؊ ØļØ¨Øˇ اŲŲŲŲ</string>
|
||||
@@ -1116,16 +1073,14 @@ Second \"item\" text"</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">"ØĒØĒØļŲ
Ų Ø§ŲØĒØēŲبਧØĒ:
|
||||
<string name="revanced_change_form_factor_user_dialog_message">"Ø§ŲØĒØēŲبਧØĒ ØĒØ´Ų
Ų:
|
||||
|
||||
ØĒØŽØˇŲØˇ Ø§ŲØŦŲØ§Ø˛ اŲŲŲØŲ
|
||||
âĸ ØĨØŽŲØ§ØĄ Ų
ŲØ´ŲØąØ§ØĒ اŲŲ
ØŦØĒŲ
Øš
|
||||
ØĒØĩŲ
ŲŲ
Ø§ŲØŦŲØ§Ø˛ اŲŲŲØŲ
|
||||
âĸ Ų
Ø´Ø§ØąŲØ§ØĒ اŲŲ
ØŦØĒŲ
Øš Ų
ØŽŲŲØŠ
|
||||
|
||||
ØĒØŽØˇŲØˇ Automotive
|
||||
âĸ ØĨØŽŲØ§ØĄ ŲØ§ØĻŲ
ØŠ ØŗØŦŲ Ø§ŲŲ
Ø´Ø§ŲØ¯ØŠ
|
||||
âĸ Ø§ØŗØĒؚاد؊ ØšŲØ§Ų
ØŠ Ø§ŲØĒØ¨ŲŲØ¨ \"Ø§ØŗØĒŲØ´Ø§Ų\"
|
||||
âĸ ŲØĒØ ŲŲØ¯ŲŲŲØ§ØĒ Shorts ŲŲ Ø§ŲŲ
Ø´ØēŲ Ø§ŲØšØ§Ø¯Ų
|
||||
âĸ ØĒŲØ¸ŲŲ
Ø§ŲØŽŲاØĩØŠ ØØŗØ¨ اŲŲ
ŲØļŲØšØ§ØĒ ŲØ§ŲŲŲØ§ØŠ"</string>
|
||||
ØĒØĩŲ
ŲŲ
Ø§ŲØŗŲØ§ØąØŠ
|
||||
âĸ ŲØĒŲ
ŲØĒØ Shorts ŲŲ Ø§ŲŲ
Ø´ØēŲ Ø§ŲØšØ§Ø¯Ų
|
||||
âĸ ŲØĒŲ
ØĒŲØ¸ŲŲ
Ø§ŲØŽŲاØĩØŠ ØØŗØ¨ اŲŲ
ŲØ§ØļŲØš ŲØ§ŲŲŲŲØ§ØĒ"</string>
|
||||
</patch>
|
||||
<patch id="layout.spoofappversion.spoofAppVersionPatch">
|
||||
<string name="revanced_spoof_app_version_title">ØŽŲØ¯Ø§Øš ØĨØĩØ¯Ø§Øą Ø§ŲØĒØˇØ¨ŲŲ</string>
|
||||
@@ -1140,12 +1095,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 -->
|
||||
<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_2">19.26.42 - Ø§ØŗØĒؚاد؊ ØŖŲŲŲŲØ§ØĒ Ø§ŲØĒŲŲŲ Ø§ŲŲØ¯ŲŲ
ØŠ</string>
|
||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - Ø§ØŗØĒؚاد؊ RYD ØšŲŲ Shorts Ø¨ŲØļØš Ø§ŲØĒØŽŲŲ</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - Ø§ØŗØĒؚاد؊ ŲØ§ØĻŲ
ØŠ ØŗØąØšØŠ اŲŲŲØ¯ŲŲ Ø§ŲØšØąŲØļØŠ & Ø§ŲØŦŲØ¯ØŠ</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - Ø§ØŗØĒؚاد؊ ØšŲØ§Ų
ØŠ ØĒبŲŲØ¨ اŲŲ
ŲØĒØ¨ØŠ</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - Ø§ØŗØĒؚاد؊ ØąŲ ŲØ§ØĻŲ
ØŠ Ø§ŲØĒØ´ØēŲŲ Ø§ŲŲØ¯ŲŲ
</string>
|
||||
<string name="revanced_spoof_app_version_target_entry_2">19.01.34 - Ø§ØŗØĒؚاد؊ ØŖŲŲŲŲØ§ØĒ Ø§ŲØĒŲŲŲ Ø§ŲŲØ¯ŲŲ
ØŠ</string>
|
||||
</patch>
|
||||
<patch id="layout.startpage.changeStartPagePatch">
|
||||
<string name="revanced_change_start_page_title">ØĒØšŲŲŲ ØĩŲØØŠ Ø§ŲØ¨Ø¯Ø§ŲØŠ</string>
|
||||
@@ -1248,8 +1198,6 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_gradient_loading_screen_title">ØĒŲ
ŲŲŲ Ø´Ø§Ø´ØŠ Ø§ŲØĒØŲ
ŲŲ Ø§ŲŲ
ØĒØ¯ØąØŦØŠ</string>
|
||||
<string name="revanced_gradient_loading_screen_summary_on">ØŗØĒØØĒŲŲ Ø´Ø§Ø´ØŠ Ø§ŲØĒØŲ
ŲŲ ØšŲŲ ØŽŲŲŲØŠ Ų
ØĒØ¯ØąØŦØŠ</string>
|
||||
<string name="revanced_gradient_loading_screen_summary_off">ØŗØĒØØĒŲŲ Ø´Ø§Ø´ØŠ Ø§ŲØĒØŲ
ŲŲ ØšŲŲ ØŽŲŲŲØŠ ØĢابØĒØŠ</string>
|
||||
</patch>
|
||||
<patch id="layout.theme.themeResourcePatch">
|
||||
<string name="revanced_seekbar_custom_color_title">ØĒŲ
ŲŲŲ ŲŲŲ Ø´ØąŲØˇ ØĒŲØ¯Ų
اŲŲŲØ¯ŲŲ Ø§ŲŲ
ØŽØĩØĩ</string>
|
||||
<string name="revanced_seekbar_custom_color_summary_on">ŲØĒŲ
ØšØąØļ ŲŲŲ Ø´ØąŲØˇ ØĒŲØ¯Ų
اŲŲŲØ¯ŲŲ Ø§ŲŲ
ØŽØĩØĩ</string>
|
||||
<string name="revanced_seekbar_custom_color_summary_off">ŲØĒŲ
ØšØąØļ ŲŲŲ Ø´ØąŲØˇ ØĒŲØ¯Ų
اŲŲŲØ¯ŲŲ Ø§ŲØ§ØĩŲŲ</string>
|
||||
@@ -1341,8 +1289,8 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="misc.links.openLinksExternallyPatch">
|
||||
<string name="revanced_external_browser_title">ŲØĒØ Ø§ŲØąŲØ§Ø¨Øˇ ŲŲ Ø§ŲŲ
ØĒØĩŲØ</string>
|
||||
<string name="revanced_external_browser_summary_on">ŲØĒØ Ø§ŲØąŲØ§Ø¨Øˇ ØŽØ§ØąØŦŲŲØ§</string>
|
||||
<string name="revanced_external_browser_summary_off">ŲØĒØ Ø§ŲØąŲØ§Ø¨Øˇ ŲŲ Ø§ŲØĒØˇØ¨ŲŲ</string>
|
||||
<string name="revanced_external_browser_summary_on">ŲØĒØ Ø§ŲØąŲØ§Ø¨Øˇ ŲŲ Ų
ØĒØĩŲØ ØŽØ§ØąØŦŲ</string>
|
||||
<string name="revanced_external_browser_summary_off">ŲØĒØ Ø§ŲØąŲØ§Ø¨Øˇ ŲŲ Ų
ØĒØĩŲØ Ø¯Ø§ØŽŲ Ø§ŲØĒØˇØ¨ŲŲ</string>
|
||||
</patch>
|
||||
<patch id="misc.privacy.removeTrackingQueryParameterPatch">
|
||||
<string name="revanced_remove_tracking_query_parameter_title">ØĨØ˛Ø§ŲØŠ Ų
ØšŲŲ
ØŠ ØĒØĒبؚ Ø§ŲØ§ØŗØĒØšŲØ§Ų
</string>
|
||||
@@ -1355,6 +1303,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_disable_zoom_haptics_summary_off">ØĒŲ
ØĒŲ
ŲŲŲ Ø§ŲØ§ŲØĒØ˛Ø§Ø˛</string>
|
||||
</patch>
|
||||
<patch id="video.audio.forceOriginalAudioPatch">
|
||||
<string name="revanced_force_original_audio_title">ŲØąØļ ŲØēØŠ Ø§ŲØĩŲØĒ Ø§ŲØŖØĩŲŲØŠ</string>
|
||||
<string name="revanced_force_original_audio_summary_on">Ø§ØŗØĒ؎داŲ
ŲØēØŠ Ø§ŲØĩŲØĒ Ø§ŲØŖØĩŲŲØŠ</string>
|
||||
<string name="revanced_force_original_audio_summary_off">Ø§ØŗØĒ؎داŲ
Ø§ŲØĩŲØĒ Ø§ŲØ§ŲØĒØąØ§ØļŲ</string>
|
||||
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||
@@ -1368,9 +1317,15 @@ Second \"item\" text"</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_mobile_title">ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ Ø§ŲØ§ŲØĒØąØ§ØļŲØŠ ØšŲŲ Ø´Ø¨ŲØŠ Ø§ŲØŦŲŲŲØ§Ų</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_title">ØĒØ°ŲØą ØĒØēŲبਧØĒ ØŦŲØ¯ØŠ Shorts</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_summary_on">ØĒŲØˇØ¨Ų ØĒØēŲبਧØĒ Ø§ŲØŦŲØ¯ØŠ ØšŲŲ ØŦŲ
ŲØš ŲŲØ¯ŲŲŲØ§ØĒ Shorts</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_summary_off">ØĒŲØˇØ¨Ų ØĒØēŲبਧØĒ Ø§ŲØŦŲØ¯ØŠ ŲŲØˇ ØšŲŲ ŲŲØ¯ŲŲ Short Ø§ŲØØ§ŲŲ</string>
|
||||
<string name="revanced_shorts_quality_default_wifi_title">ØŦŲØ¯ØŠ Shorts Ø§ŲØ§ŲØĒØąØ§ØļŲØŠ ØšŲŲ Ø´Ø¨ŲØŠ Wi-Fi</string>
|
||||
<string name="revanced_shorts_quality_default_mobile_title">ØŦŲØ¯ØŠ Shorts Ø§ŲØ§ŲØĒØąØ§ØļŲØŠ ØšŲŲ Ø´Ø¨ŲØŠ Ø§ŲØŦŲØ§Ų</string>
|
||||
<string name="revanced_remember_video_quality_mobile">Ø§ŲØŦŲŲØ§Ų</string>
|
||||
<string name="revanced_remember_video_quality_wifi">Wi-Fi</string>
|
||||
<string name="revanced_remember_video_quality_toast">ØĒŲ
ØĒØēŲŲØą ØŦŲØ¯ØŠ %1$s Ø§ŲØ§ŲØĒØąØ§ØļŲØŠ ØĨŲŲ: %2$s</string>
|
||||
<string name="revanced_remember_video_quality_toast_shorts">ØĒŲ
ØĒØēŲŲØą ØŦŲØ¯ØŠ Shorts %1$s ØĨŲŲ: %2$s</string>
|
||||
</patch>
|
||||
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
||||
<string name="revanced_playback_speed_dialog_button_title">ØšØąØļ Ø˛Øą Ų
ØąØ¨Øš ØŲØ§Øą Ø§ŲØŗØąØšØŠ</string>
|
||||
@@ -1401,10 +1356,10 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_disable_hdr_video_summary_on">ØĒŲ
ØĒØšØˇŲŲ ŲŲØ¯ŲŲ HDR</string>
|
||||
<string name="revanced_disable_hdr_video_summary_off">ØĒŲ
ØĒŲ
ŲŲŲ ŲŲØ¯ŲŲ HDR</string>
|
||||
</patch>
|
||||
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch">
|
||||
<string name="revanced_restore_old_video_quality_menu_title">Ø§ØŗØĒؚاد؊ ŲØ§ØĻŲ
ØŠ ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ Ø§ŲŲØ¯ŲŲ
ØŠ</string>
|
||||
<string name="revanced_restore_old_video_quality_menu_summary_on">ŲØĒŲ
ØšØąØļ ŲØ§ØĻŲ
ØŠ ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ Ø§ŲŲØ¯ŲŲ
ØŠ</string>
|
||||
<string name="revanced_restore_old_video_quality_menu_summary_off">ŲØ§ ŲØĒŲ
ØšØąØļ ŲØ§ØĻŲ
ØŠ ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ Ø§ŲŲØ¯ŲŲ
ØŠ</string>
|
||||
<patch id="video.quality.advancedVideoQualityMenuPatch">
|
||||
<string name="revanced_advanced_video_quality_menu_title">ØĨØ¸ŲØ§Øą ŲØ§ØĻŲ
ØŠ ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ Ø§ŲŲ
ØĒŲØ¯Ų
ØŠ</string>
|
||||
<string name="revanced_advanced_video_quality_menu_summary_on">ŲØĒŲ
ØšØąØļ ŲØ§ØĻŲ
ØŠ ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ Ø§ŲŲ
ØĒŲØ¯Ų
ØŠ</string>
|
||||
<string name="revanced_advanced_video_quality_menu_summary_off">ŲØ§ ŲØĒŲ
ØšØąØļ ŲØ§ØĻŲ
ØŠ ØŦŲØ¯ØŠ اŲŲŲØ¯ŲŲ Ø§ŲŲ
ØĒŲØ¯Ų
ØŠ</string>
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
||||
<string name="revanced_slide_to_seek_title">ØĒŲ
ŲŲŲ Ø§ŲØĒŲ
ØąŲØą ŲŲØĒŲØ¯ŲŲ
ØŖŲ Ø§ŲØĒØąØŦŲØš</string>
|
||||
|
||||
@@ -50,9 +50,9 @@ Second \"item\" text"</string>
|
||||
This button usually appears when searching for a YT creator. -->
|
||||
<!-- https://logos.fandom.com/wiki/YouTube/Yoodles -->
|
||||
<!-- 'Component path builder strings' is the technical name for identifying the Litho UI layout items to hide. This is an advanced feature and most users will never use this. -->
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
<!-- For localization, it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc.) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
<patch id="ad.general.hideAdsResourcePatch">
|
||||
@@ -156,6 +156,7 @@ Second \"item\" text"</string>
|
||||
<patch id="layout.sponsorblock.sponsorBlockResourcePatch">
|
||||
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<!-- A segment start and end time, such as "02:10 to 03:40" -->
|
||||
<!-- Shown in the settings preferences, and translations can be any text length. -->
|
||||
</patch>
|
||||
<patch id="layout.formfactor.changeFormFactorPatch">
|
||||
@@ -163,7 +164,6 @@ Second \"item\" text"</string>
|
||||
<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'.
|
||||
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
|
||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
||||
</patch>
|
||||
<patch id="layout.startpage.changeStartPagePatch">
|
||||
</patch>
|
||||
@@ -177,8 +177,6 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="layout.theme.themePatch">
|
||||
</patch>
|
||||
<patch id="layout.theme.themeResourcePatch">
|
||||
</patch>
|
||||
<patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch">
|
||||
</patch>
|
||||
<patch id="layout.thumbnails.alternativeThumbnailsPatch">
|
||||
@@ -221,7 +219,7 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="video.hdr.disableHdrPatch">
|
||||
</patch>
|
||||
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch">
|
||||
<patch id="video.quality.advancedVideoQualityMenuPatch">
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
||||
</patch>
|
||||
|
||||
@@ -48,57 +48,6 @@ Second \"item\" text"</string>
|
||||
|
||||
Yeni dillÉri tÉrcÃŧmÉ etmÉk ÃŧçÃŧn translate.revanced.app 'É daxil olun"</string>
|
||||
<string name="revanced_language_DEFAULT">TÉtbiq dili</string>
|
||||
<string name="revanced_language_AR">ÆrÉbcÉ</string>
|
||||
<string name="revanced_language_AZ">AzÉrbaycanca</string>
|
||||
<string name="revanced_language_BG">Bolqarca</string>
|
||||
<string name="revanced_language_BN">Benqalca</string>
|
||||
<string name="revanced_language_CA">Katalan dili</string>
|
||||
<string name="revanced_language_CS">ÃexcÉ</string>
|
||||
<string name="revanced_language_DA">Dan dili</string>
|
||||
<string name="revanced_language_DE">Almanca</string>
|
||||
<string name="revanced_language_EL">Yunanca</string>
|
||||
<string name="revanced_language_EN">İngiliscÉ</string>
|
||||
<string name="revanced_language_ES">İspanca</string>
|
||||
<string name="revanced_language_ET">Estonca</string>
|
||||
<string name="revanced_language_FA">Farsca</string>
|
||||
<string name="revanced_language_FI">FincÉ</string>
|
||||
<string name="revanced_language_FR">FransÄązca</string>
|
||||
<string name="revanced_language_GU">QÃŧcÉrat dili</string>
|
||||
<string name="revanced_language_HI">HindcÉ</string>
|
||||
<string name="revanced_language_HR">Xorvatca</string>
|
||||
<string name="revanced_language_HU">Macarca</string>
|
||||
<string name="revanced_language_ID">İndoneziya dili</string>
|
||||
<string name="revanced_language_IT">İtalyanca</string>
|
||||
<string name="revanced_language_JA">Yaponca</string>
|
||||
<string name="revanced_language_KK">Qazax dili</string>
|
||||
<string name="revanced_language_KO">Koreya dili</string>
|
||||
<string name="revanced_language_LT">Litva Dili</string>
|
||||
<string name="revanced_language_LV">Letonca</string>
|
||||
<string name="revanced_language_MK">Makedon Dili</string>
|
||||
<string name="revanced_language_MN">Monqolca</string>
|
||||
<string name="revanced_language_MR">Marathi dili</string>
|
||||
<string name="revanced_language_MS">Malay dili</string>
|
||||
<string name="revanced_language_MY">Birmanca</string>
|
||||
<string name="revanced_language_NL">Hollandca</string>
|
||||
<string name="revanced_language_OR">Oriya dili</string>
|
||||
<string name="revanced_language_PA">PÉncabca</string>
|
||||
<string name="revanced_language_PL">Polyak dili</string>
|
||||
<string name="revanced_language_PT">Portuqal dili</string>
|
||||
<string name="revanced_language_RO">RumÄąnca</string>
|
||||
<string name="revanced_language_RU">Rusca</string>
|
||||
<string name="revanced_language_SK">Slovak dili</string>
|
||||
<string name="revanced_language_SL">SlovencÉ</string>
|
||||
<string name="revanced_language_SR">SerbcÉ</string>
|
||||
<string name="revanced_language_SV">İsveçcÉ</string>
|
||||
<string name="revanced_language_SW">Suahili dili</string>
|
||||
<string name="revanced_language_TA">TamilcÉ</string>
|
||||
<string name="revanced_language_TE">Teluqu dili</string>
|
||||
<string name="revanced_language_TH">Tayca</string>
|
||||
<string name="revanced_language_TR">TÃŧrkcÉ</string>
|
||||
<string name="revanced_language_UK">Ukrayna dili</string>
|
||||
<string name="revanced_language_UR">Urdu dili</string>
|
||||
<string name="revanced_language_VI">Vyetnamca</string>
|
||||
<string name="revanced_language_ZH">ÃincÉ</string>
|
||||
<string name="revanced_pref_import_export_title">İdxal/İxrac et</string>
|
||||
<string name="revanced_pref_import_export_summary">ReVanced tÉnzimlÉmÉlÉrin idxal/ixrac et</string>
|
||||
<!-- Settings about dialog. -->
|
||||
@@ -278,12 +227,12 @@ GÃļzlÉnilmÉz hallardan xÉbÉrdar olmayacaqsÄąnÄąz."</string>
|
||||
<string name="revanced_hide_artist_cards_summary_on">SÉnÉtçi kartlarÄą gizlidir</string>
|
||||
<string name="revanced_hide_artist_cards_summary_off">SÉnÉtçi kartlarÄą gÃļstÉrilir</string>
|
||||
<string name="revanced_hide_attributes_section_title">AtributlarÄą GizlÉt</string>
|
||||
<string name="revanced_hide_attributes_section_summary_on">SeçilÉn mÉkanlar, Oyunlar, Musiqi vÉ qeyd edilÉn insanlar bÃļlmÉlÉri gizlÉdilir</string>
|
||||
<string name="revanced_hide_attributes_section_summary_off">SeçilÉn mÉkanlar, Oyunlar, Musiqi vÉ qeyd edilÉn insanlar bÃļlmÉlÉri gÃļrÃŧnÃŧr</string>
|
||||
<string name="revanced_hide_attributes_section_summary_on">SeçilÉn yerlÉr, Oyunlar, Musiqi vÉ qeyd edilÉn insanlar bÃļlmÉlÉri gizlÉdilir</string>
|
||||
<string name="revanced_hide_attributes_section_summary_off">SeçilÉn yerlÉr, Oyunlar, Musiqi vÉ qeyd edilÉn insanlar bÃļlmÉlÉri gÃļrÃŧnÃŧr</string>
|
||||
<string name="revanced_hide_chapters_section_title">FÉsillÉri GizlÉt</string>
|
||||
<string name="revanced_hide_chapters_section_summary_on">BÃļlÃŧmlÉr bÃļlmÉsi gizlidir</string>
|
||||
<string name="revanced_hide_chapters_section_summary_off">BÃļlÃŧmlÉr bÃļlmÉsi gÃļstÉrilir</string>
|
||||
<string name="revanced_hide_how_this_was_made_section_title">\'Bu mÉzmun necÉ hazÄąrlanÄąb\'Äą GizlÉt</string>
|
||||
<string name="revanced_hide_how_this_was_made_section_title">\'Bu kontent necÉ hazÄąrlanÄąb\'Äą GizlÉt</string>
|
||||
<string name="revanced_hide_how_this_was_made_section_summary_on">Bu mÉzmunun necÉ hazÄąrlandÄąÄÄą bÃļlmÉsi gizlidir</string>
|
||||
<string name="revanced_hide_how_this_was_made_section_summary_off">Bu mÉzmunun necÉ hazÄąrlandÄąÄÄą bÃļlmÉsi gÃļrÃŧnÃŧr</string>
|
||||
<string name="revanced_hide_podcast_section_title">\'PodkastÄą araÅdÄąrÄąn\"-Äą GizlÉt</string>
|
||||
@@ -292,14 +241,14 @@ GÃļzlÉnilmÉz hallardan xÉbÉrdar olmayacaqsÄąnÄąz."</string>
|
||||
<string name="revanced_hide_info_cards_section_title">MÉlumat KartlarÄąnÄą GizlÉt</string>
|
||||
<string name="revanced_hide_info_cards_section_summary_on">MÉlumat kartlarÄą bÃļlmÉsi gizlÉdilir</string>
|
||||
<string name="revanced_hide_info_cards_section_summary_off">MÉlumat kartlarÄą bÃļlmÉsi gÃļstÉrilir</string>
|
||||
<string name="revanced_hide_key_concepts_section_title">\"Æsas anlayÄąÅlarÄą\" gizlÉt</string>
|
||||
<string name="revanced_hide_key_concepts_section_summary_on">Æsas anlayÄąÅlar bÃļlmÉsi gizlidir</string>
|
||||
<string name="revanced_hide_key_concepts_section_summary_off">Æsas anlayÄąÅlar bÃļlmÉsi gÃļrÃŧnÃŧr</string>
|
||||
<string name="revanced_hide_key_concepts_section_title">\"Æsas konseptlÉr-i\" gizlÉt</string>
|
||||
<string name="revanced_hide_key_concepts_section_summary_on">Æsas konseptlÉr bÃļlmÉsi gizlidir</string>
|
||||
<string name="revanced_hide_key_concepts_section_summary_off">Æsas konseptlÉr bÃļlmÉsi gÃļrÃŧnÃŧr</string>
|
||||
<string name="revanced_hide_transcript_section_title">Transkript-i GizlÉt</string>
|
||||
<string name="revanced_hide_transcript_section_summary_on">Transkripsiya bÃļlmÉsi gizlidir</string>
|
||||
<string name="revanced_hide_transcript_section_summary_off">Transkripsiya bÃļlmÉsi gÃļstÉrilir</string>
|
||||
<string name="revanced_hide_description_components_screen_title">Video aÃ§ÄąqlamasÄą</string>
|
||||
<string name="revanced_hide_description_components_screen_summary">Video aÃ§ÄąqlamasÄą elementlÉrini gizlÉt vÉ ya gÃļstÉr</string>
|
||||
<string name="revanced_hide_description_components_screen_title">Video tÉsviri</string>
|
||||
<string name="revanced_hide_description_components_screen_summary">Video tÉsviri elementlÉrini gizlÉt vÉ ya gÃļstÉr</string>
|
||||
<string name="revanced_hide_filter_bar_screen_title">Filtr çubuÄu</string>
|
||||
<string name="revanced_hide_filter_bar_screen_summary">AxÄąnda, axtarÄąÅ nÉticÉlÉrindÉ vÉ ÉlaqÉli videolarda filtr cÉrgÉsin gizlÉt vÉ ya gÃļstÉr</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_feed_title">AxÄąnda gizlÉt</string>
|
||||
@@ -313,9 +262,8 @@ GÃļzlÉnilmÉz hallardan xÉbÉrdar olmayacaqsÄąnÄąz."</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">ÆlaqÉli videolarda gÃļrÃŧnÃŧr</string>
|
||||
<string name="revanced_comments_screen_title">ÅÉrhlÉr</string>
|
||||
<string name="revanced_comments_screen_summary">ÅÉrhlÉr bÃļlmÉsi elementlÉrin gizlÉt vÉ ya gÃļstÉr</string>
|
||||
<string name="revanced_hide_comments_chat_summary_title">\'SÃļhbÉt yekunun\' GizlÉt</string>
|
||||
<string name="revanced_hide_comments_chat_summary_summary_on">SÃļhbÉt yekunu gizlidir </string>
|
||||
<string name="revanced_hide_comments_chat_summary_summary_off">SÃļhbÉt yekunu gÃļrÃŧnÃŧr</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_on">SÃļhbÉt yekunu gizlidir </string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_off">SÃļhbÉt yekunu gÃļrÃŧnÃŧr</string>
|
||||
<string name="revanced_hide_comments_by_members_header_title">\'ÃzvlÉrin ÅÉrhlÉri\' baÅlÄąÄÄąnÄą gizlÉt</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_on">ÃzvlÉrin ÅÉrhlÉri baÅlÄąÄÄą gizlidir</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_off">ÃzvlÉrin ÅÉrhlÉri baÅlÄąÄÄą gÃļrÃŧnÃŧr</string>
|
||||
@@ -362,7 +310,7 @@ GÃļzlÉnilmÉz hallardan xÉbÉrdar olmayacaqsÄąnÄąz."</string>
|
||||
<string name="revanced_hide_keyword_content_subscriptions_summary_on">AbunÉliklÉr bÃļlmÉsindÉki videolar açar sÃļzlÉrlÉ filtrlÉnir</string>
|
||||
<string name="revanced_hide_keyword_content_subscriptions_summary_off">AbunÉliklÉr bÃļlmÉsindÉki videolar açar sÃļzlÉrlÉ filtrlÉnmir</string>
|
||||
<string name="revanced_hide_keyword_content_phrases_title">GizlÉdilÉcÉk açar sÃļzlÉr</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
<!-- For localization, it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">"Yeni sÉtirlÉrlÉ ayrÄąlan, gizlÉdilÉcÉk açar sÃļzlÉr vÉ ifadÉlÉr
|
||||
|
||||
@@ -377,7 +325,7 @@ MÉhdudiyyÉtlÉr
|
||||
âĸ BÉzi UI hissÉciklÉri gizlÉnÉ bilmÉz
|
||||
âĸ Açar sÃļz axtarma nÉticÉ vermÉyÉ bilÉr"</string>
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_title">BÃŧtÃŧn sÃļzlÉri uyÄunlaÅdÄąr</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc.) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_summary">Açar sÃļz/frazanÄąn qoÅa dÄąrnaqlarla ÉhatÉ olunmasÄą video adlarÄą vÉ kanal adlarÄąnÄąn qismÉn uyÄunlaÅmasÄąna mane olacaq <br><br>MÉsÉlÉn,<br><b>\"ai\"</b> videonu gizlÉdÉcÉk:<b>How does AI work?</b><br> lakin gizlÉtmÉyÉcÉk: DÃŧzgÃŧn;<b>What does fair use mean?</b></string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Açar sÃļz istifadÉ edilÉ bilmir: %s</string>
|
||||
@@ -404,7 +352,7 @@ Bu xÃŧsusiyyÉt yalnÄąz kÃļhnÉ cihazlar ÃŧçÃŧn mÃļvcuddur"</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_title">Ãz-sponsorlu kartlarÄą gizlÉt</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_on">ÃzÃŧnÉ sponsorluq edilÉn kartlar gizlidir</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_off">ÃzÃŧnÉ sponsorluq edilÉn kartlar gÃļstÉrilir</string>
|
||||
<string name="revanced_hide_products_banner_title">MÉhsullara baxma etiketin gizlÉt</string>
|
||||
<string name="revanced_hide_products_banner_title">\"MÉhsullara baxÄąn\" etiketin gizlÉt</string>
|
||||
<string name="revanced_hide_products_banner_summary_on">Etiket gizlÉdilib</string>
|
||||
<string name="revanced_hide_products_banner_summary_off">Etiket gÃļstÉrilir</string>
|
||||
<string name="revanced_hide_end_screen_store_banner_title">Son ekran maÄaza etiketini gizlÉt</string>
|
||||
@@ -475,9 +423,6 @@ Bu xÃŧsusiyyÉt yalnÄąz kÃļhnÉ cihazlar ÃŧçÃŧn mÃļvcuddur"</string>
|
||||
<string name="revanced_disable_precise_seeking_gesture_summary_off">Jest aktivlÉÅdirilib</string>
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSeekbarTappingPatch">
|
||||
<string name="revanced_seekbar_tapping_title">İrÉlilÉmÉ cizgisi toxunmasÄąnÄą aktivlÉÅdir</string>
|
||||
<string name="revanced_seekbar_tapping_summary_on">İrÉlilÉyiÅ cizgisi toxunmasÄą aktivdir</string>
|
||||
<string name="revanced_seekbar_tapping_summary_off">İrÉlilÉyiÅ cizgisi toxunmasÄą qapalÄądÄąr</string>
|
||||
</patch>
|
||||
<patch id="interaction.swipecontrols.swipeControlsResourcePatch">
|
||||
<string name="revanced_swipe_brightness_title">ParlaqlÄąq jestini aktivlÉÅdir</string>
|
||||
@@ -490,9 +435,6 @@ EkranÄąn sol tÉrÉfindÉ dikinÉ sÃŧrÃŧÅdÃŧrÉrÉk parlaqlÄąÄÄą tÉnzimlÉyin
|
||||
|
||||
EkranÄąn saÄ tÉrÉfindÉ dÃŧzÃŧnÉ sÃŧrÃŧÅdÃŧrÉrÉk sÉs sÉviyyÉsini tÉnzimlÉ"</string>
|
||||
<string name="revanced_swipe_volume_summary_off">Tam ekran sÉs sÃŧrÃŧÅdÃŧrmÉsi qapalÄądÄąr</string>
|
||||
<string name="revanced_swipe_press_to_engage_title">BasÄąb sÃŧrÃŧÅdÃŧrmÉ jestini aktivlÉÅdir</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_on">SÃŧrÃŧÅdÃŧrmÉk ÃŧçÃŧn basma aktivdir</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_off">SÃŧrÃŧÅdÃŧrmÉk ÃŧçÃŧn basma qeyri-aktivdir</string>
|
||||
<string name="revanced_swipe_haptic_feedback_title">Æks-ÉlaqÉ reaksiyasÄąnÄą aktivlÉÅdir</string>
|
||||
<string name="revanced_swipe_haptic_feedback_summary_on">Æks-ÉlaqÉ reaksiyasÄą aktivlÉÅdirilib</string>
|
||||
<string name="revanced_swipe_haptic_feedback_summary_off">Æks-ÉlaqÉ reaksiyasÄą qeyri-aktivdir</string>
|
||||
@@ -663,7 +605,7 @@ Bu seçimi dÉyiÅdirmÉ iÅÉ dÃŧÅmÃŧrsÉ, Gizli rejimÉ keçmÉyÉ Ã§alÄąÅÄą
|
||||
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">Video keyfiyyÉt menyusu alt mÉlumatÄą gÃļstÉrilir</string>
|
||||
</patch>
|
||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||
<string name="revanced_hide_player_previous_next_buttons_title">ÆvvÉlki/nÃļvbÉti video dÃŧymÉlÉrin gizlÉt</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_title">ÆvvÉlki vÉ NÃļvbÉti dÃŧymÉlÉrin gizlÉt</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_summary_on">DÃŧymÉlÉr gizlidir</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_summary_off">DÃŧymÉlÉr gÃļstÉrilir</string>
|
||||
<string name="revanced_hide_cast_button_title">YayÄąmla dÃŧymÉsini gizlÉt</string>
|
||||
@@ -855,7 +797,6 @@ Avtomatik oynatma YouTube ayarlarÄąnda dÉyiÅdirilÉ bilÉr: Ayarlar â Oxunu
|
||||
<string name="revanced_ryd_enable_summary_on">BÉyÉnmÉmÉlÉr gÃļstÉrilir</string>
|
||||
<string name="revanced_ryd_enable_summary_off">BÉyÉnmÉmÉlÉr gÃļstÉrilmir</string>
|
||||
<string name="revanced_ryd_shorts_title">\"Shorts\"da bÉyÉnmÉmÉ sayÄąnÄą gÃļstÉr</string>
|
||||
<string name="revanced_ryd_shorts_summary_on">BÉyÉnmÉmÉlÉr Shorts-da gÃļstÉrilir</string>
|
||||
<string name="revanced_ryd_shorts_summary_on_disclaimer">"BÉyÉnmÉmÉlÉr Shorts-da gÃļstÉrilir
|
||||
|
||||
MÉhdudiyyÉt: BÉyÉnmÉmÉlÉr gizli rejimdÉ gÃļrÃŧnmÉyÉ bilÉr"</string>
|
||||
@@ -1053,6 +994,8 @@ ArtÄąq mÃļvcuddur"</string>
|
||||
<string name="revanced_sb_vote_downvote">MÉnfi sÉs</string>
|
||||
<string name="revanced_sb_vote_category">KateqoriyanÄą dÉyiÅdir</string>
|
||||
<string name="revanced_sb_vote_no_segments">SÉsvermÉ ÃŧçÃŧn bÃļlÃŧm yoxdur</string>
|
||||
<!-- A segment start and end time, such as "02:10 to 03:40" -->
|
||||
<string name="revanced_sb_vote_segment_time_to_from">%1$s - %2$s</string>
|
||||
<string name="revanced_sb_new_segment_choose_category">BÃļlÃŧm kateqoriyasÄąnÄą seçin</string>
|
||||
<string name="revanced_sb_new_segment_disabled_category">SeçimlÉrdÉ kateqoriya qeyri-aktivdir. GÃļndÉrmÉk ÃŧçÃŧn kateqoriyanÄą aktiv et.</string>
|
||||
<string name="revanced_sb_new_segment_title">Yeni SponsorBlock bÃļlÃŧmÃŧ</string>
|
||||
@@ -1100,6 +1043,7 @@ TÉqdim etmÉyÉ hazÄąrdÄąr?"</string>
|
||||
<string name="revanced_sb_stats_saved_hour_format">%1$s saat %2$s dÉqiqÉ</string>
|
||||
<string name="revanced_sb_stats_saved_minute_format">%1$s dÉqiqÉ %2$s saniyÉ</string>
|
||||
<string name="revanced_sb_stats_saved_second_format">%s saniyÉ</string>
|
||||
<string name="revanced_sb_color_opacity_label">Qeyri-ÅÉffaflÄąq:</string>
|
||||
<string name="revanced_sb_color_dot_label">RÉng:</string>
|
||||
<string name="revanced_sb_color_changed">RÉng dÉyiÅdirildi</string>
|
||||
<string name="revanced_sb_color_reset">RÉngi sÄąfÄąrla</string>
|
||||
@@ -1115,16 +1059,14 @@ TÉqdim etmÉyÉ hazÄąrdÄąr?"</string>
|
||||
<string name="revanced_change_form_factor_entry_2">Telefon</string>
|
||||
<string name="revanced_change_form_factor_entry_3">PlanÅet</string>
|
||||
<string name="revanced_change_form_factor_entry_4">Avtomobil</string>
|
||||
<string name="revanced_change_form_factor_user_dialog_message">"DÉyiÅikliklÉrÉ daxildir:
|
||||
<string name="revanced_change_form_factor_user_dialog_message">"DÉyiÅikliklÉr ehtiva edir:
|
||||
|
||||
PlanÅet tÉrtibatÄą
|
||||
âĸ İcma elanlarÄą gizlidir
|
||||
âĸ İcma elanlarÄą gizlÉdilib
|
||||
|
||||
Avtomobil tÉrtibatÄą
|
||||
âĸ BaxÄąÅ tarixçÉsi seçimi gizlidir
|
||||
âĸ \"KÉÅf et\" bÃļlmÉsi qaytarÄąlÄąb
|
||||
âĸ Shorts daimi oynadÄącÄąda aÃ§ÄąlÄąr
|
||||
âĸ AxÄąn mÃļvzulara vÉ kanala gÃļrÉ hazÄąrlanÄąb"</string>
|
||||
âĸ Shorts mÃŧntÉzÉm oynadÄącÄąda aÃ§ÄąlÄąr
|
||||
âĸ AxÄąn mÃļvzular vÉ kanallardan ibarÉtdir"</string>
|
||||
</patch>
|
||||
<patch id="layout.spoofappversion.spoofAppVersionPatch">
|
||||
<string name="revanced_spoof_app_version_title">TÉtbiq versiyasÄąnÄą saxtalaÅdÄąr</string>
|
||||
@@ -1139,12 +1081,7 @@ Sonradan qapadÄąlarsa, UI sÉhvlÉrin ÃļnlÉmÉk ÃŧçÃŧn tÉtbiq mÉlumatlarÄąn
|
||||
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
|
||||
<string name="revanced_spoof_app_version_target_title">Saxta tÉtbiq versiyasÄą hÉdÉfi</string>
|
||||
<string name="revanced_spoof_app_version_target_entry_1">19.35.36 - KÃļhnÉ Shorts oynadÄącÄą iÅarÉlÉrin bÉrpa et</string>
|
||||
<string name="revanced_spoof_app_version_target_entry_2">19.26.42 - KÃļhnÉ fÉaliyyÉt simvollarÄąn bÉrpa et</string>
|
||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - Shorts gizli rejimindÉ RYD-ni bÉrpa et</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - GeniÅ video sÃŧrÉti & keyfiyyÉt menyusunu bÉrpa et</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - Kitabxana panelini bÉrpa et</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - KÃļhnÉ pleylist bÃļlmÉsin bÉrpa et</string>
|
||||
<string name="revanced_spoof_app_version_target_entry_2">19.01.34 - KÃļhnÉ fÉaliyyÉt simvollarÄąn bÉrpa et</string>
|
||||
</patch>
|
||||
<patch id="layout.startpage.changeStartPagePatch">
|
||||
<string name="revanced_change_start_page_title">BaÅlanÄÄąc sÉhifÉsini tÉyin et</string>
|
||||
@@ -1194,7 +1131,7 @@ Sonradan qapadÄąlarsa, UI sÉhvlÉrin ÃļnlÉmÉk ÃŧçÃŧn tÉtbiq mÉlumatlarÄąn
|
||||
</patch>
|
||||
<patch id="layout.miniplayer.miniplayerPatch">
|
||||
<string name="revanced_miniplayer_screen_title">Kiçik oynadÄącÄą</string>
|
||||
<string name="revanced_miniplayer_screen_summary">TÉtbiqdÉ kiçildilÉn oynadÄącÄą Ãŧslubunu dÉyiÅdir</string>
|
||||
<string name="revanced_miniplayer_screen_summary">TÉtbiqdaxili kiçilÉn oynadÄącÄą Ãŧslubunu dÉyiÅdir</string>
|
||||
<string name="revanced_miniplayer_type_title">Kiçik oynadÄącÄą nÃļvÃŧ</string>
|
||||
<string name="revanced_miniplayer_type_entry_0">Qeyri-aktivdir</string>
|
||||
<string name="revanced_miniplayer_type_entry_1">İlkin</string>
|
||||
@@ -1247,8 +1184,6 @@ GeniÅlÉndirmÉk vÉ ya baÄlamaq ÃŧçÃŧn sÃŧrÃŧÅdÃŧr"</string>
|
||||
<string name="revanced_gradient_loading_screen_title">DÉyiÅkÉn yÃŧklÉmÉ ekranÄąnÄą aktivlÉÅdir</string>
|
||||
<string name="revanced_gradient_loading_screen_summary_on">YÃŧklÉmÉ ekranÄą, dÉyiÅkÉn arxa plana malik olacaq</string>
|
||||
<string name="revanced_gradient_loading_screen_summary_off">YÃŧklÉmÉ ekranÄą, vahid arxa plana malik olacaq</string>
|
||||
</patch>
|
||||
<patch id="layout.theme.themeResourcePatch">
|
||||
<string name="revanced_seekbar_custom_color_title">FÉrdi irÉlilÉmÉ cizgisi rÉngini aktivlÉÅdir</string>
|
||||
<string name="revanced_seekbar_custom_color_summary_on">FÉrdi irÉlilÉmÉ cizgisi rÉngi gÃļstÉrilir</string>
|
||||
<string name="revanced_seekbar_custom_color_summary_off">Orijinal irÉlilÉmÉ cizgisi rÉngi gÃļstÉrilir</string>
|
||||
@@ -1340,8 +1275,8 @@ Bunu aktivlÉÅdirmÉ daha yÃŧksÉk video keyfiyyÉtlÉri ÉngÉlin silÉ bilÉr
|
||||
</patch>
|
||||
<patch id="misc.links.openLinksExternallyPatch">
|
||||
<string name="revanced_external_browser_title">BaÄlantÄąlarÄą brauzerdÉ aç</string>
|
||||
<string name="revanced_external_browser_summary_on">BaÄlantÄąlar xarici yolla aÃ§ÄąlÄąr</string>
|
||||
<string name="revanced_external_browser_summary_off">BaÄlantÄąlar tÉtbiqdÉ aÃ§ÄąlÄąr</string>
|
||||
<string name="revanced_external_browser_summary_on">Xarici brauzerdÉ baÄlantÄąlarÄąn aÃ§ÄąlmasÄą</string>
|
||||
<string name="revanced_external_browser_summary_off">TÉtbiqdaxili brauzerdÉ baÄlantÄąlarÄąn aÃ§ÄąlmasÄą</string>
|
||||
</patch>
|
||||
<patch id="misc.privacy.removeTrackingQueryParameterPatch">
|
||||
<string name="revanced_remove_tracking_query_parameter_title">İzlÉmÉ sorÄusu faktorun sil</string>
|
||||
@@ -1368,9 +1303,15 @@ Bunu aktivlÉÅdirmÉ daha yÃŧksÉk video keyfiyyÉtlÉri ÉngÉlin silÉ bilÉr
|
||||
<string name="revanced_remember_video_quality_last_selected_summary_off">KeyfiyyÉt dÉyiÅikliklÉri yalnÄąz cari videoya tÉtbiq edilir</string>
|
||||
<string name="revanced_video_quality_default_wifi_title">Wi-Fi ÅÉbÉkÉsindÉ ilkin video keyfiyyÉti</string>
|
||||
<string name="revanced_video_quality_default_mobile_title">Mobil ÅÉbÉkÉdÉ ilkin video keyfiyyÉti</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_title">Shorts keyfiyyÉt dÉyiÅikliklÉrini xatÄąrla</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_summary_on">KeyfiyyÉt dÉyiÅikliklÉri bÃŧtÃŧn Shorts-a tÉtbiq edilir</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_summary_off">KeyfiyyÉt dÉyiÅikliklÉri yalnÄąz cari Short-a tÉtbiq edilir</string>
|
||||
<string name="revanced_shorts_quality_default_wifi_title">Wi-Fi ÅÉbÉkÉsindÉ ilkin Shorts keyfiyyÉti</string>
|
||||
<string name="revanced_shorts_quality_default_mobile_title">Mobil ÅÉbÉkÉdÉ ilkin Shorts keyfiyyÉti</string>
|
||||
<string name="revanced_remember_video_quality_mobile">mobil</string>
|
||||
<string name="revanced_remember_video_quality_wifi">wi-fi</string>
|
||||
<string name="revanced_remember_video_quality_toast">İlkin %1$s keyfiyyÉti %2$s kimi dÉyiÅdi</string>
|
||||
<string name="revanced_remember_video_quality_toast_shorts">Shorts-un %1$s keyfiyyÉti %2$s olaraq dÉyiÅdirildi</string>
|
||||
</patch>
|
||||
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
||||
<string name="revanced_playback_speed_dialog_button_title">SÃŧrÉt dialoq dÃŧymÉsini gÃļstÉr</string>
|
||||
@@ -1401,10 +1342,10 @@ Bunu aktivlÉÅdirmÉ daha yÃŧksÉk video keyfiyyÉtlÉri ÉngÉlin silÉ bilÉr
|
||||
<string name="revanced_disable_hdr_video_summary_on">HDR video qapalÄądÄąr</string>
|
||||
<string name="revanced_disable_hdr_video_summary_off">HDR video aktivdir</string>
|
||||
</patch>
|
||||
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch">
|
||||
<string name="revanced_restore_old_video_quality_menu_title">KÃļhnÉ video keyfiyyÉt menusun qaytar</string>
|
||||
<string name="revanced_restore_old_video_quality_menu_summary_on">KÃļhnÉ video keyfiyyÉt siyahÄąsÄą gÃļstÉrilir</string>
|
||||
<string name="revanced_restore_old_video_quality_menu_summary_off">KÃļhnÉ video keyfiyyÉt siyahÄąsÄą gÃļrÃŧnmÃŧr</string>
|
||||
<patch id="video.quality.advancedVideoQualityMenuPatch">
|
||||
<string name="revanced_advanced_video_quality_menu_title">QabaqcÄąl video keyfiyyÉt siyahÄąsÄąn gÃļstÉr</string>
|
||||
<string name="revanced_advanced_video_quality_menu_summary_on">QabaqcÄąl video keyfiyyÉt siyahÄąsÄą gÃļstÉrilir</string>
|
||||
<string name="revanced_advanced_video_quality_menu_summary_off">QabaqcÄąl video keyfiyyÉt siyahÄąsÄą gÃļstÉrilmir</string>
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
||||
<string name="revanced_slide_to_seek_title">Axtarmaq ÃŧçÃŧn sÃŧrÃŧÅdÃŧrmÉni aktiv et</string>
|
||||
|
||||
@@ -48,57 +48,6 @@ Second \"item\" text"</string>
|
||||
|
||||
Đай дадаŅŅ ĐŊОвŅŅ ĐŧОвŅ, ĐŊавĐĩдаКŅĐĩ 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_summary">ĐĐŧĐŋаŅŅ / ĐĐēŅĐŋаŅŅ ĐŊаĐģад ReVanced</string>
|
||||
<!-- Settings about dialog. -->
|
||||
@@ -277,6 +226,9 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_artist_cards_title">ĐĄŅ
аваŅŅ ĐēаŅŅĐēŅ Đ˛ŅĐēаĐŊаŅŅаŅ</string>
|
||||
<string name="revanced_hide_artist_cards_summary_on">ĐаŅŅĐēŅ Đ˛ŅĐēаĐŊаŅŅĐ°Ņ ŅŅ
аваĐŊŅŅ</string>
|
||||
<string name="revanced_hide_artist_cards_summary_off">ĐаĐēаСваŅŅŅа ĐēаŅŅĐēŅ Đ˛ŅĐēаĐŊаŅŅаŅ</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_title">ĐĄŅ
аваŅŅ ÂĢĐвОдĐēŅ Đ˛ŅĐ´Ņа, ĐˇĐŗĐĩĐŊŅŅаваĐŊŅŅ ŅŅŅŅĐŊŅĐŧ ŅĐŊŅŅĐģĐĩĐēŅаĐŧÂģ</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_summary_on">РаСдСĐĩĐģ СвОдĐēŅ Đ˛ŅĐ´Ņа ŅŅ
аваĐŊŅ</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_summary_off">РаСдСĐĩĐģ СвОдĐēŅ Đ˛ŅĐ´Ņа ĐŋаĐēаСаĐŊŅ</string>
|
||||
<string name="revanced_hide_attributes_section_title">ĐĄŅ
аваŅŅ Đ°ŅŅŅĐąŅŅŅ</string>
|
||||
<string name="revanced_hide_attributes_section_summary_on">РаСдСĐĩĐģŅ ÂĢĐаĐŋŅĐģŅŅĐŊŅŅ ĐŧĐĩŅŅŅÂģ, ÂĢĐŅĐģŅĐŊŅÂģ, ÂĢĐŅСŅĐēаÂģ Ņ ÂĢĐŅдСŅ, ŅĐēŅŅ
ĐˇĐŗĐ°Đ´Đ˛Đ°ĐģŅÂģ ŅŅ
аваĐŊŅŅ</string>
|
||||
<string name="revanced_hide_attributes_section_summary_off">РаСдСĐĩĐģŅ ÂĢĐаĐŋŅĐģŅŅĐŊŅŅ ĐŧĐĩŅŅŅÂģ, ÂĢĐŅĐģŅĐŊŅÂģ, ÂĢĐŅСŅĐēаÂģ Ņ ÂĢĐŅдСŅ, ŅĐēŅŅ
ĐˇĐŗĐ°Đ´Đ˛Đ°ĐģŅÂģ ĐŋаĐēаСаĐŊŅŅ</string>
|
||||
@@ -313,9 +265,12 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">ĐаĐēаСаĐŊа Ņ ĐˇĐ˛ŅСаĐŊŅŅ
вŅĐ´Ņа</string>
|
||||
<string name="revanced_comments_screen_title">ĐаĐŧĐĩĐŊŅаŅŅŅ</string>
|
||||
<string name="revanced_comments_screen_summary">ĐĄŅ
аваŅŅ Đ°ĐąĐž ĐŋаĐēаСаŅŅ ĐēаĐŧĐŋаĐŊĐĩĐŊŅŅ ŅаСдСĐĩĐģа ĐēаĐŧĐĩĐŊŅаŅŅŅŅ</string>
|
||||
<string name="revanced_hide_comments_chat_summary_title">ĐĄŅ
аваŅŅ ÂĢĐвОдĐēŅ ŅаŅаÂģ</string>
|
||||
<string name="revanced_hide_comments_chat_summary_summary_on">ĐвОдĐēа ŅаŅа ŅŅ
аваĐŊаŅ</string>
|
||||
<string name="revanced_hide_comments_chat_summary_summary_off">ĐвОдĐēа ŅаŅа ĐŋаĐēаСаĐŊаŅ</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_title">ĐĄŅ
аваŅŅ ĐˇĐ˛ĐžĐ´ĐēŅ ŅаŅа Ņа ŅŅŅŅĐŊŅĐŧ ŅĐŊŅŅĐģĐĩĐēŅаĐŧ</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_on">ĐвОдĐēа ŅаŅа ŅŅ
аваĐŊаŅ</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_off">ĐвОдĐēа ŅаŅа ĐŋаĐēаСаĐŊаŅ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_title">ĐĄŅ
аваŅŅ ĐˇĐ˛ĐžĐ´ĐēŅ ĐēаĐŧĐĩĐŊŅаŅŅŅŅ Ņа ŅŅŅŅĐŊŅĐŧ ŅĐŊŅŅĐģĐĩĐēŅаĐŧ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_on">ĐвОдĐēа ĐēаĐŧĐĩĐŊŅаŅŅŅŅ ŅŅ
аваĐŊаŅ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_off">ĐвОдĐēа ĐēаĐŧĐĩĐŊŅаŅŅŅŅ ĐŋаĐēаСаĐŊаŅ</string>
|
||||
<string name="revanced_hide_comments_by_members_header_title">ĐĄŅ
аваŅŅ ĐˇĐ°ĐŗĐ°ĐģОваĐē \"ĐаĐŧĐĩĐŊŅаŅŅŅ ŅдСĐĩĐģŅĐŊŅĐēаŅ\"</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_on">ĐĐ°ĐŗĐ°ĐģОваĐē ÂĢĐаĐŧĐĩĐŊŅаŅŅ ŅдСĐĩĐģŅĐŊŅĐēаŅÂģ ŅŅ
аваĐŊŅ</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_off">ĐĐ°ĐŗĐ°ĐģОваĐē ÂĢĐаĐŧĐĩĐŊŅаŅŅ ŅдСĐĩĐģŅĐŊŅĐēаŅÂģ ĐŋаĐēаСаĐŊŅ</string>
|
||||
@@ -362,7 +317,7 @@ Second \"item\" text"</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_phrases_title">ĐĐģŅŅавŅŅ ŅĐģОвŅ, ŅĐēŅŅ ŅŅŅйа ŅŅ
аваŅŅ</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
<!-- For localization, it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">"ĐĐģŅŅавŅŅ ŅĐģĐžĐ˛Ņ Ņ ŅŅĐ°ĐˇŅ Đ´ĐģŅ ŅŅ
аваĐŊĐŊŅ, ĐŋадСĐĩĐģĐĩĐŊŅŅ ĐŋĐĩŅаŅ
ОдаĐŧŅ ĐŊа ĐŊОвŅŅ ŅадОĐē
|
||||
|
||||
@@ -377,7 +332,7 @@ Second \"item\" text"</string>
|
||||
âĸ ĐĐĩĐēаŅĐžŅŅŅ ŅĐģĐĩĐŧĐĩĐŊŅŅ ŅĐŊŅŅŅŅĐĩĐšŅŅ ĐŧĐžĐŗŅŅŅ ĐŊĐĩ ĐąŅŅŅ ŅŅ
аваĐŊŅ
|
||||
âĸ ĐĐžŅŅĐē Đŋа ĐēĐģŅŅавŅĐŧ ŅĐģОвĐĩ ĐŧĐžĐļа ĐŊĐĩ ĐŋаĐēаСаŅŅ Đ˛ŅĐŊŅĐēŅ"</string>
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_title">ĐĄŅĐŋадСĐĩĐŊĐŊĐĩ ŅŅĐģŅŅ
ŅĐģĐžŅ</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc.) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_summary">ĐаĐģŅ Đ˛Ņ Đ°Ņ
ŅĐŊĐĩŅĐĩ ĐēĐģŅŅавОĐĩ ŅĐģОва айО ŅŅĐ°ĐˇŅ Ņ Đ´Đ˛ŅŅ
ŅаСОвŅŅ ĐģаĐŋĐēŅ, ĐŗŅŅа ĐŋĐĩŅаŅĐēОдСŅŅŅ ŅаŅŅĐēОваĐŧŅ ŅŅĐŋадСĐĩĐŊĐŊŅ ĐŊĐ°ĐˇĐ˛Đ°Ņ Đ˛ŅĐ´Ņа Ņ ĐēаĐŊаĐģаŅ<br><br>ĐаĐŋŅŅĐēĐģад,<br><b>\"ai\"</b> ŅŅ
аваĐĩ вŅĐ´Ņа: <b>How does AI work?</b><br>аĐģĐĩ ĐŊĐĩ ŅŅ
аваĐĩ: <b>What does fair use mean?</b></string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">ĐĐĩĐģŅĐŗĐ° вŅĐēаŅŅŅŅĐžŅваŅŅ ĐēĐģŅŅавОĐĩ ŅĐģОва: %s</string>
|
||||
@@ -404,7 +359,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_title">ĐĄŅ
аваŅŅ ŅаĐŧŅ ŅĐŋаĐŊŅаваĐŊŅŅ ĐēаŅŅŅ</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_on">ĐĄĐŋĐžĐŊŅаŅŅĐēŅŅ ĐēаŅŅĐēŅ ŅŅ
аваĐŊŅŅ</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_off">ĐаĐēаСваŅŅŅа ŅĐģаŅĐŊŅŅ ĐēаŅŅŅ</string>
|
||||
<string name="revanced_hide_products_banner_title">ĐĄŅ
аваŅŅ ĐąĐ°ĐŊĐĩŅ Đ´ĐģŅ ĐŋŅĐ°ĐŗĐģŅĐ´Ņ ĐŋŅадŅĐēŅаŅ</string>
|
||||
<string name="revanced_hide_products_banner_title">ĐĄŅ
аваŅŅ ĐąĐ°ĐŊĐĩŅ ÂĢĐĐ°ĐŗĐģŅдСĐĩŅŅ ĐŋŅадŅĐēŅŅÂģ</string>
|
||||
<string name="revanced_hide_products_banner_summary_on">ĐаĐŊŅŅ ŅŅ
аваĐŊŅ</string>
|
||||
<string name="revanced_hide_products_banner_summary_off">ĐаĐēаСваĐĩŅŅа йаĐŊŅŅ</string>
|
||||
<string name="revanced_hide_end_screen_store_banner_title">ĐĄŅ
аваŅŅ ĐąĐ°ĐŊĐĩŅ ĐēŅаĐŧŅ ĐŊа ĐēаĐŊŅаŅĐēОвŅĐŧ ŅĐēŅаĐŊĐĩ</string>
|
||||
@@ -475,9 +430,9 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_disable_precise_seeking_gesture_summary_off">ĐŅŅŅ ŅĐēĐģŅŅаĐŊŅ</string>
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSeekbarTappingPatch">
|
||||
<string name="revanced_seekbar_tapping_title">ĐŖĐēĐģŅŅŅŅŅ ĐŊаŅŅŅĐē ĐŊа ĐŋаĐŊŅĐģŅ ĐŋĐžŅŅĐēŅ</string>
|
||||
<string name="revanced_seekbar_tapping_summary_on">ĐаŅŅŅĐē ĐŋаĐŊŅĐģŅ ĐŋĐžŅŅĐēŅ ŅĐēĐģŅŅаĐŊŅ</string>
|
||||
<string name="revanced_seekbar_tapping_summary_off">ĐаŅŅŅĐē ĐŋаĐŊŅĐģŅ ĐŋĐžŅŅĐēŅ Đ°Đ´ĐēĐģŅŅаĐŊŅ</string>
|
||||
<string name="revanced_seekbar_tapping_title">ĐŖĐēĐģŅŅŅŅŅ ĐŊаŅŅŅĐēаĐŊĐŊĐĩ Đ´ĐģŅ ĐŋĐžŅŅĐēŅ</string>
|
||||
<string name="revanced_seekbar_tapping_summary_on">ĐаŅŅŅĐŊŅŅĐĩ, Đēай ŅĐēĐģŅŅŅŅŅ ĐŋĐžŅŅĐē</string>
|
||||
<string name="revanced_seekbar_tapping_summary_off">ĐаŅŅŅĐēаĐŊĐŊĐĩ Đ´ĐģŅ ĐŋĐžŅŅĐēŅ Đ°Đ´ĐēĐģŅŅаĐŊа</string>
|
||||
</patch>
|
||||
<patch id="interaction.swipecontrols.swipeControlsResourcePatch">
|
||||
<string name="revanced_swipe_brightness_title">ĐŖĐēĐģŅŅŅŅŅ ĐļŅŅŅ ŅŅĐēаŅŅŅ</string>
|
||||
@@ -490,9 +445,9 @@ Second \"item\" text"</string>
|
||||
|
||||
Đ ŅĐŗŅĐģŅĐšŅĐĩ ĐŗŅŅĐŊаŅŅŅ, ĐŋŅавОдСŅŅŅ ĐŋаĐģŅŅаĐŧ вĐĩŅŅŅĐēаĐģŅĐŊа Đŋа ĐŋŅаваК ŅаŅŅŅŅ ŅĐēŅаĐŊа"</string>
|
||||
<string name="revanced_swipe_volume_summary_off">ĐŅавŅдСĐĩĐŊĐŊĐĩ ĐŋаĐģŅŅаĐŧ Đ´ĐģŅ ŅŅĐŗŅĐģŅваĐŊĐŊŅ ĐŗŅŅĐŊаŅŅŅ Đ˛Đ° ŅвĐĩŅŅ ŅĐēŅаĐŊ вŅĐēĐģŅŅаĐŊа</string>
|
||||
<string name="revanced_swipe_press_to_engage_title">ĐŖĐēĐģŅŅŅŅŅ ĐļŅŅŅ \"ĐŊаŅŅŅĐēаĐŊĐŊĐĩ Đ´ĐģŅ ĐŋŅавŅдСĐĩĐŊĐŊŅ ĐŋаĐģŅŅаĐŧ\"</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_on">ĐŅавŅдСĐĩĐŊĐŊĐĩ ĐŋаĐģŅŅаĐŧ ŅĐēĐģŅŅаĐŊа</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_off">ĐŅавŅдСĐĩĐŊĐŊĐĩ ĐŋаĐģŅŅаĐŧ адĐēĐģŅŅаĐŊа</string>
|
||||
<string name="revanced_swipe_press_to_engage_title">ĐŖĐēĐģŅŅŅŅŅ ĐļŅŅŅ ĐŋŅавŅдСĐĩĐŊĐŊŅ ĐŊаŅŅŅĐēаĐŧ</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_on">ĐŅавŅдСĐĩĐŊĐŊĐĩ ĐŊаŅŅŅĐēаĐŧ ŅĐēĐģŅŅаĐŊа</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_off">ĐŅавŅдСĐĩĐŊĐŊĐĩ ĐŊаŅŅŅĐēаĐŧ адĐēĐģŅŅаĐŊа</string>
|
||||
<string name="revanced_swipe_haptic_feedback_title">ĐŖĐēĐģŅŅŅŅŅ ŅаĐēŅŅĐģŅĐŊŅŅ ĐˇĐ˛Đ°ŅĐžŅĐŊŅŅ ŅŅвŅСŅ</string>
|
||||
<string name="revanced_swipe_haptic_feedback_summary_on">ĐĸаĐēŅŅĐģŅĐŊĐ°Ņ ĐˇĐ˛Đ°ŅĐžŅĐŊĐ°Ņ ŅŅвŅĐˇŅ ŅĐēĐģŅŅаĐŊа</string>
|
||||
<string name="revanced_swipe_haptic_feedback_summary_off">ĐĸаĐēŅŅĐģŅĐŊĐ°Ņ ĐˇĐ˛Đ°ŅĐžŅĐŊĐ°Ņ ŅŅвŅĐˇŅ Đ°Đ´ĐēĐģŅŅаĐŊа</string>
|
||||
@@ -663,7 +618,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">ĐаĐēаСваĐĩŅŅа ĐŊŅĐļĐŊŅ ĐēаĐģĐžĐŊŅŅŅŅĐģ ĐŧĐĩĐŊŅ ŅĐēаŅŅŅ Đ˛ŅĐ´Ņа</string>
|
||||
</patch>
|
||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||
<string name="revanced_hide_player_previous_next_buttons_title">ĐĄŅ
аваŅŅ ĐŋаĐŋŅŅŅĐ´ĐŊŅ & ĐēĐŊĐžĐŋĐēŅ ĐŊаŅŅŅĐŋĐŊĐ°ĐŗĐ° вŅĐ´Ņа</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_title">ĐĄŅ
аваŅŅ ĐŋаĐŋŅŅŅĐ´ĐŊŅŅ & ĐēĐŊĐžĐŋĐēŅ ÂĢĐаĐģĐĩĐšÂģ</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_summary_on">ĐĐŊĐžĐŋĐēŅ ŅŅ
аваĐŊŅŅ</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_summary_off">ĐаĐēаСваŅŅŅа ĐēĐŊĐžĐŋĐēŅ</string>
|
||||
<string name="revanced_hide_cast_button_title">ĐĄŅ
аваŅŅ ĐēĐŊĐžĐŋĐēŅ ÂĢĐĸŅаĐŊŅĐģŅŅŅŅÂģ</string>
|
||||
@@ -856,7 +811,6 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_ryd_enable_summary_on">ĐŅСĐģаКĐēŅ ĐŋаĐēаСаĐŊŅ</string>
|
||||
<string name="revanced_ryd_enable_summary_off">ĐŅСĐģаКĐēŅ ĐŊĐĩ ĐŋаĐēаСваŅŅŅа</string>
|
||||
<string name="revanced_ryd_shorts_title">ĐаĐēаСваКŅĐĩ \"ĐŊĐĩ ĐŋадайаĐĩŅŅа\" ĐŊа Shorts</string>
|
||||
<string name="revanced_ryd_shorts_summary_on">ĐŅСĐģаКĐēŅ ĐŊа Shorts ĐŋаĐēаСаĐŊŅŅ</string>
|
||||
<string name="revanced_ryd_shorts_summary_on_disclaimer">"ĐŅСĐģаКĐēŅ ĐŊа Shorts ĐŋаĐēаСаĐŊŅŅ
|
||||
|
||||
ĐĐąĐŧĐĩĐļаваĐŊĐŊĐĩ: Đ´ŅСĐģаКĐēŅ ĐŧĐžĐŗŅŅŅ ĐŊĐĩ адĐģŅŅŅŅĐžŅваŅŅа Ņ ŅŅĐļŅĐŧĐĩ ŅĐŊĐēĐžĐŗĐŊŅŅа"</string>
|
||||
@@ -1055,6 +1009,8 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_sb_vote_downvote">ĐаĐģаŅаваŅŅ ŅŅĐŋŅаŅŅ</string>
|
||||
<string name="revanced_sb_vote_category">ĐĐŧŅĐŊŅŅŅ ĐēаŅŅĐŗĐžŅŅŅ</string>
|
||||
<string name="revanced_sb_vote_no_segments">ĐŅĐŧа ŅĐĩĐŗĐŧĐĩĐŊŅĐ°Ņ Đ´ĐģŅ ĐŗĐ°ĐģаŅаваĐŊĐŊŅ</string>
|
||||
<!-- A segment start and end time, such as "02:10 to 03:40" -->
|
||||
<string name="revanced_sb_vote_segment_time_to_from">%1$s да %2$s</string>
|
||||
<string name="revanced_sb_new_segment_choose_category">ĐŅĐąĐĩŅŅŅĐĩ ĐēаŅŅĐŗĐžŅŅŅ ŅĐĩĐŗĐŧĐĩĐŊŅа</string>
|
||||
<string name="revanced_sb_new_segment_disabled_category">ĐаŅŅĐŗĐžŅŅŅ Đ°Đ´ĐēĐģŅŅаĐŊа Ņ ĐŊаĐģадаŅ
. ĐŖĐēĐģŅŅŅŅĐĩ ĐēаŅŅĐŗĐžŅŅŅ Đ´ĐģŅ Đ°Đ´ĐŋŅаŅĐēŅ.</string>
|
||||
<string name="revanced_sb_new_segment_title">ĐĐžĐ˛Ņ ŅĐĩĐŗĐŧĐĩĐŊŅ SponsorBlock</string>
|
||||
@@ -1102,6 +1058,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_sb_stats_saved_hour_format">%1$s ĐŗĐ°Đ´ĐˇŅĐŊ %2$s Ņ
вŅĐģŅĐŊ</string>
|
||||
<string name="revanced_sb_stats_saved_minute_format">%1$s Ņ
вŅĐģŅĐŊ %2$s ŅĐĩĐēŅĐŊĐ´</string>
|
||||
<string name="revanced_sb_stats_saved_second_format">%s ŅĐĩĐēŅĐŊĐ´</string>
|
||||
<string name="revanced_sb_color_opacity_label">ĐĐĩĐŋŅаСŅŅŅŅаŅŅŅ:</string>
|
||||
<string name="revanced_sb_color_dot_label">ĐēĐžĐģĐĩŅ:</string>
|
||||
<string name="revanced_sb_color_changed">ĐĐžĐģĐĩŅ ĐˇĐŧŅĐŊŅŅŅŅ</string>
|
||||
<string name="revanced_sb_color_reset">ĐĄĐēŅĐ´ ĐēĐžĐģĐĩŅŅ</string>
|
||||
@@ -1119,13 +1076,11 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_change_form_factor_entry_4">ĐŅŅаĐŧайŅĐģŅĐŊŅ</string>
|
||||
<string name="revanced_change_form_factor_user_dialog_message">"ĐĐŧĐĩĐŊŅ ŅĐēĐģŅŅаŅŅŅ:
|
||||
|
||||
РаŅĐēĐģадĐēа ĐŋĐģаĐŊŅŅŅа
|
||||
âĸ ĐавĐĩдаĐŧĐģĐĩĐŊĐŊŅ ŅŅĐŋĐžĐģŅĐŊаŅŅŅ ŅŅ
аваĐŊŅ
|
||||
ĐаĐēĐĩŅ Đ´ĐģŅ ĐŋĐģаĐŊŅŅŅа
|
||||
âĸ ĐавĐĩдаĐŧĐģĐĩĐŊĐŊŅ ŅŅĐŋĐžĐģŅĐŊаŅŅŅ ŅŅ
аваĐŊŅŅ
|
||||
|
||||
РаŅĐēĐģадĐēа аŅŅаĐŧайŅĐģŅ
|
||||
âĸ ĐĐĩĐŊŅ ĐŗŅŅŅĐžŅŅŅ ĐŋŅĐ°ĐŗĐģŅĐ´Đ°Ņ ŅŅ
аваĐŊа
|
||||
âĸ ĐĐ´ĐŊĐžŅĐģĐĩĐŊа ŅĐēĐģадĐēа ÂĢĐаŅĐģĐĩдаваŅŅÂģ
|
||||
âĸ Đ ĐžĐģŅĐēŅ Shorts адĐēŅŅваŅŅŅа Ņ ĐˇĐ˛ŅŅаКĐŊŅĐŧ ĐŋŅĐ°ĐšĐŗŅаваĐģŅĐŊŅĐēŅ
|
||||
ĐŅŅаĐŧайŅĐģŅĐŊŅ ĐŧаĐēĐĩŅ
|
||||
âĸ Shorts адĐēŅŅваŅŅŅа Ņ ĐˇĐ˛ŅŅаКĐŊŅĐŧ ĐŋĐģŅĐĩŅŅ
|
||||
âĸ ĐĄŅŅĐļĐēа аŅĐŗĐ°ĐŊŅСаваĐŊа Đŋа ŅŅĐŧаŅ
Ņ ĐēаĐŊаĐģаŅ
"</string>
|
||||
</patch>
|
||||
<patch id="layout.spoofappversion.spoofAppVersionPatch">
|
||||
@@ -1141,12 +1096,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 -->
|
||||
<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_2">19.26.42 - ĐĐ´ĐŊаŅĐģĐĩĐŊĐŊĐĩ ŅŅаŅŅŅ
СĐŊаŅĐēĐžŅ ĐŊавŅĐŗĐ°ŅŅŅ</string>
|
||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - ĐĐ´ĐŊаŅĐģĐĩĐŊĐŊĐĩ RYD ĐŊа Shorts Ņ ŅŅĐļŅĐŧĐĩ ŅĐŊĐēĐžĐŗĐŊŅŅа</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - ĐĐ´ĐŊавŅŅŅ Ņ
ŅŅĐēаŅŅŅ ŅŅŅĐžĐēĐ°ĐŗĐ° вŅĐ´Ņа & ŅĐēаŅĐŊаĐĩ ĐŧĐĩĐŊŅ</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - ĐĐ´ĐŊаŅĐģĐĩĐŊĐŊĐĩ ŅĐēĐģадĐēŅ ĐąŅĐąĐģŅŅŅŅĐēŅ</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - ĐĐ´ĐŊаŅĐģĐĩĐŊĐŊĐĩ ŅŅаŅОК ĐŋаĐģŅŅŅ ĐŋĐģŅĐšĐģŅŅŅĐžŅ</string>
|
||||
<string name="revanced_spoof_app_version_target_entry_2">19.01.34 - ĐĐ´ĐŊаŅĐģĐĩĐŊĐŊĐĩ ŅŅаŅŅŅ
СĐŊаŅĐēĐžŅ ĐŊавŅĐŗĐ°ŅŅŅ</string>
|
||||
</patch>
|
||||
<patch id="layout.startpage.changeStartPagePatch">
|
||||
<string name="revanced_change_start_page_title">ĐŖŅŅаĐģŅваŅŅ ŅŅаŅŅавŅŅ ŅŅаŅĐžĐŊĐēŅ</string>
|
||||
@@ -1196,7 +1146,7 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="layout.miniplayer.miniplayerPatch">
|
||||
<string name="revanced_miniplayer_screen_title">ĐŅĐŊŅ-ĐŋĐģŅĐĩŅ</string>
|
||||
<string name="revanced_miniplayer_screen_summary">ĐĐŧŅĐŊŅŅĐĩ ŅŅŅĐģŅ ĐŧŅĐŊŅĐŧŅСаваĐŊĐ°ĐŗĐ° ĐŋĐģŅĐĩŅа Ņ ĐŋŅĐ°ĐŗŅаĐŧĐĩ</string>
|
||||
<string name="revanced_miniplayer_screen_summary">ĐĐŧŅĐŊŅŅŅ ŅŅŅĐģŅ ĐˇĐŗĐžŅĐŊŅŅĐ°ĐŗĐ° ĐŋŅĐ°ĐšĐŗŅаваĐģŅĐŊŅĐēа Ņ ĐŋŅĐ°ĐŗŅаĐŧĐĩ</string>
|
||||
<string name="revanced_miniplayer_type_title">ĐĸŅĐŋ ĐŧŅĐŊŅĐŋĐģŅĐĩŅа</string>
|
||||
<string name="revanced_miniplayer_type_entry_0">ĐĐŊваĐģŅĐ´Ņ</string>
|
||||
<string name="revanced_miniplayer_type_entry_1">Đа СĐŧаŅŅаĐŊĐŊŅ</string>
|
||||
@@ -1249,8 +1199,6 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_gradient_loading_screen_title">ĐŖĐēĐģŅŅŅŅŅ ĐŗŅадŅĐĩĐŊŅĐŊŅ ŅĐēŅаĐŊ ĐˇĐ°ĐŗŅŅСĐēŅ</string>
|
||||
<string name="revanced_gradient_loading_screen_summary_on">ĐĐēŅаĐŊ ĐˇĐ°ĐŗŅŅСĐēŅ ĐąŅдСĐĩ ĐŧĐĩŅŅ ĐŗŅадŅĐĩĐŊŅĐŊŅ ŅĐžĐŊ</string>
|
||||
<string name="revanced_gradient_loading_screen_summary_off">ĐĐēŅаĐŊ ĐˇĐ°ĐŗŅŅСĐēŅ ĐąŅдСĐĩ ĐŧĐĩŅŅ ŅŅŅŅĐģŅĐŊŅ ŅĐžĐŊ</string>
|
||||
</patch>
|
||||
<patch id="layout.theme.themeResourcePatch">
|
||||
<string name="revanced_seekbar_custom_color_title">ĐŖĐēĐģŅŅŅŅŅ ŅĐģаŅĐŊŅ ĐēĐžĐģĐĩŅ ĐŋаĐŊŅĐģŅ ĐŋĐžŅŅĐēŅ</string>
|
||||
<string name="revanced_seekbar_custom_color_summary_on">ĐаĐēаСваĐĩŅŅа ĐēаŅŅŅŅаĐģŅĐŊŅŅĐēŅ ĐēĐžĐģĐĩŅ ĐŋаĐŊŅĐģŅ ĐŋĐžŅŅĐēŅ</string>
|
||||
<string name="revanced_seekbar_custom_color_summary_off">ĐаĐēаСаĐŊŅ ĐˇŅŅ
ОдĐŊŅ ĐēĐžĐģĐĩŅ ĐŋаĐŊŅĐģŅ ĐŋĐžŅŅĐēŅ</string>
|
||||
@@ -1342,8 +1290,8 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="misc.links.openLinksExternallyPatch">
|
||||
<string name="revanced_external_browser_title">ĐĐ´ĐēŅŅваŅŅ ŅĐŋаŅŅĐģĐēŅ Ņ ĐąŅаŅСĐĩŅŅ</string>
|
||||
<string name="revanced_external_browser_summary_on">ĐĐ´ĐēŅŅŅŅŅ ŅĐŋаŅŅĐģаĐē СвОĐŊĐēŅ</string>
|
||||
<string name="revanced_external_browser_summary_off">ĐĐ´ĐēŅŅŅŅŅ ŅĐŋаŅŅĐģаĐē Ņ ĐŋŅĐ°ĐŗŅаĐŧĐĩ</string>
|
||||
<string name="revanced_external_browser_summary_on">ĐĐ´ĐēŅŅŅŅŅ ŅĐŋаŅŅĐģаĐē Ņ ĐˇĐŊĐĩŅĐŊŅĐŧ ĐąŅаŅСĐĩŅŅ</string>
|
||||
<string name="revanced_external_browser_summary_off">ĐĐ´ĐēŅŅŅŅŅ ŅĐŋаŅŅĐģаĐē ва ŅĐąŅдаваĐŊŅĐŧ ĐąŅаŅСĐĩŅŅ</string>
|
||||
</patch>
|
||||
<patch id="misc.privacy.removeTrackingQueryParameterPatch">
|
||||
<string name="revanced_remove_tracking_query_parameter_title">ĐŅдаĐģŅŅŅ ĐŋаŅаĐŧĐĩŅŅ ĐˇĐ°ĐŋŅŅŅ Đ°Đ´ŅĐžŅваĐŊĐŊŅ</string>
|
||||
@@ -1370,9 +1318,15 @@ Second \"item\" text"</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_mobile_title">ĐĄŅаĐŊдаŅŅĐŊĐ°Ņ ŅĐēаŅŅŅ Đ˛ŅĐ´Ņа Ņ ĐŧайŅĐģŅĐŊаК ŅĐĩŅŅŅ</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_title">ĐаĐŋĐžĐŧĐŊŅŅŅ ĐˇĐŧĐĩĐŊŅ ŅĐēаŅŅŅ Shorts</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_summary_on">ĐĐŧĐĩĐŊŅ ŅĐēаŅŅŅ ĐŋŅŅĐŧŅĐŊŅŅŅŅа да ŅŅŅŅ
Shorts</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_summary_off">ĐĐŧĐĩĐŊŅ ŅĐēаŅŅŅ ĐŋŅŅĐŧŅĐŊŅŅŅŅа ŅĐžĐģŅĐēŅ Đ´Đ° ĐąŅĐŗŅŅĐ°ĐŗĐ° Short</string>
|
||||
<string name="revanced_shorts_quality_default_wifi_title">Đ¯ĐēаŅŅŅ Shorts Đŋа СĐŧаŅŅаĐŊĐŊŅ Ņ ŅĐĩŅŅŅ Wi-Fi</string>
|
||||
<string name="revanced_shorts_quality_default_mobile_title">Đ¯ĐēаŅŅŅ Shorts Đŋа СĐŧаŅŅаĐŊĐŊŅ Ņ ĐŧайŅĐģŅĐŊаК ŅĐĩŅŅŅ</string>
|
||||
<string name="revanced_remember_video_quality_mobile">ĐŧайŅĐģŅĐŊŅ</string>
|
||||
<string name="revanced_remember_video_quality_wifi">wi-fi</string>
|
||||
<string name="revanced_remember_video_quality_toast">ĐĄŅаĐŊдаŅŅĐŊĐ°Ņ ŅĐēаŅŅŅ %1$s СĐŧĐĩĐŊĐĩĐŊа ĐŊа: %2$s</string>
|
||||
<string name="revanced_remember_video_quality_toast_shorts">Đ¯ĐēаŅŅŅ Shorts %1$s СĐŧĐĩĐŊĐĩĐŊа ĐŊа: %2$s</string>
|
||||
</patch>
|
||||
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
||||
<string name="revanced_playback_speed_dialog_button_title">ĐаĐēаСаŅŅ Đ´ŅŅĐģĐžĐŗĐ°Đ˛ŅŅ ĐēĐŊĐžĐŋĐēŅ Ņ
ŅŅĐēаŅŅŅ</string>
|
||||
@@ -1403,10 +1357,10 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_disable_hdr_video_summary_on">ĐŅĐ´Ņа Ņ ŅаŅĐŧаŅĐĩ HDR адĐēĐģŅŅаĐŊа</string>
|
||||
<string name="revanced_disable_hdr_video_summary_off">ĐŅĐ´Ņа Ņ ŅаŅĐŧаŅĐĩ HDR ŅĐēĐģŅŅаĐŊа</string>
|
||||
</patch>
|
||||
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch">
|
||||
<string name="revanced_restore_old_video_quality_menu_title">ĐĐ´ĐŊавŅŅŅ ŅŅаŅĐžĐĩ ĐŧĐĩĐŊŅ ŅĐēаŅŅŅ Đ˛ŅĐ´Ņа</string>
|
||||
<string name="revanced_restore_old_video_quality_menu_summary_on">ĐаĐēаСаĐŊа ŅŅаŅĐžĐĩ ĐŧĐĩĐŊŅ ŅĐēаŅŅŅ Đ˛ŅĐ´Ņа</string>
|
||||
<string name="revanced_restore_old_video_quality_menu_summary_off">ĐĄŅаŅĐžĐĩ ĐŧĐĩĐŊŅ ŅĐēаŅŅŅ Đ˛ŅĐ´Ņа ĐŊĐĩ ĐŋаĐēаСваĐĩŅŅа</string>
|
||||
<patch id="video.quality.advancedVideoQualityMenuPatch">
|
||||
<string name="revanced_advanced_video_quality_menu_title">ĐаĐēаСаŅŅ ĐŋаŅŅŅаĐŊаĐĩ ĐŧĐĩĐŊŅ ŅĐēаŅŅŅ Đ˛ŅĐ´Ņа</string>
|
||||
<string name="revanced_advanced_video_quality_menu_summary_on">ĐаŅŅŅаĐŊаĐĩ ĐŧĐĩĐŊŅ ŅĐēаŅŅŅ Đ˛ŅĐ´Ņа ĐŋаĐēаСаĐŊа</string>
|
||||
<string name="revanced_advanced_video_quality_menu_summary_off">ĐаŅŅŅаĐŊаĐĩ ĐŧĐĩĐŊŅ ŅĐēаŅŅŅ Đ˛ŅĐ´Ņа ĐŊĐĩ ĐŋаĐēаСаĐŊа</string>
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
||||
<string name="revanced_slide_to_seek_title">ĐŖĐēĐģŅŅŅŅŅ ŅĐģаКд Đ´ĐģŅ ĐŋĐžŅŅĐēŅ</string>
|
||||
|
||||
@@ -48,57 +48,6 @@ Second \"item\" text"</string>
|
||||
|
||||
Đа да ĐŋŅĐĩвĐĩĐ´ĐĩŅĐĩ ĐŊОви ĐĩСиŅи, ĐŋĐžŅĐĩŅĐĩŅĐĩ 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_summary">ĐĐŧĐŋĐžŅŅиŅаĐŊĐĩ / ĐĐēŅĐŋĐžŅŅиŅаĐŊĐĩ ĐŊа ReVanced ĐŊаŅŅŅОКĐēиŅĐĩ</string>
|
||||
<!-- Settings about dialog. -->
|
||||
@@ -277,6 +226,9 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_artist_cards_title">ĐĄĐēŅиваĐŊĐĩ ĐŊа ĐēаŅŅиŅĐĩ ĐŊа аŅŅиŅŅиŅĐĩ</string>
|
||||
<string name="revanced_hide_artist_cards_summary_on">ĐаŅŅиŅĐĩ ĐŊа иСĐŋŅĐģĐŊиŅĐĩĐģиŅĐĩ Ņа ŅĐēŅиŅи</string>
|
||||
<string name="revanced_hide_artist_cards_summary_off">ĐĐžĐēĐ°ĐˇĐ˛Đ°Ņ ŅĐĩ ĐēаŅŅи ĐŊа аŅŅиŅŅи</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_title">ĐĄĐēŅиваĐŊĐĩ ĐŊа \"AI-ĐŗĐĩĐŊĐĩŅиŅаĐŊĐž видĐĩĐž ŅĐĩСŅĐŧĐĩ\"</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_summary_on">ĐĄĐēŅĐ¸Ņ Đĩ ŅаСдĐĩĐģŅŅ Ņ Đ˛Đ¸Đ´ĐĩĐž ŅĐĩСŅĐŧĐĩ</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_summary_off">ĐĐžĐēаСва ŅĐĩ ŅаСдĐĩĐģŅŅ Ņ Đ˛Đ¸Đ´ĐĩĐž ŅĐĩСŅĐŧĐĩ</string>
|
||||
<string name="revanced_hide_attributes_section_title">ĐĄĐēŅиваĐŊĐĩ ĐŊа аŅŅийŅŅи</string>
|
||||
<string name="revanced_hide_attributes_section_summary_on">ĐĄĐĩĐēŅииŅĐĩ \"ĐŅĐĩĐŋĐžŅŅŅаĐŊи ĐŧĐĩŅŅа\", \"ĐĐŗŅи\", \"ĐŅСиĐēа\" и \"ĐĄĐŋĐžĐŧĐĩĐŊаŅи Ņ
ĐžŅа\" Ņа ŅĐēŅиŅи</string>
|
||||
<string name="revanced_hide_attributes_section_summary_off">ĐĄĐĩĐēŅииŅĐĩ \"ĐŅĐĩĐŋĐžŅŅŅаĐŊи ĐŧĐĩŅŅа\", \"ĐĐŗŅи\", \"ĐŅСиĐēа\" и \"ĐĄĐŋĐžĐŧĐĩĐŊаŅи Ņ
ĐžŅа\" Ņа ĐŋĐžĐēаСаĐŊи</string>
|
||||
@@ -313,9 +265,12 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">ĐĐžĐēаСаĐŊĐž в ŅŅОдĐŊи видĐĩĐžĐēĐģиĐŋОвĐĩ</string>
|
||||
<string name="revanced_comments_screen_title">ĐĐžĐŧĐĩĐŊŅаŅи</string>
|
||||
<string name="revanced_comments_screen_summary">ĐĄĐēŅиваĐŊĐĩ иĐģи ĐŋĐžĐēаСваĐŊĐĩ ĐŊа ŅĐĩĐēŅиŅŅа Са ĐēĐžĐŧĐĩĐŊŅаŅи</string>
|
||||
<string name="revanced_hide_comments_chat_summary_title">ĐĄĐēŅиваĐŊĐĩ ĐŊа \"Đ ĐĩСŅĐŧĐĩ ĐŊа ŅаŅа\"</string>
|
||||
<string name="revanced_hide_comments_chat_summary_summary_on">Đ ĐĩСŅĐŧĐĩŅĐž ĐŊа ŅаŅа Đĩ ŅĐēŅиŅĐž</string>
|
||||
<string name="revanced_hide_comments_chat_summary_summary_off">Đ ĐĩСŅĐŧĐĩŅĐž ĐŊа ŅаŅа Đĩ ĐŋĐžĐēаСаĐŊĐž</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_title">ĐĄĐēŅиваĐŊĐĩ ĐŊа ŅĐĩСŅĐŧĐĩŅĐž ĐŊа AI Chat</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_on">Đ ĐĩСŅĐŧĐĩŅĐž ĐŊа ŅаŅа Đĩ ŅĐēŅиŅĐž</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_off">Đ ĐĩСŅĐŧĐĩŅĐž ĐŊа ŅаŅа Đĩ ĐŋĐžĐēаСаĐŊĐž</string>
|
||||
<string name="revanced_hide_comments_ai_summary_title">ĐĄĐēŅиваĐŊĐĩ ĐŊа ŅĐĩСŅĐŧĐĩŅĐž ĐŊа AI ĐēĐžĐŧĐĩĐŊŅаŅиŅĐĩ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_on">Đ ĐĩСŅĐŧĐĩŅĐž ĐŊа ĐēĐžĐŧĐĩĐŊŅаŅиŅĐĩ Đĩ ŅĐēŅиŅĐž</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_off">Đ ĐĩСŅĐŧĐĩŅĐž ĐŊа ĐēĐžĐŧĐĩĐŊŅаŅиŅĐĩ Đĩ ĐŋĐžĐēаСаĐŊĐž</string>
|
||||
<string name="revanced_hide_comments_by_members_header_title">ĐĄĐēŅиваĐŊĐĩ ĐŊа âĐĐžĐŧĐĩĐŊŅаŅи, ĐŊаĐŋŅавĐĩĐŊи ĐžŅ ŅĐģĐĩĐŊОвĐĩâ</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_on">ĐĐ°ĐŗĐģавиĐĩŅĐž ĐŊа ĐēĐžĐŧĐĩĐŊŅаŅиŅĐĩ ĐžŅ ŅĐģĐĩĐŊОвĐĩ Đĩ ŅĐēŅиŅĐž</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_off">ĐĐ°ĐŗĐģавиĐĩŅĐž ĐŊа ĐēĐžĐŧĐĩĐŊŅаŅиŅĐĩ ĐžŅ ŅĐģĐĩĐŊОвĐĩ Đĩ ĐŋĐžĐēаСаĐŊĐž</string>
|
||||
@@ -362,7 +317,7 @@ Second \"item\" text"</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_phrases_title">ĐĐģŅŅОви Đ´ŅĐŧи, ĐēОиŅĐž да ĐąŅĐ´Đ°Ņ ŅĐēŅиŅи</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
<!-- For localization, it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">"ĐĐģŅŅОви Đ´ŅĐŧи и ŅŅаСи Са ŅĐēŅиваĐŊĐĩ, ŅаСдĐĩĐģĐĩĐŊи ĐžŅ ĐŊОв ŅĐĩĐ´
|
||||
|
||||
@@ -377,7 +332,7 @@ Second \"item\" text"</string>
|
||||
âĸ ĐŅĐēОи UI ĐēĐžĐŧĐŋĐžĐŊĐĩĐŊŅи ĐŧĐžĐļĐĩ да ĐŊĐĩ Ņа ŅĐēŅиŅи
|
||||
âĸ ĐĸŅŅŅĐĩĐŊĐĩŅĐž ĐŊа ĐēĐģŅŅОва Đ´ŅĐŧа ĐŧĐžĐļĐĩ да ĐŊĐĩ ĐŋĐžĐēаĐļĐĩ ŅĐĩСŅĐģŅаŅи"</string>
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_title">ĐĄŅвĐŋадĐĩĐŊиĐĩ ĐŊа вŅиŅĐēи Đ´ŅĐŧи</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc.) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_summary">ĐĐŗŅаĐļдаĐŊĐĩŅĐž ĐŊа ĐēĐģŅŅОва Đ´ŅĐŧа/ŅŅаСа Ņ Đ´Đ˛ĐžĐšĐŊи ĐēавиŅĐēи ŅĐĩ ĐŋŅĐĩĐ´ĐžŅвŅаŅи ŅаŅŅиŅĐŊи ŅŅвĐŋадĐĩĐŊĐ¸Ņ ĐŊа ĐˇĐ°ĐŗĐģĐ°Đ˛Đ¸Ņ ĐŊа видĐĩĐžĐēĐģиĐŋОвĐĩ и иĐŧĐĩĐŊа ĐŊа ĐēаĐŊаĐģи<br><br>ĐаĐŋŅиĐŧĐĩŅ,<br><b>\"ai\"</b> ŅĐĩ ŅĐēŅиĐĩ видĐĩĐžĐēĐģиĐŋа: <b>How does AI work?</b><br>ĐŊĐž ĐŊŅĐŧа да ŅĐēŅиĐĩ: <b>What does fair use mean?</b></string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">ĐĐĩ ĐŧĐžĐļĐĩŅĐĩ да иСĐŋĐžĐģСваŅĐĩ ĐēĐģŅŅОваŅа Đ´ŅĐŧа: %s</string>
|
||||
@@ -404,7 +359,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_title">ĐĄĐēŅиваĐŊĐĩ ĐŊа ŅаĐŧĐžŅĐŋĐžĐŊŅĐžŅиŅаĐŊи ĐēаŅŅи</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_on">ХаĐŧĐžŅĐŋĐžĐŊŅĐžŅиŅаĐŊиŅĐĩ ĐēаŅŅи Ņа ŅĐēŅиŅи</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_off">ХаĐŧĐžŅĐŋĐžĐŊŅĐžŅиŅаĐŊиŅĐĩ ĐēаŅŅи Ņа ĐŋĐžĐēаСаĐŊи</string>
|
||||
<string name="revanced_hide_products_banner_title">ĐĄĐēŅиваĐŊĐĩ ĐŊа йаĐŊĐĩŅа Са ĐŋĐžĐēаСваĐŊĐĩ ĐŊа ĐŋŅОдŅĐēŅи</string>
|
||||
<string name="revanced_hide_products_banner_title">ĐĄĐēŅиваĐŊĐĩ ĐŊа йаĐŊĐĩŅа \"ĐŅĐĩĐŗĐģĐĩĐ´ ĐŊа ĐŋŅОдŅĐēŅи\"</string>
|
||||
<string name="revanced_hide_products_banner_summary_on">ĐаĐŊĐĩŅŅŅ Đĩ ŅĐēŅиŅ</string>
|
||||
<string name="revanced_hide_products_banner_summary_off">ĐаĐŊĐĩŅŅŅ Đĩ ĐŋĐžĐēаСаĐŊ</string>
|
||||
<string name="revanced_hide_end_screen_store_banner_title">ĐĄĐēŅиК йаĐŊĐĩŅа Са ŅĐĩĐēĐģаĐŧа в ĐēŅĐ°Ņ ĐŊа ĐĩĐēŅаĐŊа</string>
|
||||
@@ -475,9 +430,9 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_disable_precise_seeking_gesture_summary_off">ĐĐĩŅŅ Đ˛ĐēĐģŅŅĐĩĐŊ</string>
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSeekbarTappingPatch">
|
||||
<string name="revanced_seekbar_tapping_title">ĐĐēŅивиŅаĐŊĐĩ ĐŊа Đ´ĐžĐēĐžŅваĐŊĐĩŅĐž ĐŊа ĐģĐĩĐŊŅаŅа Са вŅĐĩĐŧĐĩ</string>
|
||||
<string name="revanced_seekbar_tapping_summary_on">ФŅĐŊĐēŅиŅŅа âĐĐžĐēĐžŅваĐŊĐĩ Đ´Đž ĐģĐĩĐŊŅаŅа Са ŅŅŅŅĐĩĐŊĐĩâ Đĩ аĐēŅивиŅаĐŊа</string>
|
||||
<string name="revanced_seekbar_tapping_summary_off">ФŅĐŊĐēŅиŅŅа âĐĐžĐēĐžŅваĐŊĐĩ Đ´Đž ĐģĐĩĐŊŅаŅа Са ŅŅŅŅĐĩĐŊĐĩâ Đĩ Đ´ĐĩаĐēŅивиŅаĐŊа</string>
|
||||
<string name="revanced_seekbar_tapping_title">ĐĐēŅивиŅаĐŊĐĩ ĐŊа Đ´ĐžĐēĐžŅваĐŊĐĩ Са ĐŋŅĐĩвŅŅŅаĐŊĐĩ</string>
|
||||
<string name="revanced_seekbar_tapping_summary_on">ĐĐžĐēĐžŅĐŊĐĩŅĐĩ, Са да ŅŅŅŅиŅĐĩ Đĩ аĐēŅивиŅаĐŊĐž</string>
|
||||
<string name="revanced_seekbar_tapping_summary_off">ĐĐžĐēĐžŅваĐŊĐĩŅĐž Са ĐŋŅĐĩвŅŅŅаĐŊĐĩ Đĩ Đ´ĐĩаĐēŅивиŅаĐŊĐž</string>
|
||||
</patch>
|
||||
<patch id="interaction.swipecontrols.swipeControlsResourcePatch">
|
||||
<string name="revanced_swipe_brightness_title">ĐадаваĐŊĐĩ ĐŊа ŅŅĐēĐžŅŅ ŅŅĐĩС ĐŋĐģŅĐˇĐŗĐ°ĐŊĐĩ</string>
|
||||
@@ -490,9 +445,9 @@ Second \"item\" text"</string>
|
||||
|
||||
Đ ĐĩĐŗŅĐģиŅаКŅĐĩ ŅиĐģаŅа ĐŊа СвŅĐēа, ĐēаŅĐž ĐŋĐģŅСĐŊĐĩŅĐĩ вĐĩŅŅиĐēаĐģĐŊĐž ĐžŅ Đ´ŅŅĐŊаŅа ŅŅŅаĐŊа ĐŊа ĐĩĐēŅаĐŊа"</string>
|
||||
<string name="revanced_swipe_volume_summary_off">ĐĐģŅĐˇĐŗĐ°ĐŊĐĩŅĐž Са ŅиĐģа ĐŊа СвŅĐēа ĐŊа ŅŅĐģ ĐĩĐēŅаĐŊ Đĩ Đ´ĐĩаĐēŅивиŅаĐŊĐž</string>
|
||||
<string name="revanced_swipe_press_to_engage_title">ĐĐēŅивиŅаĐŊĐĩ ĐŊа ĐļĐĩŅŅа ĐŊаŅиŅĐēаĐŊĐĩ Са ĐŋŅĐĩĐŧĐĩŅŅваĐŊĐĩ</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_on">ĐĐģŅĐˇĐŗĐ°ĐŊĐĩŅĐž ŅŅĐĩС ĐŊаŅиŅĐēаĐŊĐĩ Đĩ аĐēŅивиŅаĐŊĐž</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_off">ĐĐģŅĐˇĐŗĐ°ĐŊĐĩŅĐž ŅŅĐĩС ĐŊаŅиŅĐēаĐŊĐĩ Đĩ Đ´ĐĩаĐēŅивиŅаĐŊĐž</string>
|
||||
<string name="revanced_swipe_press_to_engage_title">ĐĐēŅивиŅаĐŊĐĩ ĐŊа ĐŊаŅиŅĐēаĐŊĐĩ, Са да ĐŋĐģŅСĐŊĐĩŅĐĩ</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_on">ĐаŅиŅĐēаĐŊĐĩŅĐž, Са да ĐŋĐģŅСĐŊĐĩŅĐĩ, Đĩ аĐēŅивиŅаĐŊĐž</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_off">ĐаŅиŅĐēаĐŊĐĩŅĐž, Са да ĐŋĐģŅСĐŊĐĩŅĐĩ, Đĩ Đ´ĐĩаĐēŅивиŅаĐŊĐž</string>
|
||||
<string name="revanced_swipe_haptic_feedback_title">ĐĐēŅивиŅаĐŊĐĩ ĐŊа Ņ
ĐĩĐŋŅиŅĐŊаŅа ОйŅаŅĐŊа вŅŅСĐēа</string>
|
||||
<string name="revanced_swipe_haptic_feedback_summary_on">ĐĸаĐēŅиĐģĐŊаŅа ОйŅаŅĐŊа вŅŅСĐēа Đĩ аĐēŅивиŅаĐŊа</string>
|
||||
<string name="revanced_swipe_haptic_feedback_summary_off">ĐĸаĐēŅиĐģĐŊаŅа ОйŅаŅĐŊа вŅŅСĐēа Đĩ Đ´ĐĩаĐēŅивиŅаĐŊа</string>
|
||||
@@ -663,7 +618,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">ĐĐžĐģĐŊиŅŅ ĐēĐžĐģĐžĐŊŅиŅŅĐģ ĐŊа ĐŧĐĩĐŊŅŅĐž Са ĐēаŅĐĩŅŅвО ĐŊа видĐĩĐžŅĐž ŅĐĩ ĐŋĐžĐēаСва</string>
|
||||
</patch>
|
||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||
<string name="revanced_hide_player_previous_next_buttons_title">ĐŅŅĐžĐŊи Са ĐŅĐĩдиŅĐŊĐž & ĐĄĐģĐĩдваŅĐž видĐĩĐž</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_title">ĐĄĐēŅиваĐŊĐĩ ĐŊа ĐąŅŅĐžĐŊиŅĐĩ \"ĐŅĐĩдиŅĐĩĐŊ и ĐĄĐģĐĩдваŅ\"</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_summary_on">ĐŅŅĐžĐŊиŅĐĩ Ņа ŅĐēŅиŅи</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_summary_off">ĐŅŅĐžĐŊиŅĐĩ ŅĐĩ ĐŋĐžĐēаСваŅ</string>
|
||||
<string name="revanced_hide_cast_button_title">ĐĄĐēŅиваĐŊĐĩ ĐŊа ĐąŅŅĐžĐŊа Cast</string>
|
||||
@@ -856,7 +811,6 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_ryd_enable_summary_on">ĐĐĩŅ
аŅĐĩŅваĐŊиŅŅа ŅĐĩ ĐŋĐžĐēаСваŅ</string>
|
||||
<string name="revanced_ryd_enable_summary_off">ĐĐĩŅ
аŅĐĩŅваĐŊиŅŅа ĐŊĐĩ ŅĐĩ ĐŋĐžĐēаСваŅ</string>
|
||||
<string name="revanced_ryd_shorts_title">ĐĐžĐē. ĐŊĐĩŅ
аŅĐĩŅваĐŊĐ¸Ņ Đ˛ ĐēŅаŅĐēиŅĐĩ ĐēĐģиĐŋОвĐĩ</string>
|
||||
<string name="revanced_ryd_shorts_summary_on">ĐĐĩŅ
аŅĐĩŅваĐŊиŅŅа ĐŊа Shorts Ņа ĐŋĐžĐēаСаĐŊи</string>
|
||||
<string name="revanced_ryd_shorts_summary_on_disclaimer">"ĐĐĩŅ
аŅĐĩŅваĐŊиŅŅа ĐŊа Shorts Ņа ĐŋĐžĐēаСаĐŊи
|
||||
|
||||
ĐĐŗŅаĐŊиŅĐĩĐŊиĐĩ: ĐĐĩŅ
аŅĐĩŅваĐŊиŅŅа ĐŧĐžĐļĐĩ да ĐŊĐĩ ŅĐĩ ĐŋĐžĐēĐ°ĐˇĐ˛Đ°Ņ Đ˛ ŅĐĩĐļиĐŧ иĐŊĐēĐžĐŗĐŊиŅĐž"</string>
|
||||
@@ -1054,6 +1008,8 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_sb_vote_downvote">ĐŅŅиŅаŅĐĩĐģĐĩĐŊ вОŅ</string>
|
||||
<string name="revanced_sb_vote_category">ĐŅĐžĐŧŅĐŊа ĐŊа ĐēаŅĐĩĐŗĐžŅиŅŅа</string>
|
||||
<string name="revanced_sb_vote_no_segments">ĐŅĐŧа ŅĐĩĐŗĐŧĐĩĐŊŅи, Са ĐēОиŅĐž да ĐŗĐģаŅŅваŅĐĩ</string>
|
||||
<!-- A segment start and end time, such as "02:10 to 03:40" -->
|
||||
<string name="revanced_sb_vote_segment_time_to_from">%1$s Đ´Đž %2$s</string>
|
||||
<string name="revanced_sb_new_segment_choose_category">ĐСйĐĩŅĐĩŅĐĩ ĐēаŅĐĩĐŗĐžŅĐ¸Ņ ŅĐĩĐŗĐŧĐĩĐŊŅ</string>
|
||||
<string name="revanced_sb_new_segment_disabled_category">ĐаŅĐĩĐŗĐžŅиŅŅа Đĩ иСĐēĐģ. в ĐŊаŅŅŅОКĐēиŅĐĩ. ĐĐēĐģ. Ņ ĐˇĐ° да ĐŧĐžĐļĐĩŅĐĩ да иСĐŋŅаŅиŅĐĩ.</string>
|
||||
<string name="revanced_sb_new_segment_title">ĐОва ŅаŅŅ Đ˛ SponsorBlock</string>
|
||||
@@ -1101,6 +1057,7 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_sb_stats_saved_hour_format">%1$s ŅаŅОвĐĩ %2$s ĐŧиĐŊŅŅи</string>
|
||||
<string name="revanced_sb_stats_saved_minute_format">%1$s ĐŧиĐŊŅŅи %2$s ŅĐĩĐēŅĐŊди</string>
|
||||
<string name="revanced_sb_stats_saved_second_format">%s ŅĐĩĐēŅĐŊди</string>
|
||||
<string name="revanced_sb_color_opacity_label">ĐĐĩĐŋŅОСŅаŅĐŊĐžŅŅ:</string>
|
||||
<string name="revanced_sb_color_dot_label">ĐĻвŅŅ:</string>
|
||||
<string name="revanced_sb_color_changed">ĐĻвĐĩŅŅŅ Đĩ ĐŋŅĐžĐŧĐĩĐŊĐĩĐŊ</string>
|
||||
<string name="revanced_sb_color_reset">ĐŅСŅŅаĐŊОви ŅвĐĩŅа</string>
|
||||
@@ -1121,11 +1078,9 @@ Second \"item\" text"</string>
|
||||
ĐŅĐžŅĐŧĐģĐĩĐŊиĐĩ Са ŅайĐģĐĩŅ
|
||||
âĸ ĐŅĐąĐģиĐēаŅииŅĐĩ ĐŊа ОйŅĐŊĐžŅŅŅа Ņа ŅĐēŅиŅи
|
||||
|
||||
ĐŅĐžŅĐŧĐģĐĩĐŊиĐĩ Са авŅĐžĐŧОйиĐģ
|
||||
âĸ ĐĐĩĐŊŅŅĐž âĐŅŅĐžŅĐ¸Ņ ĐŊа ĐŗĐģĐĩдаĐŊĐĩâ Đĩ ŅĐēŅиŅĐž
|
||||
âĸ РаСдĐĩĐģŅŅ âĐ Đ°ĐˇĐŗĐģĐĩдаКâ Đĩ вŅСŅŅаĐŊОвĐĩĐŊ
|
||||
ĐвŅĐžĐŧОйиĐģĐŊĐž ĐžŅĐžŅĐŧĐģĐĩĐŊиĐĩ
|
||||
âĸ Shorts ŅĐĩ ĐžŅваŅŅŅ Đ˛ ОйиĐēĐŊОвĐĩĐŊĐ¸Ņ ĐŋĐģĐĩĐšŅŅ
|
||||
âĸ ĐĐĩĐŊŅаŅа Đĩ ĐžŅĐŗĐ°ĐŊиСиŅаĐŊа ĐŋĐž ŅĐĩĐŧи и ĐēаĐŊаĐģ"</string>
|
||||
âĸ ĐаĐŊаĐģŅŅ Đĩ ĐžŅĐŗĐ°ĐŊиСиŅаĐŊ ĐŋĐž ŅĐĩĐŧи и ĐēаĐŊаĐģи"</string>
|
||||
</patch>
|
||||
<patch id="layout.spoofappversion.spoofAppVersionPatch">
|
||||
<string name="revanced_spoof_app_version_title">ĐОдĐģŅĐŗĐ˛Đ°ĐŊĐĩ Са вĐĩŅŅиŅŅа ĐŊа ĐŋŅиĐģĐžĐļĐĩĐŊиĐĩŅĐž</string>
|
||||
@@ -1140,12 +1095,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 -->
|
||||
<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_2">19.26.42 - ĐŅСŅŅаĐŊОвŅваĐŊĐĩ ĐŊа ŅŅаŅиŅĐĩ иĐēĐžĐŊи Са ĐŊĐ°Đ˛Đ¸ĐŗĐ°ŅиŅ</string>
|
||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - ĐŅСŅŅаĐŊОвĐĩŅĐĩ RYD в ŅĐĩĐļиĐŧ âиĐŊĐēĐžĐŗĐŊиŅĐžâ ĐŊа Shorts</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - ĐŅСŅŅаĐŊОвŅваĐŊĐĩ ĐŊа видĐĩĐž ŅĐēĐžŅĐžŅŅ & в ĐŧĐĩĐŊŅŅĐž Са ĐēаŅĐĩŅŅвО</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - ĐŅСŅŅаĐŊОвŅваĐŊĐĩ ĐŊа Ņай \"ĐийĐģиОŅĐĩĐēа\"</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - ĐŅŅŅаĐŊĐĩ ĐŊа ŅĐĩĐēŅиŅŅа Ņ ĐŋĐģĐĩĐšĐģиŅŅа ĐēŅĐŧ ŅŅаŅĐ¸Ņ ŅŅиĐģ</string>
|
||||
<string name="revanced_spoof_app_version_target_entry_2">19.01.34 - ĐŅСŅŅаĐŊОвŅваĐŊĐĩ ĐŊа ŅŅаŅи иĐēĐžĐŊи Са ĐŊĐ°Đ˛Đ¸ĐŗĐ°ŅиŅ</string>
|
||||
</patch>
|
||||
<patch id="layout.startpage.changeStartPagePatch">
|
||||
<string name="revanced_change_start_page_title">ĐадаК ĐŊаŅаĐģĐŊа ŅŅŅаĐŊиŅа</string>
|
||||
@@ -1195,7 +1145,7 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="layout.miniplayer.miniplayerPatch">
|
||||
<string name="revanced_miniplayer_screen_title">ĐиĐŊиĐŧиСиŅаĐŊ ĐĩĐēŅаĐŊ Са вŅСĐŋŅОиСвĐĩĐļдаĐŊĐĩ</string>
|
||||
<string name="revanced_miniplayer_screen_summary">ĐŅĐžĐŧĐĩĐŊĐĩŅĐĩ ŅŅиĐģа ĐŊа ĐŧиĐŊиĐŧиСиŅаĐŊĐ¸Ņ ĐĩĐēŅаĐŊ Са вŅСĐŋŅОиСвĐĩĐļдаĐŊĐĩ</string>
|
||||
<string name="revanced_miniplayer_screen_summary">ĐŅĐžĐŧŅĐŊа ĐŊа ŅŅиĐģа ĐŊа ĐŧиĐŊиĐŧиСиŅаĐŊ ĐŋĐģĐĩĐšŅŅ Đ˛ ĐŋŅиĐģĐžĐļĐĩĐŊиĐĩŅĐž</string>
|
||||
<string name="revanced_miniplayer_type_title">ĐиĐŊиĐŧиСиŅаĐŊ ŅиĐŋ ĐĩĐēŅаĐŊ Са ĐŗĐģĐĩдаĐŊĐĩ</string>
|
||||
<string name="revanced_miniplayer_type_entry_0">ĐĐĩаĐēŅивиŅаĐŊĐž</string>
|
||||
<string name="revanced_miniplayer_type_entry_1">ĐĐž ĐŋОдŅаСйиŅаĐŊĐĩ</string>
|
||||
@@ -1248,8 +1198,6 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_gradient_loading_screen_title">ФОĐŊ ĐŊа ĐĩĐēŅаĐŊа ĐŋŅи СаŅĐĩĐļдаĐŊĐĩ ĐŊа видĐĩĐž</string>
|
||||
<string name="revanced_gradient_loading_screen_summary_on">ĐĐēŅаĐŊŅŅ ĐˇĐ° СаŅĐĩĐļдаĐŊĐĩ ŅĐĩ иĐŧа ĐŗŅадиĐĩĐŊŅĐĩĐŊ ŅĐžĐŊ</string>
|
||||
<string name="revanced_gradient_loading_screen_summary_off">ĐĐēŅаĐŊŅŅ ĐˇĐ° СаŅĐĩĐļдаĐŊĐĩ ŅĐĩ иĐŧа ĐŋĐģŅŅĐĩĐŊ ŅĐžĐŊ</string>
|
||||
</patch>
|
||||
<patch id="layout.theme.themeResourcePatch">
|
||||
<string name="revanced_seekbar_custom_color_title">ĐŅĐžĐŧŅĐŊа ĐŊа ŅвĐĩŅа ĐŊа иĐŊдиĐēаŅĐžŅа Са вŅĐĩĐŧĐĩ</string>
|
||||
<string name="revanced_seekbar_custom_color_summary_on">ĐĐžĐēаСва ŅĐĩ ĐŋĐĩŅŅĐžĐŊаĐģиСиŅаĐŊ ŅвŅŅ ĐŊа ĐģĐĩĐŊŅаŅа Са ĐŊаĐŋŅĐĩĐ´ŅĐē</string>
|
||||
<string name="revanced_seekbar_custom_color_summary_off">ĐĐžĐēаСва ŅĐĩ ĐžŅĐ¸ĐŗĐ¸ĐŊаĐģĐŊĐ¸Ņ ŅвŅŅ ĐŊа ĐģĐĩĐŊŅаŅа Са ĐŊаĐŋŅĐĩĐ´ŅĐē</string>
|
||||
@@ -1341,8 +1289,8 @@ Second \"item\" text"</string>
|
||||
</patch>
|
||||
<patch id="misc.links.openLinksExternallyPatch">
|
||||
<string name="revanced_external_browser_title">ĐŅваŅŅĐŊĐĩ ĐŊа вŅŅСĐēи в ĐąŅаŅСŅŅа</string>
|
||||
<string name="revanced_external_browser_summary_on">ĐŅваŅŅĐŊĐĩ ĐŊа вŅĐŊŅĐŊи вŅŅСĐēи</string>
|
||||
<string name="revanced_external_browser_summary_off">ĐŅваŅŅĐŊĐĩ ĐŊа вŅŅСĐēи в ĐŋŅиĐģĐžĐļĐĩĐŊиĐĩŅĐž</string>
|
||||
<string name="revanced_external_browser_summary_on">ĐŅваŅŅĐŊĐĩ ĐŊа вŅŅСĐēи вŅв вŅĐŊŅĐĩĐŊ ĐąŅаŅСŅŅ</string>
|
||||
<string name="revanced_external_browser_summary_off">ĐŅваŅŅĐŊĐĩ ĐŊа вŅŅСĐēи вŅв Đ˛ĐŗŅадĐĩĐŊ ĐąŅаŅСŅŅ</string>
|
||||
</patch>
|
||||
<patch id="misc.privacy.removeTrackingQueryParameterPatch">
|
||||
<string name="revanced_remove_tracking_query_parameter_title">ĐŅĐĩĐŧаŅ
ĐŊĐĩŅĐĩ ĐŋаŅаĐŧĐĩŅŅŅа ĐŊа СаŅвĐēаŅа Са ĐŋŅĐžŅĐģĐĩĐ´ŅваĐŊĐĩ</string>
|
||||
@@ -1369,9 +1317,15 @@ Second \"item\" text"</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_mobile_title">ĐŅĐĩĐ´ĐŋĐžŅиŅаĐŊĐž ĐēаŅĐĩŅŅвО ĐŋŅи ĐŧОйиĐģĐŊи даĐŊĐŊи</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_title">ĐаĐŋĐžĐŧĐŊŅĐŊĐĩ ĐŊа ĐŋŅĐžĐŧĐĩĐŊиŅĐĩ в ĐēаŅĐĩŅŅвОŅĐž ĐŊа Shorts</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_summary_on">ĐŅĐžĐŧĐĩĐŊиŅĐĩ в ĐēаŅĐĩŅŅвОŅĐž ŅĐĩ ĐŋŅиĐģĐ°ĐŗĐ°Ņ ĐˇĐ° вŅиŅĐēи Shorts</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_summary_off">ĐŅĐžĐŧĐĩĐŊиŅĐĩ в ĐēаŅĐĩŅŅвОŅĐž ŅĐĩ ĐŋŅиĐģĐ°ĐŗĐ°Ņ ŅаĐŧĐž Са ŅĐĩĐēŅŅĐ¸Ņ Short</string>
|
||||
<string name="revanced_shorts_quality_default_wifi_title">ĐаŅĐĩŅŅвО ĐŋĐž ĐŋОдŅаСйиŅаĐŊĐĩ ĐŊа Shorts вŅв Wi-Fi ĐŧŅĐĩĐļа</string>
|
||||
<string name="revanced_shorts_quality_default_mobile_title">ĐаŅĐĩŅŅвО ĐŋĐž ĐŋОдŅаСйиŅаĐŊĐĩ ĐŊа Shorts в ĐŧОйиĐģĐŊа ĐŧŅĐĩĐļа</string>
|
||||
<string name="revanced_remember_video_quality_mobile">ĐŧОйиĐģĐŊи даĐŊĐŊи</string>
|
||||
<string name="revanced_remember_video_quality_wifi">wi-fi</string>
|
||||
<string name="revanced_remember_video_quality_toast">ĐŅĐžĐŧĐĩĐŊĐĩĐŊĐž ŅŅаĐŊдаŅŅĐŊĐž %1$s ĐēаŅĐĩŅŅвО ĐŊа: %2$s</string>
|
||||
<string name="revanced_remember_video_quality_toast_shorts">ĐŅĐžĐŧĐĩĐŊĐĩĐŊĐž ĐēаŅĐĩŅŅвО ĐŊа Shorts %1$s ĐŊа: %2$s</string>
|
||||
</patch>
|
||||
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
||||
<string name="revanced_playback_speed_dialog_button_title">ĐĐžĐēаСваĐŊĐĩ ĐąŅŅĐžĐŊ Са ŅĐēĐžŅĐžŅŅ</string>
|
||||
@@ -1402,10 +1356,10 @@ Second \"item\" text"</string>
|
||||
<string name="revanced_disable_hdr_video_summary_on">HDR видĐĩĐžŅĐž Đĩ Đ´ĐĩаĐēŅивиŅаĐŊĐž</string>
|
||||
<string name="revanced_disable_hdr_video_summary_off">HDR видĐĩĐžŅĐž Đĩ аĐēŅивиŅаĐŊĐž</string>
|
||||
</patch>
|
||||
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch">
|
||||
<string name="revanced_restore_old_video_quality_menu_title">ĐŅСŅŅаĐŊОвĐĩŅĐĩ ŅŅаŅĐžŅĐž ĐŧĐĩĐŊŅ ĐˇĐ° ĐēаŅĐĩŅŅвО ĐŊа видĐĩĐžŅĐž</string>
|
||||
<string name="revanced_restore_old_video_quality_menu_summary_on">ĐĐžĐēаСва ŅĐĩ ŅŅаŅĐžŅĐž ĐŧĐĩĐŊŅ ĐˇĐ° видĐĩĐž ĐēаŅĐĩŅŅвО</string>
|
||||
<string name="revanced_restore_old_video_quality_menu_summary_off">ĐĄŅаŅĐžŅĐž ĐŧĐĩĐŊŅ ĐˇĐ° видĐĩĐž ĐēаŅĐĩŅŅвО Đĩ ŅĐēŅиŅĐž</string>
|
||||
<patch id="video.quality.advancedVideoQualityMenuPatch">
|
||||
<string name="revanced_advanced_video_quality_menu_title">ĐĐžĐēаСваĐŊĐĩ ĐŊа ĐŧĐĩĐŊŅŅĐž Са ŅаСŅиŅĐĩĐŊĐž ĐēаŅĐĩŅŅвО ĐŊа видĐĩĐžŅĐž</string>
|
||||
<string name="revanced_advanced_video_quality_menu_summary_on">ĐĐžĐēаСва ŅĐĩ ĐŧĐĩĐŊŅŅĐž Са ŅаСŅиŅĐĩĐŊĐž ĐēаŅĐĩŅŅвО ĐŊа видĐĩĐžŅĐž</string>
|
||||
<string name="revanced_advanced_video_quality_menu_summary_off">ĐĐĩĐŊŅŅĐž Са ŅаСŅиŅĐĩĐŊĐž ĐēаŅĐĩŅŅвО ĐŊа видĐĩĐžŅĐž ĐŊĐĩ ŅĐĩ ĐŋĐžĐēаСва</string>
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
||||
<string name="revanced_slide_to_seek_title">ĐĐēŅивиŅаĐŊĐĩ ĐŊа ŅĐģаКд Са ĐŋŅĐĩвŅŅŅаĐŊĐĩ</string>
|
||||
|
||||
@@ -48,57 +48,6 @@ Second \"item\" text"</string>
|
||||
|
||||
āύāϤā§āύ āĻāĻžāώāĻž āĻ
āύā§āĻŦāĻžāĻĻ āĻāϰāϤ⧠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_summary">ReVanced āϏā§āĻāĻŋāĻ āĻāĻŽāĻĻāĻžāύāĻŋ āĻŦāĻž āϰāĻĒā§āϤāĻžāύāĻŋ āĻāϰā§āύ</string>
|
||||
<!-- Settings about dialog. -->
|
||||
@@ -277,6 +226,9 @@ MicroG-āĻāϰ āĻāύā§āϝ āĻŦā§āϝāĻžāĻāĻžāϰāĻŋ āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ
|
||||
<string name="revanced_hide_artist_cards_title">āĻāϰā§āĻāĻŋāϏā§āĻ āĻāĻžāϰā§āĻĄ āϞā§āĻāĻžāύ</string>
|
||||
<string name="revanced_hide_artist_cards_summary_on">āĻāϰā§āĻāĻŋāϏā§āĻ āĻāĻžāϰā§āĻĄ āϞā§āĻāĻŋā§ā§ āϰā§ā§āĻā§</string>
|
||||
<string name="revanced_hide_artist_cards_summary_off">āĻāϰā§āĻāĻŋāϏā§āĻ āĻāĻžāϰā§āĻĄ āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_title">\'AI-āĻā§āύāĻžāϰā§āĻā§āĻĄ āĻāĻŋāĻĄāĻŋāĻ āϏāĻžāϰāϏāĻāĻā§āώā§āĻĒ\' āϞā§āĻāĻžāύ</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_summary_on">āĻāĻŋāĻĄāĻŋāĻ āϏāĻžāϰāϏāĻāĻā§āώā§āĻĒ āĻŦāĻŋāĻāĻžāĻ āϞā§āĻāĻžāύ⧠āĻāĻā§</string>
|
||||
<string name="revanced_hide_ai_generated_video_summary_section_summary_off">āĻāĻŋāĻĄāĻŋāĻ āϏāĻžāϰāϏāĻāĻā§āώā§āĻĒ āĻŦāĻŋāĻāĻžāĻ āĻĻā§āĻāĻžāύ⧠āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_hide_attributes_section_title">āĻŦā§āĻļāĻŋāώā§āĻā§āϝāĻžāĻŦāϞ⧠āϞā§āĻāĻžāύ</string>
|
||||
<string name="revanced_hide_attributes_section_summary_on">āĻŦā§āĻļāĻŋāώā§āĻā§āϝāϝā§āĻā§āϤ āϏā§āĻĨāĻžāύ, āĻā§āĻŽāϏ, āϏāĻā§āĻā§āϤ, āĻāĻŦāĻ āĻāϞā§āϞāĻŋāĻāĻŋāϤ āĻŦā§āϝāĻā§āϤāĻŋ āĻŦāĻŋāĻāĻžāĻāĻā§āϞāĻŋ āϞā§āĻāĻžāύ⧠āĻāĻā§</string>
|
||||
<string name="revanced_hide_attributes_section_summary_off">āĻŦā§āĻļāĻŋāώā§āĻā§āϝāϝā§āĻā§āϤ āϏā§āĻĨāĻžāύ, āĻā§āĻŽāϏ, āϏāĻā§āĻā§āϤ, āĻāĻŦāĻ āĻāϞā§āϞāĻŋāĻāĻŋāϤ āĻŦā§āϝāĻā§āϤāĻŋ āĻŦāĻŋāĻāĻžāĻāĻā§āϞāĻŋ āĻĻā§āĻāĻžāύ⧠āĻšāϝāĻŧā§āĻā§</string>
|
||||
@@ -301,6 +253,7 @@ MicroG-āĻāϰ āĻāύā§āϝ āĻŦā§āϝāĻžāĻāĻžāϰāĻŋ āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ
|
||||
<string name="revanced_hide_description_components_screen_title">āĻāĻŋāĻĄāĻŋāĻāϰ āĻŦāĻŋāĻŦāϰāĻŖ</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_summary">āĻĢāĻŋāĻĄ, āĻ
āύā§āϏāύā§āϧāĻžāύā§āϰ āĻĢāϞāĻžāĻĢāϞ āĻāĻŦāĻ āϏāĻŽā§āĻĒāϰā§āĻāĻŋāϤ āĻāĻŋāĻĄāĻŋāĻāĻā§āϞā§āϤ⧠āĻĢāĻŋāϞā§āĻāĻžāϰ āĻŦāĻžāϰ āϞā§āĻāĻžāύ āĻ
āĻĨāĻŦāĻž āĻĻā§āĻāĻžāύ</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_off">āĻĢāĻŋāĻĄā§ āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āĻšā§ā§āĻā§</string>
|
||||
@@ -312,9 +265,12 @@ MicroG-āĻāϰ āĻāύā§āϝ āĻŦā§āϝāĻžāĻāĻžāϰāĻŋ āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ
|
||||
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">āϏāĻŽā§āĻĒāϰā§āĻāĻŋāϤ āĻāĻŋāĻĄāĻŋāĻāϤ⧠āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_comments_screen_title">āĻŽāύā§āϤāĻŦā§āϝ</string>
|
||||
<string name="revanced_comments_screen_summary">āĻŽāύā§āϤāĻŦā§āϝ āĻŦāĻŋāĻāĻžāĻā§āϰ āĻāĻĒāĻžāĻĻāĻžāύāĻā§āϞāĻŋ āϞā§āĻāĻžāύ āĻŦāĻž āĻĻā§āĻāĻžāύ⧎</string>
|
||||
<string name="revanced_hide_comments_chat_summary_title">\'Chat summary\' āϞā§āĻāĻžāύ</string>
|
||||
<string name="revanced_hide_comments_chat_summary_summary_on">āĻā§āϝāĻžāĻ āϏāĻžāϰāϏāĻāĻā§āώā§āĻĒ āϞā§āĻāĻžāύ⧠āĻāĻā§</string>
|
||||
<string name="revanced_hide_comments_chat_summary_summary_off">āĻā§āϝāĻžāĻ āϏāĻžāϰāϏāĻāĻā§āώā§āĻĒ āĻĻā§āĻāĻžāύ⧠āĻšāϝāĻŧā§āĻā§</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_title">āĻāĻāĻ āĻā§āϝāĻžāĻ āϏāĻāĻā§āώāĻŋāĻĒā§āϤāϏāĻžāϰ āϞā§āĻāĻžāύ</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_on">āĻā§āϝāĻžāĻ āϏāĻāĻā§āώāĻŋāĻĒā§āϤāϏāĻžāϰ āϞā§āĻāĻžāύ⧠āĻāĻā§</string>
|
||||
<string name="revanced_hide_comments_ai_chat_summary_summary_off">āĻā§āϝāĻžāĻ āϏāĻāĻā§āώāĻŋāĻĒā§āϤāϏāĻžāϰ āĻĻā§āĻāĻžāύ⧠āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_hide_comments_ai_summary_title">āĻāĻāĻ āĻŽāύā§āϤāĻŦā§āϝ āϏāĻāĻā§āώāĻŋāĻĒā§āϤāϏāĻžāϰ āϞā§āĻāĻžāύ</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_on">āĻŽāύā§āϤāĻŦā§āϝ āϏāĻāĻā§āώāĻŋāĻĒā§āϤāϏāĻžāϰ āϞā§āĻāĻžāύ⧠āĻāĻā§</string>
|
||||
<string name="revanced_hide_comments_ai_summary_summary_off">āĻŽāύā§āϤāĻŦā§āϝ āϏāĻāĻā§āώāĻŋāĻĒā§āϤāϏāĻžāϰ āĻĻā§āĻāĻžāύ⧠āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_hide_comments_by_members_header_title">\'āĻŽā§āĻŽā§āĻŦāĻžāϰāĻĻā§āϰ āĻŽāύā§āϤāĻŦā§āϝ\' āĻšā§āĻĄāĻžāϰ āϞā§āĻāĻžāύ</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_on">āϏāĻĻāϏā§āϝāĻĻā§āϰ āĻĻā§āĻŦāĻžāϰāĻž āĻŽāύā§āϤāĻŦā§āϝ āĻšā§āĻĄāĻžāϰ āϞā§āĻāĻžāύ⧠āĻāĻā§</string>
|
||||
<string name="revanced_hide_comments_by_members_header_summary_off">āϏāĻĻāϏā§āϝāĻĻā§āϰ āĻĻā§āĻŦāĻžāϰāĻž āĻŽāύā§āϤāĻŦā§āϝ āĻšā§āĻĄāĻžāϰ āĻĻā§āĻāĻžāύ⧠āĻšāϝāĻŧā§āĻā§</string>
|
||||
@@ -361,7 +317,7 @@ MicroG-āĻāϰ āĻāύā§āϝ āĻŦā§āϝāĻžāĻāĻžāϰāĻŋ āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ
|
||||
<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_phrases_title">āϞā§āĻāĻžāύā§āϰ āĻāύā§āϝ āĻā§āĻā§āĻžāϰā§āĻĄ</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
<!-- For localization, it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">"āύāϤā§āύ āϞāĻžāĻāύ āĻĻā§āĻŦāĻžāϰāĻž āĻĒā§āĻĨāĻ āĻāϰāĻž āϞā§āĻāĻžāύā§āϰ āĻāύā§āϝ āĻāĻŋāĻāϝāĻŧāĻžāϰā§āĻĄ āĻāĻŦāĻ āĻŦāĻžāĻā§āϝāĻžāĻāĻļ
|
||||
|
||||
@@ -376,7 +332,7 @@ MicroG-āĻāϰ āĻāύā§āϝ āĻŦā§āϝāĻžāĻāĻžāϰāĻŋ āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ
|
||||
âĸ āĻāĻŋāĻā§ UI āĻāĻĒāĻžāĻĻāĻžāύ āϞā§āĻāĻžāύ⧠āύāĻžāĻ āĻšāϤ⧠āĻĒāĻžāϰā§
|
||||
âĸ āĻā§āύāĻ āĻāĻŋāĻāϝāĻŧāĻžāϰā§āĻĄ āĻ
āύā§āϏāύā§āϧāĻžāύ āĻāϰāϞ⧠āĻā§āύāĻ āĻĢāϞāĻžāĻĢāϞ āύāĻžāĻ āĻĻā§āĻāĻžāϤ⧠āĻĒāĻžāϰā§"</string>
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_title">āϏāĻŽā§āĻĒā§āϰā§āĻŖ āĻļāĻŦā§āĻĻ āĻŽā§āϞāĻžāĻ</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc.) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_summary">āĻĄāĻžāĻŦāϞ āĻā§āĻā§āϰ āĻŽāϧā§āϝ⧠āĻāĻāĻāĻŋ āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ/āĻĢā§āϰā§āĻ āϰāĻžāĻāϞ⧠āĻāĻŋāĻĄāĻŋāĻ āĻļāĻŋāϰā§āύāĻžāĻŽ āĻāĻŦāĻ āĻā§āϝāĻžāύā§āϞā§āϰ āύāĻžāĻŽā§āϰ āĻāĻāĻļāĻŋāĻ āĻŽāĻŋāϞ āϏāύāĻžāĻā§āϤ āĻāϰāĻž āĻŦāύā§āϧ āĻšā§ā§ āϝāĻžāĻŦā§<br><br>āĻāĻĻāĻžāĻšāϰāĻŖāϏā§āĻŦāϰā§āĻĒ,<br><b>\"ai\"</b> āĻāĻŋāĻĄāĻŋāĻāĻāĻŋ āϞā§āĻāĻŋāϝāĻŧā§ āĻĻā§āĻŦā§: <b>How does AI work?</b><br>āĻāĻŋāύā§āϤ⧠āϞā§āĻāĻŋāϝāĻŧā§ āĻĻā§āĻŦā§ āύāĻž: <b>What does fair use mean?</b></string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">āĻāĻŋāĻāϝāĻŧāĻžāϰā§āĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž āϝāĻžāĻŦā§ āύāĻž: %s</string>
|
||||
@@ -403,7 +359,7 @@ MicroG-āĻāϰ āĻāύā§āϝ āĻŦā§āϝāĻžāĻāĻžāϰāĻŋ āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ
|
||||
<string name="revanced_hide_self_sponsor_ads_title">āϏā§āĻŦ-āϏā§āĻĒāύā§āϏāϰ āĻāĻžāϰā§āĻĄ āϞā§āĻāĻžāύ</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_on">āϏā§āĻŦ-āϏā§āĻĒāύā§āϏāϰ āĻāĻžāϰā§āĻĄ āϞā§āĻāĻŋā§ā§ āϰā§ā§āĻā§</string>
|
||||
<string name="revanced_hide_self_sponsor_ads_summary_off">āϏā§āĻŦ-āϏā§āĻĒāύā§āϏāϰ āĻāĻžāϰā§āĻĄ āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_hide_products_banner_title">āĻĒā§āϰā§āĻĄāĻžāĻā§āĻ āĻĻā§āĻāĻžāϰ āĻŦā§āϝāĻžāύāĻžāϰ āϞā§āĻāĻžāύ</string>
|
||||
<string name="revanced_hide_products_banner_title">\'āĻĒāĻŖā§āϝ āĻĻā§āĻā§āύ\' āĻŦā§āϝāĻžāύāĻžāϰ āϞā§āĻāĻžāύ</string>
|
||||
<string name="revanced_hide_products_banner_summary_on">āĻŦā§āϝāĻžāύāĻžāϰ āϞā§āĻāĻŋā§ā§ āϰā§ā§āĻā§</string>
|
||||
<string name="revanced_hide_products_banner_summary_off">āĻŦā§āϝāĻžāύāĻžāϰ āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_hide_end_screen_store_banner_title">āĻļā§āώ āĻĒāϰā§āĻĻāĻžāϰ āϏā§āĻā§āϰ āĻŦā§āϝāĻžāύāĻžāϰ āϞā§āĻāĻžāύ</string>
|
||||
@@ -474,9 +430,9 @@ MicroG-āĻāϰ āĻāύā§āϝ āĻŦā§āϝāĻžāĻāĻžāϰāĻŋ āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ
|
||||
<string name="revanced_disable_precise_seeking_gesture_summary_off">āĻ
āĻā§āĻāĻāĻā§āĻāĻŋ āϏāĻā§āϰāĻŋā§ āĻāϰāĻž āĻšā§ā§āĻā§</string>
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSeekbarTappingPatch">
|
||||
<string name="revanced_seekbar_tapping_title">āϏāĻŋāĻāĻŦāĻžāϰ⧠āĻāĻžāĻĒ āĻĻā§āĻā§āĻž āϏāĻā§āϰāĻŋā§ āĻāϰā§āύ</string>
|
||||
<string name="revanced_seekbar_tapping_summary_on">āϏāĻŋāĻāĻŦāĻžāϰ⧠āĻāĻžāĻĒ āĻĻā§āĻā§āĻž āϏāĻā§āϰāĻŋā§ āĻāϰāĻž āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_seekbar_tapping_summary_off">āϏāĻŋāĻāĻŦāĻžāϰ⧠āĻāĻžāĻĒ āĻĻā§āĻā§āĻž āύāĻŋāώā§āĻā§āϰāĻŋā§ āĻāϰāĻž āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_seekbar_tapping_title">āĻāĻŋāĻĄāĻŋāĻāϰ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻ
āĻāĻļā§ āϝā§āϤ⧠āĻā§āϝāĻžāĻĒ āĻāϰāĻž āϏāĻā§āϰāĻŋā§ āĻāϰā§āύ</string>
|
||||
<string name="revanced_seekbar_tapping_summary_on">āĻā§āϝāĻžāĻĒ āĻāϰ⧠āĻā§āĻāĻāĻž āϏāĻā§āϰāĻŋāϝāĻŧ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§</string>
|
||||
<string name="revanced_seekbar_tapping_summary_off">āĻāĻŋāĻĄāĻŋāĻāϰ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻ
āĻāĻļā§ āϝā§āϤ⧠āĻā§āϝāĻžāĻĒ āĻāϰāĻž āύāĻŋāώā§āĻā§āϰāĻŋāϝāĻŧ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§</string>
|
||||
</patch>
|
||||
<patch id="interaction.swipecontrols.swipeControlsResourcePatch">
|
||||
<string name="revanced_swipe_brightness_title">āĻāĻā§āĻā§āĻŦāϞāϤāĻžāϰ āϏā§āϝāĻŧāĻžāĻāĻĒ āĻ
āĻā§āĻāĻāĻā§āĻāĻŋ āϏāĻā§āϰāĻŋā§ āĻāϰā§āύ</string>
|
||||
@@ -489,9 +445,9 @@ MicroG-āĻāϰ āĻāύā§āϝ āĻŦā§āϝāĻžāĻāĻžāϰāĻŋ āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ
|
||||
|
||||
āϏā§āĻā§āϰāĻŋāύā§āϰ āĻĄāĻžāύ āĻĻāĻŋāĻā§ āĻāϞā§āϞāĻŽā§āĻŦāĻāĻžāĻŦā§ āϏā§āϝāĻŧāĻžāĻāĻĒ āĻāϰ⧠āĻāϞāĻŋāĻāĻŽ āϏāĻžāĻŽāĻā§āĻāϏā§āϝ āĻāϰā§āύ"</string>
|
||||
<string name="revanced_swipe_volume_summary_off">āĻĒā§āϰā§āĻŖ āϏā§āĻā§āϰā§āύ āĻāϞāĻŋāĻāĻŽ āϏā§āϝāĻŧāĻžāĻāĻĒ āύāĻŋāώā§āĻā§āϰāĻŋāϝāĻŧ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§</string>
|
||||
<string name="revanced_swipe_press_to_engage_title">āĻĒā§āϰā§āϏ-āĻā§-āϏā§ā§āĻžāĻāĻĒ āĻ
āĻā§āĻāĻāĻā§āĻāĻŋ āϏāĻā§āϰāĻŋā§ āĻāϰā§āύ</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_on">āĻĒā§āϰā§āϏ-āĻā§-āϏā§ā§āĻžāĻāĻĒ āϏāĻā§āϰāĻŋā§ āĻāϰāĻž āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_off">āĻĒā§āϰā§āϏ-āĻā§-āϏā§ā§āĻžāĻāĻĒ āύāĻŋāώā§āĻā§āϰāĻŋā§ āĻāϰāĻž āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_swipe_press_to_engage_title">āϏā§āϝāĻŧāĻžāĻāĻĒ āĻāϰāĻžāϰ āĻāύā§āϝ āĻĒā§āϰā§āϏ āĻāϰāĻž āĻ
āĻā§āĻāĻāĻā§āĻāĻŋ āϏāĻā§āϰāĻŋā§ āĻāϰā§āύ</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_on">āϏā§āϝāĻŧāĻžāĻāĻĒ āĻāϰāĻžāϰ āĻāύā§āϝ āĻĒā§āϰā§āϏ āĻāϰāĻž āϏāĻā§āϰāĻŋā§ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§</string>
|
||||
<string name="revanced_swipe_press_to_engage_summary_off">āϏā§āϝāĻŧāĻžāĻāĻĒ āĻāϰāĻžāϰ āĻāύā§āϝ āĻĒā§āϰā§āϏ āĻāϰāĻž āύāĻŋāώā§āĻā§āϰāĻŋāϝāĻŧ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§</string>
|
||||
<string name="revanced_swipe_haptic_feedback_title">āĻāĻŽā§āĻĒāύ āĻĒā§āϰāϤāĻŋāĻā§āϰāĻŋāϝāĻŧāĻž āϏāĻā§āϰāĻŋā§ āĻāϰā§āύ</string>
|
||||
<string name="revanced_swipe_haptic_feedback_summary_on">āĻāĻŽā§āĻĒāύ āĻĒā§āϰāϤāĻŋāĻā§āϰāĻŋāϝāĻŧāĻž āϏāĻā§āϰāĻŋā§ āĻāϰāĻž āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_swipe_haptic_feedback_summary_off">āĻāĻŽā§āĻĒāύ āĻĒā§āϰāϤāĻŋāĻā§āϰāĻŋāϝāĻŧāĻž āύāĻŋāώā§āĻā§āϰāĻŋā§ āĻāϰāĻž āĻšā§ā§āĻā§</string>
|
||||
@@ -581,6 +537,9 @@ MicroG-āĻāϰ āĻāύā§āϝ āĻŦā§āϝāĻžāĻāĻžāϰāĻŋ āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ
|
||||
<string name="revanced_hide_subscriptions_button_title">āϏāĻĻāϏā§āϝāϤāĻž āϞā§āĻāĻžāύ</string>
|
||||
<string name="revanced_hide_subscriptions_button_summary_on">āϏāĻĻāϏā§āϝāϤāĻž āύāĻŋāύ āĻŦā§āϤāĻžāĻŽ āϞā§āĻāĻŋā§ā§ āϰā§ā§āĻā§</string>
|
||||
<string name="revanced_hide_subscriptions_button_summary_off">āϏāĻĻāϏā§āϝāϤāĻž āύāĻŋāύ āĻŦā§āϤāĻžāĻŽ āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_hide_notifications_button_title">āĻŦāĻŋāĻā§āĻāĻĒā§āϤāĻŋ āϞā§āĻāĻžāύ</string>
|
||||
<string name="revanced_hide_notifications_button_summary_on">āĻŦāĻŋāĻā§āĻāĻĒā§āϤāĻŋ āĻŦā§āϤāĻžāĻŽ āϞā§āĻāĻžāύ⧠āĻāĻā§</string>
|
||||
<string name="revanced_hide_notifications_button_summary_off">āĻŦāĻŋāĻā§āĻāĻĒā§āϤāĻŋ āĻŦā§āϤāĻžāĻŽ āĻĻā§āĻāĻžāύ⧠āĻšā§ā§āĻā§</string>
|
||||
<!-- 'Notifications' should be translated using the same localized wording YouTube displays the tab. -->
|
||||
<string name="revanced_switch_create_with_notifications_button_title">āϤā§āϰāĻŋ āĻŦā§āϤāĻžāĻŽāĻā§ āĻŦāĻŋāĻā§āĻāĻĒā§āϤāĻŋ āĻŦā§āϤāĻžāĻŽ āĻĻā§āĻŦāĻžāϰāĻž āϏā§āĻāĻ āĻāϰā§āύ</string>
|
||||
<string name="revanced_switch_create_with_notifications_button_summary_on">"āϤā§āϰāĻŋ āĻŦā§āϤāĻžāĻŽāĻāĻŋ āĻŦāĻŋāĻā§āĻāĻĒā§āϤāĻŋ āĻŦā§āϤāĻžāĻŽā§āϰ āϏāĻžāĻĨā§ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰāĻž āĻšāϝāĻŧ
|
||||
@@ -659,7 +618,7 @@ MicroG-āĻāϰ āĻāύā§āϝ āĻŦā§āϝāĻžāĻāĻžāϰāĻŋ āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ
|
||||
<string name="revanced_hide_player_flyout_video_quality_footer_summary_off">āĻāĻŋāĻĄāĻŋāĻ āĻā§āĻŖāĻŽāĻžāύ āĻŽā§āύ⧠āĻĢā§āĻāĻžāϰ āĻĻā§āĻāĻžāύ⧠āĻšāĻā§āĻā§</string>
|
||||
</patch>
|
||||
<patch id="layout.buttons.overlay.hidePlayerOverlayButtonsPatch">
|
||||
<string name="revanced_hide_player_previous_next_buttons_title">āĻĒā§āϰā§āĻŦāĻŦāϰā§āϤ⧠āϞā§āĻāĻžāύ & āĻĒāϰāĻŦāϰā§āϤ⧠āĻāĻŋāĻĄāĻŋāĻ āĻŦā§āϤāĻžāĻŽ</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_title">āĻĒā§āϰā§āĻŦāĻŦāϰā§āϤ⧠āϞā§āĻāĻžāύ & āĻĒāϰāĻŦāϰā§āϤ⧠āĻŦā§āϤāĻžāĻŽ</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_summary_on">āĻŦā§āϤāĻžāĻŽ āϞā§āĻāĻžāύ⧠āĻšāϝāĻŧ</string>
|
||||
<string name="revanced_hide_player_previous_next_buttons_summary_off">āĻŦā§āϤāĻžāĻŽ āĻĻā§āĻāĻžāύ⧠āĻšāϝāĻŧ</string>
|
||||
<string name="revanced_hide_cast_button_title">āĻāĻžāϏā§āĻ āĻŦā§āϤāĻžāĻŽāĻāĻŋ āϞā§āĻāĻžāύ</string>
|
||||
@@ -852,7 +811,6 @@ YouTube āϏā§āĻāĻŋāĻāϏ⧠āĻ
āĻā§ āĻĒā§āϞ⧠āĻĒāϰāĻŋāĻŦāϰā§āϤāύ
|
||||
<string name="revanced_ryd_enable_summary_on">āĻ
āĻĒāĻāύā§āĻĻāĻā§āϞ⧠āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_ryd_enable_summary_off">āĻ
āĻĒāĻāύā§āĻĻāĻā§āϞ⧠āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āĻšā§āύāĻŋ</string>
|
||||
<string name="revanced_ryd_shorts_title">Shorts āĻ āĻ
āĻĒāĻāύā§āĻĻ āĻĻā§āĻāĻžāύ</string>
|
||||
<string name="revanced_ryd_shorts_summary_on">Shorts-āĻ āĻ
āĻĒāĻāύā§āĻĻāĻā§āϞāĻŋ āĻĻā§āĻāĻžāύ⧠āĻšāϝāĻŧā§āĻā§</string>
|
||||
<string name="revanced_ryd_shorts_summary_on_disclaimer">"Shorts-āĻ āĻ
āĻĒāĻāύā§āĻĻāĻā§āϞāĻŋ āĻĻā§āĻāĻžāύ⧠āĻšāϝāĻŧā§āĻā§
|
||||
|
||||
āϏā§āĻŽāĻžāĻŦāĻĻā§āϧāϤāĻž: āĻāĻĻā§āĻŽāĻŦā§āĻļā§ āĻŽā§āĻĄā§ āĻ
āĻĒāĻāύā§āĻĻāĻā§āϞāĻŋ āύāĻžāĻ āĻĻā§āĻāĻž āϝā§āϤ⧠āĻĒāĻžāϰā§"</string>
|
||||
@@ -1049,6 +1007,8 @@ YouTube āϏā§āĻāĻŋāĻāϏ⧠āĻ
āĻā§ āĻĒā§āϞ⧠āĻĒāϰāĻŋāĻŦāϰā§āϤāύ
|
||||
<string name="revanced_sb_vote_downvote">āĻĄāĻžāĻāύ āĻā§āĻ</string>
|
||||
<string name="revanced_sb_vote_category">āĻŦāĻŋāĻāĻžāĻ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰā§āύ</string>
|
||||
<string name="revanced_sb_vote_no_segments">āĻā§āĻ āĻĻā§ā§āĻžāϰ āĻāύā§āϝ āĻāϰ āĻā§āύ āϏā§āĻāĻŽā§āύā§āĻ āύā§āĻ</string>
|
||||
<!-- A segment start and end time, such as "02:10 to 03:40" -->
|
||||
<string name="revanced_sb_vote_segment_time_to_from">%1$s āĻĨā§āĻā§ %2$s</string>
|
||||
<string name="revanced_sb_new_segment_choose_category">āϏā§āĻāĻŽā§āύā§āĻā§āϰ āĻŦāĻŋāĻāĻžāĻ āύāĻŋāϰā§āĻŦāĻžāĻāύ āĻāϰā§āύ</string>
|
||||
<string name="revanced_sb_new_segment_disabled_category">āϏā§āĻāĻŋāĻ āĻĨā§āĻā§ āĻŦāĻŋāĻāĻžāĻ āύāĻŋāϏā§āĻā§āϰāĻŋā§ āĻāϰāĻž āĻšā§ā§āĻā§āĨ¤ āĻāĻŽāĻž āĻĻāĻŋāϤ⧠āĻŦāĻŋāĻāĻžāĻ āϏāĻā§āϰāĻŋā§ āĻāϰā§āύāĨ¤</string>
|
||||
<string name="revanced_sb_new_segment_title">āύāϤā§āύ āϏā§āĻĒāύā§āϏāϰāĻŦā§āϞāĻ āϏā§āĻāĻŽā§āύā§āĻ</string>
|
||||
@@ -1097,6 +1057,7 @@ YouTube āϏā§āĻāĻŋāĻāϏ⧠āĻ
āĻā§ āĻĒā§āϞ⧠āĻĒāϰāĻŋāĻŦāϰā§āϤāύ
|
||||
<string name="revanced_sb_stats_saved_hour_format">%1$s āĻāύā§āĻāĻž %2$s āĻŽāĻŋāύāĻŋāĻ</string>
|
||||
<string name="revanced_sb_stats_saved_minute_format">%1$s āĻŽāĻŋāύāĻŋāĻ %2$s āϏā§āĻā§āύā§āĻĄ</string>
|
||||
<string name="revanced_sb_stats_saved_second_format">%s āϏā§āĻā§āύā§āĻĄ</string>
|
||||
<string name="revanced_sb_color_opacity_label">āϏā§āĻŦāĻā§āĻāϤāĻž:</string>
|
||||
<string name="revanced_sb_color_dot_label">āϰāĻ:</string>
|
||||
<string name="revanced_sb_color_changed">āϰāĻ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰāĻž āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_sb_color_reset">āϰāĻ āĻāĻŦāĻžāϰ āϏā§āĻ āĻāϰā§āύ</string>
|
||||
@@ -1112,16 +1073,14 @@ YouTube āϏā§āĻāĻŋāĻāϏ⧠āĻ
āĻā§ āĻĒā§āϞ⧠āĻĒāϰāĻŋāĻŦāϰā§āϤāύ
|
||||
<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 name="revanced_change_form_factor_user_dialog_message">"āĻĒāϰāĻŋāĻŦāϰā§āϤāύāĻā§āϞāĻŋāϰ āĻŽāϧā§āϝ⧠āϰāϝāĻŧā§āĻā§:
|
||||
|
||||
āĻā§āϝāĻžāĻŦāϞā§āĻ āϞā§āĻāĻāĻ
|
||||
âĸ āĻāĻŽāĻŋāĻāύāĻŋāĻāĻŋ āĻĒā§āϏā§āĻ āĻā§āĻĒāύ
|
||||
âĸ āĻāĻŽāĻŋāĻāύāĻŋāĻāĻŋāϰ āĻĒā§āϏā§āĻāĻā§āϞāĻŋ āϞā§āĻāĻžāύ⧠āĻāĻā§
|
||||
|
||||
āϏā§āĻŦāϝāĻŧāĻāĻāĻžāϞāĻŋāϤ āϞā§āĻāĻāĻ
|
||||
âĸ āĻāĻĄāĻŧāĻŋāϰ āĻāϤāĻŋāĻšāĻžāϏ āĻŽā§āύ⧠āĻā§āĻĒāύ
|
||||
âĸ āĻāĻā§āϏāĻĒā§āϞā§āϰ āĻā§āϝāĻžāĻŦ āĻĒā§āύāϰā§āĻĻā§āϧāĻžāϰ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§
|
||||
âĸ āĻļāϰā§āĻāϏ āύāĻŋāϝāĻŧāĻŽāĻŋāϤ āĻĒā§āϞā§āϝāĻŧāĻžāϰ⧠āĻā§āϞā§
|
||||
âĸ āĻĢāĻŋāĻĄ āĻŦāĻŋāώāϝāĻŧ āĻāĻŦāĻ āĻā§āϝāĻžāύā§āϞ āĻĻā§āĻŦāĻžāϰāĻž āϏāĻāĻāĻ āĻŋāϤ āĻšāϝāĻŧ"</string>
|
||||
āĻ
āĻā§āĻŽā§āĻāĻŋāĻ āϞā§āĻāĻāĻ
|
||||
âĸ Shorts āύāĻŋāϝāĻŧāĻŽāĻŋāϤ āĻĒā§āϞā§āϝāĻŧāĻžāϰ⧠āĻā§āϞā§
|
||||
âĸ āĻĢāĻŋāĻĄ āĻŦāĻŋāώāϝāĻŧ āĻāĻŦāĻ āĻā§āϝāĻžāύā§āϞ āĻĻā§āĻŦāĻžāϰāĻž āϏāĻāĻāĻ āĻŋāϤ"</string>
|
||||
</patch>
|
||||
<patch id="layout.spoofappversion.spoofAppVersionPatch">
|
||||
<string name="revanced_spoof_app_version_title">āĻ
ā§āϝāĻžāĻĒ āϏāĻāϏā§āĻāϰāĻŖ āϏā§āĻĒā§āĻĢ āĻāϰā§āύ</string>
|
||||
@@ -1136,12 +1095,7 @@ YouTube āϏā§āĻāĻŋāĻāϏ⧠āĻ
āĻā§ āĻĒā§āϞ⧠āĻĒāϰāĻŋāĻŦāϰā§āϤāύ
|
||||
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
|
||||
<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_2">19.26.42 - āĻĒā§āϰāύ⧠āύā§āĻāĻŋāĻā§āĻļāύ āĻāĻāĻāύ āĻĒā§āύāϰā§āĻĻā§āϧāĻžāϰ āĻāϰā§āύ</string>
|
||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_1">18.33.40 - āĻāĻĻā§āĻŽāĻŦā§āĻļāĻŋ āĻŽā§āĻĄā§ RYD āĻĒā§āύāϰā§āĻĻā§āϧāĻžāϰ āĻāϰā§</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_2">18.20.39 - āĻĒā§āϰāĻļā§āĻŦāϏā§āϤ āĻāĻŋāĻĄāĻŋāĻ āϏā§āĻĒāĻŋāĻĄ āĻāĻŦāĻ āĻā§āĻŖāĻŽāĻžāύ āĻŽā§āύ⧠āĻĒā§āύāϰā§āĻĻā§āϧāĻžāϰ āĻāϰā§</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_3">18.09.39 - āϞāĻžāĻāĻŦā§āϰā§āϰāĻŋ āĻā§āϝāĻžāĻĒ āĻĒā§āύāϰā§āĻĻā§āϧāĻžāϰ āĻāϰā§</string>
|
||||
<string name="revanced_spoof_app_version_target_legacy_entry_4">17.33.42 - āĻĒā§āϰā§āύ⧠āĻĒā§āϞā§āϞāĻŋāϏā§āĻ āĻļā§āϞāĻĢ āĻĒā§āύāϰā§āĻĻā§āϧāĻžāϰ āĻāϰā§</string>
|
||||
<string name="revanced_spoof_app_version_target_entry_2">19.01.34 - āĻĒā§āϰāύ⧠āύā§āĻāĻŋāĻā§āĻļāύ āĻāĻāĻāύ āĻĒā§āύāϰā§āĻĻā§āϧāĻžāϰ āĻāϰā§āύ</string>
|
||||
</patch>
|
||||
<patch id="layout.startpage.changeStartPagePatch">
|
||||
<string name="revanced_change_start_page_title">āĻļā§āϰā§āϰ āĻĒā§āώā§āĻ āĻž āϏā§āĻ āĻāϰā§āύ</string>
|
||||
@@ -1191,7 +1145,7 @@ YouTube āϏā§āĻāĻŋāĻāϏ⧠āĻ
āĻā§ āĻĒā§āϞ⧠āĻĒāϰāĻŋāĻŦāϰā§āϤāύ
|
||||
</patch>
|
||||
<patch id="layout.miniplayer.miniplayerPatch">
|
||||
<string name="revanced_miniplayer_screen_title">āĻŽāĻŋāύāĻŋāĻĒā§āϞā§ā§āĻžāϰ</string>
|
||||
<string name="revanced_miniplayer_screen_summary">āĻ
ā§āϝāĻžāĻĒā§āϰ āĻŽāϧā§āϝāĻāĻžāϰ āĻŽāĻŋāύāĻŋāĻŽāĻžāĻāĻāĻĄ āĻĒā§āϞā§ā§āĻžāϰ āĻāϰ āϧāϰāĻŖ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰā§āύ</string>
|
||||
<string name="revanced_miniplayer_screen_summary">āĻāύ-āĻ
ā§āϝāĻžāĻĒ āĻŽāĻŋāύāĻŋāĻŽāĻžāĻāĻāĻĄ āĻĒā§āϞā§āϝāĻŧāĻžāϰā§āϰ āĻļā§āϞ⧠āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰā§āύ</string>
|
||||
<string name="revanced_miniplayer_type_title">āĻŽāĻŋāύāĻŋāĻĒā§āϞā§ā§āĻžāϰ āϧāϰāĻŖ</string>
|
||||
<string name="revanced_miniplayer_type_entry_0">āύāĻŋāώā§āĻā§āϰāĻŋā§ āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_miniplayer_type_entry_1">āĻĒā§āϰā§āĻŦ-āύāĻŋāϰā§āϧāĻžāϰāĻŋāϤ</string>
|
||||
@@ -1244,8 +1198,6 @@ Miniplayer āϏā§āĻā§āϰāĻŋāύ āĻĨā§āĻā§ āĻŦāĻžāĻŽā§ āĻŦāĻž āĻĄāĻžāύā§
|
||||
<string name="revanced_gradient_loading_screen_title">āĻā§āϰā§āĻĄāĻŋā§ā§āύā§āĻ āϞā§āĻĄāĻŋāĻ āϏā§āĻā§āϰāĻŋāĻŖ āϏāĻā§āϰāĻŋā§ āĻāϰā§āύ</string>
|
||||
<string name="revanced_gradient_loading_screen_summary_on">āϞā§āĻĄāĻŋāĻ āϏā§āĻā§āϰāĻŋāĻŖā§ āĻāĻāĻāĻŋ āĻā§āϰā§āĻĄāĻŋā§ā§āύā§āĻĄ āĻŦā§āϝāĻžāĻāĻā§āϰāĻžāĻāύā§āĻĄ āĻĨāĻžāĻāĻŦā§</string>
|
||||
<string name="revanced_gradient_loading_screen_summary_off">āϞā§āĻĄāĻŋāĻ āϏā§āĻā§āϰāĻŋāĻŖā§ āĻāĻāĻāĻŋ āϏāϞāĻŋāĻĄ āĻŦā§āϝāĻžāĻāĻā§āϰāĻžāĻāύā§āĻĄ āĻĨāĻžāĻāĻŦā§</string>
|
||||
</patch>
|
||||
<patch id="layout.theme.themeResourcePatch">
|
||||
<string name="revanced_seekbar_custom_color_title">āϏāĻŋāĻāĻŦāĻžāϰ⧠āύāĻŋāĻāϏā§āĻŦ āϰāĻ āϏāĻā§āϰāĻŋā§ āĻāϰā§āύ</string>
|
||||
<string name="revanced_seekbar_custom_color_summary_on">āϏāĻŋāĻāĻŦāĻžāϰ⧠āύāĻŋāĻāϏā§āĻŦ āϰāĻ āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_seekbar_custom_color_summary_off">āϏāĻŋāĻāĻŦāĻžāϰ⧠āĻŽā§āϞ āϰāĻ āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āĻšā§ā§āĻā§</string>
|
||||
@@ -1337,8 +1289,8 @@ DeArrow āϏāĻŽā§āĻĒāϰā§āĻā§ āĻāϰāĻ āĻāĻžāύāϤ⧠āĻāĻāĻžāύ⧠āĻ
|
||||
</patch>
|
||||
<patch id="misc.links.openLinksExternallyPatch">
|
||||
<string name="revanced_external_browser_title">āϞāĻŋāĻāĻ āĻŦā§āϰāĻžāĻāĻāĻžāϰ⧠āĻā§āϞā§āύ</string>
|
||||
<string name="revanced_external_browser_summary_on">āϞāĻŋāĻāĻ āĻŦāĻžāĻšāĻŋāϰ⧠āĻā§āϞā§āύ</string>
|
||||
<string name="revanced_external_browser_summary_off">āĻ
ā§āϝāĻžāĻĒā§āϰ āĻŽāϧā§āϝ⧠āϞāĻŋāĻāĻ āĻā§āϞāĻā§</string>
|
||||
<string name="revanced_external_browser_summary_on">āĻŦāĻžāĻšā§āϝāĻŋāĻ āĻŦā§āϰāĻžāĻāĻāĻžāϰ⧠āϞāĻŋāĻā§āĻ āĻā§āϞāĻž āĻšāĻā§āĻā§</string>
|
||||
<string name="revanced_external_browser_summary_off">āĻāύ-āĻ
ā§āϝāĻžāĻĒ āĻŦā§āϰāĻžāĻāĻāĻžāϰ⧠āϞāĻŋāĻā§āĻ āĻā§āϞāĻž āĻšāĻā§āĻā§</string>
|
||||
</patch>
|
||||
<patch id="misc.privacy.removeTrackingQueryParameterPatch">
|
||||
<string name="revanced_remove_tracking_query_parameter_title">āĻā§āϰā§āϝāĻžāĻāĻŋāĻ āĻāϰāĻžāϰ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāĻāĻžāϰ āĻŽā§āĻā§āύ</string>
|
||||
@@ -1365,9 +1317,15 @@ DeArrow āϏāĻŽā§āĻĒāϰā§āĻā§ āĻāϰāĻ āĻāĻžāύāϤ⧠āĻāĻāĻžāύ⧠āĻ
|
||||
<string name="revanced_remember_video_quality_last_selected_summary_off">āĻā§āĻŖāĻŽāĻžāύ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻŦāϰā§āϤāĻŽāĻžāύ āĻāĻŋāĻĄāĻŋāĻāϤ⧠āĻĒā§āϰā§ā§āĻ āĻāϰāĻž āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_video_quality_default_wifi_title">āĻā§āĻžāĻ-āĻĢāĻžāĻ āύā§āĻāĻā§āĻžāϰā§āĻā§ āĻĄāĻŋāĻĢāϞā§āĻ āĻāĻŋāĻĄāĻŋāĻ āĻā§āĻŖāĻŽāĻžāύ</string>
|
||||
<string name="revanced_video_quality_default_mobile_title">āĻŽā§āĻŦāĻžāĻāϞ āύā§āĻāĻā§āĻžāϰā§āĻā§ āĻĄāĻŋāĻĢāϞā§āĻ āĻāĻŋāĻĄāĻŋāĻ āĻā§āĻŖāĻŽāĻžāύ</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_title">Shorts āĻā§āĻŖāĻŽāĻžāύ āĻĒāϰāĻŋāĻŦāϰā§āϤāύā§āϰ āĻāĻĨāĻž āĻŽāύ⧠āϰāĻžāĻā§āύ</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_summary_on">āĻā§āĻŖāĻŽāĻžāύā§āϰ āĻĒāϰāĻŋāĻŦāϰā§āϤāύāĻā§āϞāĻŋ āϏāĻŽāϏā§āϤ Shorts-āĻāϰ āĻāύā§āϝ āĻĒā§āϰāϝā§āĻā§āϝ</string>
|
||||
<string name="revanced_remember_shorts_quality_last_selected_summary_off">āĻā§āĻŖāĻŽāĻžāύā§āϰ āĻĒāϰāĻŋāĻŦāϰā§āϤāύāĻā§āϞāĻŋ āĻļā§āϧā§āĻŽāĻžāϤā§āϰ āĻŦāϰā§āϤāĻŽāĻžāύ Short-āĻāϰ āĻāύā§āϝ āĻĒā§āϰāϝā§āĻā§āϝ</string>
|
||||
<string name="revanced_shorts_quality_default_wifi_title">Wi-Fi āύā§āĻāĻāϝāĻŧāĻžāϰā§āĻā§ āĻĄāĻŋāĻĢāϞā§āĻ Shorts āĻā§āĻŖāĻŽāĻžāύ</string>
|
||||
<string name="revanced_shorts_quality_default_mobile_title">āĻŽā§āĻŦāĻžāĻāϞ āύā§āĻāĻāϝāĻŧāĻžāϰā§āĻā§ āĻĄāĻŋāĻĢāϞā§āĻ Shorts āĻā§āĻŖāĻŽāĻžāύ</string>
|
||||
<string name="revanced_remember_video_quality_mobile">āĻŽā§āĻŦāĻžāĻāϞ</string>
|
||||
<string name="revanced_remember_video_quality_wifi">āĻā§āĻžāĻ-āĻĢāĻžāĻ</string>
|
||||
<string name="revanced_remember_video_quality_toast">āĻĄāĻŋāĻĢāϞā§āĻ %1$s āĻā§āĻŖāĻŽāĻžāύ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻšāĻā§āĻā§: %2$s</string>
|
||||
<string name="revanced_remember_video_quality_toast_shorts">Shorts %1$s āĻāϰ āĻā§āĻŖāĻŽāĻžāύ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰā§: %2$s</string>
|
||||
</patch>
|
||||
<patch id="video.speed.button.playbackSpeedButtonPatch">
|
||||
<string name="revanced_playback_speed_dialog_button_title">āϏā§āĻĒāĻŋāĻĄ āĻĄāĻžā§āĻžāϞāĻ āĻŦā§āϤāĻžāĻŽ āĻĻā§āĻāĻžāύ</string>
|
||||
@@ -1398,10 +1356,10 @@ DeArrow āϏāĻŽā§āĻĒāϰā§āĻā§ āĻāϰāĻ āĻāĻžāύāϤ⧠āĻāĻāĻžāύ⧠āĻ
|
||||
<string name="revanced_disable_hdr_video_summary_on">HDR āĻāĻŋāĻĄāĻŋāĻ āύāĻŋāώā§āĻā§āϰāĻŋāϝāĻŧ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§</string>
|
||||
<string name="revanced_disable_hdr_video_summary_off">HDR āĻāĻŋāĻĄāĻŋāĻ āϏāĻā§āϰāĻŋā§ āĻšāϝāĻŧā§āĻā§</string>
|
||||
</patch>
|
||||
<patch id="video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch">
|
||||
<string name="revanced_restore_old_video_quality_menu_title">āĻĒā§āϰā§āύ⧠āĻāĻŋāĻĄāĻŋāĻ āĻā§āĻŖāĻŽāĻžāύ āĻāĻĻā§āϧāĻžāϰ āĻāϰā§āύ</string>
|
||||
<string name="revanced_restore_old_video_quality_menu_summary_on">āĻĒā§āϰā§āύ⧠āĻāĻŋāĻĄāĻŋāĻ āĻā§āĻŖāĻŽāĻžāύ āĻŽā§āύ⧠āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āĻšā§ā§āĻā§</string>
|
||||
<string name="revanced_restore_old_video_quality_menu_summary_off">āĻĒā§āϰā§āύ⧠āĻāĻŋāĻĄāĻŋāĻ āĻā§āĻŖāĻŽāĻžāύ āĻŽā§āύ⧠āĻĒā§āϰāĻĻāϰā§āĻļāĻŋāϤ āĻšā§āύāĻŋ</string>
|
||||
<patch id="video.quality.advancedVideoQualityMenuPatch">
|
||||
<string name="revanced_advanced_video_quality_menu_title">āĻāύā§āύāϤ āĻāĻŋāĻĄāĻŋāĻ āĻā§āĻŖāĻŽāĻžāύ āĻŽā§āύ⧠āĻĻā§āĻāĻžāύ</string>
|
||||
<string name="revanced_advanced_video_quality_menu_summary_on">āĻāύā§āύāϤ āĻāĻŋāĻĄāĻŋāĻ āĻā§āĻŖāĻŽāĻžāύ āĻŽā§āύ⧠āĻĻā§āĻāĻžāύ⧠āĻšāϝāĻŧā§āĻā§</string>
|
||||
<string name="revanced_advanced_video_quality_menu_summary_off">āĻāύā§āύāϤ āĻāĻŋāĻĄāĻŋāĻ āĻā§āĻŖāĻŽāĻžāύ āĻŽā§āύ⧠āĻĻā§āĻāĻžāύ⧠āĻšāϝāĻŧāύāĻŋ</string>
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.enableSlideToSeekPatch">
|
||||
<string name="revanced_slide_to_seek_title">āĻāĻŋāĻĄāĻŋāĻāϰ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻ
āĻāĻļā§ āϝā§āϤ⧠āĻāĻžāύā§āύ āϏāĻā§āϰāĻŋā§ āĻāϰā§āύ</string>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user