Compare commits

..

66 Commits

Author SHA1 Message Date
semantic-release-bot
a65bbebfdb chore: Release v5.2.0-dev.3 [skip ci]
# [5.2.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.2...v5.2.0-dev.3) (2024-11-26)

### Features

* **VSCO:** Remove non functional `Unlock pro` patch ([1a910a2](1a910a2cf6))
2024-11-26 21:06:29 +00:00
oSumAtrIX
1a910a2cf6 feat(VSCO): Remove non functional Unlock pro patch 2024-11-26 22:03:31 +01:00
semantic-release-bot
6d23a4e000 chore: Release v5.2.0-dev.2 [skip ci]
# [5.2.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.1...v5.2.0-dev.2) (2024-11-26)

### Bug Fixes

* **YouTube - Settings:** Show navigation back button in setting sub menus ([#3991](https://github.com/ReVanced/revanced-patches/issues/3991)) ([5c3c684](5c3c68406e))
2024-11-26 16:49:10 +00:00
LisoUseInAIKyrios
5c3c68406e fix(YouTube - Settings): Show navigation back button in setting sub menus (#3991) 2024-11-26 20:45:48 +04:00
github-actions[bot]
b0c3709be7 chore: Sync translations (#3993) 2024-11-26 20:45:18 +04:00
LisoUseInAIKyrios
cd19f976e7 chore: Fix redundant patch description 2024-11-26 16:47:36 +04:00
semantic-release-bot
c181135cc1 chore: Release v5.2.0-dev.1 [skip ci]
# [5.2.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.1.1-dev.2...v5.2.0-dev.1) (2024-11-25)

### Features

* **YouTube - Theme:** Apply custom seekbar color to splash screen animation ([#3978](https://github.com/ReVanced/revanced-patches/issues/3978)) ([7f67759](7f6775950e))
2024-11-25 16:52:34 +00:00
LisoUseInAIKyrios
7f6775950e feat(YouTube - Theme): Apply custom seekbar color to splash screen animation (#3978) 2024-11-25 20:49:05 +04:00
github-actions[bot]
4b2abaf17e chore: Sync translations (#3985) 2024-11-25 20:47:23 +04:00
semantic-release-bot
677b18c41a chore: Release v5.1.1-dev.2 [skip ci]
## [5.1.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.1.1-dev.1...v5.1.1-dev.2) (2024-11-25)

### Bug Fixes

* **YouTube - Hide Shorts components:** Add missing options to patch ([736b6a9](736b6a96b8))
2024-11-25 15:43:26 +00:00
oSumAtrIX
736b6a96b8 fix(YouTube - Hide Shorts components): Add missing options to patch 2024-11-25 16:40:06 +01:00
semantic-release-bot
8c371d8579 chore: Release v5.1.1-dev.1 [skip ci]
## [5.1.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.1.0...v5.1.1-dev.1) (2024-11-24)

### Bug Fixes

* **My Expenses - Unlock pro:** Constrain compatible version to working version ([#3974](https://github.com/ReVanced/revanced-patches/issues/3974)) ([abcaa63](abcaa6336a))
2024-11-24 22:49:39 +00:00
LisoUseInAIKyrios
abcaa6336a fix(My Expenses - Unlock pro): Constrain compatible version to working version (#3974) 2024-11-24 23:47:15 +01:00
semantic-release-bot
11537526a4 chore: Release v5.1.0 [skip ci]
# [5.1.0](https://github.com/ReVanced/revanced-patches/compare/v5.0.2...v5.1.0) (2024-11-24)

### Bug Fixes

* **YouTube - Change header:** Apply header changes to A/B layout ([#3907](https://github.com/ReVanced/revanced-patches/issues/3907)) ([69c504c](69c504ca2f))
* **YouTube - Hide Shorts components:** Do not hide Shorts action buttons on app first launch ([#3933](https://github.com/ReVanced/revanced-patches/issues/3933)) ([c3701c4](c3701c4b6e))
* **YouTube - Playback speed:** Add 'Auto' speed. Always override speed if default is set to 1.0x ([#3914](https://github.com/ReVanced/revanced-patches/issues/3914)) ([78f3fd6](78f3fd6aa4))
* **YouTube - SponsorBlock:** Fix create new segment crash on tablet custom roms ([#3946](https://github.com/ReVanced/revanced-patches/issues/3946)) ([a7fc08a](a7fc08a491))
* **YouTube - Spoof app version:** Adjust legacy spoof targets ([#3934](https://github.com/ReVanced/revanced-patches/issues/3934)) ([2e3b3dc](2e3b3dca4b))
* **YouTube - Spoof app version:** Remove broken spoof targets when patching 19.25+ ([#3915](https://github.com/ReVanced/revanced-patches/issues/3915)) ([17b5b2e](17b5b2e384))

### Features

* **YouTube - Miniplayer:** Add option to disable miniplayer ([#3961](https://github.com/ReVanced/revanced-patches/issues/3961)) ([01cc8e0](01cc8e0abf))
* **YouTube:** Support version `19.45.38` ([#3938](https://github.com/ReVanced/revanced-patches/issues/3938)) ([8c6c8e0](8c6c8e0442))
2024-11-24 04:53:48 +00:00
oSumAtrIX
403116f591 chore: Merge branch dev to main (#3909) 2024-11-24 05:49:58 +01:00
1fexd
a1d14cffe9 chore: Move Sync video downloads patch to correct package 2024-11-24 04:06:02 +04:00
semantic-release-bot
10f221f374 chore: Release v5.1.0-dev.3 [skip ci]
# [5.1.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.1.0-dev.2...v5.1.0-dev.3) (2024-11-22)

### Features

* **YouTube - Miniplayer:** Add option to disable miniplayer ([#3961](https://github.com/ReVanced/revanced-patches/issues/3961)) ([01cc8e0](01cc8e0abf))
2024-11-22 16:44:41 +00:00
github-actions[bot]
ba1aab6d4d chore: Sync translations (#3962) 2024-11-22 20:41:24 +04:00
LisoUseInAIKyrios
01cc8e0abf feat(YouTube - Miniplayer): Add option to disable miniplayer (#3961)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-11-22 20:37:35 +04:00
LisoUseInAIKyrios
518958350d refactor(YouTube - Announcements): Do not include announcement setting with import/export 2024-11-21 18:48:06 +04:00
semantic-release-bot
a625309d1f chore: Release v5.1.0-dev.2 [skip ci]
# [5.1.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.1.0-dev.1...v5.1.0-dev.2) (2024-11-21)

### Bug Fixes

* **YouTube - SponsorBlock:** Fix create new segment crash on tablet custom roms ([#3946](https://github.com/ReVanced/revanced-patches/issues/3946)) ([a7fc08a](a7fc08a491))
2024-11-21 05:47:29 +00:00
LisoUseInAIKyrios
a7fc08a491 fix(YouTube - SponsorBlock): Fix create new segment crash on tablet custom roms (#3946) 2024-11-21 09:44:32 +04:00
semantic-release-bot
97b129e088 chore: Release v5.1.0-dev.1 [skip ci]
# [5.1.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.3-dev.5...v5.1.0-dev.1) (2024-11-20)

### Features

* **YouTube:** Support version `19.45.38` ([#3938](https://github.com/ReVanced/revanced-patches/issues/3938)) ([8c6c8e0](8c6c8e0442))
2024-11-20 09:54:50 +00:00
LisoUseInAIKyrios
8c6c8e0442 feat(YouTube): Support version 19.45.38 (#3938) 2024-11-20 13:51:36 +04:00
LisoUseInAIKyrios
16c090d2c0 refactor(YouTube): Use consistent language for 'auto' speed and quality 2024-11-19 11:07:49 +04:00
semantic-release-bot
ed35a2a4a9 chore: Release v5.0.3-dev.5 [skip ci]
## [5.0.3-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.0.3-dev.4...v5.0.3-dev.5) (2024-11-18)

### Bug Fixes

* **YouTube - Hide Shorts components:** Do not hide Shorts action buttons on app first launch ([#3933](https://github.com/ReVanced/revanced-patches/issues/3933)) ([c3701c4](c3701c4b6e))
2024-11-18 08:28:49 +00:00
LisoUseInAIKyrios
c3701c4b6e fix(YouTube - Hide Shorts components): Do not hide Shorts action buttons on app first launch (#3933) 2024-11-18 12:25:32 +04:00
github-actions[bot]
e0dc821c50 chore: Sync translations (#3936) 2024-11-18 12:21:46 +04:00
semantic-release-bot
b9efb05271 chore: Release v5.0.3-dev.4 [skip ci]
## [5.0.3-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.0.3-dev.3...v5.0.3-dev.4) (2024-11-18)

### Bug Fixes

* **YouTube - Spoof app version:** Adjust legacy spoof targets ([#3934](https://github.com/ReVanced/revanced-patches/issues/3934)) ([2e3b3dc](2e3b3dca4b))
2024-11-18 08:20:28 +00:00
LisoUseInAIKyrios
2e3b3dca4b fix(YouTube - Spoof app version): Adjust legacy spoof targets (#3934) 2024-11-18 12:17:22 +04:00
semantic-release-bot
19eaee09d0 chore: Release v5.0.3-dev.3 [skip ci]
## [5.0.3-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.0.3-dev.2...v5.0.3-dev.3) (2024-11-15)

### Bug Fixes

* **YouTube - Playback speed:** Add 'Auto' speed. Always override speed if default is set to 1.0x ([#3914](https://github.com/ReVanced/revanced-patches/issues/3914)) ([78f3fd6](78f3fd6aa4))
2024-11-15 03:59:51 +00:00
LisoUseInAIKyrios
78f3fd6aa4 fix(YouTube - Playback speed): Add 'Auto' speed. Always override speed if default is set to 1.0x (#3914) 2024-11-15 07:56:36 +04:00
semantic-release-bot
71ed37beb1 chore: Release v5.0.3-dev.2 [skip ci]
## [5.0.3-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.0.3-dev.1...v5.0.3-dev.2) (2024-11-15)

### Bug Fixes

* **YouTube - Spoof app version:** Remove broken spoof targets when patching 19.25+ ([#3915](https://github.com/ReVanced/revanced-patches/issues/3915)) ([17b5b2e](17b5b2e384))
2024-11-15 03:51:14 +00:00
github-actions[bot]
5aae234c43 chore: Sync translations (#3920) 2024-11-15 07:47:49 +04:00
LisoUseInAIKyrios
17b5b2e384 fix(YouTube - Spoof app version): Remove broken spoof targets when patching 19.25+ (#3915) 2024-11-15 07:44:28 +04:00
LisoUseInAIKyrios
462b61c2e9 refactor(YouTube - Hide mix playlist): Do not search path or buffer unless setting is enabled 2024-11-14 01:37:14 +04:00
semantic-release-bot
f23b7fffc8 chore: Release v5.0.3-dev.1 [skip ci]
## [5.0.3-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.2...v5.0.3-dev.1) (2024-11-13)

### Bug Fixes

* **YouTube - Change header:** Apply header changes to A/B layout ([#3907](https://github.com/ReVanced/revanced-patches/issues/3907)) ([69c504c](69c504ca2f))
2024-11-13 13:15:15 +00:00
LisoUseInAIKyrios
69c504ca2f fix(YouTube - Change header): Apply header changes to A/B layout (#3907) 2024-11-13 17:12:26 +04:00
semantic-release-bot
fc4b0d7c39 chore: Release v5.0.2 [skip ci]
## [5.0.2](https://github.com/ReVanced/revanced-patches/compare/v5.0.1...v5.0.2) (2024-11-12)

### Bug Fixes

* **Sync for Reddit - Fix /s/ links:** Fix patch by using correct fingerprints ([68ec011](68ec011003))
* **Sync for Reddit - Spoof client:** Fix patch by using correct fingerprints ([273bedc](273bedc74c))
* **YouTube - Player controls:** Show player control buttons with A/B layout ([#3901](https://github.com/ReVanced/revanced-patches/issues/3901)) ([e441745](e4417455c9))
2024-11-12 13:47:36 +00:00
oSumAtrIX
02e66b3d43 chore: Merge branch dev to main (#3899) 2024-11-12 14:44:18 +01:00
semantic-release-bot
a75c15b950 chore: Release v5.0.2-dev.2 [skip ci]
## [5.0.2-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.0.2-dev.1...v5.0.2-dev.2) (2024-11-12)

### Bug Fixes

* **YouTube - Player controls:** Show player control buttons with A/B layout ([#3901](https://github.com/ReVanced/revanced-patches/issues/3901)) ([e441745](e4417455c9))
2024-11-12 06:10:45 +00:00
LisoUseInAIKyrios
e4417455c9 fix(YouTube - Player controls): Show player control buttons with A/B layout (#3901) 2024-11-12 10:07:32 +04:00
semantic-release-bot
5253f4bfa4 chore: Release v5.0.2-dev.1 [skip ci]
## [5.0.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.1...v5.0.2-dev.1) (2024-11-11)

### Bug Fixes

* **Sync for Reddit - Fix /s/ links:** Fix patch by using correct fingerprints ([68ec011](68ec011003))
* **Sync for Reddit - Spoof client:** Fix patch by using correct fingerprints ([273bedc](273bedc74c))
2024-11-11 23:57:42 +00:00
oSumAtrIX
273bedc74c fix(Sync for Reddit - Spoof client): Fix patch by using correct fingerprints 2024-11-12 00:55:01 +01:00
oSumAtrIX
68ec011003 fix(Sync for Reddit - Fix /s/ links): Fix patch by using correct fingerprints 2024-11-12 00:44:54 +01:00
semantic-release-bot
f3d1103287 chore: Release v5.0.1 [skip ci]
## [5.0.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.0...v5.0.1) (2024-11-11)

### Bug Fixes

* **Sync:** Fix patches by not throwing unnecessarily ([3059aca](3059aca69d))
* **Tiktok - Settings:** Fix the patch by depending on the correct settings patch ([2094a23](2094a23ccc))
* **Twitter:** Fix patches by depending on patch that merges required extension ([3e1b5cb](3e1b5cbaf5))
* **Twitter:** Fix patches by matching fingerprint using correct class ([3793b21](3793b2103c))
* **YouTube - Playback speed:** Remember playback speed when using non 1.0x default speed ([d881d8b](d881d8bc44)), closes [#3810](https://github.com/ReVanced/revanced-patches/issues/3810)

### Performance Improvements

* Check for extension without a class proxy ([53b6b1f](53b6b1ff41))
2024-11-11 20:42:31 +00:00
oSumAtrIX
50a3541e98 chore: Merge branch dev to main (#3888) 2024-11-11 21:39:55 +01:00
github-actions[bot]
c6069a7ff6 chore: Sync translations (#3897)
Co-authored-by: revanced-bot <github@revanced.app>
2024-11-11 21:39:34 +01:00
semantic-release-bot
b10b624b4b chore: Release v5.0.1-dev.4 [skip ci]
## [5.0.1-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.0.1-dev.3...v5.0.1-dev.4) (2024-11-11)

### Bug Fixes

* **Twitter:** Fix patches by depending on patch that merges required extension ([3e1b5cb](3e1b5cbaf5))
2024-11-11 17:01:35 +00:00
oSumAtrIX
3e1b5cbaf5 fix(Twitter): Fix patches by depending on patch that merges required extension 2024-11-11 17:58:56 +01:00
semantic-release-bot
ef37b78b45 chore: Release v5.0.1-dev.3 [skip ci]
## [5.0.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.0.1-dev.2...v5.0.1-dev.3) (2024-11-11)

### Bug Fixes

* **YouTube - Playback speed:** Remember playback speed when using non 1.0x default speed ([d881d8b](d881d8bc44)), closes [#3810](https://github.com/ReVanced/revanced-patches/issues/3810)
2024-11-11 06:32:25 +00:00
LisoUseInAIKyrios
d881d8bc44 fix(YouTube - Playback speed): Remember playback speed when using non 1.0x default speed
This code was previously present with PR #3810 but was accidentally left out during the DSL migration.
2024-11-11 10:29:15 +04:00
semantic-release-bot
0cb993d6ea chore: Release v5.0.1-dev.2 [skip ci]
## [5.0.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.0.1-dev.1...v5.0.1-dev.2) (2024-11-11)

### Bug Fixes

* **Twitter:** Fix patches by matching fingerprint using correct class ([3793b21](3793b2103c))
2024-11-11 01:53:03 +00:00
oSumAtrIX
3793b2103c fix(Twitter): Fix patches by matching fingerprint using correct class 2024-11-11 02:50:21 +01:00
semantic-release-bot
658370f035 chore: Release v5.0.1-dev.1 [skip ci]
## [5.0.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.0...v5.0.1-dev.1) (2024-11-11)

### Bug Fixes

* **Sync:** Fix patches by not throwing unnecessarily ([3059aca](3059aca69d))
* **Tiktok - Settings:** Fix the patch by depending on the correct settings patch ([2094a23](2094a23ccc))

### Performance Improvements

* Check for extension without a class proxy ([53b6b1f](53b6b1ff41))
2024-11-11 01:40:33 +00:00
oSumAtrIX
3059aca69d fix(Sync): Fix patches by not throwing unnecessarily 2024-11-11 02:37:44 +01:00
oSumAtrIX
2094a23ccc fix(Tiktok - Settings): Fix the patch by depending on the correct settings patch 2024-11-11 02:33:12 +01:00
oSumAtrIX
53b6b1ff41 perf: Check for extension without a class proxy 2024-11-11 02:25:17 +01:00
semantic-release-bot
5657a7d8c8 chore: Release v5.0.0 [skip ci]
# [5.0.0](https://github.com/ReVanced/revanced-patches/compare/v4.17.0...v5.0.0) (2024-11-10)

### Bug Fixes

* Add missing dependency to patch ([327ebd3](327ebd3649))
* **MyFitnessPal - Hide ads:** Constrain patch to last working version ([#3847](https://github.com/ReVanced/revanced-patches/issues/3847)) ([9c3bec6](9c3bec69d8))
* **Twitter - Change link sharing domain:** Support latest app version ([#3786](https://github.com/ReVanced/revanced-patches/issues/3786)) ([5bdb3a2](5bdb3a2e29))
* **YouTube - Copy video URL:** Support A/B player layout ([c832143](c832143eec))
* **YouTube - Custom branding:** Change icon correctly on 19.34+ ([#3866](https://github.com/ReVanced/revanced-patches/issues/3866)) ([4d1b3fb](4d1b3fba99))
* **YouTube - Hide ads:** Hide new types of ads ([6ceb084](6ceb084831))
* **YouTube - Hide layout components:** Move hide chips settings to Feed menu ([716f0d8](716f0d8d64))
* **YouTube - Hide layout components:** Remove obsolete 'Hide gray separator' ([30a063e](30a063ea12))
* **YouTube - Playback speed:** Remember playback speed with new speed menu ([#3810](https://github.com/ReVanced/revanced-patches/issues/3810)) ([e09b039](e09b03997e))
* **YouTube - Playback speed:** Restore old playback speed menu ([#3817](https://github.com/ReVanced/revanced-patches/issues/3817)) ([1215d16](1215d16a30))
* **YouTube - Remember video quality:** Correctly set default quality when changing from a low quality video ([#3879](https://github.com/ReVanced/revanced-patches/issues/3879)) ([75d661f](75d661fcdc))
* **YouTube - Remove background playback restrictions:** Enable for Shorts as well ([#3671](https://github.com/ReVanced/revanced-patches/issues/3671)) ([a803660](a8036606c1))
* **YouTube - Return YouTube Dislike:** Show Shorts dislikes with new A/B button icons ([a0c227f](a0c227f1a0))
* **YouTube - Return YouTube Dislike:** Use latest separator height ([94adb2e](94adb2eb65))
* **YouTube - Seekbar:** Use latest shade of YouTube red ([e94b216](e94b216e44))
* **YouTube - Settings:** Use multiline preference title for localized languages ([#3821](https://github.com/ReVanced/revanced-patches/issues/3821)) ([2082f14](2082f14f34))
* **YouTube - SponsorBlock:** Show correct segment behavior in settings UI after importing ([53c2f96](53c2f96b6a))
* **YouTube - Spoof app version:** Remove obsolete 17.33.42 spoof target ([#3825](https://github.com/ReVanced/revanced-patches/issues/3825)) ([2165953](2165953a4e))
* **YouTube:** Merge `Restore old seekbar thumbnails` into `Seekbar thumbnails` ([#3860](https://github.com/ReVanced/revanced-patches/issues/3860)) ([042515a](042515a4f0))

### Build System

* Bump ReVanced Patcher ([928cf5f](928cf5f945))

### Features

* **YouTube - Hide layout components:** Hide player shopping shelf ([#3804](https://github.com/ReVanced/revanced-patches/issues/3804)) ([69329df](69329df355))
* **YouTube - Hide player flyout menu items:** Hide stable volume ([#3827](https://github.com/ReVanced/revanced-patches/issues/3827)) ([d3c4811](d3c481166f))
* **YouTube - Miniplayer:** Add horizontal drag gesture ([#3859](https://github.com/ReVanced/revanced-patches/issues/3859)) ([ecf8bd4](ecf8bd445a))
* **YouTube - Player flyout menu:** Hide sleep timer ([#3637](https://github.com/ReVanced/revanced-patches/issues/3637)) ([6348a66](6348a66fef))
* **YouTube:** Add `Seekbar thumbnails` patch ([#3813](https://github.com/ReVanced/revanced-patches/issues/3813)) ([aa2f963](aa2f963e05))
* **YouTube:** Add `Shorts autoplay` patch ([#3794](https://github.com/ReVanced/revanced-patches/issues/3794)) ([132d925](132d925d5c))
* **YouTube:** Hide player shopping shelf in playlists ([#3806](https://github.com/ReVanced/revanced-patches/issues/3806)) ([68d9edf](68d9edfd8c))
* **YouTube:** Merge multiple layout patches into `Hide Layout Components` ([#3799](https://github.com/ReVanced/revanced-patches/issues/3799)) ([24d612d](24d612d0d1))
* **YouTube:** Merge multiple player overlay patches into `Hide player overlay buttons` ([#3800](https://github.com/ReVanced/revanced-patches/issues/3800)) ([cee0641](cee0641247))
* **YouTube:** Support version `19.43.41` ([#3854](https://github.com/ReVanced/revanced-patches/issues/3854)) ([43f5e99](43f5e99e0b))

### BREAKING CHANGES

* Various APIs have been changed or removed.
2024-11-10 14:59:53 +00:00
oSumAtrIX
08ce458e28 chore: Merge branch dev to main (#3798) 2024-11-10 15:56:12 +01:00
github-actions[bot]
b5e4022fbb chore: Sync translations (#3881)
Co-authored-by: revanced-bot <github@revanced.app>
2024-11-10 15:48:08 +01:00
semantic-release-bot
6e75ffd5f1 chore: Release v5.0.0-dev.4 [skip ci]
# [5.0.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.0.0-dev.3...v5.0.0-dev.4) (2024-11-09)

### Bug Fixes

* **YouTube - Remember video quality:** Correctly set default quality when changing from a low quality video ([#3879](https://github.com/ReVanced/revanced-patches/issues/3879)) ([75d661f](75d661fcdc))
2024-11-09 18:56:29 +00:00
LisoUseInAIKyrios
75d661fcdc fix(YouTube - Remember video quality): Correctly set default quality when changing from a low quality video (#3879) 2024-11-09 22:53:01 +04:00
semantic-release-bot
4d1de6bc50 chore: Release v5.0.0-dev.3 [skip ci]
# [5.0.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.0.0-dev.2...v5.0.0-dev.3) (2024-11-09)

### Bug Fixes

* Add missing dependency to patch ([327ebd3](327ebd3649))
2024-11-09 04:20:45 +00:00
oSumAtrIX
327ebd3649 fix: Add missing dependency to patch 2024-11-09 05:17:06 +01:00
LisoUseInAIKyrios
34e98a54e0 chore(YouTube - Announcements): Remove language parameter of API call (#3874) 2024-11-08 22:11:31 -04:00
206 changed files with 3165 additions and 1924 deletions

View File

@@ -1,3 +1,249 @@
# [5.2.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.2...v5.2.0-dev.3) (2024-11-26)
### Features
* **VSCO:** Remove non functional `Unlock pro` patch ([4fddb19](https://github.com/ReVanced/revanced-patches/commit/4fddb1930bc7adeee3b60ae9cd346b143e88bd42))
# [5.2.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.1...v5.2.0-dev.2) (2024-11-26)
### Bug Fixes
* **YouTube - Settings:** Show navigation back button in setting sub menus ([#3991](https://github.com/ReVanced/revanced-patches/issues/3991)) ([e61686c](https://github.com/ReVanced/revanced-patches/commit/e61686c1039ae29e443273e4da4ec63956216841))
# [5.2.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.1.1-dev.2...v5.2.0-dev.1) (2024-11-25)
### Features
* **YouTube - Theme:** Apply custom seekbar color to splash screen animation ([#3978](https://github.com/ReVanced/revanced-patches/issues/3978)) ([98d57e2](https://github.com/ReVanced/revanced-patches/commit/98d57e28af7206099867474b7aa3760cd4fe333f))
## [5.1.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.1.1-dev.1...v5.1.1-dev.2) (2024-11-25)
### Bug Fixes
* **YouTube - Hide Shorts components:** Add missing options to patch ([65f62fc](https://github.com/ReVanced/revanced-patches/commit/65f62fcd5ac340616a96542c64faf2af2a60df28))
## [5.1.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.1.0...v5.1.1-dev.1) (2024-11-24)
### Bug Fixes
* **My Expenses - Unlock pro:** Constrain compatible version to working version ([#3974](https://github.com/ReVanced/revanced-patches/issues/3974)) ([ba3bf69](https://github.com/ReVanced/revanced-patches/commit/ba3bf69df07ec8dab46868c3940ebd56db0cd137))
# [5.1.0](https://github.com/ReVanced/revanced-patches/compare/v5.0.2...v5.1.0) (2024-11-24)
### Bug Fixes
* **YouTube - Change header:** Apply header changes to A/B layout ([#3907](https://github.com/ReVanced/revanced-patches/issues/3907)) ([6ccf114](https://github.com/ReVanced/revanced-patches/commit/6ccf11426ec9e9cd9c8e89a2443f0d0645cc78b1))
* **YouTube - Hide Shorts components:** Do not hide Shorts action buttons on app first launch ([#3933](https://github.com/ReVanced/revanced-patches/issues/3933)) ([0d78815](https://github.com/ReVanced/revanced-patches/commit/0d78815e33bf2ae216e519f067fb773df0f2084e))
* **YouTube - Playback speed:** Add 'Auto' speed. Always override speed if default is set to 1.0x ([#3914](https://github.com/ReVanced/revanced-patches/issues/3914)) ([497739e](https://github.com/ReVanced/revanced-patches/commit/497739e8ce6933c1f1ea46edffc102e56b985623))
* **YouTube - SponsorBlock:** Fix create new segment crash on tablet custom roms ([#3946](https://github.com/ReVanced/revanced-patches/issues/3946)) ([a0da377](https://github.com/ReVanced/revanced-patches/commit/a0da377ba8f90ba39e905ed9730b3e819633bd50))
* **YouTube - Spoof app version:** Adjust legacy spoof targets ([#3934](https://github.com/ReVanced/revanced-patches/issues/3934)) ([f5794c1](https://github.com/ReVanced/revanced-patches/commit/f5794c1f896c331d76fdfc299e31a2773f2209ca))
* **YouTube - Spoof app version:** Remove broken spoof targets when patching 19.25+ ([#3915](https://github.com/ReVanced/revanced-patches/issues/3915)) ([9e18eca](https://github.com/ReVanced/revanced-patches/commit/9e18ecab1877dd33a3ad0fe216e6b91a8daaf1f8))
### Features
* **YouTube - Miniplayer:** Add option to disable miniplayer ([#3961](https://github.com/ReVanced/revanced-patches/issues/3961)) ([e565cdb](https://github.com/ReVanced/revanced-patches/commit/e565cdb583aacfc0052d12c430f56fd9abd5bf00))
* **YouTube:** Support version `19.45.38` ([#3938](https://github.com/ReVanced/revanced-patches/issues/3938)) ([7c4e3fe](https://github.com/ReVanced/revanced-patches/commit/7c4e3fe97e8cbbb8cf16a2fb95f64223ca2bd7ef))
# [5.1.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.1.0-dev.2...v5.1.0-dev.3) (2024-11-22)
### Features
* **YouTube - Miniplayer:** Add option to disable miniplayer ([#3961](https://github.com/ReVanced/revanced-patches/issues/3961)) ([e565cdb](https://github.com/ReVanced/revanced-patches/commit/e565cdb583aacfc0052d12c430f56fd9abd5bf00))
# [5.1.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.1.0-dev.1...v5.1.0-dev.2) (2024-11-21)
### Bug Fixes
* **YouTube - SponsorBlock:** Fix create new segment crash on tablet custom roms ([#3946](https://github.com/ReVanced/revanced-patches/issues/3946)) ([a0da377](https://github.com/ReVanced/revanced-patches/commit/a0da377ba8f90ba39e905ed9730b3e819633bd50))
# [5.1.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.3-dev.5...v5.1.0-dev.1) (2024-11-20)
### Features
* **YouTube:** Support version `19.45.38` ([#3938](https://github.com/ReVanced/revanced-patches/issues/3938)) ([7c4e3fe](https://github.com/ReVanced/revanced-patches/commit/7c4e3fe97e8cbbb8cf16a2fb95f64223ca2bd7ef))
## [5.0.3-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.0.3-dev.4...v5.0.3-dev.5) (2024-11-18)
### Bug Fixes
* **YouTube - Hide Shorts components:** Do not hide Shorts action buttons on app first launch ([#3933](https://github.com/ReVanced/revanced-patches/issues/3933)) ([0d78815](https://github.com/ReVanced/revanced-patches/commit/0d78815e33bf2ae216e519f067fb773df0f2084e))
## [5.0.3-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.0.3-dev.3...v5.0.3-dev.4) (2024-11-18)
### Bug Fixes
* **YouTube - Spoof app version:** Adjust legacy spoof targets ([#3934](https://github.com/ReVanced/revanced-patches/issues/3934)) ([f5794c1](https://github.com/ReVanced/revanced-patches/commit/f5794c1f896c331d76fdfc299e31a2773f2209ca))
## [5.0.3-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.0.3-dev.2...v5.0.3-dev.3) (2024-11-15)
### Bug Fixes
* **YouTube - Playback speed:** Add 'Auto' speed. Always override speed if default is set to 1.0x ([#3914](https://github.com/ReVanced/revanced-patches/issues/3914)) ([497739e](https://github.com/ReVanced/revanced-patches/commit/497739e8ce6933c1f1ea46edffc102e56b985623))
## [5.0.3-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.0.3-dev.1...v5.0.3-dev.2) (2024-11-15)
### Bug Fixes
* **YouTube - Spoof app version:** Remove broken spoof targets when patching 19.25+ ([#3915](https://github.com/ReVanced/revanced-patches/issues/3915)) ([9e18eca](https://github.com/ReVanced/revanced-patches/commit/9e18ecab1877dd33a3ad0fe216e6b91a8daaf1f8))
## [5.0.3-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.2...v5.0.3-dev.1) (2024-11-13)
### Bug Fixes
* **YouTube - Change header:** Apply header changes to A/B layout ([#3907](https://github.com/ReVanced/revanced-patches/issues/3907)) ([6ccf114](https://github.com/ReVanced/revanced-patches/commit/6ccf11426ec9e9cd9c8e89a2443f0d0645cc78b1))
## [5.0.2](https://github.com/ReVanced/revanced-patches/compare/v5.0.1...v5.0.2) (2024-11-12)
### Bug Fixes
* **Sync for Reddit - Fix /s/ links:** Fix patch by using correct fingerprints ([a0ad07e](https://github.com/ReVanced/revanced-patches/commit/a0ad07ef3170dbe1d91ebd40f11d97b63d1c63d0))
* **Sync for Reddit - Spoof client:** Fix patch by using correct fingerprints ([5776de3](https://github.com/ReVanced/revanced-patches/commit/5776de3cfbfa62360267eb6026525d2da8c45654))
* **YouTube - Player controls:** Show player control buttons with A/B layout ([#3901](https://github.com/ReVanced/revanced-patches/issues/3901)) ([bb526bc](https://github.com/ReVanced/revanced-patches/commit/bb526bc00a384eb808f46267e5802c8e5beaa7d5))
## [5.0.2-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.0.2-dev.1...v5.0.2-dev.2) (2024-11-12)
### Bug Fixes
* **YouTube - Player controls:** Show player control buttons with A/B layout ([#3901](https://github.com/ReVanced/revanced-patches/issues/3901)) ([bb526bc](https://github.com/ReVanced/revanced-patches/commit/bb526bc00a384eb808f46267e5802c8e5beaa7d5))
## [5.0.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.1...v5.0.2-dev.1) (2024-11-11)
### Bug Fixes
* **Sync for Reddit - Fix /s/ links:** Fix patch by using correct fingerprints ([a0ad07e](https://github.com/ReVanced/revanced-patches/commit/a0ad07ef3170dbe1d91ebd40f11d97b63d1c63d0))
* **Sync for Reddit - Spoof client:** Fix patch by using correct fingerprints ([5776de3](https://github.com/ReVanced/revanced-patches/commit/5776de3cfbfa62360267eb6026525d2da8c45654))
## [5.0.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.0...v5.0.1) (2024-11-11)
### Bug Fixes
* **Sync:** Fix patches by not throwing unnecessarily ([2ee1316](https://github.com/ReVanced/revanced-patches/commit/2ee13160d51dba3c5806594b2387f806e5946b9a))
* **Tiktok - Settings:** Fix the patch by depending on the correct settings patch ([0c75929](https://github.com/ReVanced/revanced-patches/commit/0c75929a83729841197b482d28f7f7f5f9cec332))
* **Twitter:** Fix patches by depending on patch that merges required extension ([c330e9d](https://github.com/ReVanced/revanced-patches/commit/c330e9d67d3e8c8c3535fa43e52c9f06e33ff0bf))
* **Twitter:** Fix patches by matching fingerprint using correct class ([6ae0d12](https://github.com/ReVanced/revanced-patches/commit/6ae0d124e1f27faecd20e4008951b08353572d98))
* **YouTube - Playback speed:** Remember playback speed when using non 1.0x default speed ([05b9f87](https://github.com/ReVanced/revanced-patches/commit/05b9f8709895dae67e8cc12e8b7bdb87ff401997)), closes [#3810](https://github.com/ReVanced/revanced-patches/issues/3810)
### Performance Improvements
* Check for extension without a class proxy ([a6a74e2](https://github.com/ReVanced/revanced-patches/commit/a6a74e289db1fe04db230d1e864cb9e752f9a01d))
## [5.0.1-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.0.1-dev.3...v5.0.1-dev.4) (2024-11-11)
### Bug Fixes
* **Twitter:** Fix patches by depending on patch that merges required extension ([c330e9d](https://github.com/ReVanced/revanced-patches/commit/c330e9d67d3e8c8c3535fa43e52c9f06e33ff0bf))
## [5.0.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.0.1-dev.2...v5.0.1-dev.3) (2024-11-11)
### Bug Fixes
* **YouTube - Playback speed:** Remember playback speed when using non 1.0x default speed ([05b9f87](https://github.com/ReVanced/revanced-patches/commit/05b9f8709895dae67e8cc12e8b7bdb87ff401997)), closes [#3810](https://github.com/ReVanced/revanced-patches/issues/3810)
## [5.0.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.0.1-dev.1...v5.0.1-dev.2) (2024-11-11)
### Bug Fixes
* **Twitter:** Fix patches by matching fingerprint using correct class ([6ae0d12](https://github.com/ReVanced/revanced-patches/commit/6ae0d124e1f27faecd20e4008951b08353572d98))
## [5.0.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.0...v5.0.1-dev.1) (2024-11-11)
### Bug Fixes
* **Sync:** Fix patches by not throwing unnecessarily ([2ee1316](https://github.com/ReVanced/revanced-patches/commit/2ee13160d51dba3c5806594b2387f806e5946b9a))
* **Tiktok - Settings:** Fix the patch by depending on the correct settings patch ([0c75929](https://github.com/ReVanced/revanced-patches/commit/0c75929a83729841197b482d28f7f7f5f9cec332))
### Performance Improvements
* Check for extension without a class proxy ([a6a74e2](https://github.com/ReVanced/revanced-patches/commit/a6a74e289db1fe04db230d1e864cb9e752f9a01d))
# [5.0.0](https://github.com/ReVanced/revanced-patches/compare/v4.17.0...v5.0.0) (2024-11-10)
### Bug Fixes
* Add missing dependency to patch ([97f5240](https://github.com/ReVanced/revanced-patches/commit/97f5240d53b9978fb3745170fe03619c7c90274a))
* **MyFitnessPal - Hide ads:** Constrain patch to last working version ([#3847](https://github.com/ReVanced/revanced-patches/issues/3847)) ([f9fa526](https://github.com/ReVanced/revanced-patches/commit/f9fa526b04c2848175c389d6bb911aa5a245b60f))
* **Twitter - Change link sharing domain:** Support latest app version ([#3786](https://github.com/ReVanced/revanced-patches/issues/3786)) ([b54592c](https://github.com/ReVanced/revanced-patches/commit/b54592cf9c5d859e1af2f02e8e6aaad7d47ab760))
* **YouTube - Copy video URL:** Support A/B player layout ([0f42574](https://github.com/ReVanced/revanced-patches/commit/0f42574b7f4b1c9a48df8550c7d710093f76ce8c))
* **YouTube - Custom branding:** Change icon correctly on 19.34+ ([#3866](https://github.com/ReVanced/revanced-patches/issues/3866)) ([2e47903](https://github.com/ReVanced/revanced-patches/commit/2e4790382546256e106a5842cd8c530f41b161e5))
* **YouTube - Hide ads:** Hide new types of ads ([454281a](https://github.com/ReVanced/revanced-patches/commit/454281ac2108648832b7f0203f5fb7e814887835))
* **YouTube - Hide layout components:** Move hide chips settings to Feed menu ([1ed677f](https://github.com/ReVanced/revanced-patches/commit/1ed677f7b8ba561b2bb173dcaf5d6123c22179c4))
* **YouTube - Hide layout components:** Remove obsolete 'Hide gray separator' ([a697701](https://github.com/ReVanced/revanced-patches/commit/a697701c5f1f9510b51e310b1ff212b609f38519))
* **YouTube - Playback speed:** Remember playback speed with new speed menu ([#3810](https://github.com/ReVanced/revanced-patches/issues/3810)) ([c3a5e14](https://github.com/ReVanced/revanced-patches/commit/c3a5e14a0a24973a0f9956845c9e0f99c1301d42))
* **YouTube - Playback speed:** Restore old playback speed menu ([#3817](https://github.com/ReVanced/revanced-patches/issues/3817)) ([806b210](https://github.com/ReVanced/revanced-patches/commit/806b21093e3251697f03cd8804e5d5cd26070716))
* **YouTube - Remember video quality:** Correctly set default quality when changing from a low quality video ([#3879](https://github.com/ReVanced/revanced-patches/issues/3879)) ([ddb73e8](https://github.com/ReVanced/revanced-patches/commit/ddb73e857d7c26fd27ea995a27f53f5660d3f71c))
* **YouTube - Remove background playback restrictions:** Enable for Shorts as well ([#3671](https://github.com/ReVanced/revanced-patches/issues/3671)) ([7db1a77](https://github.com/ReVanced/revanced-patches/commit/7db1a7751dc47c4e36096fbdc2b3761b0ae11ccb))
* **YouTube - Return YouTube Dislike:** Show Shorts dislikes with new A/B button icons ([084e0a5](https://github.com/ReVanced/revanced-patches/commit/084e0a527b1c75d1ef15dc706c429aa48d0ffe6b))
* **YouTube - Return YouTube Dislike:** Use latest separator height ([ae160a3](https://github.com/ReVanced/revanced-patches/commit/ae160a37985cc96c6de7e1a2fe5a1c83bc523046))
* **YouTube - Seekbar:** Use latest shade of YouTube red ([4b77648](https://github.com/ReVanced/revanced-patches/commit/4b77648607a84eb29f4cae9ddb42b87084be7cd0))
* **YouTube - Settings:** Use multiline preference title for localized languages ([#3821](https://github.com/ReVanced/revanced-patches/issues/3821)) ([ff85d49](https://github.com/ReVanced/revanced-patches/commit/ff85d490887de64eb6c6fd42e385a3e75969ff10))
* **YouTube - SponsorBlock:** Show correct segment behavior in settings UI after importing ([e3f25a0](https://github.com/ReVanced/revanced-patches/commit/e3f25a03cd314eeae786e7660a6beacb275a6a76))
* **YouTube - Spoof app version:** Remove obsolete 17.33.42 spoof target ([#3825](https://github.com/ReVanced/revanced-patches/issues/3825)) ([33aeba2](https://github.com/ReVanced/revanced-patches/commit/33aeba2a0895e9ecaba27ba4a3b22b86c9f1a51c))
* **YouTube:** Merge `Restore old seekbar thumbnails` into `Seekbar thumbnails` ([#3860](https://github.com/ReVanced/revanced-patches/issues/3860)) ([e377b1e](https://github.com/ReVanced/revanced-patches/commit/e377b1e6ad93dea8e5f3829cd3894f71851887a3))
### Build System
* Bump ReVanced Patcher ([eee1692](https://github.com/ReVanced/revanced-patches/commit/eee16922779f994f5752190a20a9016ea98ec4cb))
### Features
* **YouTube - Hide layout components:** Hide player shopping shelf ([#3804](https://github.com/ReVanced/revanced-patches/issues/3804)) ([1952f3b](https://github.com/ReVanced/revanced-patches/commit/1952f3b3c4bca08ed0f6e5b1117e0a6c51f00ed2))
* **YouTube - Hide player flyout menu items:** Hide stable volume ([#3827](https://github.com/ReVanced/revanced-patches/issues/3827)) ([b91e932](https://github.com/ReVanced/revanced-patches/commit/b91e932e65c04b1c1aee9a2f3dc3a73772d9c225))
* **YouTube - Miniplayer:** Add horizontal drag gesture ([#3859](https://github.com/ReVanced/revanced-patches/issues/3859)) ([e32b19e](https://github.com/ReVanced/revanced-patches/commit/e32b19e170a5571b23547c3211b497089d0cd441))
* **YouTube - Player flyout menu:** Hide sleep timer ([#3637](https://github.com/ReVanced/revanced-patches/issues/3637)) ([7e1bdab](https://github.com/ReVanced/revanced-patches/commit/7e1bdab520dba65682f018f819c0b7d9783f94ca))
* **YouTube:** Add `Seekbar thumbnails` patch ([#3813](https://github.com/ReVanced/revanced-patches/issues/3813)) ([5988b75](https://github.com/ReVanced/revanced-patches/commit/5988b759752b944b6999b401faa394e2089e4003))
* **YouTube:** Add `Shorts autoplay` patch ([#3794](https://github.com/ReVanced/revanced-patches/issues/3794)) ([96b5aed](https://github.com/ReVanced/revanced-patches/commit/96b5aede482f7a69d6df17864a2e17568b0da880))
* **YouTube:** Hide player shopping shelf in playlists ([#3806](https://github.com/ReVanced/revanced-patches/issues/3806)) ([a553a13](https://github.com/ReVanced/revanced-patches/commit/a553a13c0326ef2fff7f785fed592d553a7963ce))
* **YouTube:** Merge multiple layout patches into `Hide Layout Components` ([#3799](https://github.com/ReVanced/revanced-patches/issues/3799)) ([bbcb57a](https://github.com/ReVanced/revanced-patches/commit/bbcb57a32dfc8f031886f98b1b9701285105c579))
* **YouTube:** Merge multiple player overlay patches into `Hide player overlay buttons` ([#3800](https://github.com/ReVanced/revanced-patches/issues/3800)) ([4ba0300](https://github.com/ReVanced/revanced-patches/commit/4ba0300590dd988bdcaa0761c4e606c1d7f86ce5))
* **YouTube:** Support version `19.43.41` ([#3854](https://github.com/ReVanced/revanced-patches/issues/3854)) ([85de5c7](https://github.com/ReVanced/revanced-patches/commit/85de5c7d96ce2d67f6386d1438e43620d31cc645))
### BREAKING CHANGES
* Various APIs have been changed or removed.
# [5.0.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.0.0-dev.3...v5.0.0-dev.4) (2024-11-09)
### Bug Fixes
* **YouTube - Remember video quality:** Correctly set default quality when changing from a low quality video ([#3879](https://github.com/ReVanced/revanced-patches/issues/3879)) ([ddb73e8](https://github.com/ReVanced/revanced-patches/commit/ddb73e857d7c26fd27ea995a27f53f5660d3f71c))
# [5.0.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.0.0-dev.2...v5.0.0-dev.3) (2024-11-09)
### Bug Fixes
* Add missing dependency to patch ([97f5240](https://github.com/ReVanced/revanced-patches/commit/97f5240d53b9978fb3745170fe03619c7c90274a))
# [5.0.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.0.0-dev.1...v5.0.0-dev.2) (2024-11-09) # [5.0.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.0.0-dev.1...v5.0.0-dev.2) (2024-11-09)

View File

@@ -1,7 +1,11 @@
package app.revanced.extension.shared.checks; package app.revanced.extension.shared.checks;
// Fields are set by the patch. Do not modify. /**
// Fields are not final, because the compiler is inlining them. * Fields are set by the patch. Do not modify.
* Fields are not final, because the compiler is inlining them.
*
* @noinspection CanBeFinal
*/
final class PatchInfo { final class PatchInfo {
static long PATCH_TIME = 0L; static long PATCH_TIME = 0L;

View File

@@ -1,21 +1,33 @@
package app.revanced.extension.shared.settings.preference; package app.revanced.extension.shared.settings.preference;
import static app.revanced.extension.shared.StringRef.str;
import static app.revanced.extension.shared.Utils.getResourceIdentifier;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.*; import android.preference.*;
import android.util.TypedValue;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toolbar;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import java.util.Objects;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.BooleanSetting; import app.revanced.extension.shared.settings.BooleanSetting;
import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.youtube.ThemeHelper;
import static app.revanced.extension.shared.StringRef.str;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public abstract class AbstractPreferenceFragment extends PreferenceFragment { public abstract class AbstractPreferenceFragment extends PreferenceFragment {
@@ -71,6 +83,15 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
} }
}; };
@SuppressLint("UseCompatLoadingForDrawables")
public static Drawable getBackButtonDrawable() {
final int backButtonResource = getResourceIdentifier(ThemeHelper.isDarkTheme()
? "yt_outline_arrow_left_white_24"
: "yt_outline_arrow_left_black_24",
"drawable");
return Utils.getContext().getResources().getDrawable(backButtonResource);
}
/** /**
* Initialize this instance, and do any custom behavior. * Initialize this instance, and do any custom behavior.
* <p> * <p>
@@ -98,7 +119,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
showingUserDialogMessage = true; showingUserDialogMessage = true;
new AlertDialog.Builder(context) new AlertDialog.Builder(context)
.setTitle(confirmDialogTitle) .setTitle(confirmDialogTitle)
.setMessage(setting.userDialogMessage.toString()) .setMessage(Objects.requireNonNull(setting.userDialogMessage).toString())
.setPositiveButton(android.R.string.ok, (dialog, id) -> { .setPositiveButton(android.R.string.ok, (dialog, id) -> {
if (setting.rebootApp) { if (setting.rebootApp) {
showRestartDialog(context); showRestartDialog(context);
@@ -261,6 +282,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
// causes a callback to the listener even though nothing changed. // causes a callback to the listener even though nothing changed.
initialize(); initialize();
updateUIToSettingValues(); updateUIToSettingValues();
setPreferenceScreenToolbar(getPreferenceScreen());
preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(listener); preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(listener);
} catch (Exception ex) { } catch (Exception ex) {
@@ -273,4 +295,44 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener); getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener);
super.onDestroy(); super.onDestroy();
} }
private void setPreferenceScreenToolbar(PreferenceScreen parentScreen) {
for (int i = 0, preferenceCount = parentScreen.getPreferenceCount(); i < preferenceCount; i++) {
Preference childPreference = parentScreen.getPreference(i);
if (childPreference instanceof PreferenceScreen) {
// Recursively set sub preferences.
setPreferenceScreenToolbar((PreferenceScreen) childPreference);
childPreference.setOnPreferenceClickListener(
childScreen -> {
Dialog preferenceScreenDialog = ((PreferenceScreen) childScreen).getDialog();
ViewGroup rootView = (ViewGroup) preferenceScreenDialog
.findViewById(android.R.id.content)
.getParent();
Toolbar toolbar = new Toolbar(childScreen.getContext());
toolbar.setTitle(childScreen.getTitle());
toolbar.setNavigationIcon(getBackButtonDrawable());
toolbar.setNavigationOnClickListener(view -> preferenceScreenDialog.dismiss());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
final int margin = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()
);
toolbar.setTitleMargin(margin, 0, margin, 0);
}
TextView toolbarTextView = Utils.getChildView(toolbar,
true, TextView.class::isInstance);
if (toolbarTextView != null) {
toolbarTextView.setTextColor(ThemeHelper.getForegroundColor());
}
rootView.addView(toolbar, 0);
return false;
}
);
}
}
}
} }

View File

@@ -11,9 +11,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
public class ShowOnLockscreenPatch { public class ShowOnLockscreenPatch {
/**
* @noinspection deprecation
*/
public static Window getWindow(AppCompatActivity activity, float brightness) { public static Window getWindow(AppCompatActivity activity, float brightness) {
Window window = activity.getWindow(); Window window = activity.getWindow();

View File

@@ -82,4 +82,12 @@ public class ThemeHelper {
} }
return Utils.getResourceColor(colorString); return Utils.getResourceColor(colorString);
} }
public static int getBackgroundColor() {
return isDarkTheme() ? getDarkThemeColor() : getLightThemeColor();
}
public static int getForegroundColor() {
return isDarkTheme() ? getLightThemeColor() : getDarkThemeColor();
}
} }

View File

@@ -53,4 +53,18 @@ public final class EnableDebuggingPatch {
return value; return value;
} }
/**
* Injection point.
*/
public static String isStringFeatureFlagEnabled(String value, long flag, String defaultValue) {
if (BaseSettings.DEBUG.get() && !defaultValue.equals(value)) {
if (featureFlags.putIfAbsent(flag, true) == null) {
Logger.printDebug(() -> " string feature is enabled: " + flag
+ " value: " + value + (defaultValue.isEmpty() ? "" : " default: " + defaultValue));
}
}
return value;
}
} }

View File

@@ -24,9 +24,20 @@ public final class MiniplayerPatch {
* Mini player type. Null fields indicates to use the original un-patched value. * Mini player type. Null fields indicates to use the original un-patched value.
*/ */
public enum MiniplayerType { public enum MiniplayerType {
/**
* Disabled. When swiped down the miniplayer is immediately closed.
* Only available with 19.43+
*/
DISABLED(false, null),
/** Unmodified type, and same as un-patched. */ /** Unmodified type, and same as un-patched. */
ORIGINAL(null, null), ORIGINAL(null, null),
/**
* Exactly the same as MINIMAL, and only here for migration of user settings.
* Eventually this should be deleted.
*/
@Deprecated
PHONE(false, null), PHONE(false, null),
MINIMAL(false, null),
TABLET(true, null), TABLET(true, null),
MODERN_1(null, 1), MODERN_1(null, 1),
MODERN_2(null, 2), MODERN_2(null, 2),
@@ -164,6 +175,18 @@ public final class MiniplayerPatch {
OPACITY_LEVEL = (opacity * 255) / 100; OPACITY_LEVEL = (opacity * 255) / 100;
} }
/**
* Injection point.
*
* Enables a handler that immediately closes the miniplayer when the video is minimized,
* effectively disabling the miniplayer.
*/
public static boolean getMiniplayerOnCloseHandler(boolean original) {
return CURRENT_TYPE == ORIGINAL
? original
: CURRENT_TYPE == DISABLED;
}
/** /**
* Injection point. * Injection point.
*/ */

View File

@@ -8,6 +8,7 @@ import app.revanced.extension.shared.Logger;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class PlayerControlsPatch { public class PlayerControlsPatch {
/** /**
* Injection point. * Injection point.
*/ */
@@ -41,4 +42,11 @@ public class PlayerControlsPatch {
public static void fullscreenButtonVisibilityChanged(boolean isVisible) { public static void fullscreenButtonVisibilityChanged(boolean isVisible) {
// Code added during patching. // Code added during patching.
} }
/**
* Injection point.
*/
public static String getPlayerTopControlsLayoutResourceName(String original) {
return "default";
}
} }

View File

@@ -15,13 +15,10 @@ import android.widget.TextView;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Locale;
import java.util.logging.Level;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
@@ -84,8 +81,8 @@ public final class AnnouncementsPatch {
try { try {
if (isLatestAlready()) return; if (isLatestAlready()) return;
HttpURLConnection connection = AnnouncementsRoutes.getAnnouncementsConnectionFromRoute( HttpURLConnection connection = AnnouncementsRoutes
GET_LATEST_ANNOUNCEMENTS, Locale.getDefault().toLanguageTag()); .getAnnouncementsConnectionFromRoute(GET_LATEST_ANNOUNCEMENTS);
Logger.printDebug(() -> "Get latest announcements route connection url: " + connection.getURL()); Logger.printDebug(() -> "Get latest announcements route connection url: " + connection.getURL());
@@ -98,11 +95,11 @@ public final class AnnouncementsPatch {
LocalDateTime archivedAt = LocalDateTime.MAX; LocalDateTime archivedAt = LocalDateTime.MAX;
Level level = Level.INFO; Level level = Level.INFO;
try { try {
final var announcement = new JSONObject(jsonString); final var announcement = new JSONArray(jsonString).getJSONObject(0);
id = announcement.getInt("id"); id = announcement.getInt("id");
title = announcement.getString("title"); title = announcement.getString("title");
message = announcement.getJSONObject("content").getString("message"); message = announcement.getString("content");
if (!announcement.isNull("archived_at")) { if (!announcement.isNull("archived_at")) {
archivedAt = LocalDateTime.parse(announcement.getString("archived_at")); archivedAt = LocalDateTime.parse(announcement.getString("archived_at"));
} }

View File

@@ -9,9 +9,9 @@ import java.net.HttpURLConnection;
import static app.revanced.extension.youtube.requests.Route.Method.GET; import static app.revanced.extension.youtube.requests.Route.Method.GET;
public class AnnouncementsRoutes { public class AnnouncementsRoutes {
public static final Route GET_LATEST_ANNOUNCEMENTS = new Route(GET, "/announcements/latest?tag=youtube");
public static final Route GET_LATEST_ANNOUNCEMENT_IDS = new Route(GET, "/announcements/latest/id?tag=youtube");
private static final String ANNOUNCEMENTS_PROVIDER = "https://api.revanced.app/v4"; private static final String ANNOUNCEMENTS_PROVIDER = "https://api.revanced.app/v4";
public static final Route GET_LATEST_ANNOUNCEMENT_IDS = new Route(GET, "/announcements/latest/id?tag=youtube");
public static final Route GET_LATEST_ANNOUNCEMENTS = new Route(GET, "/announcements/latest?tag=youtube");
private AnnouncementsRoutes() { private AnnouncementsRoutes() {
} }

View File

@@ -31,7 +31,7 @@ public final class LayoutComponentsFilter extends Filter {
"cell_description_body" "cell_description_body"
); );
private static final ByteArrayFilterGroup mixPlaylists = new ByteArrayFilterGroup( private static final ByteArrayFilterGroup mixPlaylists = new ByteArrayFilterGroup(
Settings.HIDE_MIX_PLAYLISTS, null,
"&list=" "&list="
); );
@@ -344,6 +344,10 @@ public final class LayoutComponentsFilter extends Filter {
*/ */
public static boolean filterMixPlaylists(final Object conversionContext, @Nullable final byte[] bytes) { public static boolean filterMixPlaylists(final Object conversionContext, @Nullable final byte[] bytes) {
try { try {
if (!Settings.HIDE_MIX_PLAYLISTS.get()) {
return false;
}
if (bytes == null) { if (bytes == null) {
Logger.printDebug(() -> "bytes is null"); Logger.printDebug(() -> "bytes is null");
return false; return false;

View File

@@ -22,12 +22,12 @@ import app.revanced.extension.youtube.shared.PlayerType;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class ShortsFilter extends Filter { public final class ShortsFilter extends Filter {
private static final boolean HIDE_SHORTS_NAVIGATION_BAR = Settings.HIDE_SHORTS_NAVIGATION_BAR.get(); private static final boolean HIDE_SHORTS_NAVIGATION_BAR = Settings.HIDE_SHORTS_NAVIGATION_BAR.get();
private final static String REEL_CHANNEL_BAR_PATH = "reel_channel_bar.eml"; private static final String REEL_CHANNEL_BAR_PATH = "reel_channel_bar.eml";
/** /**
* For paid promotion label and subscribe button that appears in the channel bar. * For paid promotion label and subscribe button that appears in the channel bar.
*/ */
private final static String REEL_METAPANEL_PATH = "reel_metapanel.eml"; private static final String REEL_METAPANEL_PATH = "reel_metapanel.eml";
/** /**
* Tags that appears when opening the Shorts player. * Tags that appears when opening the Shorts player.
@@ -52,7 +52,7 @@ public final class ShortsFilter extends Filter {
private final StringFilterGroup suggestedAction; private final StringFilterGroup suggestedAction;
private final ByteArrayFilterGroupList suggestedActionsGroupList = new ByteArrayFilterGroupList(); private final ByteArrayFilterGroupList suggestedActionsGroupList = new ByteArrayFilterGroupList();
private final StringFilterGroup actionBar; private final StringFilterGroup actionButton;
private final ByteArrayFilterGroupList videoActionButtonGroupList = new ByteArrayFilterGroupList(); private final ByteArrayFilterGroupList videoActionButtonGroupList = new ByteArrayFilterGroupList();
public ShortsFilter() { public ShortsFilter() {
@@ -156,9 +156,9 @@ public final class ShortsFilter extends Filter {
"reel_player_disclosure.eml" "reel_player_disclosure.eml"
); );
actionBar = new StringFilterGroup( actionButton = new StringFilterGroup(
null, null,
"shorts_action_bar" "shorts_video_action_button.eml"
); );
suggestedAction = new StringFilterGroup( suggestedAction = new StringFilterGroup(
@@ -167,7 +167,7 @@ public final class ShortsFilter extends Filter {
); );
addPathCallbacks( addPathCallbacks(
shortsCompactFeedVideoPath, suggestedAction, actionBar, joinButton, subscribeButton, shortsCompactFeedVideoPath, suggestedAction, actionButton, joinButton, subscribeButton,
paidPromotionButton, pausedOverlayButtons, channelBar, fullVideoLinkLabel, videoTitle, paidPromotionButton, pausedOverlayButtons, channelBar, fullVideoLinkLabel, videoTitle,
reelSoundMetadata, soundButton, infoPanel, stickers, likeFountain reelSoundMetadata, soundButton, infoPanel, stickers, likeFountain
); );
@@ -287,7 +287,7 @@ public final class ShortsFilter extends Filter {
} }
// Video action buttons (like, dislike, comment, share, remix) have the same path. // Video action buttons (like, dislike, comment, share, remix) have the same path.
if (matchedGroup == actionBar) { if (matchedGroup == actionButton) {
if (videoActionButtonGroupList.check(protobufBufferArray).isFiltered()) { if (videoActionButtonGroupList.check(protobufBufferArray).isFiltered()) {
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex); return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
} }
@@ -416,7 +416,6 @@ public final class ShortsFilter extends Filter {
// endregion // endregion
public static void setNavigationBar(PivotBar view) { public static void setNavigationBar(PivotBar view) {
Logger.printDebug(() -> "Setting navigation bar");
pivotBarRef = new WeakReference<>(view); pivotBarRef = new WeakReference<>(view);
} }

View File

@@ -62,19 +62,12 @@ public class RememberVideoQualityPatch {
*/ */
public static int setVideoQuality(Object[] qualities, final int originalQualityIndex, Object qInterface, String qIndexMethod) { public static int setVideoQuality(Object[] qualities, final int originalQualityIndex, Object qInterface, String qIndexMethod) {
try { try {
if (!(qualityNeedsUpdating || userChangedDefaultQuality) || qInterface == null) { final int preferredQuality = Utils.getNetworkType() == NetworkType.MOBILE
return originalQualityIndex; ? mobileQualitySetting.get()
} : wifiQualitySetting.get();
qualityNeedsUpdating = false;
final int preferredQuality;
if (Utils.getNetworkType() == NetworkType.MOBILE) {
preferredQuality = mobileQualitySetting.get();
} else {
preferredQuality = wifiQualitySetting.get();
}
if (!userChangedDefaultQuality && preferredQuality == AUTOMATIC_VIDEO_QUALITY_VALUE) { if (!userChangedDefaultQuality && preferredQuality == AUTOMATIC_VIDEO_QUALITY_VALUE) {
return originalQualityIndex; // nothing to do return originalQualityIndex; // Nothing to do.
} }
if (videoQualities == null || videoQualities.size() != qualities.length) { if (videoQualities == null || videoQualities.size() != qualities.length) {
@@ -87,7 +80,11 @@ public class RememberVideoQualityPatch {
} }
} }
} }
Logger.printDebug(() -> "videoQualities: " + videoQualities);
// After changing videos the qualities can initially be for the prior video.
// So if the qualities have changed an update is needed.
qualityNeedsUpdating = true;
Logger.printDebug(() -> "VideoQualities: " + videoQualities);
} }
if (userChangedDefaultQuality) { if (userChangedDefaultQuality) {
@@ -98,7 +95,12 @@ public class RememberVideoQualityPatch {
return userSelectedQualityIndex; return userSelectedQualityIndex;
} }
// find the highest quality that is equal to or less than the preferred if (!qualityNeedsUpdating) {
return originalQualityIndex;
}
qualityNeedsUpdating = false;
// Find the highest quality that is equal to or less than the preferred.
int qualityToUse = videoQualities.get(0); // first element is automatic mode int qualityToUse = videoQualities.get(0); // first element is automatic mode
int qualityIndexToUse = 0; int qualityIndexToUse = 0;
int i = 0; int i = 0;
@@ -112,20 +114,18 @@ public class RememberVideoQualityPatch {
// If the desired quality index is equal to the original index, // If the desired quality index is equal to the original index,
// then the video is already set to the desired default quality. // then the video is already set to the desired default quality.
// final int qualityToUseFinal = qualityToUse;
// The method could return here, but the UI video quality flyout will still
// show 'Auto' (ie: Auto (480p))
// It appears that "Auto" picks the resolution on video load,
// and it does not appear to change the resolution during playback.
//
// To prevent confusion, set the video index anyways (even if it matches the existing index)
// As that will force the UI picker to not display "Auto" which may confuse the user.
if (qualityIndexToUse == originalQualityIndex) { if (qualityIndexToUse == originalQualityIndex) {
Logger.printDebug(() -> "Video is already preferred quality: " + preferredQuality); // On first load of a new video, if the UI video quality flyout menu
// is not updated then it will still show 'Auto' (ie: Auto (480p)),
// even though it's already set to the desired resolution.
//
// To prevent confusion, set the video index anyways (even if it matches the existing index)
// as that will force the UI picker to not display "Auto".
Logger.printDebug(() -> "Video is already preferred quality: " + qualityToUseFinal);
} else { } else {
final int qualityToUseLog = qualityToUse; Logger.printDebug(() -> "Changing video quality from: "
Logger.printDebug(() -> "Quality changed from: " + videoQualities.get(originalQualityIndex) + " to: " + qualityToUseFinal);
+ videoQualities.get(originalQualityIndex) + " to: " + qualityToUseLog);
} }
Method m = qInterface.getClass().getMethod(qIndexMethod, Integer.TYPE); Method m = qInterface.getClass().getMethod(qIndexMethod, Integer.TYPE);

View File

@@ -1,5 +1,6 @@
package app.revanced.extension.youtube.patches.playback.speed; package app.revanced.extension.youtube.patches.playback.speed;
import static app.revanced.extension.shared.StringRef.sf;
import static app.revanced.extension.shared.StringRef.str; import static app.revanced.extension.shared.StringRef.str;
import android.preference.ListPreference; import android.preference.ListPreference;
@@ -10,15 +11,18 @@ import android.view.ViewParent;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import app.revanced.extension.youtube.patches.components.PlaybackSpeedMenuFilterPatch; import java.util.Arrays;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.patches.components.PlaybackSpeedMenuFilterPatch;
import java.util.Arrays; import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class CustomPlaybackSpeedPatch { public class CustomPlaybackSpeedPatch {
private static final float PLAYBACK_SPEED_AUTO = Settings.PLAYBACK_SPEED_DEFAULT.defaultValue;
/** /**
* Maximum playback speed, exclusive value. Custom speeds must be less than this value. * Maximum playback speed, exclusive value. Custom speeds must be less than this value.
* *
@@ -26,7 +30,7 @@ public class CustomPlaybackSpeedPatch {
* and the UI selector starts flickering and acting weird. * and the UI selector starts flickering and acting weird.
* Over 10x and the speeds show up out of order in the UI selector. * Over 10x and the speeds show up out of order in the UI selector.
*/ */
public static final float MAXIMUM_PLAYBACK_SPEED = 8; public static final float PLAYBACK_SPEED_MAXIMUM = 8;
/** /**
* Custom playback speeds. * Custom playback speeds.
@@ -69,8 +73,8 @@ public class CustomPlaybackSpeedPatch {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
if (speedFloat >= MAXIMUM_PLAYBACK_SPEED) { if (speedFloat >= PLAYBACK_SPEED_MAXIMUM) {
resetCustomSpeeds(str("revanced_custom_playback_speeds_invalid", MAXIMUM_PLAYBACK_SPEED)); resetCustomSpeeds(str("revanced_custom_playback_speeds_invalid", PLAYBACK_SPEED_MAXIMUM));
loadCustomSpeeds(); loadCustomSpeeds();
return; return;
} }
@@ -98,10 +102,15 @@ public class CustomPlaybackSpeedPatch {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public static void initializeListPreference(ListPreference preference) { public static void initializeListPreference(ListPreference preference) {
if (preferenceListEntries == null) { if (preferenceListEntries == null) {
preferenceListEntries = new String[customPlaybackSpeeds.length]; final int numberOfEntries = customPlaybackSpeeds.length + 1;
preferenceListEntryValues = new String[customPlaybackSpeeds.length]; preferenceListEntries = new String[numberOfEntries];
preferenceListEntryValues = new String[numberOfEntries];
int i = 0; // Auto speed (same behavior as unpatched).
preferenceListEntries[0] = sf("revanced_custom_playback_speeds_auto").toString();
preferenceListEntryValues[0] = String.valueOf(PLAYBACK_SPEED_AUTO);
int i = 1;
for (float speed : customPlaybackSpeeds) { for (float speed : customPlaybackSpeeds) {
String speedString = String.valueOf(speed); String speedString = String.valueOf(speed);
preferenceListEntries[i] = speedString + "x"; preferenceListEntries[i] = speedString + "x";

View File

@@ -33,7 +33,7 @@ public final class RememberPlaybackSpeedPatch {
// With the 0.05x menu, if the speed is set by integrations to higher than 2.0x // With the 0.05x menu, if the speed is set by integrations to higher than 2.0x
// then the menu will allow increasing without bounds but the max speed is // then the menu will allow increasing without bounds but the max speed is
// still capped to under 8.0x. // still capped to under 8.0x.
playbackSpeed = Math.min(playbackSpeed, CustomPlaybackSpeedPatch.MAXIMUM_PLAYBACK_SPEED - 0.05f); playbackSpeed = Math.min(playbackSpeed, CustomPlaybackSpeedPatch.PLAYBACK_SPEED_MAXIMUM - 0.05f);
// Prevent toast spamming if using the 0.05x adjustments. // Prevent toast spamming if using the 0.05x adjustments.
// Show exactly one toast after the user stops interacting with the speed menu. // Show exactly one toast after the user stops interacting with the speed menu.

View File

@@ -2,9 +2,12 @@ package app.revanced.extension.youtube.patches.theme;
import static app.revanced.extension.shared.StringRef.str; import static app.revanced.extension.shared.StringRef.str;
import android.content.res.Resources;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.AnimatedVectorDrawable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
@@ -16,7 +19,8 @@ public final class SeekbarColorPatch {
private static final boolean SEEKBAR_CUSTOM_COLOR_ENABLED = Settings.SEEKBAR_CUSTOM_COLOR.get(); private static final boolean SEEKBAR_CUSTOM_COLOR_ENABLED = Settings.SEEKBAR_CUSTOM_COLOR.get();
/** /**
* Default color of the seekbar. * Default color of the litho seekbar.
* Differs slightly from the default custom seekbar color setting.
*/ */
private static final int ORIGINAL_SEEKBAR_COLOR = 0xFFFF0000; private static final int ORIGINAL_SEEKBAR_COLOR = 0xFFFF0000;
@@ -72,12 +76,76 @@ public final class SeekbarColorPatch {
return seekbarColor; return seekbarColor;
} }
/**
* Injection point
*/
public static boolean playerSeekbarGradientEnabled(boolean original) { public static boolean playerSeekbarGradientEnabled(boolean original) {
if (SEEKBAR_CUSTOM_COLOR_ENABLED) return false; if (SEEKBAR_CUSTOM_COLOR_ENABLED) return false;
return original; return original;
} }
/**
* Injection point
*/
public static boolean useLotteLaunchSplashScreen(boolean original) {
Logger.printDebug(() -> "useLotteLaunchSplashScreen original: " + original);
if (SEEKBAR_CUSTOM_COLOR_ENABLED) return false;
return original;
}
private static int colorChannelTo3Bits(int channel8Bits) {
final float channel3Bits = channel8Bits * 7 / 255f;
// If a color channel is near zero, then allow rounding up so values between
// 0x12 and 0x23 will show as 0x24. But always round down when the channel is
// near full saturation, otherwise rounding to nearest will cause all values
// between 0xEC and 0xFE to always show as full saturation (0xFF).
return channel3Bits < 6
? Math.round(channel3Bits)
: (int) channel3Bits;
}
private static String get9BitStyleIdentifier(int color24Bit) {
final int r3 = colorChannelTo3Bits(Color.red(color24Bit));
final int g3 = colorChannelTo3Bits(Color.green(color24Bit));
final int b3 = colorChannelTo3Bits(Color.blue(color24Bit));
return String.format(Locale.US, "splash_seekbar_color_style_%d_%d_%d", r3, g3, b3);
}
/**
* Injection point
*/
public static void setSplashAnimationDrawableTheme(AnimatedVectorDrawable vectorDrawable) {
// Alternatively a ColorMatrixColorFilter can be used to change the color of the drawable
// without using any styles, but a color filter cannot selectively change the seekbar
// while keeping the red YT logo untouched.
// Even if the seekbar color xml value is changed to a completely different color (such as green),
// a color filter still cannot be selectively applied when the drawable has more than 1 color.
try {
String seekbarStyle = get9BitStyleIdentifier(seekbarColor);
Logger.printDebug(() -> "Using splash seekbar style: " + seekbarStyle);
final int styleIdentifierDefault = Utils.getResourceIdentifier(
seekbarStyle,
"style"
);
if (styleIdentifierDefault == 0) {
throw new RuntimeException("Seekbar style not found: " + seekbarStyle);
}
Resources.Theme theme = Utils.getContext().getResources().newTheme();
theme.applyStyle(styleIdentifierDefault, true);
vectorDrawable.applyTheme(theme);
} catch (Exception ex) {
Logger.printException(() -> "setSplashAnimationDrawableTheme failure", ex);
}
}
/** /**
* Injection point. * Injection point.
* *

View File

@@ -147,6 +147,7 @@ public class ReturnYouTubeDislikeApi {
*/ */
private static void randomlyWaitIfLocallyDebugging() { private static void randomlyWaitIfLocallyDebugging() {
final boolean DEBUG_RANDOMLY_DELAY_NETWORK_CALLS = false; // set true to debug UI final boolean DEBUG_RANDOMLY_DELAY_NETWORK_CALLS = false; // set true to debug UI
//noinspection ConstantValue
if (DEBUG_RANDOMLY_DELAY_NETWORK_CALLS) { if (DEBUG_RANDOMLY_DELAY_NETWORK_CALLS) {
final long amountOfTimeToWaste = (long) (Math.random() final long amountOfTimeToWaste = (long) (Math.random()
* (API_GET_VOTES_TCP_TIMEOUT_MILLISECONDS + API_GET_VOTES_HTTP_TIMEOUT_MILLISECONDS)); * (API_GET_VOTES_TCP_TIMEOUT_MILLISECONDS + API_GET_VOTES_HTTP_TIMEOUT_MILLISECONDS));
@@ -187,6 +188,7 @@ public class ReturnYouTubeDislikeApi {
*/ */
private static boolean checkIfRateLimitWasHit(int httpResponseCode) { private static boolean checkIfRateLimitWasHit(int httpResponseCode) {
final boolean DEBUG_RATE_LIMIT = false; // set to true, to verify rate limit works final boolean DEBUG_RATE_LIMIT = false; // set to true, to verify rate limit works
//noinspection ConstantValue
if (DEBUG_RATE_LIMIT) { if (DEBUG_RATE_LIMIT) {
final double RANDOM_RATE_LIMIT_PERCENTAGE = 0.2; // 20% chance of a triggering a rate limit final double RANDOM_RATE_LIMIT_PERCENTAGE = 0.2; // 20% chance of a triggering a rate limit
if (Math.random() < RANDOM_RATE_LIMIT_PERCENTAGE) { if (Math.random() < RANDOM_RATE_LIMIT_PERCENTAGE) {

View File

@@ -7,6 +7,7 @@ import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.TextView; import android.widget.TextView;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.preference.AbstractPreferenceFragment;
import app.revanced.extension.youtube.ThemeHelper; import app.revanced.extension.youtube.ThemeHelper;
import app.revanced.extension.youtube.settings.preference.ReVancedPreferenceFragment; import app.revanced.extension.youtube.settings.preference.ReVancedPreferenceFragment;
import app.revanced.extension.youtube.settings.preference.ReturnYouTubeDislikePreferenceFragment; import app.revanced.extension.youtube.settings.preference.ReturnYouTubeDislikePreferenceFragment;
@@ -39,7 +40,7 @@ public class LicenseActivityHook {
PreferenceFragment fragment; PreferenceFragment fragment;
String toolbarTitleResourceName; String toolbarTitleResourceName;
String dataString = licenseActivity.getIntent().getDataString(); String dataString = Objects.requireNonNull(licenseActivity.getIntent().getDataString());
switch (dataString) { switch (dataString) {
case "revanced_sb_settings_intent": case "revanced_sb_settings_intent":
toolbarTitleResourceName = "revanced_sb_settings_title"; toolbarTitleResourceName = "revanced_sb_settings_title";
@@ -59,12 +60,14 @@ public class LicenseActivityHook {
} }
setToolbarTitle(licenseActivity, toolbarTitleResourceName); setToolbarTitle(licenseActivity, toolbarTitleResourceName);
//noinspection deprecation
licenseActivity.getFragmentManager() licenseActivity.getFragmentManager()
.beginTransaction() .beginTransaction()
.replace(getResourceIdentifier("revanced_settings_fragments", "id"), fragment) .replace(getResourceIdentifier("revanced_settings_fragments", "id"), fragment)
.commit(); .commit();
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "onCreate failure", ex); Logger.printException(() -> "initialize failure", ex);
} }
} }
@@ -80,11 +83,7 @@ public class LicenseActivityHook {
ViewGroup toolbar = activity.findViewById(getToolbarResourceId()); ViewGroup toolbar = activity.findViewById(getToolbarResourceId());
ImageButton imageButton = Objects.requireNonNull(getChildView(toolbar, false, ImageButton imageButton = Objects.requireNonNull(getChildView(toolbar, false,
view -> view instanceof ImageButton)); view -> view instanceof ImageButton));
final int backButtonResource = getResourceIdentifier(ThemeHelper.isDarkTheme() imageButton.setImageDrawable(AbstractPreferenceFragment.getBackButtonDrawable());
? "yt_outline_arrow_left_white_24"
: "yt_outline_arrow_left_black_24",
"drawable");
imageButton.setImageDrawable(activity.getResources().getDrawable(backButtonResource));
imageButton.setOnClickListener(view -> activity.onBackPressed()); imageButton.setOnClickListener(view -> activity.onBackPressed());
} }

View File

@@ -9,6 +9,7 @@ import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerH
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType; import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType;
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.*; import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.*;
import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability; import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability;
import static app.revanced.extension.youtube.patches.VersionCheckPatch.IS_19_17_OR_GREATER;
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.*; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.*;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
@@ -23,7 +24,6 @@ import app.revanced.extension.youtube.patches.spoof.SpoofAppVersionPatch;
import app.revanced.extension.youtube.patches.spoof.SpoofVideoStreamsPatch; import app.revanced.extension.youtube.patches.spoof.SpoofVideoStreamsPatch;
import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings; import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
@SuppressWarnings("deprecation")
public class Settings extends BaseSettings { public class Settings extends BaseSettings {
// Video // Video
public static final BooleanSetting RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE); public static final BooleanSetting RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE);
@@ -33,7 +33,7 @@ public class Settings extends BaseSettings {
// Speed // Speed
public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_last_selected", FALSE); public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_last_selected", FALSE);
public static final BooleanSetting CUSTOM_SPEED_MENU = new BooleanSetting("revanced_custom_speed_menu", TRUE); public static final BooleanSetting CUSTOM_SPEED_MENU = new BooleanSetting("revanced_custom_speed_menu", TRUE);
public static final FloatSetting PLAYBACK_SPEED_DEFAULT = new FloatSetting("revanced_playback_speed_default", 1.0f); public static final FloatSetting PLAYBACK_SPEED_DEFAULT = new FloatSetting("revanced_playback_speed_default", -2.0f);
public static final StringSetting CUSTOM_PLAYBACK_SPEEDS = new StringSetting("revanced_custom_playback_speeds", public static final StringSetting CUSTOM_PLAYBACK_SPEEDS = new StringSetting("revanced_custom_playback_speeds",
"0.25\n0.5\n0.75\n0.9\n0.95\n1.0\n1.05\n1.1\n1.25\n1.5\n1.75\n2.0\n3.0\n4.0\n5.0", true); "0.25\n0.5\n0.75\n0.9\n0.95\n1.0\n1.05\n1.1\n1.25\n1.5\n1.75\n2.0\n3.0\n4.0\n5.0", true);
@@ -128,8 +128,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_AUTOPLAY_BUTTON = new BooleanSetting("revanced_hide_autoplay_button", TRUE, true); public static final BooleanSetting HIDE_AUTOPLAY_BUTTON = new BooleanSetting("revanced_hide_autoplay_button", TRUE, true);
public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_hide_cast_button", TRUE, true); public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_hide_cast_button", TRUE, true);
public static final BooleanSetting HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS = new BooleanSetting("revanced_hide_player_previous_next_buttons", FALSE, true); public static final BooleanSetting HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS = new BooleanSetting("revanced_hide_player_previous_next_buttons", FALSE, true);
@Deprecated private static final BooleanSetting DEPRECATED_HIDE_PLAYER_BUTTONS = new BooleanSetting("revanced_hide_player_buttons", FALSE, true);
public static final BooleanSetting HIDE_PLAYER_BUTTONS = new BooleanSetting("revanced_hide_player_buttons", FALSE, true);
public static final BooleanSetting COPY_VIDEO_URL = new BooleanSetting("revanced_copy_video_url", FALSE); public static final BooleanSetting COPY_VIDEO_URL = new BooleanSetting("revanced_copy_video_url", FALSE);
public static final BooleanSetting COPY_VIDEO_URL_TIMESTAMP = new BooleanSetting("revanced_copy_video_url_timestamp", TRUE); public static final BooleanSetting COPY_VIDEO_URL_TIMESTAMP = new BooleanSetting("revanced_copy_video_url_timestamp", TRUE);
public static final BooleanSetting PLAYBACK_SPEED_DIALOG_BUTTON = new BooleanSetting("revanced_playback_speed_dialog_button", FALSE); public static final BooleanSetting PLAYBACK_SPEED_DIALOG_BUTTON = new BooleanSetting("revanced_playback_speed_dialog_button", FALSE);
@@ -192,14 +191,13 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_PLAYER_FLYOUT_SLEEP_TIMER = new BooleanSetting("revanced_hide_player_flyout_sleep_timer", FALSE); public static final BooleanSetting HIDE_PLAYER_FLYOUT_SLEEP_TIMER = new BooleanSetting("revanced_hide_player_flyout_sleep_timer", FALSE);
public static final BooleanSetting HIDE_PLAYER_FLYOUT_STABLE_VOLUME = new BooleanSetting("revanced_hide_player_flyout_stable_volume", FALSE); public static final BooleanSetting HIDE_PLAYER_FLYOUT_STABLE_VOLUME = new BooleanSetting("revanced_hide_player_flyout_stable_volume", FALSE);
public static final BooleanSetting HIDE_PLAYER_FLYOUT_WATCH_IN_VR = new BooleanSetting("revanced_hide_player_flyout_watch_in_vr", TRUE); public static final BooleanSetting HIDE_PLAYER_FLYOUT_WATCH_IN_VR = new BooleanSetting("revanced_hide_player_flyout_watch_in_vr", TRUE);
@Deprecated
private static final BooleanSetting DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_video_quality_menu_footer", FALSE); private static final BooleanSetting DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_video_quality_menu_footer", FALSE);
public static final BooleanSetting HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_player_flyout_video_quality_footer", FALSE); public static final BooleanSetting HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_player_flyout_video_quality_footer", FALSE);
// General layout // General layout
public static final EnumSetting<StartPage> CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.ORIGINAL, true); public static final EnumSetting<StartPage> CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.ORIGINAL, true);
public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message"); public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message");
public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", "17.41.37", true, parent(SPOOF_APP_VERSION)); public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", IS_19_17_OR_GREATER ? "18.38.44" : "17.33.42", true, parent(SPOOF_APP_VERSION));
public static final BooleanSetting TABLET_LAYOUT = new BooleanSetting("revanced_tablet_layout", FALSE, true, "revanced_tablet_layout_user_dialog_message"); public static final BooleanSetting TABLET_LAYOUT = new BooleanSetting("revanced_tablet_layout", FALSE, true, "revanced_tablet_layout_user_dialog_message");
public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true); public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true);
public static final BooleanSetting BYPASS_IMAGE_REGION_RESTRICTIONS = new BooleanSetting("revanced_bypass_image_region_restrictions", FALSE, true); public static final BooleanSetting BYPASS_IMAGE_REGION_RESTRICTIONS = new BooleanSetting("revanced_bypass_image_region_restrictions", FALSE, true);
@@ -235,7 +233,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_SHORTS_UPCOMING_BUTTON = new BooleanSetting("revanced_hide_shorts_upcoming_button", TRUE); public static final BooleanSetting HIDE_SHORTS_UPCOMING_BUTTON = new BooleanSetting("revanced_hide_shorts_upcoming_button", TRUE);
public static final BooleanSetting HIDE_SHORTS_GREEN_SCREEN_BUTTON = new BooleanSetting("revanced_hide_shorts_green_screen_button", TRUE); public static final BooleanSetting HIDE_SHORTS_GREEN_SCREEN_BUTTON = new BooleanSetting("revanced_hide_shorts_green_screen_button", TRUE);
public static final BooleanSetting HIDE_SHORTS_HASHTAG_BUTTON = new BooleanSetting("revanced_hide_shorts_hashtag_button", TRUE); public static final BooleanSetting HIDE_SHORTS_HASHTAG_BUTTON = new BooleanSetting("revanced_hide_shorts_hashtag_button", TRUE);
public static final BooleanSetting HIDE_SHORTS_SEARCH_SUGGESTIONS = new BooleanSetting("revanced_hide_shorts_search_suggestions", FALSE); public static final BooleanSetting HIDE_SHORTS_SEARCH_SUGGESTIONS = new BooleanSetting("revanced_hide_shorts_search_suggestions", TRUE);
public static final BooleanSetting HIDE_SHORTS_STICKERS = new BooleanSetting("revanced_hide_shorts_stickers", TRUE); public static final BooleanSetting HIDE_SHORTS_STICKERS = new BooleanSetting("revanced_hide_shorts_stickers", TRUE);
public static final BooleanSetting HIDE_SHORTS_SUPER_THANKS_BUTTON = new BooleanSetting("revanced_hide_shorts_super_thanks_button", TRUE); public static final BooleanSetting HIDE_SHORTS_SUPER_THANKS_BUTTON = new BooleanSetting("revanced_hide_shorts_super_thanks_button", TRUE);
public static final BooleanSetting HIDE_SHORTS_LIKE_FOUNTAIN = new BooleanSetting("revanced_hide_shorts_like_fountain", TRUE); public static final BooleanSetting HIDE_SHORTS_LIKE_FOUNTAIN = new BooleanSetting("revanced_hide_shorts_like_fountain", TRUE);
@@ -274,7 +272,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting SPOOF_DEVICE_DIMENSIONS = new BooleanSetting("revanced_spoof_device_dimensions", FALSE, true, public static final BooleanSetting SPOOF_DEVICE_DIMENSIONS = new BooleanSetting("revanced_spoof_device_dimensions", FALSE, true,
"revanced_spoof_device_dimensions_user_dialog_message"); "revanced_spoof_device_dimensions_user_dialog_message");
public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE); public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE);
public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE); public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE, false, false);
public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true,"revanced_spoof_video_streams_user_dialog_message"); public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true,"revanced_spoof_video_streams_user_dialog_message");
public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true, public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofVideoStreamsPatch.ForceiOSAVCAvailability()); "revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofVideoStreamsPatch.ForceiOSAVCAvailability());
@@ -377,16 +375,21 @@ public class Settings extends BaseSettings {
migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID); migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID);
// Old spoof versions that no longer work reliably. migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_BUTTONS, HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS);
if (SpoofAppVersionPatch.isSpoofingToLessThan("17.33.00")) {
Logger.printInfo(() -> "Resetting spoof app version target");
Settings.SPOOF_APP_VERSION_TARGET.resetToDefault();
}
migrateOldSettingToNew(HIDE_PLAYER_BUTTONS, HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS);
migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER, HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER); migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER, HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER);
// Old spoof versions that no longer work reliably.
if (SpoofAppVersionPatch.isSpoofingToLessThan(SPOOF_APP_VERSION_TARGET.defaultValue)) {
Logger.printInfo(() -> "Resetting spoof app version target");
SPOOF_APP_VERSION_TARGET.resetToDefault();
}
// Migrate renamed enum type.
if (MINIPLAYER_TYPE.get() == PHONE) {
MINIPLAYER_TYPE.save(MINIMAL);
}
// endregion // endregion
} }
} }

View File

@@ -49,7 +49,7 @@ enum class PlayerType {
companion object { companion object {
private val nameToPlayerType = values().associateBy { it.name } private val nameToPlayerType = PlayerType.entries.associateBy { it.name }
@JvmStatic @JvmStatic
fun setFromString(enumName: String) { fun setFromString(enumName: String) {

View File

@@ -22,7 +22,7 @@ enum class VideoState {
companion object { companion object {
private val nameToVideoState = values().associateBy { it.name } private val nameToVideoState = VideoState.entries.associateBy { it.name }
@JvmStatic @JvmStatic
fun setFromString(enumName: String) { fun setFromString(enumName: String) {

View File

@@ -382,7 +382,6 @@ public class SponsorBlockUtils {
return statsNumberFormatter.format(viewCount); return statsNumberFormatter.format(viewCount);
} }
@SuppressWarnings("ConstantConditions")
private static long parseSegmentTime(@NonNull String time) { private static long parseSegmentTime(@NonNull String time) {
Matcher matcher = manualEditTimePattern.matcher(time); Matcher matcher = manualEditTimePattern.matcher(time);
if (!matcher.matches()) { if (!matcher.matches()) {

View File

@@ -113,6 +113,7 @@ public class SBRequester {
// Could benefit from: // Could benefit from:
// 1) collection of YouTube videos with test segment times (verify client skip timing matches the video, verify seekbar draws correctly) // 1) collection of YouTube videos with test segment times (verify client skip timing matches the video, verify seekbar draws correctly)
// 2) unit tests (verify everything else) // 2) unit tests (verify everything else)
//noinspection ConstantValue
if (false) { if (false) {
segments.clear(); segments.clear();
// Test auto-hide skip button: // Test auto-hide skip button:

View File

@@ -1,7 +1,5 @@
package app.revanced.extension.youtube.sponsorblock.ui; package app.revanced.extension.youtube.sponsorblock.ui;
import static app.revanced.extension.shared.Utils.getResourceIdentifier;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;

View File

@@ -107,12 +107,13 @@ public final class NewSegmentLayout extends FrameLayout {
*/ */
private void initializeButton(final Context context, final String resourceIdentifierName, private void initializeButton(final Context context, final String resourceIdentifierName,
final ButtonOnClickHandlerFunction handler, final String debugMessage) { final ButtonOnClickHandlerFunction handler, final String debugMessage) {
final ImageButton button = findViewById(getResourceIdentifier(context, resourceIdentifierName, "id")); ImageButton button = findViewById(getResourceIdentifier(context, resourceIdentifierName, "id"));
// Add ripple effect
button.setBackgroundResource(rippleEffectId); button.setBackgroundResource(rippleEffectId);
RippleDrawable rippleDrawable = (RippleDrawable) button.getBackground(); RippleDrawable rippleDrawable = new RippleDrawable(
rippleDrawable.setColor(rippleColorStateList); rippleColorStateList, null, null
);
button.setBackground(rippleDrawable);
button.setOnClickListener((v) -> { button.setOnClickListener((v) -> {
handler.apply(); handler.apply();
@@ -121,7 +122,7 @@ public final class NewSegmentLayout extends FrameLayout {
} }
@FunctionalInterface @FunctionalInterface
public interface ButtonOnClickHandlerFunction { private interface ButtonOnClickHandlerFunction {
void apply(); void apply();
} }
} }

View File

@@ -1,7 +1,5 @@
package app.revanced.extension.youtube.sponsorblock.ui; package app.revanced.extension.youtube.sponsorblock.ui;
import static app.revanced.extension.shared.Utils.getResourceIdentifier;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;

View File

@@ -7,8 +7,6 @@ import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.TypedValue import android.util.TypedValue
import android.view.HapticFeedbackConstants import android.view.HapticFeedbackConstants
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout import android.widget.RelativeLayout
import android.widget.TextView import android.widget.TextView
import app.revanced.extension.shared.StringRef.str import app.revanced.extension.shared.StringRef.str
@@ -59,8 +57,8 @@ class SwipeControlsOverlayLayout(
val compoundIconPadding = 4.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP) val compoundIconPadding = 4.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP)
feedbackTextView = TextView(context).apply { feedbackTextView = TextView(context).apply {
layoutParams = LayoutParams( layoutParams = LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
).apply { ).apply {
addRule(CENTER_IN_PARENT, TRUE) addRule(CENTER_IN_PARENT, TRUE)
setPadding( setPadding(
@@ -91,7 +89,7 @@ class SwipeControlsOverlayLayout(
private val feedbackHideHandler = Handler(Looper.getMainLooper()) private val feedbackHideHandler = Handler(Looper.getMainLooper())
private val feedbackHideCallback = Runnable { private val feedbackHideCallback = Runnable {
feedbackTextView.visibility = View.GONE feedbackTextView.visibility = GONE
} }
/** /**

View File

@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
org.gradle.parallel = true org.gradle.parallel = true
android.useAndroidX = true android.useAndroidX = true
kotlin.code.style = official kotlin.code.style = official
version = 5.0.0-dev.2 version = 5.2.0-dev.3

View File

@@ -503,6 +503,10 @@ public final class app/revanced/patches/reddit/customclients/sync/syncforreddit/
public static final fun getUseUserEndpointPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getUseUserEndpointPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
} }
public final class app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/FixVideoDownloadsPatchKt {
public static final fun getFixVideoDownloadsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatchKt { public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatchKt {
public static final fun getFixVideoDownloadsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getFixVideoDownloadsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
} }
@@ -1324,6 +1328,7 @@ public final class app/revanced/patches/youtube/misc/playservice/VersionCheckPat
public static final fun is_19_36_or_greater ()Z public static final fun is_19_36_or_greater ()Z
public static final fun is_19_41_or_greater ()Z public static final fun is_19_41_or_greater ()Z
public static final fun is_19_43_or_greater ()Z public static final fun is_19_43_or_greater ()Z
public static final fun is_19_46_or_greater ()Z
} }
public final class app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatchKt { public final class app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatchKt {
@@ -1444,10 +1449,12 @@ public final class app/revanced/util/BytecodeUtilsKt {
public static final fun indexOfFirstInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)I public static final fun indexOfFirstInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)I
public static synthetic fun indexOfFirstInstructionOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I public static synthetic fun indexOfFirstInstructionOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I
public static synthetic fun indexOfFirstInstructionOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)I public static synthetic fun indexOfFirstInstructionOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)I
public static final fun indexOfFirstInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)I
public static final fun indexOfFirstInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;)I public static final fun indexOfFirstInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;)I
public static final fun indexOfFirstInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;)I public static final fun indexOfFirstInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;)I
public static synthetic fun indexOfFirstInstructionReversed$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I public static synthetic fun indexOfFirstInstructionReversed$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I
public static synthetic fun indexOfFirstInstructionReversed$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)I public static synthetic fun indexOfFirstInstructionReversed$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)I
public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)I
public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;)I public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;)I
public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;)I public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;)I
public static synthetic fun indexOfFirstInstructionReversedOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I public static synthetic fun indexOfFirstInstructionReversedOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I

View File

@@ -1,3 +1,5 @@
package app.revanced.patches.facebook.ads.mainfeed
import app.revanced.patcher.fingerprint import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode

View File

@@ -4,14 +4,11 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import baseModelMapperFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
import getSponsoredDataModelTemplateFingerprint
import getStoryVisibilityFingerprint
@Suppress("unused") @Suppress("unused")
val hideSponsoredStoriesPatch = bytecodePatch( val hideSponsoredStoriesPatch = bytecodePatch(

View File

@@ -4,7 +4,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
@Suppress("unused") @Suppress("unused")
val enableCustomTabsPatch = bytecodePatch( val enableCustomTabsPatch = bytecodePatch(

View File

@@ -4,7 +4,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
@Suppress("unused") @Suppress("unused")
val restoreHiddenBackUpWhileChargingTogglePatch = bytecodePatch( val restoreHiddenBackUpWhileChargingTogglePatch = bytecodePatch(

View File

@@ -5,7 +5,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
@Suppress("unused") @Suppress("unused")
val removeDeviceRestrictionsPatch = bytecodePatch( val removeDeviceRestrictionsPatch = bytecodePatch(

View File

@@ -4,7 +4,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
@Suppress("unused") @Suppress("unused")
val disableSwitchingEmojiToStickerPatch = bytecodePatch( val disableSwitchingEmojiToStickerPatch = bytecodePatch(

View File

@@ -7,7 +7,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Suppress("unused")
val hideGetPremiumPatch = bytecodePatch( val hideGetPremiumPatch = bytecodePatch(
name = "Hide 'Get Music Premium' label", name = "Hide 'Get Music Premium' label",
description = "Hides the \"Get Music Premium\" label from the account menu and settings.", description = "Hides the \"Get Music Premium\" label from the account menu and settings.",

View File

@@ -4,7 +4,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
@Suppress("unused")
val backgroundPlaybackPatch = bytecodePatch( val backgroundPlaybackPatch = bytecodePatch(
name = "Remove background playback restrictions", name = "Remove background playback restrictions",
description = "Removes restrictions on background playback, including playing kids videos in the background.", description = "Removes restrictions on background playback, including playing kids videos in the background.",

View File

@@ -7,7 +7,7 @@ import app.revanced.patcher.patch.bytecodePatch
val unlockProPatch = bytecodePatch( val unlockProPatch = bytecodePatch(
name = "Unlock pro", name = "Unlock pro",
) { ) {
compatibleWith("org.totschnig.myexpenses") compatibleWith("org.totschnig.myexpenses"("3.4.9"))
execute { execute {
isEnabledFingerprint.method.addInstructions( isEnabledFingerprint.method.addInstructions(

View File

@@ -10,6 +10,6 @@ val disablePiracyDetectionPatch = bytecodePatch(
execute { execute {
// Do not throw an error if the fingerprint is not resolved. // 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. // This is fine because new versions of the target app do not need this patch.
piracyDetectionFingerprint.method.addInstruction(0, "return-void") piracyDetectionFingerprint.methodOrNull?.addInstruction(0, "return-void")
} }
} }

View File

@@ -1,9 +1,11 @@
package app.revanced.patches.reddit.customclients.sync.detection.piracy package app.revanced.patches.reddit.customclients.sync.detection.piracy
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import app.revanced.patcher.extensions.InstructionExtensions.instructions
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint import app.revanced.patcher.fingerprint
import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.reference.Reference
internal val piracyDetectionFingerprint = fingerprint { internal val piracyDetectionFingerprint = fingerprint {
accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL)
@@ -16,12 +18,9 @@ internal val piracyDetectionFingerprint = fingerprint {
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
) )
custom { method, _ -> custom { method, _ ->
method.implementation?.instructions?.any { method.implementation ?: return@custom false
if (it.opcode != Opcode.NEW_INSTANCE) return@any false method.instructions.any {
it.getReference<Reference>()?.toString() == "Lcom/github/javiersantos/piracychecker/PiracyChecker;"
val reference = (it as ReferenceInstruction).reference }
reference.toString() == "Lcom/github/javiersantos/piracychecker/PiracyChecker;"
} == true
} }
} }

View File

@@ -63,20 +63,20 @@ val spoofClientPatch = spoofClientPatch(
val randomName = (0..100000).random() val randomName = (0..100000).random()
val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)" val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
imgurImageAPIFingerprint.method.replaceInstruction( getUserAgentFingerprint.method.replaceInstruction(
0, 0,
""" """
const-string v0, "$userAgent" const-string v0, "$userAgent"
return-object v0 return-object v0
""", """,
) )
// endregion // endregion
// region Patch Imgur API URL. // region Patch Imgur API URL.
val apiUrlIndex = getUserAgentFingerprint.stringMatches!!.first().index val apiUrlIndex = imgurImageAPIFingerprint.stringMatches!!.first().index
getUserAgentFingerprint.method.replaceInstruction( imgurImageAPIFingerprint.method.replaceInstruction(
apiUrlIndex, apiUrlIndex,
"const-string v1, \"https://api.imgur.com/3/image\"", "const-string v1, \"https://api.imgur.com/3/image\"",
) )

View File

@@ -6,8 +6,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.reddit.customclients.RESOLVE_S_LINK_METHOD import app.revanced.patches.reddit.customclients.RESOLVE_S_LINK_METHOD
import app.revanced.patches.reddit.customclients.SET_ACCESS_TOKEN_METHOD import app.revanced.patches.reddit.customclients.SET_ACCESS_TOKEN_METHOD
import app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.getOAuthAccessTokenFingerprint
import app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.handleNavigationFingerprint
import app.revanced.patches.reddit.customclients.fixSLinksPatch import app.revanced.patches.reddit.customclients.fixSLinksPatch
import app.revanced.patches.reddit.customclients.sync.syncforreddit.extension.sharedExtensionPatch import app.revanced.patches.reddit.customclients.sync.syncforreddit.extension.sharedExtensionPatch
@@ -26,7 +24,7 @@ val fixSLinksPatch = fixSLinksPatch(
execute { execute {
// region Patch navigation handler. // region Patch navigation handler.
handleNavigationFingerprint.method.apply { linkHelperOpenLinkFingerprint.method.apply {
val urlRegister = "p3" val urlRegister = "p3"
val tempRegister = "v2" val tempRegister = "v2"
@@ -46,7 +44,7 @@ val fixSLinksPatch = fixSLinksPatch(
// region Patch set access token. // region Patch set access token.
getOAuthAccessTokenFingerprint.method.addInstruction( setAuthorizationHeaderFingerprint.method.addInstruction(
0, 0,
"invoke-static { p0 }, $EXTENSION_CLASS_DESCRIPTOR->$SET_ACCESS_TOKEN_METHOD", "invoke-static { p0 }, $EXTENSION_CLASS_DESCRIPTOR->$SET_ACCESS_TOKEN_METHOD",
) )

View File

@@ -1,4 +1,4 @@
package app.revanced.patches.reddit.customclients.syncforreddit.fix.video package app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.video
import app.revanced.patcher.fingerprint import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode

View File

@@ -0,0 +1,56 @@
package app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.video
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.reddit.customclients.sync.syncforreddit.extension.sharedExtensionPatch
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/syncforreddit/FixRedditVideoDownloadPatch;"
private const val GET_LINKS_METHOD = "getLinks([B)[Ljava/lang/String;"
@Suppress("unused")
val fixVideoDownloadsPatch = bytecodePatch(
name = "Fix video downloads",
description = "Fixes a bug in Sync's MPD parser resulting in only the audio-track being saved.",
) {
dependsOn(sharedExtensionPatch)
compatibleWith(
"com.laurencedawson.reddit_sync",
"com.laurencedawson.reddit_sync.pro",
"com.laurencedawson.reddit_sync.dev",
)
execute {
val scanResult = parseRedditVideoNetworkResponseFingerprint.patternMatch!!
val newInstanceIndex = scanResult.startIndex
val invokeDirectIndex = scanResult.endIndex - 1
val buildResponseInstruction =
parseRedditVideoNetworkResponseFingerprint.method.getInstruction<Instruction35c>(invokeDirectIndex)
parseRedditVideoNetworkResponseFingerprint.method.addInstructions(
newInstanceIndex + 1,
"""
# Get byte array from response.
iget-object v2, p1, Lcom/android/volley/NetworkResponse;->data:[B
# Parse the videoUrl and audioUrl from the byte array.
invoke-static { v2 }, $EXTENSION_CLASS_DESCRIPTOR->$GET_LINKS_METHOD
move-result-object v2
# Get videoUrl (Index 0).
const/4 v5, 0x0
aget-object v${buildResponseInstruction.registerE}, v2, v5
# Get audioUrl (Index 1).
const/4 v6, 0x1
aget-object v${buildResponseInstruction.registerF}, v2, v6
# Register E and F are used to build the response.
""",
)
}
}

View File

@@ -1,56 +1,18 @@
package app.revanced.patches.reddit.customclients.syncforreddit.fix.video package app.revanced.patches.reddit.customclients.syncforreddit.fix.video
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.reddit.customclients.sync.syncforreddit.extension.sharedExtensionPatch
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/syncforreddit/FixRedditVideoDownloadPatch;"
private const val GET_LINKS_METHOD = "getLinks([B)[Ljava/lang/String;"
@Deprecated(
message = "Patch was move to a different package",
ReplaceWith("app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.video.fixVideoDownloadsPatch")
)
@Suppress("unused") @Suppress("unused")
val fixVideoDownloadsPatch = bytecodePatch( val fixVideoDownloadsPatch = bytecodePatch {
name = "Fix video downloads", dependsOn(app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.video.fixVideoDownloadsPatch)
description = "Fixes a bug in Sync's MPD parser resulting in only the audio-track being saved.",
) {
dependsOn(sharedExtensionPatch)
compatibleWith( compatibleWith(
"com.laurencedawson.reddit_sync", "com.laurencedawson.reddit_sync",
"com.laurencedawson.reddit_sync.pro", "com.laurencedawson.reddit_sync.pro",
"com.laurencedawson.reddit_sync.dev", "com.laurencedawson.reddit_sync.dev",
) )
execute {
val scanResult = parseRedditVideoNetworkResponseFingerprint.patternMatch!!
val newInstanceIndex = scanResult.startIndex
val invokeDirectIndex = scanResult.endIndex - 1
val buildResponseInstruction =
parseRedditVideoNetworkResponseFingerprint.method.getInstruction<Instruction35c>(invokeDirectIndex)
parseRedditVideoNetworkResponseFingerprint.method.addInstructions(
newInstanceIndex + 1,
"""
# Get byte array from response.
iget-object v2, p1, Lcom/android/volley/NetworkResponse;->data:[B
# Parse the videoUrl and audioUrl from the byte array.
invoke-static { v2 }, $EXTENSION_CLASS_DESCRIPTOR->$GET_LINKS_METHOD
move-result-object v2
# Get videoUrl (Index 0).
const/4 v5, 0x0
aget-object v${buildResponseInstruction.registerE}, v2, v5
# Get audioUrl (Index 1).
const/4 v6, 0x1
aget-object v${buildResponseInstruction.registerF}, v2, v6
# Register E and F are used to build the response.
""",
)
}
} }

View File

@@ -20,7 +20,7 @@ fun sharedExtensionPatch(
extendWith("extensions/shared.rve") extendWith("extensions/shared.rve")
execute { execute {
if (classBy { EXTENSION_CLASS_DESCRIPTOR in it.type } == null) { if (classes.none { EXTENSION_CLASS_DESCRIPTOR == it.type }) {
throw PatchException( throw PatchException(
"Shared extension has not been merged yet. This patch can not succeed without merging it.", "Shared extension has not been merged yet. This patch can not succeed without merging it.",
) )
@@ -35,7 +35,7 @@ fun sharedExtensionPatch(
*/ */
fun getCurrentJarFilePath(): String { fun getCurrentJarFilePath(): String {
val className = object {}::class.java.enclosingClass.name.replace('.', '/') + ".class" val className = object {}::class.java.enclosingClass.name.replace('.', '/') + ".class"
val classUrl = object {}::class.java.classLoader.getResource(className) val classUrl = object {}::class.java.classLoader?.getResource(className)
if (classUrl != null) { if (classUrl != null) {
val urlString = classUrl.toString() val urlString = classUrl.toString()

View File

@@ -21,7 +21,7 @@ internal val createTabsFingerprint = fingerprint {
if (reference.definingClass != ACTIVITY_TAB_DESCRIPTOR) return@any false if (reference.definingClass != ACTIVITY_TAB_DESCRIPTOR) return@any false
if (reference.returnType != "[${ACTIVITY_TAB_DESCRIPTOR}") return@any false if (reference.returnType != "[${ACTIVITY_TAB_DESCRIPTOR}") return@any false
true true
} ?: false } == true
} }
} }
@@ -42,7 +42,7 @@ internal val showNotificationFingerprint = fingerprint {
} }
} }
true true
} ?: false } == true
} }
} }

View File

@@ -5,8 +5,8 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.tiktok.misc.extension.sharedExtensionPatch import app.revanced.patches.tiktok.misc.extension.sharedExtensionPatch
import app.revanced.patches.tiktok.misc.settings.settingsPatch
import app.revanced.patches.tiktok.misc.settings.settingsStatusLoadFingerprint import app.revanced.patches.tiktok.misc.settings.settingsStatusLoadFingerprint
import app.revanced.patches.twitch.misc.settings.settingsPatch
import app.revanced.util.findMutableMethodOf import app.revanced.util.findMutableMethodOf
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction

View File

@@ -11,7 +11,6 @@ import app.revanced.patches.twitch.misc.extension.sharedExtensionPatch
import app.revanced.patches.twitch.misc.settings.PreferenceScreen import app.revanced.patches.twitch.misc.settings.PreferenceScreen
import app.revanced.patches.twitch.misc.settings.settingsPatch import app.revanced.patches.twitch.misc.settings.settingsPatch
@Suppress("unused")
val audioAdsPatch = bytecodePatch( val audioAdsPatch = bytecodePatch(
name = "Block audio ads", name = "Block audio ads",
description = "Blocks audio ads in streams and VODs.", description = "Blocks audio ads in streams and VODs.",

View File

@@ -9,7 +9,6 @@ import app.revanced.patches.twitch.misc.extension.sharedExtensionPatch
import app.revanced.patches.twitch.misc.settings.PreferenceScreen import app.revanced.patches.twitch.misc.settings.PreferenceScreen
import app.revanced.patches.twitch.misc.settings.settingsPatch import app.revanced.patches.twitch.misc.settings.settingsPatch
@Suppress("unused")
val embeddedAdsPatch = bytecodePatch( val embeddedAdsPatch = bytecodePatch(
name = "Block embedded ads", name = "Block embedded ads",
description = "Blocks embedded stream ads using services like Luminous or PurpleAdBlocker.", description = "Blocks embedded stream ads using services like Luminous or PurpleAdBlocker.",

View File

@@ -12,7 +12,6 @@ import app.revanced.patches.twitch.misc.extension.sharedExtensionPatch
import app.revanced.patches.twitch.misc.settings.PreferenceScreen import app.revanced.patches.twitch.misc.settings.PreferenceScreen
import app.revanced.patches.twitch.misc.settings.settingsPatch import app.revanced.patches.twitch.misc.settings.settingsPatch
@Suppress("unused")
val showDeletedMessagesPatch = bytecodePatch( val showDeletedMessagesPatch = bytecodePatch(
name = "Show deleted messages", name = "Show deleted messages",
description = "Shows deleted chat messages behind a clickable spoiler.", description = "Shows deleted chat messages behind a clickable spoiler.",

View File

@@ -11,7 +11,6 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.twitch.misc.settings.PreferenceScreen import app.revanced.patches.twitch.misc.settings.PreferenceScreen
import app.revanced.patches.twitch.misc.settings.settingsPatch import app.revanced.patches.twitch.misc.settings.settingsPatch
@Suppress("unused")
val autoClaimChannelPointsPatch = bytecodePatch( val autoClaimChannelPointsPatch = bytecodePatch(
name = "Auto claim channel points", name = "Auto claim channel points",
description = "Automatically claim Channel Points.", description = "Automatically claim Channel Points.",

View File

@@ -9,7 +9,6 @@ import app.revanced.patches.twitch.misc.extension.sharedExtensionPatch
import app.revanced.patches.twitch.misc.settings.PreferenceScreen import app.revanced.patches.twitch.misc.settings.PreferenceScreen
import app.revanced.patches.twitch.misc.settings.settingsPatch import app.revanced.patches.twitch.misc.settings.settingsPatch
@Suppress("unused")
val debugModePatch = bytecodePatch( val debugModePatch = bytecodePatch(
name = "Debug mode", name = "Debug mode",
description = "Enables Twitch's internal debugging mode.", description = "Enables Twitch's internal debugging mode.",

View File

@@ -47,18 +47,22 @@ val jsonHookPatch = bytecodePatch(
dependsOn(sharedExtensionPatch) dependsOn(sharedExtensionPatch)
execute { execute {
val jsonFactoryClassDef = jsonHookPatchFingerprint.apply { jsonHookPatchFingerprint.apply {
// Make sure the extension is present. // Make sure the extension is present.
val jsonHookPatch = classBy { classDef -> classDef.type == JSON_HOOK_PATCH_CLASS_DESCRIPTOR } val jsonHookPatch = classBy { classDef -> classDef.type == JSON_HOOK_PATCH_CLASS_DESCRIPTOR }
?: throw PatchException("Could not find the extension.") ?: throw PatchException("Could not find the extension.")
matchOrNull(jsonHookPatch.immutableClass) matchOrNull(jsonHookPatch.immutableClass)
?: throw PatchException("Unexpected extension.") ?: throw PatchException("Unexpected extension.")
}.originalClassDef // Conveniently find the type to hook a method in, via a named field. }
.fields
.firstOrNull { it.name == "JSON_FACTORY" } val jsonFactoryClassDef =
?.type loganSquareFingerprint.originalClassDef // Conveniently find the type to hook a method in, via a named field.
.let { type -> classes.find { it.type == type } } ?: throw PatchException("Could not find required class.") .fields
.firstOrNull { it.name == "JSON_FACTORY" }
?.type
.let { type -> classes.find { it.type == type } }
?: throw PatchException("Could not find required class.")
// Hook the methods first parameter. // Hook the methods first parameter.
jsonInputStreamFingerprint.match(jsonFactoryClassDef).method.addInstructions( jsonInputStreamFingerprint.match(jsonFactoryClassDef).method.addInstructions(

View File

@@ -9,6 +9,7 @@ import app.revanced.patcher.patch.stringOption
import app.revanced.patches.shared.misc.mapping.get import app.revanced.patches.shared.misc.mapping.get
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.mapping.resourceMappings
import app.revanced.patches.twitter.misc.extension.sharedExtensionPatch
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
@@ -39,7 +40,10 @@ val changeLinkSharingDomainPatch = bytecodePatch(
name = "Change link sharing domain", name = "Change link sharing domain",
description = "Replaces the domain name of Twitter links when sharing them.", description = "Replaces the domain name of Twitter links when sharing them.",
) { ) {
dependsOn(changeLinkSharingDomainResourcePatch) dependsOn(
changeLinkSharingDomainResourcePatch,
sharedExtensionPatch,
)
compatibleWith("com.twitter.android") compatibleWith("com.twitter.android")
@@ -52,7 +56,6 @@ val changeLinkSharingDomainPatch = bytecodePatch(
) )
execute { execute {
val replacementIndex = val replacementIndex =
linkSharingDomainFingerprint.stringMatches!!.first().index linkSharingDomainFingerprint.stringMatches!!.first().index
val domainRegister = val domainRegister =

View File

@@ -2,6 +2,7 @@ package app.revanced.patches.twitter.misc.links
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.twitter.misc.extension.sharedExtensionPatch
@Suppress("unused") @Suppress("unused")
val openLinksWithAppChooserPatch = bytecodePatch( val openLinksWithAppChooserPatch = bytecodePatch(
@@ -10,6 +11,8 @@ val openLinksWithAppChooserPatch = bytecodePatch(
"As a result you can select a browser to open the link with.", "As a result you can select a browser to open the link with.",
use = false, use = false,
) { ) {
dependsOn(sharedExtensionPatch)
compatibleWith("com.twitter.android"("10.48.0-release.0")) compatibleWith("com.twitter.android"("10.48.0-release.0"))
execute { execute {

View File

@@ -3,9 +3,9 @@ package app.revanced.patches.vsco.misc.pro
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
@Deprecated("This patch is deprecated because it does not work anymore and will be removed in the future.")
@Suppress("unused") @Suppress("unused")
val unlockProPatch = bytecodePatch( val unlockProPatch = bytecodePatch(
name = "Unlock pro",
description = "Unlocks pro features.", description = "Unlocks pro features.",
) { ) {
compatibleWith("com.vsco.cam"("345")) compatibleWith("com.vsco.cam"("345"))

View File

@@ -75,6 +75,7 @@ val hideAdsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -31,6 +31,7 @@ val hideGetPremiumPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -11,7 +11,6 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
@Suppress("unused")
val videoAdsPatch = bytecodePatch( val videoAdsPatch = bytecodePatch(
name = "Video ads", name = "Video ads",
description = "Adds an option to remove ads in the video player.", description = "Adds an option to remove ads in the video player.",
@@ -30,6 +29,7 @@ val videoAdsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -59,6 +59,7 @@ val copyVideoUrlPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -11,7 +11,6 @@ import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Suppress("unused")
val removeViewerDiscretionDialogPatch = bytecodePatch( val removeViewerDiscretionDialogPatch = bytecodePatch(
name = "Remove viewer discretion dialog", name = "Remove viewer discretion dialog",
description = "Adds an option to remove the dialog that appears when opening a video that has been age-restricted " + description = "Adds an option to remove the dialog that appears when opening a video that has been age-restricted " +
@@ -31,6 +30,7 @@ val removeViewerDiscretionDialogPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -74,6 +74,7 @@ val downloadsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -11,7 +11,6 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
@Suppress("unused")
val disablePreciseSeekingGesturePatch = bytecodePatch( val disablePreciseSeekingGesturePatch = bytecodePatch(
name = "Disable precise seeking gesture", name = "Disable precise seeking gesture",
description = "Adds an option to disable precise seeking when swiping up on the seekbar.", description = "Adds an option to disable precise seeking when swiping up on the seekbar.",
@@ -30,6 +29,7 @@ val disablePreciseSeekingGesturePatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -14,7 +14,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused")
val enableSeekbarTappingPatch = bytecodePatch( val enableSeekbarTappingPatch = bytecodePatch(
name = "Seekbar tapping", name = "Seekbar tapping",
description = "Adds an option to enable tap-to-seek on the seekbar of the video player.", description = "Adds an option to enable tap-to-seek on the seekbar of the video player.",
@@ -33,6 +32,7 @@ val enableSeekbarTappingPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -17,12 +17,10 @@ import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
internal const val EXTENSION_METHOD_DESCRIPTOR = internal const val EXTENSION_METHOD_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/SlideToSeekPatch;->isSlideToSeekDisabled(Z)Z" "Lapp/revanced/extension/youtube/patches/SlideToSeekPatch;->isSlideToSeekDisabled(Z)Z"
@Suppress("unused")
val enableSlideToSeekPatch = bytecodePatch( val enableSlideToSeekPatch = bytecodePatch(
name = "Enable slide to seek", name = "Enable slide to seek",
description = "Adds an option to enable slide to seek " + description = "Adds an option to enable slide to seek " +
@@ -44,6 +42,7 @@ val enableSlideToSeekPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -16,7 +16,6 @@ import app.revanced.patches.youtube.misc.settings.PreferenceScreen
private const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/SeekbarThumbnailsPatch;" "Lapp/revanced/extension/youtube/patches/SeekbarThumbnailsPatch;"
@Suppress("unused")
val seekbarThumbnailsPatch = bytecodePatch( val seekbarThumbnailsPatch = bytecodePatch(
name = "Seekbar thumbnails", name = "Seekbar thumbnails",
description = "Adds an option to use high quality fullscreen seekbar thumbnails. " + description = "Adds an option to use high quality fullscreen seekbar thumbnails. " +
@@ -36,6 +35,7 @@ val seekbarThumbnailsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
) )
) )

View File

@@ -71,6 +71,7 @@ val swipeControlsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -10,7 +10,6 @@ import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.patches.youtube.shared.subtitleButtonControllerFingerprint import app.revanced.patches.youtube.shared.subtitleButtonControllerFingerprint
@Suppress("unused")
val autoCaptionsPatch = bytecodePatch( val autoCaptionsPatch = bytecodePatch(
name = "Disable auto captions", name = "Disable auto captions",
description = "Adds an option to disable captions from being automatically enabled.", description = "Adds an option to disable captions from being automatically enabled.",
@@ -29,6 +28,7 @@ val autoCaptionsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -41,7 +41,17 @@ val customBrandingPatch = resourcePatch(
) { ) {
dependsOn(versionCheckPatch) dependsOn(versionCheckPatch)
compatibleWith("com.google.android.youtube") compatibleWith(
"com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39",
"19.25.37",
"19.34.42",
"19.43.41",
"19.45.38",
),
)
val appName by stringOption( val appName by stringOption(
key = "appName", key = "appName",

View File

@@ -3,9 +3,12 @@ package app.revanced.patches.youtube.layout.branding.header
import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.stringOption import app.revanced.patcher.patch.stringOption
import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.util.ResourceGroup import app.revanced.util.ResourceGroup
import app.revanced.util.Utils.trimIndentMultiline import app.revanced.util.Utils.trimIndentMultiline
import app.revanced.util.copyResources import app.revanced.util.copyResources
import app.revanced.util.findElementByAttributeValueOrThrow
import java.io.File import java.io.File
private const val HEADER_FILE_NAME = "yt_wordmark_header" private const val HEADER_FILE_NAME = "yt_wordmark_header"
@@ -34,7 +37,19 @@ val changeHeaderPatch = resourcePatch(
description = "Applies a custom header in the top left corner within the app. Defaults to the ReVanced header.", description = "Applies a custom header in the top left corner within the app. Defaults to the ReVanced header.",
use = false, use = false,
) { ) {
compatibleWith("com.google.android.youtube") dependsOn(versionCheckPatch)
compatibleWith(
"com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39",
"19.25.37",
"19.34.42",
"19.43.41",
"19.45.38",
)
)
val header by stringOption( val header by stringOption(
key = "header", key = "header",
@@ -79,7 +94,7 @@ val changeHeaderPatch = resourcePatch(
/** /**
* A function that overwrites both header variants 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 -> fun overwriteFromTo(from: String, to: String) {
targetResourceDirectories.forEach { directory -> targetResourceDirectories.forEach { directory ->
variants.forEach { variant -> variants.forEach { variant ->
val fromPath = directory.resolve("${from}_$variant.png") val fromPath = directory.resolve("${from}_$variant.png")
@@ -91,23 +106,28 @@ val changeHeaderPatch = resourcePatch(
} }
// Functions to overwrite the header to the different variants. // Functions to overwrite the header to the different variants.
val toPremium = { overwriteFromTo(PREMIUM_HEADER_FILE_NAME, HEADER_FILE_NAME) } fun toPremium() { overwriteFromTo(PREMIUM_HEADER_FILE_NAME, HEADER_FILE_NAME) }
val toHeader = { overwriteFromTo(HEADER_FILE_NAME, PREMIUM_HEADER_FILE_NAME) } fun toHeader() { overwriteFromTo(HEADER_FILE_NAME, PREMIUM_HEADER_FILE_NAME) }
val toReVanced = { fun toReVanced() {
// Copy the ReVanced header to the resource directories. // Copy the ReVanced header to the resource directories.
targetResourceFiles.forEach { copyResources("change-header/revanced", it) } targetResourceFiles.forEach { copyResources("change-header/revanced", it) }
// Overwrite the premium with the custom header as well. // Overwrite the premium with the custom header as well.
toHeader() toHeader()
} }
val toReVancedBorderless = { fun toReVancedBorderless() {
// Copy the ReVanced borderless header to the resource directories. // Copy the ReVanced borderless header to the resource directories.
targetResourceFiles.forEach { copyResources("change-header/revanced-borderless", it) } targetResourceFiles.forEach {
copyResources(
"change-header/revanced-borderless",
it
)
}
// Overwrite the premium with the custom header as well. // Overwrite the premium with the custom header as well.
toHeader() toHeader()
} }
val toCustom = { fun toCustom() {
val sourceFolders = File(header!!).listFiles { file -> file.isDirectory } val sourceFolders = File(header!!).listFiles { file -> file.isDirectory }
?: throw PatchException("The provided path is not a directory: $header") ?: throw PatchException("The provided path is not a directory: $header")
@@ -136,11 +156,42 @@ val changeHeaderPatch = resourcePatch(
} }
when (header) { when (header) {
HEADER_OPTION -> toHeader HEADER_OPTION -> toHeader()
PREMIUM_HEADER_OPTION -> toPremium PREMIUM_HEADER_OPTION -> toPremium()
REVANCED_HEADER_OPTION -> toReVanced REVANCED_HEADER_OPTION -> toReVanced()
REVANCED_BORDERLESS_HEADER_OPTION -> toReVancedBorderless REVANCED_BORDERLESS_HEADER_OPTION -> toReVancedBorderless()
else -> toCustom else -> toCustom()
}() }
// Fix 19.25+ A/B layout with different header icons:
// yt_ringo2_wordmark_header, yt_ringo2_premium_wordmark_header
//
// These images are webp and not png, so overwriting them is not so simple.
// Instead change styles.xml to use the old drawable resources.
if (is_19_25_or_greater) {
document("res/values/styles.xml").use { document ->
arrayOf(
"CairoLightThemeRingo2Updates" to variants[0],
"CairoDarkThemeRingo2Updates" to variants[1]
).forEach { (styleName, theme) ->
val style = document.childNodes.findElementByAttributeValueOrThrow(
"name",
styleName,
)
val drawable = "@drawable/${HEADER_FILE_NAME}_${theme}"
arrayOf(
"ytWordmarkHeader",
"ytPremiumWordmarkHeader"
).forEach { itemName ->
style.childNodes.findElementByAttributeValueOrThrow(
"name",
itemName,
).textContent = drawable
}
}
}
}
} }
} }

View File

@@ -10,7 +10,6 @@ import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
@Suppress("unused")
val hideButtonsPatch = resourcePatch( val hideButtonsPatch = resourcePatch(
name = "Hide video action buttons", name = "Hide video action buttons",
description = "Adds options to hide action buttons (such as the Download button) under videos.", description = "Adds options to hide action buttons (such as the Download button) under videos.",
@@ -29,6 +28,7 @@ val hideButtonsPatch = resourcePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -19,7 +19,6 @@ import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
internal const val EXTENSION_CLASS_DESCRIPTOR = internal const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/NavigationButtonsPatch;" "Lapp/revanced/extension/youtube/patches/NavigationButtonsPatch;"
@@ -43,6 +42,7 @@ val navigationButtonsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -60,6 +60,7 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -62,6 +62,7 @@ val hideEndscreenCardsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -17,7 +17,6 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal const val EXTENSION_CLASS_DESCRIPTOR = internal const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/DisableFullscreenAmbientModePatch;" "Lapp/revanced/extension/youtube/patches/DisableFullscreenAmbientModePatch;"
@Suppress("unused")
val disableFullscreenAmbientModePatch = bytecodePatch( val disableFullscreenAmbientModePatch = bytecodePatch(
name = "Disable fullscreen ambient mode", name = "Disable fullscreen ambient mode",
description = "Adds an option to disable the ambient mode when in fullscreen.", description = "Adds an option to disable the ambient mode when in fullscreen.",
@@ -36,6 +35,7 @@ val disableFullscreenAmbientModePatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -107,7 +107,6 @@ private const val CUSTOM_FILTER_CLASS_NAME =
private const val KEYWORD_FILTER_CLASS_NAME = private const val KEYWORD_FILTER_CLASS_NAME =
"Lapp/revanced/extension/youtube/patches/components/KeywordContentFilter;" "Lapp/revanced/extension/youtube/patches/components/KeywordContentFilter;"
@Suppress("unused")
val hideLayoutComponentsPatch = bytecodePatch( val hideLayoutComponentsPatch = bytecodePatch(
name = "Hide layout components", name = "Hide layout components",
description = "Adds options to hide general layout components.", description = "Adds options to hide general layout components.",
@@ -129,6 +128,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -63,6 +63,7 @@ val hideInfoCardsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -11,7 +11,6 @@ import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
@Suppress("unused")
val hidePlayerFlyoutMenuPatch = bytecodePatch( val hidePlayerFlyoutMenuPatch = bytecodePatch(
name = "Hide player flyout menu items", name = "Hide player flyout menu items",
description = "Adds options to hide menu items that appear when pressing the gear icon in the video player.", description = "Adds options to hide menu items that appear when pressing the gear icon in the video player.",
@@ -31,6 +30,7 @@ val hidePlayerFlyoutMenuPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -17,7 +17,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
private const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/DisableRollingNumberAnimationsPatch;" "Lapp/revanced/extension/youtube/patches/DisableRollingNumberAnimationsPatch;"
@Suppress("unused")
val disableRollingNumberAnimationPatch = bytecodePatch( val disableRollingNumberAnimationPatch = bytecodePatch(
name = "Disable rolling number animations", name = "Disable rolling number animations",
description = "Adds an option to disable rolling number animations of video view count, user likes, and upload time.", description = "Adds an option to disable rolling number animations of video view count, user likes, and upload time.",
@@ -36,6 +35,7 @@ val disableRollingNumberAnimationPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -12,7 +12,6 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.patches.youtube.shared.seekbarFingerprint import app.revanced.patches.youtube.shared.seekbarFingerprint
import app.revanced.patches.youtube.shared.seekbarOnDrawFingerprint import app.revanced.patches.youtube.shared.seekbarOnDrawFingerprint
@Suppress("unused")
val hideSeekbarPatch = bytecodePatch( val hideSeekbarPatch = bytecodePatch(
name = "Hide seekbar", name = "Hide seekbar",
description = "Adds an option to hide the seekbar.", description = "Adds an option to hide the seekbar.",
@@ -32,6 +31,7 @@ val hideSeekbarPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -29,7 +29,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
internal var reelMultipleItemShelfId = -1L internal var reelMultipleItemShelfId = -1L
private set private set
@@ -189,9 +188,13 @@ val hideShortsComponentsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )
hideShortsAppShortcutOption()
hideShortsWidgetOption()
execute { execute {
// region Hide the Shorts shelf. // region Hide the Shorts shelf.

View File

@@ -60,6 +60,7 @@ val disableSuggestedVideoEndScreenPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -9,7 +9,6 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
@Suppress("unused")
val hideTimestampPatch = bytecodePatch( val hideTimestampPatch = bytecodePatch(
name = "Hide timestamp", name = "Hide timestamp",
description = "Adds an option to hide the timestamp in the bottom left of the video player.", description = "Adds an option to hide the timestamp in the bottom left of the video player.",
@@ -28,6 +27,7 @@ val hideTimestampPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -43,6 +43,7 @@ internal const val MINIPLAYER_DRAG_DROP_FEATURE_KEY = 45628752L
internal const val MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY = 45658112L internal const val MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY = 45658112L
internal const val MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY = 45652224L internal const val MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY = 45652224L
internal const val MINIPLAYER_INITIAL_SIZE_FEATURE_KEY = 45640023L internal const val MINIPLAYER_INITIAL_SIZE_FEATURE_KEY = 45640023L
internal const val MINIPLAYER_DISABLED_FEATURE_KEY = 45657015L
internal val miniplayerModernConstructorFingerprint = fingerprint { internal val miniplayerModernConstructorFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
@@ -50,6 +51,12 @@ internal val miniplayerModernConstructorFingerprint = fingerprint {
literal { 45623000L } literal { 45623000L }
} }
internal val miniplayerOnCloseHandlerFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Z")
literal { MINIPLAYER_DISABLED_FEATURE_KEY }
}
/** /**
* Matches using the class found in [miniplayerModernViewParentFingerprint]. * Matches using the class found in [miniplayerModernViewParentFingerprint].
*/ */

View File

@@ -135,8 +135,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/
@Suppress("unused") @Suppress("unused")
val miniplayerPatch = bytecodePatch( val miniplayerPatch = bytecodePatch(
name = "Miniplayer", name = "Miniplayer",
description = "Adds options to change the in app minimized player. " + description = "Adds options to change the in app minimized player."
"Patching target 19.16+ adds modern miniplayers.",
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,
@@ -147,8 +146,7 @@ val miniplayerPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.google.android.youtube"( "com.google.android.youtube"(
"18.38.44", // 18.49.37 // Could be supported, but no reason when 19.16 exists and has modern types.
"18.49.37",
// 19.14.43 // Incomplete code for modern miniplayers. // 19.14.43 // Incomplete code for modern miniplayers.
// 19.15.36 // Different code for handling subtitle texts and not worth supporting. // 19.15.36 // Different code for handling subtitle texts and not worth supporting.
"19.16.39", // First with modern miniplayers. "19.16.39", // First with modern miniplayers.
@@ -170,6 +168,7 @@ val miniplayerPatch = bytecodePatch(
// 19.33.35 // 19.33.35
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )
@@ -178,58 +177,60 @@ val miniplayerPatch = bytecodePatch(
val preferences = mutableSetOf<BasePreference>() val preferences = mutableSetOf<BasePreference>()
if (!is_19_16_or_greater) {
preferences += ListPreference(
"revanced_miniplayer_type",
summaryKey = null,
entriesKey = "revanced_miniplayer_type_legacy_entries",
entryValuesKey = "revanced_miniplayer_type_legacy_entry_values",
)
} else {
preferences += ListPreference(
"revanced_miniplayer_type",
summaryKey = null,
)
if (is_19_25_or_greater) {
if (!is_19_29_or_greater) {
preferences += SwitchPreference("revanced_miniplayer_double_tap_action")
}
preferences += SwitchPreference("revanced_miniplayer_drag_and_drop")
}
preferences +=
if (is_19_43_or_greater) { if (is_19_43_or_greater) {
preferences += SwitchPreference("revanced_miniplayer_horizontal_drag") ListPreference(
} "revanced_miniplayer_type",
summaryKey = null,
if (is_19_36_or_greater) { )
preferences += SwitchPreference("revanced_miniplayer_rounded_corners")
}
preferences += SwitchPreference("revanced_miniplayer_hide_subtext")
preferences += if (is_19_26_or_greater) {
SwitchPreference("revanced_miniplayer_hide_expand_close")
} else { } else {
SwitchPreference( ListPreference(
key = "revanced_miniplayer_hide_expand_close", "revanced_miniplayer_type",
titleKey = "revanced_miniplayer_hide_expand_close_legacy_title", summaryKey = null,
summaryOnKey = "revanced_miniplayer_hide_expand_close_legacy_summary_on", entriesKey = "revanced_miniplayer_type_legacy_entries",
summaryOffKey = "revanced_miniplayer_hide_expand_close_legacy_summary_off", entryValuesKey = "revanced_miniplayer_type_legacy_entry_values",
) )
} }
if (!is_19_26_or_greater) { if (is_19_25_or_greater) {
preferences += SwitchPreference("revanced_miniplayer_hide_rewind_forward") if (!is_19_29_or_greater) {
preferences += SwitchPreference("revanced_miniplayer_double_tap_action")
} }
preferences += SwitchPreference("revanced_miniplayer_drag_and_drop")
if (is_19_26_or_greater) {
preferences += TextPreference("revanced_miniplayer_width_dip", inputType = InputType.NUMBER)
}
preferences += TextPreference("revanced_miniplayer_opacity", inputType = InputType.NUMBER)
} }
if (is_19_43_or_greater) {
preferences += SwitchPreference("revanced_miniplayer_horizontal_drag")
}
if (is_19_36_or_greater) {
preferences += SwitchPreference("revanced_miniplayer_rounded_corners")
}
preferences += SwitchPreference("revanced_miniplayer_hide_subtext")
preferences += if (is_19_26_or_greater) {
SwitchPreference("revanced_miniplayer_hide_expand_close")
} else {
SwitchPreference(
key = "revanced_miniplayer_hide_expand_close",
titleKey = "revanced_miniplayer_hide_expand_close_legacy_title",
summaryOnKey = "revanced_miniplayer_hide_expand_close_legacy_summary_on",
summaryOffKey = "revanced_miniplayer_hide_expand_close_legacy_summary_off",
)
}
if (!is_19_26_or_greater) {
preferences += SwitchPreference("revanced_miniplayer_hide_rewind_forward")
}
if (is_19_26_or_greater) {
preferences += TextPreference("revanced_miniplayer_width_dip", inputType = InputType.NUMBER)
}
preferences += TextPreference("revanced_miniplayer_opacity", inputType = InputType.NUMBER)
PreferenceScreen.PLAYER.addPreferences( PreferenceScreen.PLAYER.addPreferences(
PreferenceScreenPreference( PreferenceScreenPreference(
key = "revanced_miniplayer_screen", key = "revanced_miniplayer_screen",
@@ -349,11 +350,6 @@ val miniplayerPatch = bytecodePatch(
it.method.insertLegacyTabletMiniplayerOverride(it.patternMatch!!.endIndex) it.method.insertLegacyTabletMiniplayerOverride(it.patternMatch!!.endIndex)
} }
if (!is_19_16_or_greater) {
// Return here, as patch below is only for the current versions of the app.
return@execute
}
// endregion // endregion
// region Enable modern miniplayer. // region Enable modern miniplayer.
@@ -379,13 +375,6 @@ val miniplayerPatch = bytecodePatch(
) )
} }
if (is_19_43_or_greater) {
miniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY,
"setHorizontalDrag",
)
}
if (is_19_25_or_greater) { if (is_19_25_or_greater) {
miniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride( miniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
MINIPLAYER_MODERN_FEATURE_LEGACY_KEY, MINIPLAYER_MODERN_FEATURE_LEGACY_KEY,
@@ -442,6 +431,18 @@ val miniplayerPatch = bytecodePatch(
) )
} }
if (is_19_43_or_greater) {
miniplayerOnCloseHandlerFingerprint.insertLiteralValueBooleanOverride(
MINIPLAYER_DISABLED_FEATURE_KEY,
"getMiniplayerOnCloseHandler"
)
miniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY,
"setHorizontalDrag",
)
}
// endregion // endregion
// region Fix 19.16 using mixed up drawables for tablet modern. // region Fix 19.16 using mixed up drawables for tablet modern.

View File

@@ -9,7 +9,6 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
@Suppress("unused")
val playerPopupPanelsPatch = bytecodePatch( val playerPopupPanelsPatch = bytecodePatch(
name = "Disable player popup panels", name = "Disable player popup panels",
description = "Adds an option to disable panels (such as live chat) from opening automatically.", description = "Adds an option to disable panels (such as live chat) from opening automatically.",
@@ -28,6 +27,7 @@ val playerPopupPanelsPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -18,6 +18,7 @@ val playerControlsBackgroundPatch = resourcePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -58,6 +58,7 @@ val customPlayerOverlayOpacityPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -31,7 +31,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.iface.reference.TypeReference import com.android.tools.smali.dexlib2.iface.reference.TypeReference
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
private const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch;" "Lapp/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch;"
@@ -39,7 +38,6 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
private const val FILTER_CLASS_DESCRIPTOR = private const val FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/components/ReturnYouTubeDislikeFilterPatch;" "Lapp/revanced/extension/youtube/patches/components/ReturnYouTubeDislikeFilterPatch;"
@Suppress("unused")
val returnYouTubeDislikePatch = bytecodePatch( val returnYouTubeDislikePatch = bytecodePatch(
name = "Return YouTube Dislike", name = "Return YouTube Dislike",
description = "Adds an option to show the dislike count of videos with Return YouTube Dislike.", description = "Adds an option to show the dislike count of videos with Return YouTube Dislike.",
@@ -61,6 +59,7 @@ val returnYouTubeDislikePatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -17,7 +17,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
private const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/WideSearchbarPatch;" "Lapp/revanced/extension/youtube/patches/WideSearchbarPatch;"
@Suppress("unused")
val wideSearchbarPatch = bytecodePatch( val wideSearchbarPatch = bytecodePatch(
name = "Wide searchbar", name = "Wide searchbar",
description = "Adds an option to replace the search icon with a wide search bar. This will hide the YouTube logo when active.", description = "Adds an option to replace the search icon with a wide search bar. This will hide the YouTube logo when active.",
@@ -36,6 +35,7 @@ val wideSearchbarPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -48,3 +48,17 @@ internal val lithoLinearGradientFingerprint = fingerprint {
returns("Landroid/graphics/LinearGradient;") returns("Landroid/graphics/LinearGradient;")
parameters("F", "F", "F", "F", "[I", "[F") parameters("F", "F", "F", "F", "[I", "[F")
} }
internal const val launchScreenLayoutTypeLotteFeatureFlag = 268507948L
internal val launchScreenLayoutTypeFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
returns("V")
custom { method, _ ->
val firstParameter = method.parameterTypes.firstOrNull()
// 19.25 - 19.45
(firstParameter == "Lcom/google/android/apps/youtube/app/watchwhile/MainActivity;"
|| firstParameter == "Landroid/app/Activity;") // 19.46+
&& method.containsLiteralInstruction(launchScreenLayoutTypeLotteFeatureFlag)
}
}

View File

@@ -13,15 +13,24 @@ import app.revanced.patches.shared.misc.mapping.resourceMappings
import app.revanced.patches.youtube.layout.theme.lithoColorHookPatch import app.revanced.patches.youtube.layout.theme.lithoColorHookPatch
import app.revanced.patches.youtube.layout.theme.lithoColorOverrideHook import app.revanced.patches.youtube.layout.theme.lithoColorOverrideHook
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_23_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
import app.revanced.util.copyXmlNode
import app.revanced.util.findElementByAttributeValueOrThrow
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
import app.revanced.util.inputStreamFromBundledResource
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import org.w3c.dom.Element import org.w3c.dom.Element
import java.io.ByteArrayInputStream
import kotlin.use
internal var reelTimeBarPlayedColorId = -1L internal var reelTimeBarPlayedColorId = -1L
private set private set
@@ -30,6 +39,8 @@ internal var inlineTimeBarColorizedBarPlayedColorDarkId = -1L
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
private set private set
internal const val splashSeekbarColorAttributeName = "splash_custom_seekbar_color"
private val seekbarColorResourcePatch = resourcePatch { private val seekbarColorResourcePatch = resourcePatch {
dependsOn( dependsOn(
settingsPatch, settingsPatch,
@@ -51,9 +62,8 @@ private val seekbarColorResourcePatch = resourcePatch {
"inline_time_bar_played_not_highlighted_color", "inline_time_bar_played_not_highlighted_color",
] ]
// Edit the resume playback drawable and replace the progress bar with a custom drawable // Modify the resume playback drawable and replace the progress bar with a custom drawable.
document("res/drawable/resume_playback_progressbar_drawable.xml").use { document -> document("res/drawable/resume_playback_progressbar_drawable.xml").use { document ->
val layerList = document.getElementsByTagName("layer-list").item(0) as Element val layerList = document.getElementsByTagName("layer-list").item(0) as Element
val progressNode = layerList.getElementsByTagName("item").item(1) as Element val progressNode = layerList.getElementsByTagName("item").item(1) as Element
if (!progressNode.getAttributeNode("android:id").value.endsWith("progress")) { if (!progressNode.getAttributeNode("android:id").value.endsWith("progress")) {
@@ -66,9 +76,102 @@ private val seekbarColorResourcePatch = resourcePatch {
) )
scaleNode.replaceChild(replacementNode, shapeNode) scaleNode.replaceChild(replacementNode, shapeNode)
} }
if (!is_19_25_or_greater) {
return@execute
}
// Add attribute and styles for splash screen custom color.
// Using a style is the only way to selectively change just the seekbar fill color.
//
// Because the style colors must be hard coded for all color possibilities,
// instead of allowing 24 bit color the style is restricted to 9-bit (3 bits per color channel)
// and the style color closest to the users custom color is used for the splash screen.
arrayOf(
inputStreamFromBundledResource("seekbar/values", "attrs.xml")!! to "res/values/attrs.xml",
ByteArrayInputStream(create9BitSeekbarColorStyles().toByteArray()) to "res/values/styles.xml"
).forEach { (source, destination) ->
"resources".copyXmlNode(
document(source),
document(destination),
).close()
}
fun setSplashDrawablePathFillColor(xmlFileNames: Iterable<String>, vararg resourceNames: String) {
xmlFileNames.forEach { xmlFileName ->
document(xmlFileName).use { document ->
resourceNames.forEach { elementId ->
val element = document.childNodes.findElementByAttributeValueOrThrow(
"android:name",
elementId
)
val attribute = "android:fillColor"
if (!element.hasAttribute(attribute)) {
throw PatchException("Could not find $attribute for $elementId")
}
element.setAttribute(attribute, "?attr/$splashSeekbarColorAttributeName")
}
}
}
}
setSplashDrawablePathFillColor(
listOf(
"res/drawable/\$startup_animation_light__0.xml",
"res/drawable/\$startup_animation_dark__0.xml"
),
"_R_G_L_10_G_D_0_P_0"
)
if (!is_19_46_or_greater) {
// Resources removed in 19.46+
setSplashDrawablePathFillColor(
listOf(
"res/drawable/\$buenos_aires_animation_light__0.xml",
"res/drawable/\$buenos_aires_animation_dark__0.xml"
),
"_R_G_L_8_G_D_0_P_0"
)
}
} }
} }
/**
* Generate a style xml with all combinations of 9-bit colors.
*/
private fun create9BitSeekbarColorStyles(): String = StringBuilder().apply {
append("<?xml version=\"1.0\" encoding=\"utf-8\"?>")
append("<resources>\n")
for (red in 0..7) {
for (green in 0..7) {
for (blue in 0..7) {
val name = "${red}_${green}_${blue}"
fun roundTo3BitHex(channel8Bits: Int) =
(channel8Bits * 255 / 7).toString(16).padStart(2, '0')
val r = roundTo3BitHex(red)
val g = roundTo3BitHex(green)
val b = roundTo3BitHex(blue)
val color = "#ff$r$g$b"
append(
"""
<style name="splash_seekbar_color_style_$name">
<item name="$splashSeekbarColorAttributeName">$color</item>
</style>
"""
)
}
}
}
append("</resources>")
}.toString()
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/theme/SeekbarColorPatch;" private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/theme/SeekbarColorPatch;"
val seekbarColorPatch = bytecodePatch( val seekbarColorPatch = bytecodePatch(
@@ -117,27 +220,73 @@ val seekbarColorPatch = bytecodePatch(
} }
} }
if (is_19_23_or_greater) { lithoColorOverrideHook(EXTENSION_CLASS_DESCRIPTOR, "getLithoColor")
playerSeekbarGradientConfigFingerprint.method.apply {
val literalIndex = indexOfFirstLiteralInstructionOrThrow(PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG) if (!is_19_25_or_greater) {
return@execute
}
// 19.25+ changes
playerSeekbarGradientConfigFingerprint.method.apply {
val literalIndex = indexOfFirstLiteralInstructionOrThrow(PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG)
val resultIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA
addInstructions(
resultIndex + 1,
"""
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->playerSeekbarGradientEnabled(Z)Z
move-result v$register
"""
)
}
lithoLinearGradientFingerprint.method.addInstruction(
0,
"invoke-static/range { p4 .. p5 }, $EXTENSION_CLASS_DESCRIPTOR->setLinearGradient([I[F)V"
)
// region apply seekbar custom color to splash screen animation.
// Don't use the lotte splash screen layout if using custom seekbar.
arrayOf(
launchScreenLayoutTypeFingerprint,
mainActivityOnCreateFingerprint
).forEach { fingerprint ->
fingerprint.method.apply {
val literalIndex = indexOfFirstLiteralInstructionOrThrow(launchScreenLayoutTypeLotteFeatureFlag)
val resultIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT) val resultIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA
addInstructions( addInstructions(
resultIndex + 1, resultIndex + 1,
""" """
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->playerSeekbarGradientEnabled(Z)Z invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->useLotteLaunchSplashScreen(Z)Z
move-result v$register move-result v$register
""", """
) )
} }
}
lithoLinearGradientFingerprint.method.addInstruction( // Hook the splash animation drawable to set the a seekbar color theme.
0, mainActivityOnCreateFingerprint.method.apply {
"invoke-static/range { p4 .. p5 }, $EXTENSION_CLASS_DESCRIPTOR->setLinearGradient([I[F)V", val drawableIndex = indexOfFirstInstructionOrThrow {
val reference = getReference<MethodReference>()
reference?.definingClass == "Landroid/widget/ImageView;"
&& reference.name == "getDrawable"
}
val checkCastIndex = indexOfFirstInstructionOrThrow(drawableIndex, Opcode.CHECK_CAST)
val drawableRegister = getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
addInstruction(
checkCastIndex + 1,
"invoke-static { v$drawableRegister }, $EXTENSION_CLASS_DESCRIPTOR->" +
"setSplashAnimationDrawableTheme(Landroid/graphics/drawable/AnimatedVectorDrawable;)V"
) )
} }
lithoColorOverrideHook(EXTENSION_CLASS_DESCRIPTOR, "getLithoColor") // endregion
} }
} }

View File

@@ -19,7 +19,6 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/ShortsAutoplayPatch;" private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/ShortsAutoplayPatch;"
@Suppress("unused")
val shortsAutoplayPatch = bytecodePatch( val shortsAutoplayPatch = bytecodePatch(
name = "Shorts autoplay", name = "Shorts autoplay",
description = "Adds options to automatically play the next Short.", description = "Adds options to automatically play the next Short.",
@@ -38,6 +37,7 @@ val shortsAutoplayPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )
@@ -56,7 +56,7 @@ val shortsAutoplayPatch = bytecodePatch(
// Main activity is used to check if app is in pip mode. // Main activity is used to check if app is in pip mode.
mainActivityOnCreateFingerprint.method.addInstructions( mainActivityOnCreateFingerprint.method.addInstructions(
0, 1,
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" + "invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" +
"setMainActivity(Landroid/app/Activity;)V", "setMainActivity(Landroid/app/Activity;)V",
) )

View File

@@ -117,6 +117,7 @@ val sponsorBlockPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -8,6 +8,8 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.ListPreference import app.revanced.patches.shared.misc.settings.preference.ListPreference
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_17_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@@ -15,16 +17,17 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
private const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/spoof/SpoofAppVersionPatch;" "Lapp/revanced/extension/youtube/patches/spoof/SpoofAppVersionPatch;"
@Suppress("unused")
val spoofAppVersionPatch = bytecodePatch( val spoofAppVersionPatch = bytecodePatch(
name = "Spoof app version", name = "Spoof app version",
description = "Adds an option to trick YouTube into thinking you are running an older version of the app. " + description = "Adds an option to trick YouTube into thinking you are running an older version of the app. " +
"This can be used to restore old UI elements and features.", "This can be used to restore old UI elements and features. " +
"Patching 19.16.39 or lower includes additional older spoofing targets.",
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,
settingsPatch, settingsPatch,
addResourcesPatch, addResourcesPatch,
versionCheckPatch
) )
compatibleWith( compatibleWith(
@@ -35,6 +38,7 @@ val spoofAppVersionPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )
@@ -43,10 +47,19 @@ val spoofAppVersionPatch = bytecodePatch(
PreferenceScreen.GENERAL_LAYOUT.addPreferences( PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_spoof_app_version"), SwitchPreference("revanced_spoof_app_version"),
ListPreference( if (is_19_17_or_greater) {
key = "revanced_spoof_app_version_target", ListPreference(
summaryKey = null, key = "revanced_spoof_app_version_target",
), summaryKey = null,
)
} else {
ListPreference(
key = "revanced_spoof_app_version_target",
summaryKey = null,
entriesKey = "revanced_spoof_app_version_target_legacy_entries",
entryValuesKey = "revanced_spoof_app_version_target_legacy_entry_values"
)
}
) )
val insertIndex = spoofAppVersionFingerprint.patternMatch!!.startIndex + 1 val insertIndex = spoofAppVersionFingerprint.patternMatch!!.startIndex + 1

View File

@@ -17,7 +17,6 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/ChangeStartPagePatch;" private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/ChangeStartPagePatch;"
@Suppress("unused")
val changeStartPagePatch = bytecodePatch( val changeStartPagePatch = bytecodePatch(
name = "Change start page", name = "Change start page",
description = "Adds an option to set which page the app opens in instead of the homepage.", description = "Adds an option to set which page the app opens in instead of the homepage.",
@@ -36,6 +35,7 @@ val changeStartPagePatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -19,7 +19,6 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
private const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/DisableResumingStartupShortsPlayerPatch;" "Lapp/revanced/extension/youtube/patches/DisableResumingStartupShortsPlayerPatch;"
@Suppress("unused")
val disableResumingShortsOnStartupPatch = bytecodePatch( val disableResumingShortsOnStartupPatch = bytecodePatch(
name = "Disable resuming Shorts on startup", name = "Disable resuming Shorts on startup",
description = "Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched.", description = "Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched.",
@@ -38,6 +37,7 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -14,7 +14,6 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch
const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/TabletLayoutPatch;" const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/TabletLayoutPatch;"
@Suppress("unused")
val enableTabletLayoutPatch = bytecodePatch( val enableTabletLayoutPatch = bytecodePatch(
name = "Enable tablet layout", name = "Enable tablet layout",
description = "Adds an option to enable tablet layout.", description = "Adds an option to enable tablet layout.",
@@ -33,6 +32,7 @@ val enableTabletLayoutPatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

View File

@@ -28,7 +28,6 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
internal const val GRADIENT_LOADING_SCREEN_AB_CONSTANT = 45412406L internal const val GRADIENT_LOADING_SCREEN_AB_CONSTANT = 45412406L
@Suppress("unused")
val themePatch = bytecodePatch( val themePatch = bytecodePatch(
name = "Theme", name = "Theme",
description = "Adds options for theming and applies a custom background theme (dark background theme defaults to amoled black).", description = "Adds options for theming and applies a custom background theme (dark background theme defaults to amoled black).",
@@ -201,6 +200,7 @@ val themePatch = bytecodePatch(
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41", "19.43.41",
"19.45.38",
), ),
) )

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