Compare commits

...

20 Commits

Author SHA1 Message Date
semantic-release-bot
e55364ca87 chore(release): 4.4.0-dev.3 [skip ci]
# [4.4.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.2...v4.4.0-dev.3) (2024-03-08)

### Bug Fixes

* **YouTube - Downloads:** Use new task context ([#2841](https://github.com/ReVanced/revanced-patches/issues/2841)) ([5cca421](5cca42121a))
2024-03-08 05:11:28 +00:00
LisoUseInAIKyrios
5cca42121a fix(YouTube - Downloads): Use new task context (#2841) 2024-03-08 09:09:15 +04:00
semantic-release-bot
7b0365360e chore(release): 4.4.0-dev.2 [skip ci]
# [4.4.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.1...v4.4.0-dev.2) (2024-03-04)

### Features

* **YouTube - External downloader:** Add ability to use in-app download button ([7f8b7c0](7f8b7c08b2))
2024-03-04 19:38:46 +00:00
oSumAtrIX
7f8b7c08b2 feat(YouTube - External downloader): Add ability to use in-app download button 2024-03-04 20:36:25 +01:00
oSumAtrIX
058acff28c build: Set target bytecode level to JVM 11 2024-03-04 18:10:12 +01:00
semantic-release-bot
060b2c2323 chore(release): 4.4.0-dev.1 [skip ci]
# [4.4.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.3.0...v4.4.0-dev.1) (2024-03-04)

### Features

* **YouTube Vanced:** Remove `Hide ads` patch ([bcce7be](bcce7bee9a))
2024-03-04 14:01:53 +00:00
oSumAtrIX
bcce7bee9a feat(YouTube Vanced): Remove Hide ads patch 2024-03-04 14:59:32 +01:00
oSumAtrIX
d3f83230f8 build: Bump dependencies 2024-03-02 20:51:11 +01:00
semantic-release-bot
0ad377bb4c chore(release): 4.3.0 [skip ci]
# [4.3.0](https://github.com/ReVanced/revanced-patches/compare/v4.2.0...v4.3.0) (2024-03-02)

### Bug Fixes

* Compile DEX without debugging information ([afe7f06](afe7f0605e))
* **Override certificate pinning:** Always overwrite with a generic network security configuration ([16eee2f](16eee2f03f))
* Remove extra space from patch description ([#2780](https://github.com/ReVanced/revanced-patches/issues/2780)) ([a6f5dd9](a6f5dd933f))
* Use deprecated members to ensure backwards compatibility ([a6d8e42](a6d8e4210f))
* **YouTube - Spoof app version:** Remove broken versions ([#2776](https://github.com/ReVanced/revanced-patches/issues/2776)) ([2fe9060](2fe9060944))
* **YouTube - Spoof signature:** Fix tracking such as history or watch time ([f2edae2](f2edae2ac1))

### Features

* **OpeningHours:** Add `Fix crash` patch ([#2697](https://github.com/ReVanced/revanced-patches/issues/2697)) ([6742cd9](6742cd9232))
* Remove unnecessary description from patch ([348e42a](348e42a374))
* **Sync for Reddit:** Add `Fix /s/ links` patch ([0434d88](0434d8812b))
* **Twitter - Unlock downloads:** Unlock GIF downloads ([3200da8](3200da8657))
* **VSCO - Unlock pro:** Constrain to last working version ([0f7ed84](0f7ed841d1))
* **X:** Add `Open links as query` patch ([#2730](https://github.com/ReVanced/revanced-patches/issues/2730)) ([43359b9](43359b95eb))
* **YouTube - Change header:** Improve patch option description ([e775bc2](e775bc2cae))
* **YouTube - Change start page:** Add more start pages ([96f9b73](96f9b73c74))
* **YouTube - Custom branding:** Improve patch option description ([f4b888b](f4b888be56))
* **YouTube - Spoof app version:** Add target versions ([#2787](https://github.com/ReVanced/revanced-patches/issues/2787)) ([f9ae1a4](f9ae1a46d2))
* **YouTube:** Reorganize settings menu ([#2737](https://github.com/ReVanced/revanced-patches/issues/2737)) ([3b4b21f](3b4b21ff2e))
2024-03-02 18:59:36 +00:00
oSumAtrIX
9917ddd9c1 chore: Merge branch dev to main (#2707) 2024-03-02 19:57:07 +01:00
semantic-release-bot
951ebc54ca chore(release): 4.3.0-dev.13 [skip ci]
# [4.3.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.12...v4.3.0-dev.13) (2024-03-02)

### Features

* **YouTube:** Reorganize settings menu ([#2737](https://github.com/ReVanced/revanced-patches/issues/2737)) ([3b4b21f](3b4b21ff2e))
2024-03-02 07:29:04 +00:00
LisoUseInAIKyrios
3b4b21ff2e feat(YouTube): Reorganize settings menu (#2737)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
Co-authored-by: dic1911 <htk030@protonmail.com>
2024-03-02 08:27:05 +01:00
semantic-release-bot
2f2ad3e584 chore(release): 4.3.0-dev.12 [skip ci]
# [4.3.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.11...v4.3.0-dev.12) (2024-03-02)

### Features

* **YouTube - Spoof app version:** Add target versions ([#2787](https://github.com/ReVanced/revanced-patches/issues/2787)) ([f9ae1a4](f9ae1a46d2))
2024-03-02 07:12:52 +00:00
kitadai31
f9ae1a46d2 feat(YouTube - Spoof app version): Add target versions (#2787) 2024-03-02 08:10:07 +01:00
semantic-release-bot
e386313deb chore(release): 4.3.0-dev.11 [skip ci]
# [4.3.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.10...v4.3.0-dev.11) (2024-03-02)

### Bug Fixes

* **YouTube - Spoof signature:** Fix tracking such as history or watch time ([f2edae2](f2edae2ac1))
2024-03-02 07:05:33 +00:00
oSumAtrIX
f2edae2ac1 fix(YouTube - Spoof signature): Fix tracking such as history or watch time 2024-03-02 08:03:07 +01:00
semantic-release-bot
c153979981 chore(release): 4.3.0-dev.10 [skip ci]
# [4.3.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.9...v4.3.0-dev.10) (2024-02-29)

### Bug Fixes

* **YouTube - Spoof app version:** Remove broken versions ([#2776](https://github.com/ReVanced/revanced-patches/issues/2776)) ([2fe9060](2fe9060944))
2024-02-29 00:18:20 +00:00
oSumAtrIX
2fe9060944 fix(YouTube - Spoof app version): Remove broken versions (#2776) 2024-02-29 01:16:06 +01:00
semantic-release-bot
212a94cbb3 chore(release): 4.3.0-dev.9 [skip ci]
# [4.3.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.8...v4.3.0-dev.9) (2024-02-28)

### Bug Fixes

* **Override certificate pinning:** Always overwrite with a generic network security configuration ([16eee2f](16eee2f03f))
2024-02-28 22:04:01 +00:00
oSumAtrIX
16eee2f03f fix(Override certificate pinning): Always overwrite with a generic network security configuration
Previously some conditional checks prevented to patch YouTube for example. The current configuration should work globally for all apps.
2024-02-28 23:01:56 +01:00
100 changed files with 997 additions and 647 deletions

View File

@@ -1,3 +1,86 @@
# [4.4.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.2...v4.4.0-dev.3) (2024-03-08)
### Bug Fixes
* **YouTube - Downloads:** Use new task context ([#2841](https://github.com/ReVanced/revanced-patches/issues/2841)) ([6d88cb4](https://github.com/ReVanced/revanced-patches/commit/6d88cb49ec739700866290babcba5fb3032dbced))
# [4.4.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.1...v4.4.0-dev.2) (2024-03-04)
### Features
* **YouTube - External downloader:** Add ability to use in-app download button ([d900011](https://github.com/ReVanced/revanced-patches/commit/d9000113a905c14f8409aa75008f1ef6a1aecd0c))
# [4.4.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.3.0...v4.4.0-dev.1) (2024-03-04)
### Features
* **YouTube Vanced:** Remove `Hide ads` patch ([87887e4](https://github.com/ReVanced/revanced-patches/commit/87887e4163dd9e242209f4d0fefb415f9bc7ca75))
# [4.3.0](https://github.com/ReVanced/revanced-patches/compare/v4.2.0...v4.3.0) (2024-03-02)
### Bug Fixes
* Compile DEX without debugging information ([f5df957](https://github.com/ReVanced/revanced-patches/commit/f5df9578669f71a67411bc93a25a7e8da43610d0))
* **Override certificate pinning:** Always overwrite with a generic network security configuration ([2a842a1](https://github.com/ReVanced/revanced-patches/commit/2a842a1e14e1993eb028ae0bd1a93e227bb929a6))
* Remove extra space from patch description ([#2780](https://github.com/ReVanced/revanced-patches/issues/2780)) ([96a3f35](https://github.com/ReVanced/revanced-patches/commit/96a3f359266ff8d16ae9ee3c6ce2f16ce67a3b93))
* Use deprecated members to ensure backwards compatibility ([083bd40](https://github.com/ReVanced/revanced-patches/commit/083bd4009231b9612394b4496ca1d329947d6577))
* **YouTube - Spoof app version:** Remove broken versions ([#2776](https://github.com/ReVanced/revanced-patches/issues/2776)) ([9466d97](https://github.com/ReVanced/revanced-patches/commit/9466d973c6d7a2891e3fa9f283107b64399152ea))
* **YouTube - Spoof signature:** Fix tracking such as history or watch time ([bcd8b48](https://github.com/ReVanced/revanced-patches/commit/bcd8b48e70693dac1bfcc0bf4971d6b526065b59))
### Features
* **OpeningHours:** Add `Fix crash` patch ([#2697](https://github.com/ReVanced/revanced-patches/issues/2697)) ([0d011b8](https://github.com/ReVanced/revanced-patches/commit/0d011b876ecf05031a7daa54ab7e6d3506728a47))
* Remove unnecessary description from patch ([1a89dd9](https://github.com/ReVanced/revanced-patches/commit/1a89dd9f8cd0c614055a9da97338839b77a25ed1))
* **Sync for Reddit:** Add `Fix /s/ links` patch ([f15ef3f](https://github.com/ReVanced/revanced-patches/commit/f15ef3f63460254236185f8e22c9395db4db9465))
* **Twitter - Unlock downloads:** Unlock GIF downloads ([d0f91c8](https://github.com/ReVanced/revanced-patches/commit/d0f91c8550592723e1252e1af2971b508591dd59))
* **VSCO - Unlock pro:** Constrain to last working version ([6dd4a7c](https://github.com/ReVanced/revanced-patches/commit/6dd4a7c29e48c3bc517bbdd7ed160624c36c2333))
* **X:** Add `Open links as query` patch ([#2730](https://github.com/ReVanced/revanced-patches/issues/2730)) ([ba75a51](https://github.com/ReVanced/revanced-patches/commit/ba75a51b71dbb9157db230b3e97a90361019fe30))
* **YouTube - Change header:** Improve patch option description ([3b8bc08](https://github.com/ReVanced/revanced-patches/commit/3b8bc08d4ed3a3a0f96d2f476e5059840b9f9d9b))
* **YouTube - Change start page:** Add more start pages ([cc1d9b7](https://github.com/ReVanced/revanced-patches/commit/cc1d9b743633c619fb6acc428e884c1c9b53e10b))
* **YouTube - Custom branding:** Improve patch option description ([e27f56c](https://github.com/ReVanced/revanced-patches/commit/e27f56c8a34d41167b290f47280276c1c6003876))
* **YouTube - Spoof app version:** Add target versions ([#2787](https://github.com/ReVanced/revanced-patches/issues/2787)) ([83a7bd8](https://github.com/ReVanced/revanced-patches/commit/83a7bd8d69e62623fc4d2ba73d9fb49e92751d89))
* **YouTube:** Reorganize settings menu ([#2737](https://github.com/ReVanced/revanced-patches/issues/2737)) ([36132df](https://github.com/ReVanced/revanced-patches/commit/36132df4be6a04c08b6f3dd79de1bcea93a80fb8))
# [4.3.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.12...v4.3.0-dev.13) (2024-03-02)
### Features
* **YouTube:** Reorganize settings menu ([#2737](https://github.com/ReVanced/revanced-patches/issues/2737)) ([36132df](https://github.com/ReVanced/revanced-patches/commit/36132df4be6a04c08b6f3dd79de1bcea93a80fb8))
# [4.3.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.11...v4.3.0-dev.12) (2024-03-02)
### Features
* **YouTube - Spoof app version:** Add target versions ([#2787](https://github.com/ReVanced/revanced-patches/issues/2787)) ([83a7bd8](https://github.com/ReVanced/revanced-patches/commit/83a7bd8d69e62623fc4d2ba73d9fb49e92751d89))
# [4.3.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.10...v4.3.0-dev.11) (2024-03-02)
### Bug Fixes
* **YouTube - Spoof signature:** Fix tracking such as history or watch time ([bcd8b48](https://github.com/ReVanced/revanced-patches/commit/bcd8b48e70693dac1bfcc0bf4971d6b526065b59))
# [4.3.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.9...v4.3.0-dev.10) (2024-02-29)
### Bug Fixes
* **YouTube - Spoof app version:** Remove broken versions ([#2776](https://github.com/ReVanced/revanced-patches/issues/2776)) ([9466d97](https://github.com/ReVanced/revanced-patches/commit/9466d973c6d7a2891e3fa9f283107b64399152ea))
# [4.3.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.8...v4.3.0-dev.9) (2024-02-28)
### Bug Fixes
* **Override certificate pinning:** Always overwrite with a generic network security configuration ([2a842a1](https://github.com/ReVanced/revanced-patches/commit/2a842a1e14e1993eb028ae0bd1a93e227bb929a6))
# [4.3.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.7...v4.3.0-dev.8) (2024-02-28)

View File

@@ -723,10 +723,8 @@ public abstract class app/revanced/patches/shared/misc/settings/preference/BaseP
}
public class app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen : app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$BasePreferenceCollection {
public fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;)V
public synthetic fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;)V
public synthetic fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;)V
public synthetic fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun addPreferences ([Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;)V
public final fun getCategories ()Ljava/util/Set;
public synthetic fun transform ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;
@@ -798,12 +796,22 @@ public class app/revanced/patches/shared/misc/settings/preference/PreferenceCate
}
public class app/revanced/patches/shared/misc/settings/preference/PreferenceScreen : app/revanced/patches/shared/misc/settings/preference/BasePreference {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;Ljava/lang/String;Ljava/util/Set;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getPreferences ()Ljava/util/Set;
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
}
public final class app/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting : java/lang/Enum {
public static final field BY_KEY Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;
public static final field BY_TITLE Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;
public static final field UNSORTED Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public final fun getKeySuffix ()Ljava/lang/String;
public static fun valueOf (Ljava/lang/String;)Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;
public static fun values ()[Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;
}
public final class app/revanced/patches/shared/misc/settings/preference/SummaryType : java/lang/Enum {
public static final field DEFAULT Lapp/revanced/patches/shared/misc/settings/preference/SummaryType;
public static final field OFF Lapp/revanced/patches/shared/misc/settings/preference/SummaryType;
@@ -1186,8 +1194,8 @@ public final class app/revanced/patches/youtube/interaction/dialog/RemoveViewerD
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}
public final class app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch;
public final class app/revanced/patches/youtube/interaction/downloads/DownloadsPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/youtube/interaction/downloads/DownloadsPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}
@@ -1468,7 +1476,6 @@ public final class app/revanced/patches/youtube/layout/tabletminiplayer/TabletMi
public static final field INSTANCE Lapp/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
public final fun unwrap (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lkotlin/Triple;
}
public final class app/revanced/patches/youtube/layout/theme/ThemeBytecodePatch : app/revanced/patcher/patch/BytecodePatch {
@@ -1617,9 +1624,14 @@ public final class app/revanced/patches/youtube/misc/settings/SettingsPatch$Pref
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/settings/SettingsPatch$PreferenceScreen;
public fun commit (Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen;)V
public final fun getADS ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getINTERACTIONS ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getLAYOUT ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getALTERNATIVE_THUMBNAILS ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getFEED ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getGENERAL_LAYOUT ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getMISC ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getPLAYER ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getSEEKBAR ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getSHORTS ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getSWIPE_CONTROLS ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getVIDEO ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
}
@@ -1736,6 +1748,7 @@ public final class app/revanced/util/BytecodeUtilsKt {
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V
public static final fun resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;
public static final fun returnEarly (Ljava/util/List;Z)V
public static synthetic fun returnEarly$default (Ljava/util/List;ZILjava/lang/Object;)V
public static final fun transformMethods (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lkotlin/jvm/functions/Function1;)V

View File

@@ -1,4 +1,5 @@
import org.gradle.kotlin.dsl.support.listFilesOrdered
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.kotlin)
@@ -33,7 +34,13 @@ dependencies {
}
kotlin {
jvmToolchain(11)
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
}
}
java {
targetCompatibility = JavaVersion.VERSION_11
}
tasks {

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
kotlin.code.style = official
version = 4.3.0-dev.8
version = 4.4.0-dev.3

View File

@@ -1,6 +1,6 @@
[versions]
revanced-patcher = "19.3.1"
smali = "3.0.4"
smali = "3.0.5"
guava = "33.0.0-jre"
gson = "2.10.1"
binary-compatibility-validator = "0.14.0"

View File

@@ -4,6 +4,7 @@ import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.debugging.EnableAndroidDebuggingPatch
import app.revanced.util.Utils.trimIndentMultiline
import org.w3c.dom.Element
import java.io.File
@@ -32,10 +33,8 @@ object OverrideCertificatePinningPatch : ResourcePatch() {
// In case the file does not exist create the "network_security_config.xml" file.
File(resXmlDirectory, "network_security_config.xml").apply {
if (!exists()) {
createNewFile()
writeText(
"""
writeText(
"""
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
@@ -55,21 +54,8 @@ object OverrideCertificatePinningPatch : ResourcePatch() {
</trust-anchors>
</debug-overrides>
</network-security-config>
""",
)
} else {
// If the file already exists.
readText().let { text ->
if (!text.contains("<certificates src=\"user\" />")) {
writeText(
text.replace(
"<trust-anchors>",
"<trust-anchors>\n<certificates src=\"user\" overridePins=\"true\" />\n<certificates src=\"system\" />",
),
)
}
}
}
""".trimIndentMultiline(),
)
}
}
}

View File

@@ -7,7 +7,7 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.ad.comments.fingerprints.HideCommentAdsFingerprint
@Patch(description = "Removes ads in the comments.",)
@Patch(description = "Removes ads in the comments.")
object HideCommentAdsPatch : BytecodePatch(
setOf(HideCommentAdsFingerprint)
) {

View File

@@ -6,18 +6,13 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.fingerprints.PiracyDetectionFingerprint
@Patch(description = "Disables detection of modified versions.",)
@Patch(description = "Disables detection of modified versions.")
object DisablePiracyDetectionPatch : BytecodePatch(setOf(PiracyDetectionFingerprint)) {
override fun execute(context: BytecodeContext) {
// Do not throw an error if the fingerprint is not resolved.
// This is fine because new versions of the target app do not need this patch.
PiracyDetectionFingerprint.result?.mutableMethod?.apply {
addInstruction(
0,
"""
return-void
"""
)
addInstruction(0, "return-void")
}
}
}
}

View File

@@ -64,8 +64,8 @@ abstract class BaseIntegrationsPatch(
method.addInstruction(
0,
"sput-object v$contextRegister, " +
"$integrationsDescriptor->context:Landroid/content/Context;",
"invoke-static/range { v$contextRegister .. v$contextRegister }, " +
"$integrationsDescriptor->setContext(Landroid/content/Context;)V",
)
} ?: throw PatchException("Could not find hook target fingerprint.")
}

View File

@@ -41,12 +41,18 @@ abstract class BaseSettingsResourcePatch(
}
override fun close() {
fun Node.addPreference(preference: BasePreference) {
fun Node.addPreference(preference: BasePreference, prepend: Boolean = false) {
preference.serialize(ownerDocument) { resource ->
// TODO: Currently, resources can only be added to "values", which may not be the correct place.
// It may be necessary to ask for the desired resourceValue in the future.
AddResourcesPatch("values", resource)
}.let(this::appendChild)
}.let { preferenceNode ->
if (prepend && firstChild != null) {
insertBefore(preferenceNode, firstChild)
} else {
appendChild(preferenceNode)
}
}
}
// Add the root preference to an existing fragment if needed.
@@ -54,7 +60,7 @@ abstract class BaseSettingsResourcePatch(
context.xmlEditor["res/xml/$fragment.xml"].use { editor ->
val document = editor.file
document.getNode("PreferenceScreen").addPreference(intentPreference)
document.getNode("PreferenceScreen").addPreference(intentPreference, true)
}
}

View File

@@ -1,9 +1,10 @@
package app.revanced.patches.shared.misc.settings.preference
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import java.io.Closeable
abstract class BasePreferenceScreen(
private val root: MutableSet<Screen> = mutableSetOf()
private val root: MutableSet<Screen> = mutableSetOf(),
) : Closeable {
override fun close() {
@@ -24,33 +25,27 @@ abstract class BasePreferenceScreen(
titleKey: String = "${key}_title",
private val summaryKey: String? = "${key}_summary",
preferences: MutableSet<BasePreference> = mutableSetOf(),
val categories: MutableSet<Category> = mutableSetOf()
val categories: MutableSet<Category> = mutableSetOf(),
private val sorting: Sorting = Sorting.BY_TITLE,
) : BasePreferenceCollection(key, titleKey, preferences) {
/**
* Initialize using title and summary keys with suffix "_title" and "_summary".
*/
constructor(
key: String? = null,
preferences: MutableSet<BasePreference> = mutableSetOf(),
categories: MutableSet<Category> = mutableSetOf()
) : this(key, key + "_title", key + "_summary", preferences, categories)
override fun transform(): PreferenceScreen {
return PreferenceScreen(
key,
titleKey,
summaryKey,
sorting,
// Screens and preferences are sorted at runtime by integrations code,
// so they appear in alphabetical order for the localized language in use.
preferences = preferences + categories.map { it.transform() }
// so title sorting uses the localized language in use.
preferences = preferences + categories.map { it.transform() },
)
}
private fun ensureScreenInserted() {
// Add to screens if not yet done
if (!root.contains(this))
if (!root.contains(this)) {
root.add(this)
}
}
fun addPreferences(vararg preferences: BasePreference) {
@@ -61,13 +56,13 @@ abstract class BasePreferenceScreen(
open inner class Category(
key: String? = null,
titleKey: String = "${key}_title",
preferences: MutableSet<BasePreference> = mutableSetOf()
preferences: MutableSet<BasePreference> = mutableSetOf(),
) : BasePreferenceCollection(key, titleKey, preferences) {
override fun transform(): PreferenceCategory {
return PreferenceCategory(
key,
titleKey,
preferences = preferences
preferences = preferences,
)
}
@@ -75,8 +70,9 @@ abstract class BasePreferenceScreen(
ensureScreenInserted()
// Add to the categories if not done yet.
if (!categories.contains(this))
if (!categories.contains(this)) {
categories.add(this)
}
this.preferences.addAll(preferences)
}
@@ -86,8 +82,8 @@ abstract class BasePreferenceScreen(
abstract class BasePreferenceCollection(
val key: String? = null,
val titleKey: String = "${key}_title",
val preferences: MutableSet<BasePreference> = mutableSetOf()
val preferences: MutableSet<BasePreference> = mutableSetOf(),
) {
abstract fun transform(): BasePreference
}
}
}

View File

@@ -1,19 +1,16 @@
package app.revanced.patches.shared.misc.settings.preference
import app.revanced.patches.shared.misc.settings.preference.IntentPreference.Intent
import app.revanced.util.resource.BaseResource
import org.w3c.dom.Document
/**
* A preference that opens an intent.
*
* @param key The preference key. If null, other parameters must be specified.
* @param key Optional preference key.
* @param titleKey The preference title key.
* @param summaryKey The preference summary key.
* @param tag The preference tag.
* @param intent The intent to open.
*
* @see Intent
*/
class IntentPreference(
key: String? = null,
@@ -21,7 +18,7 @@ class IntentPreference(
summaryKey: String? = "${key}_summary",
tag: String = "Preference",
val intent: Intent,
) : BasePreference(null, titleKey, summaryKey, tag) {
) : BasePreference(key, titleKey, summaryKey, tag) {
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply {

View File

@@ -6,10 +6,12 @@ import org.w3c.dom.Document
/**
* A non-interactive preference.
*
* Typically used to present static text, but also used for custom integration code that responds to taps.
*
* @param key The preference key.
* @param summaryKey The preference summary key.
* @param tag The preference tag.
* @param selectable Whether the preference is selectable.
* @param tag The tag or full class name of the preference.
* @param selectable If the preference is selectable and responds to tap events.
*/
@Suppress("MemberVisibilityCanBePrivate")
class NonInteractivePreference(

View File

@@ -9,6 +9,8 @@ import org.w3c.dom.Document
* @param key The key of the preference. If null, other parameters must be specified.
* @param titleKey The key of the preference title.
* @param summaryKey The key of the preference summary.
* @param sorting Sorting to use. If the sorting is not [Sorting.UNSORTED],
* then the key parameter will be modified to include the sort type.
* @param tag The tag or full class name of the preference.
* @param preferences The preferences in this screen.
*/
@@ -17,14 +19,40 @@ open class PreferenceScreen(
key: String? = null,
titleKey: String = "${key}_title",
summaryKey: String? = "${key}_summary",
sorting: Sorting = Sorting.BY_TITLE,
tag: String = "PreferenceScreen",
val preferences: Set<BasePreference>
) : BasePreference(key, titleKey, summaryKey, tag) {
val preferences: Set<BasePreference>,
// Alternatively, instead of repurposing the key for sorting,
// an extra bundle parameter can be added to the preferences XML declaration.
// This would require bundling and referencing an additional XML file
// or adding new attributes to the attrs.xml file.
// Since the key value is not currently used by integrations,
// for now it's much simpler to modify the key to include the sort parameter.
) : BasePreference(if (sorting == Sorting.UNSORTED) key else (key + sorting.keySuffix), titleKey, summaryKey, tag) {
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply {
preferences.forEach {
appendChild(it.serialize(ownerDocument, resourceCallback))
}
}
/**
* How a PreferenceScreen should be sorted.
*/
enum class Sorting(val keySuffix: String) {
/**
* Sort by the localized preference title.
*/
BY_TITLE("_sort_by_title"),
/**
* Sort by the preference keys.
*/
BY_KEY("_sort_by_key"),
/**
* Unspecified sorting.
*/
UNSORTED("_sort_by_unsorted"),
}
}

View File

@@ -26,7 +26,9 @@ object AudioAdsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.ADS.CLIENT_SIDE.addPreferences(SwitchPreference("revanced_block_audio_ads"))
SettingsPatch.PreferenceScreen.ADS.CLIENT_SIDE.addPreferences(
SwitchPreference("revanced_block_audio_ads")
)
// Block playAds call
with(AudioAdsPresenterPlayFingerprint.result!!) {

View File

@@ -35,7 +35,9 @@ object VideoAdsPatch : BaseAdPatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.ADS.CLIENT_SIDE.addPreferences(SwitchPreference("revanced_block_video_ads"))
SettingsPatch.PreferenceScreen.ADS.CLIENT_SIDE.addPreferences(
SwitchPreference("revanced_block_video_ads")
)
/* Amazon ads SDK */
context.blockMethods(

View File

@@ -32,7 +32,9 @@ object DebugModePatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.MISC.OTHER.addPreferences(SwitchPreference("revanced_twitch_debug_mode"))
SettingsPatch.PreferenceScreen.MISC.OTHER.addPreferences(
SwitchPreference("revanced_twitch_debug_mode")
)
listOf(
IsDebugConfigEnabledFingerprint,

View File

@@ -25,7 +25,6 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.immutable.ImmutableField
import java.io.Closeable
@Patch(
name = "Settings",
description = "Adds settings menu to Twitch.",
@@ -62,7 +61,9 @@ object SettingsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
PreferenceScreen.MISC.OTHER.addPreferences(SwitchPreference("revanced_debug"))
PreferenceScreen.MISC.OTHER.addPreferences(
SwitchPreference("revanced_debug")
)
// Hook onCreate to handle fragment creation
SettingsActivityOnCreateFingerprint.result?.apply {

View File

@@ -8,7 +8,6 @@ import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch.PreferenceScreen
@Patch(
dependencies = [
@@ -27,7 +26,7 @@ object HideAdsResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
PreferenceScreen.ADS.addPreferences(
SettingsPatch.PreferenceScreen.ADS.addPreferences(
SwitchPreference("revanced_hide_general_ads"),
SwitchPreference("revanced_hide_fullscreen_ads"),
SwitchPreference("revanced_hide_buttoned_ads"),

View File

@@ -44,7 +44,9 @@ object HideGetPremiumPatch : BytecodePatch(setOf(GetPremiumViewFingerprint)) {
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.ADS.addPreferences(SwitchPreference("revanced_hide_get_premium"))
SettingsPatch.PreferenceScreen.ADS.addPreferences(
SwitchPreference("revanced_hide_get_premium")
)
GetPremiumViewFingerprint.result?.let {
it.mutableMethod.apply {

View File

@@ -49,7 +49,9 @@ object VideoAdsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.ADS.addPreferences(SwitchPreference("revanced_hide_video_ads"))
SettingsPatch.PreferenceScreen.ADS.addPreferences(
SwitchPreference("revanced_hide_video_ads")
)
val loadVideoAdsFingerprintMethod = LoadVideoAdsFingerprint.result!!.mutableMethod

View File

@@ -39,7 +39,6 @@ object CopyVideoUrlBytecodePatch : BytecodePatch(emptySet()) {
)
override fun execute(context: BytecodeContext) {
// Initialize buttons and inject visibility control
BUTTONS_DESCRIPTORS.forEach { descriptor ->
PlayerControlsBytecodePatch.initializeControl("$descriptor->initializeButton(Landroid/view/View;)V")
PlayerControlsBytecodePatch.injectVisibilityCheckCall("$descriptor->changeVisibility(Z)V")

View File

@@ -4,7 +4,6 @@ import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.playercontrols.BottomControlsResourcePatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
@@ -22,14 +21,9 @@ internal object CopyVideoUrlResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(
PreferenceScreen(
"revanced_copy_video_url_preference_screen",
preferences = setOf(
SwitchPreference("revanced_copy_video_url"),
SwitchPreference("revanced_copy_video_url_timestamp")
)
)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_copy_video_url"),
SwitchPreference("revanced_copy_video_url_timestamp")
)
context.copyResources(
@@ -40,8 +34,6 @@ internal object CopyVideoUrlResourcePatch : ResourcePatch() {
)
)
AddResourcesPatch(this::class)
BottomControlsResourcePatch.addControls("copyvideourl")
}
}

View File

@@ -50,7 +50,9 @@ object RemoveViewerDiscretionDialogPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(SwitchPreference("revanced_remove_viewer_discretion_dialog"))
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_remove_viewer_discretion_dialog")
)
CreateDialogFingerprint.result?.mutableMethod?.apply {
val showDialogIndex = implementation!!.instructions.lastIndex - 2

View File

@@ -0,0 +1,98 @@
package app.revanced.patches.youtube.interaction.downloads
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.interaction.downloads.fingerprints.DownloadActionCommandResolverFingerprint
import app.revanced.patches.youtube.interaction.downloads.fingerprints.DownloadActionCommandResolverParentFingerprint
import app.revanced.patches.youtube.interaction.downloads.fingerprints.LegacyDownloadCommandResolverFingerprint
import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch
import app.revanced.patches.youtube.shared.fingerprints.MainActivityFingerprint
import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.util.resultOrThrow
@Patch(
name = "Downloads",
description = "Adds support to download videos with an external downloader app" +
"using the in-app download button or a video player action button.",
dependencies = [
DownloadsResourcePatch::class,
PlayerControlsBytecodePatch::class,
VideoInformationPatch::class,
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube",
[
"18.48.39",
"18.49.37",
"19.01.34",
"19.02.39",
"19.03.35",
"19.03.36",
"19.04.37",
],
),
],
)
@Suppress("unused")
object DownloadsPatch : BytecodePatch(
setOf(
DownloadActionCommandResolverParentFingerprint,
LegacyDownloadCommandResolverFingerprint,
MainActivityFingerprint
)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/DownloadsPatch;"
private const val BUTTON_DESCRIPTOR = "Lapp/revanced/integrations/youtube/videoplayer/ExternalDownloadButton;"
override fun execute(context: BytecodeContext) {
PlayerControlsBytecodePatch.initializeControl("$BUTTON_DESCRIPTOR->initializeButton(Landroid/view/View;)V")
PlayerControlsBytecodePatch.injectVisibilityCheckCall("$BUTTON_DESCRIPTOR->changeVisibility(Z)V")
// Main activity is used to launch downloader intent.
MainActivityFingerprint.resultOrThrow().mutableMethod.apply {
addInstruction(
implementation!!.instructions.lastIndex,
"invoke-static { p0 }, $INTEGRATIONS_CLASS_DESCRIPTOR->activityCreated(Landroid/app/Activity;)V"
)
}
val commonInstructions = """
move-result v0
if-eqz v0, :show_native_downloader
return-void
:show_native_downloader
nop
"""
DownloadActionCommandResolverFingerprint.resolve(context,
DownloadActionCommandResolverParentFingerprint.resultOrThrow().classDef)
DownloadActionCommandResolverFingerprint.resultOrThrow().mutableMethod.apply {
addInstructionsWithLabels(
0,
"""
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadButtonOnClick()Z
$commonInstructions
"""
)
}
// Legacy fingerprint is used for old spoofed versions,
// or if download playlist is pressed on any version.
// Downloading playlists is not yet supported,
// as the code this hooks does not easily expost the playlist id.
LegacyDownloadCommandResolverFingerprint.resultOrThrow().mutableMethod.apply {
addInstructionsWithLabels(
0,
"""
invoke-static/range {p1 .. p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadPlaylistLegacyOnClick(Ljava/lang/String;)Z
$commonInstructions
"""
)
}
}
}

View File

@@ -6,6 +6,7 @@ import app.revanced.patcher.patch.annotation.Patch
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.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.misc.playercontrols.BottomControlsResourcePatch
@@ -18,25 +19,27 @@ import app.revanced.util.copyResources
BottomControlsResourcePatch::class,
SettingsPatch::class,
AddResourcesPatch::class,
]
],
)
internal object ExternalDownloadsResourcePatch : ResourcePatch() {
internal object DownloadsResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
PreferenceScreen(
"revanced_external_downloader_preference_screen",
key = "revanced_external_downloader_screen",
sorting = Sorting.UNSORTED,
preferences = setOf(
SwitchPreference("revanced_external_downloader"),
TextPreference("revanced_external_downloader_name", inputType = InputType.TEXT)
SwitchPreference("revanced_external_downloader_action_button"),
TextPreference("revanced_external_downloader_name", inputType = InputType.TEXT),
),
)
),
)
context.copyResources(
"downloads",
ResourceGroup("drawable", "revanced_yt_download_button.xml")
ResourceGroup("drawable", "revanced_yt_download_button.xml"),
)
BottomControlsResourcePatch.addControls("downloads")

View File

@@ -1,54 +0,0 @@
package app.revanced.patches.youtube.interaction.downloads
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch
import app.revanced.patches.youtube.video.information.VideoInformationPatch
@Patch(
name = "External downloads",
description = "Adds support to download and save YouTube videos using an external downloader app.",
dependencies = [
ExternalDownloadsResourcePatch::class,
PlayerControlsBytecodePatch::class,
VideoInformationPatch::class,
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube",
[
"18.48.39",
"18.49.37",
"19.01.34",
"19.02.39",
"19.03.35",
"19.03.36",
"19.04.37",
],
),
],
)
@Suppress("unused")
object ExternalDownloadsBytecodePatch : BytecodePatch(emptySet()) {
private const val BUTTON_DESCRIPTOR = "Lapp/revanced/integrations/youtube/videoplayer/ExternalDownloadButton;"
override fun execute(context: BytecodeContext) {
/*
initialize the control
*/
PlayerControlsBytecodePatch.initializeControl(
"$BUTTON_DESCRIPTOR->initializeButton(Landroid/view/View;)V",
)
/*
add code to change the visibility of the control
*/
PlayerControlsBytecodePatch.injectVisibilityCheckCall(
"$BUTTON_DESCRIPTOR->changeVisibility(Z)V",
)
}
}

View File

@@ -0,0 +1,14 @@
package app.revanced.patches.youtube.interaction.downloads.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
/**
* Resolves to the class found in [DownloadActionCommandResolverParentFingerprint].
*/
internal object DownloadActionCommandResolverFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("L", "Ljava/util/Map;")
)

View File

@@ -0,0 +1,17 @@
package app.revanced.patches.youtube.interaction.downloads.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object DownloadActionCommandResolverParentFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("L", "L"),
strings = listOf(
// Strings are not unique and found in other methods.
"com.google.android.libraries.youtube.logging.interaction_logger",
"Unknown command"
),
literalSupplier = { 16 }
)

View File

@@ -0,0 +1,24 @@
package app.revanced.patches.youtube.interaction.downloads.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
/**
* For spoofing to older versions. Also called if download playlist is pressed for any version.
*/
internal object LegacyDownloadCommandResolverFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("Ljava/lang/String;", "Ljava/lang/String;", "L", "L"),
strings = listOf(""),
opcodes = listOf(
Opcode.MOVE_OBJECT_FROM16,
Opcode.MOVE_OBJECT_FROM16,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
)
)

View File

@@ -50,7 +50,7 @@ object DisablePreciseSeekingGesturePatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(
SettingsPatch.PreferenceScreen.SEEKBAR.addPreferences(
SwitchPreference("revanced_disable_precise_seeking_gesture")
)

View File

@@ -51,7 +51,9 @@ object EnableSeekbarTappingPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(SwitchPreference("revanced_seekbar_tapping"))
SettingsPatch.PreferenceScreen.SEEKBAR.addPreferences(
SwitchPreference("revanced_seekbar_tapping")
)
// Find the required methods to tap the seekbar.
val seekbarTappingMethods = OnTouchEventHandlerFingerprint.result?.let {

View File

@@ -50,7 +50,9 @@ object EnableSlideToSeekPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(SwitchPreference("revanced_slide_to_seek"))
SettingsPatch.PreferenceScreen.SEEKBAR.addPreferences(
SwitchPreference("revanced_slide_to_seek")
)
arrayOf(
// Restore the behaviour to slide to seek.

View File

@@ -5,7 +5,6 @@ import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
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.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch
@@ -13,27 +12,22 @@ import app.revanced.util.ResourceGroup
import app.revanced.util.copyResources
@Patch(
dependencies = [SettingsPatch::class, AddResourcesPatch::class]
dependencies = [SettingsPatch::class, AddResourcesPatch::class],
)
internal object SwipeControlsResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(
PreferenceScreen(
key = "revanced_swipe_controls_preference_screen",
preferences = setOf(
SwitchPreference("revanced_swipe_brightness"),
SwitchPreference("revanced_swipe_volume"),
SwitchPreference("revanced_swipe_press_to_engage"),
SwitchPreference("revanced_swipe_haptic_feedback"),
SwitchPreference("revanced_swipe_save_and_restore_brightness"),
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_text_overlay_size", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_overlay_background_alpha", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_threshold", inputType = InputType.NUMBER)
),
)
SettingsPatch.PreferenceScreen.SWIPE_CONTROLS.addPreferences(
SwitchPreference("revanced_swipe_brightness"),
SwitchPreference("revanced_swipe_volume"),
SwitchPreference("revanced_swipe_press_to_engage"),
SwitchPreference("revanced_swipe_haptic_feedback"),
SwitchPreference("revanced_swipe_save_and_restore_brightness"),
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_text_overlay_size", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_overlay_background_alpha", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_threshold", inputType = InputType.NUMBER),
)
context.copyResources(
@@ -43,8 +37,8 @@ internal object SwipeControlsResourcePatch : ResourcePatch() {
"revanced_ic_sc_brightness_auto.xml",
"revanced_ic_sc_brightness_manual.xml",
"revanced_ic_sc_volume_mute.xml",
"revanced_ic_sc_volume_normal.xml"
)
"revanced_ic_sc_volume_normal.xml",
),
)
}
}

View File

@@ -48,7 +48,9 @@ object AutoCaptionsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_auto_captions"))
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_auto_captions")
)
mapOf(
StartVideoInformerFingerprint to 0,

View File

@@ -82,7 +82,7 @@ object ChangeHeaderPatch : ResourcePatch() {
}
/**
* A function that overwrites both header variants from [from] to [to] in the target resource directories.
* A function that overwrites both header variants in the target resource directories.
*/
val overwriteFromTo: (String, String) -> Unit = { from: String, to: String ->
targetResourceDirectories.forEach { directory ->

View File

@@ -48,12 +48,11 @@ object HideButtonsPatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
PreferenceScreen(
"revanced_hide_buttons_preference_screen",
"revanced_hide_buttons_screen",
preferences = setOf(
SwitchPreference("revanced_hide_like_dislike_button"),
SwitchPreference("revanced_hide_live_chat_button"),
SwitchPreference("revanced_hide_share_button"),
SwitchPreference("revanced_hide_report_button"),
SwitchPreference("revanced_hide_remix_button"),

View File

@@ -57,7 +57,9 @@ object HideAutoplayButtonPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_autoplay_button"))
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_autoplay_button")
)
LayoutConstructorFingerprint.result?.mutableMethod?.apply {
val layoutGenMethodInstructions = implementation!!.instructions

View File

@@ -48,7 +48,9 @@ object HideCaptionsButtonPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_captions_button"))
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_captions_button")
)
val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod

View File

@@ -27,7 +27,9 @@ object HideCastButtonPatch : BytecodePatch(emptySet()) {
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_cast_button"))
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_cast_button")
)
val buttonClass = context.findClass("MediaRouteButton")
?: throw PatchException("MediaRouteButton class not found.")

View File

@@ -8,6 +8,7 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.*
import app.revanced.patches.youtube.layout.buttons.navigation.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT
@@ -24,7 +25,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
IntegrationsPatch::class,
SettingsPatch::class,
ResolvePivotBarFingerprintsPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
compatiblePackages = [
CompatiblePackage(
@@ -42,14 +43,14 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.02.39",
"19.03.35",
"19.03.36",
"19.04.37"
]
)
]
"19.04.37",
],
),
],
)
@Suppress("unused")
object NavigationButtonsPatch : BytecodePatch(
setOf(AddCreateButtonViewFingerprint)
setOf(AddCreateButtonViewFingerprint),
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/NavigationButtonsPatch;"
@@ -57,17 +58,18 @@ object NavigationButtonsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
PreferenceScreen(
key = "revanced_navigation_buttons_preference_screen",
key = "revanced_navigation_buttons_screen",
sorting = Sorting.UNSORTED,
preferences = setOf(
SwitchPreference("revanced_hide_home_button"),
SwitchPreference("revanced_hide_shorts_button"),
SwitchPreference("revanced_hide_subscriptions_button"),
SwitchPreference("revanced_hide_create_button"),
SwitchPreference("revanced_hide_subscriptions_button"),
SwitchPreference("revanced_switch_create_with_notifications_button"),
),
)
),
)
/*
@@ -82,14 +84,14 @@ object NavigationButtonsPatch : BytecodePatch(
if (!it.resolve(
context,
initializeButtonsResult.mutableMethod,
initializeButtonsResult.mutableClass
initializeButtonsResult.mutableClass,
)
)
) {
throw it.exception
}
}
.map { it.result!!.scanResult.patternScanResult!! }
val enumScanResult = fingerprintResults[0]
val buttonViewResult = fingerprintResults[1]
@@ -101,14 +103,14 @@ object NavigationButtonsPatch : BytecodePatch(
*/
val enumHook = "sput-object v$REGISTER_TEMPLATE_REPLACEMENT, " +
"$INTEGRATIONS_CLASS_DESCRIPTOR->lastNavigationButton:Ljava/lang/Enum;"
"$INTEGRATIONS_CLASS_DESCRIPTOR->lastNavigationButton:Ljava/lang/Enum;"
val buttonHook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
"$INTEGRATIONS_CLASS_DESCRIPTOR->hideButton(Landroid/view/View;)V"
"$INTEGRATIONS_CLASS_DESCRIPTOR->hideButton(Landroid/view/View;)V"
// Inject bottom to top to not mess up the indices
mapOf(
buttonHook to buttonHookInsertIndex,
enumHook to enumHookInsertIndex
enumHook to enumHookInsertIndex,
).forEach { (hook, insertIndex) ->
initializeButtonsResult.mutableMethod.injectHook(hook, insertIndex)
}
@@ -131,7 +133,7 @@ object NavigationButtonsPatch : BytecodePatch(
"""
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->switchCreateWithNotificationButton()Z
move-result v$conditionRegister
"""
""",
)
}
} ?: throw AddCreateButtonViewFingerprint.exception
@@ -141,8 +143,9 @@ object NavigationButtonsPatch : BytecodePatch(
*/
InitializeButtonsFingerprint.result!!.let {
if (!PivotBarCreateButtonViewFingerprint.resolve(context, it.mutableMethod, it.mutableClass))
if (!PivotBarCreateButtonViewFingerprint.resolve(context, it.mutableMethod, it.mutableClass)) {
throw PivotBarCreateButtonViewFingerprint.exception
}
}
PivotBarCreateButtonViewFingerprint.result!!.apply {
@@ -152,9 +155,9 @@ object NavigationButtonsPatch : BytecodePatch(
* Inject hooks
*/
val hook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
"$INTEGRATIONS_CLASS_DESCRIPTOR->hideCreateButton(Landroid/view/View;)V"
"$INTEGRATIONS_CLASS_DESCRIPTOR->hideCreateButton(Landroid/view/View;)V"
mutableMethod.injectHook(hook, insertIndex)
}
}
}
}

View File

@@ -52,7 +52,9 @@ object HidePlayerButtonsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_player_buttons"))
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_player_buttons")
)
PlayerControlsVisibilityModelFingerprint.result?.apply {
val callIndex = scanResult.patternScanResult!!.endIndex

View File

@@ -21,7 +21,9 @@ internal object AlbumCardsResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_album_cards"))
SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_album_cards")
)
albumCardId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "album_card"

View File

@@ -21,7 +21,9 @@ internal object BreakingNewsResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_breaking_news"))
SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_breaking_news")
)
horizontalCardListId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "horizontal_card_list"

View File

@@ -47,9 +47,9 @@ object CommentsPatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
PreferenceScreen(
"revanced_comments_preference_screen",
"revanced_comments_screen",
preferences = setOf(
SwitchPreference("revanced_hide_comments_section"),
SwitchPreference("revanced_hide_preview_comment")

View File

@@ -21,7 +21,9 @@ internal object CrowdfundingBoxResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_crowdfunding_box"))
SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_crowdfunding_box")
)
crowdfundingBoxId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "donation_companion"

View File

@@ -23,7 +23,9 @@ internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_endscreen_cards"))
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_endscreen_cards")
)
fun findEndscreenResourceId(name: String) = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "endscreen_element_layout_$name"

View File

@@ -18,9 +18,9 @@ internal object HideFilterBarResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SettingsPatch.PreferenceScreen.FEED.addPreferences(
PreferenceScreen(
key = "revanced_hide_filter_bar_preference",
key = "revanced_hide_filter_bar_screen",
preferences = setOf(
SwitchPreference("revanced_hide_filter_bar_feed_in_feed"),
SwitchPreference("revanced_hide_filter_bar_feed_in_search"),

View File

@@ -22,7 +22,9 @@ internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_floating_microphone_button"))
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_hide_floating_microphone_button")
)
fabButtonId = ResourceMappingPatch.resourceMappings.find { it.type == "id" && it.name == "fab" }?.id
?: throw PatchException("Can not find required fab button resource id")

View File

@@ -45,7 +45,7 @@ object DisableFullscreenAmbientModePatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_disable_fullscreen_ambient_mode")
)

View File

@@ -12,6 +12,8 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
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.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElementFromBufferFingerprint
@@ -19,7 +21,6 @@ import app.revanced.patches.youtube.layout.hide.general.fingerprints.PlayerOverl
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ShowWatermarkFingerprint
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch.PreferenceScreen
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@@ -31,11 +32,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
dependencies = [
LithoFilterPatch::class,
SettingsPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
"com.google.android.youtube",
[
"18.32.39",
"18.37.36",
"18.38.44",
@@ -48,14 +50,14 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.02.39",
"19.03.35",
"19.03.36",
"19.04.37"
]
)
]
"19.04.37",
],
),
],
)
@Suppress("unused")
object HideLayoutComponentsPatch : BytecodePatch(
setOf(ParseElementFromBufferFingerprint, PlayerOverlayFingerprint)
setOf(ParseElementFromBufferFingerprint, PlayerOverlayFingerprint),
) {
private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/components/LayoutComponentsFilter;"
@@ -64,59 +66,68 @@ object HideLayoutComponentsPatch : BytecodePatch(
private const val CUSTOM_FILTER_CLASS_NAME =
"Lapp/revanced/integrations/youtube/patches/components/CustomFilter;"
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference("revanced_hide_gray_separator"),
SwitchPreference("revanced_hide_join_membership_button"),
SwitchPreference("revanced_hide_channel_watermark"),
SwitchPreference("revanced_hide_for_you_shelf"),
SwitchPreference("revanced_hide_notify_me_button"),
SwitchPreference("revanced_hide_timed_reactions"),
SwitchPreference("revanced_hide_search_result_recommendations"),
SwitchPreference("revanced_hide_search_result_shelf_header"),
SwitchPreference("revanced_hide_channel_guidelines"),
SwitchPreference("revanced_hide_expandable_chip"),
SwitchPreference("revanced_hide_video_quality_menu_footer"),
SwitchPreference("revanced_hide_chapters"),
SwitchPreference("revanced_hide_community_posts"),
SwitchPreference("revanced_hide_compact_banner"),
SwitchPreference("revanced_hide_movies_section"),
SwitchPreference("revanced_hide_feed_survey"),
SwitchPreference("revanced_hide_community_guidelines"),
SwitchPreference("revanced_hide_subscribers_community_guidelines"),
SwitchPreference("revanced_hide_channel_member_shelf"),
SwitchPreference("revanced_hide_emergency_box"),
SwitchPreference("revanced_hide_info_panels"),
SwitchPreference("revanced_hide_medical_panels"),
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_channel_bar"),
SwitchPreference("revanced_hide_quick_actions"),
SwitchPreference("revanced_hide_related_videos"),
SwitchPreference("revanced_hide_image_shelf"),
SwitchPreference("revanced_hide_latest_posts_ads"),
SwitchPreference("revanced_hide_mix_playlists"),
SwitchPreference("revanced_hide_artist_cards"),
SwitchPreference("revanced_hide_channel_guidelines"),
SwitchPreference("revanced_hide_channel_member_shelf"),
SwitchPreference("revanced_hide_channel_watermark"),
SwitchPreference("revanced_hide_chips_shelf"),
app.revanced.patches.shared.misc.settings.preference.PreferenceScreen(
"revanced_hide_description_components_preference_screen",
SwitchPreference("revanced_hide_community_guidelines"),
PreferenceScreen(
key = "revanced_hide_description_components_screen",
preferences = setOf(
SwitchPreference("revanced_hide_chapters"),
SwitchPreference("revanced_hide_info_cards_section"),
SwitchPreference("revanced_hide_game_section"),
SwitchPreference("revanced_hide_music_section"),
SwitchPreference("revanced_hide_podcast_section"),
SwitchPreference("revanced_hide_transcript_section"),
)
),
),
app.revanced.patches.shared.misc.settings.preference.PreferenceScreen(
"revanced_custom_filter_preference_screen",
SwitchPreference("revanced_hide_emergency_box"),
SwitchPreference("revanced_hide_expandable_chip"),
SwitchPreference("revanced_hide_info_panels"),
SwitchPreference("revanced_hide_medical_panels"),
SwitchPreference("revanced_hide_quick_actions"),
SwitchPreference("revanced_hide_related_videos"),
SwitchPreference("revanced_hide_subscribers_community_guidelines"),
SwitchPreference("revanced_hide_timed_reactions"),
)
SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_artist_cards"),
SwitchPreference("revanced_hide_community_posts"),
SwitchPreference("revanced_hide_compact_banner"),
SwitchPreference("revanced_hide_feed_survey"),
SwitchPreference("revanced_hide_for_you_shelf"),
SwitchPreference("revanced_hide_image_shelf"),
SwitchPreference("revanced_hide_join_membership_button"),
SwitchPreference("revanced_hide_latest_posts_ads"),
SwitchPreference("revanced_hide_mix_playlists"),
SwitchPreference("revanced_hide_movies_section"),
SwitchPreference("revanced_hide_notify_me_button"),
SwitchPreference("revanced_hide_search_result_recommendations"),
SwitchPreference("revanced_hide_search_result_shelf_header"),
)
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_hide_gray_separator"),
PreferenceScreen(
key = "revanced_custom_filter_screen",
sorting = Sorting.UNSORTED,
preferences = setOf(
SwitchPreference("revanced_custom_filter"),
// TODO: This should be a dynamic ListPreference, which does not exist yet
TextPreference("revanced_custom_filter_strings", inputType = InputType.TEXT_MULTI_LINE)
)
)
TextPreference("revanced_custom_filter_strings", inputType = InputType.TEXT_MULTI_LINE),
),
),
)
SettingsPatch.PreferenceScreen.VIDEO.addPreferences(
SwitchPreference("revanced_hide_video_quality_menu_footer"),
)
LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR)
@@ -136,14 +147,15 @@ object HideLayoutComponentsPatch : BytecodePatch(
val byteBufferRegister = getInstruction<FiveRegisterInstruction>(consumeByteBufferIndex).registerD
addInstructionsWithLabels(
consumeByteBufferIndex, """
consumeByteBufferIndex,
"""
invoke-static {v$conversionContextRegister, v$byteBufferRegister}, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->filterMixPlaylists(Ljava/lang/Object;[B)Z
move-result v0 # Conveniently same register happens to be free.
if-nez v0, :return_empty_component
""", ExternalLabel("return_empty_component", returnEmptyComponentInstruction)
""",
ExternalLabel("return_empty_component", returnEmptyComponentInstruction),
)
}
} ?: throw ParseElementFromBufferFingerprint.exception
// endregion
@@ -157,10 +169,11 @@ object HideLayoutComponentsPatch : BytecodePatch(
removeInstruction(index)
addInstructions(
index, """
index,
"""
invoke-static {}, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->showWatermark()Z
move-result p2
"""
""",
)
} ?: throw ShowWatermarkFingerprint.exception

View File

@@ -21,7 +21,9 @@ object HideInfocardsResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_info_cards"))
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_info_cards")
)
drawerResourceId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "info_cards_drawer_header"

View File

@@ -21,7 +21,9 @@ internal object HideLoadMoreButtonResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_load_more_button"))
SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_load_more_button")
)
expandButtonDownId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "expand_button_down"

View File

@@ -50,7 +50,7 @@ object HidePlayerFlyoutMenuPatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
PreferenceScreen(
key = KEY,
preferences = setOf(

View File

@@ -49,7 +49,7 @@ object DisableRollingNumberAnimationPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_disable_rolling_number_animations")
)

View File

@@ -8,7 +8,6 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.layout.seekbar.SeekbarColorBytecodePatch
import app.revanced.patches.youtube.layout.seekbar.SeekbarPreferencesPatch
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
@@ -21,7 +20,6 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
IntegrationsPatch::class,
SettingsPatch::class,
SeekbarColorBytecodePatch::class,
SeekbarPreferencesPatch::class,
AddResourcesPatch::class
],
compatiblePackages = [
@@ -51,7 +49,7 @@ object HideSeekbarPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SeekbarPreferencesPatch.addPreferences(
SettingsPatch.PreferenceScreen.SEEKBAR.addPreferences(
SwitchPreference("revanced_hide_seekbar"),
SwitchPreference("revanced_hide_seekbar_thumbnail")
)

View File

@@ -5,7 +5,6 @@ import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch
@@ -17,24 +16,19 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
PreferenceScreen(
"revanced_shorts_preference_screen",
preferences = setOf(
SwitchPreference("revanced_hide_shorts"),
SwitchPreference("revanced_hide_shorts_join_button"),
SwitchPreference("revanced_hide_shorts_subscribe_button"),
SwitchPreference("revanced_hide_shorts_subscribe_button_paused"),
SwitchPreference("revanced_hide_shorts_thanks_button"),
SwitchPreference("revanced_hide_shorts_comments_button"),
SwitchPreference("revanced_hide_shorts_remix_button"),
SwitchPreference("revanced_hide_shorts_share_button"),
SwitchPreference("revanced_hide_shorts_info_panel"),
SwitchPreference("revanced_hide_shorts_channel_bar"),
SwitchPreference("revanced_hide_shorts_sound_button"),
SwitchPreference("revanced_hide_shorts_navigation_bar")
)
)
SettingsPatch.PreferenceScreen.SHORTS.addPreferences(
SwitchPreference("revanced_hide_shorts"),
SwitchPreference("revanced_hide_shorts_join_button"),
SwitchPreference("revanced_hide_shorts_subscribe_button"),
SwitchPreference("revanced_hide_shorts_subscribe_button_paused"),
SwitchPreference("revanced_hide_shorts_thanks_button"),
SwitchPreference("revanced_hide_shorts_comments_button"),
SwitchPreference("revanced_hide_shorts_remix_button"),
SwitchPreference("revanced_hide_shorts_share_button"),
SwitchPreference("revanced_hide_shorts_info_panel"),
SwitchPreference("revanced_hide_shorts_channel_bar"),
SwitchPreference("revanced_hide_shorts_sound_button"),
SwitchPreference("revanced_hide_shorts_navigation_bar")
)
ResourceMappingPatch.resourceMappings.find {

View File

@@ -21,7 +21,7 @@ internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_disable_suggested_video_end_screen")
)

View File

@@ -42,7 +42,9 @@ object HideTimestampPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_timestamp"))
SettingsPatch.PreferenceScreen.SEEKBAR.addPreferences(
SwitchPreference("revanced_hide_timestamp")
)
TimeCounterFingerprint.result?.apply {
mutableMethod.addInstructionsWithLabels(

View File

@@ -43,7 +43,9 @@ object PlayerPopupPanelsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_hide_player_popup_panels"))
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_player_popup_panels")
)
val engagementPanelControllerMethod = EngagementPanelControllerFingerprint
.result?.mutableMethod ?: throw EngagementPanelControllerFingerprint.exception

View File

@@ -18,7 +18,7 @@ internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER)
)

View File

@@ -32,6 +32,7 @@ import app.revanced.patches.youtube.video.videoid.VideoIdPatch
import app.revanced.util.exception
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.resultOrThrow
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
@@ -88,8 +89,6 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
private const val FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/components/ReturnYouTubeDislikeFilterPatch;"
private fun MethodFingerprint.resultOrThrow() = result ?: throw exception
override fun execute(context: BytecodeContext) {
// region Inject newVideoLoaded event handler to update dislikes when a new video is loaded.

View File

@@ -7,6 +7,7 @@ import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.IntentPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.misc.settings.SettingsResourcePatch
@Patch(
dependencies = [
@@ -20,15 +21,13 @@ internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
IntentPreference(
"revanced_ryd_settings",
intent = SettingsPatch.newIntent("revanced_ryd_settings_intent")
)
SettingsResourcePatch += IntentPreference(
key = "revanced_settings_screen_09",
titleKey = "revanced_ryd_settings_title",
summaryKey = null,
intent = SettingsPatch.newIntent("revanced_ryd_settings_intent")
)
AddResourcesPatch(this::class)
oldUIDislikeId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "dislike_button"
}.id

View File

@@ -54,7 +54,9 @@ object WideSearchbarPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_wide_searchbar"))
SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_wide_searchbar")
)
val result = CreateSearchSuggestionsFingerprint.result ?: throw CreateSearchSuggestionsFingerprint.exception

View File

@@ -10,12 +10,13 @@ import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.layout.seekbar.fingerprints.FullscreenSeekbarThumbnailsFingerprint
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.util.exception
@Patch(
name = "Restore old seekbar thumbnails",
description = "Adds an option to restore the old seekbar thumbnails that appear above the seekbar while seeking instead of fullscreen thumbnails.",
dependencies = [IntegrationsPatch::class, SeekbarPreferencesPatch::class, AddResourcesPatch::class],
dependencies = [IntegrationsPatch::class, AddResourcesPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
@@ -45,7 +46,9 @@ object RestoreOldSeekbarThumbnailsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SeekbarPreferencesPatch.addPreferences(SwitchPreference("revanced_restore_old_seekbar_thumbnails"))
SettingsPatch.PreferenceScreen.SEEKBAR.addPreferences(
SwitchPreference("revanced_restore_old_seekbar_thumbnails")
)
FullscreenSeekbarThumbnailsFingerprint.result?.mutableMethod?.apply {
val moveResultIndex = getInstructions().lastIndex - 1

View File

@@ -1,34 +0,0 @@
package app.revanced.patches.youtube.layout.seekbar
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.BasePreference
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import java.io.Closeable
@Patch(dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class])
internal object SeekbarPreferencesPatch : ResourcePatch(), Closeable {
private val seekbarPreferences = mutableSetOf<BasePreference>()
override fun execute(context: ResourceContext) {
// Nothing to do here. All work is done in close method.
}
override fun close() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
PreferenceScreen(
"revanced_seekbar_preference_screen",
preferences = seekbarPreferences,
)
)
}
internal fun addPreferences(vararg preferencesToAdd: BasePreference) =
seekbarPreferences.addAll(preferencesToAdd)
}

View File

@@ -8,6 +8,7 @@ import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.IntentPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.misc.settings.SettingsResourcePatch
import app.revanced.util.ResourceGroup
import app.revanced.util.copyResources
import app.revanced.util.copyXmlNode
@@ -24,12 +25,13 @@ internal object SponsorBlockResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
IntentPreference(
"revanced_sb_settings",
intent = SettingsPatch.newIntent("revanced_sb_settings_intent"),
),
SettingsResourcePatch += IntentPreference(
key = "revanced_settings_screen_10",
titleKey = "revanced_sb_settings_title",
summaryKey = null,
intent = SettingsPatch.newIntent("revanced_sb_settings_intent")
)
arrayOf(
ResourceGroup(
"layout",

View File

@@ -49,7 +49,7 @@ object SpoofAppVersionPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_spoof_app_version"),
ListPreference(
key = "revanced_spoof_app_version_target",

View File

@@ -33,7 +33,7 @@ object ChangeStartPagePatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
ListPreference(
key = "revanced_start_page",
summaryKey = null,

View File

@@ -56,7 +56,7 @@ object DisableResumingShortsOnStartupPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SettingsPatch.PreferenceScreen.SHORTS.addPreferences(
SwitchPreference("revanced_disable_resuming_shorts_player")
)

View File

@@ -28,7 +28,9 @@ object EnableTabletLayoutPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_tablet_layout"))
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_tablet_layout")
)
GetFormFactorFingerprint.result?.let {
it.mutableMethod.apply {

View File

@@ -55,7 +55,9 @@ object TabletMiniPlayerPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_tablet_miniplayer"))
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_tablet_miniplayer")
)
// First resolve the fingerprints via the parent fingerprint.
MiniPlayerDimensionsCalculatorParentFingerprint.result
@@ -127,7 +129,7 @@ object TabletMiniPlayerPatch : BytecodePatch(
)
}
fun MethodFingerprint.unwrap(): Triple<MutableMethod, Int, Int> {
private fun MethodFingerprint.unwrap(): Triple<MutableMethod, Int, Int> {
val result = this.result!!
val scanIndex = result.scanResult.patternScanResult!!.endIndex
val method = result.mutableMethod

View File

@@ -100,7 +100,9 @@ object ThemeBytecodePatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference("revanced_gradient_loading_screen"))
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_gradient_loading_screen")
)
UseGradientLoadingScreenFingerprint.result?.mutableMethod?.apply {
val isEnabledIndex = indexOfFirstWideLiteralInstructionValue(GRADIENT_LOADING_SCREEN_AB_CONSTANT) + 3

View File

@@ -9,7 +9,6 @@ import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
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.layout.seekbar.SeekbarPreferencesPatch
import app.revanced.patches.youtube.layout.theme.ThemeBytecodePatch.darkThemeBackgroundColor
import app.revanced.patches.youtube.layout.theme.ThemeBytecodePatch.lightThemeBackgroundColor
import app.revanced.patches.youtube.misc.settings.SettingsPatch
@@ -19,7 +18,6 @@ import org.w3c.dom.Element
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
SeekbarPreferencesPatch::class,
AddResourcesPatch::class,
],
)
@@ -29,7 +27,7 @@ internal object ThemeResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SeekbarPreferencesPatch.addPreferences(
SettingsPatch.PreferenceScreen.SEEKBAR.addPreferences(
SwitchPreference("revanced_seekbar_custom_color"),
TextPreference("revanced_seekbar_custom_color_value", inputType = InputType.TEXT_CAP_CHARACTERS),
)

View File

@@ -11,7 +11,10 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.*
import app.revanced.patches.shared.misc.settings.preference.ListPreference
import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.layout.thumbnails.fingerprints.MessageDigestImageUrlFingerprint
import app.revanced.patches.youtube.layout.thumbnails.fingerprints.MessageDigestImageUrlParentFingerprint
import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.RequestFingerprint
@@ -20,7 +23,7 @@ import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.reques
import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback.OnSucceededFingerprint
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
@@ -34,8 +37,7 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
dependencies = [
IntegrationsPatch::class,
SettingsPatch::class,
AlternativeThumbnailsResourcePatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
compatiblePackages = [
CompatiblePackage(
@@ -53,10 +55,10 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"19.02.39",
"19.03.35",
"19.03.36",
"19.04.37"
]
)
]
"19.04.37",
],
),
],
)
@Suppress("unused")
object AlternativeThumbnailsPatch : BytecodePatch(
@@ -64,7 +66,7 @@ object AlternativeThumbnailsPatch : BytecodePatch(
MessageDigestImageUrlParentFingerprint,
OnResponseStartedFingerprint,
RequestFingerprint,
)
),
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/AlternativeThumbnailsPatch;"
@@ -88,7 +90,7 @@ object AlternativeThumbnailsPatch : BytecodePatch(
"""
invoke-static { p1 }, $targetMethodClass->overrideImageURL(Ljava/lang/String;)Ljava/lang/String;
move-result-object p1
"""
""",
)
loadImageUrlIndex += 2
}
@@ -102,7 +104,7 @@ object AlternativeThumbnailsPatch : BytecodePatch(
loadImageSuccessCallbackMethod.addInstruction(
loadImageSuccessCallbackIndex++,
"invoke-static { p1, p2 }, $targetMethodClass->handleCronetSuccess(" +
"Lorg/chromium/net/UrlRequest;Lorg/chromium/net/UrlResponseInfo;)V"
"Lorg/chromium/net/UrlRequest;Lorg/chromium/net/UrlResponseInfo;)V",
)
}
@@ -114,55 +116,40 @@ object AlternativeThumbnailsPatch : BytecodePatch(
loadImageErrorCallbackMethod.addInstruction(
loadImageErrorCallbackIndex++,
"invoke-static { p1, p2, p3 }, $targetMethodClass->handleCronetFailure(" +
"Lorg/chromium/net/UrlRequest;Lorg/chromium/net/UrlResponseInfo;Ljava/io/IOException;)V"
"Lorg/chromium/net/UrlRequest;Lorg/chromium/net/UrlResponseInfo;Ljava/io/IOException;)V",
)
}
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
PreferenceScreen(
"revanced_alt_thumbnail_preference_screen",
preferences = setOf(
NonInteractivePreference(
"revanced_alt_thumbnail_about",
null, // Summary is dynamically updated based on the current settings.
tag = "app.revanced.integrations.youtube.settings.preference.AlternativeThumbnailsStatusPreference"
),
SwitchPreference("revanced_alt_thumbnail_dearrow"),
SwitchPreference("revanced_alt_thumbnail_dearrow_connection_toast"),
TextPreference("revanced_alt_thumbnail_dearrow_api_url"),
NonInteractivePreference(
"revanced_alt_thumbnail_dearrow_about",
// Custom about preference with link to the DeArrow website.
tag = "app.revanced.integrations.youtube.settings.preference.AlternativeThumbnailsAboutDeArrowPreference",
selectable = true
),
SwitchPreference("revanced_alt_thumbnail_stills"),
ListPreference(
"revanced_alt_thumbnail_stills_time",
summaryKey = null,
),
SwitchPreference("revanced_alt_thumbnail_stills_fast"),
NonInteractivePreference(
"revanced_alt_thumbnail_stills_about",
// Restore the preference dividers to keep it from looking weird.
selectable = true
)
)
)
SettingsPatch.PreferenceScreen.ALTERNATIVE_THUMBNAILS.addPreferences(
NonInteractivePreference(
"revanced_alt_thumbnail_about",
null, // Summary is dynamically updated based on the current settings.
tag = "app.revanced.integrations.youtube.settings.preference.AlternativeThumbnailsStatusPreference",
),
SwitchPreference("revanced_alt_thumbnail_dearrow"),
SwitchPreference("revanced_alt_thumbnail_dearrow_connection_toast"),
TextPreference("revanced_alt_thumbnail_dearrow_api_url"),
NonInteractivePreference(
"revanced_alt_thumbnail_dearrow_about",
// Custom about preference with link to the DeArrow website.
tag = "app.revanced.integrations.youtube.settings.preference.AlternativeThumbnailsAboutDeArrowPreference",
selectable = true,
),
SwitchPreference("revanced_alt_thumbnail_stills"),
ListPreference("revanced_alt_thumbnail_stills_time", summaryKey = null),
SwitchPreference("revanced_alt_thumbnail_stills_fast"),
NonInteractivePreference("revanced_alt_thumbnail_stills_about"),
)
fun MethodFingerprint.getResultOrThrow() =
result ?: throw exception
fun MethodFingerprint.alsoResolve(fingerprint: MethodFingerprint) =
also { resolve(context, fingerprint.getResultOrThrow().classDef) }.getResultOrThrow()
also { resolve(context, fingerprint.resultOrThrow().classDef) }.resultOrThrow()
fun MethodFingerprint.resolveAndLetMutableMethod(
fingerprint: MethodFingerprint,
block: (MutableMethod) -> Unit
block: (MutableMethod) -> Unit,
) = alsoResolve(fingerprint).also { block(it.mutableMethod) }
MessageDigestImageUrlFingerprint.resolveAndLetMutableMethod(MessageDigestImageUrlParentFingerprint) {
@@ -182,7 +169,7 @@ object AlternativeThumbnailsPatch : BytecodePatch(
// The URL is required for the failure callback hook, but the URL field is obfuscated.
// Add a helper get method that returns the URL field.
RequestFingerprint.getResultOrThrow().apply {
RequestFingerprint.resultOrThrow().apply {
// The url is the only string field that is set inside the constructor.
val urlFieldInstruction = mutableMethod.getInstructions().first {
if (it.opcode != Opcode.IPUT_OBJECT) return@first false
@@ -203,15 +190,16 @@ object AlternativeThumbnailsPatch : BytecodePatch(
AccessFlags.PUBLIC.value,
null,
null,
MutableMethodImplementation(2)
MutableMethodImplementation(2),
).toMutable().apply {
addInstructions(
"""
iget-object v0, p0, $definingClass->${urlFieldName}:Ljava/lang/String;
iget-object v0, p0, $definingClass->$urlFieldName:Ljava/lang/String;
return-object v0
"""
""",
)
})
},
)
}
}
}

View File

@@ -1,19 +0,0 @@
package app.revanced.patches.youtube.layout.thumbnails
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch(
dependencies = [
SettingsPatch::class,
AddResourcesPatch::class
]
)
internal object AlternativeThumbnailsResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
}
}

View File

@@ -29,7 +29,9 @@ object AnnouncementsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.MISC.addPreferences(SwitchPreference("revanced_announcements"))
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference("revanced_announcements")
)
val onCreateMethod = MainActivityFingerprint.result?.let {
it.mutableClass.methods.find { method -> method.name == "onCreate" }

View File

@@ -47,7 +47,9 @@ object AutoRepeatPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.MISC.addPreferences(SwitchPreference("revanced_auto_repeat"))
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference("revanced_auto_repeat")
)
//Get Result from the ParentFingerprint which is the playMethod we need to get.
val parentResult = AutoRepeatParentFingerprint.result

View File

@@ -6,6 +6,7 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
@@ -14,7 +15,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
name = "Enable debugging",
description = "Adds options for debugging.",
dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class],
compatiblePackages = [CompatiblePackage("com.google.android.youtube")]
compatiblePackages = [CompatiblePackage("com.google.android.youtube")],
)
@Suppress("unused")
object DebuggingPatch : ResourcePatch() {
@@ -23,14 +24,15 @@ object DebuggingPatch : ResourcePatch() {
SettingsPatch.PreferenceScreen.MISC.addPreferences(
PreferenceScreen(
"revanced_debug_preference_screen",
key = "revanced_debug_screen",
sorting = Sorting.UNSORTED,
preferences = setOf(
SwitchPreference("revanced_debug"),
SwitchPreference("revanced_debug_protobuffer"),
SwitchPreference("revanced_debug_stacktrace"),
SwitchPreference("revanced_debug_toast_on_error")
)
)
SwitchPreference("revanced_debug_toast_on_error"),
),
),
)
}
}

View File

@@ -45,7 +45,9 @@ object SpoofDeviceDimensionsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.MISC.addPreferences(SwitchPreference("revanced_spoof_device_dimensions",))
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference("revanced_spoof_device_dimensions")
)
DeviceDimensionsModelToStringFingerprint.result
?.mutableClass?.methods?.find { method -> method.name == "<init>" }

View File

@@ -10,13 +10,25 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ParamsMapPutFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerResponseModelImplGeneralFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerResponseModelImplLiveStreamFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerResponseModelImplRecommendedLevelFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ScrubbedPreviewLayoutFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardRendererDecoderRecommendedLevelFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardRendererDecoderSpecFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardRendererSpecFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardThumbnailFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardThumbnailParentFingerprint
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
import app.revanced.util.exception
import app.revanced.util.*
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@@ -28,8 +40,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
PlayerResponseMethodHookPatch::class,
VideoInformationPatch::class,
SpoofSignatureResourcePatch::class,
AddResourcesPatch::class
]
AddResourcesPatch::class,
],
)
object SpoofSignaturePatch : BytecodePatch(
setOf(
@@ -41,7 +53,9 @@ object SpoofSignaturePatch : BytecodePatch(
StoryboardRendererDecoderRecommendedLevelFingerprint,
StoryboardThumbnailParentFingerprint,
ScrubbedPreviewLayoutFingerprint,
)
StatsQueryParameterFingerprint,
ParamsMapPutFingerprint,
),
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/spoof/SpoofSignaturePatch;"
@@ -51,18 +65,19 @@ object SpoofSignaturePatch : BytecodePatch(
SettingsPatch.PreferenceScreen.MISC.addPreferences(
PreferenceScreen(
"revanced_spoof_signature_verification",
key = "revanced_spoof_signature_verification_screen",
sorting = Sorting.UNSORTED,
preferences = setOf(
SwitchPreference("revanced_spoof_signature_verification_enabled"),
SwitchPreference("revanced_spoof_signature_in_feed_enabled"),
SwitchPreference("revanced_spoof_storyboard")
SwitchPreference("revanced_spoof_storyboard"),
),
)
),
)
// Hook the player parameters.
PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.ProtoBufferParameter(
"$INTEGRATIONS_CLASS_DESCRIPTOR->spoofParameter(Ljava/lang/String;Z)Ljava/lang/String;"
"$INTEGRATIONS_CLASS_DESCRIPTOR->spoofParameter(Ljava/lang/String;Z)Ljava/lang/String;",
)
// Force the seekbar time and chapters to always show up.
@@ -72,7 +87,7 @@ object SpoofSignaturePatch : BytecodePatch(
StoryboardThumbnailFingerprint.also {
it.resolve(
context,
classDef
classDef,
)
}.result?.let {
val endIndex = it.scanResult.patternScanResult!!.endIndex
@@ -84,7 +99,7 @@ object SpoofSignaturePatch : BytecodePatch(
endIndex,
"""
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->getSeekbarThumbnailOverrideValue()Z
"""
""",
)
// Since this is end of the method must replace one line then add the rest.
it.mutableMethod.addInstructions(
@@ -92,7 +107,7 @@ object SpoofSignaturePatch : BytecodePatch(
"""
move-result v0
return v0
"""
""",
)
} ?: throw StoryboardThumbnailFingerprint.exception
}
@@ -107,7 +122,7 @@ object SpoofSignaturePatch : BytecodePatch(
"""
iget-object v0, p0, $imageViewFieldName # copy imageview field to a register
invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->seekbarImageViewCreated(Landroid/widget/ImageView;)V
"""
""",
)
}
} ?: throw ScrubbedPreviewLayoutFingerprint.exception
@@ -117,7 +132,7 @@ object SpoofSignaturePatch : BytecodePatch(
*/
arrayOf(
PlayerResponseModelImplGeneralFingerprint,
PlayerResponseModelImplLiveStreamFingerprint
PlayerResponseModelImplLiveStreamFingerprint,
).forEach { fingerprint ->
fingerprint.result?.let {
it.mutableMethod.apply {
@@ -130,7 +145,7 @@ object SpoofSignaturePatch : BytecodePatch(
"""
invoke-static { v$getStoryBoardRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$getStoryBoardRegister
"""
""",
)
}
} ?: throw fingerprint.exception
@@ -143,10 +158,11 @@ object SpoofSignaturePatch : BytecodePatch(
.getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA
it.mutableMethod.addInstructions(
moveOriginalRecommendedValueIndex + 1, """
moveOriginalRecommendedValueIndex + 1,
"""
invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I
move-result v$originalValueRegister
"""
""",
)
} ?: throw StoryboardRendererDecoderRecommendedLevelFingerprint.exception
@@ -158,10 +174,11 @@ object SpoofSignaturePatch : BytecodePatch(
getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA
addInstructions(
moveOriginalRecommendedValueIndex, """
moveOriginalRecommendedValueIndex,
"""
invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I
move-result v$originalValueRegister
"""
""",
)
}
} ?: throw PlayerResponseModelImplRecommendedLevelFingerprint.exception
@@ -177,7 +194,7 @@ object SpoofSignaturePatch : BytecodePatch(
invoke-static { p$storyBoardUrlParams }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String;
move-result-object p$storyBoardUrlParams
""",
ExternalLabel("ignore", getInstruction(0))
ExternalLabel("ignore", getInstruction(0)),
)
}
} ?: throw StoryboardRendererSpecFingerprint.exception
@@ -189,11 +206,43 @@ object SpoofSignaturePatch : BytecodePatch(
it.mutableMethod.getInstruction<OneRegisterInstruction>(storyBoardUrlIndex).registerA
it.mutableMethod.addInstructions(
storyBoardUrlIndex + 1, """
storyBoardUrlIndex + 1,
"""
invoke-static { v$storyboardUrlRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardDecoderRendererSpec(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$storyboardUrlRegister
"""
""",
)
} ?: throw StoryboardRendererDecoderSpecFingerprint.exception
// Fix stats not being tracked.
// Due to signature spoofing "adformat" is present in query parameters made for /stats requests,
// even though, for regular videos, it should not be.
// This breaks stats tracking.
// Replace the ad parameter with the video parameter in the query parameters.
StatsQueryParameterFingerprint.result?.let {
val putMethod = ParamsMapPutFingerprint.result?.method?.toString()
?: throw ParamsMapPutFingerprint.exception
it.mutableMethod.apply {
val adParamIndex = it.scanResult.stringsScanResult!!.matches.first().index
val videoParamIndex = adParamIndex + 3
// Replace the ad parameter with the video parameter.
replaceInstruction(adParamIndex, getInstruction(videoParamIndex))
// Call paramsMap.put instead of paramsMap.putIfNotExist
// because the key is already present in the map.
val putAdParamIndex = adParamIndex + 1
val putIfKeyNotExistsInstruction = getInstruction<FiveRegisterInstruction>(putAdParamIndex)
replaceInstruction(
putAdParamIndex,
"invoke-virtual { " +
"v${putIfKeyNotExistsInstruction.registerC}, " +
"v${putIfKeyNotExistsInstruction.registerD}, " +
"v${putIfKeyNotExistsInstruction.registerE} }, " +
putMethod,
)
}
} ?: throw StatsQueryParameterFingerprint.exception
}
}

View File

@@ -0,0 +1,24 @@
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal object ParamsMapPutFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(
"Ljava/lang/String;",
"Ljava/lang/String;",
),
opcodes = listOf(
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.MOVE_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.INVOKE_DIRECT_RANGE,
),
)

View File

@@ -0,0 +1,7 @@
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object StatsQueryParameterFingerprint : MethodFingerprint(
strings = listOf("adunit"),
)

View File

@@ -44,7 +44,9 @@ object BypassURLRedirectsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.MISC.addPreferences(SwitchPreference("revanced_bypass_url_redirects" ))
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference("revanced_bypass_url_redirects")
)
mapOf(
ABUriParserFingerprint to 7, // Offset to Uri.parse.

View File

@@ -71,7 +71,9 @@ object OpenLinksExternallyPatch : BaseTransformInstructionsPatch<Pair<Int, Int>>
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.MISC.addPreferences(SwitchPreference("revanced_external_browser"))
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference("revanced_external_browser")
)
super.execute(context)
}

View File

@@ -61,13 +61,7 @@ object MinimizedPlaybackPatch : BytecodePatch(
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.MISC.addPreferences(
NonInteractivePreference(
"revanced_minimized_playback_enabled",
"revanced_minimized_playback_summary_on",
// Use horizontal dividers to keep the settings from looking weird.
// If PreferenceCategories are added, then this should be removed.
selectable = true
)
NonInteractivePreference("revanced_minimized_playback")
)
MinimizedPlaybackManagerFingerprint.result?.apply {

View File

@@ -3,30 +3,31 @@ package app.revanced.patches.youtube.misc.playeroverlay
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.playeroverlay.fingerprint.PlayerOverlaysOnFinishInflateFingerprint
import app.revanced.util.exception
@Patch(
description = "Hook for adding custom overlays to the video player.",
description = "Hook for the video player overlay",
dependencies = [IntegrationsPatch::class],
compatiblePackages = [
CompatiblePackage("com.google.android.youtube", [
"18.32.39"
])
]
)
/**
* Edit: This patch is not in use and may not work.
*/
@Suppress("unused")
object PlayerOverlaysHookPatch : BytecodePatch( // TODO: delete this unused outdated patch and its integration code.
object PlayerOverlaysHookPatch : BytecodePatch(
setOf(PlayerOverlaysOnFinishInflateFingerprint)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/PlayerOverlaysHookPatch;"
override fun execute(context: BytecodeContext) {
// hook YouTubePlayerOverlaysLayout.onFinishInflate()
val method = PlayerOverlaysOnFinishInflateFingerprint.result!!.mutableMethod
method.addInstruction(
method.implementation!!.instructions.size - 2,
"invoke-static { p0 }, Lapp/revanced/integrations/youtube/patches/PlayerOverlaysHookPatch;->YouTubePlayerOverlaysLayout_onFinishInflateHook(Ljava/lang/Object;)V"
)
PlayerOverlaysOnFinishInflateFingerprint.result?.mutableMethod?.apply {
addInstruction(
implementation!!.instructions.lastIndex,
"invoke-static { p0 }, $INTEGRATIONS_CLASS_DESCRIPTOR->playerOverlayInflated(Landroid/view/ViewGroup;)V"
)
} ?: throw PlayerOverlaysOnFinishInflateFingerprint.exception
}
}

View File

@@ -1,10 +1,14 @@
package app.revanced.patches.youtube.misc.playeroverlay.fingerprint
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object PlayerOverlaysOnFinishInflateFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("YouTubePlayerOverlaysLayout;") && methodDef.name == "onFinishInflate"
}
methodDef.definingClass.endsWith("/YouTubePlayerOverlaysLayout;")
&& methodDef.name == "onFinishInflate"
},
)

View File

@@ -51,7 +51,9 @@ object RemoveTrackingQueryParameterPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.MISC.addPreferences(SwitchPreference("revanced_remove_tracking_query_parameter"))
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference("revanced_remove_tracking_query_parameter")
)
fun MethodFingerprint.hook(
getInsertIndex: PatternScanResult.() -> Int,

View File

@@ -9,10 +9,11 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.packagename.ChangePackageNamePatch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.InputType
import app.revanced.patches.shared.misc.settings.preference.IntentPreference
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.fingerprints.LicenseActivityOnCreateFingerprint
import app.revanced.patches.youtube.misc.settings.fingerprints.SetThemeFingerprint
@@ -27,12 +28,14 @@ import java.io.Closeable
dependencies = [
IntegrationsPatch::class,
SettingsResourcePatch::class,
AddResourcesPatch::class
]
AddResourcesPatch::class,
],
)
object SettingsPatch : BytecodePatch(
setOf(LicenseActivityOnCreateFingerprint, SetThemeFingerprint)
), Closeable {
object SettingsPatch :
BytecodePatch(
setOf(LicenseActivityOnCreateFingerprint, SetThemeFingerprint),
),
Closeable {
private const val INTEGRATIONS_PACKAGE = "app/revanced/integrations/youtube"
private const val ACTIVITY_HOOK_CLASS_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/settings/LicenseActivityHook;"
@@ -48,8 +51,8 @@ object SettingsPatch : BytecodePatch(
titleKey = "revanced_pref_import_export_title",
summaryKey = "revanced_pref_import_export_summary",
inputType = InputType.TEXT_MULTI_LINE,
tag = "app.revanced.integrations.shared.settings.preference.ImportExportPreference"
)
tag = "app.revanced.integrations.shared.settings.preference.ImportExportPreference",
),
)
SetThemeFingerprint.result?.mutableMethod?.let { setThemeMethod ->
@@ -66,7 +69,7 @@ object SettingsPatch : BytecodePatch(
replaceInstruction(
returnIndex,
"invoke-static { v$register }, " +
"$THEME_HELPER_DESCRIPTOR->$SET_THEME_METHOD_NAME(Ljava/lang/Object;)V"
"$THEME_HELPER_DESCRIPTOR->$SET_THEME_METHOD_NAME(Ljava/lang/Object;)V",
)
addInstruction(returnIndex + 1, "return-object v$register")
}
@@ -82,7 +85,7 @@ object SettingsPatch : BytecodePatch(
"""
invoke-static { p0 }, $ACTIVITY_HOOK_CLASS_DESCRIPTOR->initialize(Landroid/app/Activity;)V
return-void
"""
""",
)
// Remove other methods as they will break as the onCreate method is modified above.
@@ -97,18 +100,67 @@ object SettingsPatch : BytecodePatch(
*/
fun newIntent(settingsName: String) = IntentPreference.Intent(
data = settingsName,
targetClass = "com.google.android.libraries.social.licenses.LicenseActivity"
targetClass = "com.google.android.libraries.social.licenses.LicenseActivity",
) {
// The package name change has to be reflected in the intent.
ChangePackageNamePatch.setOrGetFallbackPackageName("com.google.android.youtube")
}
object PreferenceScreen : BasePreferenceScreen() {
val ADS = Screen("revanced_ads_screen")
val INTERACTIONS = Screen("revanced_interactions_screen")
val LAYOUT = Screen("revanced_layout_screen")
val VIDEO = Screen("revanced_video_screen")
val MISC = Screen("revanced_misc_screen")
// Sort screens in the root menu by key, to not scatter related items apart
// (sorting key is set in revanced_prefs.xml).
// If no preferences are added to a screen, the screen will not be added to the settings.
val ADS = Screen(
key = "revanced_settings_screen_01_ads",
summaryKey = null,
)
val ALTERNATIVE_THUMBNAILS = Screen(
key = "revanced_settings_screen_02_alt_thumbnails",
summaryKey = null,
sorting = Sorting.UNSORTED,
)
val FEED = Screen(
key = "revanced_settings_screen_03_feed",
summaryKey = null,
)
val PLAYER = Screen(
key = "revanced_settings_screen_04_player",
summaryKey = null,
)
val GENERAL_LAYOUT = Screen(
key = "revanced_settings_screen_05_general",
summaryKey = null,
)
// Don't sort, as related preferences are scattered apart.
// Can use title sorting after PreferenceCategory support is added.
val SHORTS = Screen(
key = "revanced_settings_screen_06_shorts",
summaryKey = null,
sorting = Sorting.UNSORTED,
)
// Don't sort, because title sorting scatters the custom color preferences.
val SEEKBAR = Screen(
key = "revanced_settings_screen_07_seekbar",
summaryKey = null,
sorting = Sorting.UNSORTED,
)
val SWIPE_CONTROLS = Screen(
key = "revanced_settings_screen_08_swipe_controls",
summaryKey = null,
sorting = Sorting.UNSORTED,
)
// RYD and SB are items 9 and 10.
// Menus are added in their own patch because they use an Intent and not a Screen.
val MISC = Screen(
key = "revanced_settings_screen_11_misc",
summaryKey = null,
)
val VIDEO = Screen(
key = "revanced_settings_screen_12_video",
summaryKey = null,
)
override fun commit(screen: app.revanced.patches.shared.misc.settings.preference.PreferenceScreen) {
SettingsResourcePatch += screen

View File

@@ -1,6 +1,7 @@
package app.revanced.patches.youtube.misc.settings
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.BaseSettingsResourcePatch
@@ -11,7 +12,8 @@ import org.w3c.dom.Element
object SettingsResourcePatch : BaseSettingsResourcePatch(
IntentPreference(
"revanced_settings",
titleKey = "revanced_settings_title",
summaryKey = null,
intent = SettingsPatch.newIntent("revanced_settings_intent"),
) to "settings_fragment",
dependencies =
@@ -40,12 +42,29 @@ object SettingsResourcePatch : BaseSettingsResourcePatch(
context.copyResources("settings", resourceGroup)
}
// Remove horizontal divider from the settings Preferences
// To better match the appearance of the stock YouTube settings.
context.xmlEditor["res/values/styles.xml"].use { editor ->
val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element
for (i in 0 until resourcesNode.childNodes.length) {
val node = resourcesNode.childNodes.item(i) as? Element ?: continue
val name = node.getAttribute("name")
if (name == "Theme.YouTube.Settings" || name == "Theme.YouTube.Settings.Dark") {
val listDividerNode = editor.file.createElement("item")
listDividerNode.setAttribute("name", "android:listDivider")
listDividerNode.appendChild(editor.file.createTextNode("@null"))
node.appendChild(listDividerNode)
}
}
}
// Modify the manifest and add a data intent filter to the LicenseActivity.
// Some devices freak out if undeclared data is passed to an intent,
// and this change appears to fix the issue.
var modifiedIntent = false
context.xmlEditor["AndroidManifest.xml"].use { editor ->
val document = editor.file
// A xml regular-expression would probably work better than this manual searching.
val manifestNodes = document.getElementsByTagName("manifest").item(0).childNodes
for (i in 0..manifestNodes.length) {
@@ -62,11 +81,14 @@ object SettingsResourcePatch : BaseSettingsResourcePatch(
mimeType.setAttribute("android:mimeType", "text/plain")
intentFilter.appendChild(mimeType)
applicationChild.appendChild(intentFilter)
modifiedIntent = true
break
}
}
}
}
}
if (!modifiedIntent) throw PatchException("Could not modify activity intent")
}
}

View File

@@ -25,7 +25,9 @@ object ZoomHapticsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.MISC.addPreferences(SwitchPreference("revanced_disable_zoom_haptics"))
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference("revanced_disable_zoom_haptics")
)
val zoomHapticsFingerprintMethod = ZoomHapticsFingerprint.result!!.mutableMethod

View File

@@ -45,7 +45,9 @@ object HDRBrightnessPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.VIDEO.addPreferences(SwitchPreference("revanced_hdr_auto_brightness"))
SettingsPatch.PreferenceScreen.VIDEO.addPreferences(
SwitchPreference("revanced_hdr_auto_brightness")
)
val method = HDRBrightnessFingerprint.result!!.mutableMethod

View File

@@ -1,6 +1,5 @@
package app.revanced.patches.youtubevanced.ad.general
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
@@ -9,17 +8,19 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.misc.fix.verticalscroll.VerticalScrollPatch
import app.revanced.patches.youtubevanced.ad.general.fingerprints.ContainsAdFingerprint
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
@Deprecated("This patch is going to be removed in the future.")
@Patch(
name = "Hide ads",
description = "Removes general ads.",
dependencies = [VerticalScrollPatch::class],
compatiblePackages = [CompatiblePackage("com.vanced.android.youtube")]
compatiblePackages = [CompatiblePackage("com.vanced.android.youtube")],
use = false,
)
@Suppress("unused")
object HideAdsPatch : BytecodePatch(
setOf(ContainsAdFingerprint)
setOf(ContainsAdFingerprint),
) {
override fun execute(context: BytecodeContext) {
ContainsAdFingerprint.result?.let { result ->
@@ -40,14 +41,14 @@ object HideAdsPatch : BytecodePatch(
"hero_promo_image",
"statement_banner",
"primetime_promo",
"carousel_footered_layout"
"carousel_footered_layout",
).forEach { component ->
addInstructions(
insertIndex,
"""
const-string v$adsListRegister, "$component"
invoke-interface {v0, v$adsListRegister}, Ljava/util/List;->add(Ljava/lang/Object;)Z
"""
""",
)
}
}

View File

@@ -15,6 +15,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
import com.android.tools.smali.dexlib2.iface.reference.Reference
import com.android.tools.smali.dexlib2.util.MethodUtil
fun MethodFingerprint.resultOrThrow() = result ?: throw exception
/**
* The [PatchException] of failing to resolve a [MethodFingerprint].
*

View File

@@ -7,15 +7,13 @@
<item>@string/revanced_spoof_app_version_target_entry_3</item>
<item>@string/revanced_spoof_app_version_target_entry_4</item>
<item>@string/revanced_spoof_app_version_target_entry_5</item>
<item>@string/revanced_spoof_app_version_target_entry_6</item>
</string-array>
<string-array name="revanced_spoof_app_version_target_entry_values">
<item>18.33.40</item>
<item>18.20.39</item>
<item>18.09.39</item>
<item>17.08.35</item>
<item>16.08.35</item>
<item>16.01.35</item>
<item>17.41.37</item>
<item>17.33.42</item>
</string-array>
</patch>
<patch id="layout.startpage.ChangeStartPagePatch">

View File

@@ -18,37 +18,29 @@
</patch>
</app>
<app id="youtube">
<patch id="layout.thumbnails.AlternativeThumbnailsResourcePatch">
<string name="revanced_alt_thumbnail_about_status_disabled">Showing original YouTube thumbnails</string>
<string name="revanced_alt_thumbnail_about_status_stills">Showing still video captures</string>
<string name="revanced_alt_thumbnail_about_status_dearrow">Showing DeArrow thumbnails. If a video has no DeArrow thumbnails then the original YouTube thumbnails are shown</string>
<string name="revanced_alt_thumbnail_about_status_dearrow_stills">Showing DeArrow thumbnails. If a video has no DeArrow thumbnails then still video captures are shown</string>
<string name="revanced_alt_thumbnail_dearrow_error">DeArrow temporarily not available (status code: %s)</string>
<string name="revanced_alt_thumbnail_dearrow_error_generic">DeArrow temporarily not available</string>
</patch>
<patch id="misc.settings.SettingsResourcePatch">
<string name="revanced_settings">ReVanced</string>
<string name="revanced_settings_summary">ReVanced specific settings</string>
<string name="revanced_pref_import_export_title">Import / Export</string>
<string name="revanced_pref_import_export_summary">Import / Export ReVanced settings</string>
</patch>
<patch id="misc.settings.SettingsPatch">
<string name="revanced_ads_screen_title">Ads</string>
<string name="revanced_ads_screen_summary">Ad related settings</string>
<string name="revanced_interactions_screen_title">Interactions</string>
<string name="revanced_interactions_screen_summary">Settings related to interactions</string>
<string name="revanced_layout_screen_title">Layout</string>
<string name="revanced_layout_screen_summary">Settings related to the layout</string>
<string name="revanced_video_screen_title">Video</string>
<string name="revanced_video_screen_summary">Settings related to the video player</string>
<string name="revanced_misc_screen_title">Misc</string>
<string name="revanced_misc_screen_summary">Miscellaneous patches</string>
<string name="revanced_settings_screen_01_ads_title">Ads</string>
<string name="revanced_settings_screen_02_alt_thumbnails_title">Alternative thumbnails</string>
<string name="revanced_settings_screen_03_feed_title">Feed</string>
<string name="revanced_settings_screen_04_player_title">Player</string>
<string name="revanced_settings_screen_05_general_title">General layout</string>
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
<string name="revanced_settings_screen_07_seekbar_title">Seekbar</string>
<string name="revanced_settings_screen_08_swipe_controls_title">Swipe controls</string>
<string name="revanced_settings_screen_11_misc_title">Misc</string>
<string name="revanced_settings_screen_12_video_title">Video</string>
</patch>
<patch id="misc.debugging.DebuggingPatch">
<string name="revanced_debug_screen_title">Debugging</string>
<string name="revanced_debug_screen_summary">Enable or disable debugging options</string>
<string name="revanced_debug_title">Debug logging</string>
<string name="revanced_debug_summary_on">Debug logs are enabled</string>
<string name="revanced_debug_summary_off">Debug logs are disabled</string>
<string name="revanced_debug_preference_screen_title">Debugging</string>
<string name="revanced_debug_protobuffer_title">Log protocol buffer</string>
<string name="revanced_debug_protobuffer_summary_on">Debug logs include proto buffer</string>
<string name="revanced_debug_protobuffer_summary_off">Debug logs do not include proto buffer</string>
@@ -59,18 +51,15 @@
<string name="revanced_debug_toast_on_error_summary_on">Toast shown if error occurs</string>
<string name="revanced_debug_toast_on_error_summary_off">Toast not shown if error occurs</string>
<string name="revanced_debug_toast_on_error_user_dialog_message">Turning off error toasts hides all ReVanced error notifications.\n\nYou will not be notified of any unexpected events.</string>
<string name="revanced_debug_preference_screen_summary">Enable or disable debugging options</string>
</patch>
<patch id="layout.hide.general.HideLayoutComponentsPatch">
<string name="ads_title">Ads</string>
<string name="ads_summary">Ad related settings</string>
<string name="revanced_hide_gray_separator_title">Hide gray separator</string>
<string name="revanced_hide_gray_separator_summary_on">Gray separators are hidden</string>
<string name="revanced_hide_gray_separator_summary_off">Gray separators are shown</string>
<string name="revanced_hide_join_membership_button_title">Hide \'Join\' button</string>
<string name="revanced_hide_join_membership_button_summary_on">Button is hidden</string>
<string name="revanced_hide_join_membership_button_summary_off">Button is shown</string>
<string name="revanced_hide_channel_watermark_title">Hide channel watermark in video player</string>
<string name="revanced_hide_channel_watermark_title">Hide channel watermark</string>
<string name="revanced_hide_channel_watermark_summary_on">Watermark is hidden</string>
<string name="revanced_hide_channel_watermark_summary_off">Watermark is shown</string>
<string name="revanced_hide_for_you_shelf_title">Hide \'For you\' shelf in channel page</string>
@@ -97,9 +86,6 @@
<string name="revanced_hide_video_quality_menu_footer_title">Hide video quality menu footer</string>
<string name="revanced_hide_video_quality_menu_footer_summary_on">Video quality menu footer is hidden</string>
<string name="revanced_hide_video_quality_menu_footer_summary_off">Video quality menu footer is shown</string>
<string name="revanced_hide_chapters_title">Hide chapters in the video description</string>
<string name="revanced_hide_chapters_summary_on">Chapters are hidden</string>
<string name="revanced_hide_chapters_summary_off">Chapters are shown</string>
<string name="revanced_hide_community_posts_title">Hide community posts</string>
<string name="revanced_hide_community_posts_summary_on">Community posts are hidden</string>
<string name="revanced_hide_community_posts_summary_off">Community posts are shown</string>
@@ -154,10 +140,12 @@
<string name="revanced_hide_chips_shelf_title">Hide chips shelf</string>
<string name="revanced_hide_chips_shelf_summary_on">Chips shelf is hidden</string>
<string name="revanced_hide_chips_shelf_summary_off">Chips shelf is shown</string>
<string name="revanced_hide_description_components_preference_screen_title">Hide components in the video description</string>
<string name="revanced_hide_info_cards_section_title">Hide info cards section</string>
<string name="revanced_hide_info_cards_section_summary_on">Info cards section is hidden</string>
<string name="revanced_hide_info_cards_section_summary_off">Info cards section is shown</string>
<string name="revanced_hide_chapters_title">Hide chapters</string>
<string name="revanced_hide_chapters_summary_on">Chapters are hidden</string>
<string name="revanced_hide_chapters_summary_off">Chapters are shown</string>
<string name="revanced_hide_game_section_title">Hide game section</string>
<string name="revanced_hide_game_section_summary_on">Game section is hidden</string>
<string name="revanced_hide_game_section_summary_off">Game section is shown</string>
@@ -170,14 +158,15 @@
<string name="revanced_hide_transcript_section_title">Hide transcript section</string>
<string name="revanced_hide_transcript_section_summary_on">Transcript section is hidden</string>
<string name="revanced_hide_transcript_section_summary_off">Transcript section is shown</string>
<string name="revanced_hide_description_components_preference_screen_summary">Hide components under the video description</string>
<string name="revanced_custom_filter_preference_screen_title">Custom filter</string>
<string name="revanced_hide_description_components_screen_title">Video description</string>
<string name="revanced_hide_description_components_screen_summary">Hide or show video description components</string>
<string name="revanced_custom_filter_screen_title">Custom filter</string>
<string name="revanced_custom_filter_screen_summary">Hide components using custom filters</string>
<string name="revanced_custom_filter_title">Enable custom filter</string>
<string name="revanced_custom_filter_summary_on">Custom filter is enabled</string>
<string name="revanced_custom_filter_summary_off">Custom filter is disabled</string>
<string name="revanced_custom_filter_strings_title">Custom filter</string>
<string name="revanced_custom_filter_strings_summary">List of component path builder strings to filter separated by new line</string>
<string name="revanced_custom_filter_preference_screen_summary">Hide components using custom filters</string>
<string name="revanced_custom_filter_toast_invalid_characters">Invalid custom filter (must be ASCII only): %s</string>
<string name="revanced_custom_filter_toast_invalid_syntax">Invalid custom filter: %s</string>
<string name="revanced_custom_filter_toast_reset">Custom filter reset to default</string>
@@ -224,14 +213,12 @@
<patch id="interaction.copyvideourl.CopyVideoUrlResourcePatch">
<string name="revanced_share_copy_url_success">URL copied to clipboard</string>
<string name="revanced_share_copy_url_timestamp_success">URL with timestamp copied</string>
<string name="revanced_copy_video_url_preference_screen_title">Copy video URL settings</string>
<string name="revanced_copy_video_url_title">Show copy video URL button</string>
<string name="revanced_copy_video_url_summary_on">Button is shown. Tap to copy video URL. Tap and hold to copy video URL with timestamp</string>
<string name="revanced_copy_video_url_summary_off">Button is not shown</string>
<string name="revanced_copy_video_url_timestamp_title">Show copy timestamp URL button</string>
<string name="revanced_copy_video_url_timestamp_summary_on">Button is shown. Tap to copy video URL with timestamp. Tap and hold to copy video without timestamp</string>
<string name="revanced_copy_video_url_timestamp_summary_off">Button is not shown</string>
<string name="revanced_copy_video_url_preference_screen_summary">Settings related to copy URL buttons in video player</string>
</patch>
<patch id="interaction.dialog.RemoveViewerDiscretionDialogPatch">
<string name="revanced_remove_viewer_discretion_dialog_title">Remove viewer discretion dialog</string>
@@ -239,15 +226,18 @@
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Dialog will be shown</string>
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">This does not bypass the age restriction. It just accepts it automatically.</string>
</patch>
<patch id="interaction.downloads.ExternalDownloadsResourcePatch">
<string name="revanced_external_downloader_not_installed_warning">%s is not installed. Please install it.</string>
<string name="revanced_external_downloader_preference_screen_title">External download settings</string>
<patch id="interaction.downloads.DownloadsResourcePatch">
<string name="revanced_external_downloader_screen_title">External downloads</string>
<string name="revanced_external_downloader_screen_summary">Settings for using an external downloader</string>
<string name="revanced_external_downloader_title">Show external download button</string>
<string name="revanced_external_downloader_summary_on">Download button shown in player</string>
<string name="revanced_external_downloader_summary_off">Download button not shown in player</string>
<string name="revanced_external_downloader_action_button_title">Override download action button</string>
<string name="revanced_external_downloader_action_button_summary_on">Download button opens your external downloader</string>
<string name="revanced_external_downloader_action_button_summary_off">Download button opens the native in-app downloader</string>
<string name="revanced_external_downloader_name_title">Downloader package name</string>
<string name="revanced_external_downloader_name_summary">Package name of your installed external downloader app, such as NewPipe or Seal</string>
<string name="revanced_external_downloader_preference_screen_summary">Settings for using an external downloader</string>
<string name="revanced_external_downloader_not_installed_warning">%s is not installed. Please install it.</string>
</patch>
<patch id="interaction.seekbar.DisablePreciseSeekingGesturePatch">
<string name="revanced_disable_precise_seeking_gesture_title">Disable precise seeking gesture</string>
@@ -260,7 +250,6 @@
<string name="revanced_seekbar_tapping_summary_off">Seekbar tapping is disabled</string>
</patch>
<patch id="interaction.swipecontrols.SwipeControlsResourcePatch">
<string name="revanced_swipe_controls_preference_screen_title">Swipe controls</string>
<string name="revanced_swipe_brightness_title">Enable brightness gesture</string>
<string name="revanced_swipe_brightness_summary_on">Brightness swipe is enabled</string>
<string name="revanced_swipe_brightness_summary_off">Brightness swipe is disabled</string>
@@ -284,7 +273,6 @@
<string name="revanced_swipe_overlay_background_alpha_summary">The visibility of swipe overlay background</string>
<string name="revanced_swipe_threshold_title">Swipe magnitude threshold</string>
<string name="revanced_swipe_threshold_summary">The amount of threshold for swipe to occur</string>
<string name="revanced_swipe_controls_preference_screen_summary">Control volume and brightness</string>
</patch>
<patch id="layout.autocaptions.AutoCaptionsPatch">
<string name="revanced_auto_captions_title">Disable auto captions</string>
@@ -292,38 +280,35 @@
<string name="revanced_auto_captions_summary_off">Auto captions are enabled</string>
</patch>
<patch id="layout.buttons.action.HideButtonsPatch">
<string name="revanced_hide_buttons_preference_screen_title">Hide action buttons</string>
<string name="revanced_hide_like_dislike_button_title">Hide like and dislike buttons</string>
<string name="revanced_hide_like_dislike_button_summary_on">Like and dislike buttons are hidden</string>
<string name="revanced_hide_like_dislike_button_summary_off">Like and dislike buttons are shown</string>
<string name="revanced_hide_live_chat_button_title">Hide live chat button</string>
<string name="revanced_hide_live_chat_button_summary_on">Live chat button is hidden</string>
<string name="revanced_hide_live_chat_button_summary_off">Live chat button is shown</string>
<string name="revanced_hide_share_button_title">Hide share button</string>
<string name="revanced_hide_buttons_screen_title">Action buttons</string>
<string name="revanced_hide_buttons_screen_summary">Hide or show buttons under videos</string>
<string name="revanced_hide_like_dislike_button_title">Hide Like and Dislike</string>
<string name="revanced_hide_like_dislike_button_summary_on">Like and Dislike buttons are hidden</string>
<string name="revanced_hide_like_dislike_button_summary_off">Like and Dislike buttons are shown</string>
<string name="revanced_hide_share_button_title">Hide Share</string>
<string name="revanced_hide_share_button_summary_on">Share button is hidden</string>
<string name="revanced_hide_share_button_summary_off">Share button is shown</string>
<string name="revanced_hide_report_button_title">Hide report button</string>
<string name="revanced_hide_report_button_title">Hide Report</string>
<string name="revanced_hide_report_button_summary_on">Report button is hidden</string>
<string name="revanced_hide_report_button_summary_off">Report button is shown</string>
<string name="revanced_hide_remix_button_title">Hide remix button</string>
<string name="revanced_hide_remix_button_title">Hide Remix</string>
<string name="revanced_hide_remix_button_summary_on">Remix button is hidden</string>
<string name="revanced_hide_remix_button_summary_off">Remix button is shown</string>
<string name="revanced_hide_download_button_title">Hide download button</string>
<string name="revanced_hide_download_button_title">Hide Download</string>
<string name="revanced_hide_download_button_summary_on">Download button is hidden</string>
<string name="revanced_hide_download_button_summary_off">Download button is shown</string>
<string name="revanced_hide_thanks_button_title">Hide thanks button</string>
<string name="revanced_hide_thanks_button_title">Hide Thanks</string>
<string name="revanced_hide_thanks_button_summary_on">Thanks button is hidden</string>
<string name="revanced_hide_thanks_button_summary_off">Thanks button is shown</string>
<string name="revanced_hide_clip_button_title">Hide clip button</string>
<string name="revanced_hide_clip_button_title">Hide Clip</string>
<string name="revanced_hide_clip_button_summary_on">Clip button is hidden</string>
<string name="revanced_hide_clip_button_summary_off">Clip button is shown</string>
<string name="revanced_hide_playlist_button_title">Hide save to playlist button</string>
<string name="revanced_hide_playlist_button_summary_on">Save button is hidden</string>
<string name="revanced_hide_playlist_button_summary_off">Save button is shown</string>
<string name="revanced_hide_shop_button_title">Hide shop button</string>
<string name="revanced_hide_playlist_button_title">Hide Save to playlist</string>
<string name="revanced_hide_playlist_button_summary_on">Save to playlist button is hidden</string>
<string name="revanced_hide_playlist_button_summary_off">Save to playlist button is shown</string>
<string name="revanced_hide_shop_button_title">Hide Shop</string>
<string name="revanced_hide_shop_button_summary_on">Shop button is hidden</string>
<string name="revanced_hide_shop_button_summary_off">Shop button is shown</string>
<string name="revanced_hide_buttons_preference_screen_summary">Hide or show buttons under videos</string>
</patch>
<patch id="layout.buttons.autoplay.HideAutoplayButtonPatch">
<string name="revanced_hide_autoplay_button_title">Hide autoplay button</string>
@@ -341,57 +326,57 @@
<string name="revanced_hide_cast_button_summary_off">Cast button is shown</string>
</patch>
<patch id="layout.buttons.navigation.NavigationButtonsPatch">
<string name="revanced_navigation_buttons_preference_screen_title">Navigation buttons</string>
<string name="revanced_hide_home_button_title">Hide home button</string>
<string name="revanced_navigation_buttons_screen_title">Navigation buttons</string>
<string name="revanced_navigation_buttons_screen_summary">Hide or change buttons in the navigation bar</string>
<string name="revanced_hide_home_button_title">Hide Home</string>
<string name="revanced_hide_home_button_summary_on">Home button is hidden</string>
<string name="revanced_hide_home_button_summary_off">Home button is shown</string>
<string name="revanced_hide_shorts_button_title">Hide Shorts button</string>
<string name="revanced_hide_shorts_button_title">Hide Shorts</string>
<string name="revanced_hide_shorts_button_summary_on">Shorts button is hidden</string>
<string name="revanced_hide_shorts_button_summary_off">Shorts button is shown</string>
<string name="revanced_hide_subscriptions_button_title">Hide subscriptions button</string>
<string name="revanced_hide_subscriptions_button_summary_on">Home subscriptions is hidden</string>
<string name="revanced_hide_subscriptions_button_summary_off">Home subscriptions is shown</string>
<string name="revanced_hide_create_button_title">Hide create button</string>
<string name="revanced_hide_create_button_title">Hide Create</string>
<string name="revanced_hide_create_button_summary_on">Create button is hidden</string>
<string name="revanced_hide_create_button_summary_off">Create button is shown</string>
<string name="revanced_switch_create_with_notifications_button_title">Switch create with notifications button</string>
<string name="revanced_switch_create_with_notifications_button_summary_on">Create button is switched with notifications</string>
<string name="revanced_switch_create_with_notifications_button_summary_off">Create button is not switched with notifications</string>
<string name="revanced_navigation_buttons_preference_screen_summary">Hide or change buttons in the navigation bar</string>
<string name="revanced_hide_subscriptions_button_title">Hide Subscriptions</string>
<string name="revanced_hide_subscriptions_button_summary_on">Subscriptions button is hidden</string>
<string name="revanced_hide_subscriptions_button_summary_off">Subscriptions button is shown</string>
<string name="revanced_switch_create_with_notifications_button_title">Switch Create with Notifications</string>
<string name="revanced_switch_create_with_notifications_button_summary_on">Create button is switched with Notifications button</string>
<string name="revanced_switch_create_with_notifications_button_summary_off">Create button is not switched with Notifications button</string>
</patch>
<patch id="layout.hide.player.flyoutmenupanel.HidePlayerFlyoutMenuPatch">
<string name="revanced_hide_player_flyout_title">Player flyout menu items</string>
<string name="revanced_hide_player_flyout_summary">Manage the visibility of player flyout menu items</string>
<string name="revanced_hide_player_flyout_captions_title">Hide Captions menu</string>
<string name="revanced_hide_player_flyout_captions_summary_on">Captions menu item is hidden</string>
<string name="revanced_hide_player_flyout_captions_summary_off">Captions menu item is shown</string>
<string name="revanced_hide_player_flyout_additional_settings_title">Hide Additional settings menu</string>
<string name="revanced_hide_player_flyout_additional_settings_summary_on">Additional settings menu item is hidden</string>
<string name="revanced_hide_player_flyout_additional_settings_summary_off">Additional settings menu item is shown</string>
<string name="revanced_hide_player_flyout_loop_video_title">Hide Loop video menu</string>
<string name="revanced_hide_player_flyout_loop_video_summary_on">Loop video menu item is hidden</string>
<string name="revanced_hide_player_flyout_loop_video_summary_off">Loop video menu item is shown</string>
<string name="revanced_hide_player_flyout_ambient_mode_title">Hide Ambient mode menu</string>
<string name="revanced_hide_player_flyout_ambient_mode_summary_on">Ambient mode menu item is hidden</string>
<string name="revanced_hide_player_flyout_ambient_mode_summary_off">Ambient mode menu item is shown</string>
<string name="revanced_hide_player_flyout_report_title">Hide Report menu</string>
<string name="revanced_hide_player_flyout_report_summary_on">Report menu item is hidden</string>
<string name="revanced_hide_player_flyout_report_summary_off">Report menu item is shown</string>
<string name="revanced_hide_player_flyout_help_title">Hide Help menu</string>
<string name="revanced_hide_player_flyout_help_summary_on">Help menu item is hidden</string>
<string name="revanced_hide_player_flyout_help_summary_off">Help menu item is shown</string>
<string name="revanced_hide_player_flyout_speed_title">Hide Speed menu</string>
<string name="revanced_hide_player_flyout_speed_summary_on">Speed menu item is hidden</string>
<string name="revanced_hide_player_flyout_speed_summary_off">Speed menu item is shown</string>
<string name="revanced_hide_player_flyout_more_info_title">Hide More info menu</string>
<string name="revanced_hide_player_flyout_more_info_summary_on">More info menu item is hidden</string>
<string name="revanced_hide_player_flyout_more_info_summary_off">More info menu item is shown</string>
<string name="revanced_hide_player_flyout_audio_track_title">Hide Audio track menu</string>
<string name="revanced_hide_player_flyout_audio_track_summary_on">Audio track menu item is hidden</string>
<string name="revanced_hide_player_flyout_audio_track_summary_off">Audio track menu item is shown</string>
<string name="revanced_hide_player_flyout_watch_in_vr_title">Hide Watch in VR menu</string>
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Watch in VR menu item is hidden</string>
<string name="revanced_hide_player_flyout_watch_in_vr_summary_off">Watch in VR menu item is shown</string>
<string name="revanced_hide_player_flyout_title">Flyout menu</string>
<string name="revanced_hide_player_flyout_summary">Hide or show player flyout menu items</string>
<string name="revanced_hide_player_flyout_captions_title">Hide Captions</string>
<string name="revanced_hide_player_flyout_captions_summary_on">Captions menu is hidden</string>
<string name="revanced_hide_player_flyout_captions_summary_off">Captions menu is shown</string>
<string name="revanced_hide_player_flyout_additional_settings_title">Hide Additional settings</string>
<string name="revanced_hide_player_flyout_additional_settings_summary_on">Additional settings menu is hidden</string>
<string name="revanced_hide_player_flyout_additional_settings_summary_off">Additional settings menu is shown</string>
<string name="revanced_hide_player_flyout_loop_video_title">Hide Loop video</string>
<string name="revanced_hide_player_flyout_loop_video_summary_on">Loop video menu is hidden</string>
<string name="revanced_hide_player_flyout_loop_video_summary_off">Loop video menu is shown</string>
<string name="revanced_hide_player_flyout_ambient_mode_title">Hide Ambient mode</string>
<string name="revanced_hide_player_flyout_ambient_mode_summary_on">Ambient mode menu is hidden</string>
<string name="revanced_hide_player_flyout_ambient_mode_summary_off">Ambient mode menu is shown</string>
<string name="revanced_hide_player_flyout_report_title">Hide Report</string>
<string name="revanced_hide_player_flyout_report_summary_on">Report menu is hidden</string>
<string name="revanced_hide_player_flyout_report_summary_off">Report menu is shown</string>
<string name="revanced_hide_player_flyout_help_title">Hide Help &amp; feedback</string>
<string name="revanced_hide_player_flyout_help_summary_on">Help &amp; feedback menu is hidden</string>
<string name="revanced_hide_player_flyout_help_summary_off">Help &amp; feedback menu is shown</string>
<string name="revanced_hide_player_flyout_speed_title">Hide Playback speed</string>
<string name="revanced_hide_player_flyout_speed_summary_on">Playback speed menu is hidden</string>
<string name="revanced_hide_player_flyout_speed_summary_off">Playback speed menu is shown</string>
<string name="revanced_hide_player_flyout_more_info_title">Hide More info</string>
<string name="revanced_hide_player_flyout_more_info_summary_on">More info menu is hidden</string>
<string name="revanced_hide_player_flyout_more_info_summary_off">More info menu is shown</string>
<string name="revanced_hide_player_flyout_audio_track_title">Hide Audio track</string>
<string name="revanced_hide_player_flyout_audio_track_summary_on">Audio track menu is hidden</string>
<string name="revanced_hide_player_flyout_audio_track_summary_off">Audio track menu is shown</string>
<string name="revanced_hide_player_flyout_watch_in_vr_title">Hide Watch in VR</string>
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Watch in VR menu is hidden</string>
<string name="revanced_hide_player_flyout_watch_in_vr_summary_off">Watch in VR menu is shown</string>
</patch>
<patch id="layout.buttons.player.hide.HidePlayerButtonsPatch">
<string name="revanced_hide_player_buttons_title">Hide previous &amp; next video buttons</string>
@@ -409,14 +394,14 @@
<string name="revanced_hide_breaking_news_summary_off">Breaking news are shown</string>
</patch>
<patch id="layout.hide.comments.CommentsPatch">
<string name="revanced_comments_preference_screen_title">Comments</string>
<string name="revanced_comments_screen_title">Comments</string>
<string name="revanced_comments_screen_summary">Hide or show comments section components</string>
<string name="revanced_hide_comments_section_title">Hide comments section</string>
<string name="revanced_hide_comments_section_summary_on">Comment section is hidden</string>
<string name="revanced_hide_comments_section_summary_off">Comment section is shown</string>
<string name="revanced_hide_preview_comment_title">Hide preview comment</string>
<string name="revanced_hide_preview_comment_summary_on">Preview comment is hidden</string>
<string name="revanced_hide_preview_comment_summary_off">Preview comment is shown</string>
<string name="revanced_comments_preference_screen_summary">Manage the visibility of comments section components</string>
</patch>
<patch id="layout.hide.crowdfundingbox.CrowdfundingBoxResourcePatch">
<string name="revanced_hide_crowdfunding_box_title">Hide crowdfunding box</string>
@@ -429,7 +414,8 @@
<string name="revanced_hide_endscreen_cards_summary_off">End screen cards are shown</string>
</patch>
<patch id="layout.hide.filterbar.HideFilterBarResourcePatch">
<string name="revanced_hide_filter_bar_preference_title">Hide filter bar</string>
<string name="revanced_hide_filter_bar_screen_title">Filter bar</string>
<string name="revanced_hide_filter_bar_screen_summary">Hide or show the filter bar in the feed, search, and related videos</string>
<string name="revanced_hide_filter_bar_feed_in_feed_title">Hide in feed</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_on">Hidden in feed</string>
<string name="revanced_hide_filter_bar_feed_in_feed_summary_off">Shown in feed</string>
@@ -439,7 +425,6 @@
<string name="revanced_hide_filter_bar_feed_in_related_videos_title">Hide in related videos</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_on">Hidden in related videos</string>
<string name="revanced_hide_filter_bar_feed_in_related_videos_summary_off">Shown in related videos</string>
<string name="revanced_hide_filter_bar_preference_summary">Manage the visibility of the filter bar in the feed, search and related videos</string>
</patch>
<patch id="layout.hide.floatingmicrophone.HideFloatingMicrophoneButtonResourcePatch">
<string name="revanced_hide_floating_microphone_button_title">Hide floating microphone button</string>
@@ -478,7 +463,6 @@
<string name="revanced_hide_seekbar_thumbnail_summary_off">Thumbnail seekbar is shown</string>
</patch>
<patch id="layout.hide.shorts.HideShortsComponentsResourcePatch">
<string name="revanced_shorts_preference_screen_title">Shorts components</string>
<string name="revanced_hide_shorts_title">Hide Shorts in feed</string>
<string name="revanced_hide_shorts_summary_on">Shorts are hidden</string>
<string name="revanced_hide_shorts_summary_off">Shorts are shown</string>
@@ -515,7 +499,6 @@
<string name="revanced_hide_shorts_navigation_bar_title">Hide navigation bar</string>
<string name="revanced_hide_shorts_navigation_bar_summary_on">Navigation bar is hidden</string>
<string name="revanced_hide_shorts_navigation_bar_summary_off">Navigation bar is shown</string>
<string name="revanced_shorts_preference_screen_summary">Manage the visibility of Shorts components</string>
</patch>
<patch id="layout.hide.suggestedvideoendscreen.DisableSuggestedVideoEndScreenResourcePatch">
<string name="revanced_disable_suggested_video_end_screen_title">Disable suggested video end screen</string>
@@ -538,7 +521,6 @@
</patch>
<patch id="layout.returnyoutubedislike.ReturnYouTubeDislikeResourcePatch">
<string name="revanced_ryd_settings_title">Return YouTube Dislike</string>
<string name="revanced_ryd_settings_summary">Settings for Return YouTube Dislike</string>
<string name="revanced_ryd_video_likes_hidden_by_video_owner">Hidden</string>
<string name="revanced_ryd_failure_connection_timeout">Dislikes temporarily not available (API timed out)</string>
<string name="revanced_ryd_failure_connection_status_code" formatted="false">Dislikes not available (status %d)</string>
@@ -594,13 +576,8 @@
<string name="revanced_restore_old_seekbar_thumbnails_summary_on">Seekbar thumbnails will appear above the seekbar</string>
<string name="revanced_restore_old_seekbar_thumbnails_summary_off">Seekbar thumbnails will appear in fullscreen</string>
</patch>
<patch id="layout.seekbar.SeekbarPreferencesPatch">
<string name="revanced_seekbar_preference_screen_title">Seekbar</string>
<string name="revanced_seekbar_preference_screen_summary">Settings for the seekbar</string>
</patch>
<patch id="layout.sponsorblock.SponsorBlockResourcePatch">
<string name="revanced_sb_settings_title">SponsorBlock</string>
<string name="revanced_sb_settings_summary">SponsorBlock related settings</string>
<string name="revanced_sb_enable_sb">Enable SponsorBlock</string>
<string name="revanced_sb_enable_sb_sum">SponsorBlock is a crowd-sourced system for skipping annoying parts of YouTube videos</string>
<string name="revanced_sb_appearance_category">Appearance</string>
@@ -783,12 +760,11 @@
<string name="revanced_spoof_app_version_summary_off">Version not spoofed</string>
<string name="revanced_spoof_app_version_user_dialog_message">App version will be spoofed to an older version of YouTube.\n\nThis will change the appearance and features of the app, but unknown side effects may occur.\n\nIf later turned off, it is recommended to clear the app data to prevent UI bugs.</string>
<string name="revanced_spoof_app_version_target_title">Spoof app version target</string>
<string name="revanced_spoof_app_version_target_entry_1">18.33.40 - Restore RYD Shorts incognito mode</string>
<string name="revanced_spoof_app_version_target_entry_1">18.33.40 - Restore RYD on Shorts incognito mode</string>
<string name="revanced_spoof_app_version_target_entry_2">18.20.39 - Restore wide video speed &amp; quality menu</string>
<string name="revanced_spoof_app_version_target_entry_3">18.09.39 - Restore library tab</string>
<string name="revanced_spoof_app_version_target_entry_4">17.08.35 - Restore old UI layout</string>
<string name="revanced_spoof_app_version_target_entry_5">16.08.35 - Restore explore tab</string>
<string name="revanced_spoof_app_version_target_entry_6">16.01.35 - Restore fewer video player action buttons</string>
<string name="revanced_spoof_app_version_target_entry_4">17.41.37 - Restore old playlist shelf</string>
<string name="revanced_spoof_app_version_target_entry_5">17.33.42 - Restore old UI layout</string>
</patch>
<patch id="layout.startpage.ChangeStartPagePatch">
<string name="revanced_start_page_title">Set start page</string>
@@ -834,7 +810,6 @@
<string name="revanced_seekbar_custom_color_invalid">Invalid seekbar color value. Using default value.</string>
</patch>
<patch id="layout.thumbnails.AlternativeThumbnailsPatch">
<string name="revanced_alt_thumbnail_preference_screen_title">Alternative thumbnails</string>
<string name="revanced_alt_thumbnail_about_title">Thumbnails in use</string>
<string name="revanced_alt_thumbnail_dearrow_title">Enable DeArrow thumbnails</string>
<string name="revanced_alt_thumbnail_dearrow_summary_on">Using DeArrow thumbnails</string>
@@ -858,7 +833,12 @@
<string name="revanced_alt_thumbnail_stills_fast_summary_off">Using high quality still captures</string>
<string name="revanced_alt_thumbnail_stills_about_title">About still video captures</string>
<string name="revanced_alt_thumbnail_stills_about_summary">Still captures are taken from the beginning/middle/end of each video. These images are built into YouTube and no external API is used</string>
<string name="revanced_alt_thumbnail_preference_screen_summary">Video thumbnail settings</string>
<string name="revanced_alt_thumbnail_about_status_disabled">Showing original YouTube thumbnails</string>
<string name="revanced_alt_thumbnail_about_status_stills">Showing still video captures</string>
<string name="revanced_alt_thumbnail_about_status_dearrow">Showing DeArrow thumbnails. If a video has no DeArrow thumbnails then the original YouTube thumbnails are shown</string>
<string name="revanced_alt_thumbnail_about_status_dearrow_stills">Showing DeArrow thumbnails. If a video has no DeArrow thumbnails then still video captures are shown</string>
<string name="revanced_alt_thumbnail_dearrow_error">DeArrow temporarily not available (status code: %s)</string>
<string name="revanced_alt_thumbnail_dearrow_error_generic">DeArrow temporarily not available</string>
</patch>
<patch id="misc.announcements.AnnouncementsPatch">
<string name="revanced_announcements_title">Show ReVanced announcements</string>
@@ -878,7 +858,8 @@
<string name="revanced_spoof_device_dimensions_summary_off">Device dimensions not spoofed\n\nSpoofing the device dimensions can unlock higher video qualities but unknown side effects may occur</string>
</patch>
<patch id="misc.fix.playback.SpoofSignaturePatch">
<string name="revanced_spoof_signature_verification_title">Spoof app signature</string>
<string name="revanced_spoof_signature_verification_screen_title">Spoof app signature</string>
<string name="revanced_spoof_signature_verification_screen_summary">Spoof the app signature to prevent playback issues</string>
<string name="revanced_spoof_signature_verification_enabled_title">Spoof app signature</string>
<string name="revanced_spoof_signature_verification_enabled_summary_on">App signature spoofed\n\nSide effects include:\n• Enhanced bitrate is not available\n• Videos cannot be downloaded\n• No seekbar thumbnails for paid videos</string>
<string name="revanced_spoof_signature_verification_enabled_summary_off">App signature not spoofed\n\nVideo playback may not work</string>
@@ -889,7 +870,6 @@
<string name="revanced_spoof_storyboard_title">Spoof storyboard</string>
<string name="revanced_spoof_storyboard_summary_on">Storyboard spoofed</string>
<string name="revanced_spoof_storyboard_summary_off">Storyboard not spoofed\n\nSide effects include:\n• No ambient mode\n• Seekbar thumbnails are hidden</string>
<string name="revanced_spoof_signature_verification_summary">Spoof the app signature to prevent playback issues</string>
<string name="revanced_spoof_storyboard_timeout">Spoof storyboard temporarily not available (API timed out)</string>
<string name="revanced_spoof_storyboard_io_exception">Spoof storyboard temporarily not available: %s</string>
</patch>
@@ -908,8 +888,8 @@
<string name="revanced_external_browser_summary_off">Opening links in app</string>
</patch>
<patch id="misc.minimizedplayback.MinimizedPlaybackPatch">
<string name="revanced_minimized_playback_enabled_title">Minimized playback</string>
<string name="revanced_minimized_playback_summary_on">This setting can be found in Settings -&gt; Background</string>
<string name="revanced_minimized_playback_title">Minimized playback</string>
<string name="revanced_minimized_playback_summary">This setting can be found in Settings -&gt; Background</string>
</patch>
<patch id="misc.privacy.RemoveTrackingQueryParameterPatch">
<string name="revanced_remove_tracking_query_parameter_title">Remove tracking query parameter</string>
@@ -1007,9 +987,6 @@
</patch>
<patch id="misc.settings.SettingsPatch">
<string name="revanced_settings">ReVanced Settings</string>
<string name="revanced_debug_title">Debug logging</string>
<string name="revanced_debug_summary_on">Debug logs are enabled</string>
<string name="revanced_debug_summary_off">Debug logs are disabled</string>
<string name="revanced_ads_screen_title">Ads</string>
<string name="revanced_ads_screen_summary">Ad blocking settings</string>
<string name="revanced_chat_screen_title">Chat</string>
@@ -1020,6 +997,9 @@
<string name="revanced_other_category_title">Other settings</string>
<string name="revanced_client_ads_category_title">Client-side ads</string>
<string name="revanced_surestream_ads_category_title">Server-side surestream ads</string>
<string name="revanced_debug_title">Debug logging</string>
<string name="revanced_debug_summary_on">Debug logs are enabled</string>
<string name="revanced_debug_summary_off">Debug logs are disabled</string>
</patch>
</app>
</resources>

View File

@@ -13,7 +13,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/yt_white1"
android:elevation="4dp">
android:elevation="0dp">
<android.support.v7.widget.Toolbar
android:id="@+id/revanced_toolbar"

View File

@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:yt="http://schemas.android.com/apk/res-auto">
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yt="http://schemas.android.com/apk/res-auto"
android:key="revanced_settings_root_screen_sort_by_key"> <!-- Sort by preference key -->
</PreferenceScreen>