Compare commits

...

30 Commits

Author SHA1 Message Date
semantic-release-bot
2b93ff6cfc chore: Release v5.31.2-dev.1 [skip ci]
## [5.31.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.31.1...v5.31.2-dev.1) (2025-07-12)

### Bug Fixes

* **YouTube - Hide layout components:** Hide quick actions does not work ([#5423](https://github.com/ReVanced/revanced-patches/issues/5423)) ([cc6984e](cc6984e919))
2025-07-12 09:46:21 +00:00
MarcaD
cc6984e919 fix(YouTube - Hide layout components): Hide quick actions does not work (#5423) 2025-07-12 13:43:26 +04:00
github-actions[bot]
8bf575e778 chore: Sync translations (#5427) 2025-07-12 13:42:55 +04:00
semantic-release-bot
2e625ee1a2 chore: Release v5.31.1 [skip ci]
## [5.31.1](https://github.com/ReVanced/revanced-patches/compare/v5.31.0...v5.31.1) (2025-07-11)

### Bug Fixes

* **Spotify - Unlock Premium:** Fix hiding context menu ads for latest version ([#5415](https://github.com/ReVanced/revanced-patches/issues/5415)) ([82255a0](82255a09d3))
2025-07-11 16:28:51 +00:00
oSumAtrIX
6bcba48ee7 chore: Merge branch dev to main (#5414) 2025-07-11 18:25:35 +02:00
semantic-release-bot
c3034edc43 chore: Release v5.31.1-dev.1 [skip ci]
## [5.31.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.31.0...v5.31.1-dev.1) (2025-07-11)

### Bug Fixes

* **Spotify - Unlock Premium:** Fix hiding context menu ads for latest version ([#5415](https://github.com/ReVanced/revanced-patches/issues/5415)) ([82255a0](82255a09d3))
2025-07-11 16:25:25 +00:00
Nuckyz
82255a09d3 fix(Spotify - Unlock Premium): Fix hiding context menu ads for latest version (#5415) 2025-07-11 18:21:49 +02:00
LisoUseInAIKyrios
594dce13cd chore(YouTube): Adjust settings UI text to not clip/wrap 2025-07-11 20:05:52 +04:00
semantic-release-bot
479e205808 chore: Release v5.31.0 [skip ci]
# [5.31.0](https://github.com/ReVanced/revanced-patches/compare/v5.30.0...v5.31.0) (2025-07-11)

### Bug Fixes

* **Bacon Reader - Spoof client:** Use www instead of ssl API to fix auth related issues  ([#5402](https://github.com/ReVanced/revanced-patches/issues/5402)) ([37a8682](37a8682901))
* Correctly name `Enable ROM signature spoofing` patch ([bd2a939](bd2a939a72))
* Fix accidental changes ([42195b9](42195b9f63))
* Fix refactoring typo ([b0129d3](b0129d383a))
* Handle empty list of announcements ([eafe3df](eafe3dfc45))
* **SoundCloud:** Constrain patches to last working app target ([89ec5d5](89ec5d5bc6))
* **Spotify - Unlock Premium:** Remove wrongfully hidden non ad browse sections ([#5403](https://github.com/ReVanced/revanced-patches/issues/5403)) ([b3e6c21](b3e6c215cc))
* **Spotify:** Remove other ads type from the browse screen ([#5333](https://github.com/ReVanced/revanced-patches/issues/5333)) ([4c8cfc8](4c8cfc8800))
* **Sync for Reddit - Spoof client:** Use www instead of ssl API to fix auth related issues ([#5392](https://github.com/ReVanced/revanced-patches/issues/5392)) ([6412a5c](6412a5cb1a))
* **YouTube - Hide ads:** Hide new type of general ad ([#5345](https://github.com/ReVanced/revanced-patches/issues/5345)) ([f9abec3](f9abec358a))
* **YouTube - Hide layout components:** Do not hide playlist sort button if 'Hide AI comments summary' is on ([cc4aef8](cc4aef89d3))
* **YouTube - Playback speed:** Allow custom speeds with 0.01x precision ([#5360](https://github.com/ReVanced/revanced-patches/issues/5360)) ([10f4464](10f4464735))
* **YouTube - Slide to seek:** Show tap and hold 2x speed overlay when active ([#5398](https://github.com/ReVanced/revanced-patches/issues/5398)) ([6833d37](6833d37c26))

### Features

* **Cricbuzz - Hide ads:** Hide Cricbuzz11 UI elements ([#5381](https://github.com/ReVanced/revanced-patches/issues/5381)) ([a3d47e7](a3d47e72e3))
* **Lightroom:** Constrain patches to last working version ([#5335](https://github.com/ReVanced/revanced-patches/issues/5335)) ([f7f49b8](f7f49b834e))
* **Spotify - Spoof client:** Fix issues like songs skipping by spoofing to iOS ([#5388](https://github.com/ReVanced/revanced-patches/issues/5388)) ([65cbf3c](65cbf3c1eb))
* **Spotify:** Remove support for old versions ([#5404](https://github.com/ReVanced/revanced-patches/issues/5404)) ([c9cc3d5](c9cc3d5c41))
* **YouTube - Change header:** Add in-app setting to change the app header ([#5346](https://github.com/ReVanced/revanced-patches/issues/5346)) ([4e74207](4e742075f3))
* **YouTube - Hide layout components:** Add `Hide channel links preview` and `Hide 'Visit Community' button` in channel page ([#5320](https://github.com/ReVanced/revanced-patches/issues/5320)) ([3eac215](3eac215e13))
* **YouTube:** Disable two-finger tap gesture for skipping chapters ([#5374](https://github.com/ReVanced/revanced-patches/issues/5374)) ([61c1a7a](61c1a7a75a))
2025-07-11 15:58:36 +00:00
oSumAtrIX
3d1b7e8101 chore: Merge branch dev to main (#5339) 2025-07-11 17:54:40 +02:00
LisoUseInAIKyrios
e951184b7a chore: Fix announcement url encoding 2025-07-11 19:51:19 +04:00
github-actions[bot]
d088b1e7ed chore: Sync translations (#5411) 2025-07-11 19:48:19 +04:00
semantic-release-bot
a38f635514 chore: Release v5.31.0-dev.17 [skip ci]
# [5.31.0-dev.17](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.16...v5.31.0-dev.17) (2025-07-11)

### Bug Fixes

* **Spotify - Unlock Premium:** Remove wrongfully hidden non ad browse sections ([#5403](https://github.com/ReVanced/revanced-patches/issues/5403)) ([b3e6c21](b3e6c215cc))

### Features

* **Spotify:** Remove support for old versions ([#5404](https://github.com/ReVanced/revanced-patches/issues/5404)) ([c9cc3d5](c9cc3d5c41))
2025-07-11 15:41:53 +00:00
Nuckyz
b3e6c215cc fix(Spotify - Unlock Premium): Remove wrongfully hidden non ad browse sections (#5403) 2025-07-11 17:38:33 +02:00
Nuckyz
c9cc3d5c41 feat(Spotify): Remove support for old versions (#5404) 2025-07-11 17:37:59 +02:00
semantic-release-bot
536e64565c chore: Release v5.31.0-dev.16 [skip ci]
# [5.31.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.15...v5.31.0-dev.16) (2025-07-11)

### Features

* **Spotify - Spoof client:** Fix issues like songs skipping by spoofing to iOS ([#5388](https://github.com/ReVanced/revanced-patches/issues/5388)) ([65cbf3c](65cbf3c1eb))
* **YouTube:** Disable two-finger tap gesture for skipping chapters ([#5374](https://github.com/ReVanced/revanced-patches/issues/5374)) ([61c1a7a](61c1a7a75a))
2025-07-11 15:37:29 +00:00
Dawid Krajcarz
65cbf3c1eb feat(Spotify - Spoof client): Fix issues like songs skipping by spoofing to iOS (#5388)
Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-07-11 17:34:02 +02:00
abel1502
61c1a7a75a feat(YouTube): Disable two-finger tap gesture for skipping chapters (#5374)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-07-11 17:32:59 +02:00
Pun Butrach
1e39db06b8 ci: Remove fetch-depth from checkout (#5311) 2025-07-11 17:31:12 +02:00
Pun Butrach
e019f83232 ci: Group all Dependabot update into one PR (#5336) 2025-07-11 17:31:03 +02:00
semantic-release-bot
3b57a5f8c0 chore: Release v5.31.0-dev.15 [skip ci]
# [5.31.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.14...v5.31.0-dev.15) (2025-07-11)

### Bug Fixes

* Handle empty list of announcements ([eafe3df](eafe3dfc45))
2025-07-11 09:31:21 +00:00
oSumAtrIX
eafe3dfc45 fix: Handle empty list of announcements 2025-07-11 11:28:13 +02:00
semantic-release-bot
d56d8d990c chore: Release v5.31.0-dev.14 [skip ci]
# [5.31.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.13...v5.31.0-dev.14) (2025-07-10)

### Bug Fixes

* **Bacon Reader - Spoof client:** Use www instead of ssl API to fix auth related issues  ([#5402](https://github.com/ReVanced/revanced-patches/issues/5402)) ([37a8682](37a8682901))
2025-07-10 18:51:55 +00:00
Chirag Gada
37a8682901 fix(Bacon Reader - Spoof client): Use www instead of ssl API to fix auth related issues (#5402) 2025-07-10 20:49:04 +02:00
semantic-release-bot
11ba7d4e3e chore: Release v5.31.0-dev.13 [skip ci]
# [5.31.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.12...v5.31.0-dev.13) (2025-07-10)

### Bug Fixes

* **YouTube - Slide to seek:** Show tap and hold 2x speed overlay when active ([#5398](https://github.com/ReVanced/revanced-patches/issues/5398)) ([6833d37](6833d37c26))
2025-07-10 13:38:38 +00:00
LisoUseInAIKyrios
6833d37c26 fix(YouTube - Slide to seek): Show tap and hold 2x speed overlay when active (#5398) 2025-07-10 17:35:08 +04:00
github-actions[bot]
e6f72bcb7d chore: Sync translations (#5399) 2025-07-10 17:34:47 +04:00
LisoUseInAIKyrios
e8a227c082 chore: Fix api dump 2025-07-10 15:15:34 +04:00
semantic-release-bot
0472ec2830 chore: Release v5.31.0-dev.12 [skip ci]
# [5.31.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.11...v5.31.0-dev.12) (2025-07-09)

### Bug Fixes

* **Sync for Reddit - Spoof client:** Use www instead of ssl API to fix auth related issues ([#5392](https://github.com/ReVanced/revanced-patches/issues/5392)) ([6412a5c](6412a5cb1a))
2025-07-09 18:28:47 +00:00
oSumAtrIX
6412a5cb1a fix(Sync for Reddit - Spoof client): Use www instead of ssl API to fix auth related issues (#5392) 2025-07-09 20:25:48 +02:00
129 changed files with 1386 additions and 1401 deletions

View File

@@ -1,22 +1,26 @@
version: 2
multi-ecosystem-groups:
dependency:
schedule:
interval: "weekly"
target-branch: dev
labels: [ ]
updates:
- package-ecosystem: github-actions
labels: []
multi-ecosystem-group: "dependency"
directory: /
target-branch: dev
schedule:
interval: monthly
patterns:
- "*"
- package-ecosystem: npm
labels: []
multi-ecosystem-group: "dependency"
directory: /
target-branch: dev
schedule:
interval: monthly
patterns:
- "*"
- package-ecosystem: gradle
labels: []
multi-ecosystem-group: "dependency"
directory: /
target-branch: dev
schedule:
interval: monthly
patterns:
- "*"

View File

@@ -13,8 +13,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Java
uses: actions/setup-java@v4

View File

@@ -17,7 +17,6 @@ jobs:
uses: actions/checkout@v4
with:
ref: dev
fetch-depth: 0
clean: true
- name: Pull strings

View File

@@ -15,8 +15,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Preprocess strings
env:

View File

@@ -19,8 +19,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Java
uses: actions/setup-java@v4

View File

@@ -1,3 +1,102 @@
## [5.31.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.31.1...v5.31.2-dev.1) (2025-07-12)
### Bug Fixes
* **YouTube - Hide layout components:** Hide quick actions does not work ([#5423](https://github.com/ReVanced/revanced-patches/issues/5423)) ([9c66729](https://github.com/ReVanced/revanced-patches/commit/9c6672946d44001e106bdac9041e2d79ef3f6ab2))
## [5.31.1](https://github.com/ReVanced/revanced-patches/compare/v5.31.0...v5.31.1) (2025-07-11)
### Bug Fixes
* **Spotify - Unlock Premium:** Fix hiding context menu ads for latest version ([#5415](https://github.com/ReVanced/revanced-patches/issues/5415)) ([dcde393](https://github.com/ReVanced/revanced-patches/commit/dcde3935bde3172576d0f9f5ff9eb62ecfff7dfe))
## [5.31.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.31.0...v5.31.1-dev.1) (2025-07-11)
### Bug Fixes
* **Spotify - Unlock Premium:** Fix hiding context menu ads for latest version ([#5415](https://github.com/ReVanced/revanced-patches/issues/5415)) ([dcde393](https://github.com/ReVanced/revanced-patches/commit/dcde3935bde3172576d0f9f5ff9eb62ecfff7dfe))
# [5.31.0](https://github.com/ReVanced/revanced-patches/compare/v5.30.0...v5.31.0) (2025-07-11)
### Bug Fixes
* **Bacon Reader - Spoof client:** Use www instead of ssl API to fix auth related issues ([#5402](https://github.com/ReVanced/revanced-patches/issues/5402)) ([72459bb](https://github.com/ReVanced/revanced-patches/commit/72459bb2eaf4691e32822dfdd1db3240e2fe98dd))
* Correctly name `Enable ROM signature spoofing` patch ([d85881a](https://github.com/ReVanced/revanced-patches/commit/d85881a6768232a999534677bebb248e640fe5ab))
* Fix accidental changes ([e2ac841](https://github.com/ReVanced/revanced-patches/commit/e2ac8419756e3c7d62e2c0430a2918a3c1c63666))
* Fix refactoring typo ([ec0ae42](https://github.com/ReVanced/revanced-patches/commit/ec0ae42496628cdeb2a639020fce94316b41b751))
* Handle empty list of announcements ([de9d720](https://github.com/ReVanced/revanced-patches/commit/de9d7209f4e818a618a7fd9000013ae8ebd728f2))
* **SoundCloud:** Constrain patches to last working app target ([e8ea89f](https://github.com/ReVanced/revanced-patches/commit/e8ea89fc1a3f0531a0af7529663f13328aca4fe7))
* **Spotify - Unlock Premium:** Remove wrongfully hidden non ad browse sections ([#5403](https://github.com/ReVanced/revanced-patches/issues/5403)) ([8633544](https://github.com/ReVanced/revanced-patches/commit/8633544decc0814d7a548fbc5576b4bdd1d7eee0))
* **Spotify:** Remove other ads type from the browse screen ([#5333](https://github.com/ReVanced/revanced-patches/issues/5333)) ([c68533a](https://github.com/ReVanced/revanced-patches/commit/c68533a33a399ca813380b5c9ccddce434ceadf8))
* **Sync for Reddit - Spoof client:** Use www instead of ssl API to fix auth related issues ([#5392](https://github.com/ReVanced/revanced-patches/issues/5392)) ([47e6b62](https://github.com/ReVanced/revanced-patches/commit/47e6b62f3d8b07960cfb2963f441222d3e67df92))
* **YouTube - Hide ads:** Hide new type of general ad ([#5345](https://github.com/ReVanced/revanced-patches/issues/5345)) ([f23716b](https://github.com/ReVanced/revanced-patches/commit/f23716bc52c03d8d0271bfe38b19247e6de7021d))
* **YouTube - Hide layout components:** Do not hide playlist sort button if 'Hide AI comments summary' is on ([5f3e48e](https://github.com/ReVanced/revanced-patches/commit/5f3e48ec5853f6439800ef58239291c34bcab5f6))
* **YouTube - Playback speed:** Allow custom speeds with 0.01x precision ([#5360](https://github.com/ReVanced/revanced-patches/issues/5360)) ([0eecef0](https://github.com/ReVanced/revanced-patches/commit/0eecef00fc93d2a217944978e29dce82e3134e35))
* **YouTube - Slide to seek:** Show tap and hold 2x speed overlay when active ([#5398](https://github.com/ReVanced/revanced-patches/issues/5398)) ([dbc9c5f](https://github.com/ReVanced/revanced-patches/commit/dbc9c5f00c1f5bbb95f8822667cc1ac3c613fa00))
### Features
* **Cricbuzz - Hide ads:** Hide Cricbuzz11 UI elements ([#5381](https://github.com/ReVanced/revanced-patches/issues/5381)) ([a42c98f](https://github.com/ReVanced/revanced-patches/commit/a42c98f8b51fd37d815fd38b75a2b7ccc4fb049b))
* **Lightroom:** Constrain patches to last working version ([#5335](https://github.com/ReVanced/revanced-patches/issues/5335)) ([32ce70e](https://github.com/ReVanced/revanced-patches/commit/32ce70e994f354b9a569376bb89eb38b3190e6f9))
* **Spotify - Spoof client:** Fix issues like songs skipping by spoofing to iOS ([#5388](https://github.com/ReVanced/revanced-patches/issues/5388)) ([e36d4c1](https://github.com/ReVanced/revanced-patches/commit/e36d4c1986b58815c7659e6ef44011166873f9c8))
* **Spotify:** Remove support for old versions ([#5404](https://github.com/ReVanced/revanced-patches/issues/5404)) ([9d31238](https://github.com/ReVanced/revanced-patches/commit/9d31238803a45e957472760fc40c3862da2cf3f0))
* **YouTube - Change header:** Add in-app setting to change the app header ([#5346](https://github.com/ReVanced/revanced-patches/issues/5346)) ([9ba45b6](https://github.com/ReVanced/revanced-patches/commit/9ba45b6680595d732b47e8fa54bee98b7c7af179))
* **YouTube - Hide layout components:** Add `Hide channel links preview` and `Hide 'Visit Community' button` in channel page ([#5320](https://github.com/ReVanced/revanced-patches/issues/5320)) ([9d9cce3](https://github.com/ReVanced/revanced-patches/commit/9d9cce3ec5550b2fea88df745f1700bb2f17eb9e))
* **YouTube:** Disable two-finger tap gesture for skipping chapters ([#5374](https://github.com/ReVanced/revanced-patches/issues/5374)) ([71db0a2](https://github.com/ReVanced/revanced-patches/commit/71db0a2661b5f76eb5048cdeed83f26fbfdf4fee))
# [5.31.0-dev.17](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.16...v5.31.0-dev.17) (2025-07-11)
### Bug Fixes
* **Spotify - Unlock Premium:** Remove wrongfully hidden non ad browse sections ([#5403](https://github.com/ReVanced/revanced-patches/issues/5403)) ([8633544](https://github.com/ReVanced/revanced-patches/commit/8633544decc0814d7a548fbc5576b4bdd1d7eee0))
### Features
* **Spotify:** Remove support for old versions ([#5404](https://github.com/ReVanced/revanced-patches/issues/5404)) ([9d31238](https://github.com/ReVanced/revanced-patches/commit/9d31238803a45e957472760fc40c3862da2cf3f0))
# [5.31.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.15...v5.31.0-dev.16) (2025-07-11)
### Features
* **Spotify - Spoof client:** Fix issues like songs skipping by spoofing to iOS ([#5388](https://github.com/ReVanced/revanced-patches/issues/5388)) ([e36d4c1](https://github.com/ReVanced/revanced-patches/commit/e36d4c1986b58815c7659e6ef44011166873f9c8))
* **YouTube:** Disable two-finger tap gesture for skipping chapters ([#5374](https://github.com/ReVanced/revanced-patches/issues/5374)) ([71db0a2](https://github.com/ReVanced/revanced-patches/commit/71db0a2661b5f76eb5048cdeed83f26fbfdf4fee))
# [5.31.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.14...v5.31.0-dev.15) (2025-07-11)
### Bug Fixes
* Handle empty list of announcements ([de9d720](https://github.com/ReVanced/revanced-patches/commit/de9d7209f4e818a618a7fd9000013ae8ebd728f2))
# [5.31.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.13...v5.31.0-dev.14) (2025-07-10)
### Bug Fixes
* **Bacon Reader - Spoof client:** Use www instead of ssl API to fix auth related issues ([#5402](https://github.com/ReVanced/revanced-patches/issues/5402)) ([72459bb](https://github.com/ReVanced/revanced-patches/commit/72459bb2eaf4691e32822dfdd1db3240e2fe98dd))
# [5.31.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.12...v5.31.0-dev.13) (2025-07-10)
### Bug Fixes
* **YouTube - Slide to seek:** Show tap and hold 2x speed overlay when active ([#5398](https://github.com/ReVanced/revanced-patches/issues/5398)) ([dbc9c5f](https://github.com/ReVanced/revanced-patches/commit/dbc9c5f00c1f5bbb95f8822667cc1ac3c613fa00))
# [5.31.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.11...v5.31.0-dev.12) (2025-07-09)
### Bug Fixes
* **Sync for Reddit - Spoof client:** Use www instead of ssl API to fix auth related issues ([#5392](https://github.com/ReVanced/revanced-patches/issues/5392)) ([47e6b62](https://github.com/ReVanced/revanced-patches/commit/47e6b62f3d8b07960cfb2963f441222d3e67df92))
# [5.31.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v5.31.0-dev.10...v5.31.0-dev.11) (2025-07-09)

View File

@@ -7,7 +7,6 @@ dependencies {
compileOnly(project(":extensions:spotify:stub"))
compileOnly(libs.annotation)
implementation(project(":extensions:spotify:utils"))
implementation(libs.nanohttpd)
implementation(libs.protobuf.javalite)
}

View File

@@ -1,9 +1,11 @@
package app.revanced.extension.spotify.layout.hide.createbutton;
import java.util.List;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.spotify.shared.ComponentFilters.*;
import app.revanced.extension.spotify.shared.ComponentFilters.ComponentFilter;
import app.revanced.extension.spotify.shared.ComponentFilters.ResourceIdComponentFilter;
import app.revanced.extension.spotify.shared.ComponentFilters.StringComponentFilter;
import java.util.List;
@SuppressWarnings("unused")
public final class HideCreateButtonPatch {
@@ -53,7 +55,9 @@ public final class HideCreateButtonPatch {
return null;
}
}
} catch (Exception ex) {
} catch (Throwable ex) {
// Catch Throwable as calling toString can cause crashes with wrongfully generated code that throws
// NoSuchMethod errors.
Logger.printException(() -> "returnNullIfIsCreateButton failure", ex);
}

View File

@@ -0,0 +1,115 @@
package app.revanced.extension.spotify.misc.fix;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.spotify.misc.fix.clienttoken.data.v0.ClienttokenHttp.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import static app.revanced.extension.spotify.misc.fix.Constants.*;
class ClientTokenService {
private static final String IOS_CLIENT_ID = "58bd3c95768941ea9eb4350aaa033eb3";
private static final String IOS_USER_AGENT;
static {
String clientVersion = getClientVersion();
int commitHashIndex = clientVersion.lastIndexOf(".");
String version = clientVersion.substring(
clientVersion.indexOf("-") + 1,
clientVersion.lastIndexOf(".", commitHashIndex - 1)
);
IOS_USER_AGENT = "Spotify/" + version + " iOS/" + getSystemVersion() + " (" + getHardwareMachine() + ")";
}
private static final ConnectivitySdkData.Builder IOS_CONNECTIVITY_SDK_DATA =
ConnectivitySdkData.newBuilder()
.setPlatformSpecificData(PlatformSpecificData.newBuilder()
.setIos(NativeIOSData.newBuilder()
.setHwMachine(getHardwareMachine())
.setSystemVersion(getSystemVersion())
)
);
private static final ClientDataRequest.Builder IOS_CLIENT_DATA_REQUEST =
ClientDataRequest.newBuilder()
.setClientVersion(getClientVersion())
.setClientId(IOS_CLIENT_ID);
private static final ClientTokenRequest.Builder IOS_CLIENT_TOKEN_REQUEST =
ClientTokenRequest.newBuilder()
.setRequestType(ClientTokenRequestType.REQUEST_CLIENT_DATA_REQUEST);
@NonNull
static ClientTokenRequest newIOSClientTokenRequest(String deviceId) {
Logger.printInfo(() -> "Creating new iOS client token request with device ID: " + deviceId);
return IOS_CLIENT_TOKEN_REQUEST
.setClientData(IOS_CLIENT_DATA_REQUEST
.setConnectivitySdkData(IOS_CONNECTIVITY_SDK_DATA
.setDeviceId(deviceId)
)
)
.build();
}
@Nullable
static ClientTokenResponse getClientTokenResponse(@NonNull ClientTokenRequest request) {
if (request.getRequestType() == ClientTokenRequestType.REQUEST_CLIENT_DATA_REQUEST) {
Logger.printInfo(() -> "Requesting iOS client token");
String deviceId = request.getClientData().getConnectivitySdkData().getDeviceId();
request = newIOSClientTokenRequest(deviceId);
}
ClientTokenResponse response;
try {
response = requestClientToken(request);
} catch (IOException ex) {
Logger.printException(() -> "Failed to handle request", ex);
return null;
}
return response;
}
@NonNull
private static ClientTokenResponse requestClientToken(@NonNull ClientTokenRequest request) throws IOException {
HttpURLConnection urlConnection = (HttpURLConnection) new URL(CLIENT_TOKEN_API_URL).openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/x-protobuf");
urlConnection.setRequestProperty("Accept", "application/x-protobuf");
urlConnection.setRequestProperty("User-Agent", IOS_USER_AGENT);
byte[] requestArray = request.toByteArray();
urlConnection.setFixedLengthStreamingMode(requestArray.length);
urlConnection.getOutputStream().write(requestArray);
try (InputStream inputStream = urlConnection.getInputStream()) {
return ClientTokenResponse.parseFrom(inputStream);
}
}
@Nullable
static ClientTokenResponse serveClientTokenRequest(@NonNull InputStream inputStream) {
ClientTokenRequest request;
try {
request = ClientTokenRequest.parseFrom(inputStream);
} catch (IOException ex) {
Logger.printException(() -> "Failed to parse request from input stream", ex);
return null;
}
Logger.printInfo(() -> "Request of type: " + request.getRequestType());
ClientTokenResponse response = getClientTokenResponse(request);
if (response != null) Logger.printInfo(() -> "Response of type: " + response.getResponseType());
return response;
}
}

View File

@@ -0,0 +1,26 @@
package app.revanced.extension.spotify.misc.fix;
import androidx.annotation.NonNull;
class Constants {
static final String CLIENT_TOKEN_API_PATH = "/v1/clienttoken";
static final String CLIENT_TOKEN_API_URL = "https://clienttoken.spotify.com" + CLIENT_TOKEN_API_PATH;
// Modified by a patch. Do not touch.
@NonNull
static String getClientVersion() {
return "";
}
// Modified by a patch. Do not touch.
@NonNull
static String getSystemVersion() {
return "";
}
// Modified by a patch. Do not touch.
@NonNull
static String getHardwareMachine() {
return "";
}
}

View File

@@ -1,158 +0,0 @@
package app.revanced.extension.spotify.misc.fix;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.spotify.login5.v4.proto.Login5.*;
import com.google.protobuf.ByteString;
import com.google.protobuf.MessageLite;
import fi.iki.elonen.NanoHTTPD;
import java.io.ByteArrayInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import static app.revanced.extension.spotify.misc.fix.Session.FAILED_TO_RENEW_SESSION;
import static fi.iki.elonen.NanoHTTPD.Response.Status.INTERNAL_ERROR;
class LoginRequestListener extends NanoHTTPD {
LoginRequestListener(int port) {
super(port);
try {
start();
} catch (IOException ex) {
Logger.printException(() -> "Failed to start login request listener on port " + port, ex);
throw new RuntimeException(ex);
}
}
@NonNull
@Override
public Response serve(IHTTPSession request) {
Logger.printInfo(() -> "Serving request for URI: " + request.getUri());
InputStream requestBodyInputStream = getRequestBodyInputStream(request);
LoginRequest loginRequest;
try {
loginRequest = LoginRequest.parseFrom(requestBodyInputStream);
} catch (IOException ex) {
Logger.printException(() -> "Failed to parse LoginRequest", ex);
return newResponse(INTERNAL_ERROR);
}
MessageLite loginResponse;
// A request may be made concurrently by Spotify,
// however a webview can only handle one request at a time due to singleton cookie manager.
// Therefore, synchronize to ensure that only one webview handles the request at a time.
synchronized (this) {
try {
loginResponse = getLoginResponse(loginRequest);
} catch (Exception ex) {
Logger.printException(() -> "Failed to get login response", ex);
return newResponse(INTERNAL_ERROR);
}
}
return newResponse(Response.Status.OK, loginResponse);
}
private static LoginResponse getLoginResponse(@NonNull LoginRequest loginRequest) {
Session session;
if (!loginRequest.hasStoredCredential()) {
Logger.printInfo(() -> "Received request for initial login");
session = WebApp.currentSession; // Session obtained from WebApp.launchLogin, can be null if still in progress.
} else {
Logger.printInfo(() -> "Received request to restore saved session");
session = Session.read(loginRequest.getStoredCredential().getUsername());
}
return toLoginResponse(session);
}
private static LoginResponse toLoginResponse(@Nullable Session session) {
LoginResponse.Builder builder = LoginResponse.newBuilder();
if (session == null) {
Logger.printException(() -> "Session is null. An initial login may still be in progress, returning try again later error");
builder.setError(LoginError.TRY_AGAIN_LATER);
} else if (session.accessTokenExpired()) {
Logger.printInfo(() -> "Access token expired, renewing session");
WebApp.renewSessionBlocking(session.cookies);
return toLoginResponse(WebApp.currentSession);
} else if (session.username == null) {
Logger.printException(() -> "Session username is null, likely caused by invalid cookies, returning invalid credentials error");
session.delete();
builder.setError(LoginError.INVALID_CREDENTIALS);
} else if (session == FAILED_TO_RENEW_SESSION) {
Logger.printException(() -> "Failed to renew session, likely caused by a timeout, returning try again later error");
builder.setError(LoginError.TRY_AGAIN_LATER);
} else {
session.save();
Logger.printInfo(() -> "Returning session for username: " + session.username);
builder.setOk(LoginOk.newBuilder()
.setUsername(session.username)
.setAccessToken(session.accessToken)
.setStoredCredential(ByteString.fromHex("00")) // Placeholder, as it cannot be null or empty.
.setAccessTokenExpiresIn(session.accessTokenExpiresInSeconds())
.build());
}
return builder.build();
}
@NonNull
private static InputStream limitedInputStream(InputStream inputStream, long contentLength) {
return new FilterInputStream(inputStream) {
private long remaining = contentLength;
@Override
public int read() throws IOException {
if (remaining <= 0) return -1;
int result = super.read();
if (result != -1) remaining--;
return result;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
if (remaining <= 0) return -1;
len = (int) Math.min(len, remaining);
int result = super.read(b, off, len);
if (result != -1) remaining -= result;
return result;
}
};
}
@NonNull
private static InputStream getRequestBodyInputStream(@NonNull IHTTPSession request) {
long requestContentLength =
Long.parseLong(Objects.requireNonNull(request.getHeaders().get("content-length")));
return limitedInputStream(request.getInputStream(), requestContentLength);
}
@SuppressWarnings("SameParameterValue")
@NonNull
private static Response newResponse(Response.Status status) {
return newResponse(status, null);
}
@NonNull
private static Response newResponse(Response.IStatus status, MessageLite messageLite) {
if (messageLite == null) {
return newFixedLengthResponse(status, "application/x-protobuf", null);
}
byte[] messageBytes = messageLite.toByteArray();
InputStream stream = new ByteArrayInputStream(messageBytes);
return newFixedLengthResponse(status, "application/x-protobuf", stream, messageBytes.length);
}
}

View File

@@ -0,0 +1,94 @@
package app.revanced.extension.spotify.misc.fix;
import androidx.annotation.NonNull;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.spotify.misc.fix.clienttoken.data.v0.ClienttokenHttp.ClientTokenResponse;
import com.google.protobuf.MessageLite;
import fi.iki.elonen.NanoHTTPD;
import java.io.ByteArrayInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import static app.revanced.extension.spotify.misc.fix.ClientTokenService.serveClientTokenRequest;
import static app.revanced.extension.spotify.misc.fix.Constants.CLIENT_TOKEN_API_PATH;
import static fi.iki.elonen.NanoHTTPD.Response.Status.INTERNAL_ERROR;
class RequestListener extends NanoHTTPD {
RequestListener(int port) {
super(port);
try {
start();
} catch (IOException ex) {
Logger.printException(() -> "Failed to start request listener on port " + port, ex);
throw new RuntimeException(ex);
}
}
@NonNull
@Override
public Response serve(@NonNull IHTTPSession session) {
String uri = session.getUri();
if (!uri.equals(CLIENT_TOKEN_API_PATH)) return INTERNAL_ERROR_RESPONSE;
Logger.printInfo(() -> "Serving request for URI: " + uri);
ClientTokenResponse response = serveClientTokenRequest(getInputStream(session));
if (response != null) return newResponse(Response.Status.OK, response);
Logger.printException(() -> "Failed to serve client token request");
return INTERNAL_ERROR_RESPONSE;
}
@NonNull
private static InputStream newLimitedInputStream(InputStream inputStream, long contentLength) {
return new FilterInputStream(inputStream) {
private long remaining = contentLength;
@Override
public int read() throws IOException {
if (remaining <= 0) return -1;
int result = super.read();
if (result != -1) remaining--;
return result;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
if (remaining <= 0) return -1;
len = (int) Math.min(len, remaining);
int result = super.read(b, off, len);
if (result != -1) remaining -= result;
return result;
}
};
}
@NonNull
private static InputStream getInputStream(@NonNull IHTTPSession session) {
long requestContentLength = Long.parseLong(Objects.requireNonNull(session.getHeaders().get("content-length")));
return newLimitedInputStream(session.getInputStream(), requestContentLength);
}
private static final Response INTERNAL_ERROR_RESPONSE = newResponse(INTERNAL_ERROR);
@SuppressWarnings("SameParameterValue")
@NonNull
private static Response newResponse(Response.Status status) {
return newResponse(status, null);
}
@NonNull
private static Response newResponse(Response.IStatus status, MessageLite messageLite) {
if (messageLite == null) {
return newFixedLengthResponse(status, "application/x-protobuf", null);
}
byte[] messageBytes = messageLite.toByteArray();
InputStream stream = new ByteArrayInputStream(messageBytes);
return newFixedLengthResponse(status, "application/x-protobuf", stream, messageBytes.length);
}
}

View File

@@ -1,136 +0,0 @@
package app.revanced.extension.spotify.misc.fix;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import org.json.JSONException;
import org.json.JSONObject;
import static android.content.Context.MODE_PRIVATE;
class Session {
/**
* Username of the account. Null if this session does not have an authenticated user.
*/
@Nullable
final String username;
/**
* Access token for this session.
*/
final String accessToken;
/**
* Session expiration timestamp in milliseconds.
*/
final Long expirationTime;
/**
* Authentication cookies for this session.
*/
final String cookies;
/**
* Session that represents a failed attempt to renew the session.
*/
static final Session FAILED_TO_RENEW_SESSION = new Session("", "", "");
/**
* @param username Username of the account. Empty if this session does not have an authenticated user.
* @param accessToken Access token for this session.
* @param cookies Authentication cookies for this session.
*/
Session(@Nullable String username, String accessToken, String cookies) {
this(username, accessToken, System.currentTimeMillis() + 60 * 60 * 1000, cookies);
}
private Session(@Nullable String username, String accessToken, long expirationTime, String cookies) {
this.username = username;
this.accessToken = accessToken;
this.expirationTime = expirationTime;
this.cookies = cookies;
}
/**
* @return The number of milliseconds until the access token expires.
*/
long accessTokenExpiresInMillis() {
long currentTime = System.currentTimeMillis();
return expirationTime - currentTime;
}
/**
* @return The number of seconds until the access token expires.
*/
int accessTokenExpiresInSeconds() {
return (int) accessTokenExpiresInMillis() / 1000;
}
/**
* @return True if the access token has expired, false otherwise.
*/
boolean accessTokenExpired() {
return accessTokenExpiresInMillis() <= 0;
}
void save() {
Logger.printInfo(() -> "Saving session: " + this);
SharedPreferences.Editor editor = Utils.getContext().getSharedPreferences("revanced", MODE_PRIVATE).edit();
String json;
try {
json = new JSONObject()
.put("accessToken", accessToken)
.put("expirationTime", expirationTime)
.put("cookies", cookies).toString();
} catch (JSONException ex) {
Logger.printException(() -> "Failed to convert session to stored credential", ex);
return;
}
editor.putString("session_" + username, json);
editor.apply();
}
void delete() {
Logger.printInfo(() -> "Deleting saved session for username: " + username);
SharedPreferences.Editor editor = Utils.getContext().getSharedPreferences("revanced", MODE_PRIVATE).edit();
editor.remove("session_" + username);
editor.apply();
}
@Nullable
static Session read(String username) {
Logger.printInfo(() -> "Reading saved session for username: " + username);
SharedPreferences sharedPreferences = Utils.getContext().getSharedPreferences("revanced", MODE_PRIVATE);
String savedJson = sharedPreferences.getString("session_" + username, null);
if (savedJson == null) {
Logger.printInfo(() -> "No session found in shared preferences");
return null;
}
try {
JSONObject json = new JSONObject(savedJson);
String accessToken = json.getString("accessToken");
long expirationTime = json.getLong("expirationTime");
String cookies = json.getString("cookies");
return new Session(username, accessToken, expirationTime, cookies);
} catch (JSONException ex) {
Logger.printException(() -> "Failed to read session from shared preferences", ex);
return null;
}
}
@NonNull
@Override
public String toString() {
return "Session(" +
"username=" + username +
", accessToken=" + accessToken +
", expirationTime=" + expirationTime +
", cookies=" + cookies +
')';
}
}

View File

@@ -1,19 +1,15 @@
package app.revanced.extension.spotify.misc.fix;
import android.view.LayoutInflater;
import android.view.View;
import app.revanced.extension.shared.Logger;
@SuppressWarnings("unused")
public class SpoofClientPatch {
private static LoginRequestListener listener;
private static RequestListener listener;
/**
* Injection point.
* <br>
* Launch login server.
* Injection point. Launch requests listener server.
*/
public static void launchListener(int port) {
public synchronized static void launchListener(int port) {
if (listener != null) {
Logger.printInfo(() -> "Listener already running on port " + port);
return;
@@ -21,34 +17,9 @@ public class SpoofClientPatch {
try {
Logger.printInfo(() -> "Launching listener on port " + port);
listener = new LoginRequestListener(port);
listener = new RequestListener(port);
} catch (Exception ex) {
Logger.printException(() -> "launchListener failure", ex);
}
}
/**
* Injection point.
* <br>
* Launch login web view.
*/
public static void launchLogin(LayoutInflater inflater) {
try {
WebApp.launchLogin(inflater.getContext());
} catch (Exception ex) {
Logger.printException(() -> "launchLogin failure", ex);
}
}
/**
* Injection point.
* <br>
* Set handler to call the native login after the webview login.
*/
public static void setNativeLoginHandler(View startLoginButton) {
WebApp.nativeLoginHandler = (() -> {
startLoginButton.setSoundEffectsEnabled(false);
startLoginButton.performClick();
});
}
}

View File

@@ -1,297 +0,0 @@
package app.revanced.extension.spotify.misc.fix;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.view.Window;
import android.view.WindowInsets;
import android.webkit.*;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.spotify.UserAgent;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static app.revanced.extension.spotify.misc.fix.Session.FAILED_TO_RENEW_SESSION;
class WebApp {
private static final String OPEN_SPOTIFY_COM = "open.spotify.com";
private static final String OPEN_SPOTIFY_COM_URL = "https://" + OPEN_SPOTIFY_COM;
private static final String OPEN_SPOTIFY_COM_PREFERENCES_URL = OPEN_SPOTIFY_COM_URL + "/preferences";
private static final String ACCOUNTS_SPOTIFY_COM_LOGIN_URL = "https://accounts.spotify.com/login?allow_password=1"
+ "&continue=https%3A%2F%2Fopen.spotify.com%2Fpreferences";
private static final int GET_SESSION_TIMEOUT_SECONDS = 10;
private static final String JAVASCRIPT_INTERFACE_NAME = "androidInterface";
private static final String USER_AGENT = getWebUserAgent();
/**
* A session obtained from the webview after logging in.
*/
@Nullable
static volatile Session currentSession = null;
/**
* Current webview in use. Any use of the object must be done on the main thread.
*/
@SuppressLint("StaticFieldLeak")
private static volatile WebView currentWebView;
interface NativeLoginHandler {
void login();
}
static NativeLoginHandler nativeLoginHandler;
static void launchLogin(Context context) {
final Dialog dialog = newDialog(context);
Utils.runOnBackgroundThread(() -> {
Logger.printInfo(() -> "Launching login");
// A session must be obtained from a login. Repeat until a session is acquired.
boolean isAcquired = false;
do {
CountDownLatch onLoggedInLatch = new CountDownLatch(1);
CountDownLatch getSessionLatch = new CountDownLatch(1);
// Can't use Utils.getContext() here, because autofill won't work.
// See https://stackoverflow.com/a/79182053/11213244.
launchWebView(context, ACCOUNTS_SPOTIFY_COM_LOGIN_URL, new WebViewCallback() {
@Override
void onInitialized(WebView webView) {
super.onInitialized(webView);
dialog.setContentView(webView);
dialog.show();
}
@Override
void onLoggedIn(String cookies) {
onLoggedInLatch.countDown();
}
@Override
void onReceivedSession(Session session) {
super.onReceivedSession(session);
getSessionLatch.countDown();
dialog.dismiss();
try {
nativeLoginHandler.login();
} catch (Exception ex) {
Logger.printException(() -> "nativeLoginHandler failure", ex);
}
}
});
try {
// Wait indefinitely until the user logs in.
onLoggedInLatch.await();
// Wait until the session is received, or timeout.
isAcquired = getSessionLatch.await(GET_SESSION_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
Logger.printException(() -> "Login interrupted", ex);
Thread.currentThread().interrupt();
}
} while (!isAcquired);
});
}
static void renewSessionBlocking(String cookies) {
Logger.printInfo(() -> "Renewing session with cookies: " + cookies);
CountDownLatch getSessionLatch = new CountDownLatch(1);
launchWebView(Utils.getContext(), OPEN_SPOTIFY_COM_PREFERENCES_URL, new WebViewCallback() {
@Override
public void onInitialized(WebView webView) {
setCookies(cookies);
super.onInitialized(webView);
}
public void onReceivedSession(Session session) {
super.onReceivedSession(session);
getSessionLatch.countDown();
}
});
boolean isAcquired = false;
try {
isAcquired = getSessionLatch.await(GET_SESSION_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
Logger.printException(() -> "Session renewal interrupted", ex);
Thread.currentThread().interrupt();
}
if (!isAcquired) {
Logger.printException(() -> "Failed to retrieve session within " + GET_SESSION_TIMEOUT_SECONDS + " seconds");
currentSession = FAILED_TO_RENEW_SESSION;
destructWebView();
}
}
/**
* All methods are called on the main thread.
*/
abstract static class WebViewCallback {
void onInitialized(WebView webView) {
currentWebView = webView;
currentSession = null; // Reset current session.
}
void onLoggedIn(String cookies) {
}
void onReceivedSession(Session session) {
Logger.printInfo(() -> "Received session: " + session);
currentSession = session;
destructWebView();
}
}
@SuppressLint("SetJavaScriptEnabled")
private static void launchWebView(
Context context,
String initialUrl,
WebViewCallback webViewCallback
) {
Utils.runOnMainThreadNowOrLater(() -> {
WebView webView = new WebView(context);
WebSettings settings = webView.getSettings();
settings.setDomStorageEnabled(true);
settings.setJavaScriptEnabled(true);
settings.setUserAgentString(USER_AGENT);
// WebViewClient is always called off the main thread,
// but callback interface methods are called on the main thread.
webView.setWebViewClient(new WebViewClient() {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
if (OPEN_SPOTIFY_COM.equals(request.getUrl().getHost())) {
Utils.runOnMainThread(() -> webViewCallback.onLoggedIn(getCurrentCookies()));
}
return super.shouldInterceptRequest(view, request);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Logger.printInfo(() -> "Page started loading: " + url);
if (!url.startsWith(OPEN_SPOTIFY_COM_URL)) {
return;
}
Logger.printInfo(() -> "Evaluating script to get session on url: " + url);
String getSessionScript = "Object.defineProperty(Object.prototype, \"_username\", {" +
" configurable: true," +
" set(username) {" +
" accessToken = this._builder?.accessToken;" +
" if (accessToken) {" +
" " + JAVASCRIPT_INTERFACE_NAME + ".getSession(username, accessToken);" +
" delete Object.prototype._username;" +
" }" +
" " +
" Object.defineProperty(this, \"_username\", {" +
" configurable: true," +
" enumerable: true," +
" writable: true," +
" value: username" +
" })" +
" " +
" }" +
"});" +
"if (new URLSearchParams(window.location.search).get('_authfailed') != null) {" +
" " + JAVASCRIPT_INTERFACE_NAME + ".getSession(null, null);" +
"}";
view.evaluateJavascript(getSessionScript, null);
}
});
webView.addJavascriptInterface(new Object() {
@SuppressWarnings("unused")
@JavascriptInterface
public void getSession(String username, String accessToken) {
Session session = new Session(username, accessToken, getCurrentCookies());
Utils.runOnMainThread(() -> webViewCallback.onReceivedSession(session));
}
}, JAVASCRIPT_INTERFACE_NAME);
CookieManager.getInstance().removeAllCookies((anyRemoved) -> {
Logger.printInfo(() -> "Loading URL: " + initialUrl);
webView.loadUrl(initialUrl);
Logger.printInfo(() -> "WebView initialized with user agent: " + USER_AGENT);
webViewCallback.onInitialized(webView);
});
});
}
private static void destructWebView() {
Utils.runOnMainThreadNowOrLater(() -> {
currentWebView.stopLoading();
currentWebView.destroy();
currentWebView = null;
});
}
private static String getWebUserAgent() {
String userAgentString = WebSettings.getDefaultUserAgent(Utils.getContext());
try {
return new UserAgent(userAgentString)
.withCommentReplaced("Android", "Windows NT 10.0; Win64; x64")
.withoutProduct("Mobile")
.toString();
} catch (IllegalArgumentException ex) {
userAgentString = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edge/137.0.0.0";
String fallback = userAgentString;
Logger.printException(() -> "Failed to get user agent, falling back to " + fallback, ex);
}
return userAgentString;
}
@NonNull
private static Dialog newDialog(Context context) {
Dialog dialog = new Dialog(context, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
dialog.setCancelable(false);
// Ensure that the keyboard does not cover the webview content.
Window window = dialog.getWindow();
//noinspection StatementWithEmptyBody
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.getDecorView().setOnApplyWindowInsetsListener((v, insets) -> {
v.setPadding(0, 0, 0, insets.getInsets(WindowInsets.Type.ime()).bottom);
return WindowInsets.CONSUMED;
});
} else {
// TODO: Implement for lower Android versions.
}
return dialog;
}
private static String getCurrentCookies() {
CookieManager cookieManager = CookieManager.getInstance();
return cookieManager.getCookie(OPEN_SPOTIFY_COM_URL);
}
private static void setCookies(@NonNull String cookies) {
CookieManager cookieManager = CookieManager.getInstance();
String[] cookiesList = cookies.split(";");
for (String cookie : cookiesList) {
cookieManager.setCookie(OPEN_SPOTIFY_COM_URL, cookie);
}
}
}

View File

@@ -0,0 +1,73 @@
syntax = "proto3";
package spotify.clienttoken.data.v0;
option optimize_for = LITE_RUNTIME;
option java_package = "app.revanced.extension.spotify.misc.fix.clienttoken.data.v0";
message ClientTokenRequest {
ClientTokenRequestType request_type = 1;
oneof request {
ClientDataRequest client_data = 2;
}
}
enum ClientTokenRequestType {
REQUEST_UNKNOWN = 0;
REQUEST_CLIENT_DATA_REQUEST = 1;
REQUEST_CHALLENGE_ANSWERS_REQUEST = 2;
}
message ClientDataRequest {
string client_version = 1;
string client_id = 2;
oneof data {
ConnectivitySdkData connectivity_sdk_data = 3;
}
}
message ConnectivitySdkData {
PlatformSpecificData platform_specific_data = 1;
string device_id = 2;
}
message PlatformSpecificData {
oneof data {
NativeIOSData ios = 2;
}
}
message NativeIOSData {
int32 user_interface_idiom = 1;
bool target_iphone_simulator = 2;
string hw_machine = 3;
string system_version = 4;
string simulator_model_identifier = 5;
}
message ClientTokenResponse {
ClientTokenResponseType response_type = 1;
oneof response {
GrantedTokenResponse granted_token = 2;
}
}
enum ClientTokenResponseType {
RESPONSE_UNKNOWN = 0;
RESPONSE_GRANTED_TOKEN_RESPONSE = 1;
RESPONSE_CHALLENGES_RESPONSE = 2;
}
message GrantedTokenResponse {
string token = 1;
int32 expires_after_seconds = 2;
int32 refresh_after_seconds = 3;
repeated TokenDomain domains = 4;
}
message TokenDomain {
string domain = 1;
}

View File

@@ -1,43 +0,0 @@
syntax = "proto3";
package spotify.login5.v4;
option optimize_for = LITE_RUNTIME;
option java_package = "app.revanced.extension.spotify.login5.v4.proto";
message StoredCredential {
string username = 1;
bytes data = 2;
}
message LoginRequest {
oneof login_method {
StoredCredential stored_credential = 100;
}
}
message LoginOk {
string username = 1;
string access_token = 2;
bytes stored_credential = 3;
int32 access_token_expires_in = 4;
}
message LoginResponse {
oneof response {
LoginOk ok = 1;
LoginError error = 2;
}
}
enum LoginError {
UNKNOWN_ERROR = 0;
INVALID_CREDENTIALS = 1;
BAD_REQUEST = 2;
UNSUPPORTED_LOGIN_PROTOCOL = 3;
TIMEOUT = 4;
UNKNOWN_IDENTIFIER = 5;
TOO_MANY_ATTEMPTS = 6;
INVALID_PHONENUMBER = 7;
TRY_AGAIN_LATER = 8;
}

View File

@@ -2,7 +2,5 @@ package com.spotify.browsita.v1.resolved;
public final class Section {
public static final int BRAND_ADS_FIELD_NUMBER = 6;
public static final int PROMOTION_V1_FIELD_NUMBER = 3;
public static final int PROMOTION_V3_FIELD_NUMBER = 5;
public int sectionTypeCase_;
}

View File

@@ -1,8 +0,0 @@
package com.spotify.useraccount.v1;
/**
* Used for target 8.6.98.900. Class is still present in newer app targets.
*/
public class AccountAttribute {
public Object value_;
}

View File

@@ -1,19 +0,0 @@
plugins {
java
antlr
}
dependencies {
antlr(libs.antlr4)
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
tasks {
generateGrammarSource {
arguments = listOf("-visitor")
}
}

View File

@@ -1,35 +0,0 @@
grammar UserAgent;
@header { package app.revanced.extension.spotify; }
userAgent
: product (WS product)* EOF
;
product
: name ('/' version)? (WS comment)?
;
name
: STRING
;
version
: STRING ('.' STRING)*
;
comment
: COMMENT
;
COMMENT
: '(' ~ ')'* ')'
;
STRING
: [a-zA-Z0-9]+
;
WS
: [ \r\n]+
;

View File

@@ -1,60 +0,0 @@
package app.revanced.extension.spotify;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStreamRewriter;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
public class UserAgent {
private final UserAgentParser.UserAgentContext tree;
private final TokenStreamRewriter rewriter;
private final ParseTreeWalker walker;
public UserAgent(String userAgentString) {
CharStream input = CharStreams.fromString(userAgentString);
UserAgentLexer lexer = new UserAgentLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
tree = new UserAgentParser(tokens).userAgent();
walker = new ParseTreeWalker();
rewriter = new TokenStreamRewriter(tokens);
}
public UserAgent withoutProduct(String name) {
walker.walk(new UserAgentBaseListener() {
@Override
public void exitProduct(UserAgentParser.ProductContext ctx) {
if (!ctx.name().getText().contains(name)) return;
int startIndex = ctx.getStart().getTokenIndex();
if (startIndex != 0) startIndex -= 1; // Also remove the preceding whitespace.
int stopIndex = ctx.getStop().getTokenIndex();
rewriter.delete(startIndex, stopIndex);
}
}, tree);
return new UserAgent(rewriter.getText().trim());
}
public UserAgent withCommentReplaced(String containing, String replacement) {
walker.walk(new UserAgentBaseListener() {
@Override
public void exitComment(UserAgentParser.CommentContext ctx) {
if (ctx.getText().contains(containing)) {
rewriter.replace(ctx.getStart(), ctx.getStop(), "(" + replacement + ")");
}
}
}, tree);
return new UserAgent(rewriter.getText());
}
@Override
public String toString() {
return rewriter.getText();
}
}

View File

@@ -0,0 +1,16 @@
package app.revanced.extension.youtube.patches;
import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused")
public final class DisableChapterSkipDoubleTapPatch {
/**
* Injection point.
*
* @return If "should skip to chapter start" flag is set.
*/
public static boolean disableDoubleTapChapters(boolean original) {
return original && !Settings.DISABLE_CHAPTER_SKIP_DOUBLE_TAP.get();
}
}

View File

@@ -59,10 +59,11 @@ public final class AnnouncementsPatch {
int id = Settings.ANNOUNCEMENT_LAST_ID.defaultValue;
try {
final var announcementIds = new JSONArray(jsonString);
if (announcementIds.length() == 0) return true;
id = announcementIds.getJSONObject(0).getInt("id");
} catch (Throwable ex) {
Logger.printException(() -> "Failed to parse announcement IDs", ex);
Logger.printException(() -> "Failed to parse announcement ID", ex);
}
// Do not show the announcement, if the last announcement id is the same as the current one.

View File

@@ -10,8 +10,8 @@ import static app.revanced.extension.shared.requests.Route.Method.GET;
public class AnnouncementsRoutes {
private static final String ANNOUNCEMENTS_PROVIDER = "https://api.revanced.app/v4";
public static final Route GET_LATEST_ANNOUNCEMENT_IDS = new Route(GET, "/announcements/latest/id?tag=youtube");
public static final Route GET_LATEST_ANNOUNCEMENTS = new Route(GET, "/announcements/latest?tag=youtube");
public static final Route GET_LATEST_ANNOUNCEMENT_IDS = new Route(GET, "/announcements/latest/id?tag=\uD83C\uDF9E\uFE0F%20YouTube");
public static final Route GET_LATEST_ANNOUNCEMENTS = new Route(GET, "/announcements/latest?tag=\uD83C\uDF9E\uFE0F%20YouTube");
private AnnouncementsRoutes() {
}

View File

@@ -291,6 +291,7 @@ public final class LayoutComponentsFilter extends Filter {
notifyMe,
paidPromotion,
playables,
quickActions,
relatedVideos,
singleItemInformationPanel,
subscribersCommunityGuidelines,

View File

@@ -146,6 +146,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting COPY_VIDEO_URL = new BooleanSetting("revanced_copy_video_url", FALSE);
public static final BooleanSetting COPY_VIDEO_URL_TIMESTAMP = new BooleanSetting("revanced_copy_video_url_timestamp", TRUE);
public static final BooleanSetting DISABLE_AUTO_CAPTIONS = new BooleanSetting("revanced_disable_auto_captions", FALSE, true);
public static final BooleanSetting DISABLE_CHAPTER_SKIP_DOUBLE_TAP = new BooleanSetting("revanced_disable_chapter_skip_double_tap", FALSE);
public static final BooleanSetting DISABLE_FULLSCREEN_AMBIENT_MODE = new BooleanSetting("revanced_disable_fullscreen_ambient_mode", TRUE, true);
public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE);
public static final EnumSetting<FullscreenMode> EXIT_FULLSCREEN = new EnumSetting<>("revanced_exit_fullscreen", FullscreenMode.DISABLED);

View File

@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
org.gradle.parallel = true
android.useAndroidX = true
kotlin.code.style = official
version = 5.31.0-dev.11
version = 5.31.2-dev.1

View File

@@ -904,6 +904,10 @@ public final class app/revanced/patches/shared/misc/spoof/UserAgentClientSpoofPa
public static final fun userAgentClientSpoofPatch (Ljava/lang/String;)Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/shared/misc/string/ReplaceStringPatchKt {
public static final fun replaceStringPatch (Ljava/lang/String;Ljava/lang/String;)Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/solidexplorer2/functionality/filesize/RemoveFileSizeLimitPatchKt {
public static final fun getRemoveFileSizeLimitPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
@@ -1232,6 +1236,10 @@ public final class app/revanced/patches/youtube/interaction/dialog/RemoveViewerD
public static final fun getRemoveViewerDiscretionDialogPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/interaction/doubletap/DisableChapterSkipDoubleTapPatchKt {
public static final fun getDisableChapterSkipDoubleTapPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/interaction/downloads/DownloadsPatchKt {
public static final fun getDownloadsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}

View File

@@ -4,9 +4,16 @@ import app.revanced.patcher.Fingerprint
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patches.reddit.customclients.spoofClientPatch
import app.revanced.patches.shared.misc.string.replaceStringPatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
val spoofClientPatch = spoofClientPatch(redirectUri = "http://baconreader.com/auth") { clientIdOption ->
dependsOn(
// Redirects from SSL to WWW domain are bugged causing auth problems.
// Manually rewrite the URLs to fix this.
replaceStringPatch("ssl.reddit.com", "www.reddit.com")
)
compatibleWith(
"com.onelouder.baconreader",
"com.onelouder.baconreader.premium",

View File

@@ -61,7 +61,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "redditisfun://auth") { cl
// region Patch miscellaneous.
// Reddit messed up and does not append a redirect uri to the authorization url to old.reddit.com/login.
// Replace old.reddit.com with ssl.reddit.com to fix this.
// Replace old.reddit.com with www.reddit.com to fix this.
buildAuthorizationStringFingerprint.method.apply {
val index = indexOfFirstInstructionOrThrow {
getReference<StringReference>()?.contains("old.reddit.com") == true
@@ -70,7 +70,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "redditisfun://auth") { cl
val targetRegister = getInstruction<OneRegisterInstruction>(index).registerA
replaceInstruction(
index,
"const-string v$targetRegister, \"https://ssl.reddit.com/api/v1/authorize.compact\"",
"const-string v$targetRegister, \"https://www.reddit.com/api/v1/authorize.compact\"",
)
}

View File

@@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patches.reddit.customclients.spoofClientPatch
import app.revanced.patches.reddit.customclients.sync.detection.piracy.disablePiracyDetectionPatch
import app.revanced.patches.shared.misc.string.replaceStringPatch
import app.revanced.util.returnEarly
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@@ -13,7 +14,12 @@ import java.util.Base64
val spoofClientPatch = spoofClientPatch(
redirectUri = "http://redditsync/auth",
) { clientIdOption ->
dependsOn(disablePiracyDetectionPatch)
dependsOn(
disablePiracyDetectionPatch,
// Redirects from SSL to WWW domain are bugged causing auth problems.
// Manually rewrite the URLs to fix this.
replaceStringPatch("ssl.reddit.com", "www.reddit.com")
)
compatibleWith(
"com.laurencedawson.reddit_sync",

View File

@@ -0,0 +1,39 @@
package app.revanced.patches.shared.misc.string
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.ReferenceType
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.StringReference
import kotlin.text.contains
fun replaceStringPatch(
from: String,
to: String
) = bytecodePatch(
description = "Replaces occurrences of '$from' with '$to' in string references.",
) {
dependsOn(
transformInstructionsPatch(
filterMap = filterMap@{ _, _, instruction, instructionIndex ->
if (instruction.opcode.referenceType != ReferenceType.STRING) return@filterMap null
val stringReference = instruction.getReference<StringReference>()!!.string
if (from !in stringReference) return@filterMap null
Triple(instructionIndex, instruction as OneRegisterInstruction, stringReference)
},
transform = transform@{ mutableMethod, entry ->
val (instructionIndex, instruction, stringReference) = entry
val newString = stringReference.replace(from, to)
mutableMethod.replaceInstruction(
instructionIndex,
"${instruction.opcode.name} v${instruction.registerA}, \"$newString\"",
)
},
)
)
}

View File

@@ -6,12 +6,10 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import java.util.logging.Logger
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/spotify/layout/hide/createbutton/HideCreateButtonPatch;"
@@ -26,13 +24,6 @@ val hideCreateButtonPatch = bytecodePatch(
dependsOn(sharedExtensionPatch)
execute {
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
Logger.getLogger(this::class.java.name).warning(
"Create button does not exist in legacy app target. No changes applied."
)
return@execute
}
val oldNavigationBarAddItemMethod = oldNavigationBarAddItemFingerprint.originalMethodOrNull
// Only throw the fingerprint error when oldNavigationBarAddItemMethod does not exist.
val navigationBarItemSetClassDef = if (oldNavigationBarAddItemMethod == null) {

View File

@@ -7,8 +7,8 @@ import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.stringOption
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
import app.revanced.util.*
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import org.w3c.dom.Element
@@ -19,12 +19,6 @@ private val customThemeBytecodePatch = bytecodePatch {
dependsOn(sharedExtensionPatch)
execute {
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
// Bytecode changes are not needed for legacy app target.
// Player background color is changed with existing resource patch.
return@execute
}
val colorSpaceUtilsClassDef = colorSpaceUtilsClassFingerprint.originalClassDef
// Hook a util method that converts ARGB to RGBA in the sRGB color space to replace hardcoded accent colors.

View File

@@ -1,23 +0,0 @@
package app.revanced.patches.spotify.lite.ondemand
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.fingerprint
internal val onDemandFingerprint = fingerprint(fuzzyPatternScanThreshold = 2) {
returns("L")
parameters()
opcodes(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_EQZ,
Opcode.SGET_OBJECT,
Opcode.GOTO,
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IPUT,
Opcode.RETURN_OBJECT,
)
}

View File

@@ -1,21 +1,9 @@
package app.revanced.patches.spotify.lite.ondemand
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch
@Deprecated("Patch no longer works and will be deleted soon")
@Suppress("unused")
val onDemandPatch = bytecodePatch(
description = "Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.",
) {
compatibleWith("com.spotify.lite")
execute {
// Spoof a premium account
onDemandFingerprint.method.addInstruction(
onDemandFingerprint.patternMatch!!.endIndex - 1,
"const/4 v0, 0x2",
)
}
}
)

View File

@@ -2,7 +2,6 @@ package app.revanced.patches.spotify.misc
import app.revanced.patcher.fingerprint
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.AccessFlags
@@ -13,25 +12,13 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
context(BytecodePatchContext)
internal val accountAttributeFingerprint get() = fingerprint {
custom { _, classDef ->
classDef.type == if (IS_SPOTIFY_LEGACY_APP_TARGET) {
"Lcom/spotify/useraccount/v1/AccountAttribute;"
} else {
"Lcom/spotify/remoteconfig/internal/AccountAttribute;"
}
}
custom { _, classDef -> classDef.type == "Lcom/spotify/remoteconfig/internal/AccountAttribute;" }
}
context(BytecodePatchContext)
internal val productStateProtoGetMapFingerprint get() = fingerprint {
returns("Ljava/util/Map;")
custom { _, classDef ->
classDef.type == if (IS_SPOTIFY_LEGACY_APP_TARGET) {
"Lcom/spotify/ucs/proto/v0/UcsResponseWrapper${'$'}AccountAttributesResponse;"
} else {
"Lcom/spotify/remoteconfig/internal/ProductStateProto;"
}
}
custom { _, classDef -> classDef.type == "Lcom/spotify/remoteconfig/internal/ProductStateProto;" }
}
internal val buildQueryParametersFingerprint = fingerprint {
@@ -62,8 +49,8 @@ internal val contextMenuViewModelConstructorFingerprint = fingerprint {
/**
* Used to find the interface name of a context menu item.
*/
internal val browsePodcastsContextMenuItemClassFingerprint = fingerprint {
strings("browse_podcast_item", "ui_navigate")
internal val removeAdsContextMenuItemClassFingerprint = fingerprint {
strings("remove_ads_item", "ui_navigate")
}
internal const val CONTEXT_MENU_ITEM_CLASS_DESCRIPTOR_PLACEHOLDER = "Lapp/revanced/ContextMenuItemPlaceholder;"
@@ -90,14 +77,14 @@ internal val contextFromJsonFingerprint = fingerprint {
)
custom { method, classDef ->
method.name == "fromJson" &&
classDef.endsWith("voiceassistants/playermodels/ContextJsonAdapter;")
classDef.type.endsWith("voiceassistants/playermodels/ContextJsonAdapter;")
}
}
internal val readPlayerOptionOverridesFingerprint = fingerprint {
custom { method, classDef ->
method.name == "readPlayerOptionOverrides" &&
classDef.endsWith("voiceassistants/playermodels/PreparePlayOptionsJsonAdapter;")
classDef.type.endsWith("voiceassistants/playermodels/PreparePlayOptionsJsonAdapter;")
}
}
@@ -119,21 +106,21 @@ internal val abstractProtobufListEnsureIsMutableFingerprint = fingerprint {
internal fun structureGetSectionsFingerprint(className: String) = fingerprint {
custom { method, classDef ->
classDef.endsWith(className) && method.indexOfFirstInstruction {
classDef.type.endsWith(className) && method.indexOfFirstInstruction {
opcode == Opcode.IGET_OBJECT && getReference<FieldReference>()?.name == "sections_"
} >= 0
}
}
internal val homeSectionFingerprint = fingerprint {
custom { _, classDef -> classDef.endsWith("homeapi/proto/Section;") }
custom { _, classDef -> classDef.type.endsWith("homeapi/proto/Section;") }
}
internal val homeStructureGetSectionsFingerprint =
structureGetSectionsFingerprint("homeapi/proto/HomeStructure;")
internal val browseSectionFingerprint = fingerprint {
custom { _, classDef-> classDef.endsWith("browsita/v1/resolved/Section;") }
custom { _, classDef-> classDef.type.endsWith("browsita/v1/resolved/Section;") }
}
internal val browseStructureGetSectionsFingerprint =

View File

@@ -7,37 +7,12 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal val getPackageInfoFingerprint = fingerprint {
strings(
"Failed to get the application signatures"
)
}
internal val loadOrbitLibraryFingerprint = fingerprint {
strings("/liborbit-jni-spotify.so")
}
internal val startupPageLayoutInflateFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Landroid/view/View;")
parameters("Landroid/view/LayoutInflater;", "Landroid/view/ViewGroup;", "Landroid/os/Bundle;")
strings("blueprintContainer", "gradient", "valuePropositionTextView")
}
internal val renderStartLoginScreenFingerprint = fingerprint {
strings("authenticationButtonFactory", "MORE_OPTIONS")
}
internal val renderSecondLoginScreenFingerprint = fingerprint {
strings("authenticationButtonFactory", "intent_login")
}
internal val renderThirdLoginScreenFingerprint = fingerprint {
strings("EMAIL_OR_USERNAME", "listener")
}
internal val thirdLoginScreenLoginOnClickFingerprint = fingerprint {
strings("login", "listener", "none")
internal val extensionFixConstantsFingerprint = fingerprint {
custom { _, classDef -> classDef.type == "Lapp/revanced/extension/spotify/misc/fix/Constants;" }
}
internal val runIntegrityVerificationFingerprint = fingerprint {

View File

@@ -1,19 +1,13 @@
package app.revanced.patches.spotify.misc.fix
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.intOption
import app.revanced.patcher.patch.stringOption
import app.revanced.patches.shared.misc.hex.HexPatchBuilder
import app.revanced.patches.shared.misc.hex.hexPatch
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
import app.revanced.util.*
import com.android.tools.smali.dexlib2.Opcode
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
import app.revanced.util.returnEarly
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/spotify/misc/fix/SpoofClientPatch;"
@@ -25,16 +19,40 @@ val spoofClientPatch = bytecodePatch(
val requestListenerPort by intOption(
key = "requestListenerPort",
default = 4345,
title = " Login request listener port",
description = "The port to use for the listener that intercepts and handles login requests. " +
"Port must be between 0 and 65535.",
required = true,
title = "Request listener port",
description = "The port to use for the listener that intercepts and handles spoofed requests. " +
"Port must be between 0 and 65535. " +
"Do not change this option, if you do not know what you are doing.",
validator = {
it!!
!(it < 0 || it > 65535)
}
)
val clientVersion by stringOption(
key = "clientVersion",
default = "iphone-9.0.58.558.g200011c",
title = "Client version",
description = "The client version used for spoofing the client token. " +
"Do not change this option, if you do not know what you are doing."
)
val hardwareMachine by stringOption(
key = "hardwareMachine",
default = "iPhone16,1",
title = "Hardware machine",
description = "The hardware machine used for spoofing the client token. " +
"Do not change this option, if you do not know what you are doing."
)
val systemVersion by stringOption(
key = "systemVersion",
default = "17.7.2",
title = "System version",
description = "The system version used for spoofing the client token. " +
"Do not change this option, if you do not know what you are doing."
)
dependsOn(
sharedExtensionPatch,
hexPatch(ignoreMissingTargetFiles = true, block = fun HexPatchBuilder.() {
@@ -44,10 +62,8 @@ val spoofClientPatch = bytecodePatch(
"x86",
"x86_64"
).forEach { architecture ->
"https://login5.spotify.com/v3/login" to "http://127.0.0.1:$requestListenerPort/v3/login" inFile
"lib/$architecture/liborbit-jni-spotify.so"
"https://login5.spotify.com/v4/login" to "http://127.0.0.1:$requestListenerPort/v4/login" inFile
"https://clienttoken.spotify.com/v1/clienttoken" to
"http://127.0.0.1:$requestListenerPort/v1/clienttoken" inFile
"lib/$architecture/liborbit-jni-spotify.so"
}
})
@@ -56,51 +72,6 @@ val spoofClientPatch = bytecodePatch(
compatibleWith("com.spotify.music")
execute {
// region Spoof package info.
getPackageInfoFingerprint.method.apply {
// region Spoof signature.
val failedToGetSignaturesStringIndex =
getPackageInfoFingerprint.stringMatches!!.first().index
val concatSignaturesIndex = indexOfFirstInstructionReversedOrThrow(
failedToGetSignaturesStringIndex,
Opcode.MOVE_RESULT_OBJECT,
)
val signatureRegister = getInstruction<OneRegisterInstruction>(concatSignaturesIndex).registerA
val expectedSignature = "d6a6dced4a85f24204bf9505ccc1fce114cadb32"
replaceInstruction(concatSignaturesIndex, "const-string v$signatureRegister, \"$expectedSignature\"")
// endregion
// region Spoof installer name.
val expectedInstallerName = "com.android.vending"
findInstructionIndicesReversedOrThrow {
val reference = getReference<MethodReference>()
reference?.name == "getInstallerPackageName" || reference?.name == "getInstallingPackageName"
}.forEach { index ->
val returnObjectIndex = index + 1
val installerPackageNameRegister = getInstruction<OneRegisterInstruction>(
returnObjectIndex
).registerA
addInstruction(
returnObjectIndex + 1,
"const-string v$installerPackageNameRegister, \"$expectedInstallerName\""
)
}
// endregion
}
// endregion
// region Spoof client.
loadOrbitLibraryFingerprint.method.addInstructions(
@@ -111,72 +82,12 @@ val spoofClientPatch = bytecodePatch(
"""
)
startupPageLayoutInflateFingerprint.method.apply {
val openLoginWebViewDescriptor =
"$EXTENSION_CLASS_DESCRIPTOR->launchLogin(Landroid/view/LayoutInflater;)V"
addInstructions(
0,
"invoke-static/range { p1 .. p1 }, $openLoginWebViewDescriptor"
)
}
renderStartLoginScreenFingerprint.method.apply {
val onEventIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_INTERFACE && getReference<MethodReference>()?.name == "getView"
}
val buttonRegister = getInstruction<OneRegisterInstruction>(onEventIndex + 1).registerA
addInstruction(
onEventIndex + 2,
"invoke-static { v$buttonRegister }, $EXTENSION_CLASS_DESCRIPTOR->setNativeLoginHandler(Landroid/view/View;)V"
)
}
renderSecondLoginScreenFingerprint.method.apply {
val getViewIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_INTERFACE && getReference<MethodReference>()?.name == "getView"
}
val buttonRegister = getInstruction<OneRegisterInstruction>(getViewIndex + 1).registerA
// Early return the render for loop since the first item of the loop is the login button.
addInstructions(
getViewIndex + 2,
"""
invoke-virtual { v$buttonRegister }, Landroid/view/View;->performClick()Z
return-void
"""
)
}
renderThirdLoginScreenFingerprint.method.apply {
val invokeSetListenerIndex = indexOfFirstInstructionOrThrow {
val reference = getReference<MethodReference>()
reference?.definingClass == "Landroid/view/View;" && reference.name == "setOnClickListener"
}
val buttonRegister = getInstruction<FiveRegisterInstruction>(invokeSetListenerIndex).registerC
addInstruction(
invokeSetListenerIndex + 1,
"invoke-virtual { v$buttonRegister }, Landroid/view/View;->performClick()Z"
)
}
thirdLoginScreenLoginOnClickFingerprint.method.apply {
// Use placeholder credentials to pass the login screen.
val loginActionIndex = indexOfFirstInstructionOrThrow(Opcode.RETURN_VOID) - 1
val loginActionInstruction = getInstruction<FiveRegisterInstruction>(loginActionIndex)
addInstructions(
loginActionIndex,
"""
const-string v${loginActionInstruction.registerD}, "placeholder"
const-string v${loginActionInstruction.registerE}, "placeholder"
"""
)
mapOf(
"getClientVersion" to clientVersion!!,
"getSystemVersion" to systemVersion!!,
"getHardwareMachine" to hardwareMachine!!
).forEach { (methodName, value) ->
extensionFixConstantsFingerprint.classDef.methods.single { it.name == methodName }.returnEarly(value)
}
// endregion

View File

@@ -6,7 +6,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.stringOption
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
@@ -57,16 +56,10 @@ val changeLyricsProviderPatch = bytecodePatch(
}
execute {
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
Logger.getLogger(this::class.java.name).severe(
"Change lyrics provider patch is not supported for this target version."
)
return@execute
}
val httpClientBuilderMethod = httpClientBuilderFingerprint.originalMethod
// region Create a modified copy of the HTTP client builder method with the custom lyrics provider host.
val patchedHttpClientBuilderMethod = with(httpClientBuilderMethod) {
val invokeBuildUrlIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.returnType == "Lokhttp3/HttpUrl;"
@@ -89,9 +82,11 @@ val changeLyricsProviderPatch = bytecodePatch(
httpClientBuilderFingerprint.classDef.methods.add(this)
}
}
//endregion
// region Replace the call to the HTTP client builder method used exclusively for lyrics by the modified one.
getLyricsHttpClientFingerprint(httpClientBuilderMethod).method.apply {
val getLyricsHttpClientIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>() == httpClientBuilderMethod
@@ -118,6 +113,7 @@ val changeLyricsProviderPatch = bytecodePatch(
)
)
}
//endregion
}
}

View File

@@ -14,7 +14,7 @@ internal val shareCopyUrlFingerprint = fingerprint {
}
}
internal val shareCopyUrlLegacyFingerprint = fingerprint {
internal val oldShareCopyUrlFingerprint = fingerprint {
returns("Ljava/lang/Object;")
parameters("Ljava/lang/Object;")
strings("clipboard", "createNewSession failed")
@@ -38,7 +38,7 @@ internal val formatAndroidShareSheetUrlFingerprint = fingerprint {
}
}
internal val formatAndroidShareSheetUrlLegacyFingerprint = fingerprint {
internal val oldFormatAndroidShareSheetUrlFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC)
returns("Ljava/lang/String;")
parameters("Lcom/spotify/share/social/sharedata/ShareData;", "Ljava/lang/String;")

View File

@@ -1,11 +1,9 @@
package app.revanced.patches.spotify.misc.privacy
import app.revanced.patcher.Fingerprint
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.AccessFlags
@@ -28,10 +26,10 @@ val sanitizeSharingLinksPatch = bytecodePatch(
val extensionMethodDescriptor = "$EXTENSION_CLASS_DESCRIPTOR->" +
"sanitizeUrl(Ljava/lang/String;)Ljava/lang/String;"
val copyFingerprint = if (IS_SPOTIFY_LEGACY_APP_TARGET) {
shareCopyUrlLegacyFingerprint
} else {
val copyFingerprint = if (shareCopyUrlFingerprint.originalMethodOrNull != null) {
shareCopyUrlFingerprint
} else {
oldShareCopyUrlFingerprint
}
copyFingerprint.method.apply {
@@ -50,15 +48,10 @@ val sanitizeSharingLinksPatch = bytecodePatch(
}
// Android native share sheet is used for all other quick share types (X, WhatsApp, etc).
val shareUrlParameter : String
val shareSheetFingerprint : Fingerprint
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
shareSheetFingerprint = formatAndroidShareSheetUrlLegacyFingerprint
shareUrlParameter = "p2"
} else {
shareSheetFingerprint = formatAndroidShareSheetUrlFingerprint
val methodAccessFlags = formatAndroidShareSheetUrlFingerprint.originalMethod.accessFlags
shareUrlParameter = if (AccessFlags.STATIC.isSet(methodAccessFlags)) {
val shareUrlParameter: String
val shareSheetFingerprint = if (formatAndroidShareSheetUrlFingerprint.originalMethodOrNull != null) {
val methodAccessFlags = formatAndroidShareSheetUrlFingerprint.originalMethod
shareUrlParameter = if (AccessFlags.STATIC.isSet(methodAccessFlags.accessFlags)) {
// In newer implementations the method is static, so p0 is not `this`.
"p1"
} else {
@@ -66,6 +59,11 @@ val sanitizeSharingLinksPatch = bytecodePatch(
// For that reason, add one to the parameter register.
"p2"
}
formatAndroidShareSheetUrlFingerprint
} else {
shareUrlParameter = "p2"
oldFormatAndroidShareSheetUrlFingerprint
}
shareSheetFingerprint.method.addInstructions(

View File

@@ -1,9 +1,7 @@
package app.revanced.patches.spotify.misc.widgets
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
import app.revanced.util.returnEarly
import java.util.logging.Logger
@Suppress("unused")
val fixThirdPartyLaunchersWidgets = bytecodePatch(
@@ -13,14 +11,6 @@ val fixThirdPartyLaunchersWidgets = bytecodePatch(
compatibleWith("com.spotify.music")
execute {
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
// The permission check does not exist in legacy versions.
Logger.getLogger(this::class.java.name).warning(
"Legacy app target does not have any third party launcher restrictions. No changes applied."
)
return@execute
}
// Only system app launchers are granted the BIND_APPWIDGET permission.
// Override the method that checks for it to always return true, as this permission is not actually required
// for the widgets to work.

View File

@@ -1,38 +1,15 @@
package app.revanced.patches.spotify.shared
import app.revanced.patcher.fingerprint
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
private const val SPOTIFY_MAIN_ACTIVITY = "Lcom/spotify/music/SpotifyMainActivity;"
/**
* Main activity of target 8.6.98.900.
*/
internal const val SPOTIFY_MAIN_ACTIVITY_LEGACY = "Lcom/spotify/music/MainActivity;"
internal val mainActivityOnCreateFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters("Landroid/os/Bundle;")
custom { method, classDef ->
method.name == "onCreate" && (classDef.type == SPOTIFY_MAIN_ACTIVITY
|| classDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY)
method.name == "onCreate" && classDef.type == SPOTIFY_MAIN_ACTIVITY
}
}
private var isLegacyAppTarget: Boolean? = null
/**
* If patching a legacy 8.x target. This may also be set if patching slightly older/newer app targets,
* but the only legacy target of interest is 8.6.98.900 as it's the last version that
* supports Spotify integration on Kenwood/Pioneer car stereos.
*/
context(BytecodePatchContext)
internal val IS_SPOTIFY_LEGACY_APP_TARGET
get(): Boolean {
if (isLegacyAppTarget == null) {
isLegacyAppTarget = mainActivityOnCreateFingerprint.originalClassDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY
}
return isLegacyAppTarget!!
}

View File

@@ -0,0 +1,63 @@
package app.revanced.patches.youtube.interaction.doubletap
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/DisableChapterSkipDoubleTapPatch;"
@Suppress("unused")
val disableChapterSkipDoubleTapPatch = bytecodePatch(
name = "Disable double tap actions",
description = "Adds an option to disable player double tap gestures.",
) {
dependsOn(
sharedExtensionPatch,
settingsPatch,
addResourcesPatch,
)
compatibleWith(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
"19.47.53",
"20.07.39",
"20.12.46",
"20.13.41",
)
)
execute {
addResources("youtube", "interaction.doubletap.disableChapterSkipDoubleTapPatch")
PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_disable_chapter_skip_double_tap"),
)
// Force isChapterSeek flag to false.
doubleTapInfoGetSeekSourceFingerprint.method.addInstructions(
0,
"""
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->disableDoubleTapChapters(Z)Z
move-result p1
"""
)
doubleTapInfoCtorFingerprint.match(
doubleTapInfoGetSeekSourceFingerprint.classDef
).method.addInstructions(
0,
"""
invoke-static { p3 }, $EXTENSION_CLASS_DESCRIPTOR->disableDoubleTapChapters(Z)Z
move-result p3
"""
)
}
}

View File

@@ -0,0 +1,31 @@
package app.revanced.patches.youtube.interaction.doubletap
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val doubleTapInfoGetSeekSourceFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameters("Z")
returns("L") // Enum SeekSource, but name obfuscated.
opcodes(
Opcode.IF_EQZ,
Opcode.SGET_OBJECT,
Opcode.RETURN_OBJECT,
Opcode.SGET_OBJECT,
Opcode.RETURN_OBJECT,
)
custom { _, classDef ->
classDef.fields.count() == 4
}
}
internal val doubleTapInfoCtorFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
parameters(
"Landroid/view/MotionEvent;",
"I",
"Z",
"Lj\$/time/Duration;"
)
}

View File

@@ -73,12 +73,9 @@ val enableSlideToSeekPatch = bytecodePatch(
// Disable the double speed seek gesture.
if (is_19_17_or_greater) {
arrayOf(
disableFastForwardGestureFingerprint,
disableFastForwardNoticeFingerprint,
).forEach { fingerprint ->
fingerprint.method.apply {
val targetIndex = fingerprint.patternMatch!!.endIndex
disableFastForwardGestureFingerprint.let {
it.method.apply {
val targetIndex = it.patternMatch!!.endIndex
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructions(

View File

@@ -3,14 +3,12 @@ package app.revanced.patches.youtube.interaction.seekbar
import app.revanced.patcher.fingerprint
import app.revanced.util.containsLiteralInstruction
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.indexOfFirstInstructionReversed
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.iface.reference.StringReference
internal val swipingUpGestureParentFingerprint = fingerprint {
returns("Z")
@@ -59,25 +57,6 @@ internal val disableFastForwardGestureFingerprint = fingerprint {
}
}
internal val disableFastForwardNoticeFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters()
opcodes(
Opcode.CHECK_CAST,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
)
custom { method, _ ->
method.name == "run" && method.indexOfFirstInstruction {
// In later targets the code is found in different methods with different strings.
val string = getReference<StringReference>()?.string
string == "Failed to easy seek haptics vibrate." || string == "search_landing_cache_key"
} >= 0
}
}
internal val onTouchEventHandlerFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.PUBLIC)
returns("Z")

View File

@@ -9,7 +9,6 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.InputType
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.interaction.seekbar.disableFastForwardNoticeFingerprint
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

View File

@@ -1,8 +1,11 @@
package app.revanced.patches.youtube.video.speed.custom
import app.revanced.patcher.fingerprint
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.reference.StringReference
internal val speedLimiterFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
@@ -19,3 +22,16 @@ internal val speedLimiterFingerprint = fingerprint {
Opcode.INVOKE_STATIC,
)
}
internal val disableFastForwardNoticeFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters()
custom { method, _ ->
method.name == "run" && method.indexOfFirstInstruction {
// In later targets the code is found in different methods with different strings.
val string = getReference<StringReference>()?.string
string == "Failed to easy seek haptics vibrate." || string == "search_landing_cache_key"
} >= 0
}
}

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -453,6 +453,11 @@ Second \"item\" text"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">سيتم عرض مربع الحوار</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">وهذا لا يتجاوز قيود السن. بل يقبلها تلقائيًا.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">تعطيل تخطي الفصل بالنقر المزدوج</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">لا يمكن للنقر المزدوج مطلقًا أن يؤدي إلى تخطي الفصل التالي/السابق</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">يمكن للنقر المزدوج أن يؤدي أحيانًا إلى تخطي الفصل التالي/السابق</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">التنزيلات الخارجية</string>
<string name="revanced_external_downloader_screen_summary">إعدادات لاستخدام أداة التنزيل الخارجية</string>
@@ -697,9 +702,9 @@ Second \"item\" text"</string>
<string name="revanced_hide_cast_button_title">إخفاء زر البث</string>
<string name="revanced_hide_cast_button_summary_on">تم إخفاء زر البث</string>
<string name="revanced_hide_cast_button_summary_off">يتم عرض زر البث</string>
<string name="revanced_hide_player_control_buttons_background_title">إخفاء خلفية أزرار التحكم في المشغل</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">تم إخفاء خلفية أزرار التحكم في المشغل</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">تم إظهار خلفية أزرار التحكم في المشغل</string>
<string name="revanced_hide_player_control_buttons_background_title">إخفاء خلفية عناصر التحكم بالمشغل</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">خلفية عناصر تحكم المشغل مخفية</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">يتم عرض خلفية عناصر التحكم بالمشغل</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>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -168,7 +168,17 @@ Gözlənilməz hallardan xəbərdar olmayacaqsınız."</string>
<string name="revanced_hide_feed_survey_summary_on">Axın sorğuları gizlidir</string>
<string name="revanced_hide_feed_survey_summary_off">Axın sorğuları göstərilir</string>
<string name="revanced_hide_floating_microphone_button_title">Üzən mikrofon düyməsini gizlət</string>
<string name="revanced_hide_floating_microphone_button_summary_on">Axtarışda üzən mikrofon düyməsi gizlidir</string>
<string name="revanced_hide_floating_microphone_button_summary_off">Üzən mikrofon düyməsi axtarışda göstərilir</string>
<string name="revanced_hide_horizontal_shelves_title">Üfüqi hissələri gizlət</string>
<string name="revanced_hide_horizontal_shelves_summary_on">"Üfüqi cərgələr gizlidir, məsələn:
• Son xəbərlər
• İzləməyə davam et
• Daha çox kanal kəşf et
• Ən uyğun
• Alış-veriş
• Yenidən izləyin"</string>
<string name="revanced_hide_horizontal_shelves_summary_off">Üfüqi cərgələr görünür</string>
<string name="revanced_hide_image_shelf_title">Şəkil cərgəsin gizlət</string>
<string name="revanced_hide_image_shelf_summary_on">Şəkil cərgəsi axtarış nəticələrində gizlidir</string>
<string name="revanced_hide_image_shelf_summary_off">Şəkil cərgəsi axtarış nəticələrində görünür</string>
@@ -184,18 +194,27 @@ Gözlənilməz hallardan xəbərdar olmayacaqsınız."</string>
<!-- 'Notify me' should be translated using the same localized wording YouTube displays.
This item appear in the subscription feed for future livestreams or unreleased videos. -->
<string name="revanced_hide_notify_me_button_title">\"Mənə bildir\" düyməsini gizlət</string>
<string name="revanced_hide_notify_me_button_summary_on">Mənə bildir düyməsi gizlidir</string>
<string name="revanced_hide_notify_me_button_summary_off">Mənə bildir düyməsi görünür</string>
<string name="revanced_hide_playables_title">Oynadılan elementləri gizlət</string>
<string name="revanced_hide_playables_summary_on">Oynadılanlar gizlidir</string>
<string name="revanced_hide_playables_summary_off">Oynadılanlar göstərilir</string>
<!-- 'Show more' should be translated with the same localized wording that YouTube displays.
This button usually appears when searching for a YT creator. -->
<string name="revanced_hide_show_more_button_title">\'Daha çox göstər\' düyməsini gizlət</string>
<string name="revanced_hide_show_more_button_summary_on">Daha çox göstər düyməsi axtarış nəticələrində gizlidir</string>
<string name="revanced_hide_show_more_button_summary_off">Daha çox göstər düyməsi axtarış nəticələrində görünür</string>
<string name="revanced_hide_ticket_shelf_title">Bilet bölməsin gizlət</string>
<string name="revanced_hide_ticket_shelf_summary_on">Bilet bölməsi gizlidir</string>
<string name="revanced_hide_ticket_shelf_summary_off">Bilet bölməsi görünür</string>
<!-- 'People also watched' and 'You might also like' should be translated using the same localized wording YouTube displays. -->
<string name="revanced_hide_video_recommendation_labels_title">Video tövsiyə etiketlərini gizlət</string>
<string name="revanced_hide_video_recommendation_labels_summary_on">\'İnsanlar həmçinin izləyiblər\' və \'Bunu da bəyənə bilərsiniz\' etiketləri axtarış nəticələrində gizlədilib</string>
<string name="revanced_hide_video_recommendation_labels_summary_off">\'İnsanlar həmçinin izləyiblər\' və \'Bunu da bəyənə bilərsiniz\' etiketləri axtarış nəticələrində görünür</string>
<!-- https://logos.fandom.com/wiki/YouTube/Yoodles -->
<string name="revanced_hide_doodles_title">YouTube Doodle-ları gizlət</string>
<string name="revanced_hide_doodles_summary_on">YouTube Doodles animasiyası simvolda gizlidir</string>
<string name="revanced_hide_doodles_summary_off">YouTube Doodles animasiyası simvolda görünür</string>
<string name="revanced_hide_doodles_user_dialog_message">"YouTube Doodle-ları hər il bir neçə gün görünür.
Əgər hazırda bölgənizdə Doodle göstərilirsə və bu gizlətmə seçimi aktivdirsə, axtarış cizgisi aşağısındakı filtr sahəsi də gizlədiləcək."</string>
@@ -214,6 +233,8 @@ Gözlənilməz hallardan xəbərdar olmayacaqsınız."</string>
<!-- 'Join' should be translated using the same localized wording YouTube displays.
This appears in the video player for certain videos. -->
<string name="revanced_hide_join_membership_button_title">Qoşul düyməsin gizlət</string>
<string name="revanced_hide_join_membership_button_summary_on">Qoşul düyməsi gizlidir</string>
<string name="revanced_hide_join_membership_button_summary_off">Qoşul düyməsi görünür</string>
<string name="revanced_hide_medical_panels_title">Tibbi lövhələri gizlət</string>
<string name="revanced_hide_medical_panels_summary_on">Tibbi lövhələr gizlidir</string>
<string name="revanced_hide_medical_panels_summary_off">Tibbi lövhələr göstərilir</string>
@@ -371,7 +392,11 @@ Məhdudiyyətlər
</patch>
<patch id="ad.general.hideAdsResourcePatch">
<string name="revanced_hide_creator_store_shelf_title">Yaradıcı mağaza bölümün gizlət</string>
<string name="revanced_hide_creator_store_shelf_summary_on">Yaradıcı alış-veriş cərgəsi video oynadıcı altında gizlidir</string>
<string name="revanced_hide_creator_store_shelf_summary_off">Yaradıcı alış-veriş cərgəsi video oynadıcı altında görünür</string>
<string name="revanced_hide_end_screen_store_banner_title">Son ekran mağaza etiketini gizlət</string>
<string name="revanced_hide_end_screen_store_banner_summary_on">Son ekran alış-veriş etiketi gizlədilib</string>
<string name="revanced_hide_end_screen_store_banner_summary_off">Son ekran alış-veriş etiketi görünür</string>
<string name="revanced_hide_fullscreen_ads_title">Tam ekran reklamlarını gizlət</string>
<string name="revanced_hide_fullscreen_ads_summary_on">"Tam ekran reklamları gizlidir
@@ -392,8 +417,12 @@ Bu xüsusiyyət yalnız köhnə cihazlar üçün mövcuddur"</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_shopping_links_title">Alış-veriş linklərini gizlət</string>
<string name="revanced_hide_shopping_links_summary_on">Alış-veriş linkləri video təsvirdə gizlidir</string>
<string name="revanced_hide_shopping_links_summary_off">Alış-veriş linkləri video təsvirdə görünür</string>
<!-- 'View products' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_view_products_banner_title">“Məhsullara baxın” panelin gizlət</string>
<string name="revanced_hide_view_products_banner_summary_on">Məhsullara baxış etiketi video örtüyündə gizlidir</string>
<string name="revanced_hide_view_products_banner_summary_off">Məhsullara baxış etiketi video örtüyündə görünür</string>
<string name="revanced_hide_web_search_results_title">Veb axtarış nəticələrini gizlət</string>
<string name="revanced_hide_web_search_results_summary_on">Veb axtarış nəticələri gizlədilir</string>
<string name="revanced_hide_web_search_results_summary_off">Veb axtarış nəticələri göstərilir</string>
@@ -424,6 +453,11 @@ Bu xüsusiyyət yalnız köhnə cihazlar üçün mövcuddur"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Dialoq göstərilir</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Bu, yaş məhdudiyyətini ötürmür. Sadəcə birbaşa qəbul edir.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Cüt toxunuşla fəsil ötürməsini qapat</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Cüt toxunma heç vaxt növbəti/əvvəlki fəsilə keçidi zorlaya bilməz</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Cüt toxunma bəzən növbəti/əvvəlki fəsilə keçidi zorlaya bilər</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Xarici yükləmələr</string>
<string name="revanced_external_downloader_screen_summary">Xarici yükləyici istifadəsi üçün tənzimləmələr</string>
@@ -668,9 +702,9 @@ Audio trek seçimin göstərmək üçün \"Video axınları saxtalaşdır\"ı iO
<string name="revanced_hide_cast_button_title">Yayımla düyməsini gizlət</string>
<string name="revanced_hide_cast_button_summary_on">Yayım düyməsi gizlidir</string>
<string name="revanced_hide_cast_button_summary_off">Yayım düyməsi göstərilir</string>
<string name="revanced_hide_player_control_buttons_background_title">Oynadıcı idarəetmə düymələri fonunu gizlət</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Oynadıcı idarəetmə düymələri fonu gizlidir</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Oynadıcı idarəetmə düymələri fonu görünür</string>
<string name="revanced_hide_player_control_buttons_background_title">Oynadıcı idarəetmələri fonunu gizlət</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Oynadıcı idarəetmə fonu gizlədilib</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Oynadıcı idarəetmə fonu görünür</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>
@@ -707,7 +741,13 @@ Audio trek seçimin göstərmək üçün \"Video axınları saxtalaşdır\"ı iO
<string name="revanced_shorts_player_screen_title">Shorts oynadıcı</string>
<string name="revanced_shorts_player_screen_summary">Shorts oynadıcıda hissəcikləri gizlət və ya göstər</string>
<!-- 'Home' should be translated using the same localized wording YouTube displays for the Home tab. -->
<string name="revanced_hide_shorts_home_title">Shorts-u Ev axınında gizlət</string>
<string name="revanced_hide_shorts_home_summary_on">Ev axını və əlaqəli videolarda gizlidir</string>
<string name="revanced_hide_shorts_home_summary_off">Ev axını və əlaqəli videolarda görünür</string>
<!-- 'Subscriptions' should be translated using the same localized wording YouTube displays for the Subscriptions tab. -->
<string name="revanced_hide_shorts_subscriptions_title">Shorts-u Abunəliklər axınında gizlət</string>
<string name="revanced_hide_shorts_subscriptions_summary_on">Abunəliklər axınında gizlidir</string>
<string name="revanced_hide_shorts_subscriptions_summary_off">Abunəliklər axınında görünür</string>
<string name="revanced_hide_shorts_search_title">Axtarış nəticələrindəki \"Shorts\"u gizlət</string>
<string name="revanced_hide_shorts_search_summary_on">Axtarış nəticələrində gizlidir</string>
<string name="revanced_hide_shorts_search_summary_off">Axtarış nəticələrində görünür</string>
@@ -715,6 +755,8 @@ Audio trek seçimin göstərmək üçün \"Video axınları saxtalaşdır\"ı iO
<string name="revanced_hide_shorts_history_summary_on">Baxış tarixçəsində gizlidir</string>
<string name="revanced_hide_shorts_history_summary_off">Baxış tarixçəsində göstərilib</string>
<string name="revanced_hide_shorts_super_thanks_button_title">Super Təşəkkür Al düyməsini gizlət</string>
<string name="revanced_hide_shorts_super_thanks_button_summary_on">Super Təşəkkürlər Al düyməsi gizlidir</string>
<string name="revanced_hide_shorts_super_thanks_button_summary_off">Super Təşəkkürlər Al düyməsi görünür</string>
<string name="revanced_hide_shorts_effect_button_title">Effekt düyməsini gizlət</string>
<string name="revanced_hide_shorts_effect_button_summary_on">Effekt düyməsi gizlidir</string>
<string name="revanced_hide_shorts_effect_button_summary_off">Effekt düyməsi görünür</string>
@@ -797,7 +839,11 @@ Audio trek seçimin göstərmək üçün \"Video axınları saxtalaşdır\"ı iO
<string name="revanced_hide_shorts_channel_bar_summary_on">Kanal çubuğu gizlidir</string>
<string name="revanced_hide_shorts_channel_bar_summary_off">Kanal çubuğu göstərilir</string>
<string name="revanced_hide_shorts_video_title_title">Video başlığını gizlət</string>
<string name="revanced_hide_shorts_video_title_summary_on">Video başlığı gizlidir</string>
<string name="revanced_hide_shorts_video_title_summary_off">Video başlığı görünür</string>
<string name="revanced_hide_shorts_sound_metadata_label_title">Səs üst məlumat etiketini gizlət</string>
<string name="revanced_hide_shorts_sound_metadata_label_summary_on">Səs üst məlumat etiketi gizlədilib</string>
<string name="revanced_hide_shorts_sound_metadata_label_summary_off">Səs üst məlumat etiketi görünür</string>
<string name="revanced_hide_shorts_full_video_link_label_title">Video keçidi etiketini gizlət</string>
<string name="revanced_hide_shorts_full_video_link_label_summary_on">Video linki etiketi gizlidir</string>
<string name="revanced_hide_shorts_full_video_link_label_summary_off">Video link etiketi göstərilir</string>
@@ -813,6 +859,9 @@ Avtomatik oynatma YouTube ayarlarında dəyişdirilə bilər: Ayarlar → Oxunu
<string name="revanced_end_screen_suggested_video_summary_off">Son ekranda bildirilən video göstərilir</string>
</patch>
<patch id="layout.hide.relatedvideooverlay.hideRelatedVideoOverlayPatch">
<string name="revanced_hide_related_videos_overlay_title">Əlaqəli videolar örtüyünü gizlət</string>
<string name="revanced_hide_related_videos_overlay_summary_on">Əlaqəli videolar yerləşməsi tam ekranda gizlidir</string>
<string name="revanced_hide_related_videos_overlay_summary_off">Əlaqəli videolar yerləşməsi tam ekranda görünür</string>
</patch>
<patch id="layout.hide.time.hideTimestampPatch">
<string name="revanced_hide_timestamp_title">Video vaxt möhürünü gizlət</string>
@@ -1279,8 +1328,10 @@ Bunu aktivləşdirmə, bəzi regionlarda əngəllənib silinən şəkilləri dü
<!-- 'Home' should be translated using the same localized wording YouTube displays for the Home tab. -->
<string name="revanced_alt_thumbnail_home_title">Ev paneli</string>
<!-- 'Subscriptions' should be translated using the same localized wording YouTube displays for the Subscriptions tab. -->
<string name="revanced_alt_thumbnail_subscription_title">Abunəliklər bölməsi</string>
<!-- 'You' should be translated using the same localized wording YouTube displays for the You (Library) tab. -->
<string name="revanced_alt_thumbnail_library_title">\"Siz\" paneli</string>
<string name="revanced_alt_thumbnail_player_title">Oynadıcı pleylistləri &amp; tövsiyələri</string>
<string name="revanced_alt_thumbnail_search_title">Axtarış nəticələri</string>
<string name="revanced_alt_thumbnail_options_entry_1">Orijinal miniatürlər</string>
<string name="revanced_alt_thumbnail_options_entry_2">DeArrow &amp; Orijinal miniatürlər</string>
@@ -1496,6 +1547,7 @@ AVC maksimum 1080p görüntü imkanına malikdir, Opus audio kodlama olmur və v
<string name="revanced_block_video_ads_summary_off">Video reklamlar bloklanmır</string>
</patch>
<patch id="chat.antidelete.showDeletedMessagesPatch">
<string name="revanced_deleted_msg">Məlumat silindi</string>
<string name="revanced_show_deleted_messages_title">Silinən mesajları göstər</string>
<string name="revanced_show_deleted_messages_entry_1">Silinən mesajlar göstərilməsin</string>
<string name="revanced_show_deleted_messages_entry_2">Silinmiş mesajları boz panel arxasında gizlət</string>
@@ -1516,8 +1568,11 @@ AVC maksimum 1080p görüntü imkanına malikdir, Opus audio kodlama olmur və v
<string name="revanced_settings">ReVanced Tənzimləmələri</string>
<string name="revanced_about_title">Haqqında</string>
<string name="revanced_about_summary">ReVanced Haqqında</string>
<string name="revanced_ads_screen_title">Reklam Əngəlləmə</string>
<string name="revanced_ads_screen_summary">Reklam Əngəlləmə tənzimləmələri</string>
<string name="revanced_chat_screen_title">Söhbət</string>
<string name="revanced_chat_screen_summary">Söhbət tənzimləmələri</string>
<string name="revanced_misc_screen_title">Çoxvariantlı</string>
<string name="revanced_misc_screen_summary">Müxtəlif tənzimləmələr</string>
<string name="revanced_general_category_title">Ümumi tənzimləmələr</string>
<string name="revanced_other_category_title">Digər tənzimləmələr</string>

View File

@@ -453,6 +453,11 @@ Second \"item\" text"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Будзе паказана дыялогавае акно</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Гэта не абыходзіць узроставае абмежаванне. Ён проста прымае гэта аўтаматычна.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Адключыць прапуск раздзела па двайным націску</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Двайны націск ніколі не можа выклікаць прапуск да наступнага/папярэдняга раздзела</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Двайны націск можа час ад часу выклікаць прапуск да наступнага/папярэдняга раздзела</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Знешнія загрузкі</string>
<string name="revanced_external_downloader_screen_summary">Налады для выкарыстання вонкавага загрузніка</string>
@@ -697,9 +702,9 @@ Second \"item\" text"</string>
<string name="revanced_hide_cast_button_title">Схаваць кнопку «Трансляцыя»</string>
<string name="revanced_hide_cast_button_summary_on">Кнопка Cast схавана</string>
<string name="revanced_hide_cast_button_summary_off">Паказана кнопка Cast</string>
<string name="revanced_hide_player_control_buttons_background_title">Схаваць фон кнопак кіравання прайгравальнікам</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Фон кнопак кіравання прайгравальнікам схаваны</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Фон кнопак кіравання прайгравальнікам паказаны</string>
<string name="revanced_hide_player_control_buttons_background_title">Схаваць фон элементаў кіравання прайгравальнікам</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Фон элементаў кіравання плэерам схаваны</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Фон элементаў кіравання паказаны</string>
<string name="revanced_hide_player_previous_next_buttons_title">Схаваць папярэднія &amp; кнопкі «Далей»</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Кнопкі схаваныя</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Паказваюцца кнопкі</string>

View File

@@ -453,6 +453,11 @@ Second \"item\" text"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Диалоговият прозорец ще бъде показан</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Тази функция не заобикаля възрастовото ограничение. Тя просто приема възрастовата граница автоматично.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Деактивиране на пропускане на глава с двойно докосване</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Двойното докосване никога не може да предизвика пропускане до следваща/предишна глава</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Двойното докосване може понякога да предизвика пропускане до следваща/предишна глава</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Външни изтегляния</string>
<string name="revanced_external_downloader_screen_summary">Настройки за използване на външно приложение за изтегляне</string>
@@ -697,9 +702,9 @@ Second \"item\" text"</string>
<string name="revanced_hide_cast_button_title">Скриване на бутона Cast</string>
<string name="revanced_hide_cast_button_summary_on">Бутонът за предаване е скрит</string>
<string name="revanced_hide_cast_button_summary_off">Бутонът за предаване се показва</string>
<string name="revanced_hide_player_control_buttons_background_title">Скриване на фона на бутоните за управление на плейъра</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Фонът на бутоните за управление на плейъра е скрит</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Фонът на бутоните за управление на плейъра е показан</string>
<string name="revanced_hide_player_control_buttons_background_title">Скриване на фона на контролите на плейъра</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Фонът на контролите на плейъра е скрит</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Фонът на контролите на плейъра е показан</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>

View File

@@ -449,6 +449,11 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
<string name="revanced_remove_viewer_discretion_dialog_summary_off">ডায়ালগ প্রদর্শিত হবে</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">এটি বয়সের সীমাবদ্ধতাকে বাইপাস করে না। এটা শুধু স্বয়ংক্রিয়ভাবে গ্রহণ করে।</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">ডাবল ট্যাপ অধ্যায় স্কিপ অক্ষম করুন</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">ডাবল ট্যাপ কখনও পরবর্তী/পূর্ববর্তী অধ্যায়ে স্কিপ ট্রিগার করতে পারে না</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">ডাবল ট্যাপ মাঝে মাঝে পরবর্তী/পূর্ববর্তী অধ্যায়ে স্কিপ ট্রিগার করতে পারে</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">বাহিরে ডাউনলোড</string>
<string name="revanced_external_downloader_screen_summary">বাহিরের ডাউনলোডার ব্যবহার করার সেটিং</string>
@@ -693,9 +698,9 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
<string name="revanced_hide_cast_button_title">কাস্ট বোতামটি লুকান</string>
<string name="revanced_hide_cast_button_summary_on">কাস্ট বাটন লুকিয়ে রয়েছে</string>
<string name="revanced_hide_cast_button_summary_off">কাস্ট বাটন প্রদর্শিত হয়েছে</string>
<string name="revanced_hide_player_control_buttons_background_title">প্লেয়ার কন্ট্রোল বোতামগুলির পটভূমি লুকান</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">প্লেয়ার ন্্রোল বোতামগুলির পটভূমি লুকানো আছে</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">প্লেয়ার কন্ট্রোল বোতামগুলির পটভূমি দেখানো হয়েছে</string>
<string name="revanced_hide_player_control_buttons_background_title">প্লেয়ার কন্ট্রোল ব্যাকগ্রাউন্ড লুকান</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">প্লেয়ার নিয়ন্্রণের পটভূমি লুকানো আছে</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">প্লেয়ার কন্ট্রোল ব্যাকগ্রাউন্ড দেখানো হয়েছে</string>
<string name="revanced_hide_player_previous_next_buttons_title">পূর্ববর্তী লুকান &amp; পরবর্তী বোতাম</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">বোতাম লুকানো হয়</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">বোতাম দেখানো হয়</string>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -453,6 +453,11 @@ Tato funkce je dostupná pouze pro starší zařízení"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Dialog bude zobrazen</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Tímto krokem neobcházíte věkové omezení. Pouze jej automaticky akceptujete.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Zakázat přeskočení kapitoly dvojitým klepnutím</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Dvojité klepnutí nikdy nespustí přeskočení na další/předchozí kapitolu</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Dvojité klepnutí může občas spustit přeskočení na další/předchozí kapitolu</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Externí stahování</string>
<string name="revanced_external_downloader_screen_summary">Nastavení pro použití externího stahování</string>
@@ -697,9 +702,9 @@ Chcete-li zobrazit nabídku zvukové stopy, změňte možnost „Zfalšovat stre
<string name="revanced_hide_cast_button_title">Skrýt tlačítko Odeslat</string>
<string name="revanced_hide_cast_button_summary_on">Tlačítko pro odesílání je skryto</string>
<string name="revanced_hide_cast_button_summary_off">Tlačítko vysílání je viditelné</string>
<string name="revanced_hide_player_control_buttons_background_title">Skrýt pozadí ovládacích tlačítek přehrávače</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Pozadí ovládacích tlačítek přehrávače je skryté</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Zobrazuje se pozadí ovládacích tlačítek přehrávače</string>
<string name="revanced_hide_player_control_buttons_background_title">Skrýt pozadí ovládacích prvků přehrávače</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Pozadí ovládacích prvků přehrávače je skryto</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Pozadí ovládacích prvků přehrávače je zobrazeno</string>
<string name="revanced_hide_player_previous_next_buttons_title">Skrýt tlačítka Předchozí a Další</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Tlačítka jsou skryta</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Tlačítka jsou zobrazena</string>

View File

@@ -453,6 +453,11 @@ Denne funktion er kun tilgængelig for ældre enheder"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Dialog vil blive vist</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Dette går ikke uden om aldersbegrænsningen. Det accepterer bare det automatisk.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Deaktiver dobbeltklik kapitelspring</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Dobbeltklik kan aldrig udløse et spring til næste/forrige kapitel</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Dobbeltklik kan lejlighedsvis udløse et spring til næste/forrige kapitel</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Eksterne downloads</string>
<string name="revanced_external_downloader_screen_summary">Indstillinger for brug af en ekstern downloader</string>
@@ -697,9 +702,9 @@ For at vise lydspormenuen skal du ændre \"Spoof videostream\" til iOS TV"</stri
<string name="revanced_hide_cast_button_title">Skjul Cast-knappen</string>
<string name="revanced_hide_cast_button_summary_on">Cast-knappen er skjult</string>
<string name="revanced_hide_cast_button_summary_off">Cast knap er vist</string>
<string name="revanced_hide_player_control_buttons_background_title">Skjul baggrunden for afspillerens kontrolknapper</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Baggrunden for afspillerens kontrolknapper er skjult</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Baggrunden for afspillerens kontrolknapper vises</string>
<string name="revanced_hide_player_control_buttons_background_title">Skjul baggrund for afspillerkontroller</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Baggrund for afspilningskontroller er skjult</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Baggrund for afspillerkontroller vises</string>
<string name="revanced_hide_player_previous_next_buttons_title">Skjul Forrige &amp; Næste knapper</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Knapper er skjult</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Knapper vises</string>

View File

@@ -448,6 +448,11 @@ Diese Funktion ist nur für ältere Geräte verfügbar"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Dialog wird angezeigt</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Dies umgeht nicht die Altersbeschränkung, sondern akzeptiert sie nur automatisch.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Doppeltippen zum Kapitelüberspringen deaktivieren</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Doppeltippen kann niemals ein Überspringen zum nächsten/vorherigen Kapitel auslösen</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Doppeltippen kann gelegentlich ein Überspringen zum nächsten/vorherigen Kapitel auslösen</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Externe Downloads</string>
<string name="revanced_external_downloader_screen_summary">Einstellungen für die Verwendung eines externen Downloaders</string>
@@ -690,9 +695,9 @@ Um das Audiotrack-Menü anzuzeigen, ändere \"Video-Streams fälschen\" zu iOS T
<string name="revanced_hide_cast_button_title">Cast-Button ausblenden</string>
<string name="revanced_hide_cast_button_summary_on">Der Cast button ist ausgeblendet</string>
<string name="revanced_hide_cast_button_summary_off">Der Cast button wird angezeigt</string>
<string name="revanced_hide_player_control_buttons_background_title">Hintergrund der Player-Steuerungstasten ausblenden</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Hintergrund der Player-Steuerungstasten ist ausgeblendet</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Hintergrund der Player-Steuerungstasten wird angezeigt</string>
<string name="revanced_hide_player_control_buttons_background_title">Hintergrund der Player-Steuerelemente ausblenden</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Hintergrund der Wiedergabesteuerung ist ausgeblendet</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Hintergrund der Player-Steuerelemente wird angezeigt</string>
<string name="revanced_hide_player_previous_next_buttons_title">Vorherige &amp; Nächste Tasten ausblenden</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Buttons sind ausgeblendet</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Tasten werden angezeigt</string>

View File

@@ -455,6 +455,11 @@ Second \"item\" text"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Εμφανίζεται</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Αυτό δεν παρακάμπτει τον ηλικιακό περιορισμό. Απλώς τον αποδέχεται αυτόματα.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Απενεργοποίηση παράλειψης κεφαλαίου με διπλό πάτημα</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Το διπλό πάτημα δεν παράλειπει στο επόμενο/προηγούμενο κεφάλαιο</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Το διπλό πάτημα μπορεί περιστασιακά να παραλείψει στο επόμενο/προηγούμενο κεφάλαιο</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Εξωτερικές λήψεις</string>
<string name="revanced_external_downloader_screen_summary">Ρυθμίσεις για χρήση εξωτερικού προγράμματος λήψης</string>

View File

@@ -193,9 +193,9 @@ Sin embargo, si activas esto, también se registrarán algunos datos del usuario
<string name="revanced_hide_notify_me_button_title">Ocultar el botón \'Notificarme\'</string>
<string name="revanced_hide_notify_me_button_summary_on">El botón Notificarme está oculto</string>
<string name="revanced_hide_notify_me_button_summary_off">El botón Notificarme está visible</string>
<string name="revanced_hide_playables_title">Ocultar los reproducibles</string>
<string name="revanced_hide_playables_summary_on">Los reproducibles están ocultos</string>
<string name="revanced_hide_playables_summary_off">Se muestran los reproducibles</string>
<string name="revanced_hide_playables_title">Ocultar jugables</string>
<string name="revanced_hide_playables_summary_on">Los jugables están ocultos</string>
<string name="revanced_hide_playables_summary_off">Los jugables están visibles</string>
<!-- 'Show more' should be translated with the same localized wording that YouTube displays.
This button usually appears when searching for a YT creator. -->
<string name="revanced_hide_show_more_button_title">Ocultar botón \'Mostrar más\'</string>
@@ -450,6 +450,11 @@ Esta función solo está disponible para dispositivos antiguos"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Se mostrará el diálogo</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Esto no pasa por alto la restricción de edad, sino que simplemente la acepta automáticamente.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Deshabilitar el salto de capítulo con doble toque</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">El doble toque nunca puede activar un salto al capítulo siguiente/anterior</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">El doble toque puede ocasionalmente activar un salto al capítulo siguiente/anterior</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Descargas externa</string>
<string name="revanced_external_downloader_screen_summary">Configuración para el uso de un descargador externo</string>
@@ -694,9 +699,9 @@ Para mostrar el menú de la pista de audio, cambia \"Suplantar transmisiones de
<string name="revanced_hide_cast_button_title">Ocultar el botón Transmitir</string>
<string name="revanced_hide_cast_button_summary_on">El botón de envío a otros dispositivos está oculto</string>
<string name="revanced_hide_cast_button_summary_off">El botón de envío a otros dispositivos es visible</string>
<string name="revanced_hide_player_control_buttons_background_title">Ocultar el fondo de los botones de control del reproductor</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">El fondo de los botones de control del reproductor está oculto</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Se muestra el fondo de los botones de control del reproductor</string>
<string name="revanced_hide_player_control_buttons_background_title">Ocultar fondo de los controles del reproductor</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">El fondo de los controles del reproductor está oculto</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Se muestra el fondo de los controles del reproductor</string>
<string name="revanced_hide_player_previous_next_buttons_title">Ocultar botones Anterior &amp; Siguiente</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Los botones están ocultos</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Los botones se muestran</string>

View File

@@ -453,6 +453,11 @@ See funktsioon on saadaval ainult vanemates seadmetes"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Dialoog kuvatakse</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">See ei mööda vanusepiirangust. See lihtsalt aktsepteerib seda automaatselt.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Keela topeltpuudutusega peatüki vahelejätmine</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Topeltpuudutus ei saa kunagi käivitada järgmise/eelmise peatüki vahelejätmist</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Topeltpuudutus võib aeg-ajalt käivitada järgmise/eelmise peatüki vahelejätmise</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Välised allalaadimised</string>
<string name="revanced_external_downloader_screen_summary">Seaded välise allalaadija kasutamiseks</string>
@@ -698,8 +703,8 @@ Heliriba menüü kuvamiseks muutke valikut „Võltsitud videovoogedastus“ vä
<string name="revanced_hide_cast_button_summary_on">Ülekandmise nupp on peidetud</string>
<string name="revanced_hide_cast_button_summary_off">Ülekandmise nupp on nähtav</string>
<string name="revanced_hide_player_control_buttons_background_title">Peida pleieri juhtnuppude taust</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Pleieri juhtnuppude taust on peidetud</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Pleieri juhtnuppude taust on näidatud</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Mängija juhtnuppude taust on peidetud</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Pleieri juhtnuppude taust on nähtav</string>
<string name="revanced_hide_player_previous_next_buttons_title">Peida eelmine &amp; järgmine nupp</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Nupud on peidetud</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Nupud on nähtavad</string>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -115,6 +115,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -161,11 +161,20 @@ Et saa ilmoituksia odottamattomista tapahtumista."</string>
<string name="revanced_hide_crowdfunding_box_title">Piilota joukkorahoituslaatikko</string>
<string name="revanced_hide_crowdfunding_box_summary_on">Joukkorahoituslaatikko on piilotettu</string>
<string name="revanced_hide_crowdfunding_box_summary_off">Joukkorahoituslaatikko näytetään</string>
<string name="revanced_hide_expandable_card_title">Piilota laajennettava kortti</string>
<string name="revanced_hide_expandable_card_summary_on">Laajennettava kortti on piilotettu videoiden alla</string>
<string name="revanced_hide_expandable_card_summary_off">Laajennettava kortti näytetään videoiden alla</string>
<string name="revanced_hide_feed_survey_title">Piilota syötteen kyselyt</string>
<string name="revanced_hide_feed_survey_summary_on">Syötteen kyselyt on piilotettu</string>
<string name="revanced_hide_feed_survey_summary_off">Syötteen kyselyt näytetään</string>
<string name="revanced_hide_floating_microphone_button_title">Piilota kelluva mikrofonipainike</string>
<string name="revanced_hide_floating_microphone_button_summary_on">Kelluva mikrofonipainike on piilotettu haussa</string>
<string name="revanced_hide_floating_microphone_button_summary_off">Kelluva mikrofonipainike näytetään haussa</string>
<string name="revanced_hide_horizontal_shelves_title">Piilota vaakasuuntaiset hyllyt</string>
<string name="revanced_hide_horizontal_shelves_summary_off">Vaakasuuntaiset hyllyt näytetään</string>
<string name="revanced_hide_image_shelf_title">Piilota kuvahylly</string>
<string name="revanced_hide_image_shelf_summary_on">Kuvahylly on piilotettu hakutuloksissa</string>
<string name="revanced_hide_image_shelf_summary_off">Kuvahylly näytetään hakutuloksissa</string>
<string name="revanced_hide_latest_posts_title">Piilota uusimmat postaukset</string>
<string name="revanced_hide_latest_posts_summary_on">Uusimmat postaukset on piilotettu</string>
<string name="revanced_hide_latest_posts_summary_off">Uusimmat postaukset näytetään</string>
@@ -178,18 +187,25 @@ Et saa ilmoituksia odottamattomista tapahtumista."</string>
<!-- 'Notify me' should be translated using the same localized wording YouTube displays.
This item appear in the subscription feed for future livestreams or unreleased videos. -->
<string name="revanced_hide_notify_me_button_title">Piilota \"Ilmoita minulle\" -painike</string>
<string name="revanced_hide_notify_me_button_summary_on">Ilmoita minulle -painike on piilotettu</string>
<string name="revanced_hide_notify_me_button_summary_off">Ilmoita minulle -painike näytetään</string>
<string name="revanced_hide_playables_title">Piilota Pelattavat</string>
<string name="revanced_hide_playables_summary_on">Pelattavat on piilotettu</string>
<string name="revanced_hide_playables_summary_off">Pelattavat näytetään</string>
<!-- 'Show more' should be translated with the same localized wording that YouTube displays.
This button usually appears when searching for a YT creator. -->
<string name="revanced_hide_show_more_button_title">Piilota \"Näytä lisää\" -painike</string>
<string name="revanced_hide_show_more_button_summary_on">Näytä lisää -painike on piilotettu hakutuloksissa</string>
<string name="revanced_hide_show_more_button_summary_off">Näytä lisää -painike näytetään hakutuloksissa</string>
<string name="revanced_hide_ticket_shelf_title">Piilota lippuhylly</string>
<string name="revanced_hide_ticket_shelf_summary_on">Lippuhylly on piilotettu</string>
<string name="revanced_hide_ticket_shelf_summary_off">Lippuhylly näytetään</string>
<!-- 'People also watched' and 'You might also like' should be translated using the same localized wording YouTube displays. -->
<string name="revanced_hide_video_recommendation_labels_title">Piilota videosuositusten tunnisteet</string>
<!-- https://logos.fandom.com/wiki/YouTube/Yoodles -->
<string name="revanced_hide_doodles_title">Piilota YouTube Doodlet</string>
<string name="revanced_hide_doodles_summary_on">Logon YouTube Doodles -animaatio on piilotettu</string>
<string name="revanced_hide_doodles_summary_off">Logon YouTube Doodles -animaatio näytetään</string>
<string name="revanced_hide_doodles_user_dialog_message">"YouTube Doodlet näkyvät muutamana päivänä vuodessa.
Jos Doodle näkyy tällä hetkellä alueellasi ja tämä piilotusasetus on käytössä, myös hakupalkin alla oleva suodatinpalkki piilotetaan."</string>
@@ -208,10 +224,18 @@ Jos Doodle näkyy tällä hetkellä alueellasi ja tämä piilotusasetus on käyt
<!-- 'Join' should be translated using the same localized wording YouTube displays.
This appears in the video player for certain videos. -->
<string name="revanced_hide_join_membership_button_title">Piilota Liity-painike</string>
<string name="revanced_hide_join_membership_button_summary_on">Liity-painike on piilotettu</string>
<string name="revanced_hide_join_membership_button_summary_off">Liity-painike näytetään</string>
<string name="revanced_hide_medical_panels_title">Piilota lääketieteelliset paneelit</string>
<string name="revanced_hide_medical_panels_summary_on">Lääketieteelliset paneelit on piilotettu</string>
<string name="revanced_hide_medical_panels_summary_off">Lääketieteelliset paneelit näytetään</string>
<string name="revanced_hide_subscribers_community_guidelines_title">Piilota tilaajien ohjeet</string>
<string name="revanced_hide_quick_actions_title">Piilota pikatoiminnot</string>
<string name="revanced_hide_quick_actions_summary_on">Pikatoiminnot on piilotettu kokoruututilassa</string>
<string name="revanced_hide_quick_actions_summary_off">Pikatoiminnot näytetään kokoruututilassa</string>
<string name="revanced_hide_related_videos_title">Piilota liittyvät videot</string>
<string name="revanced_hide_related_videos_summary_on">Liittyvät videot on piilotettu pikatoiminnoissa</string>
<string name="revanced_hide_related_videos_summary_off">Liittyvät videot näytetään pikatoiminnoissa</string>
<string name="revanced_hide_subscribers_community_guidelines_title">Piilota tilaajien säännöt</string>
<string name="revanced_hide_subscribers_community_guidelines_summary_on">Tilaajien yhteisön säännöt on piilotettu</string>
<string name="revanced_hide_subscribers_community_guidelines_summary_off">Tilaajien yhteisön säännöt näytetään</string>
<string name="revanced_hide_timed_reactions_title">Piilota ajoitetut reaktiot</string>
@@ -260,11 +284,26 @@ Jos Doodle näkyy tällä hetkellä alueellasi ja tämä piilotusasetus on käyt
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">Piilota liittyvissä videoissa</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Piilotettu liittyvissä videoissa</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">Näytetään liittyvissä videoissa</string>
<string name="revanced_channel_screen_title">Kanavasivu</string>
<string name="revanced_channel_screen_summary">Piilota tai näytä kanavasivun osia</string>
<!-- 'For You' should be translated using the same localized wording YouTube displays. -->
<string name="revanced_hide_for_you_shelf_title">Piilota \"\'Sinulle\" -hylly</string>
<string name="revanced_hide_for_you_shelf_summary_on">Sinulle-hylly on piilotettu</string>
<string name="revanced_hide_for_you_shelf_summary_off">Sinulle-hylly näytetään</string>
<string name="revanced_hide_links_preview_title">Piilota linkkien esikatselu</string>
<string name="revanced_hide_links_preview_summary_on">Linkkien esikatselu on piilotettu</string>
<string name="revanced_hide_links_preview_summary_off">Linkkien esikatselu näytetään</string>
<string name="revanced_hide_members_shelf_title">Piilota jäsenhylly</string>
<string name="revanced_hide_members_shelf_summary_on">Jäsenhylly on piilotettu</string>
<string name="revanced_hide_members_shelf_summary_off">Jäsenhylly näytetään</string>
<!-- 'Visit Community' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_visit_community_button_title">Piilota \"Tutustu yhteisöön\" -painike</string>
<string name="revanced_hide_visit_community_button_summary_on">\"Tutustu yhteisöön\" -painike on piilotettu</string>
<string name="revanced_hide_visit_community_button_summary_off">\"Tutustu yhteisöön\" -painike näytetään</string>
<!-- 'Visit store' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_visit_store_button_title">Piilota \"Vieraile kaupassa\" -painike kanavasivuilla</string>
<string name="revanced_hide_visit_store_button_summary_on">Kaupan \"Näytä kaikki\" -painike on piilotettu</string>
<string name="revanced_hide_visit_store_button_summary_off">Kaupan \"Näytä kaikki\" -painike näytetään</string>
<string name="revanced_comments_screen_title">Kommentit</string>
<string name="revanced_comments_screen_summary">Piilota tai näytä kommenttiosion osia</string>
<string name="revanced_hide_comments_ai_chat_summary_title">Piilota tekoälyn luoma chat-yhteenveto</string>
@@ -273,12 +312,18 @@ Jos Doodle näkyy tällä hetkellä alueellasi ja tämä piilotusasetus on käyt
<string name="revanced_hide_comments_ai_summary_title">Piilota tekoälyn luoma kommenttiyhteenveto</string>
<string name="revanced_hide_comments_ai_summary_summary_on">Kommenttien yhteenveto on piilotettu</string>
<string name="revanced_hide_comments_ai_summary_summary_off">Kommenttien yhteenveto näytetään</string>
<string name="revanced_hide_comments_channel_guidelines_title">Piilota kanavan säännöt</string>
<string name="revanced_hide_comments_channel_guidelines_summary_on">Kanavan säännöt on piilotettu</string>
<string name="revanced_hide_comments_channel_guidelines_summary_off">Kanavan säännöt näytetään</string>
<string name="revanced_hide_comments_by_members_header_title">Piilota \"Jäsenten kommentit\" -ylätunniste</string>
<string name="revanced_hide_comments_by_members_header_summary_on">Jäsenten kommentit -ylätunniste on piilotettu</string>
<string name="revanced_hide_comments_by_members_header_summary_off">Jäsenten kommentit -ylätunniste näytetään</string>
<string name="revanced_hide_comments_section_title">Piilota kommenttiosio</string>
<string name="revanced_hide_comments_section_summary_on">Kommenttiosio on piilotettu</string>
<string name="revanced_hide_comments_section_summary_off">Kommenttiosio näytetään</string>
<string name="revanced_hide_comments_community_guidelines_title">Piilota yhteisön säännöt</string>
<string name="revanced_hide_comments_community_guidelines_summary_on">Yhteisön säännöt on piilotettu</string>
<string name="revanced_hide_comments_community_guidelines_summary_off">Yhteisön säännöt näytetään</string>
<string name="revanced_hide_comments_create_a_short_button_title">Piilota \"Luo Shorts-video\" -painike</string>
<string name="revanced_hide_comments_create_a_short_button_summary_on">Luo Shorts-video -painike on piilotettu</string>
<string name="revanced_hide_comments_create_a_short_button_summary_off">Luo Shorts-video -painike näytetään</string>
@@ -288,6 +333,7 @@ Jos Doodle näkyy tällä hetkellä alueellasi ja tämä piilotusasetus on käyt
<string name="revanced_hide_comments_thanks_button_title">Piilota Kiitos-painike</string>
<string name="revanced_hide_comments_thanks_button_summary_on">Kiitos-painike on piilotettu</string>
<string name="revanced_hide_comments_thanks_button_summary_off">Kiitos-painike näytetään</string>
<string name="revanced_hide_comments_timestamp_button_title">Piilota aikaleima-painike</string>
<string name="revanced_hide_comments_timestamp_button_summary_on">Aikaleimapainike on piilotettu</string>
<string name="revanced_hide_comments_timestamp_button_summary_off">Aikaleimapainike näytetään</string>
<string name="revanced_custom_filter_screen_title">Mukautettu suodatin</string>
@@ -336,7 +382,12 @@ Rajoitukset
<string name="revanced_hide_keyword_toast_invalid_broad">Avainsana piilottaa kaikki videot: %s</string>
</patch>
<patch id="ad.general.hideAdsResourcePatch">
<string name="revanced_hide_creator_store_shelf_title">Piilota sisällöntuottajan kauppahylly</string>
<string name="revanced_hide_creator_store_shelf_summary_on">Sisällöntuottajan kauppahylly videosoittimen alla on piilotettu</string>
<string name="revanced_hide_creator_store_shelf_summary_off">Sisällöntuottajan kauppahylly videosoittimen alla näytetään</string>
<string name="revanced_hide_end_screen_store_banner_title">Piilota loppunäytön kauppabanneri</string>
<string name="revanced_hide_end_screen_store_banner_summary_on">Loppunäytön kauppabanneri on piilotettu</string>
<string name="revanced_hide_end_screen_store_banner_summary_off">Loppunäytön kauppabanneri näytetään</string>
<string name="revanced_hide_fullscreen_ads_title">Piilota koko näytön mainokset</string>
<string name="revanced_hide_fullscreen_ads_summary_on">"Koko näytön mainokset on piilotettu
@@ -356,7 +407,13 @@ Tämä ominaisuus on käytettävissä vain vanhemmilla laitteilla"</string>
<string name="revanced_hide_self_sponsor_ads_title">Piilota itse-sponsoroidut kortit</string>
<string name="revanced_hide_self_sponsor_ads_summary_on">Itse-sponsoroidut kortit ovat piilotettu</string>
<string name="revanced_hide_self_sponsor_ads_summary_off">Itse-sponsoroidut kortit näytetään</string>
<string name="revanced_hide_shopping_links_title">Piilota ostoslinkit</string>
<string name="revanced_hide_shopping_links_summary_on">Ostoslinkit videon kuvauksessa on piilotettu</string>
<string name="revanced_hide_shopping_links_summary_off">Ostoslinkit videon kuvauksessa näytetään</string>
<!-- 'View products' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_view_products_banner_title">Piilota \"Näytä tuotteet\" -banneri</string>
<string name="revanced_hide_view_products_banner_summary_on">Videon peittokuvan tuotebannerit on piilotettu</string>
<string name="revanced_hide_view_products_banner_summary_off">Videon peittokuvan tuotebannerit näytetään</string>
<string name="revanced_hide_web_search_results_title">Piilota verkkohakutulokset</string>
<string name="revanced_hide_web_search_results_summary_on">Verkkohakutulokset on piilotettu</string>
<string name="revanced_hide_web_search_results_summary_off">Verkkohakutulokset näytetään</string>
@@ -387,6 +444,8 @@ Tämä ominaisuus on käytettävissä vain vanhemmilla laitteilla"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Valintaikkuna näytetään</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Tämä ei ohita ikärajoitusta. Se vain hyväksyy sen automaattisesti.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Ulkoiset lataukset</string>
<string name="revanced_external_downloader_screen_summary">Asetukset ulkoisen lataajan käyttämiselle</string>
@@ -628,9 +687,6 @@ Jos haluat nähdä sen, aseta \"Naamioi videovirrat\" iOS TV:ksi"</string>
<string name="revanced_hide_cast_button_title">Piilota Cast-painike</string>
<string name="revanced_hide_cast_button_summary_on">Cast-painike on piilotettu</string>
<string name="revanced_hide_cast_button_summary_off">Cast-painike näytetään</string>
<string name="revanced_hide_player_control_buttons_background_title">Piilota soittimen ohjauspainikkeiden tausta</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Soittimen ohjauspainikkeiden tausta on piilotettu</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Soittimen ohjauspainikkeiden tausta näytetään</string>
<string name="revanced_hide_player_previous_next_buttons_title">Piilota Edellinen &amp; Seuraava -painikkeet</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Painikkeet on piilotettu</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Painikkeet näytetään</string>
@@ -667,7 +723,13 @@ Jos haluat nähdä sen, aseta \"Naamioi videovirrat\" iOS TV:ksi"</string>
<string name="revanced_shorts_player_screen_title">Shorts-soitin</string>
<string name="revanced_shorts_player_screen_summary">Piilota tai näytä Shorts-soittimen osia</string>
<!-- 'Home' should be translated using the same localized wording YouTube displays for the Home tab. -->
<string name="revanced_hide_shorts_home_title">Piilota Shortsit kotisyötteessä</string>
<string name="revanced_hide_shorts_home_summary_on">Piilotettu kotisyötteessä ja liittyvissä videoissa</string>
<string name="revanced_hide_shorts_home_summary_off">Näytetään kotisyötteessä ja liittyvissä videoissa</string>
<!-- 'Subscriptions' should be translated using the same localized wording YouTube displays for the Subscriptions tab. -->
<string name="revanced_hide_shorts_subscriptions_title">Piilota Shortsit Tilaukset-syötteessä</string>
<string name="revanced_hide_shorts_subscriptions_summary_on">Piilotettu tilaukset-syötteessä</string>
<string name="revanced_hide_shorts_subscriptions_summary_off">Näytetään tilaukset-syötteessä</string>
<string name="revanced_hide_shorts_search_title">Piilota Shortsit hakutuloksissa</string>
<string name="revanced_hide_shorts_search_summary_on">Piilotettu hakutuloksissa</string>
<string name="revanced_hide_shorts_search_summary_off">Näytetään hakutuloksissa</string>
@@ -675,6 +737,8 @@ Jos haluat nähdä sen, aseta \"Naamioi videovirrat\" iOS TV:ksi"</string>
<string name="revanced_hide_shorts_history_summary_on">Piilotettu katseluhistoriassa</string>
<string name="revanced_hide_shorts_history_summary_off">Näytetään katseluhistoriassa</string>
<string name="revanced_hide_shorts_super_thanks_button_title">Piilota Osta Superkiitos -painike</string>
<string name="revanced_hide_shorts_super_thanks_button_summary_on">Osta Superkiitos -painike on piilotettu</string>
<string name="revanced_hide_shorts_super_thanks_button_summary_off">Osta Superkiitos -painike näytetään</string>
<string name="revanced_hide_shorts_effect_button_title">Piilota Tehoste-painike</string>
<string name="revanced_hide_shorts_effect_button_summary_on">Tehoste-painike on piilotettu</string>
<string name="revanced_hide_shorts_effect_button_summary_off">Tehoste-painike näytetään</string>
@@ -706,9 +770,9 @@ Jos haluat nähdä sen, aseta \"Naamioi videovirrat\" iOS TV:ksi"</string>
<string name="revanced_hide_shorts_search_suggestions_title">Piilota hakuehdotukset</string>
<string name="revanced_hide_shorts_search_suggestions_summary_on">Hakuehdotukset on piilotettu</string>
<string name="revanced_hide_shorts_search_suggestions_summary_off">Hakuehdotukset näytetään</string>
<string name="revanced_hide_shorts_shop_button_title">Piilota Shopping-painike</string>
<string name="revanced_hide_shorts_shop_button_summary_on">Shopping-painike on piilotettu</string>
<string name="revanced_hide_shorts_shop_button_summary_off">Shopping-painike näytetään</string>
<string name="revanced_hide_shorts_shop_button_title">Piilota Kauppa-painike</string>
<string name="revanced_hide_shorts_shop_button_summary_on">Kauppa-painike on piilotettu</string>
<string name="revanced_hide_shorts_shop_button_summary_off">Kauppa-painike näytetään</string>
<string name="revanced_hide_shorts_stickers_title">Piilota tarrat</string>
<string name="revanced_hide_shorts_stickers_summary_on">Tarrat on piilotettu</string>
<string name="revanced_hide_shorts_stickers_summary_off">Tarrat näytetään</string>
@@ -757,7 +821,12 @@ Jos haluat nähdä sen, aseta \"Naamioi videovirrat\" iOS TV:ksi"</string>
<string name="revanced_hide_shorts_channel_bar_summary_on">Kanavapalkki on piilotettu</string>
<string name="revanced_hide_shorts_channel_bar_summary_off">Kanavapalkki näytetään</string>
<string name="revanced_hide_shorts_video_title_title">Piilota videon otsikko</string>
<string name="revanced_hide_shorts_video_title_summary_on">Videon otsikko on piilotettu</string>
<string name="revanced_hide_shorts_video_title_summary_off">Videon otsikko näytetään</string>
<string name="revanced_hide_shorts_sound_metadata_label_title">Piilota äänen metadata-tunniste</string>
<string name="revanced_hide_shorts_sound_metadata_label_summary_on">Äänen metatietojen tunniste on piilotettu</string>
<string name="revanced_hide_shorts_sound_metadata_label_summary_off">Äänen metatietojen tunniste näytetään</string>
<string name="revanced_hide_shorts_full_video_link_label_title">Piilota videolinkin tunniste</string>
<string name="revanced_hide_shorts_full_video_link_label_summary_on">Videolinkin tunniste on piilotettu</string>
<string name="revanced_hide_shorts_full_video_link_label_summary_off">Videolinkin tunniste näytetään</string>
<string name="revanced_hide_shorts_navigation_bar_title">Piilota navigointipalkki</string>
@@ -773,6 +842,9 @@ Asetukset → Toisto → Toista seuraava video automaattisesti"</string>
<string name="revanced_end_screen_suggested_video_summary_off">Loppunäytön ehdotettu video näytetään</string>
</patch>
<patch id="layout.hide.relatedvideooverlay.hideRelatedVideoOverlayPatch">
<string name="revanced_hide_related_videos_overlay_title">Piilota liittyvät videot -peittokuva</string>
<string name="revanced_hide_related_videos_overlay_summary_on">Liittyvät videot -peittokuva on piilotettu kokoruututilassa</string>
<string name="revanced_hide_related_videos_overlay_summary_off">Liittyvät videot -peittokuva näytetään kokoruututilassa</string>
</patch>
<patch id="layout.hide.time.hideTimestampPatch">
<string name="revanced_hide_timestamp_title">Piilota videon aikaleima</string>
@@ -885,7 +957,13 @@ Tämä ominaisuus toimii parhaiten, kun videon laatu on 720p tai alhaisempi ja k
<string name="revanced_sb_enable_auto_hide_skip_segment_button">Piilota ohita-painike automaattisesti</string>
<string name="revanced_sb_enable_auto_hide_skip_segment_button_sum_on">Ohita-painike piiloutuu muutaman sekunnin kuluttua</string>
<string name="revanced_sb_enable_auto_hide_skip_segment_button_sum_off">Ohita-painike näytetään koko osion ajan</string>
<string name="revanced_sb_auto_hide_skip_button_duration">Ohita-painikkeen kesto</string>
<string name="revanced_sb_auto_hide_skip_button_duration_sum">Kuinka kauan ohita- ja ohita-kohokohtaan-painikkeita näytetään ennen automaattista piilottamista</string>
<string name="revanced_sb_general_skiptoast">Näytä kumoa ohitus -ponnahdusilmoitus</string>
<string name="revanced_sb_general_skiptoast_sum_on">Ponnahdusilmoitus näytetään, kun osio ohitetaan automaattisesti. Napauta ponnahdusilmoitusta kumotaksesi ohituksen</string>
<string name="revanced_sb_general_skiptoast_sum_off">Ponnahdusilmoitusta ei näytetä</string>
<string name="revanced_sb_toast_on_skip_duration">Ohita-ponnahdusilmoituksen kesto</string>
<string name="revanced_sb_toast_on_skip_duration_sum">Kuinka kauan kumoa ohitus -ponnahdusilmoitus näytetään</string>
<string name="revanced_sb_duration_1s">1 sekunti</string>
<string name="revanced_sb_duration_2s">2 sekuntia</string>
<string name="revanced_sb_duration_3s">3 sekuntia</string>
@@ -1215,7 +1293,12 @@ Minisoitin voidaan vetää pois näytöltä vasemmalle tai oikealle"</string>
<string name="revanced_seekbar_custom_color_invalid">Virheellinen etenemispalkin väriarvo</string>
</patch>
<patch id="layout.branding.changeHeaderPatch">
<string name="revanced_header_logo_title">Ylätunnisteen logo</string>
<string name="revanced_header_logo_entry_1">Oletus</string>
<string name="revanced_header_logo_entry_2">Tavallinen</string>
<!-- For this situation "Minimal" means minimalistic. It does not mean small or tiny. -->
<string name="revanced_header_logo_entry_5">ReVanced-minimaalinen</string>
<string name="revanced_header_logo_entry_6">Mukautettu</string>
</patch>
<patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch">
<string name="revanced_bypass_image_region_restrictions_title">Ohita kuvien alueelliset rajoitukset</string>
@@ -1228,8 +1311,10 @@ Tämä voi korjata puuttuvat kuvat, jotka on estetty tietyillä alueilla"</strin
<!-- 'Home' should be translated using the same localized wording YouTube displays for the Home tab. -->
<string name="revanced_alt_thumbnail_home_title">Koti-välilehti</string>
<!-- 'Subscriptions' should be translated using the same localized wording YouTube displays for the Subscriptions tab. -->
<string name="revanced_alt_thumbnail_subscription_title">Tilaukset-välilehti</string>
<!-- 'You' should be translated using the same localized wording YouTube displays for the You (Library) tab. -->
<string name="revanced_alt_thumbnail_library_title">Sinä-välilehti</string>
<string name="revanced_alt_thumbnail_player_title">Soittimen soittolistat ja suositukset</string>
<string name="revanced_alt_thumbnail_search_title">Hakutulokset</string>
<string name="revanced_alt_thumbnail_options_entry_1">Alkuperäiset pikkukuvat</string>
<string name="revanced_alt_thumbnail_options_entry_2">Alkuperäiset ja DeArrow-pikkukuvat</string>
@@ -1446,6 +1531,7 @@ AVC:n maksimiresoluutio on 1080p, Opus-äänikoodekki ei ole käytettävissä, j
<string name="revanced_block_video_ads_summary_off">Videomainoksia ei estetä</string>
</patch>
<patch id="chat.antidelete.showDeletedMessagesPatch">
<string name="revanced_deleted_msg">Viesti poistettiin</string>
<string name="revanced_show_deleted_messages_title">Näytä poistetut viestit</string>
<string name="revanced_show_deleted_messages_entry_1">Älä näytä poistettuja viestejä</string>
<string name="revanced_show_deleted_messages_entry_2">Piilota poistetut viestit spoilereilla</string>
@@ -1466,6 +1552,8 @@ AVC:n maksimiresoluutio on 1080p, Opus-äänikoodekki ei ole käytettävissä, j
<string name="revanced_settings">ReVanced-asetukset</string>
<string name="revanced_about_title">Tietoja</string>
<string name="revanced_about_summary">Tietoja ReVancedista</string>
<string name="revanced_ads_screen_title">Mainostenesto</string>
<string name="revanced_ads_screen_summary">Mainostenestoasetukset</string>
<string name="revanced_chat_screen_title">Chat</string>
<string name="revanced_chat_screen_summary">Chat-asetukset</string>
<string name="revanced_misc_screen_title">Sekalaiset</string>

View File

@@ -453,6 +453,11 @@ Ang tampok na ito ay magagamit lamang para sa mga mas lumang device"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Ipapakita ang dialog</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Hindi nito nilalampasan ang paghihigpit sa edad. Awtomatiko lang itong tinatanggap.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Huwag paganahin ang paglaktaw ng kabanata sa doble tap</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Ang doble tap ay hindi kailanman maaaring mag-trigger ng paglaktaw sa susunod/nakaraang kabanata</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Ang doble tap ay paminsan-minsan ay maaaring mag-trigger ng paglaktaw sa susunod/nakaraang kabanata</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Mga panlabas na pag-download</string>
<string name="revanced_external_downloader_screen_summary">Mga setting para sa paggamit ng external na downloader</string>
@@ -695,9 +700,9 @@ Upang ipakita ang menu ng Audio track, baguhin ang 'Spoof video streams' sa iOS
<string name="revanced_hide_cast_button_title">Itago ang Cast button</string>
<string name="revanced_hide_cast_button_summary_on">Ang buton ng Cast ay nakatago</string>
<string name="revanced_hide_cast_button_summary_off">Nakikita ang cast button</string>
<string name="revanced_hide_player_control_buttons_background_title">Itago ang background ng mga button ng kontrol ng player</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Nakatago ang background ng mga button ng kontrol ng player</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Ipinapakita ang background ng mga button ng kontrol ng player</string>
<string name="revanced_hide_player_control_buttons_background_title">Itago ang background ng mga kontrol ng manlalaro</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Nakatago ang background ng mga kontrol ng manlalaro</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Ipinapakita ang background ng mga kontrol ng manlalaro</string>
<string name="revanced_hide_player_previous_next_buttons_title">Itago ang Nakaraan at Susunod na mga pindutan</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Nakatago ang mga pindutan</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Ang mga pindutan ay ipinapakita</string>

View File

@@ -453,6 +453,11 @@ Cette fonctionnalité est disponible uniquement pour les appareils anciens"</str
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Le message sera affiché</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Cette option ne contourne pas la vérification de l\'âge. Elle est juste confirmée automatiquement.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Désactiver le double appui pour sauter les chapitres</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Le double appui ne peut jamais déclencher un saut au chapitre suivant/précédent</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Le double appui peut occasionnellement déclencher un saut au chapitre suivant/précédent</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Téléchargements externes</string>
<string name="revanced_external_downloader_screen_summary">Paramètres pour l\'utilisation d\'un outil externe de téléchargement</string>
@@ -570,7 +575,7 @@ Réglez le volume en balayant verticalement sur le côté droit de l'écran"</st
<string name="revanced_hide_thanks_button_summary_off">Le bouton Merci est affiché</string>
<!-- 'Ask' should be translated with the same localized wording that YouTube displays.
This button only shows up if the user ip is from specific region such as the USA or EU. -->
<string name="revanced_hide_ask_button_title">Masquer Demander</string>
<string name="revanced_hide_ask_button_title">Masquer \"Demander\"</string>
<string name="revanced_hide_ask_button_summary_on">Le bouton Demander est masqué</string>
<string name="revanced_hide_ask_button_summary_off">Le bouton Demander est affiché</string>
<!-- 'Clip' should be translated with the same localized wording that YouTube displays. -->
@@ -697,9 +702,9 @@ Pour afficher le menu Piste audio, définissez \"Falsifier les flux vidéo\" sur
<string name="revanced_hide_cast_button_title">Masquer le bouton Caster</string>
<string name="revanced_hide_cast_button_summary_on">Le bouton Caster est masqué</string>
<string name="revanced_hide_cast_button_summary_off">Le bouton Caster est affiché</string>
<string name="revanced_hide_player_control_buttons_background_title">Masquer l\'arrière-plan des boutons de commande du lecteur</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">L\'arrière-plan des boutons de commande du lecteur est masqué</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">L\'arrière-plan des boutons de commande du lecteur est affiché</string>
<string name="revanced_hide_player_control_buttons_background_title">Masquer l\'arrière-plan des commandes du lecteur</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">L\'arrière-plan des commandes du lecteur est masqué</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">L\'arrière-plan des commandes du lecteur est affiché</string>
<string name="revanced_hide_player_previous_next_buttons_title">Masquer les boutons Précédent et Suivant</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Les boutons sont masqués</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Les boutons sont affichés</string>

View File

@@ -453,6 +453,11 @@ Níl an ghné seo ar fáil ach do ghléasanna níos sine"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Taispeánfar dialóg</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Ní sheachnaíonn sé seo an srian aoise. Ní ghlacann sé leis go huathoibríoch.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Díchumasaigh scipeáil caibidle le sconna dúbailte</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Ní féidir le sconna dúbailte scipeáil chuig an gcéad chaibidil eile/roimhe seo a spreagadh go deo</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Is féidir le sconna dúbailte scipeáil chuig an gcéad chaibidil eile/roimhe seo a spreagadh ó am go chéile</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Íosluchtaigh seachtracha</string>
<string name="revanced_external_downloader_screen_summary">Socruithe chun íoslódálaí seachtrach a úsáid</string>
@@ -697,9 +702,9 @@ Chun roghchlár na rian fuaime a thaispeáint, athraigh 'Srutháin físeáin bhr
<string name="revanced_hide_cast_button_title">Folaigh cnaipe an Chasta</string>
<string name="revanced_hide_cast_button_summary_on">Tá cnaipe teilgthe i bhfolach</string>
<string name="revanced_hide_cast_button_summary_off">Taispeántar cnaipe teilgthe</string>
<string name="revanced_hide_player_control_buttons_background_title">Folaigh cúlra cnaipí rialaithe an tseinnteora</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Tá cúlra cnaipí rialaithe an tseinnteora folaithe</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Taispeántar cúlra cnaipí rialaithe an tseinnteora</string>
<string name="revanced_hide_player_control_buttons_background_title">Folaigh cúlra rialuithe an imreora</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Tá cúlra rialuithe an imreora i bhfolach</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Taispeántar cúlra rialuithe an imreora</string>
<string name="revanced_hide_player_previous_next_buttons_title">Folaigh Cnaipí Roimhe &amp; Ar Aghaidh</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Tá cnaipí i bhfolach</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Taispeántar cnaipí</string>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -453,6 +453,11 @@ Ez a funkció csak régebbi eszközökön érhető el"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">A párbeszédpanel megjelenik</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Ez nem kerüli meg a korhatárt, csak automatikusan elfogadja.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Dupla koppintásos fejezetátugrás letiltása</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">A dupla koppintás soha nem indíthatja el a következő/előző fejezetre való ugrást</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">A dupla koppintás alkalmanként elindíthatja a következő/előző fejezetre való ugrást</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Külső letöltések</string>
<string name="revanced_external_downloader_screen_summary">Beállítások külső letöltő használatához</string>
@@ -697,9 +702,9 @@ Az audiosáv menü megjelenítéséhez módosítsa a \"Videófolyamok hamisítá
<string name="revanced_hide_cast_button_title">Küldés gomb elrejtése</string>
<string name="revanced_hide_cast_button_summary_on">Az átküldés gomb rejtve van</string>
<string name="revanced_hide_cast_button_summary_off">Az átküldés gomb látható</string>
<string name="revanced_hide_player_control_buttons_background_title">A lejátszó vezérlőgombjainak hátterének elrejtése</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">A lejátszó vezérlőgombjainak háttere rejtve</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">A lejátszó vezérlőgombjainak háttere látható</string>
<string name="revanced_hide_player_control_buttons_background_title">Lejátszóvezérlők hátterének elrejtése</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">A lejátszóvezérlők háttere rejtett</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">A lejátszóvezérlők háttere látható</string>
<string name="revanced_hide_player_previous_next_buttons_title">Az Előző és a Következő gombok elrejtése</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">A gombok elrejtve</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">A gombok megjelennek</string>

View File

@@ -453,6 +453,11 @@ MicroG-ի համար մարտկոցի օպտիմալացումը անջատել
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Զրույցը կցուցադրվի</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Սա չի խուսափում տարիքային սահմանափակումից։ Այն պարզապես ավտոմատ կերպով ընդունում է այն։</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Անջատել կրկնակի հպումով գլուխը բաց թողնելը</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Կրկնակի հպումը երբեք չի կարող առաջացնել հաջորդ/նախորդ գլուխն անցնելը</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Կրկնակի հպումը երբեմն կարող է առաջացնել հաջորդ/նախորդ գլուխն անցնելը</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Արտաքին ներբեռնումներ</string>
<string name="revanced_external_downloader_screen_summary">Արտաքին ներբեռնող օգտագործելու համար կարգավորումներ</string>
@@ -697,9 +702,9 @@ MicroG-ի համար մարտկոցի օպտիմալացումը անջատել
<string name="revanced_hide_cast_button_title">Թաքցնել Cast կոճակը</string>
<string name="revanced_hide_cast_button_summary_on">Թափոնելու կոճակը թաքցված է</string>
<string name="revanced_hide_cast_button_summary_off">Թափոնելու կոճակը երևում է</string>
<string name="revanced_hide_player_control_buttons_background_title">Թաքցնել նվագարկչի կառավարման կոճակների ֆոնը</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Նվագարկչի կառավարման կոճակների ֆոնը թաքնված է</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Նվագարկչի կառավարման կոճակների ֆոնը ցուցադրվում է</string>
<string name="revanced_hide_player_control_buttons_background_title">Թաքցնել նվագարկչի կառավարման վահանակի ֆոնը</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Նվագարկչի կառավարման վահանակի ֆոնը թաքնված է</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Նվագարկչի կառավարման վահանակի ֆոնը ցուցադրվում է</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>

View File

@@ -453,6 +453,11 @@ Fitur ini hanya tersedia untuk perangkat yang lebih lama"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Dialog akan ditampilkan</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Ini tidak mengabaikan batasan usia. Ini hanya menerimanya secara otomatis.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Nonaktifkan lewati bab dengan ketuk dua kali</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Ketuk dua kali tidak akan pernah memicu lewati ke bab berikutnya/sebelumnya</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Ketuk dua kali terkadang dapat memicu lewati ke bab berikutnya/sebelumnya</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Unduhan eksternal</string>
<string name="revanced_external_downloader_screen_summary">Pengaturan untuk menggunakan pengunduh eksternal</string>
@@ -697,9 +702,9 @@ Untuk menampilkan menu trek Audio, ubah 'Spoof aliran video' ke iOS TV"</string>
<string name="revanced_hide_cast_button_title">Sembunyikan tombol Transmisi</string>
<string name="revanced_hide_cast_button_summary_on">Tombol transmisi disembunyikan</string>
<string name="revanced_hide_cast_button_summary_off">Tombol transmisi ditampilkan</string>
<string name="revanced_hide_player_control_buttons_background_title">Sembunyikan latar belakang tombol kontrol pemutar</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Latar belakang tombol kontrol pemutar disembunyikan</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Latar belakang tombol kontrol pemutar ditampilkan</string>
<string name="revanced_hide_player_control_buttons_background_title">Sembunyikan latar belakang kontrol pemutar</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Latar belakang kontrol pemutar disembunyikan</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Latar belakang kontrol pemutar ditampilkan</string>
<string name="revanced_hide_player_previous_next_buttons_title">Sembunyikan tombol Sebelumnya &amp; Berikutnya</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Tombol disembunyikan</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Tombol ditampilkan</string>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -453,6 +453,11 @@ Questa funzione è disponibile solo per i dispositivi più vecchi"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">La finestra di dialogo verrà mostrata </string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Questo non aggira la restrizione di età. Lo accetta solo automaticamente.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Disabilita salto capitolo con doppio tocco</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Il doppio tocco non può mai attivare il salto al capitolo successivo/precedente</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Il doppio tocco può occasionalmente attivare il salto al capitolo successivo/precedente</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Download esterni</string>
<string name="revanced_external_downloader_screen_summary">Impostazioni per l\'utilizzo di un downloader esterno</string>
@@ -697,9 +702,9 @@ Per mostrare il menu della traccia audio, cambia \"Spoof video streams\" in iOS
<string name="revanced_hide_cast_button_title">Nascondi il pulsante Trasmetti</string>
<string name="revanced_hide_cast_button_summary_on">Il pulsante Trasmetti è nascosto</string>
<string name="revanced_hide_cast_button_summary_off">Il pulsante Trasmetti è visibile</string>
<string name="revanced_hide_player_control_buttons_background_title">Nascondi sfondo dei pulsanti di controllo del player</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Lo sfondo dei pulsanti di controllo del player è nascosto</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Lo sfondo dei pulsanti di controllo del player è mostrato</string>
<string name="revanced_hide_player_control_buttons_background_title">Nascondi lo sfondo dei controlli del player</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Lo sfondo dei controlli del player è nascosto</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Lo sfondo dei controlli del player è mostrato</string>
<string name="revanced_hide_player_previous_next_buttons_title">Nascondi i pulsanti Precedente e Successivo</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">I pulsanti sono nascosti</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">I pulsanti sono visibili</string>

View File

@@ -453,6 +453,11 @@ Second \"item\" text"</string>
<string name="revanced_remove_viewer_discretion_dialog_summary_off">דו-שיח יוצג</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">זה לא עוקף את מגבלת הגיל. זה רק מסכים לזה באופן אוטומטי.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">ביטול דילוג פרקים בלחיצה כפולה</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">לחיצה כפולה לעולם לא תפעיל דילוג לפרק הבא/הקודם</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">לחיצה כפולה יכולה להפעיל מדי פעם דילוג לפרק הבא/הקודם</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">הורדות חיצוניות</string>
<string name="revanced_external_downloader_screen_summary">הגדרות לשימוש במוריד חיצונית</string>
@@ -697,9 +702,9 @@ Second \"item\" text"</string>
<string name="revanced_hide_cast_button_title">הסתר לחצן העברה</string>
<string name="revanced_hide_cast_button_summary_on">לחצן העברה מוסתר</string>
<string name="revanced_hide_cast_button_summary_off">לחצן העברה מוצג</string>
<string name="revanced_hide_player_control_buttons_background_title">הסתר רקע של לחצני שליטה בנגן</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">רקע לחצני השליטה בנגן מוסתר</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">רקע לחצני השליטה בנגן מוצג</string>
<string name="revanced_hide_player_control_buttons_background_title">הסתר רקע פקדי נגן</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">רקע פקדי הנגן מוסתר</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">רקע פקדי הנגן מוצג</string>
<string name="revanced_hide_player_previous_next_buttons_title">הסתר לחצני הקודם &amp; הבא</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">הלחצנים מוסתרים</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">הלחצנים מוצגים</string>

View File

@@ -33,7 +33,7 @@ Second \"item\" text"</string>
</patch>
<patch id="misc.settings.settingsResourcePatch">
<string name="revanced_settings_submenu_title">設定</string>
<string name="revanced_settings_confirm_user_dialog_title">本当に続行しますか?</string>
<string name="revanced_settings_confirm_user_dialog_title">続行してもよろしいですか?</string>
<string name="revanced_settings_reset">リセット</string>
<string name="revanced_settings_reset_color">色をリセット</string>
<string name="revanced_settings_color_invalid">色の値が無効です</string>
@@ -174,7 +174,7 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に
<string name="revanced_hide_horizontal_shelves_title">横スクロール欄を非表示</string>
<string name="revanced_hide_horizontal_shelves_summary_on">"横スクロール欄は表示されません
例:
緊急ニュース
・ニュース速報
・続きを見る
・他のチャンネルを探す
・関連が強い
@@ -301,9 +301,9 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に
<string name="revanced_hide_for_you_shelf_title">「おすすめ」欄を非表示</string>
<string name="revanced_hide_for_you_shelf_summary_on">「おすすめ」欄は表示されません</string>
<string name="revanced_hide_for_you_shelf_summary_off">「おすすめ」欄は表示されます</string>
<string name="revanced_hide_links_preview_title">リンク プレビューを非表示</string>
<string name="revanced_hide_links_preview_summary_on">リンク プレビューは表示されません</string>
<string name="revanced_hide_links_preview_summary_off">リンク プレビューは表示されます</string>
<string name="revanced_hide_links_preview_title">リンク集のプレビューを非表示</string>
<string name="revanced_hide_links_preview_summary_on">リンク集のプレビューは表示されません</string>
<string name="revanced_hide_links_preview_summary_off">リンク集のプレビューは表示されます</string>
<string name="revanced_hide_members_shelf_title">メンバー欄を非表示</string>
<string name="revanced_hide_members_shelf_summary_on">メンバー欄は表示されません</string>
<string name="revanced_hide_members_shelf_summary_off">メンバー欄は表示されます</string>
@@ -394,8 +394,8 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に
</patch>
<patch id="ad.general.hideAdsResourcePatch">
<string name="revanced_hide_creator_store_shelf_title">クリエイターのストア欄を非表示</string>
<string name="revanced_hide_creator_store_shelf_summary_on">動画プレーヤー下クリエイターのストア欄は表示されません</string>
<string name="revanced_hide_creator_store_shelf_summary_off">動画プレーヤー下クリエイターのストア欄は表示されます</string>
<string name="revanced_hide_creator_store_shelf_summary_on">動画プレーヤー下にあるクリエイターのストア欄は表示されません</string>
<string name="revanced_hide_creator_store_shelf_summary_off">動画プレーヤー下にあるクリエイターのストア欄は表示されます</string>
<string name="revanced_hide_end_screen_store_banner_title">終了画面のストアバナーを非表示</string>
<string name="revanced_hide_end_screen_store_banner_summary_on">終了画面のストアバナーは表示されません</string>
<string name="revanced_hide_end_screen_store_banner_summary_off">終了画面のストアバナーは表示されます</string>
@@ -412,17 +412,17 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に
<string name="revanced_hide_merchandise_banners_title">商品バナーを非表示</string>
<string name="revanced_hide_merchandise_banners_summary_on">商品バナーは表示されません</string>
<string name="revanced_hide_merchandise_banners_summary_off">商品バナーは表示されます</string>
<string name="revanced_hide_paid_promotion_label_title">「プロモーションを含みます」ボタンを非表示</string>
<string name="revanced_hide_paid_promotion_label_summary_on">プレーヤー画面の「プロモーションを含みます」ボタンは表示されません</string>
<string name="revanced_hide_paid_promotion_label_summary_off">プレーヤー画面の「プロモーションを含みます」ボタンは表示されます</string>
<string name="revanced_hide_paid_promotion_label_title">「プロモーションを含みます」ラベルを非表示</string>
<string name="revanced_hide_paid_promotion_label_summary_on">「プロモーションを含みます」ラベルは表示されません</string>
<string name="revanced_hide_paid_promotion_label_summary_off">「プロモーションを含みます」ラベルは表示されます</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_shopping_links_title">商品へのリンクを非表示</string>
<string name="revanced_hide_shopping_links_summary_on">動画の概要欄商品へのリンクは表示されません</string>
<string name="revanced_hide_shopping_links_summary_off">動画の概要欄商品へのリンクは表示されます</string>
<string name="revanced_hide_shopping_links_summary_on">動画の概要欄にある商品へのリンクは表示されません</string>
<string name="revanced_hide_shopping_links_summary_off">動画の概要欄にある商品へのリンクは表示されます</string>
<!-- 'View products' should be translated with the same localized wording that YouTube displays. -->
<string name="revanced_hide_view_products_banner_title">「商品を表示」ボタンを非表示</string>
<string name="revanced_hide_view_products_banner_title">「商品を表示」バナーを非表示</string>
<string name="revanced_hide_view_products_banner_summary_on">動画オーバーレイの「商品を表示」バナーは表示されません</string>
<string name="revanced_hide_view_products_banner_summary_off">動画オーバーレイの「商品を表示」バナーは表示されます</string>
<string name="revanced_hide_web_search_results_title">ウェブ検索結果を非表示</string>
@@ -455,6 +455,11 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に
<string name="revanced_remove_viewer_discretion_dialog_summary_off">ダイアログは表示されます</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">この機能によって年齢制限が回避される訳ではありません。自動的に承認するだけです。</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">ダブルタップ時のチャプター スキップを無効化</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">ダブルタップしたときに、次または前のチャプターへスキップしてしまうことはありません</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">ダブルタップしたときに、たまに次または前のチャプターへスキップしてしまうことがあります</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">外部ダウンロード</string>
<string name="revanced_external_downloader_screen_summary">外部ダウンローダーの設定</string>
@@ -533,8 +538,8 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に
</patch>
<patch id="layout.autocaptions.autoCaptionsPatch">
<string name="revanced_disable_auto_captions_title">自動字幕表示を無効化</string>
<string name="revanced_disable_auto_captions_summary_on">動画を開いた際の自動字幕表示は無効です</string>
<string name="revanced_disable_auto_captions_summary_off">動画を開いた際の自動字幕表示は有効です</string>
<string name="revanced_disable_auto_captions_summary_on">動画を開いた際の自動字幕表示は無効です</string>
<string name="revanced_disable_auto_captions_summary_off">動画を開いた際の自動字幕表示は有効です</string>
</patch>
<patch id="layout.buttons.action.hideButtonsPatch">
<string name="revanced_hide_buttons_screen_title">アクション ボタン</string>
@@ -699,9 +704,9 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に
<string name="revanced_hide_cast_button_title">キャストボタンを非表示</string>
<string name="revanced_hide_cast_button_summary_on">キャストボタンはオーバーレイに表示されません</string>
<string name="revanced_hide_cast_button_summary_off">キャストボタンはオーバーレイに表示されます</string>
<string name="revanced_hide_player_control_buttons_background_title">プレーヤーのコントロール ボタンの背景を非表示</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">プレーヤーのコントロール ボタンの背景は表示されません</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">プレーヤーのコントロール ボタンの背景は表示されます</string>
<string name="revanced_hide_player_control_buttons_background_title">プレーヤーのコントロールの背景を非表示</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">プレーヤーのコントロールの背景は表示されません</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">プレーヤーのコントロールの背景は表示されます</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>
@@ -868,8 +873,8 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に
</patch>
<patch id="layout.panels.popup.playerPopupPanelsPatch">
<string name="revanced_hide_player_popup_panels_title">プレーヤー ポップアップ パネルを非表示</string>
<string name="revanced_hide_player_popup_panels_summary_on">動画を開いた際のプレイリストやチャット欄などのプレーヤー ポップアップ パネルは表示されません</string>
<string name="revanced_hide_player_popup_panels_summary_off">動画を開いた際のプレイリストやチャット欄などのプレーヤー ポップアップ パネルは表示されます</string>
<string name="revanced_hide_player_popup_panels_summary_on">動画を開いた際のプレイリストやチャット欄などのプレーヤー ポップアップ パネルは表示されません</string>
<string name="revanced_hide_player_popup_panels_summary_off">動画を開いた際のプレイリストやチャット欄などのプレーヤー ポップアップ パネルは表示されます</string>
</patch>
<patch id="layout.player.fullscreen.exitFullscreenPatch">
<string name="revanced_exit_fullscreen_title">再生終了時に全画面表示を解除する</string>
@@ -1338,8 +1343,8 @@ Automotive レイアウト
詳細については、ここをタップしてください"</string>
<string name="revanced_alt_thumbnail_dearrow_connection_toast_title">API 利用不可時にトーストを表示</string>
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_on">DeArrow が利用できない場合は、トーストが表示されます</string>
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_off">DeArrow が利用できない場合でも、トーストは表示されません</string>
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_on">DeArrow が利用できない場合は、トーストポップアップが表示されます</string>
<string name="revanced_alt_thumbnail_dearrow_connection_toast_summary_off">DeArrow が利用できない場合でも、トースト ポップアップは表示されません</string>
<string name="revanced_alt_thumbnail_dearrow_api_url_title">DeArrow API のエンドポイント</string>
<string name="revanced_alt_thumbnail_dearrow_api_url_summary">DeArrow がサムネイルのキャッシュを取得するエンドポイントの URL</string>
<string name="revanced_alt_thumbnail_stills_about_title">静止画サムネイル</string>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -83,6 +83,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -207,9 +207,9 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배
<string name="revanced_hide_show_more_button_title">\'자세히 보기\' 버튼 숨기기</string>
<string name="revanced_hide_show_more_button_summary_on">검색 결과에서 \'자세히 보기\' 버튼이 숨겨집니다</string>
<string name="revanced_hide_show_more_button_summary_off">검색 결과에서 \'자세히 보기\' 버튼이 표시됩니다</string>
<string name="revanced_hide_ticket_shelf_title">이벤트 티켓 선반 숨기기</string>
<string name="revanced_hide_ticket_shelf_summary_on">이벤트 티켓 선반이 숨겨집니다</string>
<string name="revanced_hide_ticket_shelf_summary_off">이벤트 티켓 선반이 표시됩니다</string>
<string name="revanced_hide_ticket_shelf_title">콘서트 선반 숨기기</string>
<string name="revanced_hide_ticket_shelf_summary_on">콘서트 선반이 숨겨집니다</string>
<string name="revanced_hide_ticket_shelf_summary_off">콘서트 선반이 표시됩니다</string>
<!-- 'People also watched' and 'You might also like' should be translated using the same localized wording YouTube displays. -->
<string name="revanced_hide_video_recommendation_labels_title">동영상 추천 라벨 숨기기</string>
<string name="revanced_hide_video_recommendation_labels_summary_on">검색 결과에서 다음 라벨이 숨겨집니다:\n• 시청자가 이 동영상도 시청함\n• 내가 좋아할 만한 동영상</string>
@@ -296,8 +296,8 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">관련 동영상에서 카테고리 바 숨기기</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">플레이어 하단에 있는 관련 동영상에서 카테고리 바가 숨겨집니다</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">플레이어 하단에 있는 관련 동영상에서 카테고리 바가 표시됩니다</string>
<string name="revanced_channel_screen_title">채널 프로필</string>
<string name="revanced_channel_screen_summary">채널 프로필에서 구성요소를 숨기거나 표시할 수 있습니다</string>
<string name="revanced_channel_screen_title">채널 페이지</string>
<string name="revanced_channel_screen_summary">채널 페이지에서 구성요소를 숨기거나 표시할 수 있습니다</string>
<!-- 'For You' should be translated using the same localized wording YouTube displays. -->
<string name="revanced_hide_for_you_shelf_title">추천 선반 숨기기</string>
<string name="revanced_hide_for_you_shelf_summary_on">추천 선반이 숨겨집니다</string>
@@ -455,6 +455,11 @@ MicroG 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배
<string name="revanced_remove_viewer_discretion_dialog_summary_off">다음 동영상을 시청하기 전에 표시되는 시청 경고 다이얼로그를 삭제하지 않습니다:\n• 연령 제한 동영상\n• 자살 또는 자해와 관련된 동영상, etc.</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">이 설정은 다이얼로그를 자동으로 허용하기만 하며 연령 제한(성인인증 절차)을 우회할 수 없습니다.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">두 번 눌러서 챕터 건너뛰기 비활성화하기</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">두 번 눌러서 다음/이전 챕터로 건너뛰기가 절대 트리거될 수 없습니다</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">두 번 눌러서 다음/이전 챕터로 건너뛰기가 가끔 트리거될 수 있습니다</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">외부 다운로드</string>
<string name="revanced_external_downloader_screen_summary">외부 다운로더를 설정할 수 있습니다</string>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -453,6 +453,11 @@ Apribojimai
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Dialogas bus rodomas</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Tai neaplenkia amžiaus apribojimo. Jis tiesiog jį automatiškai priima.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Išjungti dvigubo bakstelėjimo skyriaus praleidimą</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Dvigubas bakstelėjimas niekada negali suaktyvinti praleidimo į kitą/ankstesnį skyrių</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Dvigubas bakstelėjimas kartais gali suaktyvinti praleidimą į kitą/ankstesnį skyrių</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Išoriniai atsisiuntimai</string>
<string name="revanced_external_downloader_screen_summary">Nustatymai naudojant išorinį atsisiuntimo įrankį</string>
@@ -695,9 +700,9 @@ Jei pakeitus šį nustatymą neįsigalioja, pabandykite perjungti į inkognito r
<string name="revanced_hide_cast_button_title">Paslėpti mygtuką \"Transliuoti\"</string>
<string name="revanced_hide_cast_button_summary_on">Transliacijos mygtukas yra paslėptas</string>
<string name="revanced_hide_cast_button_summary_off">Transliacijos mygtukas yra rodomas</string>
<string name="revanced_hide_player_control_buttons_background_title">Slėpti grotuvo valdymo mygtukų foną</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Grotuvo valdymo mygtukų fonas paslėptas</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Grotuvo valdymo mygtukų fonas rodomas</string>
<string name="revanced_hide_player_control_buttons_background_title">Slėpti grotuvo valdiklių foną</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Grotojo valdiklių fonas paslėptas</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Rodomas grotuvo valdiklių fonas</string>
<string name="revanced_hide_player_previous_next_buttons_title">Slėpti ankstesnius ir kitus mygtukus</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Mygtukai yra paslėpti</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Mygtukai yra rodomi</string>

View File

@@ -453,6 +453,11 @@ Ierobežojumi
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Dialogs tiks rādīts</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Tas neapiet vecuma ierobežojumu. Tas vienkārši automātiski to pieņem.</string>
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
<string name="revanced_disable_chapter_skip_double_tap_title">Atspējot divkāršu pieskārienu nodaļas izlaišanai</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_on">Divkāršs pieskāriens nekad nevar iedarbināt izlaišanu uz nākamo/iepriekšējo nodaļu</string>
<string name="revanced_disable_chapter_skip_double_tap_summary_off">Divkāršs pieskāriens reizēm var iedarbināt izlaišanu uz nākamo/iepriekšējo nodaļu</string>
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">Ārējie lejupielādētāji</string>
<string name="revanced_external_downloader_screen_summary">Iestatījumi, lai izmantotu ārējo lejupielādētāju</string>
@@ -697,9 +702,9 @@ Lai parādītu audio celiņu izvēlni, mainiet \"Video straumju viltošana\" uz
<string name="revanced_hide_cast_button_title">Paslēpt pogu \"Sūtīt\"</string>
<string name="revanced_hide_cast_button_summary_on">Pārraides poga ir paslēpta</string>
<string name="revanced_hide_cast_button_summary_off">Pārraides poga ir redzama</string>
<string name="revanced_hide_player_control_buttons_background_title">Slēpt atskaņotāja vadības pogu fonu</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Atskaņotāja vadības pogu fons ir paslēpts</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Atskaņotāja vadības pogu fons ir redzams</string>
<string name="revanced_hide_player_control_buttons_background_title">Paslēpt atskaņotāja vadīklu fonu</string>
<string name="revanced_hide_player_control_buttons_background_summary_on">Atskaņotāja vadības elementu fons ir paslēpts</string>
<string name="revanced_hide_player_control_buttons_background_summary_off">Atskaņotāja vadīklu fons tiek rādīts</string>
<string name="revanced_hide_player_previous_next_buttons_title">Paslēpt iepriekšējo un nākamo pogas</string>
<string name="revanced_hide_player_previous_next_buttons_summary_on">Pogas ir paslēptas</string>
<string name="revanced_hide_player_previous_next_buttons_summary_off">Pogas ir redzamas</string>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

View File

@@ -68,6 +68,8 @@ Second \"item\" text"</string>
</patch>
<patch id="interaction.dialog.removeViewerDiscretionDialogPatch">
</patch>
<patch id="interaction.doubletap.disableChapterSkipDoubleTapPatch">
</patch>
<patch id="interaction.downloads.downloadsResourcePatch">
<!-- 'Download action button' should be translated using the same wording as the translation of 'revanced_hide_download_button_title'. -->
</patch>

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