1
mirror of https://github.com/revanced/revanced-integrations synced 2025-11-19 03:23:27 +01:00

Compare commits

...

51 Commits

Author SHA1 Message Date
semantic-release-bot
a97eab5fcd chore(release): 0.108.0-dev.7 [skip ci]
# [0.108.0-dev.7](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.6...v0.108.0-dev.7) (2023-05-10)

### Bug Fixes

* **youtube/hide-ads:** don't filter for `reels_player_overlay` ([415c194](415c1948fc))
2023-05-10 00:24:32 +00:00
oSumAtrIX
415c1948fc fix(youtube/hide-ads): don't filter for reels_player_overlay
This fixes hiding Shorts ads layouts unintentionally
2023-05-10 02:22:08 +02:00
semantic-release-bot
1f72d17d49 chore(release): 0.108.0-dev.6 [skip ci]
# [0.108.0-dev.6](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.5...v0.108.0-dev.6) (2023-05-09)

### Bug Fixes

* **youtube/spoof-app-version:** restore watch history preview ([#394](https://github.com/revanced/revanced-integrations/issues/394)) ([4c7f737](4c7f737913))
2023-05-09 20:33:44 +00:00
LisoUseInAIKyrios
4c7f737913 fix(youtube/spoof-app-version): restore watch history preview (#394) 2023-05-10 00:31:21 +04:00
semantic-release-bot
9e6176886b chore(release): 0.108.0-dev.5 [skip ci]
# [0.108.0-dev.5](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.4...v0.108.0-dev.5) (2023-05-09)

### Bug Fixes

* **youtube/remember-video-quality:** fix default video quality/speed being applied when resuming app ([#392](https://github.com/revanced/revanced-integrations/issues/392)) ([c97d1b7](c97d1b7ee5))
2023-05-09 15:52:58 +00:00
LisoUseInAIKyrios
c97d1b7ee5 fix(youtube/remember-video-quality): fix default video quality/speed being applied when resuming app (#392) 2023-05-09 19:50:56 +04:00
oSumAtrIX
4fe923527e build: update gradle 2023-05-09 03:28:56 +02:00
semantic-release-bot
111d2f21f9 chore(release): 0.108.0-dev.4 [skip ci]
# [0.108.0-dev.4](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.3...v0.108.0-dev.4) (2023-05-07)

### Features

* **youtube/hide-player-overlay:** make it toggleable in settings ([#382](https://github.com/revanced/revanced-integrations/issues/382)) ([1b4aa0f](1b4aa0fcc6))
2023-05-07 23:59:40 +00:00
johnconner122
1b4aa0fcc6 feat(youtube/hide-player-overlay): make it toggleable in settings (#382) 2023-05-08 01:57:37 +02:00
semantic-release-bot
9e9399ddc3 chore(release): 0.108.0-dev.3 [skip ci]
# [0.108.0-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.2...v0.108.0-dev.3) (2023-05-07)

### Features

* **youtube:** `hide-load-more-button` patch ([#389](https://github.com/revanced/revanced-integrations/issues/389)) ([7da9d44](7da9d440ee))
2023-05-07 15:28:45 +00:00
johnconner122
7da9d440ee feat(youtube): hide-load-more-button patch (#389) 2023-05-07 17:26:56 +02:00
oSumAtrIX
43b007e865 docs: improve README structure 2023-05-07 03:03:43 +02:00
oSumAtrIX
8997ab7962 refactor: simplify casting instructions 2023-05-06 23:18:55 +02:00
semantic-release-bot
ad812cd011 chore(release): 0.108.0-dev.2 [skip ci]
# [0.108.0-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.1...v0.108.0-dev.2) (2023-05-05)

### Bug Fixes

* **youtube/theme:** fix app crash if user clears seekbar color ([#390](https://github.com/revanced/revanced-integrations/issues/390)) ([e2f5290](e2f52905dc))
2023-05-05 06:34:26 +00:00
LisoUseInAIKyrios
e2f52905dc fix(youtube/theme): fix app crash if user clears seekbar color (#390) 2023-05-05 10:32:10 +04:00
semantic-release-bot
2882ec1c9c chore(release): 0.108.0-dev.1 [skip ci]
# [0.108.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.107.1-dev.3...v0.108.0-dev.1) (2023-05-03)

### Features

* **youtube/settings:** add reset button to edit preference dialog ([#383](https://github.com/revanced/revanced-integrations/issues/383)) ([cb5a4d0](cb5a4d0c9b))
2023-05-03 07:52:45 +00:00
LisoUseInAIKyrios
cb5a4d0c9b feat(youtube/settings): add reset button to edit preference dialog (#383) 2023-05-03 11:50:22 +04:00
semantic-release-bot
b9ffd3853c chore(release): 0.107.1-dev.3 [skip ci]
## [0.107.1-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.107.1-dev.2...v0.107.1-dev.3) (2023-05-03)

### Bug Fixes

* **youtube/theme:** fix toast shown on fresh app install ([#381](https://github.com/revanced/revanced-integrations/issues/381)) ([2dc431f](2dc431f1bf))
2023-05-03 07:48:36 +00:00
LisoUseInAIKyrios
2dc431f1bf fix(youtube/theme): fix toast shown on fresh app install (#381) 2023-05-03 11:46:24 +04:00
semantic-release-bot
513d4e4542 chore(release): 0.107.1-dev.2 [skip ci]
## [0.107.1-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.107.1-dev.1...v0.107.1-dev.2) (2023-05-03)

### Bug Fixes

* **youtube/sponsorblock:** fix skip button in wrong location when full screen and comments visible ([#387](https://github.com/revanced/revanced-integrations/issues/387)) ([486b79b](486b79b4e4))
2023-05-03 07:31:28 +00:00
LisoUseInAIKyrios
486b79b4e4 fix(youtube/sponsorblock): fix skip button in wrong location when full screen and comments visible (#387) 2023-05-03 11:29:29 +04:00
semantic-release-bot
680f17257d chore(release): 0.107.1-dev.1 [skip ci]
## [0.107.1-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.107.0...v0.107.1-dev.1) (2023-05-02)

### Bug Fixes

* **youtube/return-youtube-dislike:** fix potential error toast when using old UI layout ([#384](https://github.com/revanced/revanced-integrations/issues/384)) ([6c36bee](6c36beeda1))
2023-05-02 11:33:16 +00:00
LisoUseInAIKyrios
6c36beeda1 fix(youtube/return-youtube-dislike): fix potential error toast when using old UI layout (#384) 2023-05-02 15:30:45 +04:00
semantic-release-bot
12c7c6844b chore(release): 0.107.0 [skip ci]
# [0.107.0](https://github.com/revanced/revanced-integrations/compare/v0.106.0...v0.107.0) (2023-05-02)

### Bug Fixes

* **youtube/theme:** set correct default seekbar color ([a91b036](a91b0363a8))

### Features

* **youtube/theme:** change seekbar color via preference ([1185cee](1185ceedf7))
* **youtube:** `navigation-buttons` patch ([68f42fc](68f42fc980))
2023-05-02 05:48:50 +00:00
oSumAtrIX
9b47361af4 chore: merge branch dev to main (#380) 2023-05-02 07:46:36 +02:00
semantic-release-bot
8ba636a910 chore(release): 0.107.0-dev.3 [skip ci]
# [0.107.0-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.107.0-dev.2...v0.107.0-dev.3) (2023-05-02)

### Features

* **youtube:** `navigation-buttons` patch ([68f42fc](68f42fc980))
2023-05-02 05:40:00 +00:00
oSumAtrIX
68f42fc980 feat(youtube): navigation-buttons patch 2023-05-02 07:37:40 +02:00
semantic-release-bot
8255909b2f chore(release): 0.107.0-dev.2 [skip ci]
# [0.107.0-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.107.0-dev.1...v0.107.0-dev.2) (2023-05-02)

### Bug Fixes

* **youtube/theme:** set correct default seekbar color ([a91b036](a91b0363a8))
2023-05-02 03:38:49 +00:00
oSumAtrIX
a91b0363a8 fix(youtube/theme): set correct default seekbar color 2023-05-02 05:36:04 +02:00
semantic-release-bot
e34e75133c chore(release): 0.107.0-dev.1 [skip ci]
# [0.107.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.106.0...v0.107.0-dev.1) (2023-05-02)

### Features

* **youtube/theme:** change seekbar color via preference ([1185cee](1185ceedf7))
2023-05-02 03:32:59 +00:00
oSumAtrIX
1185ceedf7 feat(youtube/theme): change seekbar color via preference 2023-05-02 05:30:12 +02:00
semantic-release-bot
2ee18fce69 chore(release): 0.106.0 [skip ci]
# [0.106.0](https://github.com/revanced/revanced-integrations/compare/v0.105.0...v0.106.0) (2023-05-01)

### Bug Fixes

* **youtube/general-ads:** remove broken ad filter ([#355](https://github.com/revanced/revanced-integrations/issues/355)) ([061ebc6](061ebc6546))
* **youtube/return-youtube-dislike:** support old UI layouts ([#378](https://github.com/revanced/revanced-integrations/issues/378)) ([d3f8fb9](d3f8fb9739))
* **youtube/spoof-signature-verification:** more fixes for subtitle window positions  ([#374](https://github.com/revanced/revanced-integrations/issues/374)) ([8cc1b6e](8cc1b6ea4a))
* **youtube:** no longer need to restart the app after changing `copy-video-url` or `downloads` patch ([#372](https://github.com/revanced/revanced-integrations/issues/372)) ([6b15514](6b15514885))

### Features

* add appreciation message for new contributors ([78d56d4](78d56d4fe1))
* **youtube/general-ads:** hide multiple audio track button on video player overlay ([#377](https://github.com/revanced/revanced-integrations/issues/377)) ([7fc7336](7fc73368f1))
* **youtube/general-ads:** hide new type of ad ([15f9c90](15f9c90941))
* **youtube/hide-get-premium:** hide get premium advertisements under video player ([#376](https://github.com/revanced/revanced-integrations/issues/376)) ([36fd284](36fd2844c4))
* **youtube/spoof-app-version:** user selectable version to spoof ([#375](https://github.com/revanced/revanced-integrations/issues/375)) ([f6f6c93](f6f6c93c57))
2023-05-01 17:05:55 +00:00
oSumAtrIX
e774be0f05 chore: merge branch dev to main (#373) 2023-05-01 19:03:55 +02:00
LisoUseInAIKyrios
8a7098cce4 refactor(youtube/return-youtube-dislike): simplify branching (#379) 2023-05-01 15:12:31 +04:00
semantic-release-bot
a93a704c22 chore(release): 0.106.0-dev.7 [skip ci]
# [0.106.0-dev.7](https://github.com/revanced/revanced-integrations/compare/v0.106.0-dev.6...v0.106.0-dev.7) (2023-05-01)

### Bug Fixes

* **youtube/general-ads:** remove broken ad filter ([#355](https://github.com/revanced/revanced-integrations/issues/355)) ([061ebc6](061ebc6546))
2023-05-01 04:31:35 +00:00
johnconner122
061ebc6546 fix(youtube/general-ads): remove broken ad filter (#355) 2023-05-01 06:29:44 +02:00
semantic-release-bot
0c6b22e929 chore(release): 0.106.0-dev.6 [skip ci]
# [0.106.0-dev.6](https://github.com/revanced/revanced-integrations/compare/v0.106.0-dev.5...v0.106.0-dev.6) (2023-05-01)

### Features

* **youtube/general-ads:** hide multiple audio track button on video player overlay ([#377](https://github.com/revanced/revanced-integrations/issues/377)) ([7fc7336](7fc73368f1))
2023-05-01 04:28:19 +00:00
LisoUseInAIKyrios
7fc73368f1 feat(youtube/general-ads): hide multiple audio track button on video player overlay (#377) 2023-05-01 06:26:12 +02:00
semantic-release-bot
8923fa9fd6 chore(release): 0.106.0-dev.5 [skip ci]
# [0.106.0-dev.5](https://github.com/revanced/revanced-integrations/compare/v0.106.0-dev.4...v0.106.0-dev.5) (2023-04-30)

### Features

* **youtube/general-ads:** hide new type of ad ([15f9c90](15f9c90941))
2023-04-30 21:16:57 +00:00
oSumAtrIX
15f9c90941 feat(youtube/general-ads): hide new type of ad 2023-04-30 23:13:39 +02:00
semantic-release-bot
c8784a5966 chore(release): 0.106.0-dev.4 [skip ci]
# [0.106.0-dev.4](https://github.com/revanced/revanced-integrations/compare/v0.106.0-dev.3...v0.106.0-dev.4) (2023-04-30)

### Bug Fixes

* **youtube/return-youtube-dislike:** support old UI layouts ([#378](https://github.com/revanced/revanced-integrations/issues/378)) ([d3f8fb9](d3f8fb9739))
2023-04-30 19:43:40 +00:00
LisoUseInAIKyrios
d3f8fb9739 fix(youtube/return-youtube-dislike): support old UI layouts (#378) 2023-04-30 23:41:13 +04:00
semantic-release-bot
ff0d64287c chore(release): 0.106.0-dev.3 [skip ci]
# [0.106.0-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.106.0-dev.2...v0.106.0-dev.3) (2023-04-30)

### Features

* **youtube/hide-get-premium:** hide get premium advertisements under video player ([#376](https://github.com/revanced/revanced-integrations/issues/376)) ([36fd284](36fd2844c4))
2023-04-30 18:36:38 +00:00
LisoUseInAIKyrios
36fd2844c4 feat(youtube/hide-get-premium): hide get premium advertisements under video player (#376) 2023-04-30 22:34:37 +04:00
oSumAtrIX
0de83fff0e chore: update gradle and dependencies 2023-04-30 05:27:21 +02:00
semantic-release-bot
24a609288f chore(release): 0.106.0-dev.2 [skip ci]
# [0.106.0-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.106.0-dev.1...v0.106.0-dev.2) (2023-04-30)

### Features

* add appreciation message for new contributors ([78d56d4](78d56d4fe1))
2023-04-30 01:17:18 +00:00
oSumAtrIX
78d56d4fe1 feat: add appreciation message for new contributors 2023-04-30 03:15:36 +02:00
semantic-release-bot
27fdcfff08 chore(release): 0.106.0-dev.1 [skip ci]
# [0.106.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.105.1-dev.2...v0.106.0-dev.1) (2023-04-28)

### Features

* **youtube/spoof-app-version:** user selectable version to spoof ([#375](https://github.com/revanced/revanced-integrations/issues/375)) ([f6f6c93](f6f6c93c57))
2023-04-28 17:53:58 +00:00
LisoUseInAIKyrios
f6f6c93c57 feat(youtube/spoof-app-version): user selectable version to spoof (#375) 2023-04-28 21:52:09 +04:00
semantic-release-bot
a661dac623 chore(release): 0.105.1-dev.2 [skip ci]
## [0.105.1-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.105.1-dev.1...v0.105.1-dev.2) (2023-04-28)

### Bug Fixes

* **youtube/spoof-signature-verification:** more fixes for subtitle window positions  ([#374](https://github.com/revanced/revanced-integrations/issues/374)) ([8cc1b6e](8cc1b6ea4a))
2023-04-28 08:51:38 +00:00
LisoUseInAIKyrios
8cc1b6ea4a fix(youtube/spoof-signature-verification): more fixes for subtitle window positions (#374) 2023-04-28 12:49:41 +04:00
36 changed files with 693 additions and 311 deletions

2
.github/config.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
firstPRMergeComment: >
Thank you for contributing to ReVanced. Join us on [Discord](https://revanced.app/discord) if you want to receive a contributor role.

View File

@@ -1,3 +1,182 @@
# [0.108.0-dev.7](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.6...v0.108.0-dev.7) (2023-05-10)
### Bug Fixes
* **youtube/hide-ads:** don't filter for `reels_player_overlay` ([415c194](https://github.com/revanced/revanced-integrations/commit/415c1948fccdc8eb27b76b043996017c5c56eac3))
# [0.108.0-dev.6](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.5...v0.108.0-dev.6) (2023-05-09)
### Bug Fixes
* **youtube/spoof-app-version:** restore watch history preview ([#394](https://github.com/revanced/revanced-integrations/issues/394)) ([4c7f737](https://github.com/revanced/revanced-integrations/commit/4c7f737913a0c3690f8230c51f6dd217e8b04c7a))
# [0.108.0-dev.5](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.4...v0.108.0-dev.5) (2023-05-09)
### Bug Fixes
* **youtube/remember-video-quality:** fix default video quality/speed being applied when resuming app ([#392](https://github.com/revanced/revanced-integrations/issues/392)) ([c97d1b7](https://github.com/revanced/revanced-integrations/commit/c97d1b7ee5be6a0f097f2995321608bc74f5822c))
# [0.108.0-dev.4](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.3...v0.108.0-dev.4) (2023-05-07)
### Features
* **youtube/hide-player-overlay:** make it toggleable in settings ([#382](https://github.com/revanced/revanced-integrations/issues/382)) ([1b4aa0f](https://github.com/revanced/revanced-integrations/commit/1b4aa0fcc6b89acd4156e93685b1da7519aa7148))
# [0.108.0-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.2...v0.108.0-dev.3) (2023-05-07)
### Features
* **youtube:** `hide-load-more-button` patch ([#389](https://github.com/revanced/revanced-integrations/issues/389)) ([7da9d44](https://github.com/revanced/revanced-integrations/commit/7da9d440eedfc895b49aac40498f0279156ad117))
# [0.108.0-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.1...v0.108.0-dev.2) (2023-05-05)
### Bug Fixes
* **youtube/theme:** fix app crash if user clears seekbar color ([#390](https://github.com/revanced/revanced-integrations/issues/390)) ([e2f5290](https://github.com/revanced/revanced-integrations/commit/e2f52905dc445f881666c06877c3a69306335dcb))
# [0.108.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.107.1-dev.3...v0.108.0-dev.1) (2023-05-03)
### Features
* **youtube/settings:** add reset button to edit preference dialog ([#383](https://github.com/revanced/revanced-integrations/issues/383)) ([cb5a4d0](https://github.com/revanced/revanced-integrations/commit/cb5a4d0c9b3b340928695fcb1d10b164a6dcef27))
## [0.107.1-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.107.1-dev.2...v0.107.1-dev.3) (2023-05-03)
### Bug Fixes
* **youtube/theme:** fix toast shown on fresh app install ([#381](https://github.com/revanced/revanced-integrations/issues/381)) ([2dc431f](https://github.com/revanced/revanced-integrations/commit/2dc431f1bf54c12dfc45c4511a0b0792e214be4f))
## [0.107.1-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.107.1-dev.1...v0.107.1-dev.2) (2023-05-03)
### Bug Fixes
* **youtube/sponsorblock:** fix skip button in wrong location when full screen and comments visible ([#387](https://github.com/revanced/revanced-integrations/issues/387)) ([486b79b](https://github.com/revanced/revanced-integrations/commit/486b79b4e4927d4c05cfb4d5222a1d74fe60e327))
## [0.107.1-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.107.0...v0.107.1-dev.1) (2023-05-02)
### Bug Fixes
* **youtube/return-youtube-dislike:** fix potential error toast when using old UI layout ([#384](https://github.com/revanced/revanced-integrations/issues/384)) ([6c36bee](https://github.com/revanced/revanced-integrations/commit/6c36beeda139156bfbb5a17bc89aa63c25afa83c))
# [0.107.0](https://github.com/revanced/revanced-integrations/compare/v0.106.0...v0.107.0) (2023-05-02)
### Bug Fixes
* **youtube/theme:** set correct default seekbar color ([a91b036](https://github.com/revanced/revanced-integrations/commit/a91b0363a8aca4e195c9da4e48e2c332c1b1a7a6))
### Features
* **youtube/theme:** change seekbar color via preference ([1185cee](https://github.com/revanced/revanced-integrations/commit/1185ceedf7fdb40759261ae8560e79604c8cb743))
* **youtube:** `navigation-buttons` patch ([68f42fc](https://github.com/revanced/revanced-integrations/commit/68f42fc9800210f6c4d6f8e85c0132bf0cbc06d3))
# [0.107.0-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.107.0-dev.2...v0.107.0-dev.3) (2023-05-02)
### Features
* **youtube:** `navigation-buttons` patch ([68f42fc](https://github.com/revanced/revanced-integrations/commit/68f42fc9800210f6c4d6f8e85c0132bf0cbc06d3))
# [0.107.0-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.107.0-dev.1...v0.107.0-dev.2) (2023-05-02)
### Bug Fixes
* **youtube/theme:** set correct default seekbar color ([a91b036](https://github.com/revanced/revanced-integrations/commit/a91b0363a8aca4e195c9da4e48e2c332c1b1a7a6))
# [0.107.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.106.0...v0.107.0-dev.1) (2023-05-02)
### Features
* **youtube/theme:** change seekbar color via preference ([1185cee](https://github.com/revanced/revanced-integrations/commit/1185ceedf7fdb40759261ae8560e79604c8cb743))
# [0.106.0](https://github.com/revanced/revanced-integrations/compare/v0.105.0...v0.106.0) (2023-05-01)
### Bug Fixes
* **youtube/general-ads:** remove broken ad filter ([#355](https://github.com/revanced/revanced-integrations/issues/355)) ([061ebc6](https://github.com/revanced/revanced-integrations/commit/061ebc65465b2c8ef087c681070b465b82e3ebd5))
* **youtube/return-youtube-dislike:** support old UI layouts ([#378](https://github.com/revanced/revanced-integrations/issues/378)) ([d3f8fb9](https://github.com/revanced/revanced-integrations/commit/d3f8fb97399aafe98a4198234338c6d0196a7e75))
* **youtube/spoof-signature-verification:** more fixes for subtitle window positions ([#374](https://github.com/revanced/revanced-integrations/issues/374)) ([8cc1b6e](https://github.com/revanced/revanced-integrations/commit/8cc1b6ea4af4e642fb2d97233d50f34b0113f2c0))
* **youtube:** no longer need to restart the app after changing `copy-video-url` or `downloads` patch ([#372](https://github.com/revanced/revanced-integrations/issues/372)) ([6b15514](https://github.com/revanced/revanced-integrations/commit/6b155148854fbfe155c9384ba8976b5ddf3d5992))
### Features
* add appreciation message for new contributors ([78d56d4](https://github.com/revanced/revanced-integrations/commit/78d56d4fe182999555ddf5881a10880e3726782e))
* **youtube/general-ads:** hide multiple audio track button on video player overlay ([#377](https://github.com/revanced/revanced-integrations/issues/377)) ([7fc7336](https://github.com/revanced/revanced-integrations/commit/7fc73368f161ee1973f36323054f8cbb53b6e7ce))
* **youtube/general-ads:** hide new type of ad ([15f9c90](https://github.com/revanced/revanced-integrations/commit/15f9c90941535e93a0779118158c5b4a8accb799))
* **youtube/hide-get-premium:** hide get premium advertisements under video player ([#376](https://github.com/revanced/revanced-integrations/issues/376)) ([36fd284](https://github.com/revanced/revanced-integrations/commit/36fd2844c468a4a9af3fe6ee5e62775f1e8dbe56))
* **youtube/spoof-app-version:** user selectable version to spoof ([#375](https://github.com/revanced/revanced-integrations/issues/375)) ([f6f6c93](https://github.com/revanced/revanced-integrations/commit/f6f6c93c57bdbec13f09acd802f58554cb981f3a))
# [0.106.0-dev.7](https://github.com/revanced/revanced-integrations/compare/v0.106.0-dev.6...v0.106.0-dev.7) (2023-05-01)
### Bug Fixes
* **youtube/general-ads:** remove broken ad filter ([#355](https://github.com/revanced/revanced-integrations/issues/355)) ([061ebc6](https://github.com/revanced/revanced-integrations/commit/061ebc65465b2c8ef087c681070b465b82e3ebd5))
# [0.106.0-dev.6](https://github.com/revanced/revanced-integrations/compare/v0.106.0-dev.5...v0.106.0-dev.6) (2023-05-01)
### Features
* **youtube/general-ads:** hide multiple audio track button on video player overlay ([#377](https://github.com/revanced/revanced-integrations/issues/377)) ([7fc7336](https://github.com/revanced/revanced-integrations/commit/7fc73368f161ee1973f36323054f8cbb53b6e7ce))
# [0.106.0-dev.5](https://github.com/revanced/revanced-integrations/compare/v0.106.0-dev.4...v0.106.0-dev.5) (2023-04-30)
### Features
* **youtube/general-ads:** hide new type of ad ([15f9c90](https://github.com/revanced/revanced-integrations/commit/15f9c90941535e93a0779118158c5b4a8accb799))
# [0.106.0-dev.4](https://github.com/revanced/revanced-integrations/compare/v0.106.0-dev.3...v0.106.0-dev.4) (2023-04-30)
### Bug Fixes
* **youtube/return-youtube-dislike:** support old UI layouts ([#378](https://github.com/revanced/revanced-integrations/issues/378)) ([d3f8fb9](https://github.com/revanced/revanced-integrations/commit/d3f8fb97399aafe98a4198234338c6d0196a7e75))
# [0.106.0-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.106.0-dev.2...v0.106.0-dev.3) (2023-04-30)
### Features
* **youtube/hide-get-premium:** hide get premium advertisements under video player ([#376](https://github.com/revanced/revanced-integrations/issues/376)) ([36fd284](https://github.com/revanced/revanced-integrations/commit/36fd2844c468a4a9af3fe6ee5e62775f1e8dbe56))
# [0.106.0-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.106.0-dev.1...v0.106.0-dev.2) (2023-04-30)
### Features
* add appreciation message for new contributors ([78d56d4](https://github.com/revanced/revanced-integrations/commit/78d56d4fe182999555ddf5881a10880e3726782e))
# [0.106.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.105.1-dev.2...v0.106.0-dev.1) (2023-04-28)
### Features
* **youtube/spoof-app-version:** user selectable version to spoof ([#375](https://github.com/revanced/revanced-integrations/issues/375)) ([f6f6c93](https://github.com/revanced/revanced-integrations/commit/f6f6c93c57bdbec13f09acd802f58554cb981f3a))
## [0.105.1-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.105.1-dev.1...v0.105.1-dev.2) (2023-04-28)
### Bug Fixes
* **youtube/spoof-signature-verification:** more fixes for subtitle window positions ([#374](https://github.com/revanced/revanced-integrations/issues/374)) ([8cc1b6e](https://github.com/revanced/revanced-integrations/commit/8cc1b6ea4af4e642fb2d97233d50f34b0113f2c0))
## [0.105.1-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.105.0...v0.105.1-dev.1) (2023-04-28)

View File

@@ -1,8 +1,10 @@
# ReVanced Integrations
# 🔩 ReVanced Integrations
The official ReVanced Integrations containing classes to be merged by ReVanced Patcher.
## ❓ How to use debugging:
# How to use debugging:
- Usage on Windows: ```adb logcat | findstr "revanced" > log.txt```
- Usage on Linux: ```adb logcat | grep --line-buffered "revanced" > log.txt```
This will write the log to a file called log.txt which you can view then.

View File

@@ -44,7 +44,7 @@ android {
dependencies {
compileOnly(project(mapOf("path" to ":dummy")))
compileOnly("androidx.annotation:annotation:1.6.0")
compileOnly("androidx.appcompat:appcompat:1.6.1")
compileOnly("androidx.appcompat:appcompat:1.7.0-alpha02")
compileOnly("com.squareup.okhttp3:okhttp:5.0.0-alpha.11")
compileOnly("com.squareup.retrofit2:retrofit:2.9.0")
}

View File

@@ -33,6 +33,7 @@ public final class GeneralAdsPatch extends Filter {
var infoPanel = new BlockRule(SettingsEnum.ADREMOVER_INFO_PANEL_REMOVAL, "publisher_transparency_panel", "single_item_information_panel");
var latestPosts = new BlockRule(SettingsEnum.ADREMOVER_HIDE_LATEST_POSTS, "post_shelf");
var channelGuidelines = new BlockRule(SettingsEnum.ADREMOVER_HIDE_CHANNEL_GUIDELINES, "channel_guidelines_entry_banner");
var audioTrackButton = new BlockRule(SettingsEnum.HIDE_AUDIO_TRACK_BUTTON, "multi_feed_icon_button");
var artistCard = new BlockRule(SettingsEnum.HIDE_ARTIST_CARDS, "official_card");
var selfSponsor = new BlockRule(SettingsEnum.ADREMOVER_SELF_SPONSOR_REMOVAL, "cta_shelf_card");
var chapterTeaser = new BlockRule(SettingsEnum.ADREMOVER_CHAPTER_TEASER_REMOVAL, "expandable_metadata", "macro_markers_carousel");
@@ -64,8 +65,8 @@ public final class GeneralAdsPatch extends Filter {
"carousel_footered_layout",
"text_image_button_layout",
"primetime_promo",
"feature_grid_interstitial",
"product_details",
"full_width_portrait_image_layout",
"brand_video_shelf"
);
var movieAds = new BlockRule(
@@ -97,6 +98,7 @@ public final class GeneralAdsPatch extends Filter {
merchandise,
infoPanel,
channelGuidelines,
audioTrackButton,
artistCard,
selfSponsor,
webLinkPanel,
@@ -109,7 +111,6 @@ public final class GeneralAdsPatch extends Filter {
"carousel_ad"
);
var shorts = new BlockRule(SettingsEnum.ADREMOVER_SHORTS_REMOVAL,
"reels_player_overlay",
"shorts_shelf",
"inline_shorts",
"shorts_grid"

View File

@@ -6,8 +6,7 @@ import app.revanced.integrations.adremover.AdRemoverAPI;
import app.revanced.integrations.settings.SettingsEnum;
public class HideAlbumCardsPatch {
//Used by app.revanced.patches.youtube.layout.hidealbumcards.patch.HideAlbumCardsPatch
public static void hideAlbumCards(View view) {
public static void hideAlbumCard(View view) {
if (!SettingsEnum.HIDE_ALBUM_CARDS.getBoolean()) return;
AdRemoverAPI.HideViewWithLayout1dp(view);
}

View File

@@ -6,9 +6,24 @@ import app.revanced.integrations.adremover.AdRemoverAPI;
import app.revanced.integrations.settings.SettingsEnum;
public class HideBreakingNewsPatch {
//Used by app.revanced.patches.youtube.layout.homepage.breakingnews.patch.BreakingNewsPatch
/**
* When spoofing to app versions older than 17.30.35, the watch history preview bar uses
* the same layout components as the breaking news shelf.
*
* Breaking news does not appear to be present in these older versions anyways.
*/
private static boolean isSpoofingOldVersionWithHorizontalCardListWatchHistory() {
return SettingsEnum.SPOOF_APP_VERSION.getBoolean()
&& SettingsEnum.SPOOF_APP_VERSION_TARGET.getString().compareTo("17.30.35") < 0;
}
/**
* Injection point.
*/
public static void hideBreakingNews(View view) {
if (!SettingsEnum.HIDE_BREAKING_NEWS.getBoolean()) return;
if (!SettingsEnum.HIDE_BREAKING_NEWS.getBoolean()
|| isSpoofingOldVersionWithHorizontalCardListWatchHistory()) return;
AdRemoverAPI.HideViewWithLayout1dp(view);
}
}

View File

@@ -1,16 +0,0 @@
package app.revanced.integrations.patches;
import android.view.View;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
public class HideCreateButtonPatch {
//Used by app.revanced.patches.youtube.layout.createbutton.patch.CreateButtonRemoverPatch
public static void hideCreateButton(View view) {
boolean hidden = SettingsEnum.HIDE_CREATE_BUTTON.getBoolean();
LogHelper.printDebug(() -> "Create button: " + (hidden ? "hidden" : "shown"));
view.setVisibility(hidden ? View.GONE : View.VISIBLE);
}
}

View File

@@ -0,0 +1,12 @@
package app.revanced.integrations.patches;
import app.revanced.integrations.settings.SettingsEnum;
public class HideGetPremiumPatch {
/**
* Injection point.
*/
public static boolean hideGetPremiumView() {
return SettingsEnum.HIDE_GET_PREMIUM.getBoolean();
}
}

View File

@@ -0,0 +1,13 @@
package app.revanced.integrations.patches;
import android.view.View;
import app.revanced.integrations.adremover.AdRemoverAPI;
import app.revanced.integrations.settings.SettingsEnum;
public class HideLoadMoreButtonPatch {
public static void hideLoadMoreButton(View view){
if(!SettingsEnum.HIDE_LOAD_MORE_BUTTON.getBoolean()) return;
AdRemoverAPI.HideViewWithLayout1dp(view);
}
}

View File

@@ -0,0 +1,12 @@
package app.revanced.integrations.patches;
import android.widget.ImageView;
import app.revanced.integrations.settings.SettingsEnum;
public class HidePlayerOverlayPatch {
public static void hidePlayerOverlay(ImageView view) {
if (!SettingsEnum.HIDE_PLAYER_OVERLAY.getBoolean()) return;
view.setImageResource(android.R.color.transparent);
}
}

View File

@@ -1,24 +0,0 @@
package app.revanced.integrations.patches;
import android.view.View;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
public class HideShortsButtonPatch {
// Used by app.revanced.patches.youtube.layout.shorts.button.patch.ShortsButtonRemoverPatch
public static void hideShortsButton(View view) {
if (lastPivotTab != null && lastPivotTab.name() == "TAB_SHORTS") {
boolean hide = SettingsEnum.HIDE_SHORTS_BUTTON.getBoolean();
LogHelper.printDebug(() -> hide ? "Shorts button: hidden" : "Shorts button: shown");
if (hide) {
view.setVisibility(View.GONE);
}
}
}
//Needed for the ShortsButtonRemoverPatch
public static Enum lastPivotTab;
}

View File

@@ -2,6 +2,7 @@ package app.revanced.integrations.patches;
import static app.revanced.integrations.utils.StringRef.str;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -28,6 +29,7 @@ public class MicroGSupport {
context.startActivity(intent);
}
@TargetApi(26)
public static void checkAvailability() {
var context = Objects.requireNonNull(ReVancedUtils.getContext());
@@ -41,10 +43,11 @@ public class MicroGSupport {
System.exit(0);
}
try (var client = context.getContentResolver().acquireContentProviderClient(VANCED_MICROG_PROVIDER)) {
if (client != null) return;
LogHelper.printInfo(() -> "Vanced MicroG is not running in the background");
startIntent(context, DONT_KILL_MY_APP_LINK, str("microg_not_running_warning"));
}
}
}
}

View File

@@ -0,0 +1,38 @@
package app.revanced.integrations.patches;
import android.view.View;
import app.revanced.integrations.settings.SettingsEnum;
public final class NavigationButtonsPatch {
public static Enum lastNavigationButton;
public static void hideCreateButton(final View view) {
view.setVisibility(SettingsEnum.HIDE_CREATE_BUTTON.getBoolean() ? View.GONE : View.VISIBLE);
}
public static boolean switchCreateWithNotificationButton() {
return SettingsEnum.SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON.getBoolean();
}
public static void hideButton(final View buttonView) {
if (lastNavigationButton == null) return;
for (NavigationButton button : NavigationButton.values())
if (button.name.equals(lastNavigationButton.name()))
if (button.enabled) buttonView.setVisibility(View.GONE);
}
private enum NavigationButton {
HOME("PIVOT_HOME", SettingsEnum.HIDE_HOME_BUTTON.getBoolean()),
SHORTS("TAB_SHORTS", SettingsEnum.HIDE_SHORTS_BUTTON.getBoolean()),
SUBSCRIPTIONS("PIVOT_SUBSCRIPTIONS", SettingsEnum.HIDE_SUBSCRIPTIONS_BUTTON.getBoolean());
private final boolean enabled;
private final String name;
NavigationButton(final String name, final boolean enabled) {
this.name = name;
this.enabled = enabled;
}
}
}

View File

@@ -2,23 +2,111 @@ package app.revanced.integrations.patches;
import static app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike.Vote;
import android.text.SpannableString;
import android.text.Editable;
import android.text.Spannable;
import android.text.Spanned;
import android.text.TextWatcher;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicReference;
import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.shared.PlayerType;
import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils;
public class ReturnYouTubeDislikePatch {
/**
* Resource identifier of old UI dislike button.
*/
private static final int OLD_UI_DISLIKE_BUTTON_RESOURCE_ID
= ReVancedUtils.getResourceIdentifier("dislike_button", "id");
/**
* Dislikes text label used by old UI.
*/
@NonNull
private static WeakReference<TextView> oldUITextViewRef = new WeakReference<>(null);
/**
* Original old UI 'Dislikes' text before patch modifications.
* Required to reset the dislikes when changing videos and RYD is not available.
* Set only once during the first load.
*/
private static Spanned oldUIOriginalSpan;
/**
* Replacement span that contains dislike value. Used by {@link #oldUiTextWatcher}.
*/
@Nullable
private static Spanned oldUIReplacementSpan;
/**
* Old UI dislikes can be set multiple times by YouTube.
* To prevent it from reverting changes made here, this listener overrides any future changes YouTube makes.
*/
private static final TextWatcher oldUiTextWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void afterTextChanged(Editable s) {
if (oldUIReplacementSpan == null || oldUIReplacementSpan.toString().equals(s.toString())) {
return;
}
s.replace(0, s.length(), oldUIReplacementSpan);
}
};
private static void updateOldUIDislikesTextView() {
TextView oldUITextView = oldUITextViewRef.get();
if (oldUITextView == null) {
return;
}
oldUIReplacementSpan = ReturnYouTubeDislike.getDislikesSpanForRegularVideo(oldUIOriginalSpan, false);
if (!oldUIReplacementSpan.equals(oldUITextView.getText())) {
oldUITextView.setText(oldUIReplacementSpan);
}
}
/**
* Injection point. Called on main thread.
*
* Used when spoofing the older app versions of {@link SpoofAppVersionPatch}.
*/
public static void setOldUILayoutDislikes(int buttonViewResourceId, @Nullable TextView textView) {
try {
if (!SettingsEnum.RYD_ENABLED.getBoolean()
|| buttonViewResourceId != OLD_UI_DISLIKE_BUTTON_RESOURCE_ID
|| textView == null) {
return;
}
if (oldUIOriginalSpan == null) {
// Use value of the first instance, as it appears TextViews can be recycled
// and might contain dislikes previously added by the patch.
oldUIOriginalSpan = (Spanned) textView.getText();
}
oldUITextViewRef = new WeakReference<>(textView);
// No way to check if a listener is already attached, so remove and add again.
textView.removeTextChangedListener(oldUiTextWatcher);
textView.addTextChangedListener(oldUiTextWatcher);
updateOldUIDislikesTextView();
} catch (Exception ex) {
LogHelper.printException(() -> "setOldUILayoutDislikes failure", ex);
}
}
/**
* Injection point.
*/
public static void newVideoLoaded(String videoId) {
public static void newVideoLoaded(@NonNull String videoId) {
try {
if (!SettingsEnum.RYD_ENABLED.getBoolean()) return;
ReturnYouTubeDislike.newVideoLoaded(videoId);
@@ -47,14 +135,23 @@ public class ReturnYouTubeDislikePatch {
@NonNull AtomicReference<CharSequence> textRef,
@NonNull CharSequence original) {
try {
if (!SettingsEnum.RYD_ENABLED.getBoolean()) {
if (!SettingsEnum.RYD_ENABLED.getBoolean() || PlayerType.getCurrent().isNoneOrHidden()) {
return original;
}
SpannableString replacement = ReturnYouTubeDislike.getDislikeSpanForContext(conversionContext, original);
if (replacement != null) {
textRef.set(replacement);
return replacement;
String conversionContextString = conversionContext.toString();
final boolean isSegmentedButton;
if (conversionContextString.contains("|segmented_like_dislike_button.eml|")) {
isSegmentedButton = true;
} else if (conversionContextString.contains("|dislike_button.eml|")) {
isSegmentedButton = false;
} else {
return original;
}
Spanned replacement = ReturnYouTubeDislike.getDislikesSpanForRegularVideo((Spannable) original, isSegmentedButton);
textRef.set(replacement);
return replacement;
} catch (Exception ex) {
LogHelper.printException(() -> "onLithoTextLoaded failure", ex);
}
@@ -71,10 +168,7 @@ public class ReturnYouTubeDislikePatch {
if (!SettingsEnum.RYD_ENABLED.getBoolean()) {
return original;
}
SpannableString replacement = ReturnYouTubeDislike.getDislikeSpanForShort(original);
if (replacement != null) {
return replacement;
}
return ReturnYouTubeDislike.getDislikeSpanForShort(original);
} catch (Exception ex) {
LogHelper.printException(() -> "onShortsComponentCreated failure", ex);
}
@@ -97,6 +191,7 @@ public class ReturnYouTubeDislikePatch {
for (Vote v : Vote.values()) {
if (v.value == vote) {
ReturnYouTubeDislike.sendVote(v);
updateOldUIDislikesTextView();
return;
}
}

View File

@@ -5,10 +5,8 @@ import app.revanced.integrations.settings.SettingsEnum;
public class SpoofAppVersionPatch {
public static String getYouTubeVersionOverride(String version) {
if (SettingsEnum.SPOOF_APP_VERSION.getBoolean()){
// Override with the most recent version that does not show the new UI player layout.
// If the new UI shows up for some users, then change this to an older version (such as 17.29.34).
return "17.30.34";
if (SettingsEnum.SPOOF_APP_VERSION.getBoolean()) {
return SettingsEnum.SPOOF_APP_VERSION_TARGET.getString();
}
return version;
}

View File

@@ -31,13 +31,27 @@ public class SpoofSignatureVerificationPatch {
"SAFg" // Autoplay in scrim
};
@Nullable
private static String currentVideoId;
/**
* On app first start, the first video played usually contains a single non-default window setting value
* and all other subtitle settings for the video are (incorrect) default shorts window settings.
* For this situation, the shorts settings must be replaced.
*
* But some videos use multiple text positions on screen (such as https://youtu.be/3hW1rMNC89o),
* and by chance many of the subtitles uses window positions that match a default shorts position.
* To handle these videos, selectively allowing the shorts specific window settings to 'pass thru' unchanged,
* but only if the video contains multiple non-default subtitle window positions.
*
* Do not enable 'pass thru mode' until this many non default subtitle settings are observed for a single video.
*/
private static final int NUMBER_OF_NON_DEFAULT_SUBTITLES_BEFORE_ENABLING_PASSTHRU = 2;
/**
* If any of the subtitles settings encountered from the current video have been non default values.
* The number of non default subtitle settings encountered for the current video.
*/
private static boolean nonDefaultSubtitlesEncountered;
private static int numberOfNonDefaultSettingsObserved;
@Nullable
private static String currentVideoId;
/**
* Injection point.
@@ -137,15 +151,19 @@ public class SpoofSignatureVerificationPatch {
// then this will incorrectly replace the setting.
// But, if the video uses multiple subtitles in different screen locations, then detect the non-default values
// and do not replace any window settings for the video (regardless if they match a shorts default).
if (signatureSpoofing && !nonDefaultSubtitlesEncountered && !PlayerType.getCurrent().isNoneOrHidden()) {
if (signatureSpoofing && !PlayerType.getCurrent().isNoneOrHidden()
&& numberOfNonDefaultSettingsObserved < NUMBER_OF_NON_DEFAULT_SUBTITLES_BEFORE_ENABLING_PASSTHRU) {
for (SubtitleWindowReplacementSettings setting : SubtitleWindowReplacementSettings.values()) {
if (setting.match(ap, ah, av, vs, sd)) {
return setting.replacementSetting();
}
}
// Settings appear to be custom subtitles.
nonDefaultSubtitlesEncountered = true;
LogHelper.printDebug(() -> "Non default subtitles found. Using existing settings without replacement.");
numberOfNonDefaultSettingsObserved++;
LogHelper.printDebug(() ->
numberOfNonDefaultSettingsObserved < NUMBER_OF_NON_DEFAULT_SUBTITLES_BEFORE_ENABLING_PASSTHRU
? "Non default subtitle found."
: "Multiple non default subtitles found. Allowing all subtitles for this video to pass thru unchanged.");
}
return new int[]{ap, ah, av};
@@ -160,7 +178,7 @@ public class SpoofSignatureVerificationPatch {
return;
}
currentVideoId = videoId;
nonDefaultSubtitlesEncountered = false;
numberOfNonDefaultSettingsObserved = 0;
} catch (Exception ex) {
LogHelper.printException(() -> "setCurrentVideoId failure", ex);
}

View File

@@ -4,6 +4,7 @@ import androidx.annotation.NonNull;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.Objects;
import app.revanced.integrations.patches.playback.speed.RememberPlaybackSpeedPatch;
import app.revanced.integrations.utils.LogHelper;
@@ -16,7 +17,7 @@ public final class VideoInformation {
private static final float DEFAULT_YOUTUBE_PLAYBACK_SPEED = 1.0f;
private static final String SEEK_METHOD_NAME = "seekTo";
private static WeakReference<Object> playerController;
private static WeakReference<Object> playerControllerRef;
private static Method seekMethod;
@NonNull
@@ -30,17 +31,17 @@ public final class VideoInformation {
/**
* Injection point.
* Sets a reference to the YouTube playback controller.
*
* @param thisRef Reference to the player controller object.
* @param playerController player controller object.
*/
public static void playerController_onCreateHook(final Object thisRef) {
playerController = new WeakReference<>(thisRef);
videoLength = 0;
videoTime = -1;
public static void initialize(@NonNull Object playerController) {
try {
seekMethod = thisRef.getClass().getMethod(SEEK_METHOD_NAME, Long.TYPE);
playerControllerRef = new WeakReference<>(Objects.requireNonNull(playerController));
videoTime = -1;
videoLength = 0;
playbackSpeed = DEFAULT_YOUTUBE_PLAYBACK_SPEED;
seekMethod = playerController.getClass().getMethod(SEEK_METHOD_NAME, Long.TYPE);
seekMethod.setAccessible(true);
} catch (Exception ex) {
LogHelper.printException(() -> "Failed to initialize", ex);
@@ -56,7 +57,6 @@ public final class VideoInformation {
if (!videoId.equals(newlyLoadedVideoId)) {
LogHelper.printDebug(() -> "New video id: " + newlyLoadedVideoId);
videoId = newlyLoadedVideoId;
playbackSpeed = DEFAULT_YOUTUBE_PLAYBACK_SPEED;
}
}
@@ -124,7 +124,7 @@ public final class VideoInformation {
try {
LogHelper.printDebug(() -> "Seeking to " + millisecond);
return (Boolean) seekMethod.invoke(playerController.get(), millisecond);
return (Boolean) seekMethod.invoke(playerControllerRef.get(), millisecond);
} catch (Exception ex) {
LogHelper.printException(() -> "Failed to seek", ex);
return false;

View File

@@ -2,7 +2,6 @@ package app.revanced.integrations.patches.playback.quality;
import static app.revanced.integrations.utils.ReVancedUtils.NetworkType;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.reflect.Field;
@@ -20,8 +19,6 @@ public class RememberVideoQualityPatch {
private static final SettingsEnum mobileQualitySetting = SettingsEnum.VIDEO_QUALITY_DEFAULT_MOBILE;
private static boolean qualityNeedsUpdating;
@Nullable
private static String currentVideoId;
/**
* If the user selected a new quality from the flyout menu,
@@ -91,7 +88,7 @@ public class RememberVideoQualityPatch {
}
}
}
LogHelper.printDebug(() -> "VideoId: " + currentVideoId + " videoQualities: " + videoQualities);
LogHelper.printDebug(() -> "videoQualities: " + videoQualities);
}
if (userChangedDefaultQuality) {
@@ -144,25 +141,9 @@ public class RememberVideoQualityPatch {
/**
* Injection point.
*/
public static void newVideoStarted(@NonNull String videoId) {
// The same videoId can be passed in multiple times for a single video playback.
// Such as closing and opening the app, and sometimes when turning off/on the device screen.
//
// Known limitation, if:
// 1. a default video quality exists, and remember quality is turned off
// 2. user opens a video
// 3. user changes the video quality
// 4. user turns off then on the device screen (or does anything else that triggers the video id hook)
// result: the video quality of the current video will revert back to the saved default
//
// qualityNeedsUpdating could be set only when the videoId changes
// but then if the user closes and re-opens the same video the default video quality will not be applied.
LogHelper.printDebug(() -> "newVideoStarted: " + videoId);
public static void newVideoStarted(Object ignoredPlayerController) {
LogHelper.printDebug(() -> "newVideoStarted");
qualityNeedsUpdating = true;
if (!videoId.equals(currentVideoId)) {
currentVideoId = videoId;
videoQualities = null;
}
videoQualities = null;
}
}

View File

@@ -2,11 +2,9 @@ package app.revanced.integrations.patches.playback.speed;
import android.preference.ListPreference;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.revanced.integrations.patches.VideoInformation;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils;
public final class RememberPlaybackSpeedPatch {
@@ -16,18 +14,12 @@ public final class RememberPlaybackSpeedPatch {
*/
private static String[] preferenceListEntries, preferenceListEntryValues;
@Nullable
private static String currentVideoId;
/**
* Injection point.
* Called when a new video loads.
*/
public static void newVideoLoaded(@NonNull String videoId) {
if (videoId.equals(currentVideoId)) {
return;
}
currentVideoId = videoId;
public static void newVideoStarted(Object ignoredPlayerController) {
LogHelper.printDebug(() -> "newVideoStarted");
VideoInformation.overridePlaybackSpeed(SettingsEnum.PLAYBACK_SPEED_DEFAULT.getFloat());
}

View File

@@ -1,9 +1,9 @@
package app.revanced.integrations.patches;
package app.revanced.integrations.patches.theme;
import app.revanced.integrations.utils.ReVancedUtils;
import app.revanced.integrations.utils.ThemeHelper;
public class LithoThemePatch {
public class ThemeLithoComponentsPatch {
// color constants used in relation with litho components
private static final int[] WHITE_VALUES = {
-1, // comments chip background
@@ -31,7 +31,7 @@ public class LithoThemePatch {
* @param originalValue The original color value.
* @return The new or original color value
*/
public static int applyLithoTheme(int originalValue) {
public static int getValue(int originalValue) {
if (ThemeHelper.isDarkTheme()) {
if (anyEquals(originalValue, DARK_VALUES)) return getBlackColor();
} else {

View File

@@ -0,0 +1,32 @@
package app.revanced.integrations.patches.theme;
import android.graphics.Color;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.ReVancedUtils;
public final class ThemePatch {
private static final int ORIGINAL_SEEKBAR_CLICKED_COLOR = -65536;
private static void resetSeekbarColor() {
ReVancedUtils.showToastShort("Invalid seekbar color value. Using default value.");
SettingsEnum.SEEKBAR_COLOR.saveValue(SettingsEnum.SEEKBAR_COLOR.defaultValue);
}
/**
* Injection point.
*/
public static int getSeekbarClickedColorValue(final int colorValue) {
// YouTube uses a specific color when the seekbar is clicked. Override in that case.
return colorValue == ORIGINAL_SEEKBAR_CLICKED_COLOR ? getSeekbarColorValue() : colorValue;
}
public static int getSeekbarColorValue() {
try {
return Color.parseColor(SettingsEnum.SEEKBAR_COLOR.getString());
} catch (Exception exception) {
resetSeekbarColor();
return getSeekbarColorValue();
}
}
}

View File

@@ -76,7 +76,7 @@ public class ReturnYouTubeDislike {
/**
* If {@link #currentVideoId} and the RYD data is for the last shorts loaded.
*/
private static volatile boolean lastVideoLoadedWasShort;
private static volatile boolean dislikeDataIsShort;
/**
* Stores the results of the vote api fetch, and used as a barrier to wait until fetch completes.
@@ -141,7 +141,7 @@ public class ReturnYouTubeDislike {
LogHelper.printDebug(() -> "Clearing data");
}
currentVideoId = videoId;
lastVideoLoadedWasShort = false;
dislikeDataIsShort = false;
voteFetchFuture = null;
originalDislikeSpan = null;
replacementLikeDislikeSpan = null;
@@ -198,7 +198,7 @@ public class ReturnYouTubeDislike {
// If a Short is opened while a regular video is on screen, this will incorrectly set this as false.
// But this check is needed to fix unusual situations of opening/closing the app
// while both a regular video and a short are on screen.
lastVideoLoadedWasShort = PlayerType.getCurrent().isNoneOrHidden();
dislikeDataIsShort = PlayerType.getCurrent().isNoneOrHidden();
// No need to wrap the call in a try/catch,
// as any exceptions are propagated out in the later Future#Get call.
@@ -207,41 +207,28 @@ public class ReturnYouTubeDislike {
}
/**
* @return NULL if the span does not need changing or if RYD is not available.
* @return the replacement span containing dislikes, or the original span if RYD is not available.
*/
@Nullable
public static SpannableString getDislikeSpanForContext(@NonNull Object conversionContext, @NonNull CharSequence original) {
if (PlayerType.getCurrent().isNoneOrHidden()) {
return null;
}
String conversionContextString = conversionContext.toString();
final boolean isSegmentedButton;
if (conversionContextString.contains("|segmented_like_dislike_button.eml|")) {
isSegmentedButton = true;
} else if (conversionContextString.contains("|dislike_button.eml|")) {
isSegmentedButton = false;
} else {
return null;
}
if (lastVideoLoadedWasShort) {
@NonNull
public static Spanned getDislikesSpanForRegularVideo(@NonNull Spanned original, boolean isSegmentedButton) {
if (dislikeDataIsShort) {
// user:
// 1, opened a video
// 2. opened a short (without closing the regular video)
// 3. closed the short
// 4. regular video is now present, but the videoId and RYD data is still for the short
LogHelper.printDebug(() -> "Ignoring getDislikeSpanForContext(), as data loaded is for prior short");
return null;
return original;
}
return waitForFetchAndUpdateReplacementSpan((Spannable) original, isSegmentedButton);
return waitForFetchAndUpdateReplacementSpan(original, isSegmentedButton);
}
/**
* Called when a Shorts dislike Spannable is created.
*/
public static SpannableString getDislikeSpanForShort(@NonNull Spanned original) {
lastVideoLoadedWasShort = true; // it's now certain the video and data are a short
@NonNull
public static Spanned getDislikeSpanForShort(@NonNull Spanned original) {
dislikeDataIsShort = true; // it's now certain the video and data are a short
return waitForFetchAndUpdateReplacementSpan(original, false);
}
@@ -250,17 +237,14 @@ public class ReturnYouTubeDislike {
return span.toString().indexOf(MIDDLE_SEPARATOR_CHARACTER) != -1;
}
/**
* @return NULL if the span does not need changing or if RYD is not available.
*/
@Nullable
private static SpannableString waitForFetchAndUpdateReplacementSpan(@NonNull Spanned oldSpannable, boolean isSegmentedButton) {
@NonNull
private static Spanned waitForFetchAndUpdateReplacementSpan(@NonNull Spanned oldSpannable, boolean isSegmentedButton) {
try {
synchronized (videoIdLockObject) {
if (replacementLikeDislikeSpan != null) {
if (spansHaveEqualTextAndColor(replacementLikeDislikeSpan, oldSpannable)) {
LogHelper.printDebug(() -> "Ignoring previously created dislikes span");
return null;
return oldSpannable;
}
if (spansHaveEqualTextAndColor(Objects.requireNonNull(originalDislikeSpan), oldSpannable)) {
LogHelper.printDebug(() -> "Replacing span with previously created dislike span");
@@ -269,11 +253,11 @@ public class ReturnYouTubeDislike {
}
if (isSegmentedButton && isPreviouslyCreatedSegmentedSpan(oldSpannable)) {
// need to recreate using original, as oldSpannable has prior outdated dislike values
oldSpannable = originalDislikeSpan;
if (oldSpannable == null) {
if (originalDislikeSpan == null) {
LogHelper.printDebug(() -> "Cannot add dislikes - original span is null"); // should never happen
return null;
return oldSpannable;
}
oldSpannable = originalDislikeSpan;
} else {
originalDislikeSpan = oldSpannable; // most up to date original
}
@@ -284,12 +268,12 @@ public class ReturnYouTubeDislike {
Future<RYDVoteData> fetchFuture = getVoteFetchFuture();
if (fetchFuture == null) {
LogHelper.printDebug(() -> "fetch future not available (user enabled RYD while video was playing?)");
return null;
return oldSpannable;
}
RYDVoteData votingData = fetchFuture.get(MAX_MILLISECONDS_TO_BLOCK_UI_WHILE_WAITING_FOR_FETCH_VOTES_TO_COMPLETE, TimeUnit.MILLISECONDS);
if (votingData == null) {
LogHelper.printDebug(() -> "Cannot add dislike to UI (RYD data not available)");
return null;
return oldSpannable;
}
SpannableString replacement = createDislikeSpan(oldSpannable, isSegmentedButton, votingData);
@@ -304,7 +288,7 @@ public class ReturnYouTubeDislike {
} catch (Exception e) {
LogHelper.printException(() -> "waitForFetchAndUpdateReplacementSpan failure", e); // should never happen
}
return null;
return oldSpannable;
}
public static void sendVote(@NonNull Vote vote) {
@@ -313,7 +297,7 @@ public class ReturnYouTubeDislike {
try {
// Must make a local copy of videoId, since it may change between now and when the vote thread runs.
String videoIdToVoteFor = getCurrentVideoId();
if (videoIdToVoteFor == null || lastVideoLoadedWasShort != PlayerType.getCurrent().isNoneOrHidden()) {
if (videoIdToVoteFor == null || dislikeDataIsShort != PlayerType.getCurrent().isNoneOrHidden()) {
// User enabled RYD after starting playback of a video.
// Or shorts was loaded with regular video present, then shorts was closed,
// and then user voted on the now visible original video.

View File

@@ -136,21 +136,20 @@ public class ReturnYouTubeDislikeApi {
/**
* Simulates a slow response by doing meaningless calculations.
* Used to debug the app UI and verify UI timeout logic works
*
* @param maximumTimeToWait maximum time to wait
*/
@SuppressWarnings("UnusedReturnValue")
private static long randomlyWaitIfLocallyDebugging(long maximumTimeToWait) {
private static long randomlyWaitIfLocallyDebugging() {
final boolean DEBUG_RANDOMLY_DELAY_NETWORK_CALLS = false; // set true to debug UI
if (DEBUG_RANDOMLY_DELAY_NETWORK_CALLS) {
final long amountOfTimeToWaste = (long) (Math.random() * maximumTimeToWait);
final long amountOfTimeToWaste = (long) (Math.random()
* (API_GET_VOTES_TCP_TIMEOUT_MILLISECONDS + API_GET_VOTES_HTTP_TIMEOUT_MILLISECONDS));
final long timeCalculationStarted = System.currentTimeMillis();
LogHelper.printDebug(() -> "Artificially creating network delay of: " + amountOfTimeToWaste + " ms");
LogHelper.printDebug(() -> "Artificially creating network delay of: " + amountOfTimeToWaste + "ms");
long meaninglessValue = 0;
while (System.currentTimeMillis() - timeCalculationStarted < amountOfTimeToWaste) {
// could do a thread sleep, but that will trigger an exception if the thread is interrupted
meaninglessValue += Long.numberOfLeadingZeros((long) (Math.random() * Long.MAX_VALUE));
meaninglessValue += Long.numberOfLeadingZeros((long)Math.exp(Math.random()));
}
// return the value, otherwise the compiler or VM might optimize and remove the meaningless time wasting work,
// leaving an empty loop that hammers on the System.currentTimeMillis native call
@@ -246,7 +245,7 @@ public class ReturnYouTubeDislikeApi {
connection.setConnectTimeout(API_GET_VOTES_TCP_TIMEOUT_MILLISECONDS); // timeout for TCP connection to server
connection.setReadTimeout(API_GET_VOTES_HTTP_TIMEOUT_MILLISECONDS); // timeout for server response
randomlyWaitIfLocallyDebugging(2*(API_GET_VOTES_TCP_TIMEOUT_MILLISECONDS + API_GET_VOTES_HTTP_TIMEOUT_MILLISECONDS));
randomlyWaitIfLocallyDebugging();
final int responseCode = connection.getResponseCode();
if (checkIfRateLimitWasHit(responseCode)) {

View File

@@ -1,21 +1,17 @@
package app.revanced.integrations.settings;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static app.revanced.integrations.settings.SettingsEnum.ReturnType.BOOLEAN;
import static app.revanced.integrations.settings.SettingsEnum.ReturnType.FLOAT;
import static app.revanced.integrations.settings.SettingsEnum.ReturnType.INTEGER;
import static app.revanced.integrations.settings.SettingsEnum.ReturnType.LONG;
import static app.revanced.integrations.settings.SettingsEnum.ReturnType.STRING;
import static app.revanced.integrations.settings.SharedPrefCategory.RETURN_YOUTUBE_DISLIKE;
import static app.revanced.integrations.settings.SharedPrefCategory.SPONSOR_BLOCK;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.revanced.integrations.utils.StringRef;
import app.revanced.integrations.patches.theme.ThemePatch;
import java.util.Objects;
import app.revanced.integrations.utils.StringRef;
import static app.revanced.integrations.settings.SettingsEnum.ReturnType.*;
import static app.revanced.integrations.settings.SharedPrefCategory.RETURN_YOUTUBE_DISLIKE;
import static app.revanced.integrations.settings.SharedPrefCategory.SPONSOR_BLOCK;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
public enum SettingsEnum {
//Download Settings
@@ -80,30 +76,39 @@ public enum SettingsEnum {
DISABLE_STARTUP_SHORTS_PLAYER("revanced_startup_shorts_player_enabled", BOOLEAN, FALSE),
HIDE_ALBUM_CARDS("revanced_hide_album_cards", BOOLEAN, FALSE, true),
HIDE_ARTIST_CARDS("revanced_hide_artist_cards", BOOLEAN, FALSE),
HIDE_AUDIO_TRACK_BUTTON("revanced_hide_audio_track_button", BOOLEAN, FALSE),
HIDE_AUTOPLAY_BUTTON("revanced_hide_autoplay_button", BOOLEAN, TRUE, true),
HIDE_BREAKING_NEWS("revanced_hide_breaking_news", BOOLEAN, TRUE, true),
HIDE_CAPTIONS_BUTTON("revanced_hide_captions_button", BOOLEAN, FALSE),
HIDE_CAST_BUTTON("revanced_hide_cast_button", BOOLEAN, TRUE, true),
HIDE_COMMENTS_SECTION("revanced_hide_comments_section", BOOLEAN, FALSE, true),
HIDE_CREATE_BUTTON("revanced_hide_create_button", BOOLEAN, TRUE, true),
SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON("revanced_switch_create_with_notifications_button", BOOLEAN, TRUE, true),
HIDE_CROWDFUNDING_BOX("revanced_hide_crowdfunding_box", BOOLEAN, FALSE, true),
HIDE_EMAIL_ADDRESS("revanced_hide_email_address", BOOLEAN, FALSE),
HIDE_ENDSCREEN_CARDS("revanced_hide_endscreen_cards", BOOLEAN, TRUE),
HIDE_FLOATING_MICROPHONE_BUTTON("revanced_hide_floating_microphone_button", BOOLEAN, TRUE, true),
HIDE_FULLSCREEN_PANELS("revanced_hide_fullscreen_panels", BOOLEAN, TRUE),
HIDE_GET_PREMIUM("revanced_hide_get_premium", BOOLEAN, TRUE),
HIDE_INFO_CARDS("revanced_hide_infocards", BOOLEAN, TRUE),
HIDE_LOAD_MORE_BUTTON("revanced_hide_load_more_button", BOOLEAN, TRUE, true),
HIDE_PLAYER_BUTTONS("revanced_hide_player_buttons", BOOLEAN, FALSE),
HIDE_PLAYER_OVERLAY("revanced_hide_player_overlay", BOOLEAN, FALSE, true),
HIDE_PREVIEW_COMMENT("revanced_hide_preview_comment", BOOLEAN, FALSE, true),
HIDE_SEEKBAR("revanced_hide_seekbar", BOOLEAN, FALSE),
HIDE_HOME_BUTTON("revanced_hide_home_button", BOOLEAN, FALSE, true),
HIDE_SHORTS_BUTTON("revanced_hide_shorts_button", BOOLEAN, TRUE, true),
HIDE_SUBSCRIPTIONS_BUTTON("revanced_hide_subscriptions_button", BOOLEAN, FALSE, true),
HIDE_SHORTS_COMMENTS_BUTTON("revanced_hide_shorts_comments_button", BOOLEAN, FALSE),
HIDE_TIMESTAMP("revanced_hide_timestamp", BOOLEAN, FALSE),
HIDE_VIDEO_WATERMARK("revanced_hide_video_watermark", BOOLEAN, TRUE),
HIDE_WATCH_IN_VR("revanced_hide_watch_in_vr", BOOLEAN, FALSE, true),
PLAYER_POPUP_PANELS("revanced_player_popup_panels_enabled", BOOLEAN, FALSE),
SPOOF_APP_VERSION("revanced_spoof_app_version", BOOLEAN, FALSE, true, "revanced_spoof_app_version_user_dialog_message"),
SPOOF_APP_VERSION_TARGET("revanced_spoof_app_version_target", STRING, "17.30.35", true, parents(SPOOF_APP_VERSION)),
USE_TABLET_MINIPLAYER("revanced_tablet_miniplayer", BOOLEAN, FALSE, true),
WIDE_SEARCHBAR("revanced_wide_searchbar", BOOLEAN, FALSE, true),
SEEKBAR_COLOR("revanced_seekbar_color", STRING, "#FF0000", true),
// Misc. Settings
SIGNATURE_SPOOFING("revanced_spoof_signature_verification", BOOLEAN, TRUE, "revanced_spoof_signature_verification_user_dialog_message"),
@@ -121,11 +126,11 @@ public enum SettingsEnum {
parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)),
ENABLE_SWIPE_HAPTIC_FEEDBACK("revanced_enable_swipe_haptic_feedback", BOOLEAN, TRUE,
parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)),
SWIPE_MAGNITUDE_THRESHOLD("revanced_swipe_magnitude_threshold", FLOAT, 30f,
SWIPE_MAGNITUDE_THRESHOLD("revanced_swipe_magnitude_threshold", FLOAT, 30f, // edit: why is this a float and not an Integer?
parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)),
SWIPE_OVERLAY_BACKGROUND_ALPHA("revanced_swipe_overlay_background_alpha", INTEGER, 127,
parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)),
SWIPE_OVERLAY_TEXT_SIZE("revanced_swipe_overlay_text_size", FLOAT, 22f,
SWIPE_OVERLAY_TEXT_SIZE("revanced_swipe_overlay_text_size", FLOAT, 22f, // edit: why is this a float and not an Integer?
parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)),
SWIPE_OVERLAY_TIMEOUT("revanced_swipe_overlay_timeout", LONG, 500L,
parents(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)),
@@ -426,4 +431,4 @@ public enum SettingsEnum {
LONG,
FLOAT,
}
}
}

View File

@@ -8,6 +8,7 @@ import androidx.annotation.Nullable;
import java.util.Objects;
import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils;
/**
@@ -35,6 +36,11 @@ public enum SharedPrefCategory {
preferences = Objects.requireNonNull(ReVancedUtils.getContext()).getSharedPreferences(prefName, Context.MODE_PRIVATE);
}
private void removeConflictingPreferenceKeyValue(@NonNull String key) {
LogHelper.printException(() -> "Found conflicting preference: " + key);
preferences.edit().remove(key).apply();
}
private void saveObjectAsString(@NonNull String key, @Nullable Object value) {
preferences.edit().putString(key, (value == null ? null : value.toString())).apply();
}
@@ -91,7 +97,14 @@ public enum SharedPrefCategory {
}
return _default;
} catch (ClassCastException ex) {
return preferences.getInt(key, _default); // old data, previously stored as primitive
try {
// Old data previously stored as primitive.
return preferences.getInt(key, _default);
} catch (ClassCastException ex2) {
// Value stored is a completely different type (should never happen).
removeConflictingPreferenceKeyValue(key);
return _default;
}
}
}
@@ -104,7 +117,12 @@ public enum SharedPrefCategory {
}
return _default;
} catch (ClassCastException ex) {
return preferences.getLong(key, _default);
try {
return preferences.getLong(key, _default);
} catch (ClassCastException ex2) {
removeConflictingPreferenceKeyValue(key);
return _default;
}
}
}
@@ -117,7 +135,12 @@ public enum SharedPrefCategory {
}
return _default;
} catch (ClassCastException ex) {
return preferences.getFloat(key, _default);
try {
return preferences.getFloat(key, _default);
} catch (ClassCastException ex2) {
removeConflictingPreferenceKeyValue(key);
return _default;
}
}
}

View File

@@ -0,0 +1,66 @@
package app.revanced.integrations.settingsmenu;
import static app.revanced.integrations.utils.StringRef.str;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.util.AttributeSet;
import android.widget.Button;
import android.widget.EditText;
import java.util.Objects;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
public class ResettableEditTextPreference extends EditTextPreference {
public ResettableEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public ResettableEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ResettableEditTextPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ResettableEditTextPreference(Context context) {
super(context);
}
@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
SettingsEnum setting = SettingsEnum.settingFromPath(getKey());
if (setting != null) {
builder.setNeutralButton(str("revanced_settings_reset"), null);
}
}
@Override
protected void showDialog(Bundle state) {
super.showDialog(state);
// Override the button click listener to prevent dismissing the dialog.
Button button = ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_NEUTRAL);
if (button == null) {
return;
}
button.setOnClickListener(v -> {
try {
SettingsEnum setting = Objects.requireNonNull(SettingsEnum.settingFromPath(getKey()));
setting.saveValue(setting.defaultValue);
String defaultStringValue = setting.defaultValue.toString();
EditText editText = getEditText();
editText.setText(defaultStringValue);
editText.setSelection(defaultStringValue.length()); // move cursor to end of text
} catch (Exception ex) {
LogHelper.printException(() -> "reset failure", ex);
}
});
}
}

View File

@@ -20,33 +20,17 @@ import app.revanced.integrations.settings.SharedPrefCategory;
public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
/**
* If ReturnYouTubeDislike is enabled
*/
private SwitchPreference enabledPreference;
/**
* If dislikes are shown as percentage
* If dislikes are shown as percentage.
*/
private SwitchPreference percentagePreference;
/**
* If segmented like/dislike button uses smaller compact layout
* If segmented like/dislike button uses smaller compact layout.
*/
private SwitchPreference compactLayoutPreference;
private void updateUIState() {
enabledPreference.setSummary(SettingsEnum.RYD_ENABLED.getBoolean()
? str("revanced_ryd_enable_summary_on")
: str("revanced_ryd_enable_summary_off"));
percentagePreference.setSummary(SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.getBoolean()
? str("revanced_ryd_dislike_percentage_summary_on")
: str("revanced_ryd_dislike_percentage_summary_off"));
percentagePreference.setEnabled(SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.isAvailable());
compactLayoutPreference.setSummary(SettingsEnum.RYD_USE_COMPACT_LAYOUT.getBoolean()
? str("revanced_ryd_compact_layout_summary_on")
: str("revanced_ryd_compact_layout_summary_off"));
compactLayoutPreference.setEnabled(SettingsEnum.RYD_USE_COMPACT_LAYOUT.isAvailable());
}
@@ -59,9 +43,11 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(context);
setPreferenceScreen(preferenceScreen);
enabledPreference = new SwitchPreference(context);
SwitchPreference enabledPreference = new SwitchPreference(context);
enabledPreference.setChecked(SettingsEnum.RYD_ENABLED.getBoolean());
enabledPreference.setTitle(str("revanced_ryd_enable_title"));
enabledPreference.setSummaryOn(str("revanced_ryd_enable_summary_on"));
enabledPreference.setSummaryOff(str("revanced_ryd_enable_summary_off"));
enabledPreference.setOnPreferenceChangeListener((pref, newValue) -> {
final boolean rydIsEnabled = (Boolean) newValue;
SettingsEnum.RYD_ENABLED.saveValue(rydIsEnabled);
@@ -75,6 +61,8 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
percentagePreference = new SwitchPreference(context);
percentagePreference.setChecked(SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.getBoolean());
percentagePreference.setTitle(str("revanced_ryd_dislike_percentage_title"));
percentagePreference.setSummaryOn(str("revanced_ryd_dislike_percentage_summary_on"));
percentagePreference.setSummaryOff(str("revanced_ryd_dislike_percentage_summary_off"));
percentagePreference.setOnPreferenceChangeListener((pref, newValue) -> {
SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.saveValue(newValue);
ReturnYouTubeDislike.clearCache();
@@ -86,6 +74,8 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
compactLayoutPreference = new SwitchPreference(context);
compactLayoutPreference.setChecked(SettingsEnum.RYD_USE_COMPACT_LAYOUT.getBoolean());
compactLayoutPreference.setTitle(str("revanced_ryd_compact_layout_title"));
compactLayoutPreference.setSummaryOn(str("revanced_ryd_compact_layout_summary_on"));
compactLayoutPreference.setSummaryOff(str("revanced_ryd_compact_layout_summary_off"));
compactLayoutPreference.setOnPreferenceChangeListener((pref, newValue) -> {
SettingsEnum.RYD_USE_COMPACT_LAYOUT.saveValue(newValue);
ReturnYouTubeDislike.clearCache();
@@ -185,7 +175,7 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
}
}
private String createSummaryText(int value, String summaryStringZeroKey, String summaryStringOneOrMoreKey) {
private static String createSummaryText(int value, String summaryStringZeroKey, String summaryStringOneOrMoreKey) {
if (value == 0) {
return str(summaryStringZeroKey);
}

View File

@@ -102,9 +102,9 @@ public class SegmentPlaybackController {
@Nullable
private static String timeWithoutSegments;
private static float sponsorBarLeft = 1f;
private static float sponsorBarRight = 1f;
private static float sponsorBarThickness = 2f;
private static int sponsorBarAbsoluteLeft;
private static int sponsorAbsoluteBarRight;
private static int sponsorBarThickness;
@Nullable
static SponsorSegment[] getSegments() {
@@ -177,7 +177,7 @@ public class SegmentPlaybackController {
* Injection point.
* Initializes SponsorBlock when the video player starts playing a new video.
*/
public static void initialize(Object _o) {
public static void initialize(Object ignoredPlayerController) {
try {
ReVancedUtils.verifyOnMainThread();
SponsorBlockSettings.initialize();
@@ -235,7 +235,7 @@ public class SegmentPlaybackController {
SponsorSegment[] segments = SBRequester.getSegments(videoId);
ReVancedUtils.runOnMainThread(()-> {
if (!videoId.equals(SegmentPlaybackController.currentVideoId)) {
if (!videoId.equals(currentVideoId)) {
// user changed videos before get segments network call could complete
LogHelper.printDebug(() -> "Ignoring segments for prior video: " + videoId);
return;
@@ -525,7 +525,7 @@ public class SegmentPlaybackController {
if (!userManuallySkipped) {
// check for any smaller embedded segments, and count those as autoskipped
final boolean showSkipToast = SettingsEnum.SB_SHOW_TOAST_ON_SKIP.getBoolean();
for (final SponsorSegment otherSegment : segments) {
for (final SponsorSegment otherSegment : Objects.requireNonNull(segments)) {
if (segmentToSkip.end < otherSegment.start) {
break; // no other segments can be contained
}
@@ -599,20 +599,6 @@ public class SegmentPlaybackController {
}
}
/**
* Injection point.
*/
public static void setSponsorBarAbsoluteLeft(final Rect rect) {
setSponsorBarAbsoluteLeft(rect.left);
}
public static void setSponsorBarAbsoluteLeft(final float left) {
if (sponsorBarLeft != left) {
LogHelper.printDebug(() -> String.format("setSponsorBarAbsoluteLeft: left=%.2f", left));
sponsorBarLeft = left;
}
}
/**
* Injection point
*/
@@ -620,13 +606,9 @@ public class SegmentPlaybackController {
try {
Field field = self.getClass().getDeclaredField("replaceMeWithsetSponsorBarRect");
field.setAccessible(true);
Rect rect = (Rect) field.get(self);
if (rect == null) {
LogHelper.printException(() -> "Could not find sponsorblock rect");
} else {
setSponsorBarAbsoluteLeft(rect.left);
setSponsorBarAbsoluteRight(rect.right);
}
Rect rect = (Rect) Objects.requireNonNull(field.get(self));
setSponsorBarAbsoluteLeft(rect);
setSponsorBarAbsoluteRight(rect);
} catch (Exception ex) {
LogHelper.printException(() -> "setSponsorBarRect failure", ex);
}
@@ -635,27 +617,31 @@ public class SegmentPlaybackController {
/**
* Injection point.
*/
public static void setSponsorBarAbsoluteRight(final Rect rect) {
setSponsorBarAbsoluteRight(rect.right);
public static void setSponsorBarAbsoluteLeft(Rect rect) {
final int left = rect.left;
if (sponsorBarAbsoluteLeft != left) {
LogHelper.printDebug(() -> "setSponsorBarAbsoluteLeft: " + left);
sponsorBarAbsoluteLeft = left;
}
}
public static void setSponsorBarAbsoluteRight(final float right) {
if (sponsorBarRight != right) {
LogHelper.printDebug(() -> String.format("setSponsorBarAbsoluteRight: right=%.2f", right));
sponsorBarRight = right;
/**
* Injection point.
*/
public static void setSponsorBarAbsoluteRight(Rect rect) {
final int right = rect.right;
if (sponsorAbsoluteBarRight != right) {
LogHelper.printDebug(() -> "setSponsorBarAbsoluteRight: " + right);
sponsorAbsoluteBarRight = right;
}
}
/**
* Injection point
*/
public static void setSponsorBarThickness(final int thickness) {
setSponsorBarThickness((float) thickness);
}
public static void setSponsorBarThickness(final float thickness) {
public static void setSponsorBarThickness(int thickness) {
if (sponsorBarThickness != thickness) {
LogHelper.printDebug(() -> String.format("setSponsorBarThickness: %.2f", thickness));
LogHelper.printDebug(() -> "setSponsorBarThickness: " + thickness);
sponsorBarThickness = thickness;
}
}
@@ -736,25 +722,23 @@ public class SegmentPlaybackController {
*/
public static void drawSponsorTimeBars(final Canvas canvas, final float posY) {
try {
if (sponsorBarThickness < 0.1) return;
if (segments == null) return;
final long videoLength = VideoInformation.getVideoLength();
if (videoLength <= 0) return;
final float thicknessDiv2 = sponsorBarThickness / 2;
final float top = posY - thicknessDiv2;
final int thicknessDiv2 = sponsorBarThickness / 2; // rounds down
final float top = posY - (sponsorBarThickness - thicknessDiv2);
final float bottom = posY + thicknessDiv2;
final float absoluteLeft = sponsorBarLeft;
final float absoluteRight = sponsorBarRight;
final float videoMillisecondsToPixels = (1f / videoLength) * (sponsorAbsoluteBarRight - sponsorBarAbsoluteLeft);
final float leftPadding = sponsorBarAbsoluteLeft;
final float tmp1 = (1f / videoLength) * (absoluteRight - absoluteLeft);
for (SponsorSegment segment : segments) {
final float left = segment.start * tmp1 + absoluteLeft;
final float left = leftPadding + segment.start * videoMillisecondsToPixels;
final float right;
if (segment.category == SegmentCategory.HIGHLIGHT) {
right = left + getHighlightSegmentTimeBarScreenWidth();
} else {
right = segment.end * tmp1 + absoluteLeft;
right = leftPadding + segment.end * videoMillisecondsToPixels;
}
canvas.drawRect(left, top, right, bottom, segment.category.paint);
}

View File

@@ -3,52 +3,35 @@ package app.revanced.integrations.sponsorblock.ui;
import static app.revanced.integrations.utils.ReVancedUtils.getResourceIdentifier;
import android.view.View;
import android.view.animation.Animation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import java.lang.ref.WeakReference;
import java.util.Objects;
import app.revanced.integrations.patches.VideoInformation;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils;
import app.revanced.integrations.videoplayer.BottomControlButton;
public class CreateSegmentButtonController {
private static WeakReference<ImageView> buttonReference = new WeakReference<>(null);
private static Animation fadeIn;
private static Animation fadeOut;
private static boolean isShowing;
/**
* injection point
*/
public static void initialize(Object viewStub) {
public static void initialize(View youtubeControlsLayout) {
try {
LogHelper.printDebug(() -> "initializing new segment button");
RelativeLayout youtubeControlsLayout = (RelativeLayout) viewStub;
String buttonIdentifier = "sb_sponsorblock_button";
ImageView imageView = youtubeControlsLayout.findViewById(getResourceIdentifier(buttonIdentifier, "id"));
if (imageView == null) {
LogHelper.printException(() -> "Couldn't find imageView with \"" + buttonIdentifier + "\"");
return;
}
ImageView imageView = Objects.requireNonNull(youtubeControlsLayout.findViewById(
getResourceIdentifier("sb_sponsorblock_button", "id")));
imageView.setVisibility(View.GONE);
imageView.setOnClickListener(v -> {
LogHelper.printDebug(() -> "New segment button clicked");
SponsorBlockViewController.toggleNewSegmentLayoutVisibility();
});
buttonReference = new WeakReference<>(imageView);
// Animations
if (fadeIn == null) {
fadeIn = ReVancedUtils.getResourceAnimation("fade_in");
fadeIn.setDuration(ReVancedUtils.getResourceInteger("fade_duration_fast"));
fadeOut = ReVancedUtils.getResourceAnimation("fade_out");
fadeOut.setDuration(ReVancedUtils.getResourceInteger("fade_duration_scheduled"));
}
isShowing = true;
changeVisibilityImmediate(false);
buttonReference = new WeakReference<>(imageView);
} catch (Exception ex) {
LogHelper.printException(() -> "initialize failure", ex);
}
@@ -86,7 +69,7 @@ public class CreateSegmentButtonController {
return;
}
if (!immediate) {
iView.startAnimation(fadeIn);
iView.startAnimation(BottomControlButton.getButtonFadeIn());
}
iView.setVisibility(View.VISIBLE);
return;
@@ -95,7 +78,7 @@ public class CreateSegmentButtonController {
if (iView.getVisibility() == View.VISIBLE) {
iView.clearAnimation();
if (!immediate) {
iView.startAnimation(fadeOut);
iView.startAnimation(BottomControlButton.getButtonFadeOut());
}
iView.setVisibility(View.GONE);
}

View File

@@ -51,7 +51,7 @@ public class SponsorBlockViewController {
/**
* Injection point.
*/
public static void initialize(Object obj) {
public static void initialize(ViewGroup viewGroup) {
try {
LogHelper.printDebug(() -> "initializing");
@@ -64,7 +64,6 @@ public class SponsorBlockViewController {
LayoutInflater.from(context).inflate(getResourceIdentifier("inline_sponsor_overlay", "layout"), layout);
inlineSponsorOverlayRef = new WeakReference<>(layout);
ViewGroup viewGroup = (ViewGroup) obj;
viewGroup.addView(layout);
viewGroup.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
@Override

View File

@@ -3,11 +3,10 @@ package app.revanced.integrations.sponsorblock.ui;
import static app.revanced.integrations.utils.ReVancedUtils.getResourceIdentifier;
import android.view.View;
import android.view.animation.Animation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import java.lang.ref.WeakReference;
import java.util.Objects;
import app.revanced.integrations.patches.VideoInformation;
import app.revanced.integrations.settings.SettingsEnum;
@@ -15,40 +14,26 @@ import app.revanced.integrations.sponsorblock.SegmentPlaybackController;
import app.revanced.integrations.sponsorblock.SponsorBlockUtils;
import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils;
import app.revanced.integrations.videoplayer.BottomControlButton;
public class VotingButtonController {
private static WeakReference<ImageView> buttonReference = new WeakReference<>(null);
private static Animation fadeIn;
private static Animation fadeOut;
private static boolean isShowing;
/**
* injection point
*/
public static void initialize(Object viewStub) {
public static void initialize(View youtubeControlsLayout) {
try {
LogHelper.printDebug(() -> "initializing voting button");
RelativeLayout controlsLayout = (RelativeLayout) viewStub;
String buttonResourceName = "sb_voting_button";
ImageView imageView = controlsLayout.findViewById(getResourceIdentifier(buttonResourceName, "id"));
if (imageView == null) {
LogHelper.printException(() -> "Couldn't find imageView with \"" + buttonResourceName + "\"");
return;
}
ImageView imageView = Objects.requireNonNull(youtubeControlsLayout.findViewById(
getResourceIdentifier("sb_voting_button", "id")));
imageView.setVisibility(View.GONE);
imageView.setOnClickListener(v -> {
SponsorBlockUtils.onVotingClicked(v.getContext());
});
buttonReference = new WeakReference<>(imageView);
// Animations
if (fadeIn == null) {
fadeIn = ReVancedUtils.getResourceAnimation("fade_in");
fadeIn.setDuration(ReVancedUtils.getResourceInteger("fade_duration_fast"));
fadeOut = ReVancedUtils.getResourceAnimation("fade_out");
fadeOut.setDuration(ReVancedUtils.getResourceInteger("fade_duration_scheduled"));
}
isShowing = true;
changeVisibilityImmediate(false);
buttonReference = new WeakReference<>(imageView);
} catch (Exception ex) {
LogHelper.printException(() -> "Unable to set RelativeLayout", ex);
}
@@ -86,7 +71,7 @@ public class VotingButtonController {
return;
}
if (!immediate) {
iView.startAnimation(fadeIn);
iView.startAnimation(BottomControlButton.getButtonFadeIn());
}
iView.setVisibility(View.VISIBLE);
return;
@@ -95,7 +80,7 @@ public class VotingButtonController {
if (iView.getVisibility() == View.VISIBLE) {
iView.clearAnimation();
if (!immediate) {
iView.startAnimation(fadeOut);
iView.startAnimation(BottomControlButton.getButtonFadeOut());
}
iView.setVisibility(View.GONE);
}
@@ -116,7 +101,6 @@ public class VotingButtonController {
ReVancedUtils.verifyOnMainThread();
View v = buttonReference.get();
if (v == null) {
LogHelper.printDebug(() -> "Cannot hide voting button (value is null)");
return;
}
v.setVisibility(View.GONE);

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