Compare commits

...
Sign in to create a new pull request.

661 commits

Author SHA1 Message Date
semantic-release-bot
b632d0f042 chore: Release v6.1.0 [skip ci]
# [6.1.0](https://github.com/ReVanced/revanced-patches/compare/v6.0.1...v6.1.0) (2026-03-18)

### Bug Fixes

* **Export internal data documents provider:** Correct S_IFLNK constant and symlink detection mask ([#6819](https://github.com/ReVanced/revanced-patches/issues/6819)) ([252617b](252617b8dd))
* **YouTube - Custom branding:** Fix double icons and change default branding to ReVanced ([#6806](https://github.com/ReVanced/revanced-patches/issues/6806)) ([e51c529](e51c5292c1))

### Features

* Add `Spoof root of trust` and `Spoof keystore security level` patch ([#6751](https://github.com/ReVanced/revanced-patches/issues/6751)) ([4bc8c7c](4bc8c7c0f6))
* **Announcements:** Support ReVanced API v5 announcements ([a05386e](a05386e8bc))
* Change contact email in patches about ([df1c3a4](df1c3a4a70))
* **Instagram:** Add `Enable location sticker redesign` patch ([#6808](https://github.com/ReVanced/revanced-patches/issues/6808)) ([4b699da](4b699da220))
* **Spoof video streams:** Add Android Reel client to fix playback issues ([#6830](https://github.com/ReVanced/revanced-patches/issues/6830)) ([4b6c3e3](4b6c3e3123))
2026-03-18 15:54:36 +00:00
oSumAtrIX
fca2470990
chore: Merge branch dev to main (#6820)
Co-authored-by: PlayDay <18056374+playday3008@users.noreply.github.com>
Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
Co-authored-by: Dawid Krajcarz <80264606+drobotk@users.noreply.github.com>
Co-authored-by: Kofhisho <github@alphexo.dev>
Co-authored-by: rospino74 <34315725+rospino74@users.noreply.github.com>
Co-authored-by: ADudeCalledLeo <7997354+Leo40Git@users.noreply.github.com>
Co-authored-by: Aaron Mompié <github@aaronmompie.com>
Co-authored-by: inotia00 <108592928+inotia00@users.noreply.github.com>
2026-03-18 16:50:48 +01:00
semantic-release-bot
66b6c8c8ed chore: Release v6.1.0-dev.4 [skip ci]
# [6.1.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v6.1.0-dev.3...v6.1.0-dev.4) (2026-03-18)

### Bug Fixes

* **YouTube - Custom branding:** Fix double icons and change default branding to ReVanced ([#6806](https://github.com/ReVanced/revanced-patches/issues/6806)) ([e51c529](e51c5292c1))

### Features

* Add `Spoof root of trust` and `Spoof keystore security level` patch ([#6751](https://github.com/ReVanced/revanced-patches/issues/6751)) ([4bc8c7c](4bc8c7c0f6))
* **Instagram:** Add `Enable location sticker redesign` patch ([#6808](https://github.com/ReVanced/revanced-patches/issues/6808)) ([4b699da](4b699da220))
2026-03-18 15:44:38 +00:00
Aaron Mompié
4b699da220
feat(Instagram): Add Enable location sticker redesign patch (#6808)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-03-18 16:41:12 +01:00
rospino74
e19275fb7d
feat!: Add Spoof Play Age Signals patch (#6692)
Co-authored-by: ADudeCalledLeo <7997354+Leo40Git@users.noreply.github.com>
Co-authored-by: Dawid Krajcarz <80264606+drobotk@users.noreply.github.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-03-18 16:40:22 +01:00
Kofhisho
4bc8c7c0f6
feat: Add Spoof root of trust and Spoof keystore security level patch (#6751)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-03-18 16:39:46 +01:00
Dawid Krajcarz
e51c5292c1
fix(YouTube - Custom branding): Fix double icons and change default branding to ReVanced (#6806) 2026-03-18 16:38:30 +01:00
semantic-release-bot
43688d0622 chore: Release v6.1.0-dev.3 [skip ci]
# [6.1.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v6.1.0-dev.2...v6.1.0-dev.3) (2026-03-18)

### Features

* **Spoof video streams:** Add Android Reel client to fix playback issues ([#6830](https://github.com/ReVanced/revanced-patches/issues/6830)) ([4b6c3e3](4b6c3e3123))
2026-03-18 14:04:42 +00:00
oSumAtrIX
4b6c3e3123
feat(Spoof video streams): Add Android Reel client to fix playback issues (#6830)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
Co-authored-by: inotia00 <108592928+inotia00@users.noreply.github.com>
2026-03-18 15:00:26 +01:00
oSumAtrIX
14ea61355d
ci: Make strings permissions writeable for processing 2026-03-18 15:00:13 +01:00
oSumAtrIX
90eebe082c
chore: Sync translations from Crowdin 2026-03-18 14:56:59 +01:00
semantic-release-bot
6564c7642f chore: Release v6.1.0-dev.2 [skip ci]
# [6.1.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v6.1.0-dev.1...v6.1.0-dev.2) (2026-03-17)

### Features

* **Announcements:** Support ReVanced API v5 announcements ([a05386e](a05386e8bc))
2026-03-17 12:19:34 +00:00
oSumAtrIX
a05386e8bc
feat(Announcements): Support ReVanced API v5 announcements 2026-03-17 13:17:00 +01:00
semantic-release-bot
64cae2bfa5 chore: Release v6.1.0-dev.1 [skip ci]
# [6.1.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v6.0.2-dev.1...v6.1.0-dev.1) (2026-03-16)

### Features

* Change contact email in patches about ([df1c3a4](df1c3a4a70))
2026-03-16 22:38:34 +00:00
oSumAtrIX
df1c3a4a70
feat: Change contact email in patches about
The new dedicated email will is specialized for patches purposes, keeping it separate from organizational/ general emails.
2026-03-16 23:36:07 +01:00
semantic-release-bot
558f683bf2 chore: Release v6.0.2-dev.1 [skip ci]
## [6.0.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v6.0.1...v6.0.2-dev.1) (2026-03-16)

### Bug Fixes

* **Export internal data documents provider:** Correct S_IFLNK constant and symlink detection mask ([#6819](https://github.com/ReVanced/revanced-patches/issues/6819)) ([252617b](252617b8dd))
2026-03-16 11:09:45 +00:00
PlayDay
252617b8dd
fix(Export internal data documents provider): Correct S_IFLNK constant and symlink detection mask (#6819) 2026-03-16 12:07:09 +01:00
semantic-release-bot
c35b8b8e96 chore: Release v6.0.1 [skip ci]
## [6.0.1](https://github.com/ReVanced/revanced-patches/compare/v6.0.0...v6.0.1) (2026-03-15)

### Bug Fixes

* **GmsCore support:** use `prefixOrReplace` for non-matching APP_AUTHORITIES in content URL transformation ([#6801](https://github.com/ReVanced/revanced-patches/issues/6801)) ([8f6f128](8f6f128d71))
* **YouTube Music - Hide buttons:** Crashes on startup due to null LayoutParams ([#6799](https://github.com/ReVanced/revanced-patches/issues/6799)) ([3e32c38](3e32c38732))
* **YouTube:** Use correct query parameters for DeArrow requests ([#6780](https://github.com/ReVanced/revanced-patches/issues/6780)) ([02a48e7](02a48e7a5f))
2026-03-15 18:03:19 +00:00
oSumAtrIX
33aa830a1c
chore: Merge branch dev to main (#6786)
Co-authored-by: Itroublve <115026399+Anajrim01@users.noreply.github.com>
Co-authored-by: Dawid Krajcarz <80264606+drobotk@users.noreply.github.com>
Co-authored-by: Lucas Martinati <127530926+lucas-martinati@users.noreply.github.com>
2026-03-15 19:00:23 +01:00
semantic-release-bot
8f10eb62a8 chore: Release v6.0.1-dev.3 [skip ci]
## [6.0.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v6.0.1-dev.2...v6.0.1-dev.3) (2026-03-15)

### Bug Fixes

* **GmsCore support:** use `prefixOrReplace` for non-matching APP_AUTHORITIES in content URL transformation ([#6801](https://github.com/ReVanced/revanced-patches/issues/6801)) ([8f6f128](8f6f128d71))
2026-03-15 16:50:02 +00:00
Lucas Martinati
8f6f128d71
fix(GmsCore support): use prefixOrReplace for non-matching APP_AUTHORITIES in content URL transformation (#6801) 2026-03-15 17:47:15 +01:00
semantic-release-bot
5fe8b58284 chore: Release v6.0.1-dev.2 [skip ci]
## [6.0.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v6.0.1-dev.1...v6.0.1-dev.2) (2026-03-15)

### Bug Fixes

* **YouTube Music - Hide buttons:** Crashes on startup due to null LayoutParams ([#6799](https://github.com/ReVanced/revanced-patches/issues/6799)) ([3e32c38](3e32c38732))
2026-03-15 16:21:39 +00:00
Dawid Krajcarz
3e32c38732
fix(YouTube Music - Hide buttons): Crashes on startup due to null LayoutParams (#6799) 2026-03-15 17:19:06 +01:00
semantic-release-bot
ce85fbfad7 chore: Release v6.0.1-dev.1 [skip ci]
## [6.0.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v6.0.0...v6.0.1-dev.1) (2026-03-15)

### Bug Fixes

* **YouTube:** Use correct query parameters for DeArrow requests ([#6780](https://github.com/ReVanced/revanced-patches/issues/6780)) ([02a48e7](02a48e7a5f))
2026-03-15 10:19:34 +00:00
Itroublve
02a48e7a5f
fix(YouTube): Use correct query parameters for DeArrow requests (#6780) 2026-03-15 11:16:51 +01:00
semantic-release-bot
5e1f899a3b chore: Release v6.0.0 [skip ci]
# [6.0.0](https://github.com/ReVanced/revanced-patches/compare/v5.50.2...v6.0.0) (2026-03-14)

* build(Needs bump)!: Update to ReVanced Patcher v22  ([#6542](https://github.com/ReVanced/revanced-patches/issues/6542)) ([ab2ac36](ab2ac36e30))

### Bug Fixes

* Add minSdk to all extension projects ([#6778](https://github.com/ReVanced/revanced-patches/issues/6778)) ([7517f57](7517f57ac7))
* **Check environment:** Use another (also more suitable) API to circumvent a bug ([393700f](393700f74a))
* **Custom branding:** Fix defaults ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([3e00a99](3e00a99c1b))
* **Custom branding:** Resolve background playback crash with custom branded root installation ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([6aba2d1](6aba2d1274))
* **Enable debugging:** Add missing preference to log protocol buffer ([26d8a9e](26d8a9e5f8))
* Fix return type check to match method successfully ([0a73452](0a734528dc))
* **GmsCore support:** Handle GmsCore flavors when checking for updates ([2aa19f5](2aa19f5995))
* **GmsCore support:** Insert check after another missing necessary context hook ([3c0c5a8](3c0c5a86d8))
* **GmsCore support:** Insert check after necessary context hook ([03e8e3d](03e8e3d75c))
* **GmsCore support:** Rename MicroG GmsCore specific strings as well and rename app specific strings correctly ([c2ac1f0](c2ac1f04a0))
* **GmsCore support:** Try replacing in strings before prefixing to handle more edge cases ([4d94a41](4d94a41c46))
* **Hex patch:** Fix bug in implementation of Boyer-Moore algorithm ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f59323c](f59323c87d))
* **Hex:** Add back name, which was accidentally removed from the patch ([6a547a9](6a547a97e5))
* **Instagram:** Update fingerprints for version `417.0.0.54.77` ([#6734](https://github.com/ReVanced/revanced-patches/issues/6734)) ([55f510d](55f510dbed))
* Move strings to correct patch ([4dfe3fb](4dfe3fb088))
* **ProtonVPN - Remove delay:** Make it work on latest version by patching the correct class ([#6757](https://github.com/ReVanced/revanced-patches/issues/6757)) ([e0dc009](e0dc009780))
* **Reddit clients:** Fix patching broken during patcher migration by searching for strings with contains([#6681](https://github.com/ReVanced/revanced-patches/issues/6681)) ([00da402](00da402770))
* Rename string keys correctly ([16e00ab](16e00ab4c0))
* **Spotify - Sanitize sharing links:** Update patch to latest app versions ([#6685](https://github.com/ReVanced/revanced-patches/issues/6685)) ([bb7448b](bb7448bc9d))
* Use correct string key ([9d55d00](9d55d00ff4))
* Use custom comparison block for strings in `anyOf` ([56a087d](56a087dbac))
* Use positional substitutes in strings where multiple are present ([aa8c87f](aa8c87f865))
* **YouTube - Enable Debugging Patch:** Use correct Protocolbuffer setting name ([#6711](https://github.com/ReVanced/revanced-patches/issues/6711)) ([f934022](f934022f37))
* **YouTube - Exit fullscreen mode:** Handle exiting fullscreen on first opened video ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([88724d4](88724d47b1))
* **YouTube - Hide ads:** Empty space left when ads are hidden on tablets ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([c1c2aa9](c1c2aa98b2))
* **YouTube - Hide ads:** Fix "Hide YouTube Premium promotions" hiding YouTube Doodles ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([d26e352](d26e352850))
* **YouTube - Hide ads:** Hide new type of general ad, movie ad and web search result ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([9b12dd1](9b12dd1065))
* **YouTube - Hide ads:** Hide new type of player ad ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([c97aefc](c97aefc272))
* **YouTube - Hide ads:** Hide video ads does not hide Shorts ads ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([8d274a7](8d274a7afc))
* **YouTube - Hide ads:** Support Hide fullscreen ads on Android 13+ devices ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([02b405e](02b405e6ac))
* **YouTube - Hide ads:** YouTube Doodles unclickable when Hide ads is enabled ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([5d45b6d](5d45b6da74))
* **YouTube - Hide end screen cards:** Resolve patching 20.31.4x ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([3ff303f](3ff303f045))
* **YouTube - Hide layout components:** Ensure featured places also hide watch history shelf ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([d639faf](d639faf71f))
* **YouTube - Hide layout components:** Fix certain description components not working ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([1bf64eb](1bf64eb8b0))
* **YouTube - Hide layout components:** Fix empty space issues (subscribed channels bar, show more button, landscape mode) ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([22ef700](22ef7002e0))
* **YouTube - Hide layout components:** Fix side effect of Disable translucent status bar ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([5760c58](5760c5860a))
* **YouTube - Hide layout components:** Resolve "Hide community posts" not working in search results ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([3153222](315322220d))
* **YouTube - Hide layout components:** Resolve community posts sometimes showing in player suggestions ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([828df77](828df77810))
* **YouTube - Hide Shorts components:** Action buttons not hidden in 20.22+ ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([a90a0b1](a90a0b1199))
* **YouTube - Hide Shorts components:** Do not hide channel page headers when hiding shorts ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([1246e43](1246e430f2))
* **YouTube - Hide Shorts components:** Find resource id only for 21.05+ ([63161e9](63161e9fb3))
* **YouTube - Hide Shorts components:** Fix sound metadata label hiding other components ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([49d1f65](49d1f65fca))
* **YouTube - Hide Shorts components:** Hide new type of sound metadata label ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([a6b8d2f](a6b8d2f103))
* **YouTube - Hide Shorts components:** Resolve hiding Shorts not working ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([ae69bdc](ae69bdc1d3))
* **YouTube - Loop video:** Enable loop video not working in playlist ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([06dbf7e](06dbf7ee80))
* **YouTube - Loop video:** Fix looping button state ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([14d0135](14d0135b3c))
* **YouTube - Loop video:** Wrong icon applied ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([b34adf6](b34adf6437))
* **YouTube - Open Shorts in regular player:** Fix back behavior with 20.51 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([46ec3d3](46ec3d3bdd))
* **YouTube - Open Shorts in regular player:** Resolve back button closing app instead of exiting fullscreen ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([b787c46](b787c469fd))
* **YouTube - Playback speed:** Use correct extension method name ([b8b4cfb](b8b4cfbd01))
* **YouTube - Remove background playback restrictions:** Fix background playback not working with certain offline videos ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([2d098f2](2d098f2352))
* **YouTube - Remove viewer discretion dialog:** Not working on 20.14.43+ ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([64c397e](64c397eb1c))
* **YouTube - Return YouTube Dislike:** Fix incorrect dislike counts after cancel ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([ad10d76](ad10d76035))
* **YouTube - ReturnYouTubeDislike:** Fix dislikes not showing with 20.31+ ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([2033883](2033883294))
* **YouTube - Settings:** Icon not drawn correctly on some systems ([#6683](https://github.com/ReVanced/revanced-patches/issues/6683)) ([ddb6396](ddb6396b3f))
* **YouTube - SponsorBlock:** Do not show context toast when auto skipping in feed ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([88157ac](88157ac5b7))
* **YouTube - SponsorBlock:** Resolve segments not fetching on experimental app targets ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([2067799](206779942d))
* **YouTube - SponsorBlock:** Show correct nested skip segment when seeking ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f5ef68b](f5ef68b61a))
* **YouTube - Spoof app version:** Remove target `19.35.36` no longer supported by YouTube ([#6717](https://github.com/ReVanced/revanced-patches/issues/6717)) ([46fb366](46fb3669ee))
* **YouTube - Spoof video streams:** Make it work on 21.x ([#6705](https://github.com/ReVanced/revanced-patches/issues/6705)) ([fdfed3c](fdfed3c9dd))
* **YouTube Music - Navigation bar:** Hide library tab with 8.24+ ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([cfcae43](cfcae43465))
* **YouTube Music:** Prevent crash on bold icons loading ([#6712](https://github.com/ReVanced/revanced-patches/issues/6712)) ([e9bfb7c](e9bfb7ca9b))
* **YouTube:** Add back missing custom filter by adding the preference to the correct screen ([2a10489](2a10489a86))
* **YouTube:** Change recommended version to 20.37.48 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([3dd305c](3dd305ca5d))
* **YouTube:** Changes the default values for some settings ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([dce204b](dce204b41b))
* **YouTube:** Do not show bold icons if old settings menus is enabled ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([30bd852](30bd852ba5))
* **YouTube:** Fix patching unsupported 20.13.41 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([ed45375](ed45375105))
* **YouTube:** Ignore cairo flag in debug flag manager ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([093497c](093497c34f))
* **YouTube:** Remove 19.43.41 that YouTube no longer supports ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([a8526dc](a8526dc8ae))

### Features

* Add overlay buttons animation ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f6fc6aa](f6fc6aa5ac))
* **Check environment patch:** Support another ReVanced Manager debug variant package name ([e4dea68](e4dea682c6))
* **Custom branding:** Default to user-provided icon and name when provided ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f19c35e](f19c35e21c))
* **Enable debugging:** Allow overriding String/long/double flags in debug flag manager ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([1f91bc8](1f91bc8a20))
* **GMX Mail:** Add `Force enable Freephone` patch ([#6650](https://github.com/ReVanced/revanced-patches/issues/6650)) ([997b5d6](997b5d63d1))
* **GMX Mail:** Add `Hide ads` and `Hide Premium upgrade button` patches ([#6583](https://github.com/ReVanced/revanced-patches/issues/6583)) ([2976ea3](2976ea3ddd))
* Handle multiple branch conditionals jumping to the same instruction index ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([2f7b57d](2f7b57d071))
* **Instagram:** Add `Disable Reels auto-scroll` patch ([#6736](https://github.com/ReVanced/revanced-patches/issues/6736)) ([806d6c7](806d6c799f))
* Perform full search of free registers ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([01ef43a](01ef43abab))
* **Photoshop Mix:** Add `Bypass login` patch ([#6745](https://github.com/ReVanced/revanced-patches/issues/6745)) ([24caae9](24caae98b7))
* Update YouTube & YouTube Music patches ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([88d33b8](88d33b847d))
* Use more informative patch error if the same APK is patched twice ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([26e5ce1](26e5ce1a32))
* **YouTube - Disable haptic feedback:** Add Disable tap and hold haptics setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f135122](f135122df1))
* **YouTube - Hide ads:** Add Hide player popup ads setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([487a95d](487a95d3ef))
* **YouTube - Hide layout components:** Add "Hide channel tab filter" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([0adcd8c](0adcd8c62e))
* **YouTube - Hide layout components:** Add "Hide collapse button" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([1554fd9](1554fd916d))
* **YouTube - Hide layout components:** Add "Hide comments section in Home feed" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([5278434](5278434534))
* **YouTube - Hide layout components:** Add "Hide course progress" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([1927564](192756443a))
* **YouTube - Hide layout components:** Add "Hide explore this course" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([3e24762](3e24762c18))
* **YouTube - Hide layout components:** Add "Hide featured links", "Hide featured videos", "Hide join button", and "Hide subscribe button" options ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f9e843d](f9e843d756))
* **YouTube - Hide layout components:** Add "Hide feed flyout menu filter" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([a93de46](a93de46572))
* **YouTube - Hide layout components:** Add "Hide fullscreen button" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([b07b160](b07b1609e4))
* **YouTube - Hide layout components:** Add "Hide latest videos button" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([ebfdd8d](ebfdd8df2c))
* **YouTube - Hide layout components:** Add "Hide live chat replay button" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([a6bd311](a6bd3116f9))
* **YouTube - Hide layout components:** Add "Hide quizzes" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([70b9e10](70b9e103ae))
* **YouTube - Hide layout components:** Add "Hide search box trending results" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([21bf455](21bf455c3f))
* **YouTube - Hide layout components:** Add "Hide subscribed channels bar" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([e41a40f](e41a40f0d7))
* **YouTube - Hide layout components:** Add "Hide video title" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([2cfbe08](2cfbe08b21))
* **YouTube - Hide layout components:** Apply hide search suggestions only to more recent app targets ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([a43c0e1](a43c0e111b))
* **YouTube - Hide layout components:** Replace "Hide search suggestions" with "Hide You may like section" ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([80f6b01](80f6b01c64))
* **YouTube - Hide Shorts components:** Add "Hide AI button" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([99aace4](99aace4178))
* **YouTube - Hide Shorts components:** Add "Hide in video description" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([e0a8b7b](e0a8b7bc59))
* **YouTube - Navigation bar:** Add settings to hide toolbar buttons ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([d72e39f](d72e39f2a8))
* **YouTube - Navigation buttons:** Add setting to use narrow navigation bar buttons ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([e48a5d7](e48a5d76f7))
* **YouTube - SponsorBlock:** Show skip button if player overlay controls are active ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([35ec655](35ec655f83))
* **YouTube - Theme:** Add "Hide splash screen" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([ca6e184](ca6e184172))
* **YouTube - Video quality:** Add Hide Premium video quality setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([50a2b67](50a2b67ef6))
* **YouTube Music:** Add experimental support for 9.02.50 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([50a102d](50a102d8af))
* **YouTube Music:** Add experimental support for 9.03.52 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([d5b9c0c](d5b9c0c03d))
* **YouTube Music:** Change recommended version to 8.37.56 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([d1e7900](d1e7900793))
* **YouTube Music:** Support version 8.40.54 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([62f130c](62f130cc88))
* **YouTube Music:** Unofficial support of 8.50.51 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([c1d7cae](c1d7caeee2))
* **YouTube:** Add experimental support for 21.02.32 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([7904b60](7904b60dbe))
* **YouTube:** Add experimental support for 21.03.34 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([1ae36a1](1ae36a1cc7))
* **YouTube:** Add experimental support for 21.04.221 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([66e113a](66e113a966))
* **YouTube:** Add experimental support for 21.05.264 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f646c82](f646c820d7))
* **YouTube:** Add experimental support for 21.06.251 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([44b17d4](44b17d4758))
* **YouTube:** Add experimental support for 21.06.257 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([abb703d](abb703dcb2))
* **YouTube:** Add experimental support for 21.07.240 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([79b0c1f](79b0c1f72f))
* **YouTube:** Add Hide autoplay preview patch ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([79e3955](79e3955fde))
* **YouTube:** Add more double tap to seek length options ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([fb04071](fb04071528))
* **YouTube:** Remove obsolete seekbar thumbnail patch ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([9909fc1](9909fc1e5d))
* **YouTube:** Support version 20.40.45 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([96c85d0](96c85d0371))

### BREAKING CHANGES

* Deprecated APIs have been removed, and various APIs now use the updated ReVanced Patcher v22 APIs.
2026-03-14 23:09:51 +00:00
oSumAtrIX
938c6fae60
chore: Merge branch dev to main (#6591) 2026-03-15 00:06:00 +01:00
oSumAtrIX
ca903248a5
chore: Sync translations from Crowdin 2026-03-14 22:53:13 +01:00
semantic-release-bot
a2a11d7362 chore: Release v6.0.0-dev.26 [skip ci]
# [6.0.0-dev.26](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.25...v6.0.0-dev.26) (2026-03-14)

### Bug Fixes

* Add minSdk to all extension projects ([#6778](https://github.com/ReVanced/revanced-patches/issues/6778)) ([7517f57](7517f57ac7))
2026-03-14 18:44:52 +00:00
kitadai31
7517f57ac7
fix: Add minSdk to all extension projects (#6778) 2026-03-14 19:41:18 +01:00
semantic-release-bot
dc39dfdab4 chore: Release v6.0.0-dev.25 [skip ci]
# [6.0.0-dev.25](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.24...v6.0.0-dev.25) (2026-03-14)

### Features

* **Instagram:** Add `Disable Reels auto-scroll` patch ([#6736](https://github.com/ReVanced/revanced-patches/issues/6736)) ([806d6c7](806d6c799f))
2026-03-14 12:55:58 +00:00
Aaron Mompié
806d6c799f
feat(Instagram): Add Disable Reels auto-scroll patch (#6736)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-03-14 13:52:12 +01:00
Pun Butrach
b2b1e4f993
ci: Bump actions to avoid Node 20 deprecation (#6772) 2026-03-13 14:41:35 +01:00
semantic-release-bot
882cb4a0d4 chore: Release v6.0.0-dev.24 [skip ci]
# [6.0.0-dev.24](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.23...v6.0.0-dev.24) (2026-03-09)

### Features

* **Photoshop Mix:** Add `Bypass login` patch ([#6745](https://github.com/ReVanced/revanced-patches/issues/6745)) ([24caae9](24caae98b7))
2026-03-09 19:07:17 +00:00
Dylan
24caae98b7
feat(Photoshop Mix): Add Bypass login patch (#6745)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-03-09 20:03:25 +01:00
semantic-release-bot
a02350bbc8 chore: Release v6.0.0-dev.23 [skip ci]
# [6.0.0-dev.23](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.22...v6.0.0-dev.23) (2026-03-09)

### Bug Fixes

* **ProtonVPN - Remove delay:** Make it work on latest version by patching the correct class ([#6757](https://github.com/ReVanced/revanced-patches/issues/6757)) ([e0dc009](e0dc009780))
2026-03-09 18:13:38 +00:00
Sayanth
e0dc009780
fix(ProtonVPN - Remove delay): Make it work on latest version by patching the correct class (#6757) 2026-03-09 19:10:05 +01:00
semantic-release-bot
d2659637ac chore: Release v6.0.0-dev.22 [skip ci]
# [6.0.0-dev.22](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.21...v6.0.0-dev.22) (2026-03-08)

### Bug Fixes

* **YouTube - Settings:** Icon not drawn correctly on some systems ([#6683](https://github.com/ReVanced/revanced-patches/issues/6683)) ([ddb6396](ddb6396b3f))
2026-03-08 19:55:59 +00:00
Dawid Krajcarz
ddb6396b3f
fix(YouTube - Settings): Icon not drawn correctly on some systems (#6683) 2026-03-08 20:52:16 +01:00
semantic-release-bot
49dffe37c5 chore: Release v6.0.0-dev.21 [skip ci]
# [6.0.0-dev.21](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.20...v6.0.0-dev.21) (2026-03-08)

### Bug Fixes

* **Instagram:** Update fingerprints for version `417.0.0.54.77` ([#6734](https://github.com/ReVanced/revanced-patches/issues/6734)) ([55f510d](55f510dbed))
* **Spotify - Sanitize sharing links:** Update patch to latest app versions ([#6685](https://github.com/ReVanced/revanced-patches/issues/6685)) ([bb7448b](bb7448bc9d))
2026-03-08 19:39:41 +00:00
Pun Butrach
0637d4596a
ci: Use new attestation action (#6744) 2026-03-08 20:36:06 +01:00
Aaron Mompié
55f510dbed
fix(Instagram): Update fingerprints for version 417.0.0.54.77 (#6734) 2026-03-08 20:34:52 +01:00
Dawid Krajcarz
bb7448bc9d
fix(Spotify - Sanitize sharing links): Update patch to latest app versions (#6685) 2026-03-08 20:33:36 +01:00
semantic-release-bot
ed9f191a2e chore: Release v6.0.0-dev.20 [skip ci]
# [6.0.0-dev.20](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.19...v6.0.0-dev.20) (2026-03-08)

### Bug Fixes

* **YouTube - Enable Debugging Patch:** Use correct Protocolbuffer setting name ([#6711](https://github.com/ReVanced/revanced-patches/issues/6711)) ([f934022](f934022f37))
2026-03-08 16:12:49 +00:00
rospino74
f934022f37
fix(YouTube - Enable Debugging Patch): Use correct Protocolbuffer setting name (#6711) 2026-03-08 17:09:24 +01:00
semantic-release-bot
11bd06d374 chore: Release v6.0.0-dev.19 [skip ci]
# [6.0.0-dev.19](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.18...v6.0.0-dev.19) (2026-03-06)

### Bug Fixes

* **Hex:** Add back name, which was accidentally removed from the patch ([6a547a9](6a547a97e5))
2026-03-06 18:01:51 +00:00
oSumAtrIX
6a547a97e5
fix(Hex): Add back name, which was accidentally removed from the patch 2026-03-06 18:56:45 +01:00
semantic-release-bot
f7298ffd52 chore: Release v6.0.0-dev.18 [skip ci]
# [6.0.0-dev.18](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.17...v6.0.0-dev.18) (2026-03-06)

### Bug Fixes

* **YouTube - Hide Shorts components:** Find resource id only for 21.05+ ([63161e9](63161e9fb3))
2026-03-06 14:36:34 +00:00
oSumAtrIX
63161e9fb3
fix(YouTube - Hide Shorts components): Find resource id only for 21.05+ 2026-03-06 15:32:35 +01:00
semantic-release-bot
a031891566 chore: Release v6.0.0-dev.17 [skip ci]
# [6.0.0-dev.17](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.16...v6.0.0-dev.17) (2026-03-06)

### Bug Fixes

* **YouTube - Spoof video streams:** Make it work on 21.x ([#6705](https://github.com/ReVanced/revanced-patches/issues/6705)) ([fdfed3c](fdfed3c9dd))
2026-03-06 11:31:07 +00:00
Jack
fdfed3c9dd
fix(YouTube - Spoof video streams): Make it work on 21.x (#6705)
Co-authored-by: wowitsjack <no@email>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-03-06 12:27:41 +01:00
semantic-release-bot
f045923cef chore: Release v6.0.0-dev.16 [skip ci]
# [6.0.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.15...v6.0.0-dev.16) (2026-03-05)

### Bug Fixes

* **YouTube - Spoof app version:** Remove target `19.35.36` no longer supported by YouTube ([#6717](https://github.com/ReVanced/revanced-patches/issues/6717)) ([46fb366](46fb3669ee))
* **YouTube Music:** Prevent crash on bold icons loading ([#6712](https://github.com/ReVanced/revanced-patches/issues/6712)) ([e9bfb7c](e9bfb7ca9b))
2026-03-05 22:23:17 +00:00
rospino74
e9bfb7ca9b
fix(YouTube Music): Prevent crash on bold icons loading (#6712) 2026-03-05 23:19:29 +01:00
Dawid Krajcarz
46fb3669ee
fix(YouTube - Spoof app version): Remove target 19.35.36 no longer supported by YouTube (#6717) 2026-03-05 23:17:53 +01:00
semantic-release-bot
79b6733eec chore: Release v6.0.0-dev.15 [skip ci]
# [6.0.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.14...v6.0.0-dev.15) (2026-03-05)

### Bug Fixes

* **Check environment:** Use another (also more suitable) API to circumvent a bug ([393700f](393700f74a))
2026-03-05 21:29:55 +00:00
oSumAtrIX
393700f74a
fix(Check environment): Use another (also more suitable) API to circumvent a bug 2026-03-05 22:26:14 +01:00
semantic-release-bot
380be33fed chore: Release v6.0.0-dev.14 [skip ci]
# [6.0.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.13...v6.0.0-dev.14) (2026-03-03)

### Bug Fixes

* **YouTube - Playback speed:** Use correct extension method name ([b8b4cfb](b8b4cfbd01))
2026-03-03 07:33:54 +00:00
Dawid Krajcarz
b8b4cfbd01
fix(YouTube - Playback speed): Use correct extension method name 2026-03-03 08:30:04 +01:00
semantic-release-bot
eff5388520 chore: Release v6.0.0-dev.13 [skip ci]
# [6.0.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.12...v6.0.0-dev.13) (2026-03-02)

### Bug Fixes

* Use custom comparison block for strings in `anyOf` ([56a087d](56a087dbac))
2026-03-02 22:30:24 +00:00
drobotk
56a087dbac
fix: Use custom comparison block for strings in anyOf 2026-03-02 23:26:26 +01:00
semantic-release-bot
8125741d90 chore: Release v6.0.0-dev.12 [skip ci]
# [6.0.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.11...v6.0.0-dev.12) (2026-03-02)

### Bug Fixes

* Fix return type check to match method successfully ([0a73452](0a734528dc))

### Features

* **Check environment patch:** Support another ReVanced Manager debug variant package name ([e4dea68](e4dea682c6))
2026-03-02 17:26:36 +00:00
oSumAtrIX
0a734528dc
fix: Fix return type check to match method successfully 2026-03-02 18:22:39 +01:00
oSumAtrIX
e4dea682c6
feat(Check environment patch): Support another ReVanced Manager debug variant package name 2026-03-02 18:22:39 +01:00
semantic-release-bot
29b60bad4c chore: Release v6.0.0-dev.11 [skip ci]
# [6.0.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.10...v6.0.0-dev.11) (2026-03-02)

### Bug Fixes

* Use correct string key ([9d55d00](9d55d00ff4))
2026-03-02 16:38:29 +00:00
oSumAtrIX
9d55d00ff4
fix: Use correct string key 2026-03-02 17:34:47 +01:00
oSumAtrIX
0f378c9cea
ci: Do not archive PR build artifacts 2026-03-02 12:57:46 +01:00
semantic-release-bot
4936011ad5 chore: Release v6.0.0-dev.10 [skip ci]
# [6.0.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.9...v6.0.0-dev.10) (2026-03-01)

### Bug Fixes

* **Enable debugging:** Add missing preference to log protocol buffer ([26d8a9e](26d8a9e5f8))
2026-03-01 00:12:25 +00:00
oSumAtrIX
26d8a9e5f8
fix(Enable debugging): Add missing preference to log protocol buffer 2026-03-01 01:08:38 +01:00
semantic-release-bot
d5c8961675 chore: Release v6.0.0-dev.9 [skip ci]
# [6.0.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.8...v6.0.0-dev.9) (2026-02-28)

### Bug Fixes

* **YouTube:** Add back missing custom filter by adding the preference to the correct screen ([2a10489](2a10489a86))
2026-02-28 23:58:41 +00:00
oSumAtrIX
2a10489a86
fix(YouTube): Add back missing custom filter by adding the preference to the correct screen 2026-03-01 00:54:36 +01:00
semantic-release-bot
c6da2841a1 chore: Release v6.0.0-dev.8 [skip ci]
# [6.0.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.7...v6.0.0-dev.8) (2026-02-28)

### Bug Fixes

* **GmsCore support:** Try replacing in strings before prefixing to handle more edge cases ([4d94a41](4d94a41c46))
2026-02-28 23:14:40 +00:00
oSumAtrIX
4d94a41c46
fix(GmsCore support): Try replacing in strings before prefixing to handle more edge cases 2026-03-01 00:11:09 +01:00
semantic-release-bot
0cd6be5cd8 chore: Release v6.0.0-dev.7 [skip ci]
# [6.0.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.6...v6.0.0-dev.7) (2026-02-28)

### Bug Fixes

* Rename string keys correctly ([16e00ab](16e00ab4c0))
2026-02-28 22:12:17 +00:00
oSumAtrIX
16e00ab4c0
fix: Rename string keys correctly 2026-02-28 23:08:53 +01:00
semantic-release-bot
f7d0a18440 chore: Release v6.0.0-dev.6 [skip ci]
# [6.0.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.5...v6.0.0-dev.6) (2026-02-28)

### Bug Fixes

* Move strings to correct patch ([4dfe3fb](4dfe3fb088))
2026-02-28 21:28:48 +00:00
oSumAtrIX
4dfe3fb088
fix: Move strings to correct patch 2026-02-28 22:25:07 +01:00
semantic-release-bot
4dbc5312f5 chore: Release v6.0.0-dev.5 [skip ci]
# [6.0.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.4...v6.0.0-dev.5) (2026-02-28)

### Bug Fixes

* **Reddit clients:** Fix patching broken during patcher migration by searching for strings with contains([#6681](https://github.com/ReVanced/revanced-patches/issues/6681)) ([00da402](00da402770))
2026-02-28 19:08:53 +00:00
Dawid Krajcarz
00da402770
fix(Reddit clients): Fix patching broken during patcher migration by searching for strings with contains(#6681) 2026-02-28 20:05:29 +01:00
Dawid Krajcarz
adcaa11953
build: Use more fitting repository name to pull Gradle plugin from 2026-02-28 13:03:34 +01:00
semantic-release-bot
756783fc70 chore: Release v6.0.0-dev.4 [skip ci]
# [6.0.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v6.0.0-dev.3...v6.0.0-dev.4) (2026-02-27)

### Bug Fixes

* **Custom branding:** Fix defaults ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([3e00a99](3e00a99c1b))
* **Custom branding:** Resolve background playback crash with custom branded root installation ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([6aba2d1](6aba2d1274))
* **Hex patch:** Fix bug in implementation of Boyer-Moore algorithm ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f59323c](f59323c87d))
* **YouTube - Exit fullscreen mode:** Handle exiting fullscreen on first opened video ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([88724d4](88724d47b1))
* **YouTube - Hide ads:** Empty space left when ads are hidden on tablets ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([c1c2aa9](c1c2aa98b2))
* **YouTube - Hide ads:** Fix "Hide YouTube Premium promotions" hiding YouTube Doodles ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([d26e352](d26e352850))
* **YouTube - Hide ads:** Hide new type of general ad, movie ad and web search result ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([9b12dd1](9b12dd1065))
* **YouTube - Hide ads:** Hide new type of player ad ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([c97aefc](c97aefc272))
* **YouTube - Hide ads:** Hide video ads does not hide Shorts ads ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([8d274a7](8d274a7afc))
* **YouTube - Hide ads:** Support Hide fullscreen ads on Android 13+ devices ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([02b405e](02b405e6ac))
* **YouTube - Hide ads:** YouTube Doodles unclickable when Hide ads is enabled ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([5d45b6d](5d45b6da74))
* **YouTube - Hide end screen cards:** Resolve patching 20.31.4x ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([3ff303f](3ff303f045))
* **YouTube - Hide layout components:** Ensure featured places also hide watch history shelf ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([d639faf](d639faf71f))
* **YouTube - Hide layout components:** Fix certain description components not working ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([1bf64eb](1bf64eb8b0))
* **YouTube - Hide layout components:** Fix empty space issues (subscribed channels bar, show more button, landscape mode) ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([22ef700](22ef7002e0))
* **YouTube - Hide layout components:** Fix side effect of Disable translucent status bar ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([5760c58](5760c5860a))
* **YouTube - Hide layout components:** Resolve "Hide community posts" not working in search results ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([3153222](315322220d))
* **YouTube - Hide layout components:** Resolve community posts sometimes showing in player suggestions ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([828df77](828df77810))
* **YouTube - Hide Shorts components:** Action buttons not hidden in 20.22+ ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([a90a0b1](a90a0b1199))
* **YouTube - Hide Shorts components:** Do not hide channel page headers when hiding shorts ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([1246e43](1246e430f2))
* **YouTube - Hide Shorts components:** Fix sound metadata label hiding other components ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([49d1f65](49d1f65fca))
* **YouTube - Hide Shorts components:** Hide new type of sound metadata label ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([a6b8d2f](a6b8d2f103))
* **YouTube - Hide Shorts components:** Resolve hiding Shorts not working ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([ae69bdc](ae69bdc1d3))
* **YouTube - Loop video:** Enable loop video not working in playlist ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([06dbf7e](06dbf7ee80))
* **YouTube - Loop video:** Fix looping button state ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([14d0135](14d0135b3c))
* **YouTube - Loop video:** Wrong icon applied ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([b34adf6](b34adf6437))
* **YouTube - Open Shorts in regular player:** Fix back behavior with 20.51 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([46ec3d3](46ec3d3bdd))
* **YouTube - Open Shorts in regular player:** Resolve back button closing app instead of exiting fullscreen ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([b787c46](b787c469fd))
* **YouTube - Remove background playback restrictions:** Fix background playback not working with certain offline videos ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([2d098f2](2d098f2352))
* **YouTube - Remove viewer discretion dialog:** Not working on 20.14.43+ ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([64c397e](64c397eb1c))
* **YouTube - Return YouTube Dislike:** Fix incorrect dislike counts after cancel ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([ad10d76](ad10d76035))
* **YouTube - ReturnYouTubeDislike:** Fix dislikes not showing with 20.31+ ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([2033883](2033883294))
* **YouTube - SponsorBlock:** Do not show context toast when auto skipping in feed ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([88157ac](88157ac5b7))
* **YouTube - SponsorBlock:** Resolve segments not fetching on experimental app targets ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([2067799](206779942d))
* **YouTube - SponsorBlock:** Show correct nested skip segment when seeking ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f5ef68b](f5ef68b61a))
* **YouTube Music - Navigation bar:** Hide library tab with 8.24+ ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([cfcae43](cfcae43465))
* **YouTube:** Change recommended version to 20.37.48 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([3dd305c](3dd305ca5d))
* **YouTube:** Changes the default values for some settings ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([dce204b](dce204b41b))
* **YouTube:** Do not show bold icons if old settings menus is enabled ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([30bd852](30bd852ba5))
* **YouTube:** Fix patching unsupported 20.13.41 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([ed45375](ed45375105))
* **YouTube:** Ignore cairo flag in debug flag manager ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([093497c](093497c34f))
* **YouTube:** Remove 19.43.41 that YouTube no longer supports ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([a8526dc](a8526dc8ae))

### Features

* Add overlay buttons animation ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f6fc6aa](f6fc6aa5ac))
* **Custom branding:** Default to user-provided icon and name when provided ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f19c35e](f19c35e21c))
* **Enable debugging:** Allow overriding String/long/double flags in debug flag manager ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([1f91bc8](1f91bc8a20))
* Handle multiple branch conditionals jumping to the same instruction index ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([2f7b57d](2f7b57d071))
* Perform full search of free registers ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([01ef43a](01ef43abab))
* Update YouTube & YouTube Music patches ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([88d33b8](88d33b847d))
* Use more informative patch error if the same APK is patched twice ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([26e5ce1](26e5ce1a32))
* **YouTube - Disable haptic feedback:** Add Disable tap and hold haptics setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f135122](f135122df1))
* **YouTube - Hide ads:** Add Hide player popup ads setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([487a95d](487a95d3ef))
* **YouTube - Hide layout components:** Add "Hide channel tab filter" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([0adcd8c](0adcd8c62e))
* **YouTube - Hide layout components:** Add "Hide collapse button" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([1554fd9](1554fd916d))
* **YouTube - Hide layout components:** Add "Hide comments section in Home feed" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([5278434](5278434534))
* **YouTube - Hide layout components:** Add "Hide course progress" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([1927564](192756443a))
* **YouTube - Hide layout components:** Add "Hide explore this course" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([3e24762](3e24762c18))
* **YouTube - Hide layout components:** Add "Hide featured links", "Hide featured videos", "Hide join button", and "Hide subscribe button" options ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f9e843d](f9e843d756))
* **YouTube - Hide layout components:** Add "Hide feed flyout menu filter" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([a93de46](a93de46572))
* **YouTube - Hide layout components:** Add "Hide fullscreen button" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([b07b160](b07b1609e4))
* **YouTube - Hide layout components:** Add "Hide latest videos button" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([ebfdd8d](ebfdd8df2c))
* **YouTube - Hide layout components:** Add "Hide live chat replay button" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([a6bd311](a6bd3116f9))
* **YouTube - Hide layout components:** Add "Hide quizzes" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([70b9e10](70b9e103ae))
* **YouTube - Hide layout components:** Add "Hide search box trending results" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([21bf455](21bf455c3f))
* **YouTube - Hide layout components:** Add "Hide subscribed channels bar" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([e41a40f](e41a40f0d7))
* **YouTube - Hide layout components:** Add "Hide video title" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([2cfbe08](2cfbe08b21))
* **YouTube - Hide layout components:** Apply hide search suggestions only to more recent app targets ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([a43c0e1](a43c0e111b))
* **YouTube - Hide layout components:** Replace "Hide search suggestions" with "Hide You may like section" ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([80f6b01](80f6b01c64))
* **YouTube - Hide Shorts components:** Add "Hide AI button" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([99aace4](99aace4178))
* **YouTube - Hide Shorts components:** Add "Hide in video description" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([e0a8b7b](e0a8b7bc59))
* **YouTube - Navigation bar:** Add settings to hide toolbar buttons ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([d72e39f](d72e39f2a8))
* **YouTube - Navigation buttons:** Add setting to use narrow navigation bar buttons ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([e48a5d7](e48a5d76f7))
* **YouTube - SponsorBlock:** Show skip button if player overlay controls are active ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([35ec655](35ec655f83))
* **YouTube - Theme:** Add "Hide splash screen" setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([ca6e184](ca6e184172))
* **YouTube - Video quality:** Add Hide Premium video quality setting ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([50a2b67](50a2b67ef6))
* **YouTube Music:** Add experimental support for 9.02.50 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([50a102d](50a102d8af))
* **YouTube Music:** Add experimental support for 9.03.52 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([d5b9c0c](d5b9c0c03d))
* **YouTube Music:** Change recommended version to 8.37.56 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([d1e7900](d1e7900793))
* **YouTube Music:** Support version 8.40.54 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([62f130c](62f130cc88))
* **YouTube Music:** Unofficial support of 8.50.51 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([c1d7cae](c1d7caeee2))
* **YouTube:** Add experimental support for 21.02.32 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([7904b60](7904b60dbe))
* **YouTube:** Add experimental support for 21.03.34 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([1ae36a1](1ae36a1cc7))
* **YouTube:** Add experimental support for 21.04.221 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([66e113a](66e113a966))
* **YouTube:** Add experimental support for 21.05.264 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([f646c82](f646c820d7))
* **YouTube:** Add experimental support for 21.06.251 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([44b17d4](44b17d4758))
* **YouTube:** Add experimental support for 21.06.257 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([abb703d](abb703dcb2))
* **YouTube:** Add experimental support for 21.07.240 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([79b0c1f](79b0c1f72f))
* **YouTube:** Add Hide autoplay preview patch ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([79e3955](79e3955fde))
* **YouTube:** Add more double tap to seek length options ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([fb04071](fb04071528))
* **YouTube:** Remove obsolete seekbar thumbnail patch ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([9909fc1](9909fc1e5d))
* **YouTube:** Support version 20.40.45 ([#6571](https://github.com/ReVanced/revanced-patches/issues/6571)) ([96c85d0](96c85d0371))
2026-02-27 16:58:21 +00:00
oSumAtrIX
4c484d90eb
build: Update ReVanced Patches Gradle plugin to fix publication 2026-02-27 17:52:01 +01:00
oSumAtrIX
79b0c1f72f
feat(YouTube): Add experimental support for 21.07.240 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:19:05 +01:00
oSumAtrIX
abb703dcb2
feat(YouTube): Add experimental support for 21.06.257 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:19:04 +01:00
oSumAtrIX
44b17d4758
feat(YouTube): Add experimental support for 21.06.251 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:19:04 +01:00
oSumAtrIX
f646c820d7
feat(YouTube): Add experimental support for 21.05.264 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:19:03 +01:00
oSumAtrIX
66e113a966
feat(YouTube): Add experimental support for 21.04.221 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:19:03 +01:00
oSumAtrIX
1ae36a1cc7
feat(YouTube): Add experimental support for 21.03.34 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:19:02 +01:00
oSumAtrIX
7904b60dbe
feat(YouTube): Add experimental support for 21.02.32 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:19:02 +01:00
oSumAtrIX
96c85d0371
feat(YouTube): Support version 20.40.45 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:19:01 +01:00
oSumAtrIX
79e3955fde
feat(YouTube): Add Hide autoplay preview patch (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:19:01 +01:00
oSumAtrIX
fb04071528
feat(YouTube): Add more double tap to seek length options (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:19:00 +01:00
oSumAtrIX
9909fc1e5d
feat(YouTube): Remove obsolete seekbar thumbnail patch (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:19:00 +01:00
oSumAtrIX
62f130cc88
feat(YouTube Music): Support version 8.40.54 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:19:00 +01:00
oSumAtrIX
d5b9c0c03d
feat(YouTube Music): Add experimental support for 9.03.52 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:59 +01:00
oSumAtrIX
50a102d8af
feat(YouTube Music): Add experimental support for 9.02.50 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:59 +01:00
oSumAtrIX
c1d7caeee2
feat(YouTube Music): Unofficial support of 8.50.51 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:58 +01:00
oSumAtrIX
d1e7900793
feat(YouTube Music): Change recommended version to 8.37.56 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:58 +01:00
oSumAtrIX
487a95d3ef
feat(YouTube - Hide ads): Add Hide player popup ads setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:57 +01:00
oSumAtrIX
0adcd8c62e
feat(YouTube - Hide layout components): Add "Hide channel tab filter" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:57 +01:00
oSumAtrIX
a93de46572
feat(YouTube - Hide layout components): Add "Hide feed flyout menu filter" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:57 +01:00
oSumAtrIX
1554fd916d
feat(YouTube - Hide layout components): Add "Hide collapse button" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:56 +01:00
oSumAtrIX
b07b1609e4
feat(YouTube - Hide layout components): Add "Hide fullscreen button" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:56 +01:00
oSumAtrIX
70b9e103ae
feat(YouTube - Hide layout components): Add "Hide quizzes" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:55 +01:00
oSumAtrIX
3e24762c18
feat(YouTube - Hide layout components): Add "Hide explore this course" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:55 +01:00
oSumAtrIX
5278434534
feat(YouTube - Hide layout components): Add "Hide comments section in Home feed" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:54 +01:00
oSumAtrIX
192756443a
feat(YouTube - Hide layout components): Add "Hide course progress" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:54 +01:00
oSumAtrIX
a6bd3116f9
feat(YouTube - Hide layout components): Add "Hide live chat replay button" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:53 +01:00
oSumAtrIX
ebfdd8df2c
feat(YouTube - Hide layout components): Add "Hide latest videos button" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:53 +01:00
oSumAtrIX
2cfbe08b21
feat(YouTube - Hide layout components): Add "Hide video title" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:52 +01:00
oSumAtrIX
f9e843d756
feat(YouTube - Hide layout components): Add "Hide featured links", "Hide featured videos", "Hide join button", and "Hide subscribe button" options (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:52 +01:00
oSumAtrIX
e41a40f0d7
feat(YouTube - Hide layout components): Add "Hide subscribed channels bar" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:51 +01:00
oSumAtrIX
21bf455c3f
feat(YouTube - Hide layout components): Add "Hide search box trending results" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:51 +01:00
oSumAtrIX
a43c0e111b
feat(YouTube - Hide layout components): Apply hide search suggestions only to more recent app targets (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:50 +01:00
oSumAtrIX
80f6b01c64
feat(YouTube - Hide layout components): Replace "Hide search suggestions" with "Hide You may like section" (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:49 +01:00
oSumAtrIX
50a2b67ef6
feat(YouTube - Video quality): Add Hide Premium video quality setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:49 +01:00
oSumAtrIX
99aace4178
feat(YouTube - Hide Shorts components): Add "Hide AI button" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:48 +01:00
oSumAtrIX
e0a8b7bc59
feat(YouTube - Hide Shorts components): Add "Hide in video description" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:48 +01:00
oSumAtrIX
d72e39f2a8
feat(YouTube - Navigation bar): Add settings to hide toolbar buttons (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:48 +01:00
oSumAtrIX
e48a5d76f7
feat(YouTube - Navigation buttons): Add setting to use narrow navigation bar buttons (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:47 +01:00
oSumAtrIX
ca6e184172
feat(YouTube - Theme): Add "Hide splash screen" setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:47 +01:00
oSumAtrIX
35ec655f83
feat(YouTube - SponsorBlock): Show skip button if player overlay controls are active (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:46 +01:00
oSumAtrIX
f135122df1
feat(YouTube - Disable haptic feedback): Add Disable tap and hold haptics setting (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:46 +01:00
oSumAtrIX
f19c35e21c
feat(Custom branding): Default to user-provided icon and name when provided (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:46 +01:00
oSumAtrIX
26e5ce1a32
feat: Use more informative patch error if the same APK is patched twice (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:45 +01:00
oSumAtrIX
2f7b57d071
feat: Handle multiple branch conditionals jumping to the same instruction index (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:45 +01:00
oSumAtrIX
01ef43abab
feat: Perform full search of free registers (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:44 +01:00
oSumAtrIX
1f91bc8a20
feat(Enable debugging): Allow overriding String/long/double flags in debug flag manager (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:44 +01:00
oSumAtrIX
f6fc6aa5ac
feat: Add overlay buttons animation (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:43 +01:00
oSumAtrIX
ed45375105
fix(YouTube): Fix patching unsupported 20.13.41 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:43 +01:00
oSumAtrIX
30bd852ba5
fix(YouTube): Do not show bold icons if old settings menus is enabled (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:43 +01:00
oSumAtrIX
093497c34f
fix(YouTube): Ignore cairo flag in debug flag manager (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:42 +01:00
oSumAtrIX
3dd305ca5d
fix(YouTube): Change recommended version to 20.37.48 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:42 +01:00
oSumAtrIX
a8526dc8ae
fix(YouTube): Remove 19.43.41 that YouTube no longer supports (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:41 +01:00
oSumAtrIX
dce204b41b
fix(YouTube): Changes the default values for some settings (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:41 +01:00
oSumAtrIX
828df77810
fix(YouTube - Hide layout components): Resolve community posts sometimes showing in player suggestions (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:40 +01:00
oSumAtrIX
315322220d
fix(YouTube - Hide layout components): Resolve "Hide community posts" not working in search results (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:40 +01:00
oSumAtrIX
22ef7002e0
fix(YouTube - Hide layout components): Fix empty space issues (subscribed channels bar, show more button, landscape mode) (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:40 +01:00
oSumAtrIX
1bf64eb8b0
fix(YouTube - Hide layout components): Fix certain description components not working (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:39 +01:00
oSumAtrIX
5760c5860a
fix(YouTube - Hide layout components): Fix side effect of Disable translucent status bar (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:39 +01:00
oSumAtrIX
d639faf71f
fix(YouTube - Hide layout components): Ensure featured places also hide watch history shelf (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:38 +01:00
oSumAtrIX
9b12dd1065
fix(YouTube - Hide ads): Hide new type of general ad, movie ad and web search result (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:38 +01:00
oSumAtrIX
c97aefc272
fix(YouTube - Hide ads): Hide new type of player ad (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:37 +01:00
oSumAtrIX
8d274a7afc
fix(YouTube - Hide ads): Hide video ads does not hide Shorts ads (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:37 +01:00
oSumAtrIX
02b405e6ac
fix(YouTube - Hide ads): Support Hide fullscreen ads on Android 13+ devices (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:37 +01:00
oSumAtrIX
c1c2aa98b2
fix(YouTube - Hide ads): Empty space left when ads are hidden on tablets (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:36 +01:00
oSumAtrIX
d26e352850
fix(YouTube - Hide ads): Fix "Hide YouTube Premium promotions" hiding YouTube Doodles (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:36 +01:00
oSumAtrIX
5d45b6da74
fix(YouTube - Hide ads): YouTube Doodles unclickable when Hide ads is enabled (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:35 +01:00
oSumAtrIX
206779942d
fix(YouTube - SponsorBlock): Resolve segments not fetching on experimental app targets (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:35 +01:00
oSumAtrIX
f5ef68b61a
fix(YouTube - SponsorBlock): Show correct nested skip segment when seeking (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:35 +01:00
oSumAtrIX
88157ac5b7
fix(YouTube - SponsorBlock): Do not show context toast when auto skipping in feed (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:34 +01:00
oSumAtrIX
14d0135b3c
fix(YouTube - Loop video): Fix looping button state (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:34 +01:00
oSumAtrIX
06dbf7ee80
fix(YouTube - Loop video): Enable loop video not working in playlist (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:33 +01:00
oSumAtrIX
b34adf6437
fix(YouTube - Loop video): Wrong icon applied (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:33 +01:00
oSumAtrIX
b787c469fd
fix(YouTube - Open Shorts in regular player): Resolve back button closing app instead of exiting fullscreen (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:33 +01:00
oSumAtrIX
46ec3d3bdd
fix(YouTube - Open Shorts in regular player): Fix back behavior with 20.51 (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:32 +01:00
oSumAtrIX
1246e430f2
fix(YouTube - Hide Shorts components): Do not hide channel page headers when hiding shorts (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:32 +01:00
oSumAtrIX
49d1f65fca
fix(YouTube - Hide Shorts components): Fix sound metadata label hiding other components (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:31 +01:00
oSumAtrIX
a6b8d2f103
fix(YouTube - Hide Shorts components): Hide new type of sound metadata label (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:31 +01:00
oSumAtrIX
a90a0b1199
fix(YouTube - Hide Shorts components): Action buttons not hidden in 20.22+ (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:30 +01:00
oSumAtrIX
ae69bdc1d3
fix(YouTube - Hide Shorts components): Resolve hiding Shorts not working (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:30 +01:00
oSumAtrIX
3ff303f045
fix(YouTube - Hide end screen cards): Resolve patching 20.31.4x (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:30 +01:00
oSumAtrIX
2d098f2352
fix(YouTube - Remove background playback restrictions): Fix background playback not working with certain offline videos (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:29 +01:00
oSumAtrIX
3e00a99c1b
fix(Custom branding): Fix defaults (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:29 +01:00
oSumAtrIX
6aba2d1274
fix(Custom branding): Resolve background playback crash with custom branded root installation (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:29 +01:00
oSumAtrIX
2033883294
fix(YouTube - ReturnYouTubeDislike): Fix dislikes not showing with 20.31+ (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:28 +01:00
oSumAtrIX
ad10d76035
fix(YouTube - Return YouTube Dislike): Fix incorrect dislike counts after cancel (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:28 +01:00
oSumAtrIX
64c397eb1c
fix(YouTube - Remove viewer discretion dialog): Not working on 20.14.43+ (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:28 +01:00
oSumAtrIX
88724d47b1
fix(YouTube - Exit fullscreen mode): Handle exiting fullscreen on first opened video (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:27 +01:00
oSumAtrIX
cfcae43465
fix(YouTube Music - Navigation bar): Hide library tab with 8.24+ (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:27 +01:00
oSumAtrIX
f59323c87d
fix(Hex patch): Fix bug in implementation of Boyer-Moore algorithm (#6571)
This commit is empty because its changes are squashed into commit 88d33b847d instead, also containing relevant attribution notices.
2026-02-27 16:18:27 +01:00
oSumAtrIX
88d33b847d
feat: Update YouTube & YouTube Music patches (#6571)
This commit is a squash of multiple commits, authored by the individuals referenced below. To see the exact commits by each author, see the unsquashed tree at https://github.com/ReVanced/revanced-patches/pull/6571 or with commit 03940665d27a42ed08992757dfe4534bd8243356.

Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
Co-authored-by: hoodles <207470673+hoo-dles@users.noreply.github.com>
Co-authored-by: ILoveOpenSourceApplications <117499019+iloveopensourceapplications@users.noreply.github.com>
Co-authored-by: LisoUseInAIKyrios <118716522+lisouseinaikyrios@users.noreply.github.com>
Co-authored-by: inotia00 <108592928+inotia00@users.noreply.github.com>
Co-authored-by: OxrxL <108184954+oxrxl@users.noreply.github.com>
2026-02-27 16:16:21 +01:00
semantic-release-bot
db5e0fe587 chore: Release v6.0.0-dev.1 [skip ci]
# [6.0.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.51.0-dev.2...v6.0.0-dev.1) (2026-02-27)

* build(Needs bump)!: Update to ReVanced Patcher v22  ([#6542](https://github.com/ReVanced/revanced-patches/issues/6542)) ([ab2ac36](ab2ac36e30))

### BREAKING CHANGES

* Deprecated APIs have been removed, and various APIs now use the updated ReVanced Patcher v22 APIs.
2026-02-27 01:43:27 +00:00
oSumAtrIX
ab2ac36e30
build(Needs bump)!: Update to ReVanced Patcher v22 (#6542)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Co-authored-by: Pun Butrach <pun.butrach@gmail.com>
Co-authored-by: Ushie <ushiekane@gmail.com>
Co-authored-by: ILoveOpenSourceApplications <ILoveOpenSourceApplications@users.noreply.github.com>
Co-authored-by: rospino74 <34315725+rospino74@users.noreply.github.com>
Co-authored-by: drobotk <pawwwll@gmail.com>
Co-authored-by: Sayanth <13906889+SayanthD@users.noreply.github.com>
Co-authored-by: kitadai31 <90122968+kitadai31@users.noreply.github.com>

BREAKING CHANGE: Deprecated APIs have been removed, and various APIs now use the updated ReVanced Patcher v22 APIs.
2026-02-27 02:39:17 +01:00
semantic-release-bot
376f2af8d8 chore: Release v5.51.0-dev.2 [skip ci]
# [5.51.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.51.0-dev.1...v5.51.0-dev.2) (2026-02-26)

### Features

* **GMX Mail:** Add `Hide ads` and `Hide Premium upgrade button` patches ([#6583](https://github.com/ReVanced/revanced-patches/issues/6583)) ([2976ea3](2976ea3ddd))
2026-02-26 23:06:44 +00:00
obXfuse
2976ea3ddd
feat(GMX Mail): Add Hide ads and Hide Premium upgrade button patches (#6583)
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-02-27 00:03:55 +01:00
semantic-release-bot
8a84f1a516 chore: Release v5.51.0-dev.1 [skip ci]
# [5.51.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.50.3-dev.4...v5.51.0-dev.1) (2026-02-26)

### Features

* **GMX Mail:** Add `Force enable Freephone` patch ([#6650](https://github.com/ReVanced/revanced-patches/issues/6650)) ([997b5d6](997b5d63d1))
2026-02-26 22:13:53 +00:00
obXfuse
997b5d63d1
feat(GMX Mail): Add Force enable Freephone patch (#6650)
Co-authored-by: obXfuse <obXfuse>
2026-02-26 23:10:35 +01:00
semantic-release-bot
2f72ae5bf6 chore: Release v5.50.3-dev.4 [skip ci]
## [5.50.3-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.50.3-dev.3...v5.50.3-dev.4) (2026-02-23)

### Bug Fixes

* **GmsCore support:** Insert check after another missing necessary context hook ([3c0c5a8](3c0c5a86d8))
2026-02-23 22:32:31 +00:00
oSumAtrIX
3c0c5a86d8
fix(GmsCore support): Insert check after another missing necessary context hook 2026-02-23 23:29:29 +01:00
semantic-release-bot
2bd3778459 chore: Release v5.50.3-dev.3 [skip ci]
## [5.50.3-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.50.3-dev.2...v5.50.3-dev.3) (2026-02-20)

### Bug Fixes

* **GmsCore support:** Insert check after necessary context hook ([03e8e3d](03e8e3d75c))
2026-02-20 21:04:13 +00:00
oSumAtrIX
03e8e3d75c
fix(GmsCore support): Insert check after necessary context hook 2026-02-20 22:01:14 +01:00
semantic-release-bot
784bcdace4 chore: Release v5.50.3-dev.2 [skip ci]
## [5.50.3-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.50.3-dev.1...v5.50.3-dev.2) (2026-02-16)

### Bug Fixes

* **GmsCore support:** Handle GmsCore flavors when checking for updates ([2aa19f5](2aa19f5995))
* Use positional substitutes in strings where multiple are present ([aa8c87f](aa8c87f865))
2026-02-16 18:05:22 +00:00
oSumAtrIX
aa8c87f865
fix: Use positional substitutes in strings where multiple are present 2026-02-16 19:01:26 +01:00
oSumAtrIX
2aa19f5995
fix(GmsCore support): Handle GmsCore flavors when checking for updates 2026-02-16 19:01:25 +01:00
semantic-release-bot
9f3a16005a chore: Release v5.50.3-dev.1 [skip ci]
## [5.50.3-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.50.2...v5.50.3-dev.1) (2026-02-16)

### Bug Fixes

* **GmsCore support:** Rename MicroG GmsCore specific strings as well and rename app specific strings correctly ([c2ac1f0](c2ac1f04a0))
2026-02-16 01:50:41 +00:00
oSumAtrIX
131ee4f707
ci: Fix string processing command 2026-02-16 02:09:00 +01:00
oSumAtrIX
c2ac1f04a0
fix(GmsCore support): Rename MicroG GmsCore specific strings as well and rename app specific strings correctly 2026-02-16 02:08:19 +01:00
oSumAtrIX
450454019d
chore: Process strings from Crowdin correctly 2026-02-16 01:52:59 +01:00
semantic-release-bot
6b06b9d132 chore: Release v5.50.2 [skip ci]
## [5.50.2](https://github.com/ReVanced/revanced-patches/compare/v5.50.1...v5.50.2) (2026-02-15)

### Bug Fixes

* Add missing patch option descriptions ([16e42a7](16e42a75ec))
2026-02-15 22:54:54 +00:00
oSumAtrIX
cb143b13f7
chore: Merge branch dev to main (#6588) 2026-02-15 23:52:27 +01:00
oSumAtrIX
16e42a75ec
fix: Add missing patch option descriptions 2026-02-15 23:51:33 +01:00
semantic-release-bot
4f5b93d71a chore: Release v5.50.1 [skip ci]
## [5.50.1](https://github.com/ReVanced/revanced-patches/compare/v5.50.0...v5.50.1) (2026-02-15)

### Bug Fixes

* Fix broken release by bumping to v5.50.1 ([d416609](d416609257))
2026-02-15 19:38:46 +00:00
oSumAtrIX
bb45805b40
chore: Merge branch dev to main (#6585) 2026-02-15 20:34:12 +01:00
semantic-release-bot
55fc1b04e1 chore: Release v5.50.1-dev.1 [skip ci]
## [5.50.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.50.0...v5.50.1-dev.1) (2026-02-15)

### Bug Fixes

* Fix broken release by bumping to v5.50.1 ([d416609](d416609257))
2026-02-15 19:32:28 +00:00
oSumAtrIX
d416609257
fix: Fix broken release by bumping to v5.50.1 2026-02-15 20:28:31 +01:00
semantic-release-bot
413b4312ff chore: Release v5.49.0 [skip ci]
# [5.49.0](https://github.com/ReVanced/revanced-patches/compare/v5.48.0...v5.49.0) (2026-02-15)

### Bug Fixes

* Disable `Prevent screenshot detection` by default ([#6511](https://github.com/ReVanced/revanced-patches/issues/6511)) ([5b5c502](5b5c50254d))
* **Instagram - Open links externally:** Fix patch by handling >4-bit register ([#6538](https://github.com/ReVanced/revanced-patches/issues/6538)) ([f681a6f](f681a6ffd4))
* **Instagram:** Make `Change link sharing domain` and `Sanitize sharing links` work with latest versions again ([#6518](https://github.com/ReVanced/revanced-patches/issues/6518)) ([85a9079](85a9079c25))
* **Letterboxd - Hide ads:** Fix patch by returning the correct return type ([#6527](https://github.com/ReVanced/revanced-patches/issues/6527)) ([80c34b9](80c34b9d74))
* Process strings from Crowdin to strip the app/patch prefixes again ([e566efc](e566efc51f))
* **Strava:** Fix `Add media download` patch ([#6526](https://github.com/ReVanced/revanced-patches/issues/6526)) ([dc9e68b](dc9e68ba57))

### Features

* **FotMob:** Add `Hide ads` patch ([#6566](https://github.com/ReVanced/revanced-patches/issues/6566)) ([4b0b737](4b0b7374f2))
* **GmsCore support:** Reduce amount of necessary changes and add update check ([#6582](https://github.com/ReVanced/revanced-patches/issues/6582)) ([650e6a2](650e6a2710))
* **Instagram:** Add `Disable analytics` patch ([#6531](https://github.com/ReVanced/revanced-patches/issues/6531)) ([ad92864](ad92864483))
* **Kleinanzeigen:** Add `Hide ads` patch ([#6533](https://github.com/ReVanced/revanced-patches/issues/6533)) ([bd6e544](bd6e544007))
* **Kleinanzeigen:** Add `Hide PUR` patch  ([#6558](https://github.com/ReVanced/revanced-patches/issues/6558)) ([4958ecf](4958ecf10c))
* **Microsoft Lens:** Remove migration to OneDrive ([#6551](https://github.com/ReVanced/revanced-patches/issues/6551)) ([e389632](e389632afd))
* **Nothing X:** Add `Show K1 token(s)` patch ([#6490](https://github.com/ReVanced/revanced-patches/issues/6490)) ([421cb28](421cb2899e))
* **Strava:** Add `Hide distractions` patch ([#6479](https://github.com/ReVanced/revanced-patches/issues/6479)) ([66b0852](66b0852f8f))
* **YouTube Music:** Add `Hide layout components` patch ([#6365](https://github.com/ReVanced/revanced-patches/issues/6365)) ([71ce823](71ce8230a9))
* **YouTube Music:** Add `Unlock Android Auto Media Browser` patch ([#6477](https://github.com/ReVanced/revanced-patches/issues/6477)) ([5edd9dc](5edd9dccae))
2026-02-15 18:49:09 +00:00
oSumAtrIX
86328331c4
chore: Merge branch dev to main (#6512) 2026-02-15 19:45:32 +01:00
semantic-release-bot
8b6ff851a4 chore: Release v5.50.0-dev.8 [skip ci]
# [5.50.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.50.0-dev.7...v5.50.0-dev.8) (2026-02-15)

### Features

* **GmsCore support:** Reduce amount of necessary changes and add update check ([#6582](https://github.com/ReVanced/revanced-patches/issues/6582)) ([650e6a2](650e6a2710))
2026-02-15 18:45:16 +00:00
github-actions[bot]
161a89a056
chore: Sync translations (#6517)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-02-15 19:40:56 +01:00
oSumAtrIX
650e6a2710
feat(GmsCore support): Reduce amount of necessary changes and add update check (#6582) 2026-02-15 19:37:38 +01:00
Tobias
6f70167369
ci: Add input to choose PR when dispatching Build pull request workflow (#6572) 2026-02-15 19:26:16 +01:00
semantic-release-bot
652b904a71 chore: Release v5.50.0-dev.7 [skip ci]
# [5.50.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.50.0-dev.6...v5.50.0-dev.7) (2026-02-12)

### Bug Fixes

* **Instagram:** Make `Change link sharing domain` and `Sanitize sharing links` work with latest versions again ([#6518](https://github.com/ReVanced/revanced-patches/issues/6518)) ([85a9079](85a9079c25))

### Features

* **Instagram:** Add `Disable analytics` patch ([#6531](https://github.com/ReVanced/revanced-patches/issues/6531)) ([ad92864](ad92864483))
* **Kleinanzeigen:** Add `Hide PUR` patch  ([#6558](https://github.com/ReVanced/revanced-patches/issues/6558)) ([4958ecf](4958ecf10c))
* **Microsoft Lens:** Remove migration to OneDrive ([#6551](https://github.com/ReVanced/revanced-patches/issues/6551)) ([e389632](e389632afd))
2026-02-12 20:53:16 +00:00
Johannes Obermeier
4958ecf10c
feat(Kleinanzeigen): Add Hide PUR patch (#6558) 2026-02-12 21:49:26 +01:00
Jamie
e389632afd
feat(Microsoft Lens): Remove migration to OneDrive (#6551)
Co-authored-by: Jamie Stumme <3059647+StummeJ@users.noreply.github.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-02-12 21:48:45 +01:00
Swakshan
ad92864483
feat(Instagram): Add Disable analytics patch (#6531)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-02-12 21:48:22 +01:00
Swakshan
85a9079c25
fix(Instagram): Make Change link sharing domain and Sanitize sharing links work with latest versions again (#6518) 2026-02-12 21:48:09 +01:00
semantic-release-bot
95c2d5fd6c chore: Release v5.50.0-dev.6 [skip ci]
# [5.50.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.50.0-dev.5...v5.50.0-dev.6) (2026-02-06)

### Features

* **FotMob:** Add `Hide ads` patch ([#6566](https://github.com/ReVanced/revanced-patches/issues/6566)) ([4b0b737](4b0b7374f2))
2026-02-06 19:57:17 +00:00
Sayanth
4b0b7374f2
feat(FotMob): Add Hide ads patch (#6566) 2026-02-06 20:51:43 +01:00
semantic-release-bot
d17a1ba9d7 chore: Release v5.50.0-dev.5 [skip ci]
# [5.50.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.50.0-dev.4...v5.50.0-dev.5) (2026-02-01)

### Bug Fixes

* Process strings from Crowdin to strip the app/patch prefixes again ([e566efc](e566efc51f))
2026-02-01 21:03:45 +00:00
oSumAtrIX
e566efc51f
fix: Process strings from Crowdin to strip the app/patch prefixes again 2026-02-01 21:59:18 +01:00
semantic-release-bot
2c0e81ee17 chore: Release v5.50.0-dev.4 [skip ci]
# [5.50.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.50.0-dev.3...v5.50.0-dev.4) (2026-01-27)

### Bug Fixes

* **Instagram - Open links externally:** Fix patch by handling >4-bit register ([#6538](https://github.com/ReVanced/revanced-patches/issues/6538)) ([f681a6f](f681a6ffd4))
2026-01-27 18:47:27 +00:00
xehpuk
f681a6ffd4
fix(Instagram - Open links externally): Fix patch by handling >4-bit register (#6538) 2026-01-27 19:42:25 +01:00
semantic-release-bot
59f9e4328f chore: Release v5.50.0-dev.3 [skip ci]
# [5.50.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.50.0-dev.2...v5.50.0-dev.3) (2026-01-26)

### Features

* **Kleinanzeigen:** Add `Hide ads` patch ([#6533](https://github.com/ReVanced/revanced-patches/issues/6533)) ([bd6e544](bd6e544007))
2026-01-26 14:24:11 +00:00
xehpuk
bd6e544007
feat(Kleinanzeigen): Add Hide ads patch (#6533)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-01-26 15:20:59 +01:00
semantic-release-bot
dbdd2a67ff chore: Release v5.50.0-dev.2 [skip ci]
# [5.50.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.50.0-dev.1...v5.50.0-dev.2) (2026-01-25)

### Bug Fixes

* **Letterboxd - Hide ads:** Fix patch by returning the correct return type ([#6527](https://github.com/ReVanced/revanced-patches/issues/6527)) ([80c34b9](80c34b9d74))
2026-01-25 10:08:33 +00:00
xehpuk
80c34b9d74
fix(Letterboxd - Hide ads): Fix patch by returning the correct return type (#6527) 2026-01-25 11:03:06 +01:00
semantic-release-bot
debf297d9e chore: Release v5.50.0-dev.1 [skip ci]
# [5.50.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.49.0-dev.1...v5.50.0-dev.1) (2026-01-25)

### Bug Fixes

* **Strava:** Fix `Add media download` patch ([#6526](https://github.com/ReVanced/revanced-patches/issues/6526)) ([dc9e68b](dc9e68ba57))

### Features

* **Nothing X:** Add `Show K1 token(s)` patch ([#6490](https://github.com/ReVanced/revanced-patches/issues/6490)) ([421cb28](421cb2899e))
* **Strava:** Add `Hide distractions` patch ([#6479](https://github.com/ReVanced/revanced-patches/issues/6479)) ([66b0852](66b0852f8f))
* **YouTube Music:** Add `Unlock Android Auto Media Browser` patch ([#6477](https://github.com/ReVanced/revanced-patches/issues/6477)) ([5edd9dc](5edd9dccae))
2026-01-25 00:53:06 +00:00
xehpuk
dc9e68ba57
fix(Strava): Fix Add media download patch (#6526) 2026-01-25 01:49:33 +01:00
semantic-release-bot
ebea32fe87 chore: Release v5.50.0-dev.1 [skip ci]
# [5.50.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.49.0-dev.1...v5.50.0-dev.1) (2026-01-22)

### Features

* **Nothing X:** Add `Show K1 token(s)` patch ([#6490](https://github.com/ReVanced/revanced-patches/issues/6490)) ([421cb28](421cb2899e))
* **Strava:** Add `Hide distractions` patch ([#6479](https://github.com/ReVanced/revanced-patches/issues/6479)) ([66b0852](66b0852f8f))
* **YouTube Music:** Add `Unlock Android Auto Media Browser` patch ([#6477](https://github.com/ReVanced/revanced-patches/issues/6477)) ([5edd9dc](5edd9dccae))
2026-01-22 19:21:45 +00:00
xehpuk
66b0852f8f
feat(Strava): Add Hide distractions patch (#6479)
Co-authored-by: Pun Butrach <pun.butrach@gmail.com>
Co-authored-by: ekaunt <62402760+ekaunt@users.noreply.github.com>
Co-authored-by: bengross <bengross@vecta.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-01-22 19:56:27 +01:00
Pa1NarK
421cb2899e
feat(Nothing X): Add Show K1 token(s) patch (#6490)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-01-22 19:17:45 +01:00
semantic-release-bot
97e74157fa
chore: Release v5.50.0-dev.1 [skip ci]
# [5.50.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.48.0...v5.50.0-dev.1) (2026-01-22)

### Features

* **YouTube Music:** Add `Unlock Android Auto Media Browser` patch ([#6477](https://github.com/ReVanced/revanced-patches/issues/6477)) ([89645dc](89645dcc2e))
2026-01-22 19:10:39 +01:00
Johannes Obermeier
5edd9dccae
feat(YouTube Music): Add Unlock Android Auto Media Browser patch (#6477)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
(cherry picked from commit 89645dcc2e13603b8f2fedb5e16231cb396e5965)
2026-01-22 19:04:09 +01:00
semantic-release-bot
9c18e1e649 chore: Release v5.49.0-dev.1 [skip ci]
# [5.49.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.48.1-dev.1...v5.49.0-dev.1) (2026-01-22)

### Features

* **YouTube Music:** Add `Hide layout components` patch ([#6365](https://github.com/ReVanced/revanced-patches/issues/6365)) ([71ce823](71ce8230a9))
2026-01-22 17:43:08 +00:00
rospino74
71ce8230a9
feat(YouTube Music): Add Hide layout components patch (#6365)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-01-22 18:36:37 +01:00
github-actions[bot]
156441d3cf
chore: Sync translations (#6516)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-01-22 18:21:28 +01:00
oSumAtrIX
634f47ef84
ci: Set necessary env vars for running Gradle task 2026-01-22 17:37:44 +01:00
oSumAtrIX
eeb133325e
ci: Properly implement Crowdin strings processing 2026-01-22 17:37:44 +01:00
semantic-release-bot
e8d58ca9af chore: Release v5.48.1-dev.1 [skip ci]
## [5.48.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.48.0...v5.48.1-dev.1) (2026-01-21)

### Bug Fixes

* Disable `Prevent screenshot detection` by default ([#6511](https://github.com/ReVanced/revanced-patches/issues/6511)) ([5b5c502](5b5c50254d))
2026-01-21 17:49:31 +00:00
Sayanth
5b5c50254d
fix: Disable Prevent screenshot detection by default (#6511) 2026-01-21 18:44:04 +01:00
semantic-release-bot
ef052c0d8f chore: Release v5.48.0 [skip ci]
# [5.48.0](https://github.com/ReVanced/revanced-patches/compare/v5.47.0...v5.48.0) (2026-01-19)

### Bug Fixes

* **Boost for Reddit - Fix missing audio in video downloads:** Make it work again by reflecting Reddits latest changes ([#6500](https://github.com/ReVanced/revanced-patches/issues/6500)) ([eecc44b](eecc44b956))
* **Disney+ - Skip ads:** Remove unsupported package names ([#6422](https://github.com/ReVanced/revanced-patches/issues/6422)) ([44e7dbc](44e7dbcf4d))
* Fix build error introduced in `4046bee` ([#6417](https://github.com/ReVanced/revanced-patches/issues/6417)) ([789f0a5](789f0a5628))
* Fix compilation error introduced in `6bb6281` ([#6409](https://github.com/ReVanced/revanced-patches/issues/6409)) ([71c6cb5](71c6cb569e))
* Fix compilation error introduced in dc69f243 ([#6392](https://github.com/ReVanced/revanced-patches/issues/6392)) ([a429824](a429824bb7))
* **Instagram:** `Sanitize sharing links` ([#6483](https://github.com/ReVanced/revanced-patches/issues/6483)) ([8724759](87247590de))
* **YouTube - Hide layout components:** Hide new type of crowdfunding box ([#6380](https://github.com/ReVanced/revanced-patches/issues/6380)) ([dc69f24](dc69f2433e))

### Features

* Add `Disable Sentry telemetry` patch ([#6416](https://github.com/ReVanced/revanced-patches/issues/6416)) ([4cc3159](4cc315952d))
* Add `Prevent screenshot detection` patch ([#6482](https://github.com/ReVanced/revanced-patches/issues/6482)) ([83c0127](83c0127ebb))
* Disable Play Integrity patch ([#6412](https://github.com/ReVanced/revanced-patches/issues/6412)) ([6312fe8](6312fe8d60))
* **Instagram - Hides navigation buttons:** Add more buttons to hide ([#6390](https://github.com/ReVanced/revanced-patches/issues/6390)) ([6bb6281](6bb6281149))
* **Instagram:** Add `Hide highlights tray` patch ([#6489](https://github.com/ReVanced/revanced-patches/issues/6489)) ([8725a49](8725a49ba3))
* **Instagram:** Add `Remove build expired popup` patch ([#6488](https://github.com/ReVanced/revanced-patches/issues/6488)) ([18c0b04](18c0b04f0c))
* **Instagram:** Disable `Disable Reels scrolling` by default ([3401467](3401467a6d))
* **Letterboxd:** Add `Unlock app icons` patch ([#6415](https://github.com/ReVanced/revanced-patches/issues/6415)) ([d25dcfe](d25dcfe49a))
* **ProtonVPN:** Add `Unlock split tunneling` patch ([#6353](https://github.com/ReVanced/revanced-patches/issues/6353)) ([e0f3346](e0f33468e6))
* **SBS On Demand:** Add `Remove ads` patch ([#6378](https://github.com/ReVanced/revanced-patches/issues/6378)) ([315931c](315931cbf8))
* **Strava:** Add `Add 'Give Kudos' button to 'Group Activity'` patch ([#6475](https://github.com/ReVanced/revanced-patches/issues/6475)) ([4c4ba1c](4c4ba1c78c))
* **Strava:** Add `Add media download` patch ([#6449](https://github.com/ReVanced/revanced-patches/issues/6449)) ([778d13c](778d13ce8b))
* **Strava:** Add `Block Snowplow tracking` patch ([#6413](https://github.com/ReVanced/revanced-patches/issues/6413)) ([c47beae](c47beae213))
* **Strava:** Add `Disable Quick Edit` patch ([#6452](https://github.com/ReVanced/revanced-patches/issues/6452)) ([f5cbb31](f5cbb31724))
* **Strava:** Add `Enable password login` patch ([#6396](https://github.com/ReVanced/revanced-patches/issues/6396)) ([8f3f4c9](8f3f4c95bb))
* **Strava:** Add `Overwrite media upload parameters` patch ([#6410](https://github.com/ReVanced/revanced-patches/issues/6410)) ([b42ae27](b42ae27ce6))
* **YouTube:** Add `Pause on audio interrupt` patch ([#6464](https://github.com/ReVanced/revanced-patches/issues/6464)) ([19f146c](19f146c01d))
2026-01-19 09:28:58 +00:00
oSumAtrIX
d9fa580222
chore: Merge branch dev to main (#6385) 2026-01-19 10:25:41 +01:00
semantic-release-bot
182224c79d chore: Release v5.48.0-dev.13 [skip ci]
# [5.48.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v5.48.0-dev.12...v5.48.0-dev.13) (2026-01-19)

### Features

* Add `Prevent screenshot detection` patch ([#6482](https://github.com/ReVanced/revanced-patches/issues/6482)) ([83c0127](83c0127ebb))
2026-01-19 09:21:21 +00:00
xehpuk
83c0127ebb
feat: Add Prevent screenshot detection patch (#6482)
Co-authored-by: Swakshan <56347042+Swakshan@users.noreply.github.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-01-19 10:16:30 +01:00
semantic-release-bot
3762f1de08 chore: Release v5.48.0-dev.12 [skip ci]
# [5.48.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v5.48.0-dev.11...v5.48.0-dev.12) (2026-01-19)

### Features

* **Instagram:** Add `Remove build expired popup` patch ([#6488](https://github.com/ReVanced/revanced-patches/issues/6488)) ([18c0b04](18c0b04f0c))
* **Strava:** Add `Add 'Give Kudos' button to 'Group Activity'` patch ([#6475](https://github.com/ReVanced/revanced-patches/issues/6475)) ([4c4ba1c](4c4ba1c78c))
2026-01-19 09:06:41 +00:00
Swakshan
18c0b04f0c
feat(Instagram): Add Remove build expired popup patch (#6488)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-01-19 10:01:42 +01:00
xehpuk
4c4ba1c78c
feat(Strava): Add Add 'Give Kudos' button to 'Group Activity' patch (#6475)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-01-19 10:00:25 +01:00
semantic-release-bot
7cef24a5e9 chore: Release v5.48.0-dev.11 [skip ci]
# [5.48.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v5.48.0-dev.10...v5.48.0-dev.11) (2026-01-19)

### Features

* **Instagram:** Add `Hide highlights tray` patch ([#6489](https://github.com/ReVanced/revanced-patches/issues/6489)) ([8725a49](8725a49ba3))
2026-01-19 08:56:06 +00:00
Swakshan
8725a49ba3
feat(Instagram): Add Hide highlights tray patch (#6489)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-01-19 09:52:36 +01:00
semantic-release-bot
8b6360e34f chore: Release v5.48.0-dev.10 [skip ci]
# [5.48.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v5.48.0-dev.9...v5.48.0-dev.10) (2026-01-19)

### Bug Fixes

* **Boost for Reddit - Fix missing audio in video downloads:** Make it work again by reflecting Reddits latest changes ([#6500](https://github.com/ReVanced/revanced-patches/issues/6500)) ([eecc44b](eecc44b956))
* **Instagram:** `Sanitize sharing links` ([#6483](https://github.com/ReVanced/revanced-patches/issues/6483)) ([8724759](87247590de))

### Features

* **Instagram:** Disable `Disable Reels scrolling` by default ([3401467](3401467a6d))
* **Strava:** Add `Add media download` patch ([#6449](https://github.com/ReVanced/revanced-patches/issues/6449)) ([778d13c](778d13ce8b))
* **YouTube:** Add `Pause on audio interrupt` patch ([#6464](https://github.com/ReVanced/revanced-patches/issues/6464)) ([19f146c](19f146c01d))
2026-01-19 08:40:58 +00:00
Pun Butrach
a10c51f160
ci: Include require environment variables in release step (#6493) 2026-01-19 09:38:25 +01:00
scruz
eecc44b956
fix(Boost for Reddit - Fix missing audio in video downloads): Make it work again by reflecting Reddits latest changes (#6500) 2026-01-18 16:21:59 +01:00
oSumAtrIX
3401467a6d
feat(Instagram): Disable Disable Reels scrolling by default 2026-01-15 23:30:17 +01:00
Swakshan
87247590de
fix(Instagram): Sanitize sharing links (#6483) 2026-01-13 20:10:25 +01:00
xehpuk
41e2590584
chore(Strava): Restructure media package (#6480) 2026-01-13 15:46:49 +01:00
xehpuk
778d13ce8b
feat(Strava): Add Add media download patch (#6449)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-01-12 23:28:15 +01:00
ekaunt
19f146c01d
feat(YouTube): Add Pause on audio interrupt patch (#6464)
Co-authored-by: bengross <bengross@vecta.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-01-12 23:18:09 +01:00
Pun Butrach
12b819d20e
ci: Schedule Crowdin to runs weekly instead of every 12 hours (#6466) 2026-01-12 02:40:19 +01:00
Pun Butrach
004b5908db
build: Use Gradle credentials system (#6467) 2026-01-11 16:59:48 +01:00
semantic-release-bot
f4af27dfec chore: Release v5.48.0-dev.9 [skip ci]
# [5.48.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.48.0-dev.8...v5.48.0-dev.9) (2026-01-08)

### Features

* Add `Disable Sentry telemetry` patch ([#6416](https://github.com/ReVanced/revanced-patches/issues/6416)) ([4cc3159](4cc315952d))
* Disable Play Integrity patch ([#6412](https://github.com/ReVanced/revanced-patches/issues/6412)) ([6312fe8](6312fe8d60))
2026-01-08 00:11:57 +00:00
xehpuk
4cc315952d
feat: Add Disable Sentry telemetry patch (#6416) 2026-01-08 01:08:52 +01:00
1fexd
6312fe8d60
feat: Disable Play Integrity patch (#6412)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-01-08 01:06:05 +01:00
Ushie
3d754575a4
ci: Simplify Crowdin translation file destination path (#6463) 2026-01-07 22:31:15 +01:00
semantic-release-bot
a3f7609fe3 chore: Release v5.48.0-dev.8 [skip ci]
# [5.48.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.48.0-dev.7...v5.48.0-dev.8) (2026-01-04)

### Features

* **Letterboxd:** Add `Unlock app icons` patch ([#6415](https://github.com/ReVanced/revanced-patches/issues/6415)) ([d25dcfe](d25dcfe49a))
2026-01-04 13:17:54 +00:00
Swakshan
d25dcfe49a
feat(Letterboxd): Add Unlock app icons patch (#6415) 2026-01-04 14:14:29 +01:00
semantic-release-bot
1cc2cb9cb2 chore: Release v5.48.0-dev.7 [skip ci]
# [5.48.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.48.0-dev.6...v5.48.0-dev.7) (2026-01-04)

### Features

* **Strava:** Add `Disable Quick Edit` patch ([#6452](https://github.com/ReVanced/revanced-patches/issues/6452)) ([f5cbb31](f5cbb31724))
* **Strava:** Add `Overwrite media upload parameters` patch ([#6410](https://github.com/ReVanced/revanced-patches/issues/6410)) ([b42ae27](b42ae27ce6))
2026-01-04 02:43:29 +00:00
xehpuk
f5cbb31724
feat(Strava): Add Disable Quick Edit patch (#6452)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2026-01-04 03:38:04 +01:00
xehpuk
b42ae27ce6
feat(Strava): Add Overwrite media upload parameters patch (#6410) 2026-01-04 03:36:08 +01:00
semantic-release-bot
43ab29d03d chore: Release v5.48.0-dev.6 [skip ci]
# [5.48.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.48.0-dev.5...v5.48.0-dev.6) (2026-01-04)

### Bug Fixes

* Fix build error introduced in `4046bee` ([#6417](https://github.com/ReVanced/revanced-patches/issues/6417)) ([789f0a5](789f0a5628))
2026-01-04 02:07:07 +00:00
xehpuk
789f0a5628
fix: Fix build error introduced in 4046bee (#6417) 2026-01-04 03:03:44 +01:00
semantic-release-bot
da836b667c chore: Release v5.48.0-dev.5 [skip ci]
# [5.48.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.48.0-dev.4...v5.48.0-dev.5) (2025-12-30)

### Bug Fixes

* **Disney+ - Skip ads:** Remove unsupported package names ([#6422](https://github.com/ReVanced/revanced-patches/issues/6422)) ([44e7dbc](44e7dbcf4d))
2025-12-30 18:37:28 +00:00
ILoveOpenSourceApplications
44e7dbcf4d
fix(Disney+ - Skip ads): Remove unsupported package names (#6422) 2025-12-30 19:32:17 +01:00
semantic-release-bot
195c239000 chore: Release v5.48.0-dev.4 [skip ci]
# [5.48.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.48.0-dev.3...v5.48.0-dev.4) (2025-12-29)

### Features

* **Strava:** Add `Block Snowplow tracking` patch ([#6413](https://github.com/ReVanced/revanced-patches/issues/6413)) ([c47beae](c47beae213))
2025-12-29 21:25:35 +00:00
xehpuk
c47beae213
feat(Strava): Add Block Snowplow tracking patch (#6413)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-12-29 22:20:26 +01:00
semantic-release-bot
cebcfab86a chore: Release v5.48.0-dev.3 [skip ci]
# [5.48.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.48.0-dev.2...v5.48.0-dev.3) (2025-12-28)

### Bug Fixes

* Fix compilation error introduced in `6bb6281` ([#6409](https://github.com/ReVanced/revanced-patches/issues/6409)) ([71c6cb5](71c6cb569e))

### Features

* **Instagram - Hides navigation buttons:** Add more buttons to hide ([#6390](https://github.com/ReVanced/revanced-patches/issues/6390)) ([6bb6281](6bb6281149))
2025-12-28 22:33:37 +00:00
xehpuk
71c6cb569e
fix: Fix compilation error introduced in 6bb6281 (#6409) 2025-12-28 23:30:32 +01:00
PainfulPaladins
6bb6281149
feat(Instagram - Hides navigation buttons): Add more buttons to hide (#6390) 2025-12-27 18:50:08 +01:00
semantic-release-bot
16bd96e2bb chore: Release v5.48.0-dev.2 [skip ci]
# [5.48.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.48.0-dev.1...v5.48.0-dev.2) (2025-12-27)

### Features

* **Strava:** Add `Enable password login` patch ([#6396](https://github.com/ReVanced/revanced-patches/issues/6396)) ([8f3f4c9](8f3f4c95bb))
2025-12-27 17:48:32 +00:00
xehpuk
8f3f4c95bb
feat(Strava): Add Enable password login patch (#6396)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-12-27 18:45:09 +01:00
semantic-release-bot
da02d68587 chore: Release v5.48.0-dev.1 [skip ci]
# [5.48.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.47.0...v5.48.0-dev.1) (2025-12-23)

### Bug Fixes

* Fix compilation error introduced in dc69f243 ([#6392](https://github.com/ReVanced/revanced-patches/issues/6392)) ([a429824](a429824bb7))
* **YouTube - Hide layout components:** Hide new type of crowdfunding box ([#6380](https://github.com/ReVanced/revanced-patches/issues/6380)) ([dc69f24](dc69f2433e))

### Features

* **ProtonVPN:** Add `Unlock split tunneling` patch ([#6353](https://github.com/ReVanced/revanced-patches/issues/6353)) ([e0f3346](e0f33468e6))
* **SBS On Demand:** Add `Remove ads` patch ([#6378](https://github.com/ReVanced/revanced-patches/issues/6378)) ([315931c](315931cbf8))
2025-12-23 01:30:13 +00:00
xehpuk
a429824bb7
fix: Fix compilation error introduced in dc69f243 (#6392) 2025-12-23 02:26:54 +01:00
Sylvain Finot
e0f33468e6
feat(ProtonVPN): Add Unlock split tunneling patch (#6353)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-12-22 15:00:08 +01:00
trespyian
315931cbf8
feat(SBS On Demand): Add Remove ads patch (#6378)
Co-authored-by: Trespyian <trespyian@nowhere.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-12-22 14:49:19 +01:00
ILoveOpenSourceApplications
dc69f2433e
fix(YouTube - Hide layout components): Hide new type of crowdfunding box (#6380) 2025-12-21 23:10:35 +01:00
semantic-release-bot
73e43b2a49 chore: Release v5.47.0 [skip ci]
# [5.47.0](https://github.com/ReVanced/revanced-patches/compare/v5.46.0...v5.47.0) (2025-12-18)

### Bug Fixes

* **Instagram - Disable signature check:** Change patch to default excluded ([#6283](https://github.com/ReVanced/revanced-patches/issues/6283)) ([bb745b5](bb745b555b))
* **Lightroom:** Add `Disable version check` patch to fix opening the app  ([#6315](https://github.com/ReVanced/revanced-patches/issues/6315)) ([018d176](018d176914))
* **Reddit - Hide ads:** Update patch for new versions of Reddit ([#6342](https://github.com/ReVanced/revanced-patches/issues/6342)) ([f8bd123](f8bd1239cc))
* **Spotify:** Make patches work with latest versions again ([#6359](https://github.com/ReVanced/revanced-patches/issues/6359)) ([34830ba](34830ba63b))
* **YouTube - Hide layout components:** Fix "Hide Subscribe button" in channel page not working ([#6363](https://github.com/ReVanced/revanced-patches/issues/6363)) ([ded8370](ded8370207))
* **YouTube - Hide player flyout menu items:** Allow hiding audio menu with 'Android No SDK' client type ([9495cf4](9495cf49ef))
* **YouTube - Sanitize sharing links:** Handle non hierarchical urls ([654d091](654d091e65))

### Features

* **Disney+ - SkipAds:** Add other package names the patch is compatible with ([#6372](https://github.com/ReVanced/revanced-patches/issues/6372)) ([1f4f252](1f4f252c81))
* **Disney+:** Add `Skip ads` patch ([#6343](https://github.com/ReVanced/revanced-patches/issues/6343)) ([6bd7dca](6bd7dca75b))
* **IdAustria - Remove device integrity check:** Update patch to work with latest version ([#6360](https://github.com/ReVanced/revanced-patches/issues/6360)) ([0ea3491](0ea3491227))
* **Instagram:** Add `Anonymous story viewing` patch ([#6263](https://github.com/ReVanced/revanced-patches/issues/6263)) ([94ae84a](94ae84ad0f))
* **Instagram:** Add `Disable auto story flipping` patch ([#6262](https://github.com/ReVanced/revanced-patches/issues/6262)) ([2f0de15](2f0de15e67))
* **Instagram:** Add `Disable Reels scrolling` patch ([#6317](https://github.com/ReVanced/revanced-patches/issues/6317)) ([0928dcd](0928dcd00d))
* **Letterboxd:** Add `Hide ads` patch ([#6309](https://github.com/ReVanced/revanced-patches/issues/6309)) ([0af0ee9](0af0ee92c4))
* **Peacock TV:** Add `Hide ads` patch ([#6348](https://github.com/ReVanced/revanced-patches/issues/6348)) ([847ee18](847ee189a9))
* **ProtonVPN:** Add `Remove delay` patch ([#6326](https://github.com/ReVanced/revanced-patches/issues/6326)) ([bbd8932](bbd8932b2e))
* **Spoof SIM provider:** Spoof additional TelephonyManager methods ([#6293](https://github.com/ReVanced/revanced-patches/issues/6293)) ([ac583d4](ac583d40d0))
* **YouTube - Hide layout components:** Add "Hide cell divider", "Hide featured links", and "Hide featured videos" options ([#6335](https://github.com/ReVanced/revanced-patches/issues/6335)) ([a5d197b](a5d197b977))
* **YouTube - Hide layout components:** Add "Hide Join button" and "Hide Subscribe button" options for channel page ([#6345](https://github.com/ReVanced/revanced-patches/issues/6345)) ([02831a6](02831a6069))
* **YouTube - Hide Shorts components:** Add "Hide auto-dubbed label" and "Hide live preview" options ([#6334](https://github.com/ReVanced/revanced-patches/issues/6334)) ([a7c220a](a7c220a4ae))
2025-12-18 12:14:21 +00:00
oSumAtrIX
918f04793f
chore: Merge branch dev to main (#6282) 2025-12-18 13:10:41 +01:00
semantic-release-bot
f1a9537f01 chore: Release v5.47.0-dev.18 [skip ci]
# [5.47.0-dev.18](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.17...v5.47.0-dev.18) (2025-12-18)

### Features

* **Disney+ - SkipAds:** Add other package names the patch is compatible with ([#6372](https://github.com/ReVanced/revanced-patches/issues/6372)) ([1f4f252](1f4f252c81))
2025-12-18 12:09:57 +00:00
vippium
1f4f252c81
feat(Disney+ - SkipAds): Add other package names the patch is compatible with (#6372) 2025-12-18 12:59:47 +01:00
semantic-release-bot
2b560f5fe9 chore: Release v5.47.0-dev.17 [skip ci]
# [5.47.0-dev.17](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.16...v5.47.0-dev.17) (2025-12-18)

### Bug Fixes

* **Reddit - Hide ads:** Update patch for new versions of Reddit ([#6342](https://github.com/ReVanced/revanced-patches/issues/6342)) ([f8bd123](f8bd1239cc))
2025-12-18 02:05:14 +00:00
g9q
f8bd1239cc
fix(Reddit - Hide ads): Update patch for new versions of Reddit (#6342)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-12-18 03:01:25 +01:00
semantic-release-bot
c825ebda37 chore: Release v5.47.0-dev.16 [skip ci]
# [5.47.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.15...v5.47.0-dev.16) (2025-12-15)

### Bug Fixes

* **Lightroom:** Add `Disable version check` patch to fix opening the app  ([#6315](https://github.com/ReVanced/revanced-patches/issues/6315)) ([018d176](018d176914))

### Features

* **IdAustria - Remove device integrity check:** Update patch to work with latest version ([#6360](https://github.com/ReVanced/revanced-patches/issues/6360)) ([0ea3491](0ea3491227))
2025-12-15 11:34:05 +00:00
oSumAtrIX
255c00b183
chore: Fix minor syntax error 2025-12-15 12:28:53 +01:00
Alex Katlein
0ea3491227
feat(IdAustria - Remove device integrity check): Update patch to work with latest version (#6360)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-12-15 12:26:59 +01:00
Pun Butrach
5d437b08dd
docs: Use American spelling (#6233) 2025-12-14 16:38:55 +01:00
f1re4xx
018d176914
fix(Lightroom): Add Disable version check patch to fix opening the app (#6315)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-12-14 16:38:26 +01:00
semantic-release-bot
9a77beea8a chore: Release v5.47.0-dev.15 [skip ci]
# [5.47.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.14...v5.47.0-dev.15) (2025-12-13)

### Bug Fixes

* **YouTube - Hide layout components:** Fix "Hide Subscribe button" in channel page not working ([#6363](https://github.com/ReVanced/revanced-patches/issues/6363)) ([ded8370](ded8370207))
2025-12-13 20:26:05 +00:00
ILoveOpenSourceApplications
ded8370207
fix(YouTube - Hide layout components): Fix "Hide Subscribe button" in channel page not working (#6363) 2025-12-13 21:22:35 +01:00
semantic-release-bot
4d1104fc32 chore: Release v5.47.0-dev.14 [skip ci]
# [5.47.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.13...v5.47.0-dev.14) (2025-12-13)

### Bug Fixes

* **Spotify:** Make patches work with latest versions again ([#6359](https://github.com/ReVanced/revanced-patches/issues/6359)) ([34830ba](34830ba63b))
2025-12-13 08:52:03 +00:00
Cilly Leang
34830ba63b
fix(Spotify): Make patches work with latest versions again (#6359) 2025-12-13 09:48:39 +01:00
github-actions[bot]
7a6894d809
chore: Sync translations (#6344)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-12-10 03:58:45 +01:00
semantic-release-bot
144e6e2694 chore: Release v5.47.0-dev.13 [skip ci]
# [5.47.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.12...v5.47.0-dev.13) (2025-12-10)

### Features

* **Peacock TV:** Add `Hide ads` patch ([#6348](https://github.com/ReVanced/revanced-patches/issues/6348)) ([847ee18](847ee189a9))
2025-12-10 02:58:06 +00:00
g9q
847ee189a9
feat(Peacock TV): Add Hide ads patch (#6348) 2025-12-10 03:55:08 +01:00
semantic-release-bot
dc813fe617 chore: Release v5.47.0-dev.12 [skip ci]
# [5.47.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.11...v5.47.0-dev.12) (2025-12-08)

### Features

* **YouTube - Hide layout components:** Add "Hide Join button" and "Hide Subscribe button" options for channel page ([#6345](https://github.com/ReVanced/revanced-patches/issues/6345)) ([02831a6](02831a6069))
2025-12-08 21:14:39 +00:00
ILoveOpenSourceApplications
02831a6069
feat(YouTube - Hide layout components): Add "Hide Join button" and "Hide Subscribe button" options for channel page (#6345) 2025-12-08 22:10:35 +01:00
semantic-release-bot
5228fd4b58 chore: Release v5.47.0-dev.11 [skip ci]
# [5.47.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.10...v5.47.0-dev.11) (2025-12-08)

### Features

* **Disney+:** Add `Skip ads` patch ([#6343](https://github.com/ReVanced/revanced-patches/issues/6343)) ([6bd7dca](6bd7dca75b))
2025-12-08 13:51:15 +00:00
g9q
6bd7dca75b
feat(Disney+): Add Skip ads patch (#6343)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-12-08 14:45:41 +01:00
semantic-release-bot
22ed7bfbb3 chore: Release v5.47.0-dev.10 [skip ci]
# [5.47.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.9...v5.47.0-dev.10) (2025-12-08)

### Features

* **YouTube - Hide Shorts components:** Add "Hide auto-dubbed label" and "Hide live preview" options ([#6334](https://github.com/ReVanced/revanced-patches/issues/6334)) ([a7c220a](a7c220a4ae))
2025-12-08 12:57:23 +00:00
ILoveOpenSourceApplications
a7c220a4ae
feat(YouTube - Hide Shorts components): Add "Hide auto-dubbed label" and "Hide live preview" options (#6334) 2025-12-08 13:51:57 +01:00
semantic-release-bot
d8ca4ee931 chore: Release v5.47.0-dev.9 [skip ci]
# [5.47.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.8...v5.47.0-dev.9) (2025-12-08)

### Features

* **YouTube - Hide layout components:** Add "Hide cell divider", "Hide featured links", and "Hide featured videos" options ([#6335](https://github.com/ReVanced/revanced-patches/issues/6335)) ([a5d197b](a5d197b977))
2025-12-08 12:06:03 +00:00
ILoveOpenSourceApplications
a5d197b977
feat(YouTube - Hide layout components): Add "Hide cell divider", "Hide featured links", and "Hide featured videos" options (#6335)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-12-08 13:02:22 +01:00
semantic-release-bot
a0ec4c07f7 chore: Release v5.47.0-dev.8 [skip ci]
# [5.47.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.7...v5.47.0-dev.8) (2025-12-08)

### Features

* **Instagram:** Add `Disable Reels scrolling` patch ([#6317](https://github.com/ReVanced/revanced-patches/issues/6317)) ([0928dcd](0928dcd00d))
* **ProtonVPN:** Add `Remove delay` patch ([#6326](https://github.com/ReVanced/revanced-patches/issues/6326)) ([bbd8932](bbd8932b2e))
2025-12-08 11:36:43 +00:00
Alexey Gorbachev
0928dcd00d
feat(Instagram): Add Disable Reels scrolling patch (#6317)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-12-08 12:31:54 +01:00
Sylvain Finot
bbd8932b2e
feat(ProtonVPN): Add Remove delay patch (#6326)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-12-08 12:30:47 +01:00
semantic-release-bot
300b12f948 chore: Release v5.47.0-dev.7 [skip ci]
# [5.47.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.6...v5.47.0-dev.7) (2025-12-03)

### Features

* **Spoof SIM provider:** Spoof additional TelephonyManager methods ([#6293](https://github.com/ReVanced/revanced-patches/issues/6293)) ([ac583d4](ac583d40d0))
2025-12-03 15:05:05 +00:00
rospino74
ac583d40d0
feat(Spoof SIM provider): Spoof additional TelephonyManager methods (#6293) 2025-12-03 16:01:08 +01:00
semantic-release-bot
c400188c38 chore: Release v5.47.0-dev.6 [skip ci]
# [5.47.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.5...v5.47.0-dev.6) (2025-11-24)

### Features

* **Letterboxd:** Add `Hide ads` patch ([#6309](https://github.com/ReVanced/revanced-patches/issues/6309)) ([0af0ee9](0af0ee92c4))
2025-11-24 12:01:20 +00:00
Swakshan
0af0ee92c4
feat(Letterboxd): Add Hide ads patch (#6309)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-11-24 12:56:55 +01:00
semantic-release-bot
fff29544b9 chore: Release v5.47.0-dev.5 [skip ci]
# [5.47.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.4...v5.47.0-dev.5) (2025-11-13)

### Bug Fixes

* **YouTube - Hide player flyout menu items:** Allow hiding audio menu with 'Android No SDK' client type ([9495cf4](9495cf49ef))
2025-11-13 07:44:09 +00:00
LisoUseInAIKyrios
9495cf49ef fix(YouTube - Hide player flyout menu items): Allow hiding audio menu with 'Android No SDK' client type 2025-11-13 09:40:28 +02:00
semantic-release-bot
15675b5164 chore: Release v5.47.0-dev.4 [skip ci]
# [5.47.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.3...v5.47.0-dev.4) (2025-11-12)

### Bug Fixes

* **YouTube - Sanitize sharing links:** Handle non hierarchical urls ([654d091](654d091e65))
2025-11-12 19:01:00 +00:00
LisoUseInAIKyrios
654d091e65 fix(YouTube - Sanitize sharing links): Handle non hierarchical urls 2025-11-12 20:55:32 +02:00
semantic-release-bot
98371be33c chore: Release v5.47.0-dev.3 [skip ci]
# [5.47.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.2...v5.47.0-dev.3) (2025-11-12)

### Features

* **Instagram:** Add `Disable auto story flipping` patch ([#6262](https://github.com/ReVanced/revanced-patches/issues/6262)) ([2f0de15](2f0de15e67))
2025-11-12 07:46:04 +00:00
brosssh
2f0de15e67
feat(Instagram): Add Disable auto story flipping patch (#6262)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2025-11-12 08:41:15 +01:00
semantic-release-bot
df160370e2 chore: Release v5.47.0-dev.2 [skip ci]
# [5.47.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.1...v5.47.0-dev.2) (2025-11-12)

### Bug Fixes

* **Instagram - Disable signature check:** Change patch to default excluded ([#6283](https://github.com/ReVanced/revanced-patches/issues/6283)) ([bb745b5](bb745b555b))
2025-11-12 06:19:34 +00:00
LisoUseInAIKyrios
bb745b555b
fix(Instagram - Disable signature check): Change patch to default excluded (#6283) 2025-11-12 08:14:16 +02:00
semantic-release-bot
8df9a46721 chore: Release v5.47.0-dev.1 [skip ci]
# [5.47.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.46.0...v5.47.0-dev.1) (2025-11-12)

### Features

* **Instagram:** Add `Anonymous story viewing` patch ([#6263](https://github.com/ReVanced/revanced-patches/issues/6263)) ([94ae84a](94ae84ad0f))
2025-11-12 05:32:16 +00:00
brosssh
94ae84ad0f
feat(Instagram): Add Anonymous story viewing patch (#6263) 2025-11-12 07:29:13 +02:00
github-actions[bot]
4febb2e2e9
chore: Sync translations (#6280) 2025-11-12 07:28:43 +02:00
semantic-release-bot
b9bc7e3e58 chore: Release v5.46.0 [skip ci]
# [5.46.0](https://github.com/ReVanced/revanced-patches/compare/v5.45.0...v5.46.0) (2025-11-10)

### Bug Fixes

* **Duolingo - Disable ads:** Constrain patch to last working app target ([f238ae9](f238ae9895))
* **Instagram - Hide navigation buttons:** Constrain patch to last working app target ([e030e9c](e030e9c07a))
* **Spotify - Hide Create button:** Remove obsolete patch that is no longer needed ([#6252](https://github.com/ReVanced/revanced-patches/issues/6252)) ([59d85b2](59d85b28a7))
* **YouTube - Check watch history domain name resolution:** Fix false positive warning message if the internet connection fails halfway into the DNS check ([5726353](57263538c7))
* **YouTube - Hide layout components:** Fix "Hide Hype points" ([#6247](https://github.com/ReVanced/revanced-patches/issues/6247)) ([5821440](582144026d))
* **YouTube - Settings:** Add additional languages to ReVanced language preference ([d390b54](d390b54dab))
* **YouTube - Settings:** Resolve settings search crash when searching for specific words ([#6231](https://github.com/ReVanced/revanced-patches/issues/6231)) ([76dcfae](76dcfaefd8))

### Features

* **YouTube - Debugging:** Add setting to block experimental client flags ([#6196](https://github.com/ReVanced/revanced-patches/issues/6196)) ([2e9d695](2e9d6959c9))
* **YouTube - Hide layout components:** Add "Hide Hype points" ([#6230](https://github.com/ReVanced/revanced-patches/issues/6230)) ([a52c015](a52c0153b1))
* **YouTube - Hide layout components:** Add video description "Hide Featured content" and "Hide Subscribe button" ([#6253](https://github.com/ReVanced/revanced-patches/issues/6253)) ([da4cf94](da4cf94091))
* **YouTube - Hide player flyout menu items:** Add "Hide Listen with YouTube Music" ([#6232](https://github.com/ReVanced/revanced-patches/issues/6232)) ([858edbf](858edbf3e7))
* **YouTube Music:** Add `Change miniplayer color` patch ([#6259](https://github.com/ReVanced/revanced-patches/issues/6259)) ([ab808ae](ab808aeb77))
* **YouTube Music:** Add `Hide buttons` patch ([#6255](https://github.com/ReVanced/revanced-patches/issues/6255)) ([7a18ebc](7a18ebc7ab))
2025-11-10 10:06:40 +00:00
LisoUseInAIKyrios
9f3bb26cb9
chore: Merge branch dev to main (#6237) 2025-11-10 12:03:02 +02:00
github-actions[bot]
d64dfc2884
chore: Sync translations (#6276) 2025-11-10 12:00:41 +02:00
LisoUseInAIKyrios
a39ef1e0a4 refactor(YouTube Music - Custom branding): Resolve startup app crash when patching unsupported newer app versions 2025-11-10 11:23:09 +02:00
semantic-release-bot
1d8e977a43 chore: Release v5.46.0-dev.10 [skip ci]
# [5.46.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v5.46.0-dev.9...v5.46.0-dev.10) (2025-11-09)

### Features

* **YouTube - Hide layout components:** Add video description "Hide Featured content" and "Hide Subscribe button" ([#6253](https://github.com/ReVanced/revanced-patches/issues/6253)) ([da4cf94](da4cf94091))
2025-11-09 15:35:27 +00:00
ILoveOpenSourceApplications
da4cf94091
feat(YouTube - Hide layout components): Add video description "Hide Featured content" and "Hide Subscribe button" (#6253) 2025-11-09 17:30:07 +02:00
github-actions[bot]
d23fa5e3b7
chore: Sync translations (#6270) 2025-11-09 17:29:11 +02:00
semantic-release-bot
34d29abdfa chore: Release v5.46.0-dev.9 [skip ci]
# [5.46.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.46.0-dev.8...v5.46.0-dev.9) (2025-11-09)

### Features

* **YouTube Music:** Add `Change miniplayer color` patch ([#6259](https://github.com/ReVanced/revanced-patches/issues/6259)) ([ab808ae](ab808aeb77))
2025-11-09 07:43:26 +00:00
MarcaD
ab808aeb77
feat(YouTube Music): Add Change miniplayer color patch (#6259)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2025-11-09 09:39:51 +02:00
github-actions[bot]
a6b07cceb1
chore: Sync translations (#6266) 2025-11-09 09:39:32 +02:00
semantic-release-bot
d291881215 chore: Release v5.46.0-dev.8 [skip ci]
# [5.46.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.46.0-dev.7...v5.46.0-dev.8) (2025-11-09)

### Features

* **YouTube Music:** Add `Hide buttons` patch ([#6255](https://github.com/ReVanced/revanced-patches/issues/6255)) ([7a18ebc](7a18ebc7ab))
2025-11-09 07:09:07 +00:00
MarcaD
7a18ebc7ab
feat(YouTube Music): Add Hide buttons patch (#6255) 2025-11-09 09:05:31 +02:00
semantic-release-bot
475197af45 chore: Release v5.46.0-dev.7 [skip ci]
# [5.46.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.46.0-dev.6...v5.46.0-dev.7) (2025-11-08)

### Bug Fixes

* **YouTube - Settings:** Add additional languages to ReVanced language preference ([d390b54](d390b54dab))
2025-11-08 12:32:08 +00:00
LisoUseInAIKyrios
d390b54dab fix(YouTube - Settings): Add additional languages to ReVanced language preference 2025-11-08 14:28:52 +02:00
github-actions[bot]
4d1eaa6b14
chore: Sync translations (#6260) 2025-11-08 14:26:20 +02:00
LisoUseInAIKyrios
c6364f5b49 chore: Fix compilation warning 2025-11-08 10:08:25 +02:00
semantic-release-bot
f177eae385 chore: Release v5.46.0-dev.6 [skip ci]
# [5.46.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.46.0-dev.5...v5.46.0-dev.6) (2025-11-08)

### Features

* **YouTube - Debugging:** Add setting to block experimental client flags ([#6196](https://github.com/ReVanced/revanced-patches/issues/6196)) ([2e9d695](2e9d6959c9))
2025-11-08 08:07:41 +00:00
MarcaD
2e9d6959c9
feat(YouTube - Debugging): Add setting to block experimental client flags (#6196) 2025-11-08 10:01:46 +02:00
semantic-release-bot
81f83690d6 chore: Release v5.46.0-dev.5 [skip ci]
# [5.46.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.46.0-dev.4...v5.46.0-dev.5) (2025-11-07)

### Bug Fixes

* **Duolingo - Disable ads:** Constrain patch to last working app target ([f238ae9](f238ae9895))
* **Instagram - Hide navigation buttons:** Constrain patch to last working app target ([e030e9c](e030e9c07a))
* **Spotify - Hide Create button:** Remove obsolete patch that is no longer needed ([#6252](https://github.com/ReVanced/revanced-patches/issues/6252)) ([59d85b2](59d85b28a7))
2025-11-07 11:39:00 +00:00
LisoUseInAIKyrios
f1bd6848c9 chore(deps-dev): Revert bump semantic-release from 24.2.9 to 25.0.1 (#6204)
This reverts commit 55e1a6784b.
2025-11-07 13:36:18 +02:00
LisoUseInAIKyrios
59d85b28a7
fix(Spotify - Hide Create button): Remove obsolete patch that is no longer needed (#6252) 2025-11-07 13:29:34 +02:00
LisoUseInAIKyrios
f238ae9895 fix(Duolingo - Disable ads): Constrain patch to last working app target 2025-11-07 13:27:31 +02:00
LisoUseInAIKyrios
e030e9c07a fix(Instagram - Hide navigation buttons): Constrain patch to last working app target 2025-11-07 13:25:24 +02:00
dependabot[bot]
5029e979be
chore(deps): Bump actions/upload-artifact from 4 to 5 (#6201) 2025-11-07 09:34:24 +02:00
dependabot[bot]
55e1a6784b
chore(deps-dev): Bump semantic-release from 24.2.9 to 25.0.1 (#6204) 2025-11-07 09:33:23 +02:00
dependabot[bot]
0cad5e73f0
chore(deps): Bump actions/setup-node from 5 to 6 (#6200) 2025-11-07 09:33:05 +02:00
semantic-release-bot
ce503d5b58 chore: Release v5.46.0-dev.4 [skip ci]
# [5.46.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.46.0-dev.3...v5.46.0-dev.4) (2025-11-07)

### Bug Fixes

* **YouTube - Check watch history domain name resolution:** Fix false positive warning message if the internet connection fails halfway into the DNS check ([5726353](57263538c7))
2025-11-07 07:17:59 +00:00
LisoUseInAIKyrios
57263538c7 fix(YouTube - Check watch history domain name resolution): Fix false positive warning message if the internet connection fails halfway into the DNS check 2025-11-07 09:14:21 +02:00
semantic-release-bot
70f4955e89 chore: Release v5.46.0-dev.3 [skip ci]
# [5.46.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.46.0-dev.2...v5.46.0-dev.3) (2025-11-06)

### Bug Fixes

* **YouTube - Hide layout components:** Fix "Hide Hype points" ([#6247](https://github.com/ReVanced/revanced-patches/issues/6247)) ([5821440](582144026d))
2025-11-06 12:12:38 +00:00
ILoveOpenSourceApplications
582144026d
fix(YouTube - Hide layout components): Fix "Hide Hype points" (#6247) 2025-11-06 14:09:43 +02:00
github-actions[bot]
d80892cc0e
chore: Sync translations (#6248) 2025-11-06 14:09:25 +02:00
semantic-release-bot
6c4b931b8a chore: Release v5.46.0-dev.2 [skip ci]
# [5.46.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.46.0-dev.1...v5.46.0-dev.2) (2025-11-04)

### Bug Fixes

* **YouTube - Settings:** Resolve settings search crash when searching for specific words ([#6231](https://github.com/ReVanced/revanced-patches/issues/6231)) ([76dcfae](76dcfaefd8))
2025-11-04 13:03:33 +00:00
MarcaD
76dcfaefd8
fix(YouTube - Settings): Resolve settings search crash when searching for specific words (#6231) 2025-11-04 14:59:43 +02:00
github-actions[bot]
e4f52343c0
chore: Sync translations (#6239) 2025-11-04 14:59:20 +02:00
semantic-release-bot
1196b1a147 chore: Release v5.46.0-dev.1 [skip ci]
# [5.46.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.45.0...v5.46.0-dev.1) (2025-11-04)

### Features

* **YouTube - Hide layout components:** Add "Hide Hype points" ([#6230](https://github.com/ReVanced/revanced-patches/issues/6230)) ([a52c015](a52c0153b1))
* **YouTube - Hide player flyout menu items:** Add "Hide Listen with YouTube Music" ([#6232](https://github.com/ReVanced/revanced-patches/issues/6232)) ([858edbf](858edbf3e7))
2025-11-04 07:10:24 +00:00
ILoveOpenSourceApplications
858edbf3e7
feat(YouTube - Hide player flyout menu items): Add "Hide Listen with YouTube Music" (#6232) 2025-11-04 09:07:11 +02:00
ILoveOpenSourceApplications
a52c0153b1
feat(YouTube - Hide layout components): Add "Hide Hype points" (#6230) 2025-11-04 09:05:28 +02:00
semantic-release-bot
cd9ef81354 chore: Release v5.45.0 [skip ci]
# [5.45.0](https://github.com/ReVanced/revanced-patches/compare/v5.44.0...v5.45.0) (2025-11-01)

### Bug Fixes

* **Instagram:** Update failing fingerprints on newer versions ([#6181](https://github.com/ReVanced/revanced-patches/issues/6181)) ([c73a03c](c73a03c9e1))
* **TikTok - Downloads:** Fix download path setting  ([#6191](https://github.com/ReVanced/revanced-patches/issues/6191)) ([3e4990a](3e4990afff))
* **YouTube - Change header:** Do not mirror header graphic with RTL languages ([a0c5604](a0c5604951))
* **YouTube - Force original audio:** Fall back to visionOS and not Android Studio if Android VR is not available ([6d01863](6d01863ec7))
* **YouTube - Spoof video streams:** Remove spoof stream audio selector that no longer works ([292fae4](292fae440c))
* **YouTube Music - Hide category bar:** Correctly hide the category bar in newer app targets ([#6175](https://github.com/ReVanced/revanced-patches/issues/6175)) ([13cf172](13cf1724bf))

### Features

* **Spoof video streams:** Add experimental "Android No SDK" client type ([5f23bfe](5f23bfe833))
* **TikTok:** Add `Sanitize sharing links` patch ([#6176](https://github.com/ReVanced/revanced-patches/issues/6176)) ([ef44eaa](ef44eaa119))
* **YouTube - Change Header:** Use SVG for header logo ([#6178](https://github.com/ReVanced/revanced-patches/issues/6178)) ([e9f45ce](e9f45ce926))
2025-11-01 15:36:32 +00:00
LisoUseInAIKyrios
1b2cd64a86
chore: Merge branch dev to main (#6174) 2025-11-01 16:32:23 +01:00
semantic-release-bot
0c03599f07 chore: Release v5.45.0-dev.6 [skip ci]
# [5.45.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.45.0-dev.5...v5.45.0-dev.6) (2025-11-01)

### Features

* **Spoof video streams:** Add experimental "Android No SDK" client type ([5f23bfe](5f23bfe833))
2025-11-01 08:25:19 +00:00
LisoUseInAIKyrios
5f23bfe833 feat(Spoof video streams): Add experimental "Android No SDK" client type 2025-11-01 09:19:49 +01:00
github-actions[bot]
2cf8f0e636
chore: Sync translations (#6197) 2025-11-01 09:17:01 +01:00
semantic-release-bot
c17cf98c7e chore: Release v5.45.0-dev.5 [skip ci]
# [5.45.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.45.0-dev.4...v5.45.0-dev.5) (2025-11-01)

### Bug Fixes

* **TikTok - Downloads:** Fix download path setting  ([#6191](https://github.com/ReVanced/revanced-patches/issues/6191)) ([3e4990a](3e4990afff))
* **YouTube - Spoof video streams:** Remove spoof stream audio selector that no longer works ([292fae4](292fae440c))
2025-11-01 07:36:49 +00:00
hxreborn
3e4990afff
fix(TikTok - Downloads): Fix download path setting (#6191) 2025-11-01 08:32:26 +01:00
LisoUseInAIKyrios
292fae440c fix(YouTube - Spoof video streams): Remove spoof stream audio selector that no longer works 2025-11-01 08:31:17 +01:00
semantic-release-bot
12e7c0943a chore: Release v5.45.0-dev.4 [skip ci]
# [5.45.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.45.0-dev.3...v5.45.0-dev.4) (2025-10-30)

### Bug Fixes

* **YouTube - Change header:** Do not mirror header graphic with RTL languages ([a0c5604](a0c5604951))
2025-10-30 08:32:28 +00:00
LisoUseInAIKyrios
a0c5604951 fix(YouTube - Change header): Do not mirror header graphic with RTL languages 2025-10-30 09:27:27 +01:00
LisoUseInAIKyrios
38d9299dfe
chore: Add branding license text file (#6179) 2025-10-30 09:26:18 +01:00
semantic-release-bot
dfdbbfa047 chore: Release v5.45.0-dev.3 [skip ci]
# [5.45.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.45.0-dev.2...v5.45.0-dev.3) (2025-10-27)

### Features

* **YouTube - Change Header:** Use SVG for header logo ([#6178](https://github.com/ReVanced/revanced-patches/issues/6178)) ([e9f45ce](e9f45ce926))
2025-10-27 17:14:52 +00:00
MarcaD
e9f45ce926
feat(YouTube - Change Header): Use SVG for header logo (#6178)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2025-10-27 21:10:49 +04:00
semantic-release-bot
1b38b1a3c8 chore: Release v5.45.0-dev.2 [skip ci]
# [5.45.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.45.0-dev.1...v5.45.0-dev.2) (2025-10-26)

### Bug Fixes

* **YouTube - Force original audio:** Fall back to visionOS and not Android Studio if Android VR is not available ([6d01863](6d01863ec7))
* **YouTube Music - Hide category bar:** Correctly hide the category bar in newer app targets ([#6175](https://github.com/ReVanced/revanced-patches/issues/6175)) ([13cf172](13cf1724bf))
2025-10-26 15:27:23 +00:00
MarcaD
13cf1724bf
fix(YouTube Music - Hide category bar): Correctly hide the category bar in newer app targets (#6175) 2025-10-26 19:23:40 +04:00
LisoUseInAIKyrios
6d01863ec7 fix(YouTube - Force original audio): Fall back to visionOS and not Android Studio if Android VR is not available 2025-10-26 19:23:04 +04:00
semantic-release-bot
a32ed30b4c chore: Release v5.45.0-dev.1 [skip ci]
# [5.45.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.44.0...v5.45.0-dev.1) (2025-10-26)

### Bug Fixes

* **Instagram:** Update failing fingerprints on newer versions ([#6181](https://github.com/ReVanced/revanced-patches/issues/6181)) ([c73a03c](c73a03c9e1))

### Features

* **TikTok:** Add `Sanitize sharing links` patch ([#6176](https://github.com/ReVanced/revanced-patches/issues/6176)) ([ef44eaa](ef44eaa119))
2025-10-26 10:05:58 +00:00
hxreborn
ef44eaa119
feat(TikTok): Add Sanitize sharing links patch (#6176) 2025-10-26 14:01:32 +04:00
rospino74
c73a03c9e1
fix(Instagram): Update failing fingerprints on newer versions (#6181) 2025-10-26 11:01:06 +01:00
LisoUseInAIKyrios
c1681f982a chore: Dump api 2025-10-25 08:11:57 +04:00
semantic-release-bot
1502bf7524 chore: Release v5.44.0 [skip ci]
# [5.44.0](https://github.com/ReVanced/revanced-patches/compare/v5.43.1...v5.44.0) (2025-10-24)

### Bug Fixes

* **Google Photos - Spoof features:** Add support for Pixel 10 devices ([#6161](https://github.com/ReVanced/revanced-patches/issues/6161)) ([754b719](754b71959a))
* **X / Twitter - Change link sharing domain:** Use bytecode patching to resolve patching with Manager ([#6125](https://github.com/ReVanced/revanced-patches/issues/6125)) ([0af8c8a](0af8c8a766))
* **YouTube - Hide layout components:** Hide new kind of community post ([#6146](https://github.com/ReVanced/revanced-patches/issues/6146)) ([cfd244b](cfd244b408))
* **YouTube Music:** Resolve patching 7.29 target ([2e4c6fd](2e4c6fdcad))

### Features

* Add `Custom network security` patch ([#6151](https://github.com/ReVanced/revanced-patches/issues/6151)) ([e7336d2](e7336d2ef3))
* **Duolingo - Enable debug menu:** Support latest app target ([#6163](https://github.com/ReVanced/revanced-patches/issues/6163)) ([08baa19](08baa19b4a))
* **Duolingo:** Add `Skip energy recharge ads` patch ([#6167](https://github.com/ReVanced/revanced-patches/issues/6167)) ([591e106](591e106098))
* **Samsung Radio:** Add `Disable device checks` patch ([#6145](https://github.com/ReVanced/revanced-patches/issues/6145)) ([de97562](de97562c5d))
2025-10-24 12:03:24 +00:00
LisoUseInAIKyrios
dffb1e6525
chore: Merge branch dev to main (#6135) 2025-10-24 15:59:21 +04:00
semantic-release-bot
b8c2ede2bf chore: Release v5.44.0-dev.4 [skip ci]
# [5.44.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.44.0-dev.3...v5.44.0-dev.4) (2025-10-24)

### Features

* Add `Custom network security` patch ([#6151](https://github.com/ReVanced/revanced-patches/issues/6151)) ([e7336d2](e7336d2ef3))
* **Duolingo:** Add `Skip energy recharge ads` patch ([#6167](https://github.com/ReVanced/revanced-patches/issues/6167)) ([591e106](591e106098))
2025-10-24 05:32:12 +00:00
hckrman101
591e106098
feat(Duolingo): Add Skip energy recharge ads patch (#6167) 2025-10-24 09:28:34 +04:00
Pawloland
e7336d2ef3
feat: Add Custom network security patch (#6151) 2025-10-24 09:27:12 +04:00
LisoUseInAIKyrios
7a53f8f62d chore(YouTube Music): Simplify fingerprint for upcoming app versions 2025-10-24 09:25:44 +04:00
github-actions[bot]
3466d9d210
chore: Sync translations (#6172) 2025-10-24 09:19:08 +04:00
LisoUseInAIKyrios
876d7a6b03 chore(X / Twitter - Change link sharing domain): Add disclaimer to description 2025-10-24 09:18:20 +04:00
semantic-release-bot
a2aa9cac27 chore: Release v5.44.0-dev.3 [skip ci]
# [5.44.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.44.0-dev.2...v5.44.0-dev.3) (2025-10-22)

### Features

* **Duolingo - Enable debug menu:** Support latest app target ([#6163](https://github.com/ReVanced/revanced-patches/issues/6163)) ([08baa19](08baa19b4a))
2025-10-22 20:24:37 +00:00
LisoUseInAIKyrios
08baa19b4a
feat(Duolingo - Enable debug menu): Support latest app target (#6163) 2025-10-23 00:21:30 +04:00
semantic-release-bot
7283b93cea chore: Release v5.44.0-dev.2 [skip ci]
# [5.44.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.44.0-dev.1...v5.44.0-dev.2) (2025-10-22)

### Bug Fixes

* **Google Photos - Spoof features:** Add support for Pixel 10 devices ([#6161](https://github.com/ReVanced/revanced-patches/issues/6161)) ([754b719](754b71959a))
2025-10-22 16:53:15 +00:00
Lassie111
754b71959a
fix(Google Photos - Spoof features): Add support for Pixel 10 devices (#6161) 2025-10-22 20:50:10 +04:00
LisoUseInAIKyrios
c64e29ec57 refactor(YouTube - Seekbar): Remove obsolete splash screen color code 2025-10-22 11:47:39 +04:00
semantic-release-bot
b2dd008aee chore: Release v5.44.0-dev.1 [skip ci]
# [5.44.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.43.2-dev.3...v5.44.0-dev.1) (2025-10-22)

### Features

* **Samsung Radio:** Add `Disable device checks` patch ([#6145](https://github.com/ReVanced/revanced-patches/issues/6145)) ([de97562](de97562c5d))
2025-10-22 06:14:00 +00:00
rospino74
de97562c5d
feat(Samsung Radio): Add Disable device checks patch (#6145) 2025-10-22 10:09:34 +04:00
semantic-release-bot
6373829fd6 chore: Release v5.43.2-dev.3 [skip ci]
## [5.43.2-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.43.2-dev.2...v5.43.2-dev.3) (2025-10-19)

### Bug Fixes

* **YouTube - Hide layout components:** Hide new kind of community post ([#6146](https://github.com/ReVanced/revanced-patches/issues/6146)) ([cfd244b](cfd244b408))
2025-10-19 14:29:38 +00:00
Bceez
cfd244b408
fix(YouTube - Hide layout components): Hide new kind of community post (#6146) 2025-10-19 18:24:45 +04:00
semantic-release-bot
e8e28e2b6a chore: Release v5.43.2-dev.2 [skip ci]
## [5.43.2-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.43.2-dev.1...v5.43.2-dev.2) (2025-10-17)

### Bug Fixes

* **YouTube Music:** Resolve patching 7.29 target ([2e4c6fd](2e4c6fdcad))
2025-10-17 21:15:51 +00:00
LisoUseInAIKyrios
2e4c6fdcad fix(YouTube Music): Resolve patching 7.29 target 2025-10-18 01:12:34 +04:00
github-actions[bot]
644d6dcb51
chore: Sync translations (#6142) 2025-10-18 01:08:27 +04:00
semantic-release-bot
14dd7346a8 chore: Release v5.43.2-dev.1 [skip ci]
## [5.43.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.43.1...v5.43.2-dev.1) (2025-10-16)

### Bug Fixes

* **X / Twitter - Change link sharing domain:** Use bytecode patching to resolve patching with Manager ([#6125](https://github.com/ReVanced/revanced-patches/issues/6125)) ([0af8c8a](0af8c8a766))
2025-10-16 19:37:32 +00:00
ADudeCalledLeo
0af8c8a766
fix(X / Twitter - Change link sharing domain): Use bytecode patching to resolve patching with Manager (#6125) 2025-10-16 23:29:01 +04:00
semantic-release-bot
96454c843b chore: Release v5.43.1 [skip ci]
## [5.43.1](https://github.com/ReVanced/revanced-patches/compare/v5.43.0...v5.43.1) (2025-10-15)

### Bug Fixes

* **X / Twitter - Change link sharing domain:** Resolve duplicate patch option ([#6119](https://github.com/ReVanced/revanced-patches/issues/6119)) ([7563990](7563990750))
* **X / Twitter:** Do not crash Manager when clicking on domain patch option ([2a1e318](2a1e31860f))
2025-10-15 08:15:15 +00:00
LisoUseInAIKyrios
476ef0fae1
chore: Merge branch dev to main (#6121) 2025-10-15 12:12:25 +04:00
github-actions[bot]
bbec724afb
chore: Sync translations (#6124) 2025-10-15 12:11:47 +04:00
semantic-release-bot
7a1dcbd4ee chore: Release v5.43.1-dev.2 [skip ci]
## [5.43.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.43.1-dev.1...v5.43.1-dev.2) (2025-10-14)

### Bug Fixes

* **X / Twitter:** Do not crash Manager when clicking on domain patch option ([2a1e318](2a1e31860f))
2025-10-14 19:47:15 +00:00
LisoUseInAIKyrios
2a1e31860f fix(X / Twitter): Do not crash Manager when clicking on domain patch option 2025-10-14 23:42:15 +04:00
semantic-release-bot
949d6bdd19 chore: Release v5.43.1-dev.1 [skip ci]
## [5.43.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.43.0...v5.43.1-dev.1) (2025-10-14)

### Bug Fixes

* **X / Twitter - Change link sharing domain:** Resolve duplicate patch option ([#6119](https://github.com/ReVanced/revanced-patches/issues/6119)) ([7563990](7563990750))
2025-10-14 18:19:42 +00:00
ADudeCalledLeo
7563990750
fix(X / Twitter - Change link sharing domain): Resolve duplicate patch option (#6119) 2025-10-14 22:16:01 +04:00
semantic-release-bot
4b605eb270 chore: Release v5.43.0 [skip ci]
# [5.43.0](https://github.com/ReVanced/revanced-patches/compare/v5.42.1...v5.43.0) (2025-10-14)

### Bug Fixes

* **Custom branding:** Use white notification icon for expanded status bar panel ([95eee59](95eee59a87))
* **Instagram - Change sharing domain:** Display patch option ([#6089](https://github.com/ReVanced/revanced-patches/issues/6089)) ([be2b144](be2b144cc9))
* **X / Twitter - Change Link Sharing Domain:** Change link domain of share copy action ([#6091](https://github.com/ReVanced/revanced-patches/issues/6091)) ([5484625](54846253d7))
* **YouTube - Custom branding:** Do not add a broken custom icon if the user provides an invalid custom icon path ([6555f6e](6555f6e6f8))
* **YouTube - Custom branding:** Use ReVanced icon for status bar notification icon ([#6108](https://github.com/ReVanced/revanced-patches/issues/6108)) ([10ea250](10ea250d4a))
* **YouTube - Force original audio:** Do not use translated audio if stream spoofing is off and force audio is on ([0c19dba](0c19dbaf30))

### Features

* **Instagram:** Add `Hide suggested content` patch ([#6075](https://github.com/ReVanced/revanced-patches/issues/6075)) ([50f0b9c](50f0b9c5ee))
2025-10-14 12:03:58 +00:00
LisoUseInAIKyrios
c2d7a7fb8b
chore: Merge branch dev to main (#6090) 2025-10-14 16:00:00 +04:00
github-actions[bot]
a55560dc25
chore: Sync translations (#6118) 2025-10-14 15:58:38 +04:00
semantic-release-bot
e8522d703e chore: Release v5.43.0-dev.4 [skip ci]
# [5.43.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.43.0-dev.3...v5.43.0-dev.4) (2025-10-14)

### Bug Fixes

* **YouTube - Force original audio:** Do not use translated audio if stream spoofing is off and force audio is on ([0c19dba](0c19dbaf30))
2025-10-14 11:46:49 +00:00
LisoUseInAIKyrios
068d029a03 refactor: Use notNull delegate to prevent wasting more time in the future 2025-10-14 15:43:05 +04:00
LisoUseInAIKyrios
0c19dbaf30 fix(YouTube - Force original audio): Do not use translated audio if stream spoofing is off and force audio is on 2025-10-14 15:38:05 +04:00
semantic-release-bot
bf73ac8316 chore: Release v5.43.0-dev.3 [skip ci]
# [5.43.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.43.0-dev.2...v5.43.0-dev.3) (2025-10-14)

### Bug Fixes

* **Custom branding:** Use white notification icon for expanded status bar panel ([95eee59](95eee59a87))
2025-10-14 10:39:28 +00:00
LisoUseInAIKyrios
95eee59a87 fix(Custom branding): Use white notification icon for expanded status bar panel 2025-10-14 14:36:09 +04:00
semantic-release-bot
566875ea53 chore: Release v5.43.0-dev.2 [skip ci]
# [5.43.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.43.0-dev.1...v5.43.0-dev.2) (2025-10-14)

### Bug Fixes

* **YouTube - Custom branding:** Use ReVanced icon for status bar notification icon ([#6108](https://github.com/ReVanced/revanced-patches/issues/6108)) ([10ea250](10ea250d4a))
2025-10-14 05:58:15 +00:00
LisoUseInAIKyrios
10ea250d4a
fix(YouTube - Custom branding): Use ReVanced icon for status bar notification icon (#6108) 2025-10-14 09:54:14 +04:00
github-actions[bot]
5bd0f11630
chore: Sync translations (#6117) 2025-10-14 09:53:13 +04:00
semantic-release-bot
4547ecb73c chore: Release v5.43.0-dev.1 [skip ci]
# [5.43.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.42.2-dev.3...v5.43.0-dev.1) (2025-10-11)

### Features

* **Instagram:** Add `Hide suggested content` patch ([#6075](https://github.com/ReVanced/revanced-patches/issues/6075)) ([50f0b9c](50f0b9c5ee))
2025-10-11 11:22:05 +00:00
Swakshan
50f0b9c5ee
feat(Instagram): Add Hide suggested content patch (#6075) 2025-10-11 15:17:24 +04:00
semantic-release-bot
a8c4bdb8a6 chore: Release v5.42.2-dev.3 [skip ci]
## [5.42.2-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.42.2-dev.2...v5.42.2-dev.3) (2025-10-11)

### Bug Fixes

* **YouTube - Custom branding:** Do not add a broken custom icon if the user provides an invalid custom icon path ([6555f6e](6555f6e6f8))
2025-10-11 08:04:05 +00:00
LisoUseInAIKyrios
6555f6e6f8 fix(YouTube - Custom branding): Do not add a broken custom icon if the user provides an invalid custom icon path 2025-10-11 12:00:26 +04:00
semantic-release-bot
a0e2c5c7b9 chore: Release v5.42.2-dev.2 [skip ci]
## [5.42.2-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.42.2-dev.1...v5.42.2-dev.2) (2025-10-10)

### Bug Fixes

* **X / Twitter - Change Link Sharing Domain:** Change link domain of share copy action ([#6091](https://github.com/ReVanced/revanced-patches/issues/6091)) ([5484625](54846253d7))
2025-10-10 22:05:28 +00:00
ADudeCalledLeo
54846253d7
fix(X / Twitter - Change Link Sharing Domain): Change link domain of share copy action (#6091)
Co-authored-by: nyraa <112930946+nyraa@users.noreply.github.com>
2025-10-11 02:01:44 +04:00
github-actions[bot]
a98e8f7370
chore: Sync translations (#6097) 2025-10-11 02:01:17 +04:00
semantic-release-bot
2d928e0cd6 chore: Release v5.42.2-dev.1 [skip ci]
## [5.42.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.42.1...v5.42.2-dev.1) (2025-10-09)

### Bug Fixes

* **Instagram - Change sharing domain:** Display patch option ([#6089](https://github.com/ReVanced/revanced-patches/issues/6089)) ([be2b144](be2b144cc9))
2025-10-09 08:03:53 +00:00
brosssh
be2b144cc9
fix(Instagram - Change sharing domain): Display patch option (#6089) 2025-10-09 10:00:17 +02:00
semantic-release-bot
52c0bb6aa2 chore: Release v5.42.1 [skip ci]
## [5.42.1](https://github.com/ReVanced/revanced-patches/compare/v5.42.0...v5.42.1) (2025-10-08)

### Bug Fixes

* **YouTube - Custom Branding:** Resolve startup crash with root installation ([fd4b2e1](fd4b2e1bb9))
2025-10-08 07:47:41 +00:00
LisoUseInAIKyrios
38a49cc2a1
chore: Merge branch dev to main (#6080) 2025-10-08 11:44:39 +04:00
semantic-release-bot
91044b3a50 chore: Release v5.42.1-dev.1 [skip ci]
## [5.42.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.42.0...v5.42.1-dev.1) (2025-10-08)

### Bug Fixes

* **YouTube - Custom Branding:** Resolve startup crash with root installation ([fd4b2e1](fd4b2e1bb9))
2025-10-08 07:42:49 +00:00
LisoUseInAIKyrios
fd4b2e1bb9 fix(YouTube - Custom Branding): Resolve startup crash with root installation 2025-10-08 11:39:48 +04:00
semantic-release-bot
d0f20c8c7f chore: Release v5.42.0 [skip ci]
# [5.42.0](https://github.com/ReVanced/revanced-patches/compare/v5.41.0...v5.42.0) (2025-10-08)

### Bug Fixes

* **Custom branding:** Update ReVanced logo ([#6049](https://github.com/ReVanced/revanced-patches/issues/6049)) ([9441e7a](9441e7acb4))
* **Custom branding:** Update ReVanced logo sizing ([#6029](https://github.com/ReVanced/revanced-patches/issues/6029)) ([ae4b947](ae4b9474d3))
* **Instagram - Hide navigation buttons:** Resolve app startup crash ([080a226](080a226614))
* **Spotify:** Change `Hide Create button` patch to default off ([#6067](https://github.com/ReVanced/revanced-patches/issues/6067)) ([19949e1](19949e1695))
* **X / Twitter:** Remove non functional and obsolete patch `Open links with app chooser` ([#6033](https://github.com/ReVanced/revanced-patches/issues/6033)) ([673609c](673609c2aa))
* **YouTube - Force original audio:** Change patch to default on ([#6070](https://github.com/ReVanced/revanced-patches/issues/6070)) ([bd4ba2d](bd4ba2dae8))
* **YouTube - Force original language:** Resolve some videos using Swedish audio track ([9d67316](9d6731660b))
* **YouTube - Hide end screen cards:** Hide new type of end screen card ([#6027](https://github.com/ReVanced/revanced-patches/issues/6027)) ([76b0364](76b0364c5b))
* **YouTube - Spoof video streams:** Add "Allow Android VR AV1" setting ([#6071](https://github.com/ReVanced/revanced-patches/issues/6071)) ([f03256c](f03256c471))
* **YouTube - Spoof video streams:** Do not allow VR AV1 if "Force AVC" is enabled ([7afeaeb](7afeaebb5c))
* **YouTube - Spoof video streams:** Resolve playback dropping frames ([#6051](https://github.com/ReVanced/revanced-patches/issues/6051)) ([a62ee43](a62ee43441))
* **YouTube Music - GmsCore support:** Handle sharing links to certain apps such as Instagram ([#6026](https://github.com/ReVanced/revanced-patches/issues/6026)) ([328234f](328234f39a))
* **YouTube Music - Hide cast button:** Fix patching error ([28799a5](28799a548a))
* **YouTube Music - Hide cast button:** Resolve button not hiding ([7817885](7817885cff))
* **YouTube:** Resolve UI components not hiding for some users ([#6054](https://github.com/ReVanced/revanced-patches/issues/6054)) ([6b26346](6b26346914))

### Features

* **Custom branding:** Add in-app settings to change icon and name ([#6059](https://github.com/ReVanced/revanced-patches/issues/6059)) ([a50f3b5](a50f3b5177))
* **Instagram:** Add `Custom share domain` patch ([#5998](https://github.com/ReVanced/revanced-patches/issues/5998)) ([20c4131](20c413120b))
* **Instagram:** Add `Enable developer menu` patch ([#6043](https://github.com/ReVanced/revanced-patches/issues/6043)) ([2154d89](2154d89242))
* **Instagram:** Add `Open links externally` patch ([#6012](https://github.com/ReVanced/revanced-patches/issues/6012)) ([08e8ead](08e8ead04f))
* **Instagram:** Add `Sanitize sharing links` patch ([#5986](https://github.com/ReVanced/revanced-patches/issues/5986)) ([963a4ef](963a4ef43f))
* **Viber:** Add `Hide navigation buttons` patch ([#5991](https://github.com/ReVanced/revanced-patches/issues/5991)) ([5cb46c4](5cb46c4e91))
* **YouTube Music:** Add `Custom branding` patch ([#6007](https://github.com/ReVanced/revanced-patches/issues/6007)) ([4c8b56f](4c8b56f546))
* **YouTube Music:** Add `Force original audio` patch ([#6036](https://github.com/ReVanced/revanced-patches/issues/6036)) ([d0d53d1](d0d53d109e))
2025-10-08 06:16:06 +00:00
semantic-release-bot
d65dbc749c chore: Release v5.42.0 [skip ci]
# [5.42.0](https://github.com/ReVanced/revanced-patches/compare/v5.41.0...v5.42.0) (2025-10-08)

### Bug Fixes

* **Custom branding:** Update ReVanced logo ([#6049](https://github.com/ReVanced/revanced-patches/issues/6049)) ([9441e7a](9441e7acb4))
* **Custom branding:** Update ReVanced logo sizing ([#6029](https://github.com/ReVanced/revanced-patches/issues/6029)) ([ae4b947](ae4b9474d3))
* **Instagram - Hide navigation buttons:** Resolve app startup crash ([080a226](080a226614))
* **Spotify:** Change `Hide Create button` patch to default off ([#6067](https://github.com/ReVanced/revanced-patches/issues/6067)) ([19949e1](19949e1695))
* **X / Twitter:** Remove non functional and obsolete patch `Open links with app chooser` ([#6033](https://github.com/ReVanced/revanced-patches/issues/6033)) ([673609c](673609c2aa))
* **YouTube - Force original audio:** Change patch to default on ([#6070](https://github.com/ReVanced/revanced-patches/issues/6070)) ([bd4ba2d](bd4ba2dae8))
* **YouTube - Force original language:** Resolve some videos using Swedish audio track ([9d67316](9d6731660b))
* **YouTube - Hide end screen cards:** Hide new type of end screen card ([#6027](https://github.com/ReVanced/revanced-patches/issues/6027)) ([76b0364](76b0364c5b))
* **YouTube - Spoof video streams:** Add "Allow Android VR AV1" setting ([#6071](https://github.com/ReVanced/revanced-patches/issues/6071)) ([f03256c](f03256c471))
* **YouTube - Spoof video streams:** Do not allow VR AV1 if "Force AVC" is enabled ([7afeaeb](7afeaebb5c))
* **YouTube - Spoof video streams:** Resolve playback dropping frames ([#6051](https://github.com/ReVanced/revanced-patches/issues/6051)) ([a62ee43](a62ee43441))
* **YouTube Music - GmsCore support:** Handle sharing links to certain apps such as Instagram ([#6026](https://github.com/ReVanced/revanced-patches/issues/6026)) ([328234f](328234f39a))
* **YouTube Music - Hide cast button:** Fix patching error ([28799a5](28799a548a))
* **YouTube Music - Hide cast button:** Resolve button not hiding ([7817885](7817885cff))
* **YouTube:** Resolve UI components not hiding for some users ([#6054](https://github.com/ReVanced/revanced-patches/issues/6054)) ([6b26346](6b26346914))

### Features

* **Custom branding:** Add in-app settings to change icon and name ([#6059](https://github.com/ReVanced/revanced-patches/issues/6059)) ([a50f3b5](a50f3b5177))
* **Instagram:** Add `Custom share domain` patch ([#5998](https://github.com/ReVanced/revanced-patches/issues/5998)) ([20c4131](20c413120b))
* **Instagram:** Add `Enable developer menu` patch ([#6043](https://github.com/ReVanced/revanced-patches/issues/6043)) ([2154d89](2154d89242))
* **Instagram:** Add `Open links externally` patch ([#6012](https://github.com/ReVanced/revanced-patches/issues/6012)) ([08e8ead](08e8ead04f))
* **Instagram:** Add `Sanitize sharing links` patch ([#5986](https://github.com/ReVanced/revanced-patches/issues/5986)) ([963a4ef](963a4ef43f))
* **Viber:** Add `Hide navigation buttons` patch ([#5991](https://github.com/ReVanced/revanced-patches/issues/5991)) ([5cb46c4](5cb46c4e91))
* **YouTube Music:** Add `Custom branding` patch ([#6007](https://github.com/ReVanced/revanced-patches/issues/6007)) ([4c8b56f](4c8b56f546))
* **YouTube Music:** Add `Force original audio` patch ([#6036](https://github.com/ReVanced/revanced-patches/issues/6036)) ([d0d53d1](d0d53d109e))
2025-10-08 06:01:45 +00:00
LisoUseInAIKyrios
143dcef2b8
chore: Merge branch dev to main (#6015) 2025-10-08 09:57:48 +04:00
github-actions[bot]
dbfc5be464
chore: Sync translations (#6078) 2025-10-08 09:54:53 +04:00
LisoUseInAIKyrios
0fe545cad6 chore: Add links to the ReVanced brand guidelines 2025-10-08 09:47:27 +04:00
semantic-release-bot
feca17be68 chore: Release v5.42.0-dev.19 [skip ci]
# [5.42.0-dev.19](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.18...v5.42.0-dev.19) (2025-10-07)

### Bug Fixes

* **YouTube - Spoof video streams:** Do not allow VR AV1 if "Force AVC" is enabled ([7afeaeb](7afeaebb5c))
2025-10-07 20:37:44 +00:00
LisoUseInAIKyrios
7afeaebb5c fix(YouTube - Spoof video streams): Do not allow VR AV1 if "Force AVC" is enabled 2025-10-08 00:34:45 +04:00
github-actions[bot]
60a581a632
chore: Sync translations (#6077) 2025-10-08 00:30:56 +04:00
LisoUseInAIKyrios
104d096ada chore: Change brand name to untranslatable 2025-10-07 23:53:51 +04:00
semantic-release-bot
19dcbd8efb chore: Release v5.42.0-dev.18 [skip ci]
# [5.42.0-dev.18](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.17...v5.42.0-dev.18) (2025-10-07)

### Features

* **Custom branding:** Add in-app settings to change icon and name ([#6059](https://github.com/ReVanced/revanced-patches/issues/6059)) ([a50f3b5](a50f3b5177))
2025-10-07 19:25:25 +00:00
MarcaD
a50f3b5177
feat(Custom branding): Add in-app settings to change icon and name (#6059)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2025-10-07 23:21:12 +04:00
semantic-release-bot
64d22a9c31 chore: Release v5.42.0-dev.17 [skip ci]
# [5.42.0-dev.17](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.16...v5.42.0-dev.17) (2025-10-07)

### Bug Fixes

* **YouTube - Force original audio:** Change patch to default on ([#6070](https://github.com/ReVanced/revanced-patches/issues/6070)) ([bd4ba2d](bd4ba2dae8))
2025-10-07 15:46:50 +00:00
LisoUseInAIKyrios
bd4ba2dae8
fix(YouTube - Force original audio): Change patch to default on (#6070) 2025-10-07 19:41:32 +04:00
github-actions[bot]
f51b260d1d
chore: Sync translations (#6073) 2025-10-07 19:40:18 +04:00
LisoUseInAIKyrios
63be54dd09 chore: Remove unneeded binary compatibility for code that was never released to main 2025-10-07 19:39:54 +04:00
semantic-release-bot
bb222d7a26 chore: Release v5.42.0-dev.16 [skip ci]
# [5.42.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.15...v5.42.0-dev.16) (2025-10-07)

### Bug Fixes

* **YouTube - Spoof video streams:** Add "Allow Android VR AV1" setting ([#6071](https://github.com/ReVanced/revanced-patches/issues/6071)) ([f03256c](f03256c471))
2025-10-07 15:19:06 +00:00
LisoUseInAIKyrios
f03256c471
fix(YouTube - Spoof video streams): Add "Allow Android VR AV1" setting (#6071) 2025-10-07 19:15:37 +04:00
semantic-release-bot
fe16433f20 chore: Release v5.42.0-dev.15 [skip ci]
# [5.42.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.14...v5.42.0-dev.15) (2025-10-07)

### Features

* **Instagram:** Add `Enable developer menu` patch ([#6043](https://github.com/ReVanced/revanced-patches/issues/6043)) ([2154d89](2154d89242))
2025-10-07 12:42:11 +00:00
brosssh
2154d89242
feat(Instagram): Add Enable developer menu patch (#6043) 2025-10-07 16:37:20 +04:00
semantic-release-bot
277a8b6b47 chore: Release v5.42.0-dev.14 [skip ci]
# [5.42.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.13...v5.42.0-dev.14) (2025-10-07)

### Features

* **Instagram:** Add `Custom share domain` patch ([#5998](https://github.com/ReVanced/revanced-patches/issues/5998)) ([20c4131](20c413120b))
2025-10-07 11:45:19 +00:00
brosssh
20c413120b
feat(Instagram): Add Custom share domain patch (#5998) 2025-10-07 15:40:37 +04:00
semantic-release-bot
5ed092bb7d chore: Release v5.42.0-dev.13 [skip ci]
# [5.42.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.12...v5.42.0-dev.13) (2025-10-07)

### Bug Fixes

* **Spotify:** Change `Hide Create button` patch to default off ([#6067](https://github.com/ReVanced/revanced-patches/issues/6067)) ([19949e1](19949e1695))
2025-10-07 07:14:51 +00:00
Dawid Krajcarz
19949e1695
fix(Spotify): Change Hide Create button patch to default off (#6067) 2025-10-07 11:11:41 +04:00
github-actions[bot]
ec0acc0f13
chore: Sync translations (#6069) 2025-10-07 11:11:18 +04:00
LisoUseInAIKyrios
a30a849e6e
refactor: Extract shared patch names/descriptions (#6056) 2025-10-07 01:15:03 +04:00
semantic-release-bot
603025a122 chore: Release v5.42.0-dev.12 [skip ci]
# [5.42.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.11...v5.42.0-dev.12) (2025-10-03)

### Bug Fixes

* **Custom branding:** Update ReVanced logo ([#6049](https://github.com/ReVanced/revanced-patches/issues/6049)) ([9441e7a](9441e7acb4))

### Features

* **Instagram:** Add `Sanitize sharing links` patch ([#5986](https://github.com/ReVanced/revanced-patches/issues/5986)) ([963a4ef](963a4ef43f))
2025-10-03 07:25:03 +00:00
MarcaD
9441e7acb4
fix(Custom branding): Update ReVanced logo (#6049) 2025-10-03 11:19:27 +04:00
brosssh
963a4ef43f
feat(Instagram): Add Sanitize sharing links patch (#5986)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2025-10-03 11:19:01 +04:00
semantic-release-bot
0acba30245 chore: Release v5.42.0-dev.11 [skip ci]
# [5.42.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.10...v5.42.0-dev.11) (2025-10-03)

### Bug Fixes

* **YouTube:** Resolve UI components not hiding for some users ([#6054](https://github.com/ReVanced/revanced-patches/issues/6054)) ([6b26346](6b26346914))
2025-10-03 06:57:20 +00:00
LisoUseInAIKyrios
6b26346914
fix(YouTube): Resolve UI components not hiding for some users (#6054) 2025-10-03 10:54:44 +04:00
github-actions[bot]
b1511c732d
chore: Sync translations (#6055) 2025-10-03 10:53:07 +04:00
semantic-release-bot
26117e744c chore: Release v5.42.0-dev.10 [skip ci]
# [5.42.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.9...v5.42.0-dev.10) (2025-10-02)

### Bug Fixes

* **YouTube - Spoof video streams:** Resolve playback dropping frames ([#6051](https://github.com/ReVanced/revanced-patches/issues/6051)) ([a62ee43](a62ee43441))
2025-10-02 20:09:02 +00:00
LisoUseInAIKyrios
a62ee43441
fix(YouTube - Spoof video streams): Resolve playback dropping frames (#6051) 2025-10-03 00:05:23 +04:00
LisoUseInAIKyrios
6a799110d7 refactor(YouTube - Spoof video streams): Add 'supportsMultiAudioTracks' field 2025-10-01 22:37:10 +04:00
dependabot[bot]
aec17b93f7
chore(deps): Bump com.google.guava:guava from 33.4.0-jre to 33.5.0-jre (#6042) 2025-10-01 22:18:24 +04:00
dependabot[bot]
e7a1706be4
chore(deps): Bump actions/setup-node from 4 to 5 (#6038) 2025-10-01 22:16:40 +04:00
dependabot[bot]
9469604fe0
chore(deps-dev): Bump semantic-release from 24.2.7 to 24.2.9 (#6040) 2025-10-01 22:15:52 +04:00
semantic-release-bot
1a3a12df1a chore: Release v5.42.0-dev.9 [skip ci]
# [5.42.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.8...v5.42.0-dev.9) (2025-10-01)

### Bug Fixes

* **Custom branding:** Update ReVanced logo sizing ([#6029](https://github.com/ReVanced/revanced-patches/issues/6029)) ([ae4b947](ae4b9474d3))
2025-10-01 17:33:14 +00:00
MarcaD
ae4b9474d3
fix(Custom branding): Update ReVanced logo sizing (#6029) 2025-10-01 21:29:05 +04:00
github-actions[bot]
83ccd9d3f1
chore: Sync translations (#6037) 2025-10-01 19:04:51 +04:00
semantic-release-bot
526c7c05e2 chore: Release v5.42.0-dev.8 [skip ci]
# [5.42.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.7...v5.42.0-dev.8) (2025-10-01)

### Bug Fixes

* **YouTube - Force original language:** Resolve some videos using Swedish audio track ([9d67316](9d6731660b))

### Features

* **YouTube Music:** Add `Force original audio` patch ([#6036](https://github.com/ReVanced/revanced-patches/issues/6036)) ([d0d53d1](d0d53d109e))
2025-10-01 15:04:39 +00:00
LisoUseInAIKyrios
d0d53d109e
feat(YouTube Music): Add Force original audio patch (#6036) 2025-10-01 18:59:16 +04:00
LisoUseInAIKyrios
9d6731660b fix(YouTube - Force original language): Resolve some videos using Swedish audio track 2025-10-01 18:57:53 +04:00
semantic-release-bot
5a7e199162 chore: Release v5.42.0-dev.7 [skip ci]
# [5.42.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.6...v5.42.0-dev.7) (2025-10-01)

### Features

* **Instagram:** Add `Open links externally` patch ([#6012](https://github.com/ReVanced/revanced-patches/issues/6012)) ([08e8ead](08e8ead04f))
2025-10-01 06:25:01 +00:00
LisoUseInAIKyrios
0c662c8e3b chore(deps): Bump actions/checkout from 4 to 5 2025-10-01 10:19:09 +04:00
Swakshan
08e8ead04f
feat(Instagram): Add Open links externally patch (#6012) 2025-10-01 10:17:19 +04:00
semantic-release-bot
d238a42708 chore: Release v5.42.0-dev.6 [skip ci]
# [5.42.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.5...v5.42.0-dev.6) (2025-09-30)

### Bug Fixes

* **X / Twitter:** Remove non functional and obsolete patch `Open links with app chooser` ([#6033](https://github.com/ReVanced/revanced-patches/issues/6033)) ([673609c](673609c2aa))
2025-09-30 20:09:49 +00:00
LisoUseInAIKyrios
673609c2aa
fix(X / Twitter): Remove non functional and obsolete patch Open links with app chooser (#6033) 2025-10-01 00:06:40 +04:00
github-actions[bot]
5f1a485e8f
chore: Sync translations (#6034) 2025-10-01 00:06:22 +04:00
LisoUseInAIKyrios
6961babee9 refactor(YouTube - Check watch history domain name resolution): Do not show redundant dialog cancel button 2025-09-30 12:11:06 +04:00
semantic-release-bot
328c9b6bbe chore: Release v5.42.0-dev.5 [skip ci]
# [5.42.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.4...v5.42.0-dev.5) (2025-09-28)

### Features

* **YouTube Music:** Add `Custom branding` patch ([#6007](https://github.com/ReVanced/revanced-patches/issues/6007)) ([4c8b56f](4c8b56f546))
2025-09-28 11:30:51 +00:00
MarcaD
4c8b56f546
feat(YouTube Music): Add Custom branding patch (#6007)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2025-09-28 15:26:12 +04:00
semantic-release-bot
1754023dd6 chore: Release v5.42.0-dev.4 [skip ci]
# [5.42.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.3...v5.42.0-dev.4) (2025-09-28)

### Bug Fixes

* **YouTube Music - GmsCore support:** Handle sharing links to certain apps such as Instagram ([#6026](https://github.com/ReVanced/revanced-patches/issues/6026)) ([328234f](328234f39a))
2025-09-28 10:34:39 +00:00
LisoUseInAIKyrios
328234f39a
fix(YouTube Music - GmsCore support): Handle sharing links to certain apps such as Instagram (#6026) 2025-09-28 14:31:40 +04:00
github-actions[bot]
326953cfc3
chore: Sync translations (#6028) 2025-09-28 14:30:01 +04:00
semantic-release-bot
725d5dc974 chore: Release v5.42.0-dev.3 [skip ci]
# [5.42.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.2...v5.42.0-dev.3) (2025-09-28)

### Bug Fixes

* **YouTube - Hide end screen cards:** Hide new type of end screen card ([#6027](https://github.com/ReVanced/revanced-patches/issues/6027)) ([76b0364](76b0364c5b))
2025-09-28 10:25:37 +00:00
LisoUseInAIKyrios
76b0364c5b
fix(YouTube - Hide end screen cards): Hide new type of end screen card (#6027) 2025-09-28 14:22:42 +04:00
semantic-release-bot
1cbff799ad chore: Release v5.42.0-dev.2 [skip ci]
# [5.42.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.42.0-dev.1...v5.42.0-dev.2) (2025-09-27)

### Bug Fixes

* **Instagram - Hide navigation buttons:** Resolve app startup crash ([080a226](080a226614))
2025-09-27 19:57:01 +00:00
LisoUseInAIKyrios
080a226614 fix(Instagram - Hide navigation buttons): Resolve app startup crash 2025-09-27 23:53:35 +04:00
semantic-release-bot
2b71bd80c2 chore: Release v5.42.0-dev.1 [skip ci]
# [5.42.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.41.1-dev.2...v5.42.0-dev.1) (2025-09-27)

### Features

* **Viber:** Add `Hide navigation buttons` patch ([#5991](https://github.com/ReVanced/revanced-patches/issues/5991)) ([5cb46c4](5cb46c4e91))
2025-09-27 13:02:45 +00:00
Samo Hribar
5cb46c4e91
feat(Viber): Add Hide navigation buttons patch (#5991) 2025-09-27 16:59:51 +04:00
semantic-release-bot
52c369576d chore: Release v5.41.1-dev.2 [skip ci]
## [5.41.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.41.1-dev.1...v5.41.1-dev.2) (2025-09-27)

### Bug Fixes

* **YouTube Music - Hide cast button:** Fix patching error ([28799a5](28799a548a))
2025-09-27 12:35:45 +00:00
LisoUseInAIKyrios
28799a548a fix(YouTube Music - Hide cast button): Fix patching error 2025-09-27 16:31:22 +04:00
semantic-release-bot
1c80774d79 chore: Release v5.41.1-dev.1 [skip ci]
## [5.41.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.41.0...v5.41.1-dev.1) (2025-09-27)

### Bug Fixes

* **YouTube Music - Hide cast button:** Resolve button not hiding ([7817885](7817885cff))
2025-09-27 12:24:18 +00:00
LisoUseInAIKyrios
7817885cff fix(YouTube Music - Hide cast button): Resolve button not hiding 2025-09-27 16:21:32 +04:00
LisoUseInAIKyrios
9afe9afc67 chore(YouTube): Fix patch description 2025-09-27 11:53:21 +04:00
semantic-release-bot
3a8091ae00 chore: Release v5.41.0 [skip ci]
# [5.41.0](https://github.com/ReVanced/revanced-patches/compare/v5.40.0...v5.41.0) (2025-09-27)

### Bug Fixes

* **Instagram - Hide navigation buttons:** Remove button based on name ([#5971](https://github.com/ReVanced/revanced-patches/issues/5971)) ([6fa4043](6fa404331b))
* **Instagram - Limit feed to followed profiles:** Preserve favorites feed ([#5963](https://github.com/ReVanced/revanced-patches/issues/5963)) ([ef51401](ef514017f4))
* **TikTok:** Show correct dialog restart text, use correct font color for non-dark mode ([d1a1293](d1a12930c3))
* **Twitch - Settings:** Fix missing style resources ([#5970](https://github.com/ReVanced/revanced-patches/issues/5970)) ([8c22995](8c229954d7))
* **YouTube - Hide Shorts components:** Fix "Hide preview comment" ([#5990](https://github.com/ReVanced/revanced-patches/issues/5990)) ([dd4e2cd](dd4e2cd085))
* **YouTube - Return YouTube Dislike:** Do not show error toast if API returns 401 status ([#5949](https://github.com/ReVanced/revanced-patches/issues/5949)) ([58d088a](58d088ab30))
* **YouTube - Settings:** Handle on screen back swipe gesture ([#6002](https://github.com/ReVanced/revanced-patches/issues/6002)) ([6f92b6c](6f92b6c50b))
* **YouTube - Settings:** Use an overlay to show search results ([#5806](https://github.com/ReVanced/revanced-patches/issues/5806)) ([ece8076](ece8076f7c))
* **YouTube - SponsorBlock:** Show category color dot in voting dialog menu ([4be00d0](4be00d09b7))
* **YouTube - SponsorBlock:** Show category color in create new segment menu ([#5987](https://github.com/ReVanced/revanced-patches/issues/5987)) ([ffd933c](ffd933c673))
* **YouTube - Spoof video streams:** Update client side effects summary text ([a0a62dd](a0a62ddad2))

### Features

* **Tumblr:** Add `Disable Tumblr TV` patch ([#5959](https://github.com/ReVanced/revanced-patches/issues/5959)) ([212418b](212418b8db))
* **YouTube - Hide layout components:** Add "Hide Emoji and Timestamp buttons" setting ([#5992](https://github.com/ReVanced/revanced-patches/issues/5992)) ([2b555f6](2b555f67f0))
* **YouTube - Hide layout components:** Add "Hide view count" and "Hide upload time" settings ([#5983](https://github.com/ReVanced/revanced-patches/issues/5983)) ([7a37d85](7a37d858fb))
* **YouTube - Loop video:** Add player button to change loop video state ([#5961](https://github.com/ReVanced/revanced-patches/issues/5961)) ([dfb5407](dfb5407e67))
* **YouTube - Spoof app version:** Add spoof target `20.05.46` that fixes transcript functionality ([5823f0e](5823f0e982))
* **YouTube Music:** Add `Check watch history domain name resolution` ([#5979](https://github.com/ReVanced/revanced-patches/issues/5979)) ([8af70fe](8af70fe2d1))
* **YouTube Music:** Add `Sanitize sharing links` patch ([#5952](https://github.com/ReVanced/revanced-patches/issues/5952)) ([45c1ee8](45c1ee8a12))
* **YouTube Music:** Add `Theme` patch ([#5984](https://github.com/ReVanced/revanced-patches/issues/5984)) ([3bd76d6](3bd76d60d6))
* **YouTube:** Add `Disable video codecs` patch ([#5981](https://github.com/ReVanced/revanced-patches/issues/5981)) ([bfbffbd](bfbffbd1f5))
2025-09-27 07:21:33 +00:00
LisoUseInAIKyrios
6192ece114
chore: Merge branch dev to main (#5950) 2025-09-27 11:17:09 +04:00
github-actions[bot]
5d9971444e
chore: Sync translations (#6014) 2025-09-27 11:15:04 +04:00
semantic-release-bot
cdfa75dd5a chore: Release v5.41.0-dev.18 [skip ci]
# [5.41.0-dev.18](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.17...v5.41.0-dev.18) (2025-09-26)

### Bug Fixes

* **YouTube - Settings:** Handle on screen back swipe gesture ([#6002](https://github.com/ReVanced/revanced-patches/issues/6002)) ([6f92b6c](6f92b6c50b))
2025-09-26 15:05:03 +00:00
LisoUseInAIKyrios
6f92b6c50b
fix(YouTube - Settings): Handle on screen back swipe gesture (#6002) 2025-09-26 19:00:12 +04:00
github-actions[bot]
1e023fa1f3
chore: Sync translations (#6010) 2025-09-26 18:59:48 +04:00
semantic-release-bot
00477bfebc chore: Release v5.41.0-dev.17 [skip ci]
# [5.41.0-dev.17](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.16...v5.41.0-dev.17) (2025-09-26)

### Bug Fixes

* **YouTube - SponsorBlock:** Show category color dot in voting dialog menu ([4be00d0](4be00d09b7))
2025-09-26 08:28:43 +00:00
LisoUseInAIKyrios
4be00d09b7 fix(YouTube - SponsorBlock): Show category color dot in voting dialog menu 2025-09-26 12:25:17 +04:00
github-actions[bot]
50aca3314f
chore: Sync translations (#6005) 2025-09-26 12:24:08 +04:00
LisoUseInAIKyrios
15a7e540de
refactor(YouTube - Miniplayer): Change ReVanced settings that are now YouTube default on into "Disable" style settings (#6003) 2025-09-26 12:14:20 +04:00
semantic-release-bot
041f7e0140 chore: Release v5.41.0-dev.16 [skip ci]
# [5.41.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.15...v5.41.0-dev.16) (2025-09-26)

### Features

* **YouTube Music:** Add `Theme` patch ([#5984](https://github.com/ReVanced/revanced-patches/issues/5984)) ([3bd76d6](3bd76d60d6))
2025-09-26 05:33:20 +00:00
MarcaD
3bd76d60d6
feat(YouTube Music): Add Theme patch (#5984)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-09-26 09:29:11 +04:00
github-actions[bot]
1587178ff8
chore: Sync translations (#6001) 2025-09-26 09:28:45 +04:00
semantic-release-bot
8a69240d66 chore: Release v5.41.0-dev.15 [skip ci]
# [5.41.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.14...v5.41.0-dev.15) (2025-09-25)

### Features

* **YouTube - Hide layout components:** Add "Hide view count" and "Hide upload time" settings ([#5983](https://github.com/ReVanced/revanced-patches/issues/5983)) ([7a37d85](7a37d858fb))
2025-09-25 12:47:40 +00:00
viSapio
7a37d858fb
feat(YouTube - Hide layout components): Add "Hide view count" and "Hide upload time" settings (#5983) 2025-09-25 16:43:59 +04:00
github-actions[bot]
0ed7067459
chore: Sync translations (#5996) 2025-09-25 16:38:32 +04:00
LisoUseInAIKyrios
6102644194 chore(YouTube): Adjust patch strings 2025-09-25 00:32:15 +04:00
semantic-release-bot
a89556a017 chore: Release v5.41.0-dev.14 [skip ci]
# [5.41.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.13...v5.41.0-dev.14) (2025-09-24)

### Features

* **YouTube - Hide layout components:** Add "Hide Emoji and Timestamp buttons" setting ([#5992](https://github.com/ReVanced/revanced-patches/issues/5992)) ([2b555f6](2b555f67f0))
2025-09-24 20:21:22 +00:00
ILoveOpenSourceApplications
2b555f67f0
feat(YouTube - Hide layout components): Add "Hide Emoji and Timestamp buttons" setting (#5992) 2025-09-25 00:17:08 +04:00
semantic-release-bot
fb87199514 chore: Release v5.41.0-dev.13 [skip ci]
# [5.41.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.12...v5.41.0-dev.13) (2025-09-24)

### Bug Fixes

* **YouTube - Hide Shorts components:** Fix "Hide preview comment" ([#5990](https://github.com/ReVanced/revanced-patches/issues/5990)) ([dd4e2cd](dd4e2cd085))
2025-09-24 19:44:03 +00:00
ILoveOpenSourceApplications
dd4e2cd085
fix(YouTube - Hide Shorts components): Fix "Hide preview comment" (#5990) 2025-09-24 23:41:15 +04:00
semantic-release-bot
fadc66816d chore: Release v5.41.0-dev.12 [skip ci]
# [5.41.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.11...v5.41.0-dev.12) (2025-09-24)

### Bug Fixes

* **YouTube - SponsorBlock:** Show category color in create new segment menu ([#5987](https://github.com/ReVanced/revanced-patches/issues/5987)) ([ffd933c](ffd933c673))
2025-09-24 13:53:25 +00:00
MarcaD
ffd933c673
fix(YouTube - SponsorBlock): Show category color in create new segment menu (#5987) 2025-09-24 17:50:46 +04:00
github-actions[bot]
69883530b7
chore: Sync translations (#5989) 2025-09-24 17:49:49 +04:00
LisoUseInAIKyrios
39971291f3
chore: Fix typo 2025-09-24 15:56:29 +04:00
LisoUseInAIKyrios
51facf9321 chore(YouTube): Adjust UI dialog message 2025-09-24 09:46:37 +04:00
semantic-release-bot
b83d41ca88 chore: Release v5.41.0-dev.11 [skip ci]
# [5.41.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.10...v5.41.0-dev.11) (2025-09-23)

### Features

* **YouTube:** Add `Disable video codecs` patch ([#5981](https://github.com/ReVanced/revanced-patches/issues/5981)) ([bfbffbd](bfbffbd1f5))
2025-09-23 18:10:52 +00:00
LisoUseInAIKyrios
bfbffbd1f5
feat(YouTube): Add Disable video codecs patch (#5981) 2025-09-23 22:06:02 +04:00
semantic-release-bot
ee4755646b chore: Release v5.41.0-dev.10 [skip ci]
# [5.41.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.9...v5.41.0-dev.10) (2025-09-23)

### Bug Fixes

* **TikTok:** Show correct dialog restart text, use correct font color for non-dark mode ([d1a1293](d1a12930c3))
2025-09-23 17:46:05 +00:00
LisoUseInAIKyrios
d1a12930c3 fix(TikTok): Show correct dialog restart text, use correct font color for non-dark mode 2025-09-23 21:43:04 +04:00
semantic-release-bot
dfac836a8c chore: Release v5.41.0-dev.9 [skip ci]
# [5.41.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.8...v5.41.0-dev.9) (2025-09-23)

### Bug Fixes

* **Instagram - Hide navigation buttons:** Remove button based on name ([#5971](https://github.com/ReVanced/revanced-patches/issues/5971)) ([6fa4043](6fa404331b))
2025-09-23 10:28:29 +00:00
brosssh
6fa404331b
fix(Instagram - Hide navigation buttons): Remove button based on name (#5971) 2025-09-23 12:25:36 +02:00
semantic-release-bot
8bcb95adcd chore: Release v5.41.0-dev.8 [skip ci]
# [5.41.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.7...v5.41.0-dev.8) (2025-09-23)

### Features

* **YouTube Music:** Add `Check watch history domain name resolution` ([#5979](https://github.com/ReVanced/revanced-patches/issues/5979)) ([8af70fe](8af70fe2d1))
2025-09-23 09:38:14 +00:00
LisoUseInAIKyrios
8af70fe2d1
feat(YouTube Music): Add Check watch history domain name resolution (#5979) 2025-09-23 13:34:00 +04:00
semantic-release-bot
191b9169ff chore: Release v5.41.0-dev.7 [skip ci]
# [5.41.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.6...v5.41.0-dev.7) (2025-09-23)

### Features

* **Tumblr:** Add `Disable Tumblr TV` patch ([#5959](https://github.com/ReVanced/revanced-patches/issues/5959)) ([212418b](212418b8db))
2025-09-23 06:24:06 +00:00
Temm
212418b8db
feat(Tumblr): Add Disable Tumblr TV patch (#5959) 2025-09-23 10:19:58 +04:00
github-actions[bot]
7dbc744be0
chore: Sync translations (#5978) 2025-09-23 10:18:20 +04:00
LisoUseInAIKyrios
150a3e7c60 chore(YouTube Music - GmsCore support): Add missing supported versions 2025-09-23 10:17:25 +04:00
semantic-release-bot
5027943470 chore: Release v5.41.0-dev.6 [skip ci]
# [5.41.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.5...v5.41.0-dev.6) (2025-09-22)

### Features

* **YouTube - Spoof app version:** Add spoof target `20.05.46` that fixes transcript functionality ([5823f0e](5823f0e982))
2025-09-22 18:04:18 +00:00
github-actions[bot]
fa9e590b3a
chore: Sync translations (#5972) 2025-09-22 22:01:33 +04:00
LisoUseInAIKyrios
5823f0e982 feat(YouTube - Spoof app version): Add spoof target 20.05.46 that fixes transcript functionality 2025-09-22 22:01:14 +04:00
LisoUseInAIKyrios
f506a67e4a chore(YouTube): Drop 19.43.41
Playback speed has a patch error. Don't want to fix. Most users want the latest or the oldest app target, and don't care about anything in-between.
2025-09-22 21:57:42 +04:00
semantic-release-bot
ed6e1155f2 chore: Release v5.41.0-dev.5 [skip ci]
# [5.41.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.4...v5.41.0-dev.5) (2025-09-22)

### Bug Fixes

* **Twitch - Settings:** Fix missing style resources ([#5970](https://github.com/ReVanced/revanced-patches/issues/5970)) ([8c22995](8c229954d7))
2025-09-22 16:05:55 +00:00
MarcaD
8c229954d7
fix(Twitch - Settings): Fix missing style resources (#5970) 2025-09-22 20:02:34 +04:00
semantic-release-bot
c5eb88bbf6 chore: Release v5.41.0-dev.4 [skip ci]
# [5.41.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.3...v5.41.0-dev.4) (2025-09-22)

### Bug Fixes

* **Instagram - Limit feed to followed profiles:** Preserve favorites feed ([#5963](https://github.com/ReVanced/revanced-patches/issues/5963)) ([ef51401](ef514017f4))
2025-09-22 09:35:02 +00:00
brosssh
ef514017f4
fix(Instagram - Limit feed to followed profiles): Preserve favorites feed (#5963) 2025-09-22 13:32:30 +04:00
github-actions[bot]
c72d99518c
chore: Sync translations (#5968) 2025-09-22 13:32:12 +04:00
semantic-release-bot
772df6eb73 chore: Release v5.41.0-dev.3 [skip ci]
# [5.41.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.2...v5.41.0-dev.3) (2025-09-22)

### Features

* **YouTube - Loop video:** Add player button to change loop video state ([#5961](https://github.com/ReVanced/revanced-patches/issues/5961)) ([dfb5407](dfb5407e67))
2025-09-22 08:57:43 +00:00
MarcaD
dfb5407e67
feat(YouTube - Loop video): Add player button to change loop video state (#5961) 2025-09-22 12:54:09 +04:00
semantic-release-bot
6d5f6ecdd2 chore: Release v5.41.0-dev.2 [skip ci]
# [5.41.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.41.0-dev.1...v5.41.0-dev.2) (2025-09-21)

### Bug Fixes

* **YouTube - Spoof video streams:** Update client side effects summary text ([a0a62dd](a0a62ddad2))
2025-09-21 19:45:41 +00:00
LisoUseInAIKyrios
a0a62ddad2 fix(YouTube - Spoof video streams): Update client side effects summary text 2025-09-21 23:41:38 +04:00
github-actions[bot]
512e50e892
chore: Sync translations (#5955) 2025-09-21 23:03:49 +04:00
semantic-release-bot
a2304c3310 chore: Release v5.41.0-dev.1 [skip ci]
# [5.41.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.40.1-dev.1...v5.41.0-dev.1) (2025-09-21)

### Features

* **YouTube Music:** Add `Sanitize sharing links` patch ([#5952](https://github.com/ReVanced/revanced-patches/issues/5952)) ([45c1ee8](45c1ee8a12))
2025-09-21 17:19:16 +00:00
LisoUseInAIKyrios
45c1ee8a12
feat(YouTube Music): Add Sanitize sharing links patch (#5952) 2025-09-21 21:14:19 +04:00
github-actions[bot]
74cdf550a5
chore: Sync translations (#5953) 2025-09-21 21:14:03 +04:00
semantic-release-bot
c36ea22975 chore: Release v5.40.1-dev.1 [skip ci]
## [5.40.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.40.0...v5.40.1-dev.1) (2025-09-21)

### Bug Fixes

* **YouTube - Return YouTube Dislike:** Do not show error toast if API returns 401 status ([#5949](https://github.com/ReVanced/revanced-patches/issues/5949)) ([58d088a](58d088ab30))
* **YouTube - Settings:** Use an overlay to show search results ([#5806](https://github.com/ReVanced/revanced-patches/issues/5806)) ([ece8076](ece8076f7c))
2025-09-21 13:25:05 +00:00
LisoUseInAIKyrios
58d088ab30
fix(YouTube - Return YouTube Dislike): Do not show error toast if API returns 401 status (#5949) 2025-09-21 17:20:13 +04:00
MarcaD
ece8076f7c
fix(YouTube - Settings): Use an overlay to show search results (#5806)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2025-09-21 17:19:29 +04:00
semantic-release-bot
ebb446b22a chore: Release v5.40.0 [skip ci]
# [5.40.0](https://github.com/ReVanced/revanced-patches/compare/v5.39.0...v5.40.0) (2025-09-21)

### Bug Fixes

* **Instagram - Limit feed to followed profiles:** Change patch to default off ([767f1e3](767f1e3695))
* **Spoof video streams:** Resolve occasional playback stuttering ([5c7c8b5](5c7c8b5364))
* **YouTube - Force original audio:** Show UI setting summary if spoofing to Android Studio ([b7026b7](b7026b7086))
* **YouTube - Spoof video streams:** Add "Force original audio" disclaimer for Android Studio client ([f97d332](f97d33206b))
* **YouTube - Spoof video streams:** Add stream audio selector disclaimer for Android Studio client ([a8a4107](a8a410708d))

### Features

* **Instagram:** Add `Limit feed to followed profiles` patch ([#5908](https://github.com/ReVanced/revanced-patches/issues/5908)) ([8ba9a19](8ba9a19ade))
* **Viber - Hide ads:** Support latest app target ([#5863](https://github.com/ReVanced/revanced-patches/issues/5863)) ([e6cce85](e6cce85541))
* **YouTube - Hide video action buttons:** Add "Hide comments" button ([db796fb](db796fb883))
* **YouTube Music:** Add `Enable debugging` patch ([#5939](https://github.com/ReVanced/revanced-patches/issues/5939)) ([418f594](418f5945c2))
* **YouTube Music:** Add `Hide cast button` and `Navigation bar` patches ([#5934](https://github.com/ReVanced/revanced-patches/issues/5934)) ([651d358](651d358096))
* **YouTube Music:** Support version `8.10.52` ([#5941](https://github.com/ReVanced/revanced-patches/issues/5941)) ([01c0f1b](01c0f1bd1a))
* **YouTube:** Support version `20.14.43` ([#5940](https://github.com/ReVanced/revanced-patches/issues/5940)) ([f7f4a1b](f7f4a1b0f0))
2025-09-21 06:58:02 +00:00
LisoUseInAIKyrios
b44a369f59
chore: Merge branch dev to main (#5916) 2025-09-21 10:54:28 +04:00
github-actions[bot]
092a72c774
chore: Sync translations (#5946) 2025-09-21 10:52:29 +04:00
LisoUseInAIKyrios
6330773bfc chore(YouTube Music): Add missing target version 2025-09-21 10:50:35 +04:00
LisoUseInAIKyrios
43dbb4710b
docs: Add new issue links to the FAQ and troubleshooting guide (#5929) 2025-09-21 10:42:02 +04:00
LisoUseInAIKyrios
966727ca2d chore(YouTube Music): Use string language similar to YouTube 2025-09-20 23:31:01 +04:00
semantic-release-bot
1f371c8156 chore: Release v5.40.0-dev.11 [skip ci]
# [5.40.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.10...v5.40.0-dev.11) (2025-09-20)

### Bug Fixes

* **YouTube - Spoof video streams:** Add stream audio selector disclaimer for Android Studio client ([a8a4107](a8a410708d))
2025-09-20 19:20:13 +00:00
LisoUseInAIKyrios
a8a410708d fix(YouTube - Spoof video streams): Add stream audio selector disclaimer for Android Studio client 2025-09-20 23:15:41 +04:00
semantic-release-bot
7651ef0881 chore: Release v5.40.0-dev.10 [skip ci]
# [5.40.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.9...v5.40.0-dev.10) (2025-09-20)

### Bug Fixes

* **YouTube - Spoof video streams:** Add "Force original audio" disclaimer for Android Studio client ([f97d332](f97d33206b))
2025-09-20 18:13:06 +00:00
LisoUseInAIKyrios
f97d33206b fix(YouTube - Spoof video streams): Add "Force original audio" disclaimer for Android Studio client 2025-09-20 22:08:50 +04:00
semantic-release-bot
3d986e6716 chore: Release v5.40.0-dev.9 [skip ci]
# [5.40.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.8...v5.40.0-dev.9) (2025-09-20)

### Features

* **YouTube Music:** Support version `8.10.52` ([#5941](https://github.com/ReVanced/revanced-patches/issues/5941)) ([01c0f1b](01c0f1bd1a))
2025-09-20 16:12:57 +00:00
LisoUseInAIKyrios
01c0f1bd1a
feat(YouTube Music): Support version 8.10.52 (#5941) 2025-09-20 20:09:52 +04:00
github-actions[bot]
4178e8a64f
chore: Sync translations (#5943) 2025-09-20 20:09:07 +04:00
semantic-release-bot
7e1bb8f3c7 chore: Release v5.40.0-dev.8 [skip ci]
# [5.40.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.7...v5.40.0-dev.8) (2025-09-20)

### Features

* **YouTube:** Support version `20.14.43` ([#5940](https://github.com/ReVanced/revanced-patches/issues/5940)) ([f7f4a1b](f7f4a1b0f0))
2025-09-20 15:33:42 +00:00
LisoUseInAIKyrios
f7f4a1b0f0
feat(YouTube): Support version 20.14.43 (#5940) 2025-09-20 19:30:05 +04:00
semantic-release-bot
e89660d234 chore: Release v5.40.0-dev.7 [skip ci]
# [5.40.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.6...v5.40.0-dev.7) (2025-09-20)

### Features

* **YouTube - Hide video action buttons:** Add "Hide comments" button ([db796fb](db796fb883))
2025-09-20 15:03:00 +00:00
LisoUseInAIKyrios
db796fb883 feat(YouTube - Hide video action buttons): Add "Hide comments" button
Button is only shown when using YouTube 20.14+ and the video information area is collapsed to a compact state
2025-09-20 19:00:00 +04:00
LisoUseInAIKyrios
6bb8bad8d7 chore(YouTube Music): Fix fingerprint typo, change hide cast button to default off 2025-09-20 18:03:41 +04:00
semantic-release-bot
aa1fb41ad8 chore: Release v5.40.0-dev.6 [skip ci]
# [5.40.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.5...v5.40.0-dev.6) (2025-09-20)

### Features

* **YouTube Music:** Add `Enable debugging` patch ([#5939](https://github.com/ReVanced/revanced-patches/issues/5939)) ([418f594](418f5945c2))
2025-09-20 12:37:33 +00:00
LisoUseInAIKyrios
418f5945c2
feat(YouTube Music): Add Enable debugging patch (#5939) 2025-09-20 16:33:03 +04:00
github-actions[bot]
e26c971067
chore: Sync translations (#5942) 2025-09-20 16:32:50 +04:00
semantic-release-bot
eb1d07fd98 chore: Release v5.40.0-dev.5 [skip ci]
# [5.40.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.4...v5.40.0-dev.5) (2025-09-20)

### Features

* **YouTube Music:** Add `Hide cast button` and `Navigation bar` patches ([#5934](https://github.com/ReVanced/revanced-patches/issues/5934)) ([651d358](651d358096))
2025-09-20 11:30:04 +00:00
MarcaD
651d358096
feat(YouTube Music): Add Hide cast button and Navigation bar patches (#5934) 2025-09-20 15:26:14 +04:00
semantic-release-bot
0d15c5f338 chore: Release v5.40.0-dev.4 [skip ci]
# [5.40.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.3...v5.40.0-dev.4) (2025-09-20)

### Bug Fixes

* **Spoof video streams:** Resolve occasional playback stuttering ([5c7c8b5](5c7c8b5364))
2025-09-20 10:39:29 +00:00
LisoUseInAIKyrios
5c7c8b5364 fix(Spoof video streams): Resolve occasional playback stuttering
Code adapted from:
2cf9db66ac
50d9c60374
2025-09-20 14:36:15 +04:00
semantic-release-bot
729997ec3e chore: Release v5.40.0-dev.3 [skip ci]
# [5.40.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.2...v5.40.0-dev.3) (2025-09-19)

### Bug Fixes

* **Instagram - Limit feed to followed profiles:** Change patch to default off ([767f1e3](767f1e3695))
2025-09-19 15:43:08 +00:00
LisoUseInAIKyrios
767f1e3695
fix(Instagram - Limit feed to followed profiles): Change patch to default off
Co-authored-by: brosssh <44944126+brosssh@users.noreply.github.com>
2025-09-19 19:40:32 +04:00
github-actions[bot]
7857876551
chore: Sync translations (#5933) 2025-09-19 19:40:03 +04:00
semantic-release-bot
04057c6e56 chore: Release v5.40.0-dev.2 [skip ci]
# [5.40.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.40.0-dev.1...v5.40.0-dev.2) (2025-09-18)

### Features

* **Instagram:** Add `Limit feed to followed profiles` patch ([#5908](https://github.com/ReVanced/revanced-patches/issues/5908)) ([8ba9a19](8ba9a19ade))
2025-09-18 06:16:27 +00:00
brosssh
8ba9a19ade
feat(Instagram): Add Limit feed to followed profiles patch (#5908) 2025-09-18 10:13:46 +04:00
LisoUseInAIKyrios
6862200a28 chore: Fix api dump 2025-09-17 23:42:11 +04:00
semantic-release-bot
dfff3d7c0a chore: Release v5.40.0-dev.1 [skip ci]
# [5.40.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.39.1-dev.1...v5.40.0-dev.1) (2025-09-17)

### Features

* **Viber - Hide ads:** Support latest app target ([#5863](https://github.com/ReVanced/revanced-patches/issues/5863)) ([e6cce85](e6cce85541))
2025-09-17 17:54:19 +00:00
Samo Hribar
e6cce85541
feat(Viber - Hide ads): Support latest app target (#5863) 2025-09-17 21:51:33 +04:00
github-actions[bot]
8502eb8eac
chore: Sync translations (#5918) 2025-09-17 21:51:15 +04:00
semantic-release-bot
0652c56d0d chore: Release v5.39.1-dev.1 [skip ci]
## [5.39.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.39.0...v5.39.1-dev.1) (2025-09-17)

### Bug Fixes

* **YouTube - Force original audio:** Show UI setting summary if spoofing to Android Studio ([b7026b7](b7026b7086))
2025-09-17 16:18:22 +00:00
LisoUseInAIKyrios
b7026b7086 fix(YouTube - Force original audio): Show UI setting summary if spoofing to Android Studio 2025-09-17 20:13:44 +04:00
semantic-release-bot
fa4f422a15 chore: Release v5.39.0 [skip ci]
# [5.39.0](https://github.com/ReVanced/revanced-patches/compare/v5.38.0...v5.39.0) (2025-09-17)

### Bug Fixes

* **YouTube - Spoof video streams:** Do not use Android Creator for livestreams ([cbe576b](cbe576bc38))
* **YouTube - Spoof video streams:** Show Android Studio in spoof stream menu ([c9f741e](c9f741e616))
* **YouTube Music - Spoof video streams:** Remove iPadOS client ([7eeffd3](7eeffd3392))

### Features

* **YouTube - Hide video action buttons:** Add "Hide Shop button" setting ([a84db7b](a84db7be7f))
2025-09-17 09:15:36 +00:00
LisoUseInAIKyrios
38e0cbd724
chore: Merge branch dev to main (#5907) 2025-09-17 13:12:21 +04:00
semantic-release-bot
0bdebd927d chore: Release v5.39.0-dev.2 [skip ci]
# [5.39.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.39.0-dev.1...v5.39.0-dev.2) (2025-09-17)

### Bug Fixes

* **YouTube - Spoof video streams:** Show Android Studio in spoof stream menu ([c9f741e](c9f741e616))
2025-09-17 09:01:12 +00:00
github-actions[bot]
3eac25cf7f
chore: Sync translations (#5914) 2025-09-17 12:56:47 +04:00
LisoUseInAIKyrios
c9f741e616 fix(YouTube - Spoof video streams): Show Android Studio in spoof stream menu 2025-09-17 12:54:52 +04:00
semantic-release-bot
cba44ccfc8 chore: Release v5.39.0-dev.1 [skip ci]
# [5.39.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.38.1-dev.2...v5.39.0-dev.1) (2025-09-17)

### Features

* **YouTube - Hide video action buttons:** Add "Hide Shop button" setting ([a84db7b](a84db7be7f))
2025-09-17 07:19:06 +00:00
LisoUseInAIKyrios
a84db7be7f feat(YouTube - Hide video action buttons): Add "Hide Shop button" setting 2025-09-17 11:14:24 +04:00
semantic-release-bot
2520129ace chore: Release v5.38.1-dev.2 [skip ci]
## [5.38.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.38.1-dev.1...v5.38.1-dev.2) (2025-09-16)

### Bug Fixes

* **YouTube Music - Spoof video streams:** Remove iPadOS client ([7eeffd3](7eeffd3392))
2025-09-16 21:49:36 +00:00
LisoUseInAIKyrios
7eeffd3392 fix(YouTube Music - Spoof video streams): Remove iPadOS client 2025-09-17 01:44:48 +04:00
LisoUseInAIKyrios
6c3391164e chore: Remove spoof stream data migration since iPadOS can cause 1 minute playback failure for users in some regions 2025-09-16 23:44:01 +04:00
semantic-release-bot
0b8b46c73e chore: Release v5.38.1-dev.1 [skip ci]
## [5.38.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.38.0...v5.38.1-dev.1) (2025-09-16)

### Bug Fixes

* **YouTube - Spoof video streams:** Do not use Android Creator for livestreams ([cbe576b](cbe576bc38))
2025-09-16 19:27:03 +00:00
LisoUseInAIKyrios
cbe576bc38 fix(YouTube - Spoof video streams): Do not use Android Creator for livestreams 2025-09-16 23:24:07 +04:00
github-actions[bot]
3a29f2a805
chore: Sync translations (#5909) 2025-09-16 23:21:01 +04:00
LisoUseInAIKyrios
50069c7e05 chore: Fix merge typo 2025-09-16 17:26:48 +04:00
semantic-release-bot
2e9c9dc244 chore: Release v5.38.0 [skip ci]
# [5.38.0](https://github.com/ReVanced/revanced-patches/compare/v5.37.0...v5.38.0) (2025-09-16)

### Bug Fixes

* **Instagram - Hide navigation buttons:** Support v397.1.0.52.81 ([#5855](https://github.com/ReVanced/revanced-patches/issues/5855)) ([f11d1ef](f11d1ef990))
* **Spoof video streams:** Remove Android TV and iOS TV clients, add experimental VisionOS, add temporary fix for `Force original audio` to work with any spoof client ([#5861](https://github.com/ReVanced/revanced-patches/issues/5861)) ([abe3943](abe3943f98))
* **YouTube - Spoof video streams:** Show settings summary if `Force original audio` is enabled ([3776dda](3776dda710))
* **YouTube Music - Spoof video streams:** Fix playback issues when using a cellular network ([fa04c8e](fa04c8eecf))
* **YouTube Music:** Use correct light/dark mode settings UI ([1475643](1475643f84))

### Features

* **Instagram:** Add `Hide explore feed` patch ([#5856](https://github.com/ReVanced/revanced-patches/issues/5856)) ([1d65887](1d65887e01))
* **YouTube - Spoof video streams:** Add iPadOS client ([2726231](2726231404))
* **YouTube Music:** Add `Settings` patch ([#5838](https://github.com/ReVanced/revanced-patches/issues/5838)) ([5e20bd8](5e20bd80f1))
2025-09-16 13:01:23 +00:00
LisoUseInAIKyrios
56166896d9
chore: Merge branch dev to main (#5857) 2025-09-16 16:57:55 +04:00
semantic-release-bot
b4c695b1d5 chore: Release v5.38.0-dev.5 [skip ci]
# [5.38.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.38.0-dev.4...v5.38.0-dev.5) (2025-09-16)

### Bug Fixes

* **YouTube Music:** Use correct light/dark mode settings UI ([1475643](1475643f84))
2025-09-16 12:34:52 +00:00
LisoUseInAIKyrios
1475643f84 fix(YouTube Music): Use correct light/dark mode settings UI 2025-09-16 16:31:04 +04:00
github-actions[bot]
9a7179f9cf
chore: Sync translations (#5906) 2025-09-16 16:29:53 +04:00
semantic-release-bot
6fb94a7a41 chore: Release v5.38.0-dev.4 [skip ci]
# [5.38.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.38.0-dev.3...v5.38.0-dev.4) (2025-09-16)

### Bug Fixes

* **YouTube - Spoof video streams:** Show settings summary if `Force original audio` is enabled ([3776dda](3776dda710))
2025-09-16 12:05:23 +00:00
LisoUseInAIKyrios
3776dda710 fix(YouTube - Spoof video streams): Show settings summary if Force original audio is enabled 2025-09-16 15:59:32 +04:00
LisoUseInAIKyrios
f88b3a5162 refactor(YouTube - Spoof video streams): Adjust preferred client order 2025-09-16 15:40:55 +04:00
semantic-release-bot
0eeaf7ad67 chore: Release v5.38.0-dev.3 [skip ci]
# [5.38.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.38.0-dev.2...v5.38.0-dev.3) (2025-09-16)

### Features

* **YouTube - Spoof video streams:** Add iPadOS client ([2726231](2726231404))
2025-09-16 11:36:54 +00:00
LisoUseInAIKyrios
2726231404 feat(YouTube - Spoof video streams): Add iPadOS client 2025-09-16 15:33:55 +04:00
github-actions[bot]
9f0558e494
chore: Sync translations (#5905) 2025-09-16 15:11:04 +04:00
semantic-release-bot
01f7bc9f8d chore: Release v5.38.0-dev.2 [skip ci]
# [5.38.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.38.0-dev.1...v5.38.0-dev.2) (2025-09-16)

### Features

* **YouTube Music:** Add `Settings` patch ([#5838](https://github.com/ReVanced/revanced-patches/issues/5838)) ([5e20bd8](5e20bd80f1))
2025-09-16 06:57:43 +00:00
MarcaD
5e20bd80f1
feat(YouTube Music): Add Settings patch (#5838)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
2025-09-16 10:53:49 +04:00
semantic-release-bot
f304c178e2 chore: Release v5.38.0-dev.1 [skip ci]
# [5.38.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.37.1-dev.3...v5.38.0-dev.1) (2025-09-15)

### Features

* **Instagram:** Add `Hide explore feed` patch ([#5856](https://github.com/ReVanced/revanced-patches/issues/5856)) ([1d65887](1d65887e01))
2025-09-15 19:30:52 +00:00
brosssh
1d65887e01
feat(Instagram): Add Hide explore feed patch (#5856) 2025-09-15 23:28:01 +04:00
github-actions[bot]
6b6eea8414
chore: Sync translations (#5864) 2025-09-15 23:26:07 +04:00
semantic-release-bot
1db131e90e chore: Release v5.37.1-dev.3 [skip ci]
## [5.37.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.37.1-dev.2...v5.37.1-dev.3) (2025-09-15)

### Bug Fixes

* **Spoof video streams:** Remove Android TV and iOS TV clients, add experimental VisionOS, add temporary fix for `Force original audio` to work with any spoof client ([#5861](https://github.com/ReVanced/revanced-patches/issues/5861)) ([abe3943](abe3943f98))
2025-09-15 17:02:01 +00:00
LisoUseInAIKyrios
abe3943f98
fix(Spoof video streams): Remove Android TV and iOS TV clients, add experimental VisionOS, add temporary fix for Force original audio to work with any spoof client (#5861) 2025-09-15 20:58:56 +04:00
semantic-release-bot
cb6d802de3 chore: Release v5.37.1-dev.2 [skip ci]
## [5.37.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.37.1-dev.1...v5.37.1-dev.2) (2025-09-15)

### Bug Fixes

* **Instagram - Hide navigation buttons:** Support v397.1.0.52.81 ([#5855](https://github.com/ReVanced/revanced-patches/issues/5855)) ([f11d1ef](f11d1ef990))
2025-09-15 12:52:54 +00:00
brosssh
f11d1ef990
fix(Instagram - Hide navigation buttons): Support v397.1.0.52.81 (#5855) 2025-09-15 16:48:55 +04:00
semantic-release-bot
3d25da18bc chore: Release v5.37.1-dev.1 [skip ci]
## [5.37.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.37.0...v5.37.1-dev.1) (2025-09-15)

### Bug Fixes

* **YouTube Music - Spoof video streams:** Fix playback issues when using a cellular network ([fa04c8e](fa04c8eecf))
2025-09-15 12:47:02 +00:00
LisoUseInAIKyrios
fa04c8eecf fix(YouTube Music - Spoof video streams): Fix playback issues when using a cellular network
Code adapted from 5f35e51a27
2025-09-15 16:43:04 +04:00
semantic-release-bot
105f6e0e97 chore: Release v5.37.0 [skip ci]
# [5.37.0](https://github.com/ReVanced/revanced-patches/compare/v5.36.0...v5.37.0) (2025-09-15)

### Bug Fixes

* **Instagram - Hide navigation buttons:** Add constrain to known working version ([e6c79f1](e6c79f1383))
* Resolve patching with dev branch ([09b941a](09b941abf0))
* **Spotify:** Remove broken `Spoof client` patch ([#5833](https://github.com/ReVanced/revanced-patches/issues/5833)) ([dcd4245](dcd42454bd))
* **Viber - Hide ads:** Add constrain to known working version ([2db0948](2db0948bea))
* **YouTube Music - Spoof streaming data:** Fix audio playback stuttering ([#5839](https://github.com/ReVanced/revanced-patches/issues/5839)) ([2a85a3b](2a85a3b290))

### Features

* **Viber:** Add `Hide ads` patch ([#5826](https://github.com/ReVanced/revanced-patches/issues/5826)) ([0abfab7](0abfab79d7))
2025-09-15 06:45:56 +00:00
LisoUseInAIKyrios
7d59efe05d
chore: Merge branch dev to main (#5830) 2025-09-15 10:43:05 +04:00
github-actions[bot]
81ff5576b0
chore: Sync translations (#5854) 2025-09-15 10:41:42 +04:00
semantic-release-bot
9a5c102c0d chore: Release v5.37.0-dev.6 [skip ci]
# [5.37.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.37.0-dev.5...v5.37.0-dev.6) (2025-09-15)

### Bug Fixes

* **Instagram - Hide navigation buttons:** Add constrain to known working version ([e6c79f1](e6c79f1383))
2025-09-15 06:40:30 +00:00
LisoUseInAIKyrios
e6c79f1383 fix(Instagram - Hide navigation buttons): Add constrain to known working version 2025-09-15 10:36:57 +04:00
semantic-release-bot
2a582eced8 chore: Release v5.37.0-dev.5 [skip ci]
# [5.37.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.37.0-dev.4...v5.37.0-dev.5) (2025-09-15)

### Bug Fixes

* **Viber - Hide ads:** Add constrain to known working version ([2db0948](2db0948bea))
2025-09-15 06:29:31 +00:00
LisoUseInAIKyrios
2db0948bea fix(Viber - Hide ads): Add constrain to known working version 2025-09-15 10:26:30 +04:00
semantic-release-bot
a3ba92e742 chore: Release v5.37.0-dev.4 [skip ci]
# [5.37.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.37.0-dev.3...v5.37.0-dev.4) (2025-09-14)

### Bug Fixes

* **YouTube Music - Spoof streaming data:** Fix audio playback stuttering ([#5839](https://github.com/ReVanced/revanced-patches/issues/5839)) ([2a85a3b](2a85a3b290))
2025-09-14 18:22:57 +00:00
LisoUseInAIKyrios
2a85a3b290
fix(YouTube Music - Spoof streaming data): Fix audio playback stuttering (#5839) 2025-09-14 22:19:13 +04:00
semantic-release-bot
eee72208dd chore: Release v5.37.0-dev.3 [skip ci]
# [5.37.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.37.0-dev.2...v5.37.0-dev.3) (2025-09-14)

### Bug Fixes

* **Spotify:** Remove broken `Spoof client` patch ([#5833](https://github.com/ReVanced/revanced-patches/issues/5833)) ([dcd4245](dcd42454bd))
2025-09-14 17:15:28 +00:00
LisoUseInAIKyrios
dcd42454bd
fix(Spotify): Remove broken Spoof client patch (#5833) 2025-09-14 21:11:15 +04:00
LisoUseInAIKyrios
782353c18a refactor(Spoof video streams): Handle migration of default spoof client for users upgrading from very old patches 2025-09-14 18:06:40 +04:00
semantic-release-bot
b53b870e8f chore: Release v5.37.0-dev.2 [skip ci]
# [5.37.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.37.0-dev.1...v5.37.0-dev.2) (2025-09-14)

### Bug Fixes

* Resolve patching with dev branch ([09b941a](09b941abf0))
2025-09-14 12:00:38 +00:00
LisoUseInAIKyrios
09b941abf0 fix: Resolve patching with dev branch 2025-09-14 15:58:05 +04:00
semantic-release-bot
678ef4052e chore: Release v5.37.0-dev.1 [skip ci]
# [5.37.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.36.0...v5.37.0-dev.1) (2025-09-14)

### Features

* **Viber:** Add `Hide ads` patch ([#5826](https://github.com/ReVanced/revanced-patches/issues/5826)) ([0abfab7](0abfab79d7))
2025-09-14 11:52:21 +00:00
Samo Hribar
0abfab79d7
feat(Viber): Add Hide ads patch (#5826) 2025-09-14 15:49:52 +04:00
LisoUseInAIKyrios
61cadf72cd refactor(Spoof video streams): Back port code from v22 branch to support patching the latest YT Music. Using any target above 7.49.52 is untested and only recommended for experimental or development purposes. 2025-09-14 15:49:35 +04:00
github-actions[bot]
e12359b94f
chore: Sync translations (#5829) 2025-09-14 15:46:32 +04:00
semantic-release-bot
c001daba4a chore: Release v5.36.0 [skip ci]
# [5.36.0](https://github.com/ReVanced/revanced-patches/compare/v5.35.0...v5.36.0) (2025-09-14)

### Bug Fixes

* **Duolingo - Disable ads:** Support latest app target ([#5782](https://github.com/ReVanced/revanced-patches/issues/5782)) ([88b47ef](88b47ef414))
* **YouTube - Hide layout components:** Hide new type of Playable shelf ([8cd8e59](8cd8e59bbc))
* **YouTube Music:** Resolve playback issues, change recommended app target to `7.29.52` ([#5813](https://github.com/ReVanced/revanced-patches/issues/5813)) ([a53b00d](a53b00dd51))

### Features

* **YouTube - SponsorBlock:** Add 'Hook' segment category ([#5783](https://github.com/ReVanced/revanced-patches/issues/5783)) ([9d4aa5c](9d4aa5cd16))
2025-09-14 06:56:22 +00:00
LisoUseInAIKyrios
e136f62d6e
chore: Merge branch dev to main (#5800) 2025-09-14 10:53:28 +04:00
semantic-release-bot
8ec405a359 chore: Release v5.36.0-dev.1 [skip ci]
# [5.36.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.35.0...v5.36.0-dev.1) (2025-09-13)

### Bug Fixes

* **Duolingo - Disable ads:** Support latest app target ([#5782](https://github.com/ReVanced/revanced-patches/issues/5782)) ([88b47ef](88b47ef414))
* **YouTube - Hide layout components:** Hide new type of Playable shelf ([8cd8e59](8cd8e59bbc))
* **YouTube Music:** Resolve playback issues, change recommended app target to `7.29.52` ([#5813](https://github.com/ReVanced/revanced-patches/issues/5813)) ([a53b00d](a53b00dd51))

### Features

* **YouTube - SponsorBlock:** Add 'Hook' segment category ([#5783](https://github.com/ReVanced/revanced-patches/issues/5783)) ([9d4aa5c](9d4aa5cd16))
2025-09-13 15:31:54 +00:00
github-actions[bot]
2f4b3a887b
chore: Sync translations (#5821) 2025-09-13 19:28:15 +04:00
semantic-release-bot
d1fabb242b chore: Release v5.36.0-dev.1 [skip ci]
# [5.36.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.35.0...v5.36.0-dev.1) (2025-09-13)

### Bug Fixes

* **Duolingo - Disable ads:** Support latest app target ([#5782](https://github.com/ReVanced/revanced-patches/issues/5782)) ([88b47ef](88b47ef414))
* **YouTube - Hide layout components:** Hide new type of Playable shelf ([8cd8e59](8cd8e59bbc))
* **YouTube Music:** Resolve playback issues, change recommended app target to `7.29.52` ([#5813](https://github.com/ReVanced/revanced-patches/issues/5813)) ([a53b00d](a53b00dd51))

### Features

* **YouTube - SponsorBlock:** Add 'Hook' segment category ([#5783](https://github.com/ReVanced/revanced-patches/issues/5783)) ([9d4aa5c](9d4aa5cd16))
2025-09-13 15:15:40 +00:00
LisoUseInAIKyrios
a53b00dd51
fix(YouTube Music): Resolve playback issues, change recommended app target to 7.29.52 (#5813) 2025-09-13 19:12:00 +04:00
semantic-release-bot
850c13e98e chore: Release v5.36.0-dev.1 [skip ci]
# [5.36.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.35.0...v5.36.0-dev.1) (2025-09-13)

### Bug Fixes

* **Duolingo - Disable ads:** Support latest app target ([#5782](https://github.com/ReVanced/revanced-patches/issues/5782)) ([88b47ef](88b47ef414))
* **YouTube - Hide layout components:** Hide new type of Playable shelf ([8cd8e59](8cd8e59bbc))

### Features

* **YouTube - SponsorBlock:** Add 'Hook' segment category ([#5783](https://github.com/ReVanced/revanced-patches/issues/5783)) ([9d4aa5c](9d4aa5cd16))
2025-09-13 07:00:16 +00:00
LisoUseInAIKyrios
4310789a26 chore: Fix api 2025-09-13 10:56:43 +04:00
semantic-release-bot
c4a720fbd3 chore: Release v5.36.0-dev.1 [skip ci]
# [5.36.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.35.0...v5.36.0-dev.1) (2025-09-12)

### Bug Fixes

* **Duolingo - Disable ads:** Support latest app target ([#5782](https://github.com/ReVanced/revanced-patches/issues/5782)) ([88b47ef](88b47ef414))
* **YouTube - Hide layout components:** Hide new type of Playable shelf ([8cd8e59](8cd8e59bbc))

### Features

* **YouTube - SponsorBlock:** Add 'Hook' segment category ([#5783](https://github.com/ReVanced/revanced-patches/issues/5783)) ([9d4aa5c](9d4aa5cd16))
2025-09-12 15:08:03 +00:00
LisoUseInAIKyrios
3bdb8dbce0 chore(YouTube - SponsorBlock): Adjust strings for consistency / clarity
Strings taken from https://github.com/ajayyy/ExtensionTranslations/blob/master/en/messages.json
2025-09-12 18:49:34 +04:00
LisoUseInAIKyrios
4894f33c96 chore: fix compilation 2025-09-12 18:49:33 +04:00
semantic-release-bot
7f6093ee66 chore: Release v5.36.0-dev.1 [skip ci]
# [5.36.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.35.1-dev.1...v5.36.0-dev.1) (2025-09-12)

### Features

* **YouTube - SponsorBlock:** Add 'Hook' segment category ([#5783](https://github.com/ReVanced/revanced-patches/issues/5783)) ([9d4aa5c](9d4aa5cd16))
2025-09-12 01:59:47 +00:00
LisoUseInAIKyrios
9d4aa5cd16 feat(YouTube - SponsorBlock): Add 'Hook' segment category (#5783) 2025-09-12 05:56:50 +04:00
oSumAtrIX
5ace6f587c chore: Add ads.fund verification file [skip ci] (#5786) 2025-09-11 16:00:24 +02:00
semantic-release-bot
796f56745e chore: Release v5.35.1-dev.1 [skip ci]
## [5.35.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.35.0...v5.35.1-dev.1) (2025-09-11)

### Bug Fixes

* **Duolingo - Disable ads:** Support latest app target ([#5782](https://github.com/ReVanced/revanced-patches/issues/5782)) ([88b47ef](88b47ef414))
* **YouTube - Hide layout components:** Hide new type of Playable shelf ([8cd8e59](8cd8e59bbc))
2025-09-11 01:29:16 +00:00
hoodles
88b47ef414 fix(Duolingo - Disable ads): Support latest app target (#5782) 2025-09-11 03:26:28 +02:00
LisoUseInAIKyrios
8cd8e59bbc fix(YouTube - Hide layout components): Hide new type of Playable shelf 2025-09-11 03:24:09 +02:00
LisoUseInAIKyrios
6e72b14d07 refactor(YouTube - Video Quality): Handle extremely slow internet connections that initially can use -1 quality index 2025-09-11 02:58:33 +02:00
LisoUseInAIKyrios
52b088327b chore: Fix api dump 2025-09-10 21:58:27 +02:00
1313 changed files with 136131 additions and 94709 deletions

View file

@ -1,3 +0,0 @@
[*.{kt,kts}]
ktlint_code_style = intellij_idea
ktlint_standard_no-wildcard-imports = disabled

View file

@ -72,6 +72,7 @@ body:
- **Do not submit a duplicate bug report**: Search for existing bug reports [here](https://github.com/ReVanced/revanced-patches/issues?q=label%3A%22Bug+report%22). - **Do not submit a duplicate bug report**: Search for existing bug reports [here](https://github.com/ReVanced/revanced-patches/issues?q=label%3A%22Bug+report%22).
- **Review the contribution guidelines**: Make sure your bug report adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-patches/blob/main/CONTRIBUTING.md). - **Review the contribution guidelines**: Make sure your bug report adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-patches/blob/main/CONTRIBUTING.md).
- **Check the troubleshooting guide**: A solution to your issue might be found in the [FAQ](https://github.com/ReVanced/revanced-documentation/blob/main/docs/revanced-resources/questions.md) or the [troubleshooting guide](https://github.com/ReVanced/revanced-documentation/blob/main/docs/revanced-resources/troubleshooting.md).
- **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app). - **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app).
- type: textarea - type: textarea
attributes: attributes:

View file

@ -72,6 +72,7 @@ body:
- **Do not submit a duplicate feature request**: Search for existing feature requests [here](https://github.com/ReVanced/revanced-patches/issues?q=label%3A%22Feature+request%22). - **Do not submit a duplicate feature request**: Search for existing feature requests [here](https://github.com/ReVanced/revanced-patches/issues?q=label%3A%22Feature+request%22).
- **Review the contribution guidelines**: Make sure your feature request adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-patches/blob/main/CONTRIBUTING.md). - **Review the contribution guidelines**: Make sure your feature request adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-patches/blob/main/CONTRIBUTING.md).
- **Check the troubleshooting guide**: Information about your issue might be found in the [FAQ](https://github.com/ReVanced/revanced-documentation/blob/main/docs/revanced-resources/questions.md) or the [troubleshooting guide](https://github.com/ReVanced/revanced-documentation/blob/main/docs/revanced-resources/troubleshooting.md).
- **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app). - **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app).
- type: textarea - type: textarea
attributes: attributes:

View file

@ -2,6 +2,10 @@ name: Build pull request
on: on:
workflow_dispatch: workflow_dispatch:
inputs:
pr:
description: "PR to build"
required: true
pull_request: pull_request:
branches: branches:
- dev - dev
@ -10,12 +14,17 @@ jobs:
release: release:
name: Build name: Build
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
contents: read
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v6
with:
ref: ${{ inputs.pr && format('refs/pull/{0}/merge', inputs.pr) || github.ref }}
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '17' java-version: '17'
@ -25,11 +34,13 @@ jobs:
- name: Build - name: Build
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ORG_GRADLE_PROJECT_githubPackagesUsername: ${{ github.actor }}
ORG_GRADLE_PROJECT_githubPackagesPassword: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew :patches:buildAndroid --no-daemon run: ./gradlew :patches:buildAndroid --no-daemon
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: revanced-patches name: revanced-patches
path: patches/build/libs path: patches/build/libs
archive: false

View file

@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Open pull request - name: Open pull request
uses: repo-sync/pull-request@v2 uses: repo-sync/pull-request@v2

View file

@ -1,8 +1,6 @@
name: Pull strings name: Pull strings
on: on:
schedule:
- cron: "0 */12 * * *"
workflow_dispatch: workflow_dispatch:
jobs: jobs:
@ -14,10 +12,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v6
with: with:
ref: dev ref: dev
clean: true persist-credentials: true
- name: Pull strings - name: Pull strings
uses: crowdin/github-action@v2 uses: crowdin/github-action@v2
@ -25,16 +23,29 @@ jobs:
config: crowdin.yml config: crowdin.yml
upload_sources: false upload_sources: false
download_translations: true download_translations: true
push_translations: false
skip_ref_checkout: true skip_ref_checkout: true
localization_branch_name: feat/translations
create_pull_request: false
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
- name: Process strings
run: |
chmod -R 777 patches/src/main/resources
./gradlew processStringsFromCrowdin
env:
ORG_GRADLE_PROJECT_githubPackagesUsername: ${{ github.actor }}
ORG_GRADLE_PROJECT_githubPackagesPassword: ${{ secrets.GITHUB_TOKEN }}
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v7
with:
commit_message: "chore: Sync translations from Crowdin"
push_options: '--force'
branch: feat/translations
- name: Open pull request - name: Open pull request
if: github.event_name == 'workflow_dispatch'
uses: repo-sync/pull-request@v2 uses: repo-sync/pull-request@v2
with: with:
source_branch: feat/translations source_branch: feat/translations

View file

@ -14,12 +14,13 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Preprocess strings - name: Process strings
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ORG_GRADLE_PROJECT_githubPackagesUsername: ${{ github.actor }}
run: ./gradlew clean preprocessCrowdinStrings ORG_GRADLE_PROJECT_githubPackagesPassword: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew processStringsForCrowdin
- name: Push strings - name: Push strings
uses: crowdin/github-action@v2 uses: crowdin/github-action@v2

View file

@ -15,13 +15,14 @@ jobs:
packages: write packages: write
id-token: write id-token: write
attestations: write attestations: write
artifact-metadata: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '17' java-version: '17'
@ -31,11 +32,12 @@ jobs:
- name: Build - name: Build
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ORG_GRADLE_PROJECT_githubPackagesUsername: ${{ github.actor }}
ORG_GRADLE_PROJECT_githubPackagesPassword: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew :patches:buildAndroid clean run: ./gradlew :patches:buildAndroid clean
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v6
with: with:
node-version: 'lts/*' node-version: 'lts/*'
cache: 'npm' cache: 'npm'
@ -51,14 +53,16 @@ jobs:
fingerprint: ${{ vars.GPG_FINGERPRINT }} fingerprint: ${{ vars.GPG_FINGERPRINT }}
- name: Release - name: Release
uses: cycjimmy/semantic-release-action@v4 uses: cycjimmy/semantic-release-action@v5
id: release id: release
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ORG_GRADLE_PROJECT_githubPackagesUsername: ${{ github.actor }}
ORG_GRADLE_PROJECT_githubPackagesPassword: ${{ secrets.GITHUB_TOKEN }}
- name: Attest - name: Attest
if: steps.release.outputs.new_release_published == 'true' if: steps.release.outputs.new_release_published == 'true'
uses: actions/attest-build-provenance@v2 uses: actions/attest@v4
with: with:
subject-name: 'ReVanced Patches ${{ steps.release.outputs.new_release_git_tag }}' subject-name: 'ReVanced Patches ${{ steps.release.outputs.new_release_git_tag }}'
subject-path: patches/build/libs/patches-*.rvp subject-path: patches/build/libs/patches-*.rvp

View file

@ -10,9 +10,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Update Gradle Wrapper - name: Update Gradle Wrapper
uses: gradle-update/update-gradle-wrapper-action@v1 uses: gradle-update/update-gradle-wrapper-action@v2
with: with:
target-branch: dev target-branch: dev

File diff suppressed because it is too large Load diff

View file

@ -97,9 +97,9 @@ Thank you for considering contributing to ReVanced Patches. You can find the con
To build ReVanced Patches, you can follow the [ReVanced documentation](https://github.com/ReVanced/revanced-documentation). To build ReVanced Patches, you can follow the [ReVanced documentation](https://github.com/ReVanced/revanced-documentation).
## 📜 Licence ## 📜 License
ReVanced Patches is licensed under the GPLv3 license. Please see the [license file](LICENSE) for more information. ReVanced Patches is licensed under the GPLv3 license. Please see the [license file](LICENSE) for more information.
[tl;dr](https://www.tldrlegal.com/license/gnu-general-public-license-v3-gpl-3) you may copy, distribute and modify ReVanced Patches as long as you track changes/dates in source files. [tl;dr](https://www.tldrlegal.com/license/gnu-general-public-license-v3-gpl-3) you may copy, distribute and modify ReVanced Patches as long as you track changes/dates in source files.
Any modifications to ReVanced Patches must also be made available under the GPL, Any modifications to ReVanced Patches must also be made available under the GPL,
along with build & install instructions. along with build & install instructions.

8
adsfund.json Normal file
View file

@ -0,0 +1,8 @@
{
"info": "This is verification file for ads.fund project",
"project": {
"name": "Revanced Patches",
"walletAddress": "0x7ab4091e00363654bf84B34151225742cd92FCE5",
"tokenAddress": "0xadf325f255083a3f3d9a9d01ffb3db52a148d802"
}
}

View file

@ -1,8 +1,9 @@
project_id_env: "CROWDIN_PROJECT_ID" project_id_env: "CROWDIN_PROJECT_ID"
api_token_env: "CROWDIN_PERSONAL_TOKEN" api_token_env: "CROWDIN_PERSONAL_TOKEN"
preserve_hierarchy: false preserve_hierarchy: true
files: files:
- source: patches/src/main/resources/addresources/values/strings.xml - source: patches/src/main/resources/addresources/values/strings.xml
dest: patches.xml
translation: patches/src/main/resources/addresources/values-%android_code%/strings.xml translation: patches/src/main/resources/addresources/values-%android_code%/strings.xml
skip_untranslated_strings: true skip_untranslated_strings: true

View file

@ -1,14 +1,7 @@
android { android {
namespace = "app.revanced.extension"
defaultConfig { defaultConfig {
minSdk = 21 minSdk = 21
} }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
} }
dependencies { dependencies {

View file

@ -1,9 +1,6 @@
android { android {
namespace = "app.revanced.extension" defaultConfig {
minSdk = 23
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
} }
} }

View file

@ -1,14 +1,7 @@
android { android {
namespace = "app.revanced.extension"
defaultConfig { defaultConfig {
minSdk = 21 minSdk = 21
} }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
} }
dependencies { dependencies {

View file

@ -31,7 +31,10 @@ public class InternalDataDocumentsProvider extends DocumentsProvider {
private static final String[] directoryColumns = private static final String[] directoryColumns =
{"document_id", "mime_type", "_display_name", "last_modified", "flags", {"document_id", "mime_type", "_display_name", "last_modified", "flags",
"_size", "full_path", "lstat_info"}; "_size", "full_path", "lstat_info"};
private static final int S_IFLNK = 0x8000; @SuppressWarnings("OctalInteger")
private static final int S_IFMT = 0170000;
@SuppressWarnings("OctalInteger")
private static final int S_IFLNK = 0120000;
private String packageName; private String packageName;
private File dataDirectory; private File dataDirectory;
@ -47,7 +50,7 @@ public class InternalDataDocumentsProvider extends DocumentsProvider {
if (root.isDirectory()) { if (root.isDirectory()) {
try { try {
// Only delete recursively if the directory is not a symlink // Only delete recursively if the directory is not a symlink
if ((Os.lstat(root.getPath()).st_mode & S_IFLNK) != S_IFLNK) { if ((Os.lstat(root.getPath()).st_mode & S_IFMT) != S_IFLNK) {
File[] files = root.listFiles(); File[] files = root.listFiles();
if (files != null) { if (files != null) {
for (File file : files) { for (File file : files) {
@ -324,7 +327,7 @@ public class InternalDataDocumentsProvider extends DocumentsProvider {
sb.append(";"); sb.append(";");
sb.append(lstat.st_gid); sb.append(lstat.st_gid);
// Append symlink target if it is a symlink // Append symlink target if it is a symlink
if ((lstat.st_mode & S_IFLNK) == S_IFLNK) { if ((lstat.st_mode & S_IFMT) == S_IFLNK) {
sb.append(";"); sb.append(";");
sb.append(Os.readlink(path)); sb.append(Os.readlink(path));
} }

View file

@ -0,0 +1,13 @@
android {
defaultConfig {
minSdk = 21
}
buildFeatures {
aidl = true
}
}
dependencies {
compileOnly(libs.annotation)
}

View file

@ -0,0 +1 @@
<manifest/>

View file

@ -0,0 +1,8 @@
package com.google.android.play.core.integrity.protocol;
import android.os.Bundle;
import com.google.android.play.core.integrity.protocol.IExpressIntegrityServiceCallback;
interface IExpressIntegrityService {
oneway void requestIntegrityToken(in Bundle request, IExpressIntegrityServiceCallback callback) = 2;
}

View file

@ -0,0 +1,5 @@
package com.google.android.play.core.integrity.protocol;
interface IExpressIntegrityServiceCallback {
oneway void onRequestExpressIntegrityTokenResult(in Bundle result) = 2;
}

View file

@ -0,0 +1,8 @@
package com.google.android.play.core.integrity.protocol;
import android.os.Bundle;
import com.google.android.play.core.integrity.protocol.IIntegrityServiceCallback;
interface IIntegrityService {
oneway void requestIntegrityToken(in Bundle request, IIntegrityServiceCallback callback) = 1;
}

View file

@ -0,0 +1,7 @@
package com.google.android.play.core.integrity.protocol;
import android.os.Bundle;
interface IIntegrityServiceCallback {
oneway void onResult(in Bundle result) = 1;
}

View file

@ -0,0 +1,10 @@
package android.ext;
/** @hide */
// Int values that are assigned to packages in this interface can be retrieved at runtime from
// ApplicationInfo.ext().getPackageId() or from AndroidPackage.ext().getPackageId() (in system_server).
//
// PackageIds are assigned to parsed APKs only after they are verified, either by a certificate check
// or by a check that the APK is stored on an immutable OS partition.
public interface PackageId {
String PLAY_STORE_NAME = "com.android.vending";
}

View file

@ -0,0 +1,62 @@
package android.os;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.FileDescriptor;
/** @hide */
public class BinderWrapper implements IBinder {
protected final IBinder base;
public BinderWrapper(IBinder base) {
this.base = base;
}
@Override
public boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
return base.transact(code, data, reply, flags);
}
@Nullable
@Override
public IInterface queryLocalInterface(@NonNull String descriptor) {
return base.queryLocalInterface(descriptor);
}
@Nullable
@Override
public String getInterfaceDescriptor() throws RemoteException {
return base.getInterfaceDescriptor();
}
@Override
public boolean pingBinder() {
return base.pingBinder();
}
@Override
public boolean isBinderAlive() {
return base.isBinderAlive();
}
@Override
public void dump(@NonNull FileDescriptor fd, @Nullable String[] args) throws RemoteException {
base.dump(fd, args);
}
@Override
public void dumpAsync(@NonNull FileDescriptor fd, @Nullable String[] args) throws RemoteException {
base.dumpAsync(fd, args);
}
@Override
public void linkToDeath(@NonNull DeathRecipient recipient, int flags) throws RemoteException {
base.linkToDeath(recipient, flags);
}
@Override
public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) {
return base.unlinkToDeath(recipient, flags);
}
}

View file

@ -0,0 +1,41 @@
package app.grapheneos.gmscompat.lib.playintegrity;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.os.FakeBackgroundHandler;
import com.google.android.play.core.integrity.protocol.IIntegrityService;
import com.google.android.play.core.integrity.protocol.IIntegrityServiceCallback;
class ClassicPlayIntegrityServiceWrapper extends PlayIntegrityServiceWrapper {
ClassicPlayIntegrityServiceWrapper(IBinder base) {
super(base);
requestIntegrityTokenTxnCode = 2; // IIntegrityService.Stub.TRANSACTION_requestIntegrityToken
}
static class TokenRequestStub extends IIntegrityService.Stub {
public void requestIntegrityToken(Bundle request, IIntegrityServiceCallback callback) {
Runnable r = () -> {
var result = new Bundle();
// https://developer.android.com/google/play/integrity/reference/com/google/android/play/core/integrity/model/IntegrityErrorCode.html#API_NOT_AVAILABLE
final int API_NOT_AVAILABLE = -1;
result.putInt("error", API_NOT_AVAILABLE);
try {
callback.onResult(result);
} catch (RemoteException e) {
Log.e("IIntegrityService.Stub", "", e);
}
};
FakeBackgroundHandler.getHandler().postDelayed(r, getTokenRequestResultDelay());
}
};
@Override
protected Binder createTokenRequestStub() {
return new TokenRequestStub();
}
}

View file

@ -0,0 +1,48 @@
package app.grapheneos.gmscompat.lib.playintegrity;
import android.os.Binder;
import android.os.BinderWrapper;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
import androidx.annotation.Nullable;
abstract class PlayIntegrityServiceWrapper extends BinderWrapper {
final String TAG;
protected int requestIntegrityTokenTxnCode;
public PlayIntegrityServiceWrapper(IBinder base) {
super(base);
TAG = getClass().getSimpleName();
}
protected abstract Binder createTokenRequestStub();
@Override
public boolean transact(int code, Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
if (code == requestIntegrityTokenTxnCode) {
if (maybeStubOutIntegrityTokenRequest(code, data, reply, flags)) {
return true;
}
}
return super.transact(code, data, reply, flags);
}
private boolean maybeStubOutIntegrityTokenRequest(int code, Parcel data, @Nullable Parcel reply, int flags) {
Log.d(TAG, "integrity token request detected");
try {
createTokenRequestStub().transact(code, data, reply, flags);
} catch (RemoteException e) {
// this is a local call
throw new IllegalStateException(e);
}
return true;
}
protected static long getTokenRequestResultDelay() {
return 500L;
}
}

View file

@ -0,0 +1,35 @@
package app.grapheneos.gmscompat.lib.playintegrity;
import android.content.Intent;
import android.content.ServiceConnection;
import android.ext.PackageId;
import android.os.IBinder;
import androidx.annotation.Nullable;
import app.grapheneos.gmscompat.lib.util.ServiceConnectionWrapper;
import java.util.function.UnaryOperator;
public class PlayIntegrityUtils {
public static @Nullable ServiceConnection maybeReplaceServiceConnection(Intent service, ServiceConnection orig) {
if (PackageId.PLAY_STORE_NAME.equals(service.getPackage())) {
UnaryOperator<IBinder> binderOverride = null;
final String CLASSIC_SERVICE =
"com.google.android.play.core.integrityservice.BIND_INTEGRITY_SERVICE";
final String STANDARD_SERVICE =
"com.google.android.play.core.expressintegrityservice.BIND_EXPRESS_INTEGRITY_SERVICE";
String action = service.getAction();
if (STANDARD_SERVICE.equals(action)) {
binderOverride = StandardPlayIntegrityServiceWrapper::new;
} else if (CLASSIC_SERVICE.equals(action)) {
binderOverride = ClassicPlayIntegrityServiceWrapper::new;
}
if (binderOverride != null) {
return new ServiceConnectionWrapper(orig, binderOverride);
}
}
return null;
}
}

View file

@ -0,0 +1,42 @@
package app.grapheneos.gmscompat.lib.playintegrity;
import android.annotation.SuppressLint;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.os.FakeBackgroundHandler;
import com.google.android.play.core.integrity.protocol.IExpressIntegrityService;
import com.google.android.play.core.integrity.protocol.IExpressIntegrityServiceCallback;
@SuppressLint("LongLogTag")
class StandardPlayIntegrityServiceWrapper extends PlayIntegrityServiceWrapper {
StandardPlayIntegrityServiceWrapper(IBinder base) {
super(base);
requestIntegrityTokenTxnCode = 3; // IExpressIntegrityService.Stub.TRANSACTION_requestIntegrityToken
}
static class TokenRequestStub extends IExpressIntegrityService.Stub {
public void requestIntegrityToken(Bundle request, IExpressIntegrityServiceCallback callback) {
Runnable r = () -> {
var result = new Bundle();
// https://developer.android.com/google/play/integrity/reference/com/google/android/play/core/integrity/model/StandardIntegrityErrorCode.html#API_NOT_AVAILABLE
final int API_NOT_AVAILABLE = -1;
result.putInt("error", API_NOT_AVAILABLE);
try {
callback.onRequestExpressIntegrityTokenResult(result);
} catch (RemoteException e) {
Log.e("IExpressIntegrityService.Stub", "", e);
}
};
FakeBackgroundHandler.getHandler().postDelayed(r, getTokenRequestResultDelay());
}
};
@Override
protected Binder createTokenRequestStub() {
return new TokenRequestStub();
}
}

View file

@ -0,0 +1,49 @@
package app.grapheneos.gmscompat.lib.util;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.IBinder;
import java.util.function.UnaryOperator;
public class ServiceConnectionWrapper implements ServiceConnection {
private final ServiceConnection base;
private final UnaryOperator<IBinder> binderOverride;
public ServiceConnectionWrapper(ServiceConnection base, UnaryOperator<IBinder> binderOverride) {
this.base = base;
this.binderOverride = binderOverride;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
IBinder override = binderOverride.apply(service);
if (override != null) {
service = override;
}
}
base.onServiceConnected(name, service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
base.onServiceDisconnected(name);
}
@Override
public void onBindingDied(ComponentName name) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
base.onBindingDied(name);
}
}
@Override
public void onNullBinding(ComponentName name) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
base.onNullBinding(name);
}
}
}

View file

@ -0,0 +1,17 @@
package app.revanced.extension.play;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import app.grapheneos.gmscompat.lib.playintegrity.PlayIntegrityUtils;
public class DisablePlayIntegrityPatch {
public static boolean bindService(Context context, Intent service, ServiceConnection conn, int flags) {
ServiceConnection override = PlayIntegrityUtils.maybeReplaceServiceConnection(service, conn);
if (override != null) {
conn = override;
}
return context.bindService(service, conn, flags);
}
}

View file

@ -0,0 +1,11 @@
package com.android.internal.os;
import android.os.Handler;
import android.os.Looper;
public class FakeBackgroundHandler {
public static Handler getHandler() {
return new Handler(Looper.getMainLooper());
}
}

View file

@ -1,14 +1,7 @@
android { android {
namespace = "app.revanced.extension"
defaultConfig { defaultConfig {
minSdk = 21 minSdk = 21
} }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
} }
dependencies { dependencies {

View file

@ -1,14 +1,7 @@
android { android {
namespace = "app.revanced.extension"
defaultConfig { defaultConfig {
minSdk = 21 minSdk = 21
} }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
} }
dependencies { dependencies {

View file

@ -3,3 +3,9 @@ dependencies {
compileOnly(libs.annotation) compileOnly(libs.annotation)
compileOnly(libs.okhttp) compileOnly(libs.okhttp)
} }
android {
defaultConfig {
minSdk = 22
}
}

View file

@ -4,3 +4,9 @@ dependencies {
compileOnly(libs.annotation) compileOnly(libs.annotation)
compileOnly(libs.okhttp) compileOnly(libs.okhttp)
} }
android {
defaultConfig {
minSdk = 21
}
}

View file

@ -1,4 +1,10 @@
dependencies { dependencies {
compileOnly(project(":extensions:shared:library")) compileOnly(project(":extensions:shared:library"))
compileOnly(project(":extensions:cricbuzz:stub")) compileOnly(project(":extensions:cricbuzz:stub"))
} }
android {
defaultConfig {
minSdk = 21
}
}

View file

@ -0,0 +1,9 @@
dependencies {
compileOnly(project(":extensions:shared:library"))
}
android {
defaultConfig {
minSdk = 26
}
}

View file

@ -0,0 +1 @@
<manifest/>

View file

@ -0,0 +1,26 @@
package app.revanced.extension.instagram.feed;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings("unused")
public class LimitFeedToFollowedProfiles {
/**
* Injection point.
*/
public static Map<String, String> setFollowingHeader(Map<String, String> requestHeaderMap) {
String paginationHeaderName = "pagination_source";
// Patch the header only if it's trying to fetch the default feed
String currentHeader = requestHeaderMap.get(paginationHeaderName);
if (currentHeader != null && !currentHeader.equals("feed_recs")) {
return requestHeaderMap;
}
// Create new map as original is unmodifiable.
Map<String, String> patchedRequestHeaderMap = new HashMap<>(requestHeaderMap);
patchedRequestHeaderMap.put(paginationHeaderName, "following");
return patchedRequestHeaderMap;
}
}

View file

@ -0,0 +1,33 @@
package app.revanced.extension.instagram.hide.navigation;
import java.lang.reflect.Field;
import java.util.List;
@SuppressWarnings("unused")
public class HideNavigationButtonsPatch {
/**
* Injection point.
* @param navigationButtonsList the list of navigation buttons, as an (obfuscated) Enum type
* @param buttonNameToRemove the name of the button we want to remove
* @param enumNameField the field in the nav button enum class which contains the name of the button
* @return the patched list of navigation buttons
*/
public static List<Object> removeNavigationButtonByName(
List<Object> navigationButtonsList,
String buttonNameToRemove,
String enumNameField
)
throws IllegalAccessException, NoSuchFieldException {
for (Object button : navigationButtonsList) {
Field f = button.getClass().getDeclaredField(enumNameField);
String currentButtonEnumName = (String) f.get(button);
if (buttonNameToRemove.equals(currentButtonEnumName)) {
navigationButtonsList.remove(button);
break;
}
}
return navigationButtonsList;
}
}

View file

@ -0,0 +1,30 @@
package app.revanced.extension.instagram.misc.links;
import android.net.Uri;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
@SuppressWarnings("unused")
public final class OpenLinksExternallyPatch {
/**
* Injection point.
*/
public static boolean openExternally(String url) {
try {
// The "url" parameter to this function will be of the form.
// https://l.instagram.com/?u=<actual url>&e=<tracking id>
String actualUrl = Uri.parse(url).getQueryParameter("u");
if (actualUrl != null) {
Utils.openLink(actualUrl);
return true;
}
} catch (Exception ex) {
Logger.printException(() -> "openExternally failure", ex);
}
return false;
}
}

View file

@ -0,0 +1,15 @@
package app.revanced.extension.instagram.misc.privacy;
import app.revanced.extension.shared.privacy.LinkSanitizer;
@SuppressWarnings("unused")
public final class SanitizeSharingLinksPatch {
private static final LinkSanitizer sanitizer = new LinkSanitizer("igsh");
/**
* Injection point.
*/
public static String sanitizeSharingLink(String url) {
return sanitizer.sanitizeURLString(url);
}
}

View file

@ -0,0 +1,33 @@
package app.revanced.extension.instagram.misc.share.domain;
import android.net.Uri;
import app.revanced.extension.shared.Logger;
@SuppressWarnings("unused")
public final class ChangeLinkSharingDomainPatch {
private static String getCustomShareDomain() {
// Method is modified during patching.
throw new IllegalStateException();
}
/**
* Injection point.
*/
public static String setCustomShareDomain(String url) {
try {
Uri uri = Uri.parse(url);
Uri.Builder builder = uri
.buildUpon()
.authority(getCustomShareDomain())
.clearQuery();
String patchedUrl = builder.build().toString();
Logger.printInfo(() -> "Domain change from : " + url + " to: " + patchedUrl);
return patchedUrl;
} catch (Exception ex) {
Logger.printException(() -> "setCustomShareDomain failure with " + url, ex);
return url;
}
}
}

View file

@ -0,0 +1,15 @@
package app.revanced.extension.instagram.misc.share.privacy;
import app.revanced.extension.shared.privacy.LinkSanitizer;
@SuppressWarnings("unused")
public final class SanitizeSharingLinksPatch {
private static final LinkSanitizer sanitizer = new LinkSanitizer("igsh");
/**
* Injection point.
*/
public static String sanitizeSharingLink(String url) {
return sanitizer.sanitizeURLString(url);
}
}

View file

@ -1,3 +1,9 @@
dependencies { dependencies {
compileOnly(project(":extensions:shared:library")) compileOnly(project(":extensions:shared:library"))
} }
android {
defaultConfig {
minSdk = 24
}
}

View file

@ -1,3 +1,9 @@
dependencies {
compileOnly(project(":extensions:shared:library"))
compileOnly(project(":extensions:youtube:stub"))
compileOnly(libs.annotation)
}
android { android {
defaultConfig { defaultConfig {
minSdk = 26 minSdk = 26

View file

@ -0,0 +1,12 @@
package app.revanced.extension.music;
import app.revanced.extension.shared.Utils;
public class VersionCheckUtils {
private static boolean isVersionOrGreater(String version) {
return Utils.getAppVersionName().compareTo(version) >= 0;
}
public static final boolean IS_8_40_OR_GREATER = isVersionOrGreater("8.40.00");
}

View file

@ -0,0 +1,14 @@
package app.revanced.extension.music.patches;
import app.revanced.extension.music.settings.Settings;
@SuppressWarnings("unused")
public class ChangeMiniplayerColorPatch {
/**
* Injection point
*/
public static boolean changeMiniplayerColor() {
return Settings.CHANGE_MINIPLAYER_COLOR.get();
}
}

View file

@ -0,0 +1,17 @@
package app.revanced.extension.music.patches;
import app.revanced.extension.music.settings.Settings;
@SuppressWarnings("unused")
public class ForceOriginalAudioPatch {
/**
* Injection point.
*/
public static void setEnabled() {
app.revanced.extension.shared.patches.ForceOriginalAudioPatch.setEnabled(
Settings.FORCE_ORIGINAL_AUDIO.get(),
Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get()
);
}
}

View file

@ -0,0 +1,49 @@
package app.revanced.extension.music.patches;
import static app.revanced.extension.shared.Utils.hideViewBy0dpUnderCondition;
import android.view.View;
import android.view.ViewGroup;
import app.revanced.extension.music.settings.Settings;
@SuppressWarnings("unused")
public class HideButtonsPatch {
/**
* Injection point
*/
public static int hideCastButton(int original) {
return Settings.HIDE_CAST_BUTTON.get() ? View.GONE : original;
}
/**
* Injection point
*/
public static void hideCastButton(View view) {
hideViewBy0dpUnderCondition(Settings.HIDE_CAST_BUTTON, view);
}
/**
* Injection point
*/
public static boolean hideHistoryButton(boolean original) {
return original && !Settings.HIDE_HISTORY_BUTTON.get();
}
/**
* Injection point
*/
public static void hideNotificationButton(View view) {
if (view.getParent() instanceof ViewGroup viewGroup) {
hideViewBy0dpUnderCondition(Settings.HIDE_NOTIFICATION_BUTTON, viewGroup);
}
}
/**
* Injection point
*/
public static void hideSearchButton(View view) {
hideViewBy0dpUnderCondition(Settings.HIDE_SEARCH_BUTTON, view);
}
}

View file

@ -0,0 +1,18 @@
package app.revanced.extension.music.patches;
import static app.revanced.extension.shared.Utils.hideViewBy0dpUnderCondition;
import android.view.View;
import app.revanced.extension.music.settings.Settings;
@SuppressWarnings("unused")
public class HideCategoryBarPatch {
/**
* Injection point
*/
public static void hideCategoryBar(View view) {
hideViewBy0dpUnderCondition(Settings.HIDE_CATEGORY_BAR, view);
}
}

View file

@ -0,0 +1,14 @@
package app.revanced.extension.music.patches;
import app.revanced.extension.music.settings.Settings;
@SuppressWarnings("unused")
public class HideGetPremiumPatch {
/**
* Injection point
*/
public static boolean hideGetPremiumLabel() {
return Settings.HIDE_GET_PREMIUM_LABEL.get();
}
}

View file

@ -0,0 +1,17 @@
package app.revanced.extension.music.patches;
import app.revanced.extension.music.settings.Settings;
@SuppressWarnings("unused")
public class HideVideoAdsPatch {
/**
* Injection point
*/
public static boolean showVideoAds(boolean original) {
if (Settings.HIDE_VIDEO_ADS.get()) {
return false;
}
return original;
}
}

View file

@ -0,0 +1,86 @@
package app.revanced.extension.music.patches;
import static app.revanced.extension.shared.Utils.hideViewUnderCondition;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
import app.revanced.extension.music.settings.Settings;
@SuppressWarnings("unused")
public class NavigationBarPatch {
private static String lastYTNavigationEnumName = "";
public static void setLastAppNavigationEnum(@Nullable Enum<?> ytNavigationEnumName) {
if (ytNavigationEnumName != null) {
lastYTNavigationEnumName = ytNavigationEnumName.name();
}
}
public static void hideNavigationLabel(TextView textview) {
hideViewUnderCondition(Settings.HIDE_NAVIGATION_BAR_LABEL.get(), textview);
}
public static void hideNavigationButton(View view) {
// Hide entire navigation bar.
if (Settings.HIDE_NAVIGATION_BAR.get() && view.getParent() != null) {
hideViewUnderCondition(true, (View) view.getParent());
return;
}
// Hide navigation buttons based on their type.
for (NavigationButton button : NavigationButton.values()) {
if (button.ytEnumNames.contains(lastYTNavigationEnumName)) {
hideViewUnderCondition(button.hidden, view);
break;
}
}
}
private enum NavigationButton {
HOME(
Arrays.asList(
"TAB_HOME"
),
Settings.HIDE_NAVIGATION_BAR_HOME_BUTTON.get()
),
SAMPLES(
Arrays.asList(
"TAB_SAMPLES"
),
Settings.HIDE_NAVIGATION_BAR_SAMPLES_BUTTON.get()
),
EXPLORE(
Arrays.asList(
"TAB_EXPLORE"
),
Settings.HIDE_NAVIGATION_BAR_EXPLORE_BUTTON.get()
),
LIBRARY(
Arrays.asList(
"LIBRARY_MUSIC",
"TAB_BOOKMARK" // YouTube Music 8.24+
),
Settings.HIDE_NAVIGATION_BAR_LIBRARY_BUTTON.get()
),
UPGRADE(
Arrays.asList(
"TAB_MUSIC_PREMIUM"
),
Settings.HIDE_NAVIGATION_BAR_UPGRADE_BUTTON.get()
);
private final List<String> ytEnumNames;
private final boolean hidden;
NavigationButton(List<String> ytEnumNames, boolean hidden) {
this.ytEnumNames = ytEnumNames;
this.hidden = hidden;
}
}
}

View file

@ -0,0 +1,14 @@
package app.revanced.extension.music.patches;
import app.revanced.extension.music.settings.Settings;
@SuppressWarnings("unused")
public class PermanentRepeatPatch {
/**
* Injection point
*/
public static boolean permanentRepeat() {
return Settings.PERMANENT_REPEAT.get();
}
}

View file

@ -0,0 +1,30 @@
package app.revanced.extension.music.patches.spoof;
import static app.revanced.extension.music.settings.Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE;
import static app.revanced.extension.shared.spoof.ClientType.ANDROID_REEL;
import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_43_32;
import static app.revanced.extension.shared.spoof.ClientType.ANDROID_VR_1_61_48;
import static app.revanced.extension.shared.spoof.ClientType.VISIONOS;
import java.util.List;
import app.revanced.extension.shared.spoof.ClientType;
@SuppressWarnings("unused")
public class SpoofVideoStreamsPatch {
/**
* Injection point.
*/
public static void setClientOrderToUse() {
List<ClientType> availableClients = List.of(
ANDROID_REEL,
ANDROID_VR_1_43_32,
VISIONOS,
ANDROID_VR_1_61_48
);
app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.setClientsToUse(
availableClients, SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get());
}
}

View file

@ -0,0 +1,27 @@
package app.revanced.extension.music.patches.theme;
import app.revanced.extension.shared.theme.BaseThemePatch;
@SuppressWarnings("unused")
public class ThemePatch extends BaseThemePatch {
// Color constants used in relation with litho components.
private static final int[] DARK_VALUES = {
0xFF212121, // Comments box background.
0xFF030303, // Button container background in album.
0xFF000000, // Button container background in playlist.
};
/**
* Injection point.
* <p>
* Change the color of Litho components.
* If the color of the component matches one of the values, return the background color.
*
* @param originalValue The original color value.
* @return The new or original color value.
*/
public static int getValue(int originalValue) {
return processColorValue(originalValue, DARK_VALUES, null);
}
}

View file

@ -0,0 +1,148 @@
package app.revanced.extension.music.settings;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.preference.PreferenceFragment;
import android.view.View;
import android.widget.Toolbar;
import app.revanced.extension.music.VersionCheckUtils;
import app.revanced.extension.music.settings.preference.MusicPreferenceFragment;
import app.revanced.extension.music.settings.search.MusicSearchViewController;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.ResourceType;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseActivityHook;
/**
* Hooks GoogleApiActivity to inject a custom {@link MusicPreferenceFragment} with a toolbar and search.
*/
public class MusicActivityHook extends BaseActivityHook {
@SuppressLint("StaticFieldLeak")
public static MusicSearchViewController searchViewController;
/**
* How much time has passed since the first launch of the app. Simple check to prevent
* forcing bold icons on first launch where the settings menu is partially broken
* due to missing icon resources the client has not yet received.
*
* @see app.revanced.extension.youtube.settings.YouTubeActivityHook#MINIMUM_TIME_AFTER_FIRST_LAUNCH_BEFORE_ALLOWING_BOLD_ICONS
*/
private static final long MINIMUM_TIME_AFTER_FIRST_LAUNCH_BEFORE_ALLOWING_BOLD_ICONS = 30 * 1000; // 30 seconds.
static {
final boolean useBoldIcons = VersionCheckUtils.IS_8_40_OR_GREATER
&& !Settings.SETTINGS_DISABLE_BOLD_ICONS.get()
&& (System.currentTimeMillis() - Settings.FIRST_TIME_APP_LAUNCHED.get())
> MINIMUM_TIME_AFTER_FIRST_LAUNCH_BEFORE_ALLOWING_BOLD_ICONS;
Utils.setAppIsUsingBoldIcons(useBoldIcons);
}
/**
* Injection point.
*/
@SuppressWarnings("unused")
public static void initialize(Activity parentActivity) {
// Must touch the Music settings to ensure the class is loaded and
// the values can be found when setting the UI preferences.
// Logging anything under non debug ensures this is set.
Logger.printInfo(() -> "Permanent repeat enabled: " + Settings.PERMANENT_REPEAT.get());
// YT Music always uses dark mode.
Utils.setIsDarkModeEnabled(true);
BaseActivityHook.initialize(new MusicActivityHook(), parentActivity);
}
/**
* Sets the fixed theme for the activity.
*/
@Override
protected void customizeActivityTheme(Activity activity) {
// Override the default YouTube Music theme to increase start padding of list items.
// Custom style located in resources/music/values/style.xml
activity.setTheme(Utils.getResourceIdentifierOrThrow(
ResourceType.STYLE, "Theme.ReVanced.YouTubeMusic.Settings"));
}
/**
* Returns the fixed background color for the toolbar.
*/
@Override
protected int getToolbarBackgroundColor() {
return Utils.getResourceColor("ytm_color_black");
}
/**
* Returns the navigation icon with a color filter applied.
*/
@Override
protected Drawable getNavigationIcon() {
Drawable navigationIcon = MusicPreferenceFragment.getBackButtonDrawable();
navigationIcon.setColorFilter(Utils.getAppForegroundColor(), PorterDuff.Mode.SRC_IN);
return navigationIcon;
}
/**
* Returns the click listener that finishes the activity when the navigation icon is clicked.
*/
@Override
protected View.OnClickListener getNavigationClickListener(Activity activity) {
return view -> {
if (searchViewController != null && searchViewController.isSearchActive()) {
searchViewController.closeSearch();
} else {
activity.finish();
}
};
}
/**
* Adds search view components to the toolbar for {@link MusicPreferenceFragment}.
*
* @param activity The activity hosting the toolbar.
* @param toolbar The configured toolbar.
* @param fragment The PreferenceFragment associated with the activity.
*/
@Override
protected void onPostToolbarSetup(Activity activity, Toolbar toolbar, PreferenceFragment fragment) {
if (fragment instanceof MusicPreferenceFragment) {
searchViewController = MusicSearchViewController.addSearchViewComponents(
activity, toolbar, (MusicPreferenceFragment) fragment);
}
}
/**
* Creates a new {@link MusicPreferenceFragment} for the activity.
*/
@Override
protected PreferenceFragment createPreferenceFragment() {
return new MusicPreferenceFragment();
}
/**
* Injection point.
* <p>
* Overrides {@link Activity#finish()} of the injection Activity.
*
* @return if the original activity finish method should be allowed to run.
*/
@SuppressWarnings("unused")
public static boolean handleFinish() {
return MusicSearchViewController.handleFinish(searchViewController);
}
/**
* Injection point.
* <p>
* Decides whether to use bold icons.
*/
@SuppressWarnings("unused")
public static boolean useBoldIcons(boolean original) {
return Utils.appIsUsingBoldIcons();
}
}

View file

@ -0,0 +1,41 @@
package app.revanced.extension.music.settings;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static app.revanced.extension.shared.settings.Setting.parent;
import app.revanced.extension.shared.settings.YouTubeAndMusicSettings;
import app.revanced.extension.shared.settings.BooleanSetting;
import app.revanced.extension.shared.settings.EnumSetting;
import app.revanced.extension.shared.spoof.ClientType;
public class Settings extends YouTubeAndMusicSettings {
// Ads
public static final BooleanSetting HIDE_VIDEO_ADS = new BooleanSetting("revanced_music_hide_video_ads", TRUE, true);
public static final BooleanSetting HIDE_GET_PREMIUM_LABEL = new BooleanSetting("revanced_music_hide_get_premium_label", TRUE, true);
// General
public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_music_hide_cast_button", TRUE, true);
public static final BooleanSetting HIDE_CATEGORY_BAR = new BooleanSetting("revanced_music_hide_category_bar", FALSE, true);
public static final BooleanSetting HIDE_HISTORY_BUTTON = new BooleanSetting("revanced_music_hide_history_button", FALSE, true);
public static final BooleanSetting HIDE_SEARCH_BUTTON = new BooleanSetting("revanced_music_hide_search_button", FALSE, true);
public static final BooleanSetting HIDE_NOTIFICATION_BUTTON = new BooleanSetting("revanced_music_hide_notification_button", FALSE, true);
public static final BooleanSetting HIDE_NAVIGATION_BAR_HOME_BUTTON = new BooleanSetting("revanced_music_hide_navigation_bar_home_button", FALSE, true);
public static final BooleanSetting HIDE_NAVIGATION_BAR_SAMPLES_BUTTON = new BooleanSetting("revanced_music_hide_navigation_bar_samples_button", FALSE, true);
public static final BooleanSetting HIDE_NAVIGATION_BAR_EXPLORE_BUTTON = new BooleanSetting("revanced_music_hide_navigation_bar_explore_button", FALSE, true);
public static final BooleanSetting HIDE_NAVIGATION_BAR_LIBRARY_BUTTON = new BooleanSetting("revanced_music_hide_navigation_bar_library_button", FALSE, true);
public static final BooleanSetting HIDE_NAVIGATION_BAR_UPGRADE_BUTTON = new BooleanSetting("revanced_music_hide_navigation_bar_upgrade_button", TRUE, true);
public static final BooleanSetting HIDE_NAVIGATION_BAR = new BooleanSetting("revanced_music_hide_navigation_bar", FALSE, true);
public static final BooleanSetting HIDE_NAVIGATION_BAR_LABEL = new BooleanSetting("revanced_music_hide_navigation_bar_labels", FALSE, true);
// Player
public static final BooleanSetting CHANGE_MINIPLAYER_COLOR = new BooleanSetting("revanced_music_change_miniplayer_color", FALSE, true);
public static final BooleanSetting PERMANENT_REPEAT = new BooleanSetting("revanced_music_play_permanent_repeat", FALSE, true);
// Miscellaneous
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type",
ClientType.ANDROID_REEL, true, parent(SPOOF_VIDEO_STREAMS));
public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", TRUE, true);
}

View file

@ -0,0 +1,93 @@
package app.revanced.extension.music.settings.preference;
import android.app.Dialog;
import android.preference.PreferenceScreen;
import android.widget.Toolbar;
import app.revanced.extension.music.settings.MusicActivityHook;
import app.revanced.extension.shared.GmsCoreSupport;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.preference.ToolbarPreferenceFragment;
/**
* Preference fragment for ReVanced settings.
*/
@SuppressWarnings("deprecation")
public class MusicPreferenceFragment extends ToolbarPreferenceFragment {
/**
* The main PreferenceScreen used to display the current set of preferences.
*/
private PreferenceScreen preferenceScreen;
/**
* Initializes the preference fragment.
*/
@Override
protected void initialize() {
super.initialize();
try {
preferenceScreen = getPreferenceScreen();
Utils.sortPreferenceGroups(preferenceScreen);
setPreferenceScreenToolbar(preferenceScreen);
// Clunky work around until preferences are custom classes that manage themselves.
// Custom branding only works with non-root install. But the preferences must be
// added during patched because of difficulties detecting during patching if it's
// a root install. So instead the non-functional preferences are removed during
// runtime if the app is mount (root) installation.
if (GmsCoreSupport.isPackageNameOriginal()) {
removePreferences(
BaseSettings.CUSTOM_BRANDING_ICON.key,
BaseSettings.CUSTOM_BRANDING_NAME.key);
}
} catch (Exception ex) {
Logger.printException(() -> "initialize failure", ex);
}
}
/**
* Called when the fragment starts.
*/
@Override
public void onStart() {
super.onStart();
try {
// Initialize search controller if needed
if (MusicActivityHook.searchViewController != null) {
// Trigger search data collection after fragment is ready.
MusicActivityHook.searchViewController.initializeSearchData();
}
} catch (Exception ex) {
Logger.printException(() -> "onStart failure", ex);
}
}
/**
* Sets toolbar for all nested preference screens.
*/
@Override
protected void customizeToolbar(Toolbar toolbar) {
MusicActivityHook.setToolbarLayoutParams(toolbar);
}
/**
* Perform actions after toolbar setup.
*/
@Override
protected void onPostToolbarSetup(Toolbar toolbar, Dialog preferenceScreenDialog) {
if (MusicActivityHook.searchViewController != null
&& MusicActivityHook.searchViewController.isSearchActive()) {
toolbar.post(() -> MusicActivityHook.searchViewController.closeSearch());
}
}
/**
* Returns the preference screen for external access by SearchViewController.
*/
public PreferenceScreen getPreferenceScreenForSearch() {
return preferenceScreen;
}
}

View file

@ -0,0 +1,28 @@
package app.revanced.extension.music.settings.search;
import android.content.Context;
import android.preference.PreferenceScreen;
import app.revanced.extension.shared.settings.search.BaseSearchResultsAdapter;
import app.revanced.extension.shared.settings.search.BaseSearchViewController;
import app.revanced.extension.shared.settings.search.BaseSearchResultItem;
import java.util.List;
/**
* Music-specific search results adapter.
*/
@SuppressWarnings("deprecation")
public class MusicSearchResultsAdapter extends BaseSearchResultsAdapter {
public MusicSearchResultsAdapter(Context context, List<BaseSearchResultItem> items,
BaseSearchViewController.BasePreferenceFragment fragment,
BaseSearchViewController searchViewController) {
super(context, items, fragment, searchViewController);
}
@Override
protected PreferenceScreen getMainPreferenceScreen() {
return fragment.getPreferenceScreenForSearch();
}
}

View file

@ -0,0 +1,71 @@
package app.revanced.extension.music.settings.search;
import android.app.Activity;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.view.View;
import android.widget.Toolbar;
import app.revanced.extension.music.settings.preference.MusicPreferenceFragment;
import app.revanced.extension.shared.settings.search.*;
/**
* Music-specific search view controller implementation.
*/
@SuppressWarnings("deprecation")
public class MusicSearchViewController extends BaseSearchViewController {
public static MusicSearchViewController addSearchViewComponents(Activity activity, Toolbar toolbar,
MusicPreferenceFragment fragment) {
return new MusicSearchViewController(activity, toolbar, fragment);
}
private MusicSearchViewController(Activity activity, Toolbar toolbar, MusicPreferenceFragment fragment) {
super(activity, toolbar, new PreferenceFragmentAdapter(fragment));
}
@Override
protected BaseSearchResultsAdapter createSearchResultsAdapter() {
return new MusicSearchResultsAdapter(activity, filteredSearchItems, fragment, this);
}
@Override
protected boolean isSpecialPreferenceGroup(Preference preference) {
// Music doesn't have SponsorBlock, so no special groups.
return false;
}
@Override
protected void setupSpecialPreferenceListeners(BaseSearchResultItem item) {
// Music doesn't have special preferences.
// This method can be empty or handle music-specific preferences if any.
}
// Static method for handling Activity finish
public static boolean handleFinish(MusicSearchViewController searchViewController) {
if (searchViewController != null && searchViewController.isSearchActive()) {
searchViewController.closeSearch();
return true;
}
return false;
}
// Adapter to wrap MusicPreferenceFragment to BasePreferenceFragment interface.
private record PreferenceFragmentAdapter(MusicPreferenceFragment fragment) implements BasePreferenceFragment {
@Override
public PreferenceScreen getPreferenceScreenForSearch() {
return fragment.getPreferenceScreenForSearch();
}
@Override
public View getView() {
return fragment.getView();
}
@Override
public Activity getActivity() {
return fragment.getActivity();
}
}
}

View file

@ -1,27 +0,0 @@
package app.revanced.extension.music.spoof;
/**
* @noinspection unused
*/
public class SpoofClientPatch {
private static final int CLIENT_TYPE_ID = 26;
private static final String CLIENT_VERSION = "6.21";
private static final String DEVICE_MODEL = "iPhone16,2";
private static final String OS_VERSION = "17.7.2.21H221";
public static int getClientId() {
return CLIENT_TYPE_ID;
}
public static String getClientVersion() {
return CLIENT_VERSION;
}
public static String getClientModel() {
return DEVICE_MODEL;
}
public static String getOsVersion() {
return OS_VERSION;
}
}

View file

@ -0,0 +1,10 @@
dependencies {
compileOnly(project(":extensions:shared:library"))
compileOnly(project(":extensions:nothingx:stub"))
}
android {
defaultConfig {
minSdk = 23
}
}

View file

@ -0,0 +1 @@
<manifest/>

View file

@ -0,0 +1,590 @@
package app.revanced.extension.nothingx.patches;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Application;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Patches to expose the K1 token for Nothing X app to enable pairing with GadgetBridge.
*/
@SuppressWarnings("unused")
public class ShowK1TokensPatch {
private static final String TAG = "ReVanced";
private static final String PACKAGE_NAME = "com.nothing.smartcenter";
private static final String EMPTY_MD5 = "d41d8cd98f00b204e9800998ecf8427e";
private static final String PREFS_NAME = "revanced_nothingx_prefs";
private static final String KEY_DONT_SHOW_DIALOG = "dont_show_k1_dialog";
// Colors
private static final int COLOR_BG = 0xFF1E1E1E;
private static final int COLOR_CARD = 0xFF2D2D2D;
private static final int COLOR_TEXT_PRIMARY = 0xFFFFFFFF;
private static final int COLOR_TEXT_SECONDARY = 0xFFB0B0B0;
private static final int COLOR_ACCENT = 0xFFFF9500;
private static final int COLOR_TOKEN_BG = 0xFF3A3A3A;
private static final int COLOR_BUTTON_POSITIVE = 0xFFFF9500;
private static final int COLOR_BUTTON_NEGATIVE = 0xFFFF6B6B;
// Match standalone K1: k1:, K1:, k1>, etc.
private static final Pattern K1_STANDALONE_PATTERN = Pattern.compile("(?i)(?:k1\\s*[:>]\\s*)([0-9a-f]{32})");
// Match combined r3+k1: format (64 chars = r3(32) + k1(32))
private static final Pattern K1_COMBINED_PATTERN = Pattern.compile("(?i)r3\\+k1\\s*:\\s*([0-9a-f]{64})");
private static volatile boolean k1Logged = false;
private static volatile boolean lifecycleCallbacksRegistered = false;
private static Context appContext;
/**
* Get K1 tokens from database and log files.
* Call this after the app initializes.
*
* @param context Application context
*/
public static void showK1Tokens(Context context) {
if (k1Logged) {
return;
}
appContext = context.getApplicationContext();
Set<String> allTokens = new LinkedHashSet<>();
// First try to get from database.
String dbToken = getK1TokensFromDatabase();
if (dbToken != null) {
allTokens.add(dbToken);
}
// Then get from log files.
Set<String> logTokens = getK1TokensFromLogFiles();
allTokens.addAll(logTokens);
if (allTokens.isEmpty()) {
return;
}
// Log all found tokens.
int index = 1;
for (String token : allTokens) {
Log.i(TAG, "#" + index++ + ": " + token.toUpperCase());
}
// Register lifecycle callbacks to show dialog when an Activity is ready.
registerLifecycleCallbacks(allTokens);
k1Logged = true;
}
/**
* Register ActivityLifecycleCallbacks to show dialog when first Activity resumes.
*
* @param tokens Set of K1 tokens to display
*/
private static void registerLifecycleCallbacks(Set<String> tokens) {
if (lifecycleCallbacksRegistered || !(appContext instanceof Application)) {
return;
}
Application application = (Application) appContext;
application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
// Check if user chose not to show dialog.
SharedPreferences prefs = activity.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
if (prefs.getBoolean(KEY_DONT_SHOW_DIALOG, false)) {
application.unregisterActivityLifecycleCallbacks(this);
lifecycleCallbacksRegistered = false;
return;
}
// Show dialog on first Activity resume.
if (tokens != null && !tokens.isEmpty()) {
activity.runOnUiThread(() -> showK1TokensDialog(activity, tokens));
// Unregister after showing
application.unregisterActivityLifecycleCallbacks(this);
lifecycleCallbacksRegistered = false;
}
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
lifecycleCallbacksRegistered = true;
}
/**
* Show dialog with K1 tokens.
*
* @param activity Activity context
* @param tokens Set of K1 tokens
*/
private static void showK1TokensDialog(Activity activity, Set<String> tokens) {
try {
// Create main container.
LinearLayout mainLayout = new LinearLayout(activity);
mainLayout.setOrientation(LinearLayout.VERTICAL);
mainLayout.setBackgroundColor(COLOR_BG);
mainLayout.setPadding(dpToPx(activity, 24), dpToPx(activity, 16),
dpToPx(activity, 24), dpToPx(activity, 16));
// Title.
TextView titleView = new TextView(activity);
titleView.setText("K1 Token(s) Found");
titleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
titleView.setTypeface(Typeface.DEFAULT_BOLD);
titleView.setTextColor(COLOR_TEXT_PRIMARY);
titleView.setGravity(Gravity.CENTER);
mainLayout.addView(titleView, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
));
// Subtitle.
TextView subtitleView = new TextView(activity);
subtitleView.setText(tokens.size() == 1 ? "1 token found • Tap to copy" : tokens.size() + " tokens found • Tap to copy");
subtitleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
subtitleView.setTextColor(COLOR_TEXT_SECONDARY);
subtitleView.setGravity(Gravity.CENTER);
LinearLayout.LayoutParams subtitleParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
subtitleParams.topMargin = dpToPx(activity, 4);
subtitleParams.bottomMargin = dpToPx(activity, 16);
mainLayout.addView(subtitleView, subtitleParams);
// Scrollable content.
ScrollView scrollView = new ScrollView(activity);
scrollView.setVerticalScrollBarEnabled(false);
LinearLayout.LayoutParams scrollParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
0,
1.0f
);
scrollParams.topMargin = dpToPx(activity, 8);
scrollParams.bottomMargin = dpToPx(activity, 16);
mainLayout.addView(scrollView, scrollParams);
LinearLayout tokensContainer = new LinearLayout(activity);
tokensContainer.setOrientation(LinearLayout.VERTICAL);
scrollView.addView(tokensContainer);
// Add each token as a card.
boolean singleToken = tokens.size() == 1;
int index = 1;
for (String token : tokens) {
LinearLayout tokenCard = createTokenCard(activity, token, index++, singleToken);
LinearLayout.LayoutParams cardParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
cardParams.bottomMargin = dpToPx(activity, 12);
tokensContainer.addView(tokenCard, cardParams);
}
// Info text.
TextView infoView = new TextView(activity);
infoView.setText(tokens.size() == 1 ? "Tap the token to copy it" : "Tap any token to copy it");
infoView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
infoView.setTextColor(COLOR_TEXT_SECONDARY);
infoView.setGravity(Gravity.CENTER);
infoView.setAlpha(0.7f);
LinearLayout.LayoutParams infoParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
infoParams.topMargin = dpToPx(activity, 8);
mainLayout.addView(infoView, infoParams);
// Button row.
LinearLayout buttonRow = new LinearLayout(activity);
buttonRow.setOrientation(LinearLayout.HORIZONTAL);
buttonRow.setGravity(Gravity.END);
LinearLayout.LayoutParams buttonRowParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
buttonRowParams.topMargin = dpToPx(activity, 16);
mainLayout.addView(buttonRow, buttonRowParams);
// "Don't show again" button.
Button dontShowButton = new Button(activity);
dontShowButton.setText("Don't show again");
dontShowButton.setTextColor(Color.WHITE);
dontShowButton.setBackgroundColor(Color.TRANSPARENT);
dontShowButton.setAllCaps(false);
dontShowButton.setTypeface(Typeface.DEFAULT);
dontShowButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
dontShowButton.setPadding(dpToPx(activity, 16), dpToPx(activity, 8),
dpToPx(activity, 16), dpToPx(activity, 8));
LinearLayout.LayoutParams dontShowParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
dontShowParams.rightMargin = dpToPx(activity, 8);
buttonRow.addView(dontShowButton, dontShowParams);
// "OK" button.
Button okButton = new Button(activity);
okButton.setText("OK");
okButton.setTextColor(Color.BLACK);
okButton.setBackgroundColor(COLOR_BUTTON_POSITIVE);
okButton.setAllCaps(false);
okButton.setTypeface(Typeface.DEFAULT_BOLD);
okButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
okButton.setPadding(dpToPx(activity, 24), dpToPx(activity, 12),
dpToPx(activity, 24), dpToPx(activity, 12));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
okButton.setElevation(dpToPx(activity, 4));
}
buttonRow.addView(okButton, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
));
// Build dialog.
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setView(mainLayout);
final AlertDialog dialog = builder.create();
// Style the dialog with dark background.
if (dialog.getWindow() != null) {
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
}
dialog.show();
// Set button click listeners after dialog is created.
dontShowButton.setOnClickListener(v -> {
SharedPreferences prefs = activity.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
prefs.edit().putBoolean(KEY_DONT_SHOW_DIALOG, true).apply();
Toast.makeText(activity, "Dialog disabled. Clear app data to re-enable.",
Toast.LENGTH_SHORT).show();
dialog.dismiss();
});
okButton.setOnClickListener(v -> {
dialog.dismiss();
});
} catch (Exception e) {
Log.e(TAG, "Failed to show K1 dialog", e);
}
}
/**
* Create a card view for a single token.
*/
private static LinearLayout createTokenCard(Activity activity, String token, int index, boolean singleToken) {
LinearLayout card = new LinearLayout(activity);
card.setOrientation(LinearLayout.VERTICAL);
card.setBackgroundColor(COLOR_TOKEN_BG);
card.setPadding(dpToPx(activity, 16), dpToPx(activity, 12),
dpToPx(activity, 16), dpToPx(activity, 12));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
card.setElevation(dpToPx(activity, 2));
}
card.setClickable(true);
card.setFocusable(true);
// Token label (only show if multiple tokens).
if (!singleToken) {
TextView labelView = new TextView(activity);
labelView.setText("Token #" + index);
labelView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
labelView.setTextColor(COLOR_ACCENT);
labelView.setTypeface(Typeface.DEFAULT_BOLD);
card.addView(labelView);
}
// Token value.
TextView tokenView = new TextView(activity);
tokenView.setText(token.toUpperCase());
tokenView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
tokenView.setTextColor(COLOR_TEXT_PRIMARY);
tokenView.setTypeface(Typeface.MONOSPACE);
tokenView.setLetterSpacing(0.05f);
LinearLayout.LayoutParams tokenParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
if (!singleToken) {
tokenParams.topMargin = dpToPx(activity, 8);
}
card.addView(tokenView, tokenParams);
// Click to copy.
card.setOnClickListener(v -> {
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
if (clipboard != null) {
clipboard.setText(token.toUpperCase());
Toast.makeText(activity, "Token copied!", Toast.LENGTH_SHORT).show();
}
});
return card;
}
/**
* Convert dp to pixels.
*/
private static int dpToPx(Context context, float dp) {
return (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp,
context.getResources().getDisplayMetrics()
);
}
/**
* Get K1 tokens from log files.
* Prioritizes pairing K1 tokens over reconnect tokens.
*/
private static Set<String> getK1TokensFromLogFiles() {
Set<String> pairingTokens = new LinkedHashSet<>();
Set<String> reconnectTokens = new LinkedHashSet<>();
try {
File logDir = new File("/data/data/" + PACKAGE_NAME + "/files/log");
if (!logDir.exists() || !logDir.isDirectory()) {
return pairingTokens;
}
File[] logFiles = logDir.listFiles((dir, name) ->
name.endsWith(".log") || name.endsWith(".log.") || name.matches(".*\\.log\\.\\d+"));
if (logFiles == null || logFiles.length == 0) {
return pairingTokens;
}
for (File logFile : logFiles) {
try (BufferedReader reader = new BufferedReader(new FileReader(logFile))) {
String line;
while ((line = reader.readLine()) != null) {
// Determine if this is a pairing or reconnect context.
boolean isPairingContext = line.toLowerCase().contains("watchbind");
boolean isReconnectContext = line.toLowerCase().contains("watchreconnect");
String k1Token = null;
// First check for combined r3+k1 format (priority).
Matcher combinedMatcher = K1_COMBINED_PATTERN.matcher(line);
if (combinedMatcher.find()) {
String combined = combinedMatcher.group(1);
if (combined.length() == 64) {
// Second half is the actual K1
k1Token = combined.substring(32).toLowerCase();
}
}
// Then check for standalone K1 format (only if not found in combined).
if (k1Token == null) {
Matcher standaloneMatcher = K1_STANDALONE_PATTERN.matcher(line);
if (standaloneMatcher.find()) {
String token = standaloneMatcher.group(1);
if (token != null && token.length() == 32) {
k1Token = token.toLowerCase();
}
}
}
// Add to appropriate set.
if (k1Token != null) {
if (isPairingContext && !isReconnectContext) {
pairingTokens.add(k1Token);
} else {
reconnectTokens.add(k1Token);
}
}
}
} catch (Exception e) {
// Skip unreadable files.
}
}
} catch (Exception ex) {
// Fail silently.
}
// Return pairing tokens first, add reconnect tokens if no pairing tokens found.
if (!pairingTokens.isEmpty()) {
Log.i(TAG, "Found " + pairingTokens.size() + " pairing K1 token(s)");
return pairingTokens;
}
if (!reconnectTokens.isEmpty()) {
Log.i(TAG, "Found " + reconnectTokens.size() + " reconnect K1 token(s) (may not work for initial pairing)");
}
return reconnectTokens;
}
/**
* Try to get K1 tokens from the database.
*/
private static String getK1TokensFromDatabase() {
try {
File dbDir = new File("/data/data/" + PACKAGE_NAME + "/databases");
if (!dbDir.exists() || !dbDir.isDirectory()) {
return null;
}
File[] dbFiles = dbDir.listFiles((dir, name) ->
name.endsWith(".db") && !name.startsWith("google_app_measurement") && !name.contains("firebase"));
if (dbFiles == null || dbFiles.length == 0) {
return null;
}
for (File dbFile : dbFiles) {
String token = getK1TokensFromDatabase(dbFile);
if (token != null) {
return token;
}
}
return null;
} catch (Exception ex) {
return null;
}
}
/**
* Extract K1 tokens from a database file.
*/
private static String getK1TokensFromDatabase(File dbFile) {
SQLiteDatabase db = null;
try {
db = SQLiteDatabase.openDatabase(dbFile.getPath(), null, SQLiteDatabase.OPEN_READONLY);
// Get all tables.
Cursor cursor = db.rawQuery(
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'",
null
);
List<String> tables = new ArrayList<>();
while (cursor.moveToNext()) {
tables.add(cursor.getString(0));
}
cursor.close();
// Scan all columns for 32-char hex strings.
for (String table : tables) {
Cursor schemaCursor = null;
try {
schemaCursor = db.rawQuery("PRAGMA table_info(" + table + ")", null);
List<String> columns = new ArrayList<>();
while (schemaCursor.moveToNext()) {
columns.add(schemaCursor.getString(1));
}
schemaCursor.close();
for (String column : columns) {
Cursor dataCursor = null;
try {
dataCursor = db.query(table, new String[]{column}, null, null, null, null, null);
while (dataCursor.moveToNext()) {
String value = dataCursor.getString(0);
if (value != null && value.length() == 32 && value.matches("[0-9a-fA-F]{32}")) {
// Skip obviously fake tokens (MD5 of empty string).
if (!value.equalsIgnoreCase(EMPTY_MD5)) {
dataCursor.close();
db.close();
return value.toLowerCase();
}
}
}
} catch (Exception e) {
// Skip non-string columns.
} finally {
if (dataCursor != null) {
dataCursor.close();
}
}
}
} catch (Exception e) {
// Continue to next table.
} finally {
if (schemaCursor != null && !schemaCursor.isClosed()) {
schemaCursor.close();
}
}
}
return null;
} catch (Exception ex) {
return null;
} finally {
if (db != null && db.isOpen()) {
db.close();
}
}
}
/**
* Reset the logged flag (useful for testing or re-pairing).
*/
public static void resetK1Logged() {
k1Logged = false;
lifecycleCallbacksRegistered = false;
}
/**
* Reset the "don't show again" preference.
*/
public static void resetDontShowPreference() {
if (appContext != null) {
SharedPreferences prefs = appContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
prefs.edit().putBoolean(KEY_DONT_SHOW_DIALOG, false).apply();
}
}
}

View file

@ -0,0 +1,17 @@
plugins {
alias(libs.plugins.android.library)
}
android {
namespace = "app.revanced.extension"
compileSdk = 34
defaultConfig {
minSdk = 26
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}

View file

@ -0,0 +1 @@
<manifest/>

View file

@ -2,3 +2,9 @@ dependencies {
compileOnly(project(":extensions:shared:library")) compileOnly(project(":extensions:shared:library"))
compileOnly(project(":extensions:nunl:stub")) compileOnly(project(":extensions:nunl:stub"))
} }
android {
defaultConfig {
minSdk = 26
}
}

View file

@ -2,3 +2,9 @@ dependencies {
compileOnly(project(":extensions:shared:library")) compileOnly(project(":extensions:shared:library"))
compileOnly(project(":extensions:primevideo:stub")) compileOnly(project(":extensions:primevideo:stub"))
} }
android {
defaultConfig {
minSdk = 21
}
}

View file

@ -16,6 +16,7 @@ import java.util.Arrays;
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.ui.Dim;
import com.amazon.video.sdk.player.Player; import com.amazon.video.sdk.player.Player;
@ -64,9 +65,8 @@ public class PlaybackSpeedPatch {
SpeedIconDrawable speedIcon = new SpeedIconDrawable(); SpeedIconDrawable speedIcon = new SpeedIconDrawable();
speedButton.setImageDrawable(speedIcon); speedButton.setImageDrawable(speedIcon);
int buttonSize = Utils.dipToPixels(48); speedButton.setMinimumWidth(Dim.dp48);
speedButton.setMinimumWidth(buttonSize); speedButton.setMinimumHeight(Dim.dp48);
speedButton.setMinimumHeight(buttonSize);
return speedButton; return speedButton;
} }
@ -197,11 +197,11 @@ class SpeedIconDrawable extends Drawable {
@Override @Override
public int getIntrinsicWidth() { public int getIntrinsicWidth() {
return Utils.dipToPixels(32); return Dim.dp32;
} }
@Override @Override
public int getIntrinsicHeight() { public int getIntrinsicHeight() {
return Utils.dipToPixels(32); return Dim.dp32;
} }
} }

View file

@ -1,3 +1,9 @@
dependencies { dependencies {
compileOnly(project(":extensions:reddit:stub")) compileOnly(project(":extensions:reddit:stub"))
} }
android {
defaultConfig {
minSdk = 28
}
}

View file

@ -0,0 +1,10 @@
dependencies {
compileOnly(project(":extensions:shared:library"))
compileOnly(project(":extensions:samsung:radio:stub"))
}
android {
defaultConfig {
minSdk = 26
}
}

View file

@ -0,0 +1 @@
<manifest/>

View file

@ -0,0 +1,24 @@
package app.revanced.extension.samsung.radio.misc.fix.crash;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@SuppressWarnings("unused")
public final class FixCrashPatch {
/**
* Injection point.
* <p>
* Add the required permissions to the request list to avoid crashes on API 34+.
**/
public static final String[] fixPermissionRequestList(String[] perms) {
List<String> permsList = new ArrayList<>(Arrays.asList(perms));
if (permsList.contains("android.permission.POST_NOTIFICATIONS")) {
permsList.addAll(Arrays.asList("android.permission.RECORD_AUDIO", "android.permission.READ_PHONE_STATE", "android.permission.FOREGROUND_SERVICE_MICROPHONE"));
}
if (permsList.contains("android.permission.RECORD_AUDIO")) {
permsList.add("android.permission.FOREGROUND_SERVICE_MICROPHONE");
}
return permsList.toArray(new String[0]);
}
}

View file

@ -0,0 +1,19 @@
package app.revanced.extension.samsung.radio.restrictions.device;
import android.os.SemSystemProperties;
import java.util.Arrays;
@SuppressWarnings("unused")
public final class BypassDeviceChecksPatch {
/**
* Injection point.
* <p>
* Check if the device has the required hardware
**/
public static final boolean checkIfDeviceIsIncompatible(String[] deviceList) {
String currentDevice = SemSystemProperties.getSalesCode();
return Arrays.asList(deviceList).contains(currentDevice);
}
}

View file

@ -0,0 +1,17 @@
plugins {
alias(libs.plugins.android.library)
}
android {
namespace = "app.revanced.extension"
compileSdk = 34
defaultConfig {
minSdk = 24
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}

View file

@ -0,0 +1 @@
<manifest/>

View file

@ -0,0 +1,7 @@
package android.os;
public class SemSystemProperties {
public static String getSalesCode() {
throw new UnsupportedOperationException("Stub");
}
}

View file

@ -2,3 +2,9 @@ dependencies {
implementation(project(":extensions:shared:library")) implementation(project(":extensions:shared:library"))
compileOnly(libs.okhttp) compileOnly(libs.okhttp)
} }
android {
defaultConfig {
minSdk = 23
}
}

View file

@ -1,5 +1,5 @@
plugins { plugins {
alias(libs.plugins.android.library) alias(libs.plugins.android.library)
} }
android { android {
@ -19,4 +19,6 @@ android {
dependencies { dependencies {
compileOnly(libs.annotation) compileOnly(libs.annotation)
compileOnly(libs.okhttp) compileOnly(libs.okhttp)
compileOnly(libs.protobuf.javalite)
implementation(project(":extensions:shared:protobuf", configuration = "shadowRuntimeElements"))
} }

View file

@ -1,6 +1,4 @@
package app.revanced.extension.youtube; package app.revanced.extension.shared;
import androidx.annotation.NonNull;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -39,7 +37,7 @@ public final class ByteTrieSearch extends TrieSearch<byte[]> {
return replacement; return replacement;
} }
public ByteTrieSearch(@NonNull byte[]... patterns) { public ByteTrieSearch(byte[]... patterns) {
super(new ByteTrieNode(), patterns); super(new ByteTrieNode(), patterns);
} }
} }

View file

@ -1,8 +1,5 @@
package app.revanced.extension.shared; package app.revanced.extension.shared;
import static app.revanced.extension.shared.StringRef.str;
import static app.revanced.extension.shared.requests.Route.Method.GET;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
@ -20,237 +17,396 @@ import android.widget.LinearLayout;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import app.revanced.extension.shared.requests.Requester;
import app.revanced.extension.shared.requests.Route;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.ui.CustomDialog;
import org.json.JSONObject;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Locale; import java.util.Locale;
import app.revanced.extension.shared.requests.Requester; import static app.revanced.extension.shared.StringRef.str;
import app.revanced.extension.shared.requests.Route; import static app.revanced.extension.shared.requests.Route.Method.GET;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class GmsCoreSupport { public class GmsCoreSupport {
private static final String PACKAGE_NAME_YOUTUBE = "com.google.android.youtube"; private static GmsCore gmsCore = GmsCore.UNKNOWN;
private static final String PACKAGE_NAME_YOUTUBE_MUSIC = "com.google.android.apps.youtube.music";
private static final String GMS_CORE_PACKAGE_NAME static {
= getGmsCoreVendorGroupId() + ".android.gms"; for (GmsCore core : GmsCore.values()) {
private static final Uri GMS_CORE_PROVIDER if (core.getGroupId().equals(getGmsCoreVendorGroupId())) {
= Uri.parse("content://" + getGmsCoreVendorGroupId() + ".android.gsf.gservices/prefix"); GmsCoreSupport.gmsCore = core;
private static final String DONT_KILL_MY_APP_URL break;
= "https://dontkillmyapp.com/"; }
private static final Route DONT_KILL_MY_APP_MANUFACTURER_API
= new Route(GET, "/api/v2/{manufacturer}.json");
private static final String DONT_KILL_MY_APP_NAME_PARAMETER
= "?app=MicroG";
private static final String BUILD_MANUFACTURER
= Build.MANUFACTURER.toLowerCase(Locale.ROOT).replace(" ", "-");
/**
* If a manufacturer specific page exists on DontKillMyApp.
*/
@Nullable
private static volatile Boolean DONT_KILL_MY_APP_MANUFACTURER_SUPPORTED;
private static void open(String queryOrLink) {
Logger.printInfo(() -> "Opening link: " + queryOrLink);
Intent intent;
try {
// Check if queryOrLink is a valid URL.
new URL(queryOrLink);
intent = new Intent(Intent.ACTION_VIEW, Uri.parse(queryOrLink));
} catch (MalformedURLException e) {
intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, queryOrLink);
} }
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Utils.getContext().startActivity(intent);
// Gracefully exit, otherwise the broken app will continue to run.
System.exit(0);
}
private static void showBatteryOptimizationDialog(Activity context,
String dialogMessageRef,
String positiveButtonTextRef,
DialogInterface.OnClickListener onPositiveClickListener) {
// Use a delay to allow the activity to finish initializing.
// Otherwise, if device is in dark mode the dialog is shown with wrong color scheme.
Utils.runOnMainThreadDelayed(() -> {
// Create the custom dialog.
Pair<Dialog, LinearLayout> dialogPair = Utils.createCustomDialog(
context,
str("gms_core_dialog_title"), // Title.
str(dialogMessageRef), // Message.
null, // No EditText.
str(positiveButtonTextRef), // OK button text.
() -> onPositiveClickListener.onClick(null, 0), // Convert DialogInterface.OnClickListener to Runnable.
null, // No Cancel button action.
null, // No Neutral button text.
null, // No Neutral button action.
true // Dismiss dialog when onNeutralClick.
);
Dialog dialog = dialogPair.first;
// Do not set cancelable to false, to allow using back button to skip the action,
// just in case the battery change can never be satisfied.
dialog.setCancelable(true);
// Show the dialog
Utils.showDialog(context, dialog);
}, 100);
} }
/** /**
* Injection point. * Injection point.
*/ */
public static void checkGmsCore(Activity context) { public static void checkGmsCore(Activity context) {
try { gmsCore.check(context);
// Verify the user has not included GmsCore for a root installation.
// GmsCore Support changes the package name, but with a mounted installation
// all manifest changes are ignored and the original package name is used.
String packageName = context.getPackageName();
if (packageName.equals(PACKAGE_NAME_YOUTUBE) || packageName.equals(PACKAGE_NAME_YOUTUBE_MUSIC)) {
Logger.printInfo(() -> "App is mounted with root, but GmsCore patch was included");
// Cannot use localize text here, since the app will load
// resources from the unpatched app and all patch strings are missing.
Utils.showToastLong("The 'GmsCore support' patch breaks mount installations");
// Do not exit. If the app exits before launch completes (and without
// opening another activity), then on some devices such as Pixel phone Android 10
// no toast will be shown and the app will continually relaunch
// with the appearance of a hung app.
}
// Verify GmsCore is installed.
try {
PackageManager manager = context.getPackageManager();
manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
} catch (PackageManager.NameNotFoundException exception) {
Logger.printInfo(() -> "GmsCore was not found");
// Cannot show a dialog and must show a toast,
// because on some installations the app crashes before a dialog can be displayed.
Utils.showToastLong(str("gms_core_toast_not_installed_message"));
open(getGmsCoreDownload());
return;
}
// Check if GmsCore is whitelisted from battery optimizations.
if (isAndroidAutomotive(context)) {
// Ignore Android Automotive devices (Google built-in),
// as there is no way to disable battery optimizations.
Logger.printDebug(() -> "Device is Android Automotive");
} else if (batteryOptimizationsEnabled(context)) {
Logger.printInfo(() -> "GmsCore is not whitelisted from battery optimizations");
showBatteryOptimizationDialog(context,
"gms_core_dialog_not_whitelisted_using_battery_optimizations_message",
"gms_core_dialog_continue_text",
(dialog, id) -> openGmsCoreDisableBatteryOptimizationsIntent(context));
return;
}
// Check if GmsCore is currently running in the background.
var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER);
//noinspection TryFinallyCanBeTryWithResources
try {
if (client == null) {
Logger.printInfo(() -> "GmsCore is not running in the background");
checkIfDontKillMyAppSupportsManufacturer();
showBatteryOptimizationDialog(context,
"gms_core_dialog_not_whitelisted_not_allowed_in_background_message",
"gms_core_dialog_open_website_text",
(dialog, id) -> openDontKillMyApp());
}
} finally {
if (client != null) client.close();
}
} catch (Exception ex) {
Logger.printException(() -> "checkGmsCore failure", ex);
}
} }
@SuppressLint("BatteryLife") // Permission is part of GmsCore private static String getOriginalPackageName() {
private static void openGmsCoreDisableBatteryOptimizationsIntent(Activity activity) { return null; // Modified during patching.
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.fromParts("package", GMS_CORE_PACKAGE_NAME, null));
activity.startActivityForResult(intent, 0);
} }
private static void checkIfDontKillMyAppSupportsManufacturer() { private static String getGmsCoreVendorGroupId() {
Utils.runOnBackgroundThread(() -> { return "app.revanced"; // Modified during patching.
}
/**
* @return If the current package name is the same as the original unpatched app.
* If `GmsCore support` was not included during patching, this returns true;
*/
public static boolean isPackageNameOriginal() {
String originalPackageName = getOriginalPackageName();
return originalPackageName == null
|| originalPackageName.equals(Utils.getContext().getPackageName());
}
private enum GmsCore {
REVANCED("app.revanced", "https://github.com/revanced/gmscore/releases/latest", () -> {
try { try {
final long start = System.currentTimeMillis();
HttpURLConnection connection = Requester.getConnectionFromRoute( HttpURLConnection connection = Requester.getConnectionFromRoute(
DONT_KILL_MY_APP_URL, DONT_KILL_MY_APP_MANUFACTURER_API, BUILD_MANUFACTURER); "https://api.github.com",
new Route(GET, "/repos/revanced/gmscore/releases/latest")
);
connection.setConnectTimeout(5000); connection.setConnectTimeout(5000);
connection.setReadTimeout(5000); connection.setReadTimeout(5000);
final boolean supported = connection.getResponseCode() == 200; int responseCode = connection.getResponseCode();
Logger.printInfo(() -> "Manufacturer is " + (supported ? "" : "NOT ") if (responseCode != 200) {
+ "listed on DontKillMyApp: " + BUILD_MANUFACTURER Logger.printDebug(() -> "GitHub API returned status code: " + responseCode);
+ " fetch took: " + (System.currentTimeMillis() - start) + "ms"); return null;
DONT_KILL_MY_APP_MANUFACTURER_SUPPORTED = supported; }
// Parse the response
JSONObject releaseData = Requester.parseJSONObject(connection);
String tagName = releaseData.optString("tag_name", "");
connection.disconnect();
if (tagName.isEmpty()) {
Logger.printDebug(() -> "No tag_name found in GitHub release data");
return null;
}
if (tagName.startsWith("v")) tagName = tagName.substring(1);
return tagName;
} catch (Exception ex) { } catch (Exception ex) {
Logger.printInfo(() -> "Could not check if manufacturer is listed on DontKillMyApp: " Logger.printInfo(() -> "Failed to fetch latest GmsCore version from GitHub", ex);
+ BUILD_MANUFACTURER, ex); return null;
DONT_KILL_MY_APP_MANUFACTURER_SUPPORTED = null;
} }
}); }),
} UNKNOWN(getGmsCoreVendorGroupId(), getGmsCoreVendorGroupId() + "android.gms", () -> null);
private static void openDontKillMyApp() { private static final String DONT_KILL_MY_APP_URL
final Boolean manufacturerSupported = DONT_KILL_MY_APP_MANUFACTURER_SUPPORTED; = "https://dontkillmyapp.com/";
private static final Route DONT_KILL_MY_APP_MANUFACTURER_API
= new Route(GET, "/api/v2/{manufacturer}.json");
private static final String DONT_KILL_MY_APP_NAME_PARAMETER
= "?app=MicroG";
private static final String BUILD_MANUFACTURER
= Build.MANUFACTURER.toLowerCase(Locale.ROOT).replace(" ", "-");
String manufacturerPageToOpen; /**
if (manufacturerSupported == null) { * If a manufacturer specific page exists on DontKillMyApp.
// Fetch has not completed yet. Only happens on extremely slow internet connections */
// and the user spends less than 1 second reading what's on screen. @Nullable
// Instead of waiting for the fetch (which may timeout), private volatile Boolean dontKillMyAppManufacturerSupported;
// open the website without a vendor.
manufacturerPageToOpen = ""; private final String groupId;
} else if (manufacturerSupported) { private final String packageName;
manufacturerPageToOpen = BUILD_MANUFACTURER; private final String downloadQuery;
} else { private final GetLatestVersion getLatestVersion;
// No manufacturer specific page exists. Open the general page. private final Uri gmsCoreProvider;
manufacturerPageToOpen = "general";
GmsCore(String groupId, String downloadQuery, GetLatestVersion getLatestVersion) {
this.groupId = groupId;
this.packageName = groupId + ".android.gms";
this.gmsCoreProvider = Uri.parse("content://" + groupId + ".android.gsf.gservices/prefix");
this.downloadQuery = downloadQuery;
this.getLatestVersion = getLatestVersion;
} }
open(DONT_KILL_MY_APP_URL + manufacturerPageToOpen + DONT_KILL_MY_APP_NAME_PARAMETER); String getGroupId() {
} return groupId;
}
/**
* @return If GmsCore is not whitelisted from battery optimizations. void check(Activity context) {
*/ checkInstallation(context);
private static boolean batteryOptimizationsEnabled(Context context) { checkUpdates(context);
//noinspection ObsoleteSdkInt }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Android 5.0 does not have battery optimization settings. private void checkInstallation(Activity context) {
return false; try {
// Verify the user has not included GmsCore for a root installation.
// GmsCore Support changes the package name, but with a mounted installation
// all manifest changes are ignored and the original package name is used.
if (isPackageNameOriginal()) {
Logger.printInfo(() -> "App is mounted with root, but GmsCore patch was included");
// Cannot use localize text here, since the app will load resources
// from the unpatched app and all patch strings are missing.
Utils.showToastLong("The 'GmsCore support' patch breaks mount installations");
// Do not exit. If the app exits before launch completes (and without
// opening another activity), then on some devices such as Pixel phone Android 10
// no toast will be shown and the app will continually relaunch
// with the appearance of a hung app.
}
// Verify GmsCore is installed.
try {
PackageManager manager = context.getPackageManager();
manager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
} catch (PackageManager.NameNotFoundException exception) {
Logger.printInfo(() -> "GmsCore was not found");
// Cannot show a dialog and must show a toast,
// because on some installations the app crashes before a dialog can be displayed.
Utils.showToastLong(str("revanced_gms_core_toast_not_installed_message"));
open(downloadQuery);
return;
}
// Check if GmsCore is whitelisted from battery optimizations.
if (isAndroidAutomotive(context)) {
// Ignore Android Automotive devices (Google built-in),
// as there is no way to disable battery optimizations.
Logger.printDebug(() -> "Device is Android Automotive");
} else if (batteryOptimizationsEnabled(context)) {
Logger.printInfo(() -> "GmsCore is not whitelisted from battery optimizations");
showBatteryOptimizationDialog(context,
"revanced_gms_core_dialog_not_whitelisted_using_battery_optimizations_message",
"revanced_gms_core_dialog_continue_text",
(dialog, id) -> openGmsCoreDisableBatteryOptimizationsIntent(context));
return;
}
// Check if GmsCore is currently running in the background.
var client = context.getContentResolver().acquireContentProviderClient(gmsCoreProvider);
//noinspection TryFinallyCanBeTryWithResources
try {
if (client == null) {
Logger.printInfo(() -> "GmsCore is not running in the background");
checkIfDontKillMyAppSupportsManufacturer();
showBatteryOptimizationDialog(context,
"revanced_gms_core_dialog_not_whitelisted_not_allowed_in_background_message",
"gmsrevanced_gms_core_log_open_website_text",
(dialog, id) -> openDontKillMyApp());
}
} finally {
if (client != null) client.close();
}
} catch (Exception ex) {
Logger.printException(() -> "checkGmsCore failure", ex);
}
}
private void checkUpdates(Activity context) {
if (!BaseSettings.GMS_CORE_CHECK_UPDATES.get()) {
Logger.printDebug(() -> "GmsCore update check is disabled in settings");
return;
}
Utils.runOnBackgroundThread(() -> {
try {
PackageManager manager = context.getPackageManager();
var installedVersion = manager.getPackageInfo(packageName, 0).versionName;
// GmsCore adds suffixes for flavor builds. Remove the suffix for version comparison.
int suffixIndex = installedVersion.indexOf('-');
if (suffixIndex != -1)
installedVersion = installedVersion.substring(0, suffixIndex);
String finalInstalledVersion = installedVersion;
Logger.printDebug(() -> "Installed GmsCore version: " + finalInstalledVersion);
var latestVersion = getLatestVersion.get();
if (latestVersion == null || latestVersion.isEmpty()) {
Logger.printDebug(() -> "Could not get latest GmsCore version");
Utils.showToastLong(str("revanced_gms_core_toast_update_check_failed_message"));
return;
}
Logger.printDebug(() -> "Latest GmsCore version on GitHub: " + latestVersion);
// Compare versions
if (!installedVersion.equals(latestVersion)) {
Logger.printInfo(() -> "GmsCore update available. Installed: " + finalInstalledVersion
+ ", Latest: " + latestVersion);
showUpdateDialog(context, installedVersion, latestVersion);
} else {
Logger.printDebug(() -> "GmsCore is up to date");
}
} catch (Exception ex) {
Logger.printInfo(() -> "Could not check GmsCore updates", ex);
Utils.showToastLong(str("revanced_gms_core_toast_update_check_failed_message"));
}
});
}
private void open(String queryOrLink) {
Logger.printInfo(() -> "Opening link: " + queryOrLink);
Intent intent;
try {
// Check if queryOrLink is a valid URL.
new URL(queryOrLink);
intent = new Intent(Intent.ACTION_VIEW, Uri.parse(queryOrLink));
} catch (MalformedURLException e) {
intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, queryOrLink);
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Utils.getContext().startActivity(intent);
// Gracefully exit, otherwise the broken app will continue to run.
System.exit(0);
}
private void showUpdateDialog(Activity context, String installedVersion, String latestVersion) {
// Use a delay to allow the activity to finish initializing.
// Otherwise, if device is in dark mode the dialog is shown with wrong color scheme.
Utils.runOnMainThreadDelayed(() -> {
try {
Pair<Dialog, LinearLayout> dialogPair = CustomDialog.create(
context,
str("revanced_gms_core_dialog_title"),
String.format(str("revanced_gms_core_update_available_message"), latestVersion, installedVersion),
null,
str("revanced_gms_core_dialog_open_website_text"),
() -> open(downloadQuery),
() -> {
},
str("revanced_gms_core_dialog_cancel_text"),
null,
true
);
Dialog dialog = dialogPair.first;
dialog.setCancelable(true);
Utils.showDialog(context, dialog);
} catch (Exception ex) {
Logger.printException(() -> "Failed to show GmsCore update dialog", ex);
}
}, 100);
}
private static void showBatteryOptimizationDialog(Activity context,
String dialogMessageRef,
String positiveButtonTextRef,
DialogInterface.OnClickListener onPositiveClickListener) {
// Use a delay to allow the activity to finish initializing.
// Otherwise, if device is in dark mode the dialog is shown with wrong color scheme.
Utils.runOnMainThreadDelayed(() -> {
// Create the custom dialog.
Pair<Dialog, LinearLayout> dialogPair = CustomDialog.create(
context,
str("revanced_gms_core_dialog_title"), // Title.
str(dialogMessageRef), // Message.
null, // No EditText.
str(positiveButtonTextRef), // OK button text.
() -> onPositiveClickListener.onClick(null, 0), // Convert DialogInterface.OnClickListener to Runnable.
null, // No Cancel button action.
null, // No Neutral button text.
null, // No Neutral button action.
true // Dismiss dialog when onNeutralClick.
);
Dialog dialog = dialogPair.first;
// Do not set cancelable to false to allow using back button to skip the action,
// just in case the battery change can never be satisfied.
dialog.setCancelable(true);
// Show the dialog
Utils.showDialog(context, dialog);
}, 100);
}
@SuppressLint("BatteryLife") // Permission is part of GmsCore
private void openGmsCoreDisableBatteryOptimizationsIntent(Activity activity) {
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.fromParts("package", packageName, null));
activity.startActivityForResult(intent, 0);
}
private void checkIfDontKillMyAppSupportsManufacturer() {
Utils.runOnBackgroundThread(() -> {
try {
final long start = System.currentTimeMillis();
HttpURLConnection connection = Requester.getConnectionFromRoute(
DONT_KILL_MY_APP_URL, DONT_KILL_MY_APP_MANUFACTURER_API, BUILD_MANUFACTURER);
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
final boolean supported = connection.getResponseCode() == 200;
Logger.printInfo(() -> "Manufacturer is " + (supported ? "" : "NOT ")
+ "listed on DontKillMyApp: " + BUILD_MANUFACTURER
+ " fetch took: " + (System.currentTimeMillis() - start) + "ms");
dontKillMyAppManufacturerSupported = supported;
} catch (Exception ex) {
Logger.printInfo(() -> "Could not check if manufacturer is listed on DontKillMyApp: "
+ BUILD_MANUFACTURER, ex);
dontKillMyAppManufacturerSupported = null;
}
});
}
private void openDontKillMyApp() {
final Boolean manufacturerSupported = dontKillMyAppManufacturerSupported;
String manufacturerPageToOpen;
if (manufacturerSupported == null) {
// Fetch has not completed yet. Only happens on extremely slow internet connections
// and the user spends less than 1 second reading what's on screen.
// Instead of waiting for the fetch (which may timeout),
// open the website without a vendor.
manufacturerPageToOpen = "";
} else if (manufacturerSupported) {
manufacturerPageToOpen = BUILD_MANUFACTURER;
} else {
// No manufacturer specific page exists. Open the general page.
manufacturerPageToOpen = "general";
}
open(DONT_KILL_MY_APP_URL + manufacturerPageToOpen + DONT_KILL_MY_APP_NAME_PARAMETER);
}
/**
* @return If GmsCore is not whitelisted from battery optimizations.
*/
private boolean batteryOptimizationsEnabled(Context context) {
//noinspection ObsoleteSdkInt
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Android 5.0 does not have battery optimization settings.
return false;
}
var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
return !powerManager.isIgnoringBatteryOptimizations(packageName);
}
private boolean isAndroidAutomotive(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
} }
var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
return !powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME);
} }
private static boolean isAndroidAutomotive(Context context) { @FunctionalInterface
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); private interface GetLatestVersion {
} String get();
private static String getGmsCoreDownload() {
final var vendorGroupId = getGmsCoreVendorGroupId();
//noinspection SwitchStatementWithTooFewBranches
return switch (vendorGroupId) {
case "app.revanced" -> "https://github.com/revanced/gmscore/releases/latest";
default -> vendorGroupId + ".android.gms";
};
}
// Modified by a patch. Do not touch.
private static String getGmsCoreVendorGroupId() {
return "app.revanced";
} }
} }

View file

@ -16,8 +16,8 @@ import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.preference.LogBufferManager; import app.revanced.extension.shared.settings.preference.LogBufferManager;
/** /**
* ReVanced specific logger. Logging is done to standard device log (accessible thru ADB), * ReVanced specific logger. Logging is done to standard device log (accessible through ADB),
* and additionally accessible thru {@link LogBufferManager}. * and additionally accessible through {@link LogBufferManager}.
* *
* All methods are thread safe, and are safe to call even * All methods are thread safe, and are safe to call even
* if {@link Utils#getContext()} is not available. * if {@link Utils#getContext()} is not available.
@ -202,7 +202,7 @@ public class Logger {
/** /**
* Logs exceptions under the outer class name of the code calling this method. * Logs exceptions under the outer class name of the code calling this method.
* <p> * <p>
* If the calling code is showing it's own error toast, * If the calling code is showing its own error toast,
* instead use {@link #printInfo(LogMessage, Exception)} * instead use {@link #printInfo(LogMessage, Exception)}
* *
* @param message log message * @param message log message

View file

@ -0,0 +1,57 @@
package app.revanced.extension.shared;
import java.util.HashMap;
import java.util.Map;
public enum ResourceType {
ANIM("anim"),
ANIMATOR("animator"),
ARRAY("array"),
ATTR("attr"),
BOOL("bool"),
COLOR("color"),
DIMEN("dimen"),
DRAWABLE("drawable"),
FONT("font"),
FRACTION("fraction"),
ID("id"),
INTEGER("integer"),
INTERPOLATOR("interpolator"),
LAYOUT("layout"),
MENU("menu"),
MIPMAP("mipmap"),
NAVIGATION("navigation"),
PLURALS("plurals"),
RAW("raw"),
STRING("string"),
STYLE("style"),
STYLEABLE("styleable"),
TRANSITION("transition"),
VALUES("values"),
XML("xml");
private static final Map<String, ResourceType> VALUE_MAP;
static {
ResourceType[] values = values();
VALUE_MAP = new HashMap<>(2 * values.length);
for (ResourceType type : values) {
VALUE_MAP.put(type.value, type);
}
}
public final String value;
public static ResourceType fromValue(String value) {
ResourceType type = VALUE_MAP.get(value);
if (type == null) {
throw new IllegalArgumentException("Unknown resource type: " + value);
}
return type;
}
ResourceType(String value) {
this.value = value;
}
}

View file

@ -70,7 +70,7 @@ public class StringRef {
} }
/** /**
* Creates a StringRef object that'll not change it's value * Creates a StringRef object that'll not change its value
* *
* @param value value which toString() method returns when invoked on returned object * @param value value which toString() method returns when invoked on returned object
* @return Unique StringRef instance, its value will never change * @return Unique StringRef instance, its value will never change
@ -102,7 +102,7 @@ public class StringRef {
public String toString() { public String toString() {
if (!resolved) { if (!resolved) {
if (resources == null || packageName == null) { if (resources == null || packageName == null) {
Context context = Utils.getContext(); var context = Utils.getContext();
resources = context.getResources(); resources = context.getResources();
packageName = context.getPackageName(); packageName = context.getPackageName();
} }

View file

@ -1,6 +1,4 @@
package app.revanced.extension.youtube; package app.revanced.extension.shared;
import androidx.annotation.NonNull;
/** /**
* Text pattern searching using a prefix tree (trie). * Text pattern searching using a prefix tree (trie).
@ -28,7 +26,7 @@ public final class StringTrieSearch extends TrieSearch<String> {
} }
} }
public StringTrieSearch(@NonNull String... patterns) { public StringTrieSearch(String... patterns) {
super(new StringTrieNode(), patterns); super(new StringTrieNode(), patterns);
} }
} }

View file

@ -1,6 +1,5 @@
package app.revanced.extension.youtube; package app.revanced.extension.shared;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@ -57,11 +56,13 @@ public abstract class TrieSearch<T> {
if (searchTextLength - searchTextIndex < patternLength - patternStartIndex) { if (searchTextLength - searchTextIndex < patternLength - patternStartIndex) {
return false; // Remaining search text is shorter than the remaining leaf pattern and they cannot match. return false; // Remaining search text is shorter than the remaining leaf pattern and they cannot match.
} }
for (int i = searchTextIndex, j = patternStartIndex; j < patternLength; i++, j++) { for (int i = searchTextIndex, j = patternStartIndex; j < patternLength; i++, j++) {
if (enclosingNode.getCharValue(searchText, i) != enclosingNode.getCharValue(pattern, j)) { if (enclosingNode.getCharValue(searchText, i) != enclosingNode.getCharValue(pattern, j)) {
return false; return false;
} }
} }
return callback == null || callback.patternMatched(searchText, return callback == null || callback.patternMatched(searchText,
searchTextIndex - patternStartIndex, patternLength, callbackParameter); searchTextIndex - patternStartIndex, patternLength, callbackParameter);
} }
@ -105,14 +106,18 @@ public abstract class TrieSearch<T> {
* Elements not contained can collide with elements the array does contain, * Elements not contained can collide with elements the array does contain,
* so must compare the nodes character value. * so must compare the nodes character value.
* *
* Alternatively this array could be a sorted and densely packed array, /*
* and lookup is done using binary search. * Alternatively, this could be implemented as a sorted, densely packed array
* That would save a small amount of memory because there's no null children entries, * with lookups performed via binary search.
* but would give a worst case search of O(nlog(m)) where n is the number of * This approach would save a small amount of memory by eliminating null
* characters in the searched text and m is the maximum size of the sorted character arrays. * child entries. However, it would result in a worst-case lookup time of
* Using a hash table array always gives O(n) search time. * O(n log m), where:
* The memory usage here is very small (all Litho filters use ~10KB of memory), * - n is the number of characters in the input text, and
* so the more performant hash implementation is chosen. * - m is the maximum size of the sorted character arrays.
* In contrast, using a hash-based array guarantees O(n) lookup time.
* Given that the total memory usage is already very small (all Litho filters
* together use approximately 10KB), the hash-based implementation is preferred
* for its superior performance.
*/ */
@Nullable @Nullable
private TrieNode<T>[] children; private TrieNode<T>[] children;
@ -136,7 +141,7 @@ public abstract class TrieSearch<T> {
* @param patternLength Length of the pattern. * @param patternLength Length of the pattern.
* @param callback Callback, where a value of NULL indicates to always accept a pattern match. * @param callback Callback, where a value of NULL indicates to always accept a pattern match.
*/ */
private void addPattern(@NonNull T pattern, int patternIndex, int patternLength, private void addPattern(T pattern, int patternIndex, int patternLength,
@Nullable TriePatternMatchedCallback<T> callback) { @Nullable TriePatternMatchedCallback<T> callback) {
if (patternIndex == patternLength) { // Reached the end of the pattern. if (patternIndex == patternLength) { // Reached the end of the pattern.
if (endOfPatternCallback == null) { if (endOfPatternCallback == null) {
@ -145,6 +150,7 @@ public abstract class TrieSearch<T> {
endOfPatternCallback.add(callback); endOfPatternCallback.add(callback);
return; return;
} }
if (leaf != null) { if (leaf != null) {
// Reached end of the graph and a leaf exist. // Reached end of the graph and a leaf exist.
// Recursively call back into this method and push the existing leaf down 1 level. // Recursively call back into this method and push the existing leaf down 1 level.
@ -159,6 +165,7 @@ public abstract class TrieSearch<T> {
leaf = new TrieCompressedPath<>(pattern, patternIndex, patternLength, callback); leaf = new TrieCompressedPath<>(pattern, patternIndex, patternLength, callback);
return; return;
} }
final char character = getCharValue(pattern, patternIndex); final char character = getCharValue(pattern, patternIndex);
final int arrayIndex = hashIndexForTableSize(children.length, character); final int arrayIndex = hashIndexForTableSize(children.length, character);
TrieNode<T> child = children[arrayIndex]; TrieNode<T> child = children[arrayIndex];
@ -183,6 +190,7 @@ public abstract class TrieSearch<T> {
//noinspection unchecked //noinspection unchecked
TrieNode<T>[] replacement = new TrieNode[replacementArraySize]; TrieNode<T>[] replacement = new TrieNode[replacementArraySize];
addNodeToArray(replacement, child); addNodeToArray(replacement, child);
boolean collision = false; boolean collision = false;
for (TrieNode<T> existingChild : children) { for (TrieNode<T> existingChild : children) {
if (existingChild != null) { if (existingChild != null) {
@ -195,6 +203,7 @@ public abstract class TrieSearch<T> {
if (collision) { if (collision) {
continue; continue;
} }
children = replacement; children = replacement;
return; return;
} }
@ -234,6 +243,7 @@ public abstract class TrieSearch<T> {
if (leaf != null && leaf.matches(startNode, searchText, searchTextEndIndex, searchTextIndex, callbackParameter)) { if (leaf != null && leaf.matches(startNode, searchText, searchTextEndIndex, searchTextIndex, callbackParameter)) {
return true; // Leaf exists and it matched the search text. return true; // Leaf exists and it matched the search text.
} }
List<TriePatternMatchedCallback<T>> endOfPatternCallback = node.endOfPatternCallback; List<TriePatternMatchedCallback<T>> endOfPatternCallback = node.endOfPatternCallback;
if (endOfPatternCallback != null) { if (endOfPatternCallback != null) {
final int matchStartIndex = searchTextIndex - currentMatchLength; final int matchStartIndex = searchTextIndex - currentMatchLength;
@ -246,6 +256,7 @@ public abstract class TrieSearch<T> {
} }
} }
} }
TrieNode<T>[] children = node.children; TrieNode<T>[] children = node.children;
if (children == null) { if (children == null) {
return false; // Reached a graph end point and there's no further patterns to search. return false; // Reached a graph end point and there's no further patterns to search.
@ -278,9 +289,11 @@ public abstract class TrieSearch<T> {
if (leaf != null) { if (leaf != null) {
numberOfPointers += 4; // Number of fields in leaf node. numberOfPointers += 4; // Number of fields in leaf node.
} }
if (endOfPatternCallback != null) { if (endOfPatternCallback != null) {
numberOfPointers += endOfPatternCallback.size(); numberOfPointers += endOfPatternCallback.size();
} }
if (children != null) { if (children != null) {
numberOfPointers += children.length; numberOfPointers += children.length;
for (TrieNode<T> child : children) { for (TrieNode<T> child : children) {
@ -308,13 +321,13 @@ public abstract class TrieSearch<T> {
private final List<T> patterns = new ArrayList<>(); private final List<T> patterns = new ArrayList<>();
@SafeVarargs @SafeVarargs
TrieSearch(@NonNull TrieNode<T> root, @NonNull T... patterns) { TrieSearch(TrieNode<T> root, T... patterns) {
this.root = Objects.requireNonNull(root); this.root = Objects.requireNonNull(root);
addPatterns(patterns); addPatterns(patterns);
} }
@SafeVarargs @SafeVarargs
public final void addPatterns(@NonNull T... patterns) { public final void addPatterns(T... patterns) {
for (T pattern : patterns) { for (T pattern : patterns) {
addPattern(pattern); addPattern(pattern);
} }
@ -325,7 +338,7 @@ public abstract class TrieSearch<T> {
* *
* @param pattern Pattern to add. Calling this with a zero length pattern does nothing. * @param pattern Pattern to add. Calling this with a zero length pattern does nothing.
*/ */
public void addPattern(@NonNull T pattern) { public void addPattern(T pattern) {
addPattern(pattern, root.getTextLength(pattern), null); addPattern(pattern, root.getTextLength(pattern), null);
} }
@ -333,31 +346,31 @@ public abstract class TrieSearch<T> {
* @param pattern Pattern to add. Calling this with a zero length pattern does nothing. * @param pattern Pattern to add. Calling this with a zero length pattern does nothing.
* @param callback Callback to determine if searching should halt when a match is found. * @param callback Callback to determine if searching should halt when a match is found.
*/ */
public void addPattern(@NonNull T pattern, @NonNull TriePatternMatchedCallback<T> callback) { public void addPattern(T pattern, TriePatternMatchedCallback<T> callback) {
addPattern(pattern, root.getTextLength(pattern), Objects.requireNonNull(callback)); addPattern(pattern, root.getTextLength(pattern), Objects.requireNonNull(callback));
} }
void addPattern(@NonNull T pattern, int patternLength, @Nullable TriePatternMatchedCallback<T> callback) { void addPattern(T pattern, int patternLength, @Nullable TriePatternMatchedCallback<T> callback) {
if (patternLength == 0) return; // Nothing to match if (patternLength == 0) return; // Nothing to match
patterns.add(pattern); patterns.add(pattern);
root.addPattern(pattern, 0, patternLength, callback); root.addPattern(pattern, 0, patternLength, callback);
} }
public final boolean matches(@NonNull T textToSearch) { public final boolean matches(T textToSearch) {
return matches(textToSearch, 0); return matches(textToSearch, 0);
} }
public boolean matches(@NonNull T textToSearch, @NonNull Object callbackParameter) { public boolean matches(T textToSearch, Object callbackParameter) {
return matches(textToSearch, 0, root.getTextLength(textToSearch), return matches(textToSearch, 0, root.getTextLength(textToSearch),
Objects.requireNonNull(callbackParameter)); Objects.requireNonNull(callbackParameter));
} }
public boolean matches(@NonNull T textToSearch, int startIndex) { public boolean matches(T textToSearch, int startIndex) {
return matches(textToSearch, startIndex, root.getTextLength(textToSearch)); return matches(textToSearch, startIndex, root.getTextLength(textToSearch));
} }
public final boolean matches(@NonNull T textToSearch, int startIndex, int endIndex) { public final boolean matches(T textToSearch, int startIndex, int endIndex) {
return matches(textToSearch, startIndex, endIndex, null); return matches(textToSearch, startIndex, endIndex, null);
} }
@ -370,11 +383,11 @@ public abstract class TrieSearch<T> {
* @param callbackParameter Optional parameter passed to the callbacks. * @param callbackParameter Optional parameter passed to the callbacks.
* @return If any pattern matched, and it's callback halted searching. * @return If any pattern matched, and it's callback halted searching.
*/ */
public boolean matches(@NonNull T textToSearch, int startIndex, int endIndex, @Nullable Object callbackParameter) { public boolean matches(T textToSearch, int startIndex, int endIndex, @Nullable Object callbackParameter) {
return matches(textToSearch, root.getTextLength(textToSearch), startIndex, endIndex, callbackParameter); return matches(textToSearch, root.getTextLength(textToSearch), startIndex, endIndex, callbackParameter);
} }
private boolean matches(@NonNull T textToSearch, int textToSearchLength, int startIndex, int endIndex, private boolean matches(T textToSearch, int textToSearchLength, int startIndex, int endIndex,
@Nullable Object callbackParameter) { @Nullable Object callbackParameter) {
if (endIndex > textToSearchLength) { if (endIndex > textToSearchLength) {
throw new IllegalArgumentException("endIndex: " + endIndex throw new IllegalArgumentException("endIndex: " + endIndex

View file

@ -3,14 +3,13 @@ package app.revanced.extension.shared.checks;
import static android.text.Html.FROM_HTML_MODE_COMPACT; import static android.text.Html.FROM_HTML_MODE_COMPACT;
import static app.revanced.extension.shared.StringRef.str; import static app.revanced.extension.shared.StringRef.str;
import static app.revanced.extension.shared.Utils.DialogFragmentOnStartAction; import static app.revanced.extension.shared.Utils.DialogFragmentOnStartAction;
import static app.revanced.extension.shared.Utils.dipToPixels;
import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
import android.content.Intent; import android.content.Intent;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.text.Html; import android.text.Html;
import android.util.Pair; import android.util.Pair;
import android.view.Gravity; import android.view.Gravity;
@ -20,13 +19,17 @@ import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import java.util.Collection; import java.util.Collection;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.ResourceType;
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.ui.CustomDialog;
@RequiresApi(api = Build.VERSION_CODES.N)
abstract class Check { abstract class Check {
private static final int NUMBER_OF_TIMES_TO_IGNORE_WARNING_BEFORE_DISABLING = 2; private static final int NUMBER_OF_TIMES_TO_IGNORE_WARNING_BEFORE_DISABLING = 2;
@ -75,7 +78,6 @@ abstract class Check {
BaseSettings.CHECK_ENVIRONMENT_WARNINGS_ISSUED.save(Integer.MAX_VALUE); BaseSettings.CHECK_ENVIRONMENT_WARNINGS_ISSUED.save(Integer.MAX_VALUE);
} }
@SuppressLint("NewApi")
static void issueWarning(Activity activity, Collection<Check> failedChecks) { static void issueWarning(Activity activity, Collection<Check> failedChecks) {
final var reasons = new StringBuilder(); final var reasons = new StringBuilder();
@ -93,7 +95,7 @@ abstract class Check {
Utils.runOnMainThreadDelayed(() -> { Utils.runOnMainThreadDelayed(() -> {
// Create the custom dialog. // Create the custom dialog.
Pair<Dialog, LinearLayout> dialogPair = Utils.createCustomDialog( Pair<Dialog, LinearLayout> dialogPair = CustomDialog.create(
activity, activity,
str("revanced_check_environment_failed_title"), // Title. str("revanced_check_environment_failed_title"), // Title.
message, // Message. message, // Message.
@ -127,7 +129,8 @@ abstract class Check {
// Add icon to the dialog. // Add icon to the dialog.
ImageView iconView = new ImageView(activity); ImageView iconView = new ImageView(activity);
iconView.setImageResource(Utils.getResourceIdentifier("revanced_ic_dialog_alert", "drawable")); iconView.setImageResource(Utils.getResourceIdentifierOrThrow(
ResourceType.DRAWABLE, "revanced_ic_dialog_alert"));
iconView.setColorFilter(Utils.getAppForegroundColor(), PorterDuff.Mode.SRC_IN); iconView.setColorFilter(Utils.getAppForegroundColor(), PorterDuff.Mode.SRC_IN);
iconView.setPadding(0, 0, 0, 0); iconView.setPadding(0, 0, 0, 0);
LinearLayout.LayoutParams iconParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams iconParams = new LinearLayout.LayoutParams(
@ -158,8 +161,8 @@ abstract class Check {
Button ignoreButton; Button ignoreButton;
// Check if buttons are in a single-row layout (buttonContainer has one child: rowContainer). // Check if buttons are in a single-row layout (buttonContainer has one child: rowContainer).
if (buttonContainer.getChildCount() == 1 && buttonContainer.getChildAt(0) instanceof LinearLayout) { if (buttonContainer.getChildCount() == 1
LinearLayout rowContainer = (LinearLayout) buttonContainer.getChildAt(0); && buttonContainer.getChildAt(0) instanceof LinearLayout rowContainer) {
// Neutral button is the first child (index 0). // Neutral button is the first child (index 0).
ignoreButton = (Button) rowContainer.getChildAt(0); ignoreButton = (Button) rowContainer.getChildAt(0);
// OK button is the last child. // OK button is the last child.

View file

@ -7,8 +7,12 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Build; import android.os.Build;
import android.util.Base64; import android.util.Base64;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
@ -27,6 +31,7 @@ import static app.revanced.extension.shared.checks.PatchInfo.Build.*;
* <br> * <br>
* Various indicators help to detect if the app was patched by the user. * Various indicators help to detect if the app was patched by the user.
*/ */
@RequiresApi(api = Build.VERSION_CODES.N)
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class CheckEnvironmentPatch { public final class CheckEnvironmentPatch {
private static final boolean DEBUG_ALWAYS_SHOW_CHECK_FAILED_DIALOG = debugAlwaysShowWarning(); private static final boolean DEBUG_ALWAYS_SHOW_CHECK_FAILED_DIALOG = debugAlwaysShowWarning();
@ -39,6 +44,7 @@ public final class CheckEnvironmentPatch {
ADB((String) null), ADB((String) null),
ROOT_MOUNT_ON_APP_STORE("com.android.vending"), ROOT_MOUNT_ON_APP_STORE("com.android.vending"),
MANAGER("app.revanced.manager.flutter", MANAGER("app.revanced.manager.flutter",
"app.revanced.manager.flutter.debug",
"app.revanced.manager", "app.revanced.manager",
"app.revanced.manager.debug"); "app.revanced.manager.debug");
@ -118,7 +124,7 @@ public final class CheckEnvironmentPatch {
* If the build properties are different, the app was likely downloaded pre-patched or patched on another device. * If the build properties are different, the app was likely downloaded pre-patched or patched on another device.
*/ */
private static class CheckWasPatchedOnSameDevice extends Check { private static class CheckWasPatchedOnSameDevice extends Check {
@SuppressLint({"NewApi", "HardwareIds"}) @SuppressLint("HardwareIds")
@Override @Override
protected Boolean check() { protected Boolean check() {
if (PATCH_BOARD.isEmpty()) { if (PATCH_BOARD.isEmpty()) {
@ -192,7 +198,7 @@ public final class CheckEnvironmentPatch {
PackageManager packageManager = context.getPackageManager(); PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0); PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
// Duration since initial install or last update, which ever is sooner. // Duration since initial install or last update, whichever is sooner.
durationBetweenPatchingAndInstallation = packageInfo.lastUpdateTime - PatchInfo.PATCH_TIME; durationBetweenPatchingAndInstallation = packageInfo.lastUpdateTime - PatchInfo.PATCH_TIME;
Logger.printInfo(() -> "App was installed/updated: " Logger.printInfo(() -> "App was installed/updated: "
+ (durationBetweenPatchingAndInstallation / (60 * 1000) + " minutes after patching")); + (durationBetweenPatchingAndInstallation / (60 * 1000) + " minutes after patching"));
@ -288,8 +294,8 @@ public final class CheckEnvironmentPatch {
CheckIsNearPatchTime nearPatchTime = new CheckIsNearPatchTime(); CheckIsNearPatchTime nearPatchTime = new CheckIsNearPatchTime();
Boolean timeCheckPassed = nearPatchTime.check(); Boolean timeCheckPassed = nearPatchTime.check();
if (timeCheckPassed && !DEBUG_ALWAYS_SHOW_CHECK_FAILED_DIALOG) { if (timeCheckPassed && !DEBUG_ALWAYS_SHOW_CHECK_FAILED_DIALOG) {
// Allow installing recently patched apks, // Allow installing recently patched APKs,
// even if the install source is not Manager or ADB. // even if the installation source is not Manager or ADB.
Check.disableForever(); Check.disableForever();
return; return;
} else { } else {

View file

@ -15,7 +15,6 @@ import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
public abstract class BaseFixRedgifsApiPatch implements Interceptor { public abstract class BaseFixRedgifsApiPatch implements Interceptor {
protected static BaseFixRedgifsApiPatch INSTANCE; protected static BaseFixRedgifsApiPatch INSTANCE;
public abstract String getDefaultUserAgent(); public abstract String getDefaultUserAgent();

View file

@ -1,4 +1,4 @@
package app.revanced.extension.youtube.patches; package app.revanced.extension.shared.patches;
import static app.revanced.extension.shared.StringRef.str; import static app.revanced.extension.shared.StringRef.str;
@ -13,7 +13,8 @@ import java.net.UnknownHostException;
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.settings.Settings; import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.ui.CustomDialog;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class CheckWatchHistoryDomainNameResolutionPatch { public class CheckWatchHistoryDomainNameResolutionPatch {
@ -45,10 +46,10 @@ public class CheckWatchHistoryDomainNameResolutionPatch {
/** /**
* Injection point. * Injection point.
* *
* Checks if s.youtube.com is blacklisted and playback history will fail to work. * Checks if YouTube watch history endpoint cannot be reached.
*/ */
public static void checkDnsResolver(Activity context) { public static void checkDnsResolver(Activity context) {
if (!Utils.isNetworkConnected() || !Settings.CHECK_WATCH_HISTORY_DOMAIN_NAME.get()) return; if (!Utils.isNetworkConnected() || !BaseSettings.CHECK_WATCH_HISTORY_DOMAIN_NAME.get()) return;
Utils.runOnBackgroundThread(() -> { Utils.runOnBackgroundThread(() -> {
try { try {
@ -60,34 +61,30 @@ public class CheckWatchHistoryDomainNameResolutionPatch {
// Prevent this false positive by verify youtube.com resolves. // Prevent this false positive by verify youtube.com resolves.
// If youtube.com does not resolve, then it's not a watch history domain resolving error // If youtube.com does not resolve, then it's not a watch history domain resolving error
// because the entire app will not work since no domains are resolving. // because the entire app will not work since no domains are resolving.
if (domainResolvesToValidIP(HISTORY_TRACKING_ENDPOINT) String domainYouTube = "youtube.com";
|| !domainResolvesToValidIP("youtube.com")) { if (!domainResolvesToValidIP(domainYouTube)
|| domainResolvesToValidIP(HISTORY_TRACKING_ENDPOINT)
// Check multiple times, so a false positive from a flaky connection is almost impossible.
|| !domainResolvesToValidIP(domainYouTube)
|| domainResolvesToValidIP(HISTORY_TRACKING_ENDPOINT)) {
return; return;
} }
Utils.runOnMainThread(() -> { Utils.runOnMainThread(() -> {
try { Pair<Dialog, LinearLayout> dialogPair = CustomDialog.create(
// Create the custom dialog. context,
Pair<Dialog, LinearLayout> dialogPair = Utils.createCustomDialog( str("revanced_check_watch_history_domain_name_dialog_title"), // Title.
context, Html.fromHtml(str("revanced_check_watch_history_domain_name_dialog_message")), // Message (HTML).
str("revanced_check_watch_history_domain_name_dialog_title"), // Title. null, // No EditText.
Html.fromHtml(str("revanced_check_watch_history_domain_name_dialog_message")), // Message (HTML). null, // OK button text.
null, // No EditText. () -> {}, // OK button action (just dismiss).
null, // OK button text. null, // No cancel button.
() -> {}, // OK button action (just dismiss). str("revanced_check_watch_history_domain_name_dialog_ignore"), // Neutral button text.
() -> {}, // Cancel button action (just dismiss). () -> BaseSettings.CHECK_WATCH_HISTORY_DOMAIN_NAME.save(false), // Neutral button action (Ignore).
str("revanced_check_watch_history_domain_name_dialog_ignore"), // Neutral button text. true // Dismiss dialog on Neutral button click.
() -> Settings.CHECK_WATCH_HISTORY_DOMAIN_NAME.save(false), // Neutral button action (Ignore). );
true // Dismiss dialog on Neutral button click.
);
// Show the dialog. Utils.showDialog(context, dialogPair.first, false, null);
Dialog dialog = dialogPair.first;
Utils.showDialog(context, dialog, false, null);
} catch (Exception ex) {
Logger.printException(() -> "checkDnsResolver dialog creation failure", ex);
}
}); });
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "checkDnsResolver failure", ex); Logger.printException(() -> "checkDnsResolver failure", ex);

View file

@ -0,0 +1,227 @@
package app.revanced.extension.shared.patches;
import android.app.Notification;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.view.View;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import app.revanced.extension.shared.GmsCoreSupport;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.ResourceType;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
/**
* Patch shared by YouTube and YT Music.
*/
@SuppressWarnings("unused")
public class CustomBrandingPatch {
// Important: In the future, additional branding themes can be added but all existing and prior
// themes cannot be removed or renamed.
//
// This is because if a user has a branding theme selected, then only that launch alias is enabled.
// If a future update removes or renames that alias, then after updating the app is effectively
// broken and it cannot be opened and not even clearing the app data will fix it.
// In that situation the only fix is to completely uninstall and reinstall again.
//
// The most that can be done is to hide a theme from the UI and keep the alias with dummy data.
public enum BrandingTheme {
/**
* Original unpatched icon.
*/
ORIGINAL,
ROUNDED,
MINIMAL,
SCALED,
/**
* User provided custom icon.
*/
CUSTOM;
private String packageAndNameIndexToClassAlias(String packageName, int appIndex) {
if (appIndex <= 0) {
throw new IllegalArgumentException("App index starts at index 1");
}
return packageName + ".revanced_" + name().toLowerCase(Locale.US) + '_' + appIndex;
}
}
@Nullable
private static Integer notificationSmallIcon;
private static int getNotificationSmallIcon() {
// Cannot use static initialization block otherwise cyclic references exist
// between Settings initialization and this class.
if (notificationSmallIcon == null) {
if (GmsCoreSupport.isPackageNameOriginal()) {
Logger.printDebug(() -> "App is root mounted. Not overriding small notification icon");
return notificationSmallIcon = 0;
}
BrandingTheme branding = BaseSettings.CUSTOM_BRANDING_ICON.get();
if (branding == BrandingTheme.ORIGINAL) {
notificationSmallIcon = 0;
} else {
// Original icon is quantum_ic_video_youtube_white_24
String iconName = "revanced_notification_icon";
if (branding == BrandingTheme.CUSTOM) {
iconName += "_custom";
}
notificationSmallIcon = Utils.getResourceIdentifier(ResourceType.DRAWABLE, iconName);
if (notificationSmallIcon == 0) {
Logger.printException(() -> "Could not load notification small icon");
}
}
}
return notificationSmallIcon;
}
/**
* Injection point.
*/
public static View getLottieViewOrNull(View lottieStartupView) {
if (BaseSettings.CUSTOM_BRANDING_ICON.get() == BrandingTheme.ORIGINAL) {
return lottieStartupView;
}
return null;
}
/**
* Injection point.
*/
public static void setNotificationIcon(Notification.Builder builder) {
try {
final int smallIcon = getNotificationSmallIcon();
if (smallIcon != 0) {
builder.setSmallIcon(smallIcon)
.setColor(Color.TRANSPARENT); // Remove YT red tint.
}
} catch (Exception ex) {
Logger.printException(() -> "setNotificationIcon failure", ex);
}
}
/**
* Injection point.
* <p>
* The total number of app name aliases, including dummy aliases.
*/
private static int numberOfPresetAppNames() {
// Modified during patching, but requires a default if custom branding is excluded.
return 1;
}
/**
* Injection point.
* <p>
* If a custom icon was provided during patching.
*/
private static boolean userProvidedCustomIcon() {
// Modified during patching, but requires a default if custom branding is excluded.
return false;
}
/**
* Injection point.
* <p>
* If a custom name was provided during patching.
*/
private static boolean userProvidedCustomName() {
// Modified during patching, but requires a default if custom branding is excluded..
return false;
}
public static int getDefaultAppNameIndex() {
return userProvidedCustomName()
? numberOfPresetAppNames()
: 2;
}
public static BrandingTheme getDefaultIconStyle() {
return userProvidedCustomIcon()
? BrandingTheme.CUSTOM
: BrandingTheme.ROUNDED;
}
/**
* Injection point.
*/
@SuppressWarnings("ConstantConditions")
public static void setBranding() {
try {
if (GmsCoreSupport.isPackageNameOriginal()) {
Logger.printInfo(() -> "App is root mounted. Cannot dynamically change app icon");
return;
}
Context context = Utils.getContext();
PackageManager pm = context.getPackageManager();
String packageName = context.getPackageName();
BrandingTheme selectedBranding = BaseSettings.CUSTOM_BRANDING_ICON.get();
final int selectedNameIndex = BaseSettings.CUSTOM_BRANDING_NAME.get();
ComponentName componentToEnable = null;
ComponentName defaultComponent = null;
List<ComponentName> componentsToDisable = new ArrayList<>();
for (BrandingTheme theme : BrandingTheme.values()) {
// Must always update all aliases including custom alias (last index).
final int numberOfPresetAppNames = numberOfPresetAppNames();
// App name indices starts at 1.
for (int index = 1; index <= numberOfPresetAppNames; index++) {
String aliasClass = theme.packageAndNameIndexToClassAlias(packageName, index);
ComponentName component = new ComponentName(packageName, aliasClass);
if (defaultComponent == null) {
// Default is always the first alias.
defaultComponent = component;
}
if (index == selectedNameIndex && theme == selectedBranding) {
componentToEnable = component;
} else {
componentsToDisable.add(component);
}
}
}
if (componentToEnable == null) {
// User imported a bad app name index value. Either the imported data
// was corrupted, or they previously had custom name enabled and the app
// no longer has a custom name specified.
Utils.showToastLong("Custom branding reset");
BaseSettings.CUSTOM_BRANDING_ICON.resetToDefault();
BaseSettings.CUSTOM_BRANDING_NAME.resetToDefault();
componentToEnable = defaultComponent;
componentsToDisable.remove(defaultComponent);
}
for (ComponentName disable : componentsToDisable) {
pm.setComponentEnabledSetting(disable,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
// Use info logging because if the alias status become corrupt the app cannot launch.
ComponentName componentToEnableFinal = componentToEnable;
Logger.printInfo(() -> "Enabling: " + componentToEnableFinal.getClassName());
pm.setComponentEnabledSetting(componentToEnable,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
} catch (Exception ex) {
Logger.printException(() -> "setBranding failure", ex);
}
}
}

View file

@ -1,5 +1,9 @@
package app.revanced.extension.youtube.patches; package app.revanced.extension.shared.patches;
import static java.lang.Boolean.TRUE;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
@ -21,12 +25,29 @@ public final class EnableDebuggingPatch {
? new ConcurrentHashMap<>(800, 0.5f, 1) ? new ConcurrentHashMap<>(800, 0.5f, 1)
: null; : null;
private static final Set<Long> DISABLED_FEATURE_FLAGS = parseFlags(BaseSettings.DISABLED_FEATURE_FLAGS.get());
// Log all disabled flags on app startup.
static {
if (LOG_FEATURE_FLAGS && !DISABLED_FEATURE_FLAGS.isEmpty()) {
StringBuilder sb = new StringBuilder("Disabled feature flags:\n");
for (Long flag : DISABLED_FEATURE_FLAGS) {
sb.append(" ").append(flag).append('\n');
}
Logger.printDebug(sb::toString);
}
}
/** /**
* Injection point. * Injection point.
*/ */
public static boolean isBooleanFeatureFlagEnabled(boolean value, Long flag) { public static boolean isBooleanFeatureFlagEnabled(boolean value, long flag) {
if (LOG_FEATURE_FLAGS && value) { if (LOG_FEATURE_FLAGS && value) {
if (featureFlags.putIfAbsent(flag, true) == null) { Long flagObj = flag;
if (DISABLED_FEATURE_FLAGS.contains(flagObj)) {
return false;
}
if (featureFlags.putIfAbsent(flagObj, TRUE) == null) {
Logger.printDebug(() -> "boolean feature is enabled: " + flag); Logger.printDebug(() -> "boolean feature is enabled: " + flag);
} }
} }
@ -39,6 +60,8 @@ public final class EnableDebuggingPatch {
*/ */
public static double isDoubleFeatureFlagEnabled(double value, long flag, double defaultValue) { public static double isDoubleFeatureFlagEnabled(double value, long flag, double defaultValue) {
if (LOG_FEATURE_FLAGS && defaultValue != value) { if (LOG_FEATURE_FLAGS && defaultValue != value) {
if (DISABLED_FEATURE_FLAGS.contains(flag)) return defaultValue;
if (featureFlags.putIfAbsent(flag, true) == null) { if (featureFlags.putIfAbsent(flag, true) == null) {
// Align the log outputs to make post processing easier. // Align the log outputs to make post processing easier.
Logger.printDebug(() -> " double feature is enabled: " + flag Logger.printDebug(() -> " double feature is enabled: " + flag
@ -54,6 +77,8 @@ public final class EnableDebuggingPatch {
*/ */
public static long isLongFeatureFlagEnabled(long value, long flag, long defaultValue) { public static long isLongFeatureFlagEnabled(long value, long flag, long defaultValue) {
if (LOG_FEATURE_FLAGS && defaultValue != value) { if (LOG_FEATURE_FLAGS && defaultValue != value) {
if (DISABLED_FEATURE_FLAGS.contains(flag)) return defaultValue;
if (featureFlags.putIfAbsent(flag, true) == null) { if (featureFlags.putIfAbsent(flag, true) == null) {
Logger.printDebug(() -> " long feature is enabled: " + flag Logger.printDebug(() -> " long feature is enabled: " + flag
+ " value: " + value + (defaultValue == 0 ? "" : " default: " + defaultValue)); + " value: " + value + (defaultValue == 0 ? "" : " default: " + defaultValue));
@ -70,10 +95,44 @@ public final class EnableDebuggingPatch {
if (LOG_FEATURE_FLAGS && !defaultValue.equals(value)) { if (LOG_FEATURE_FLAGS && !defaultValue.equals(value)) {
if (featureFlags.putIfAbsent(flag, true) == null) { if (featureFlags.putIfAbsent(flag, true) == null) {
Logger.printDebug(() -> " string feature is enabled: " + flag Logger.printDebug(() -> " string feature is enabled: " + flag
+ " value: " + value + (defaultValue.isEmpty() ? "" : " default: " + defaultValue)); + " value: " + value + (defaultValue.isEmpty() ? "" : " default: " + defaultValue));
} }
} }
return value; return value;
} }
/**
* Get all logged feature flags.
* @return Set of all known flags
*/
public static Set<Long> getAllLoggedFlags() {
if (featureFlags != null) {
return new HashSet<>(featureFlags.keySet());
}
return new HashSet<>();
}
/**
* Public method for parsing flags.
* @param flags String containing newline-separated flag IDs
* @return Set of parsed flag IDs
*/
public static Set<Long> parseFlags(String flags) {
Set<Long> parsedFlags = new HashSet<>();
if (!flags.isBlank()) {
for (String flag : flags.split("\n")) {
String trimmedFlag = flag.trim();
if (trimmedFlag.isEmpty()) continue; // Skip empty lines.
try {
parsedFlags.add(Long.parseLong(trimmedFlag));
} catch (NumberFormatException e) {
Logger.printException(() -> "Invalid flag ID: " + flag);
}
}
}
return parsedFlags;
}
} }

View file

@ -0,0 +1,71 @@
package app.revanced.extension.shared.patches;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.AppLanguage;
import app.revanced.extension.shared.spoof.ClientType;
import app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch;
@SuppressWarnings("unused")
public class ForceOriginalAudioPatch {
private static final String DEFAULT_AUDIO_TRACKS_SUFFIX = ".4";
private static volatile boolean enabled;
public static void setEnabled(boolean isEnabled, ClientType client) {
enabled = isEnabled;
if (isEnabled && !client.useAuth && !client.supportsMultiAudioTracks) {
// If client spoofing does not use authentication and lacks multi-audio streams,
// then can use any language code for the request and if that requested language is
// not available YT uses the original audio language. Authenticated requests ignore
// the language code and always use the account language. Use a language that is
// not auto-dubbed by YouTube: https://support.google.com/youtube/answer/15569972
// but the language is also supported natively by the Meta Quest device that
// Android VR is spoofing.
AppLanguage override = AppLanguage.NB; // Norwegian Bokmal.
Logger.printDebug(() -> "Setting language override: " + override);
SpoofVideoStreamsPatch.setLanguageOverride(override);
}
}
/**
* Injection point.
*/
public static boolean ignoreDefaultAudioStream(boolean original) {
if (enabled) {
return false;
}
return original;
}
/**
* Injection point.
*/
public static boolean isDefaultAudioStream(boolean isDefault, String audioTrackId, String audioTrackDisplayName) {
try {
if (!enabled) {
return isDefault;
}
if (audioTrackId.isEmpty()) {
// Older app targets can have empty audio tracks and these might be placeholders.
// The real audio tracks are called after these.
return isDefault;
}
Logger.printDebug(() -> "default: " + String.format("%-5s", isDefault) + " id: "
+ String.format("%-8s", audioTrackId) + " name:" + audioTrackDisplayName);
final boolean isOriginal = audioTrackId.endsWith(DEFAULT_AUDIO_TRACKS_SUFFIX);
if (isOriginal) {
Logger.printDebug(() -> "Using audio: " + audioTrackId);
}
return isOriginal;
} catch (Exception ex) {
Logger.printException(() -> "isDefaultAudioStream failure", ex);
return isDefault;
}
}
}

View file

@ -0,0 +1,31 @@
package app.revanced.extension.shared.patches;
import app.revanced.extension.shared.privacy.LinkSanitizer;
import app.revanced.extension.shared.settings.BaseSettings;
/**
* YouTube and YouTube Music.
*/
@SuppressWarnings("unused")
public final class SanitizeSharingLinksPatch {
private static final LinkSanitizer sanitizer = new LinkSanitizer(
"si",
"feature" // Old tracking parameter name, and may be obsolete.
);
/**
* Injection point.
*/
public static String sanitize(String url) {
if (BaseSettings.SANITIZE_SHARING_LINKS.get()) {
url = sanitizer.sanitizeURLString(url);
}
if (BaseSettings.REPLACE_MUSIC_LINKS_WITH_YOUTUBE.get()) {
url = url.replace("music.youtube.com", "youtube.com");
}
return url;
}
}

View file

@ -1,4 +1,4 @@
package app.revanced.extension.youtube.patches.components; package app.revanced.extension.shared.patches.litho;
import static app.revanced.extension.shared.StringRef.str; import static app.revanced.extension.shared.StringRef.str;
@ -13,17 +13,19 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.StringTrieSearch;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.ByteTrieSearch; import app.revanced.extension.shared.ByteTrieSearch;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.shared.patches.litho.FilterGroup.StringFilterGroup;
import app.revanced.extension.shared.settings.YouTubeAndMusicSettings;
/** /**
* Allows custom filtering using a path and optionally a proto buffer string. * Allows custom filtering using a path and optionally a proto buffer string.
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
final class CustomFilter extends Filter { public final class CustomFilter extends Filter {
private static void showInvalidSyntaxToast(@NonNull String expression) { private static void showInvalidSyntaxToast(String expression) {
Utils.showToastLong(str("revanced_custom_filter_toast_invalid_syntax", expression)); Utils.showToastLong(str("revanced_custom_filter_toast_invalid_syntax", expression));
} }
@ -35,7 +37,12 @@ final class CustomFilter extends Filter {
public static final String SYNTAX_STARTS_WITH = "^"; public static final String SYNTAX_STARTS_WITH = "^";
/** /**
* Optional character that separates the path from a proto buffer string pattern. * Optional character that separates the path from an accessibility string pattern.
*/
public static final String SYNTAX_ACCESSIBILITY_SYMBOL = "#";
/**
* Optional character that separates the path/accessibility from a proto buffer string pattern.
*/ */
public static final String SYNTAX_BUFFER_SYMBOL = "$"; public static final String SYNTAX_BUFFER_SYMBOL = "$";
@ -45,20 +52,26 @@ final class CustomFilter extends Filter {
@NonNull @NonNull
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
static Collection<CustomFilterGroup> parseCustomFilterGroups() { static Collection<CustomFilterGroup> parseCustomFilterGroups() {
String rawCustomFilterText = Settings.CUSTOM_FILTER_STRINGS.get(); String rawCustomFilterText = YouTubeAndMusicSettings.CUSTOM_FILTER_STRINGS.get();
if (rawCustomFilterText.isBlank()) { if (rawCustomFilterText.isBlank()) {
return Collections.emptyList(); return Collections.emptyList();
} }
// Map key is the path including optional special characters (^ and/or $) // Map key is the full path including optional special characters (^, #, $),
// and any accessibility pattern, but does not contain any buffer patterns.
Map<String, CustomFilterGroup> result = new HashMap<>(); Map<String, CustomFilterGroup> result = new HashMap<>();
Pattern pattern = Pattern.compile( Pattern pattern = Pattern.compile(
"(" // map key group "(" // Map key group.
+ "(\\Q" + SYNTAX_STARTS_WITH + "\\E?)" // optional starts with // Optional starts with.
+ "([^\\Q" + SYNTAX_BUFFER_SYMBOL + "\\E]*)" // path + "(\\Q" + SYNTAX_STARTS_WITH + "\\E?)"
+ "(\\Q" + SYNTAX_BUFFER_SYMBOL + "\\E?)" // optional buffer symbol // Path string.
+ ")" // end map key group + "([^\\Q" + SYNTAX_ACCESSIBILITY_SYMBOL + SYNTAX_BUFFER_SYMBOL + "\\E]*)"
+ "(.*)"); // optional buffer string // Optional accessibility string.
+ "(?:\\Q" + SYNTAX_ACCESSIBILITY_SYMBOL + "\\E([^\\Q" + SYNTAX_BUFFER_SYMBOL + "\\E]*))?"
// Optional buffer string.
+ "(?:\\Q" + SYNTAX_BUFFER_SYMBOL + "\\E(.*))?"
+ ")"); // end map key group
for (String expression : rawCustomFilterText.split("\n")) { for (String expression : rawCustomFilterText.split("\n")) {
if (expression.isBlank()) continue; if (expression.isBlank()) continue;
@ -72,10 +85,12 @@ final class CustomFilter extends Filter {
final String mapKey = matcher.group(1); final String mapKey = matcher.group(1);
final boolean pathStartsWith = !matcher.group(2).isEmpty(); final boolean pathStartsWith = !matcher.group(2).isEmpty();
final String path = matcher.group(3); final String path = matcher.group(3);
final boolean hasBufferSymbol = !matcher.group(4).isEmpty(); final String accessibility = matcher.group(4); // null if not present
final String bufferString = matcher.group(5); final String buffer = matcher.group(5); // null if not present
if (path.isBlank() || (hasBufferSymbol && bufferString.isBlank())) { if (path.isBlank()
|| (accessibility != null && accessibility.isEmpty())
|| (buffer != null && buffer.isEmpty())) {
showInvalidSyntaxToast(expression); showInvalidSyntaxToast(expression);
continue; continue;
} }
@ -88,8 +103,13 @@ final class CustomFilter extends Filter {
group = new CustomFilterGroup(pathStartsWith, path); group = new CustomFilterGroup(pathStartsWith, path);
result.put(mapKey, group); result.put(mapKey, group);
} }
if (hasBufferSymbol) {
group.addBufferString(bufferString); if (accessibility != null) {
group.addAccessibilityString(accessibility);
}
if (buffer != null) {
group.addBufferString(buffer);
} }
} }
@ -97,14 +117,22 @@ final class CustomFilter extends Filter {
} }
final boolean startsWith; final boolean startsWith;
StringTrieSearch accessibilitySearch;
ByteTrieSearch bufferSearch; ByteTrieSearch bufferSearch;
CustomFilterGroup(boolean startsWith, @NonNull String path) { CustomFilterGroup(boolean startsWith, String path) {
super(Settings.CUSTOM_FILTER, path); super(YouTubeAndMusicSettings.CUSTOM_FILTER, path);
this.startsWith = startsWith; this.startsWith = startsWith;
} }
void addBufferString(@NonNull String bufferString) { void addAccessibilityString(String accessibilityString) {
if (accessibilitySearch == null) {
accessibilitySearch = new StringTrieSearch();
}
accessibilitySearch.addPattern(accessibilityString);
}
void addBufferString(String bufferString) {
if (bufferSearch == null) { if (bufferSearch == null) {
bufferSearch = new ByteTrieSearch(); bufferSearch = new ByteTrieSearch();
} }
@ -116,6 +144,11 @@ final class CustomFilter extends Filter {
public String toString() { public String toString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("CustomFilterGroup{"); builder.append("CustomFilterGroup{");
if (accessibilitySearch != null) {
builder.append(", accessibility=");
builder.append(accessibilitySearch.getPatterns());
}
builder.append("path="); builder.append("path=");
if (startsWith) builder.append(SYNTAX_STARTS_WITH); if (startsWith) builder.append(SYNTAX_STARTS_WITH);
builder.append(filters[0]); builder.append(filters[0]);
@ -145,18 +178,26 @@ final class CustomFilter extends Filter {
} }
@Override @Override
boolean isFiltered(String identifier, String path, byte[] buffer, public boolean isFiltered(String identifier, String accessibility, String path, byte[] buffer,
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) { StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
// All callbacks are custom filter groups. // All callbacks are custom filter groups.
CustomFilterGroup custom = (CustomFilterGroup) matchedGroup; CustomFilterGroup custom = (CustomFilterGroup) matchedGroup;
// Check path start requirement.
if (custom.startsWith && contentIndex != 0) { if (custom.startsWith && contentIndex != 0) {
return false; return false;
} }
if (custom.bufferSearch == null) { // Check accessibility string if specified.
return true; // No buffer filter, only path filtering. if (custom.accessibilitySearch != null && !custom.accessibilitySearch.matches(accessibility)) {
return false;
} }
return custom.bufferSearch.matches(buffer); // Check buffer if specified.
if (custom.bufferSearch != null && !custom.bufferSearch.matches(buffer)) {
return false;
}
return true; // All custom filter conditions passed.
} }
} }

View file

@ -1,4 +1,7 @@
package app.revanced.extension.youtube.patches.components; package app.revanced.extension.shared.patches.litho;
import app.revanced.extension.shared.patches.litho.FilterGroup.ByteArrayFilterGroup;
import app.revanced.extension.shared.patches.litho.FilterGroup.StringFilterGroup;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -10,19 +13,20 @@ import java.util.List;
* Callbacks to filter content are added using {@link #addIdentifierCallbacks(StringFilterGroup...)} * Callbacks to filter content are added using {@link #addIdentifierCallbacks(StringFilterGroup...)}
* and {@link #addPathCallbacks(StringFilterGroup...)}. * and {@link #addPathCallbacks(StringFilterGroup...)}.
* *
* To filter {@link FilterContentType#PROTOBUFFER}, first add a callback to * To filter {@link FilterContentType#PROTOBUFFER} or {@link FilterContentType#ACCESSIBILITY}, first add a callback to
* either an identifier or a path. * either an identifier or a path.
* Then inside {@link #isFiltered(String, String, byte[], StringFilterGroup, FilterContentType, int)} * Then inside {@link #isFiltered(String, String, String, byte[], StringFilterGroup, FilterContentType, int)}
* search for the buffer content using either a {@link ByteArrayFilterGroup} (if searching for 1 pattern) * search for the buffer content using either a {@link ByteArrayFilterGroup} (if searching for 1 pattern)
* or a {@link ByteArrayFilterGroupList} (if searching for more than 1 pattern). * or a {@link FilterGroupList.ByteArrayFilterGroupList} (if searching for more than 1 pattern).
* *
* All callbacks must be registered before the constructor completes. * All callbacks must be registered before the constructor completes.
*/ */
abstract class Filter { public abstract class Filter {
public enum FilterContentType { public enum FilterContentType {
IDENTIFIER, IDENTIFIER,
PATH, PATH,
ACCESSIBILITY,
PROTOBUFFER PROTOBUFFER
} }
@ -30,15 +34,15 @@ abstract class Filter {
* Identifier callbacks. Do not add to this instance, * Identifier callbacks. Do not add to this instance,
* and instead use {@link #addIdentifierCallbacks(StringFilterGroup...)}. * and instead use {@link #addIdentifierCallbacks(StringFilterGroup...)}.
*/ */
protected final List<StringFilterGroup> identifierCallbacks = new ArrayList<>(); public final List<StringFilterGroup> identifierCallbacks = new ArrayList<>();
/** /**
* Path callbacks. Do not add to this instance, * Path callbacks. Do not add to this instance,
* and instead use {@link #addPathCallbacks(StringFilterGroup...)}. * and instead use {@link #addPathCallbacks(StringFilterGroup...)}.
*/ */
protected final List<StringFilterGroup> pathCallbacks = new ArrayList<>(); public final List<StringFilterGroup> pathCallbacks = new ArrayList<>();
/** /**
* Adds callbacks to {@link #isFiltered(String, String, byte[], StringFilterGroup, FilterContentType, int)} * Adds callbacks to {@link #isFiltered(String, String, String, byte[], StringFilterGroup, FilterContentType, int)}
* if any of the groups are found. * if any of the groups are found.
*/ */
protected final void addIdentifierCallbacks(StringFilterGroup... groups) { protected final void addIdentifierCallbacks(StringFilterGroup... groups) {
@ -46,7 +50,7 @@ abstract class Filter {
} }
/** /**
* Adds callbacks to {@link #isFiltered(String, String, byte[], StringFilterGroup, FilterContentType, int)} * Adds callbacks to {@link #isFiltered(String, String, String, byte[], StringFilterGroup, FilterContentType, int)}
* if any of the groups are found. * if any of the groups are found.
*/ */
protected final void addPathCallbacks(StringFilterGroup... groups) { protected final void addPathCallbacks(StringFilterGroup... groups) {
@ -60,12 +64,15 @@ abstract class Filter {
* <p> * <p>
* Method is called off the main thread. * Method is called off the main thread.
* *
* @param identifier Litho identifier.
* @param accessibility Accessibility string, or an empty string if not present for the component.
* @param buffer Protocol buffer.
* @param matchedGroup The actual filter that matched. * @param matchedGroup The actual filter that matched.
* @param contentType The type of content matched. * @param contentType The type of content matched.
* @param contentIndex Matched index of the identifier or path. * @param contentIndex Matched index of the identifier or path.
* @return True if the litho component should be filtered out. * @return True if the litho component should be filtered out.
*/ */
boolean isFiltered(String identifier, String path, byte[] buffer, public boolean isFiltered(String identifier, String accessibility, String path, byte[] buffer,
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) { StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
return true; return true;
} }

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