You've already forked revanced-integrations
mirror of
https://github.com/revanced/revanced-integrations
synced 2025-11-19 03:23:27 +01:00
Compare commits
76 Commits
v0.100.0-d
...
v0.104.0-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe40475b6f | ||
|
|
52a3193087 | ||
|
|
2320880a42 | ||
|
|
98edcdd589 | ||
|
|
7d95844167 | ||
|
|
afd9b6e305 | ||
|
|
5e6d9ed9cd | ||
|
|
1ada30d5c9 | ||
|
|
f20f6c24b3 | ||
|
|
a61148cac2 | ||
|
|
c2ff0c45ab | ||
|
|
587689ed7b | ||
|
|
a2af2c0c9f | ||
|
|
f7c3543d4f | ||
|
|
86c27890ad | ||
|
|
2ea55af9ce | ||
|
|
41c07f77f4 | ||
|
|
48050c1c50 | ||
|
|
8797765efa | ||
|
|
fb8442823e | ||
|
|
da7b669c97 | ||
|
|
4d9b41ca3a | ||
|
|
03f09cf7bc | ||
|
|
76a01d1b7c | ||
|
|
14223f40b5 | ||
|
|
5ba4cbd4e0 | ||
|
|
212e4f2ce4 | ||
|
|
b959c8ef98 | ||
|
|
6265a91841 | ||
|
|
6dbccfd472 | ||
|
|
e3d923d564 | ||
|
|
80ae9ebbd2 | ||
|
|
584de16236 | ||
|
|
a0ad968aaa | ||
|
|
d4de3f6819 | ||
|
|
22e453706d | ||
|
|
bbb07ec9c8 | ||
|
|
3025103014 | ||
|
|
e3529cfcec | ||
|
|
6528d444b4 | ||
|
|
f8184905bd | ||
|
|
5981e99e56 | ||
|
|
214f2c89c2 | ||
|
|
a7ae215bf7 | ||
|
|
eeddb59b08 | ||
|
|
1a0a6ee90b | ||
|
|
86bedb2183 | ||
|
|
5b9682522e | ||
|
|
6d32dff400 | ||
|
|
5cb5656324 | ||
|
|
7627e5d057 | ||
|
|
0810f84c4c | ||
|
|
8301fa07fd | ||
|
|
d16980ef2f | ||
|
|
83510e51b3 | ||
|
|
68d09305b9 | ||
|
|
dc5c1b45ba | ||
|
|
46e0272f9e | ||
|
|
69ccb5fc05 | ||
|
|
2dd14313a6 | ||
|
|
5e518855d1 | ||
|
|
52ac4acff3 | ||
|
|
a08bc53828 | ||
|
|
5d7dc94d8d | ||
|
|
1e1504d118 | ||
|
|
393d6e62f2 | ||
|
|
1361595076 | ||
|
|
2f5c839613 | ||
|
|
7e64e05709 | ||
|
|
d5919a8a2c | ||
|
|
844bc3b24f | ||
|
|
67fa87051f | ||
|
|
1f90f7b9cc | ||
|
|
0c725218fd | ||
|
|
416c695837 | ||
|
|
919f2855ed |
9
.github/workflows/pull_request.yml
vendored
9
.github/workflows/pull_request.yml
vendored
@@ -21,5 +21,10 @@ jobs:
|
||||
with:
|
||||
destination_branch: 'main'
|
||||
pr_title: 'chore: ${{ env.MESSAGE }}'
|
||||
pr_body: 'This pull request will ${{ env.MESSAGE }}.'
|
||||
pr_draft: true
|
||||
pr_body: |
|
||||
This pull request will ${{ env.MESSAGE }}.
|
||||
|
||||
## Dependencies before merge
|
||||
|
||||
- [ ] https://github.com/revanced/revanced-patches
|
||||
pr_draft: true
|
||||
|
||||
240
CHANGELOG.md
240
CHANGELOG.md
@@ -1,3 +1,243 @@
|
||||
# [0.104.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.103.1-dev.2...v0.104.0-dev.1) (2023-04-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/wide-searchbar:** rename patch ([2320880](https://github.com/revanced/revanced-integrations/commit/2320880a42bf37335ececf1f8e6cb83bd57f347d))
|
||||
* **youtube:** bump compatibility to `18.15.40` ([#367](https://github.com/revanced/revanced-integrations/issues/367)) ([52a3193](https://github.com/revanced/revanced-integrations/commit/52a31930870b838e766d08c3203bd8cd7ae443ba))
|
||||
* **youtube:** remove non working patch `hide-my-mix` ([98edcdd](https://github.com/revanced/revanced-integrations/commit/98edcdd589c0d3615530b44c8bbaeb94ae599afb))
|
||||
|
||||
## [0.103.1-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.103.1-dev.1...v0.103.1-dev.2) (2023-04-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/hide-video-action-buttons:** fix hide action buttons not working for some users ([#366](https://github.com/revanced/revanced-integrations/issues/366)) ([afd9b6e](https://github.com/revanced/revanced-integrations/commit/afd9b6e30566d735075c16d3f5173e406c965a8c))
|
||||
|
||||
## [0.103.1-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.103.0...v0.103.1-dev.1) (2023-04-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/sponsorblock:** Include milliseconds in the voting menu ([#362](https://github.com/revanced/revanced-integrations/issues/362)) ([1ada30d](https://github.com/revanced/revanced-integrations/commit/1ada30d5c925f1b0f21d45865240780e4ecd84d7))
|
||||
|
||||
# [0.103.0](https://github.com/revanced/revanced-integrations/compare/v0.102.0...v0.103.0) (2023-04-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* minor syntax error ([8797765](https://github.com/revanced/revanced-integrations/commit/8797765efa0fb98b6e11a7198ecce3943df3daf5))
|
||||
* **youtube/general-ads:** hide new types of ads ([#339](https://github.com/revanced/revanced-integrations/issues/339)) ([6528d44](https://github.com/revanced/revanced-integrations/commit/6528d444b49759ee1137c9b0eb8e1079fb4cc97c))
|
||||
* **youtube/hide-video-action-buttons:** fix 'hide share button' ([#360](https://github.com/revanced/revanced-integrations/issues/360)) ([a2af2c0](https://github.com/revanced/revanced-integrations/commit/a2af2c0c9ffc2f961773bfb8d546aff68c2d1c27))
|
||||
* **youtube/return-youtube-dislike:** fix error toast when voting ([#349](https://github.com/revanced/revanced-integrations/issues/349)) ([e3d923d](https://github.com/revanced/revanced-integrations/commit/e3d923d564ae572c5e0e10a86ce17b8009ec8c42))
|
||||
* **youtube/return-youtube-dislike:** render dislikes when scrolling into the screen ([#350](https://github.com/revanced/revanced-integrations/issues/350)) ([41c07f7](https://github.com/revanced/revanced-integrations/commit/41c07f77f47d726fdc16120bb5695407a7dec1fc))
|
||||
* **youtube/return-youtube-dislike:** stale dislike data shown after opening / closing the app during shorts playback ([#356](https://github.com/revanced/revanced-integrations/issues/356)) ([212e4f2](https://github.com/revanced/revanced-integrations/commit/212e4f2ce43360776fe20467c4142c9936b22d42))
|
||||
* **youtube/settings:** fix dialog not shown if dismissed with back button ([584de16](https://github.com/revanced/revanced-integrations/commit/584de16236ff758c2067ee84ba4cc04d765d49ba))
|
||||
* **youtube/sponsorblock:** always show the video time without segments using left to right layout ([#359](https://github.com/revanced/revanced-integrations/issues/359)) ([86c2789](https://github.com/revanced/revanced-integrations/commit/86c27890ada8739ea272f8783eb4ef526b808a27))
|
||||
* **youtube/sponsorblock:** change default behavior to better match the browser ([#353](https://github.com/revanced/revanced-integrations/issues/353)) ([b959c8e](https://github.com/revanced/revanced-integrations/commit/b959c8ef98e869201c8bc2609943108283fea453))
|
||||
* **youtube/sponsorblock:** settings do not show default behavior ([#351](https://github.com/revanced/revanced-integrations/issues/351)) ([6dbccfd](https://github.com/revanced/revanced-integrations/commit/6dbccfd472d843b5c3f0efed39b575d3ea7ac04f))
|
||||
* **youtube/sponsorblock:** update HTTP user agent ([#344](https://github.com/revanced/revanced-integrations/issues/344)) ([3025103](https://github.com/revanced/revanced-integrations/commit/3025103014a4521a437cfde0a417535e7751b517))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/general-ads:** block new type of ad ([6265a91](https://github.com/revanced/revanced-integrations/commit/6265a91841f8b037be22dd5fd5399dbeeb666745))
|
||||
* **youtube/general-ads:** hide new type of ad ([5ba4cbd](https://github.com/revanced/revanced-integrations/commit/5ba4cbd4e097d863924731d363dd5bb8849e1394))
|
||||
* **youtube/general-ads:** hide new type of ad ([f818490](https://github.com/revanced/revanced-integrations/commit/f8184905bd9601bf63e30963ff337d24f2599794))
|
||||
* **youtube/general-ads:** hide new type of movie offer ad ([da7b669](https://github.com/revanced/revanced-integrations/commit/da7b669c97d18bef51de98ddfde8a514ebb61ecf))
|
||||
* **youtube/settings:** disable preference control if the feature is turned off. show a dialog explaining side effects of some patches ([#328](https://github.com/revanced/revanced-integrations/issues/328)) ([a0ad968](https://github.com/revanced/revanced-integrations/commit/a0ad968aaa66422e67de2a61d76bc7aa88f08bf6))
|
||||
* **youtube/sponsorblock:** skip to video highlight ([#352](https://github.com/revanced/revanced-integrations/issues/352)) ([03f09cf](https://github.com/revanced/revanced-integrations/commit/03f09cf7bce1747b1d402f3a3e16dd69c364dfce))
|
||||
* **youtube:** user selectable default video speed and quality ([#354](https://github.com/revanced/revanced-integrations/issues/354)) ([14223f4](https://github.com/revanced/revanced-integrations/commit/14223f40b5ca48f35bbecfd849dff20dfd309d92))
|
||||
|
||||
# [0.103.0-dev.7](https://github.com/revanced/revanced-integrations/compare/v0.103.0-dev.6...v0.103.0-dev.7) (2023-04-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/hide-video-action-buttons:** fix 'hide share button' ([#360](https://github.com/revanced/revanced-integrations/issues/360)) ([a2af2c0](https://github.com/revanced/revanced-integrations/commit/a2af2c0c9ffc2f961773bfb8d546aff68c2d1c27))
|
||||
|
||||
# [0.103.0-dev.6](https://github.com/revanced/revanced-integrations/compare/v0.103.0-dev.5...v0.103.0-dev.6) (2023-04-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/sponsorblock:** always show the video time without segments using left to right layout ([#359](https://github.com/revanced/revanced-integrations/issues/359)) ([86c2789](https://github.com/revanced/revanced-integrations/commit/86c27890ada8739ea272f8783eb4ef526b808a27))
|
||||
|
||||
# [0.103.0-dev.5](https://github.com/revanced/revanced-integrations/compare/v0.103.0-dev.4...v0.103.0-dev.5) (2023-04-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/return-youtube-dislike:** render dislikes when scrolling into the screen ([#350](https://github.com/revanced/revanced-integrations/issues/350)) ([41c07f7](https://github.com/revanced/revanced-integrations/commit/41c07f77f47d726fdc16120bb5695407a7dec1fc))
|
||||
|
||||
# [0.103.0-dev.4](https://github.com/revanced/revanced-integrations/compare/v0.103.0-dev.3...v0.103.0-dev.4) (2023-04-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* minor syntax error ([8797765](https://github.com/revanced/revanced-integrations/commit/8797765efa0fb98b6e11a7198ecce3943df3daf5))
|
||||
|
||||
# [0.103.0-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.103.0-dev.2...v0.103.0-dev.3) (2023-04-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/general-ads:** hide new type of movie offer ad ([da7b669](https://github.com/revanced/revanced-integrations/commit/da7b669c97d18bef51de98ddfde8a514ebb61ecf))
|
||||
|
||||
# [0.103.0-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.103.0-dev.1...v0.103.0-dev.2) (2023-04-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/sponsorblock:** skip to video highlight ([#352](https://github.com/revanced/revanced-integrations/issues/352)) ([03f09cf](https://github.com/revanced/revanced-integrations/commit/03f09cf7bce1747b1d402f3a3e16dd69c364dfce))
|
||||
|
||||
# [0.103.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.102.0...v0.103.0-dev.1) (2023-04-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/general-ads:** hide new types of ads ([#339](https://github.com/revanced/revanced-integrations/issues/339)) ([6528d44](https://github.com/revanced/revanced-integrations/commit/6528d444b49759ee1137c9b0eb8e1079fb4cc97c))
|
||||
* **youtube/return-youtube-dislike:** fix error toast when voting ([#349](https://github.com/revanced/revanced-integrations/issues/349)) ([e3d923d](https://github.com/revanced/revanced-integrations/commit/e3d923d564ae572c5e0e10a86ce17b8009ec8c42))
|
||||
* **youtube/return-youtube-dislike:** stale dislike data shown after opening / closing the app during shorts playback ([#356](https://github.com/revanced/revanced-integrations/issues/356)) ([212e4f2](https://github.com/revanced/revanced-integrations/commit/212e4f2ce43360776fe20467c4142c9936b22d42))
|
||||
* **youtube/settings:** fix dialog not shown if dismissed with back button ([584de16](https://github.com/revanced/revanced-integrations/commit/584de16236ff758c2067ee84ba4cc04d765d49ba))
|
||||
* **youtube/sponsorblock:** change default behavior to better match the browser ([#353](https://github.com/revanced/revanced-integrations/issues/353)) ([b959c8e](https://github.com/revanced/revanced-integrations/commit/b959c8ef98e869201c8bc2609943108283fea453))
|
||||
* **youtube/sponsorblock:** settings do not show default behavior ([#351](https://github.com/revanced/revanced-integrations/issues/351)) ([6dbccfd](https://github.com/revanced/revanced-integrations/commit/6dbccfd472d843b5c3f0efed39b575d3ea7ac04f))
|
||||
* **youtube/sponsorblock:** update HTTP user agent ([#344](https://github.com/revanced/revanced-integrations/issues/344)) ([3025103](https://github.com/revanced/revanced-integrations/commit/3025103014a4521a437cfde0a417535e7751b517))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/general-ads:** block new type of ad ([6265a91](https://github.com/revanced/revanced-integrations/commit/6265a91841f8b037be22dd5fd5399dbeeb666745))
|
||||
* **youtube/general-ads:** hide new type of ad ([5ba4cbd](https://github.com/revanced/revanced-integrations/commit/5ba4cbd4e097d863924731d363dd5bb8849e1394))
|
||||
* **youtube/general-ads:** hide new type of ad ([f818490](https://github.com/revanced/revanced-integrations/commit/f8184905bd9601bf63e30963ff337d24f2599794))
|
||||
* **youtube/settings:** disable preference control if the feature is turned off. show a dialog explaining side effects of some patches ([#328](https://github.com/revanced/revanced-integrations/issues/328)) ([a0ad968](https://github.com/revanced/revanced-integrations/commit/a0ad968aaa66422e67de2a61d76bc7aa88f08bf6))
|
||||
* **youtube:** user selectable default video speed and quality ([#354](https://github.com/revanced/revanced-integrations/issues/354)) ([14223f4](https://github.com/revanced/revanced-integrations/commit/14223f40b5ca48f35bbecfd849dff20dfd309d92))
|
||||
|
||||
# [0.102.0](https://github.com/revanced/revanced-integrations/compare/v0.101.1...v0.102.0) (2023-04-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/spoof-signature-verification:** enable by default ([#357](https://github.com/revanced/revanced-integrations/issues/357)) ([214f2c8](https://github.com/revanced/revanced-integrations/commit/214f2c89c2884f250af557e6bf03fefb64a056b6))
|
||||
|
||||
## [0.101.1](https://github.com/revanced/revanced-integrations/compare/v0.101.0...v0.101.1) (2023-04-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/spoof-signature-verification:** additional fixes for subtitle locations ([#346](https://github.com/revanced/revanced-integrations/issues/346)) ([eeddb59](https://github.com/revanced/revanced-integrations/commit/eeddb59b0815b9e92869fc7c1d1f49d51039ce2e))
|
||||
* **youtube/spoof-signature-verification:** fixed subtitles in wrong location ([#343](https://github.com/revanced/revanced-integrations/issues/343)) ([1a0a6ee](https://github.com/revanced/revanced-integrations/commit/1a0a6ee90be8168f46ada6dfc736f3609a921561))
|
||||
* **youtube/spoof-signature-verification:** spoof videos in playlists ([86bedb2](https://github.com/revanced/revanced-integrations/commit/86bedb2183c01bd06afaa10221e2a1504ee20ed3))
|
||||
|
||||
# [0.101.0](https://github.com/revanced/revanced-integrations/compare/v0.100.1...v0.101.0) (2023-03-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/remember-playback-speed:** allow to not remember playback speed ([#338](https://github.com/revanced/revanced-integrations/issues/338)) ([7627e5d](https://github.com/revanced/revanced-integrations/commit/7627e5d057fdfb5847b2406b609634489efd3cbf))
|
||||
* **youtube/return-youtube-dislike:** fix right to left text layout ([#333](https://github.com/revanced/revanced-integrations/issues/333)) ([2dd1431](https://github.com/revanced/revanced-integrations/commit/2dd14313a64930acbb544f4ad971c51dcfbb80e1))
|
||||
* **youtube/return-youtube-dislike:** layout fix for low dpi devices ([#335](https://github.com/revanced/revanced-integrations/issues/335)) ([46e0272](https://github.com/revanced/revanced-integrations/commit/46e0272f9e96e7893e6fbb919d90248f59addaf9))
|
||||
* **youtube/spoof-signature-verification:** fix audio during home feed video playback ([#336](https://github.com/revanced/revanced-integrations/issues/336)) ([68d0930](https://github.com/revanced/revanced-integrations/commit/68d09305b990b411efffeeb02aa638e59eee9e5d))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/spoof-signature-verification:** automatic signature spoofing ([d16980e](https://github.com/revanced/revanced-integrations/commit/d16980ef2f18b7b5752be36f0183985c6c398ea1))
|
||||
|
||||
# [0.101.0-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.101.0-dev.1...v0.101.0-dev.2) (2023-03-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/remember-playback-speed:** allow to not remember playback speed ([#338](https://github.com/revanced/revanced-integrations/issues/338)) ([7627e5d](https://github.com/revanced/revanced-integrations/commit/7627e5d057fdfb5847b2406b609634489efd3cbf))
|
||||
|
||||
# [0.101.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.100.2-dev.3...v0.101.0-dev.1) (2023-03-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/spoof-signature-verification:** automatic signature spoofing ([d16980e](https://github.com/revanced/revanced-integrations/commit/d16980ef2f18b7b5752be36f0183985c6c398ea1))
|
||||
|
||||
## [0.100.2-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.100.2-dev.2...v0.100.2-dev.3) (2023-03-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/spoof-signature-verification:** fix audio during home feed video playback ([#336](https://github.com/revanced/revanced-integrations/issues/336)) ([68d0930](https://github.com/revanced/revanced-integrations/commit/68d09305b990b411efffeeb02aa638e59eee9e5d))
|
||||
|
||||
## [0.100.2-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.100.2-dev.1...v0.100.2-dev.2) (2023-03-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/return-youtube-dislike:** layout fix for low dpi devices ([#335](https://github.com/revanced/revanced-integrations/issues/335)) ([46e0272](https://github.com/revanced/revanced-integrations/commit/46e0272f9e96e7893e6fbb919d90248f59addaf9))
|
||||
|
||||
## [0.100.2-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.100.1...v0.100.2-dev.1) (2023-03-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/return-youtube-dislike:** fix right to left text layout ([#333](https://github.com/revanced/revanced-integrations/issues/333)) ([2dd1431](https://github.com/revanced/revanced-integrations/commit/2dd14313a64930acbb544f4ad971c51dcfbb80e1))
|
||||
|
||||
## [0.100.1](https://github.com/revanced/revanced-integrations/compare/v0.100.0...v0.100.1) (2023-03-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* minor syntax issue ([1e1504d](https://github.com/revanced/revanced-integrations/commit/1e1504d118d656492df0bee30364e966a8dc99b4))
|
||||
|
||||
## [0.100.1-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.100.0...v0.100.1-dev.1) (2023-03-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* minor syntax issue ([1e1504d](https://github.com/revanced/revanced-integrations/commit/1e1504d118d656492df0bee30364e966a8dc99b4))
|
||||
|
||||
# [0.100.0](https://github.com/revanced/revanced-integrations/compare/v0.99.0...v0.100.0) (2023-03-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/general-ads:** hide any kind of buttoned ad ([0b3508b](https://github.com/revanced/revanced-integrations/commit/0b3508bd8dcd6e031f1a7625ee5214fd093ee3f5))
|
||||
* **youtube/general-ads:** hide chapters in video description ([#326](https://github.com/revanced/revanced-integrations/issues/326)) ([f31e3a0](https://github.com/revanced/revanced-integrations/commit/f31e3a02a0965da0c1f901e9d6afcfe4f6f6b608))
|
||||
* **youtube/hide-floating-microphone-button:** reboot when changing settings ([919f285](https://github.com/revanced/revanced-integrations/commit/919f2855edff0acc96c42ea733fff41a55211e48))
|
||||
* **youtube/remember-video-quality:** treat any connection as wifi except mobile and bluetooth ([1f90f7b](https://github.com/revanced/revanced-integrations/commit/1f90f7b9cca2445c776f4f0c8af1ddd0c9bde5f0))
|
||||
* **youtube/return-youtube-dislike:** improve segmented like/dislike layout ([416c695](https://github.com/revanced/revanced-integrations/commit/416c695837debefb4762d381f25157de480614cc))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/general-ads:** do not hide components in library tab ([3c00e58](https://github.com/revanced/revanced-integrations/commit/3c00e58c13fa11da68ff21f4d76e341bc24c5737))
|
||||
* **youtube/general-ads:** hide image shelf from search results ([db6ce55](https://github.com/revanced/revanced-integrations/commit/db6ce554779d58b23685b1794e17f89342abbd87))
|
||||
* **youtube/general-ads:** hide new type of ad ([844bc3b](https://github.com/revanced/revanced-integrations/commit/844bc3b24fe9a2d6b69367d79ad99e452e8a7604))
|
||||
* **youtube/general-ads:** hide new type of ad ([#331](https://github.com/revanced/revanced-integrations/issues/331)) ([7e64e05](https://github.com/revanced/revanced-integrations/commit/7e64e05709c63b4631e845799e756a678138813b))
|
||||
* **youtube/hide-autoplay-button:** do not disable autoplay button when hidden ([519c2bd](https://github.com/revanced/revanced-integrations/commit/519c2bd5118db41fc512a665d9454b902134ba2c))
|
||||
* **youtube:** `hide-floating-microphone-button` patch ([cb77e96](https://github.com/revanced/revanced-integrations/commit/cb77e96da91bb4707d8559757cd86a7583f8048b))
|
||||
* **youtube:** remove `custom-video-buffer` patch ([#1718](https://github.com/revanced/revanced-integrations/issues/1718)) ([d5919a8](https://github.com/revanced/revanced-integrations/commit/d5919a8a2cff09bb884ea01ca6b01d8d2d0b8980))
|
||||
|
||||
# [0.100.0-dev.6](https://github.com/revanced/revanced-integrations/compare/v0.100.0-dev.5...v0.100.0-dev.6) (2023-03-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/hide-floating-microphone-button:** reboot when changing settings ([919f285](https://github.com/revanced/revanced-integrations/commit/919f2855edff0acc96c42ea733fff41a55211e48))
|
||||
* **youtube/remember-video-quality:** treat any connection as wifi except mobile and bluetooth ([1f90f7b](https://github.com/revanced/revanced-integrations/commit/1f90f7b9cca2445c776f4f0c8af1ddd0c9bde5f0))
|
||||
* **youtube/return-youtube-dislike:** improve segmented like/dislike layout ([416c695](https://github.com/revanced/revanced-integrations/commit/416c695837debefb4762d381f25157de480614cc))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/general-ads:** hide new type of ad ([844bc3b](https://github.com/revanced/revanced-integrations/commit/844bc3b24fe9a2d6b69367d79ad99e452e8a7604))
|
||||
* **youtube/general-ads:** hide new type of ad ([#331](https://github.com/revanced/revanced-integrations/issues/331)) ([7e64e05](https://github.com/revanced/revanced-integrations/commit/7e64e05709c63b4631e845799e756a678138813b))
|
||||
* **youtube:** remove `custom-video-buffer` patch ([#1718](https://github.com/revanced/revanced-integrations/issues/1718)) ([d5919a8](https://github.com/revanced/revanced-integrations/commit/d5919a8a2cff09bb884ea01ca6b01d8d2d0b8980))
|
||||
|
||||
# [0.100.0-dev.6](https://github.com/revanced/revanced-integrations/compare/v0.100.0-dev.5...v0.100.0-dev.6) (2023-02-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/hide-floating-microphone-button:** reboot when changing settings ([919f285](https://github.com/revanced/revanced-integrations/commit/919f2855edff0acc96c42ea733fff41a55211e48))
|
||||
|
||||
# [0.100.0-dev.5](https://github.com/revanced/revanced-integrations/compare/v0.100.0-dev.4...v0.100.0-dev.5) (2023-02-26)
|
||||
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ android {
|
||||
|
||||
dependencies {
|
||||
compileOnly(project(mapOf("path" to ":dummy")))
|
||||
compileOnly("androidx.annotation:annotation:1.5.0")
|
||||
compileOnly("androidx.annotation:annotation:1.6.0")
|
||||
compileOnly("androidx.appcompat:appcompat:1.6.1")
|
||||
compileOnly("com.squareup.okhttp3:okhttp:5.0.0-alpha.11")
|
||||
compileOnly("com.squareup.retrofit2:retrofit:2.9.0")
|
||||
|
||||
2
app/proguard-rules.pro
vendored
2
app/proguard-rules.pro
vendored
@@ -20,6 +20,8 @@
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
-dontobfuscate
|
||||
-dontoptimize
|
||||
-keepattributes * # https://www.guardsquare.com/manual/configuration/attributes
|
||||
-keep class app.revanced.** {
|
||||
*;
|
||||
}
|
||||
|
||||
@@ -1,60 +1,31 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
final class ButtonsPatch extends Filter {
|
||||
private final BlockRule actionButtonsRule;
|
||||
private final BlockRule dislikeRule;
|
||||
private final BlockRule actionBarRule;
|
||||
|
||||
private final BlockRule[] rules;
|
||||
|
||||
public ButtonsPatch() {
|
||||
BlockRule like = new BlockRule(SettingsEnum.HIDE_LIKE_BUTTON, "|like_button");
|
||||
dislikeRule = new BlockRule(SettingsEnum.HIDE_DISLIKE_BUTTON, "dislike_button");
|
||||
BlockRule download = new BlockRule(SettingsEnum.HIDE_DOWNLOAD_BUTTON, "download_button");
|
||||
actionButtonsRule = new BlockRule(SettingsEnum.HIDE_ACTION_BUTTON, "ContainerType|video_action_button");
|
||||
BlockRule playlist = new BlockRule(SettingsEnum.HIDE_PLAYLIST_BUTTON, "save_to_playlist_button");
|
||||
rules = new BlockRule[]{like, dislikeRule, download, actionButtonsRule, playlist};
|
||||
|
||||
actionBarRule = new BlockRule(null, "video_action_bar");
|
||||
|
||||
this.pathRegister.registerAll(
|
||||
like,
|
||||
dislikeRule,
|
||||
download,
|
||||
playlist
|
||||
pathRegister.registerAll(
|
||||
new BlockRule(SettingsEnum.HIDE_LIKE_DISLIKE_BUTTON, "|like_button", "dislike_button"),
|
||||
new BlockRule(SettingsEnum.HIDE_DOWNLOAD_BUTTON, "download_button"),
|
||||
new BlockRule(SettingsEnum.HIDE_PLAYLIST_BUTTON, "save_to_playlist_button"),
|
||||
new BlockRule(SettingsEnum.HIDE_CLIP_BUTTON, "|clip_button.eml|"),
|
||||
new BlockRule(SettingsEnum.HIDE_ACTION_BUTTONS, "ContainerType|video_action_button", "|CellType|CollectionType|CellType|ContainerType|button.eml|")
|
||||
);
|
||||
}
|
||||
|
||||
private boolean hideActionBar() {
|
||||
for (BlockRule rule : rules) if (!rule.isEnabled()) return false;
|
||||
private boolean canHideActionBar() {
|
||||
for (BlockRule rule : pathRegister) if (!rule.isEnabled()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(final String path, final String identifier) {
|
||||
if (hideActionBar() && actionBarRule.check(identifier).isBlocked()) return true;
|
||||
// If everything is hidden, then also hide the video bar itself.
|
||||
if (canHideActionBar() && actionBarRule.check(identifier).isBlocked()) return true;
|
||||
|
||||
var currentIsActionButton = actionButtonsRule.check(path).isBlocked();
|
||||
|
||||
if (dislikeRule.check(path).isBlocked()) ActionButton.doNotBlockCounter = 4;
|
||||
|
||||
if (currentIsActionButton && ActionButton.doNotBlockCounter-- > 0) {
|
||||
if (SettingsEnum.HIDE_SHARE_BUTTON.getBoolean()) {
|
||||
LogHelper.printDebug(() -> "Hiding share button");
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
if ((currentIsActionButton && ActionButton.doNotBlockCounter <= 0 && actionButtonsRule.isEnabled()) || pathRegister.contains(path)) {
|
||||
LogHelper.printDebug(() -> "Blocked: " + path);
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
static class ActionButton {
|
||||
public static int doNotBlockCounter = 4;
|
||||
return pathRegister.contains(path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.Toast;
|
||||
import static app.revanced.integrations.utils.StringRef.str;
|
||||
|
||||
import app.revanced.integrations.sponsorblock.StringRef;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
@@ -16,10 +14,8 @@ public class CopyVideoUrlPatch {
|
||||
url += String.format("?t=%s", seconds);
|
||||
}
|
||||
|
||||
Context context = ReVancedUtils.getContext();
|
||||
|
||||
ReVancedUtils.setClipboard(url);
|
||||
if (context != null) Toast.makeText(context, StringRef.str("share_copy_url_success"), Toast.LENGTH_SHORT).show();
|
||||
ReVancedUtils.showToastShort(str("share_copy_url_success"));
|
||||
} catch (Exception e) {
|
||||
LogHelper.printException(() -> "Failed to generate video url", e);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ public final class GeneralAdsPatch extends Filter {
|
||||
"_buttoned_layout",
|
||||
"full_width_square_image_layout",
|
||||
"_ad_with",
|
||||
"video_display_button_group_layout",
|
||||
"landscape_image_wide_button_layout"
|
||||
);
|
||||
var generalAds = new BlockRule(
|
||||
@@ -59,7 +60,13 @@ public final class GeneralAdsPatch extends Filter {
|
||||
"watch_metadata_app_promo",
|
||||
"video_display_full_layout",
|
||||
"hero_promo_image",
|
||||
"statement_banner"
|
||||
"statement_banner",
|
||||
"carousel_footered_layout",
|
||||
"text_image_button_layout",
|
||||
"primetime_promo",
|
||||
"feature_grid_interstitial",
|
||||
"product_details",
|
||||
"brand_video_shelf"
|
||||
);
|
||||
var movieAds = new BlockRule(
|
||||
SettingsEnum.ADREMOVER_MOVIE_REMOVAL,
|
||||
@@ -67,7 +74,8 @@ public final class GeneralAdsPatch extends Filter {
|
||||
"compact_movie",
|
||||
"horizontal_movie_shelf",
|
||||
"movie_and_show_upsell_card",
|
||||
"compact_tvfilm_item"
|
||||
"compact_tvfilm_item",
|
||||
"offer_module_root"
|
||||
);
|
||||
|
||||
this.pathRegister.registerAll(
|
||||
|
||||
@@ -3,7 +3,7 @@ package app.revanced.integrations.patches;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public final class HideFloatingMicrophoneButtonPatch {
|
||||
public static boolean hideFloatingMicrophoneButton(boolean original) {
|
||||
public static boolean hideFloatingMicrophoneButton(final boolean original) {
|
||||
return SettingsEnum.HIDE_FLOATING_MICROPHONE_BUTTON.getBoolean() || original;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import app.revanced.integrations.adremover.AdRemoverAPI;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class HideMixPlaylistsPatch {
|
||||
|
||||
public static void hideMixPlaylists(View view) {
|
||||
if (!SettingsEnum.HIDE_MIX_PLAYLISTS.getBoolean()) return;
|
||||
AdRemoverAPI.HideViewWithLayout1dp(view);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import app.revanced.integrations.adremover.AdRemoverAPI;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class HideReelsPatch {
|
||||
|
||||
/**
|
||||
* Used by app.revanced.patches.youtube.layout.reels.patch.HideReelsPatch
|
||||
*
|
||||
* @param view
|
||||
*/
|
||||
public static void HideReel(View view) {
|
||||
if (SettingsEnum.HIDE_REEL_BUTTON.getBoolean()) {
|
||||
AdRemoverAPI.HideViewWithLayout1dp(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,6 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import static app.revanced.integrations.utils.ReVancedUtils.getContext;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
import app.revanced.integrations.utils.ThemeHelper;
|
||||
|
||||
public class LithoThemePatch {
|
||||
@@ -44,29 +41,15 @@ public class LithoThemePatch {
|
||||
}
|
||||
|
||||
private static int getBlackColor() {
|
||||
if (blackColor == 0) blackColor = getColor("yt_black1");
|
||||
if (blackColor == 0) blackColor = ReVancedUtils.getResourceColor("yt_black1");
|
||||
return blackColor;
|
||||
}
|
||||
|
||||
private static int getWhiteColor() {
|
||||
if (whiteColor == 0) whiteColor = getColor("yt_white1");
|
||||
if (whiteColor == 0) whiteColor = ReVancedUtils.getResourceColor("yt_white1");
|
||||
return whiteColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the color for a color resource.
|
||||
*
|
||||
* @param name The color resource name.
|
||||
* @return The value of the color.
|
||||
*/
|
||||
private static int getColor(String name) {
|
||||
Context context = getContext();
|
||||
|
||||
return context != null ? context.getColor(context.getResources()
|
||||
.getIdentifier(name, "color", context.getPackageName())
|
||||
) : 0;
|
||||
}
|
||||
|
||||
private static boolean anyEquals(int value, int... of) {
|
||||
for (int v : of) if (value == v) return true;
|
||||
return false;
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import static app.revanced.integrations.utils.StringRef.str;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.widget.Toast;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static app.revanced.integrations.sponsorblock.StringRef.str;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
public class MicroGSupport {
|
||||
private static final String MICROG_VENDOR = "com.mgoogle";
|
||||
@@ -20,7 +20,7 @@ public class MicroGSupport {
|
||||
private static final Uri VANCED_MICROG_PROVIDER = Uri.parse("content://" + MICROG_VENDOR + ".android.gsf.gservices/prefix");
|
||||
|
||||
private static void startIntent(Context context, String uriString, String message) {
|
||||
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
|
||||
ReVancedUtils.showToastLong(message);
|
||||
|
||||
var intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class NewActionbarPatch {
|
||||
|
||||
//Used by app.revanced.patches.youtube.layout.widesearchbar.patch.WideSearchbarPatch
|
||||
public static boolean getNewActionBar() {
|
||||
return SettingsEnum.WIDE_SEARCHBAR.getBoolean(); // TODO: maybe this has to be inverted
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,7 +28,7 @@ public class PlayerTypeHookPatch {
|
||||
LogHelper.printException(() -> "Unknown PlayerType encountered: " + type);
|
||||
} else {
|
||||
PlayerType.setCurrent(newType);
|
||||
LogHelper.printDebug(() -> "YouTubePlayerOverlaysLayout player type was updated to " + newType);
|
||||
LogHelper.printDebug(() -> "PlayerType was updated to: " + newType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +1,108 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import static app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike.Vote;
|
||||
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* Used by app.revanced.patches.youtube.layout.returnyoutubedislike.patch.ReturnYouTubeDislikePatch
|
||||
*/
|
||||
import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
public class ReturnYouTubeDislikePatch {
|
||||
|
||||
/**
|
||||
* Injection point
|
||||
* Injection point.
|
||||
*/
|
||||
public static void newVideoLoaded(String videoId) {
|
||||
ReturnYouTubeDislike.newVideoLoaded(videoId);
|
||||
try {
|
||||
if (!SettingsEnum.RYD_ENABLED.getBoolean()) return;
|
||||
ReturnYouTubeDislike.newVideoLoaded(videoId);
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "newVideoLoaded failure", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point
|
||||
* Injection point.
|
||||
*
|
||||
* Called when a litho text component is created
|
||||
* Called when a litho text component is initially created,
|
||||
* and also when a Span is later reused again (such as scrolling off/on screen).
|
||||
*
|
||||
* This method is sometimes called on the main thread, but it usually is called _off_ the main thread.
|
||||
* This method can be called multiple times for the same UI element (including after dislikes was added).
|
||||
*
|
||||
* @param textRef Cache reference to the like/dislike char sequence,
|
||||
* which may or may not be the same as the original span parameter.
|
||||
* If dislikes are added, the atomic reference must be set to the replacement span.
|
||||
* @param original Original span that was created or reused by Litho.
|
||||
* @return The original span (if nothing should change), or a replacement span that contains dislikes.
|
||||
*/
|
||||
public static void onComponentCreated(Object conversionContext, AtomicReference<Object> textRef) {
|
||||
ReturnYouTubeDislike.onComponentCreated(conversionContext, textRef);
|
||||
@NonNull
|
||||
public static CharSequence onLithoTextLoaded(@NonNull Object conversionContext,
|
||||
@NonNull AtomicReference<CharSequence> textRef,
|
||||
@NonNull CharSequence original) {
|
||||
try {
|
||||
if (!SettingsEnum.RYD_ENABLED.getBoolean()) {
|
||||
return original;
|
||||
}
|
||||
SpannableString replacement = ReturnYouTubeDislike.getDislikeSpanForContext(conversionContext, original);
|
||||
if (replacement != null) {
|
||||
textRef.set(replacement);
|
||||
return replacement;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "onComponentCreated AtomicReference failure", ex);
|
||||
}
|
||||
return original;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point
|
||||
* Injection point.
|
||||
*
|
||||
* Called when a Shorts dislike Spannable is created
|
||||
* Called when a Shorts dislike Spanned is created.
|
||||
*/
|
||||
public static Spanned onShortsComponentCreated(Spanned dislike) {
|
||||
return ReturnYouTubeDislike.onShortsComponentCreated(dislike);
|
||||
public static Spanned onShortsComponentCreated(Spanned original) {
|
||||
try {
|
||||
if (!SettingsEnum.RYD_ENABLED.getBoolean()) {
|
||||
return original;
|
||||
}
|
||||
SpannableString replacement = ReturnYouTubeDislike.getDislikeSpanForShort(original);
|
||||
if (replacement != null) {
|
||||
return replacement;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "onShortsComponentCreated failure", ex);
|
||||
}
|
||||
return original;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point
|
||||
* Injection point.
|
||||
*
|
||||
* Called when the like/dislike button is clicked
|
||||
* Called when the user likes or dislikes.
|
||||
*
|
||||
* @param vote -1 (dislike), 0 (none) or 1 (like)
|
||||
* @param vote int that matches {@link ReturnYouTubeDislike.Vote#value}
|
||||
*/
|
||||
public static void sendVote(int vote) {
|
||||
ReturnYouTubeDislike.sendVote(vote);
|
||||
try {
|
||||
if (!SettingsEnum.RYD_ENABLED.getBoolean()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Vote v : Vote.values()) {
|
||||
if (v.value == vote) {
|
||||
ReturnYouTubeDislike.sendVote(v);
|
||||
return;
|
||||
}
|
||||
}
|
||||
LogHelper.printException(() -> "Unknown vote type: " + vote);
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "sendVote failure", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.shared.PlayerType;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
import static app.revanced.integrations.utils.ReVancedUtils.containsAny;
|
||||
|
||||
public class SpoofSignatureVerificationPatch {
|
||||
/**
|
||||
* Protobuf parameters used for autoplay in scrim.
|
||||
* Prepend this parameter to mute video playback (for autoplay in feed)
|
||||
*/
|
||||
private static final String PROTOBUF_PARAMETER_SCRIM = "SAFgAXgB";
|
||||
|
||||
/**
|
||||
* Protobuf parameter of shorts and YouTube stories.
|
||||
* Known issue: captions are positioned on upper area in the player.
|
||||
*/
|
||||
private static final String PROTOBUF_PARAMETER_SHORTS = "8AEB"; // "8AEByAMTuAQP"
|
||||
|
||||
/**
|
||||
* Target Protobuf parameters.
|
||||
*/
|
||||
private static final String[] PROTOBUF_PARAMETER_TARGETS = {
|
||||
"YAHI", // Autoplay in feed
|
||||
"SAFg" // Autoplay in scrim
|
||||
};
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*
|
||||
* @param originalValue originalValue protobuf parameter
|
||||
*/
|
||||
public static String overrideProtobufParameter(String originalValue) {
|
||||
try {
|
||||
if (!SettingsEnum.SIGNATURE_SPOOFING.getBoolean()) {
|
||||
return originalValue;
|
||||
}
|
||||
|
||||
LogHelper.printDebug(() -> "Original protobuf parameter value: " + originalValue);
|
||||
|
||||
// Video is Short or Story.
|
||||
var isPlayingShorts = originalValue.contains(PROTOBUF_PARAMETER_SHORTS);
|
||||
if (isPlayingShorts) return originalValue;
|
||||
|
||||
boolean isPlayingFeed = containsAny(originalValue, PROTOBUF_PARAMETER_TARGETS) && PlayerType.getCurrent() == PlayerType.INLINE_MINIMAL;
|
||||
if (isPlayingFeed) {
|
||||
// Videos in feed won't autoplay with sound.
|
||||
return PROTOBUF_PARAMETER_SCRIM + PROTOBUF_PARAMETER_SHORTS;
|
||||
} else{
|
||||
// Spoof the parameter to prevent playback issues.
|
||||
return PROTOBUF_PARAMETER_SHORTS;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "overrideProtobufParameter failure", ex);
|
||||
}
|
||||
|
||||
return originalValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Injection point. Runs off the main thread.
|
||||
* <p>
|
||||
* Used to check the response code of video playback requests made by YouTube.
|
||||
* Response code of interest is 403 that indicate a signature verification failure for the current request
|
||||
*
|
||||
* @param responseCode HTTP status code of the completed YouTube connection
|
||||
*/
|
||||
public static void onResponse(int responseCode) {
|
||||
try {
|
||||
if (responseCode < 400 || responseCode >= 500) {
|
||||
return; // everything normal
|
||||
}
|
||||
LogHelper.printDebug(() -> "YouTube HTTP status code: " + responseCode);
|
||||
|
||||
if (SettingsEnum.SIGNATURE_SPOOFING.getBoolean()) {
|
||||
return; // already enabled
|
||||
}
|
||||
|
||||
SettingsEnum.SIGNATURE_SPOOFING.saveValue(true);
|
||||
ReVancedUtils.showToastLong("Spoofing app signature to prevent playback issues");
|
||||
// it would be great if the video could be forcefully reloaded, but currently there is no code to do this
|
||||
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "onResponse failure", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Last WindowsSetting constructor values. Values are checked for changes to reduce log spam.
|
||||
*/
|
||||
private static int lastAp, lastAh, lastAv;
|
||||
private static boolean lastVs, lastSd;
|
||||
|
||||
/**
|
||||
* Injection point. Overrides values passed into SubtitleWindowSettings constructor.
|
||||
*
|
||||
* @param ap anchor position. A bitmask with 6 bit fields, that appears to indicate the layout position on screen
|
||||
* @param ah anchor horizontal. A percentage [0, 100], that appears to be a horizontal text anchor point
|
||||
* @param av anchor vertical. A percentage [0, 100], that appears to be a vertical text anchor point
|
||||
* @param vs appears to indicate if subtitles exist, and the value is always true.
|
||||
* @param sd function is not entirely clear
|
||||
*/
|
||||
public static int[] getSubtitleWindowSettingsOverride(int ap, int ah, int av, boolean vs, boolean sd) {
|
||||
final boolean signatureSpoofing = SettingsEnum.SIGNATURE_SPOOFING.getBoolean();
|
||||
if (SettingsEnum.DEBUG.getBoolean()) {
|
||||
if (ap != lastAp || ah != lastAh || av != lastAv || vs != lastVs || sd != lastSd) {
|
||||
LogHelper.printDebug(() -> "video: " + VideoInformation.getCurrentVideoId() + " spoof: " + signatureSpoofing
|
||||
+ " ap:" + ap + " ah:" + ah + " av:" + av + " vs:" + vs + " sd:" + sd);
|
||||
lastAp = ap;
|
||||
lastAh = ah;
|
||||
lastAv = av;
|
||||
lastVs = vs;
|
||||
lastSd = sd;
|
||||
}
|
||||
}
|
||||
|
||||
// Videos with custom captions that specify screen positions appear to always have correct screen positions (even with spoofing).
|
||||
// But for auto generated and most other captions, the spoof incorrectly gives various default Shorts caption settings.
|
||||
// Check for these known default shorts captions parameters, and replace with the known correct values.
|
||||
if (signatureSpoofing && !PlayerType.getCurrent().isNoneOrHidden()) { // video is not a Short or Story
|
||||
for (SubtitleWindowReplacementSettings setting : SubtitleWindowReplacementSettings.values()) {
|
||||
if (setting.match(ap, ah, av, vs, sd)) {
|
||||
return setting.replacementSetting();
|
||||
}
|
||||
}
|
||||
// Parameters are either subtitles with custom positions, or a set of unidentified (and incorrect) default parameters.
|
||||
// The subtitles could be forced to the bottom no matter what, but that would override custom screen positions.
|
||||
// For now, just return the original parameters.
|
||||
}
|
||||
|
||||
// No matches, pass back the original values
|
||||
return new int[]{ap, ah, av};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Known incorrect default Shorts subtitle parameters, and the corresponding correct (non-Shorts) values.
|
||||
*/
|
||||
private enum SubtitleWindowReplacementSettings {
|
||||
DEFAULT_SHORTS_PARAMETERS_1(10, 50, 0, true, false,
|
||||
34, 50, 95),
|
||||
DEFAULT_SHORTS_PARAMETERS_2(9, 20, 0, true, false,
|
||||
34, 50, 90),
|
||||
DEFAULT_SHORTS_PARAMETERS_3(9, 20, 0, true, true,
|
||||
33, 20, 100);
|
||||
|
||||
// original values
|
||||
final int ap, ah, av;
|
||||
final boolean vs, sd;
|
||||
|
||||
// replacement values
|
||||
final int replacementAp, replacementAh, replacementAv;
|
||||
|
||||
SubtitleWindowReplacementSettings(int ap, int ah, int av, boolean vs, boolean sd,
|
||||
int replacementAp, int replacementAh, int replacementAv) {
|
||||
this.ap = ap;
|
||||
this.ah = ah;
|
||||
this.av = av;
|
||||
this.vs = vs;
|
||||
this.sd = sd;
|
||||
this.replacementAp = replacementAp;
|
||||
this.replacementAh = replacementAh;
|
||||
this.replacementAv = replacementAv;
|
||||
}
|
||||
|
||||
boolean match(int ap, int ah, int av, boolean vs, boolean sd) {
|
||||
return this.ap == ap && this.ah == ah && this.av == av && this.vs == vs && this.sd == sd;
|
||||
}
|
||||
|
||||
int[] replacementSetting() {
|
||||
return new int[]{replacementAp, replacementAh, replacementAv};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class VideoBufferPatch {
|
||||
|
||||
public static int getMaxBuffer() {
|
||||
int confVal = SettingsEnum.MAX_BUFFER.getInt();
|
||||
if (confVal < 1) confVal = 1;
|
||||
return confVal;
|
||||
}
|
||||
|
||||
public static int getPlaybackBuffer() {
|
||||
int confVal = SettingsEnum.PLAYBACK_MAX_BUFFER.getInt();
|
||||
if (confVal < 1) confVal = 1;
|
||||
return confVal;
|
||||
}
|
||||
|
||||
public static int getReBuffer() {
|
||||
int confVal = SettingsEnum.MAX_PLAYBACK_BUFFER_AFTER_REBUFFER.getInt();
|
||||
if (confVal < 1) confVal = 1;
|
||||
return confVal;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,35 +1,42 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import app.revanced.integrations.patches.playback.speed.RememberPlaybackSpeedPatch;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
/**
|
||||
* Hooking class for the current playing video.
|
||||
*/
|
||||
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 Method seekMethod;
|
||||
|
||||
@NonNull
|
||||
private static String videoId = "";
|
||||
private static long videoLength = 1;
|
||||
private static long videoTime = -1;
|
||||
|
||||
private static long videoLength = 0;
|
||||
private static volatile long videoTime = -1; // must be volatile. Value is set off main thread from high precision patch hook
|
||||
/**
|
||||
* The current playback speed
|
||||
*/
|
||||
private static float playbackSpeed = DEFAULT_YOUTUBE_PLAYBACK_SPEED;
|
||||
|
||||
/**
|
||||
* Hook into PlayerController.onCreate() method.
|
||||
* Injection point.
|
||||
* Sets a reference to the YouTube playback controller.
|
||||
*
|
||||
* @param thisRef Reference to the player controller object.
|
||||
*/
|
||||
public static void playerController_onCreateHook(final Object thisRef) {
|
||||
playerController = new WeakReference<>(thisRef);
|
||||
videoLength = 1;
|
||||
videoLength = 0;
|
||||
videoTime = -1;
|
||||
|
||||
try {
|
||||
@@ -41,81 +48,146 @@ public final class VideoInformation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the video id.
|
||||
* Injection point.
|
||||
*
|
||||
* @param videoId The id of the video.
|
||||
* @param newlyLoadedVideoId id of the current video
|
||||
*/
|
||||
public static void setVideoId(String videoId) {
|
||||
LogHelper.printDebug(() -> "Setting current video id to: " + videoId);
|
||||
|
||||
VideoInformation.videoId = videoId;
|
||||
public static void setVideoId(@NonNull String newlyLoadedVideoId) {
|
||||
if (!videoId.equals(newlyLoadedVideoId)) {
|
||||
LogHelper.printDebug(() -> "New video id: " + newlyLoadedVideoId);
|
||||
videoId = newlyLoadedVideoId;
|
||||
playbackSpeed = DEFAULT_YOUTUBE_PLAYBACK_SPEED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the video length.
|
||||
* Injection point.
|
||||
* Called when user selects a playback speed.
|
||||
*
|
||||
* @param userSelectedPlaybackSpeed The playback speed the user selected
|
||||
*/
|
||||
public static void userSelectedPlaybackSpeed(float userSelectedPlaybackSpeed) {
|
||||
LogHelper.printDebug(() -> "User selected playback speed: " + userSelectedPlaybackSpeed);
|
||||
playbackSpeed = userSelectedPlaybackSpeed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the current playback speed.
|
||||
*
|
||||
* <b> Used exclusively by {@link RememberPlaybackSpeedPatch} </b>
|
||||
*/
|
||||
public static void overridePlaybackSpeed(float speedOverride) {
|
||||
if (playbackSpeed != speedOverride) {
|
||||
LogHelper.printDebug(() -> "Overriding playback speed to: " + speedOverride);
|
||||
playbackSpeed = speedOverride;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*
|
||||
* @param length The length of the video in milliseconds.
|
||||
*/
|
||||
public static void setVideoLength(final long length) {
|
||||
LogHelper.printDebug(() -> "Setting current video length to " + length);
|
||||
videoLength = length;
|
||||
if (videoLength != length) {
|
||||
LogHelper.printDebug(() -> "Current video length: " + length);
|
||||
videoLength = length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the video time.
|
||||
* Injection point.
|
||||
* Called off the main thread approximately every 50ms to 100ms
|
||||
*
|
||||
* @param time The time of the video in milliseconds.
|
||||
* @param currentPlaybackTime The current playback time of the video in milliseconds.
|
||||
*/
|
||||
public static void setVideoTime(final long time) {
|
||||
LogHelper.printDebug(() -> "Current video time " + time);
|
||||
videoTime = time;
|
||||
public static void setVideoTimeHighPrecision(final long currentPlaybackTime) {
|
||||
videoTime = currentPlaybackTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek on the current video.
|
||||
* Does not function for playback of Shorts or Stories.
|
||||
*
|
||||
* Caution: If called from a videoTimeHook() callback,
|
||||
* this will cause a recursive call into the same videoTimeHook() callback.
|
||||
*
|
||||
* @param millisecond The millisecond to seek the video to.
|
||||
* @return if the seek was successful
|
||||
*/
|
||||
public static void seekTo(final long millisecond) {
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (seekMethod == null) {
|
||||
LogHelper.printDebug(() -> "seekMethod was null");
|
||||
return;
|
||||
}
|
||||
public static boolean seekTo(final long millisecond) {
|
||||
ReVancedUtils.verifyOnMainThread();
|
||||
if (seekMethod == null) {
|
||||
LogHelper.printException(() -> "seekMethod was null");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
LogHelper.printDebug(() -> "Seeking to " + millisecond);
|
||||
seekMethod.invoke(playerController.get(), millisecond);
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "Failed to seek", ex);
|
||||
}
|
||||
});
|
||||
try {
|
||||
LogHelper.printDebug(() -> "Seeking to " + millisecond);
|
||||
return (Boolean) seekMethod.invoke(playerController.get(), millisecond);
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "Failed to seek", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean seekToRelative(long millisecondsRelative) {
|
||||
return seekTo(videoTime + millisecondsRelative);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of the current video playing.
|
||||
* Id of the current video playing. Includes Shorts and YouTube Stories.
|
||||
*
|
||||
* @return The id of the video. Empty string if not set yet.
|
||||
*/
|
||||
@NonNull
|
||||
public static String getCurrentVideoId() {
|
||||
return videoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of the current video playing.
|
||||
* @return The current playback speed.
|
||||
*/
|
||||
public static float getCurrentPlaybackSpeed() {
|
||||
return playbackSpeed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Length of the current video playing.
|
||||
* Includes Shorts playback.
|
||||
*
|
||||
* @return The length of the video in milliseconds. 1 if not set yet.
|
||||
* @return The length of the video in milliseconds.
|
||||
* If the video is not yet loaded, or if the video is playing in the background with no video visible,
|
||||
* then this returns zero.
|
||||
*/
|
||||
public static long getCurrentVideoLength() {
|
||||
return videoLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time of the current video playing.
|
||||
* Playback time of the current video playing.
|
||||
* Value can lag up to approximately 100ms behind the actual current video playback time.
|
||||
*
|
||||
* Note: Code inside a videoTimeHook patch callback
|
||||
* should use the callback video time and avoid using this method
|
||||
* (in situations of recursive hook callbacks, the value returned here may be outdated).
|
||||
*
|
||||
* Includes Shorts playback.
|
||||
*
|
||||
* @return The time of the video in milliseconds. -1 if not set yet.
|
||||
*/
|
||||
public static long getVideoTime() {
|
||||
return videoTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If the playback is at the end of the video.
|
||||
*
|
||||
* If video is playing in the background with no video visible,
|
||||
* this always returns false (even if the video is actually at the end)
|
||||
*/
|
||||
public static boolean isAtEndOfVideo() {
|
||||
return videoTime > 0 && videoLength > 0 && videoTime >= videoLength;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public final class WideSearchbarPatch {
|
||||
public static boolean enableWideSearchbar() {
|
||||
return SettingsEnum.WIDE_SEARCHBAR.getBoolean();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package app.revanced.integrations.patches.downloads.views
|
||||
|
||||
class DownloadOptions {
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,12 @@
|
||||
package app.revanced.integrations.patches.playback.speed;
|
||||
|
||||
public class CustomVideoSpeedPatch {
|
||||
// Values are useless as they are being overridden by the respective patch.
|
||||
// This generates a .array segment in Dalvik bytecode
|
||||
// which the patch utilizes to store the video speeds in, only
|
||||
// if it has two or more default values.
|
||||
public static final float[] videoSpeeds = { 0, 0 };
|
||||
/**
|
||||
* Default playback speeds offered by YouTube.
|
||||
* Values are also used by {@link RememberPlaybackSpeedPatch}.
|
||||
*
|
||||
* If custom video speed is applied,
|
||||
* then this array is overwritten by the patch with custom speeds
|
||||
*/
|
||||
public static final float[] videoSpeeds = {0.25f, 0.75f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f};
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package app.revanced.integrations.patches.playback.speed;
|
||||
|
||||
import static app.revanced.integrations.utils.SharedPrefHelper.SharedPrefNames.REVANCED_PREFS;
|
||||
import static app.revanced.integrations.utils.SharedPrefHelper.getFloat;
|
||||
import static app.revanced.integrations.utils.SharedPrefHelper.saveFloat;
|
||||
|
||||
import android.widget.Toast;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
|
||||
public final class RememberPlaybackRatePatch {
|
||||
private static final String REMEMBERED_PLAYBACK_RATE_PREFERENCE_KEY = "revanced_remember_playback_rate_last_value";
|
||||
|
||||
public static void rememberPlaybackRate(final float selectedPlaybackRate) {
|
||||
if (!SettingsEnum.REMEMBER_PLAYBACK_RATE_SELECTED.getBoolean()) return;
|
||||
|
||||
Toast.makeText(ReVancedUtils.getContext(), "Playback rate will be remembered", Toast.LENGTH_SHORT).show();
|
||||
|
||||
LogHelper.printDebug(() -> "Remembering playback rate: " + selectedPlaybackRate);
|
||||
saveFloat(REVANCED_PREFS, REMEMBERED_PLAYBACK_RATE_PREFERENCE_KEY, selectedPlaybackRate);
|
||||
}
|
||||
|
||||
public static float getRememberedPlaybackRate() {
|
||||
final var playbackRateOverride = getFloat(REVANCED_PREFS, REMEMBERED_PLAYBACK_RATE_PREFERENCE_KEY, -2f);
|
||||
|
||||
LogHelper.printDebug(() -> "Overriding playback rate: " + playbackRateOverride);
|
||||
return playbackRateOverride;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
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.ReVancedUtils;
|
||||
|
||||
public final class RememberPlaybackSpeedPatch {
|
||||
|
||||
/**
|
||||
* PreferenceList entries and values, of all available playback speeds.
|
||||
*/
|
||||
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;
|
||||
VideoInformation.overridePlaybackSpeed(SettingsEnum.PLAYBACK_SPEED_DEFAULT.getFloat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
* Called when user selects a playback speed.
|
||||
*
|
||||
* @param playbackSpeed The playback speed the user selected
|
||||
*/
|
||||
public static void userSelectedPlaybackSpeed(float playbackSpeed) {
|
||||
if (SettingsEnum.PLAYBACK_SPEED_REMEMBER_LAST_SELECTED.getBoolean()) {
|
||||
SettingsEnum.PLAYBACK_SPEED_DEFAULT.saveValue(playbackSpeed);
|
||||
ReVancedUtils.showToastLong("Changed default speed to: " + playbackSpeed + "x");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
* Overrides the video speed. Called after video loads, and immediately after user selects a different playback speed
|
||||
*/
|
||||
public static float getPlaybackSpeedOverride() {
|
||||
return VideoInformation.getCurrentPlaybackSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a settings preference list.
|
||||
*
|
||||
* Normally this is done during patching by creating a static xml preference list,
|
||||
* but the available playback speeds differ depending if {@link CustomVideoSpeedPatch} is applied or not.
|
||||
*/
|
||||
public static void initializeListPreference(ListPreference preference) {
|
||||
if (preferenceListEntries == null) {
|
||||
float[] videoSpeeds = CustomVideoSpeedPatch.videoSpeeds;
|
||||
preferenceListEntries = new String[videoSpeeds.length];
|
||||
preferenceListEntryValues = new String[videoSpeeds.length];
|
||||
int i = 0;
|
||||
for (float speed : videoSpeeds) {
|
||||
String speedString = String.valueOf(speed);
|
||||
preferenceListEntries[i] = speedString + "x";
|
||||
preferenceListEntryValues[i] = speedString;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
preference.setEntries(preferenceListEntries);
|
||||
preference.setEntryValues(preferenceListEntryValues);
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,7 @@ public class Requester {
|
||||
String url = apiUrl + route.compile(params).getCompiledRoute();
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
||||
connection.setRequestMethod(route.getMethod().name());
|
||||
// TODO: change the user agent string
|
||||
connection.setRequestProperty("User-agent", System.getProperty("http.agent") + ";vanced");
|
||||
connection.setRequestProperty("User-agent", System.getProperty("http.agent") + ";revanced");
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,12 @@
|
||||
package app.revanced.integrations.returnyoutubedislike.requests;
|
||||
|
||||
import static app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeRoutes.getRYDConnectionFromRoute;
|
||||
import static app.revanced.integrations.utils.StringRef.str;
|
||||
|
||||
import android.util.Base64;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import app.revanced.integrations.requests.Requester;
|
||||
import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@@ -20,8 +20,10 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Objects;
|
||||
|
||||
import static app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeRoutes.getRYDConnectionFromRoute;
|
||||
import static app.revanced.integrations.sponsorblock.StringRef.str;
|
||||
import app.revanced.integrations.requests.Requester;
|
||||
import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
public class ReturnYouTubeDislikeApi {
|
||||
/**
|
||||
@@ -192,9 +194,7 @@ public class ReturnYouTubeDislikeApi {
|
||||
numberOfRateLimitRequestsEncountered++;
|
||||
LogHelper.printDebug(() -> "API rate limit was hit. Stopping API calls for the next "
|
||||
+ RATE_LIMIT_BACKOFF_SECONDS + " seconds");
|
||||
ReVancedUtils.runOnMainThread(() -> { // must show toasts on main thread
|
||||
Toast.makeText(ReVancedUtils.getContext(), str("revanced_ryd_failure_client_rate_limit_requested"), Toast.LENGTH_LONG).show();
|
||||
});
|
||||
ReVancedUtils.showToastLong(str("revanced_ryd_failure_client_rate_limit_requested"));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -203,7 +203,7 @@ public class ReturnYouTubeDislikeApi {
|
||||
@SuppressWarnings("NonAtomicOperationOnVolatileField") // do not want to pay performance cost of full synchronization for debug fields that are only estimates anyways
|
||||
private static void updateStatistics(long timeNetworkCallStarted, long timeNetworkCallEnded, boolean connectionError, boolean rateLimitHit) {
|
||||
if (connectionError && rateLimitHit) {
|
||||
throw new IllegalArgumentException("both connection error and rate limit parameter were true");
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
final long responseTimeOfFetchCall = timeNetworkCallEnded - timeNetworkCallStarted;
|
||||
fetchCallResponseTimeTotal += responseTimeOfFetchCall;
|
||||
@@ -320,7 +320,7 @@ public class ReturnYouTubeDislikeApi {
|
||||
return confirmRegistration(userId, solution);
|
||||
}
|
||||
LogHelper.printException(() -> "Failed to register new user: " + userId
|
||||
+ " response code was: " + responseCode);
|
||||
+ " response code was: " + responseCode); // failed attempt, and ok to log userId
|
||||
connection.disconnect();
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "Failed to register user", ex);
|
||||
@@ -337,7 +337,7 @@ public class ReturnYouTubeDislikeApi {
|
||||
if (checkIfRateLimitInEffect("confirmRegistration")) {
|
||||
return null;
|
||||
}
|
||||
LogHelper.printDebug(() -> "Trying to confirm registration for user: " + userId + " with solution: " + solution);
|
||||
LogHelper.printDebug(() -> "Trying to confirm registration with solution: " + solution);
|
||||
|
||||
HttpURLConnection connection = getRYDConnectionFromRoute(ReturnYouTubeDislikeRoutes.CONFIRM_REGISTRATION, userId);
|
||||
applyCommonPostRequestSettings(connection);
|
||||
@@ -355,7 +355,7 @@ public class ReturnYouTubeDislikeApi {
|
||||
if (responseCode == HTTP_STATUS_CODE_SUCCESS) {
|
||||
String result = Requester.parseJson(connection);
|
||||
if (result.equalsIgnoreCase("true")) {
|
||||
LogHelper.printDebug(() -> "Registration confirmation successful for user: " + userId);
|
||||
LogHelper.printDebug(() -> "Registration confirmation successful");
|
||||
return userId;
|
||||
}
|
||||
LogHelper.printException(() -> "Failed to confirm registration for user: " + userId
|
||||
@@ -382,8 +382,7 @@ public class ReturnYouTubeDislikeApi {
|
||||
if (checkIfRateLimitInEffect("sendVote")) {
|
||||
return false;
|
||||
}
|
||||
LogHelper.printDebug(() -> "Trying to vote for video: "
|
||||
+ videoId + " with vote: " + vote + " user: " + userId);
|
||||
LogHelper.printDebug(() -> "Trying to vote for video: " + videoId + " with vote: " + vote);
|
||||
|
||||
HttpURLConnection connection = getRYDConnectionFromRoute(ReturnYouTubeDislikeRoutes.SEND_VOTE);
|
||||
applyCommonPostRequestSettings(connection);
|
||||
@@ -408,11 +407,10 @@ public class ReturnYouTubeDislikeApi {
|
||||
return confirmVote(videoId, userId, solution);
|
||||
}
|
||||
LogHelper.printException(() -> "Failed to send vote for video: " + videoId
|
||||
+ " userId: " + userId + " vote: " + vote + " response code was: " + responseCode);
|
||||
+ " vote: " + vote + " response code was: " + responseCode);
|
||||
connection.disconnect(); // something went wrong, might as well disconnect
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "Failed to send vote for video: " + videoId
|
||||
+ " user: " + userId + " vote: " + vote, ex);
|
||||
LogHelper.printException(() -> "Failed to send vote for video: " + videoId + " vote: " + vote, ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -427,8 +425,7 @@ public class ReturnYouTubeDislikeApi {
|
||||
if (checkIfRateLimitInEffect("confirmVote")) {
|
||||
return false;
|
||||
}
|
||||
LogHelper.printDebug(() -> "Trying to confirm vote for video: "
|
||||
+ videoId + " user: " + userId + " solution: " + solution);
|
||||
LogHelper.printDebug(() -> "Trying to confirm vote for video: " + videoId + " solution: " + solution);
|
||||
HttpURLConnection connection = getRYDConnectionFromRoute(ReturnYouTubeDislikeRoutes.CONFIRM_VOTE);
|
||||
applyCommonPostRequestSettings(connection);
|
||||
|
||||
@@ -450,15 +447,15 @@ public class ReturnYouTubeDislikeApi {
|
||||
return true;
|
||||
}
|
||||
LogHelper.printException(() -> "Failed to confirm vote for video: " + videoId
|
||||
+ " user: " + userId + " solution: " + solution + " response string was: " + result);
|
||||
+ " solution: " + solution + " response string was: " + result);
|
||||
} else {
|
||||
LogHelper.printException(() -> "Failed to confirm vote for video: " + videoId
|
||||
+ " user: " + userId + " solution: " + solution + " response code was: " + responseCode);
|
||||
+ " solution: " + solution + " response code was: " + responseCode);
|
||||
}
|
||||
connection.disconnect(); // something went wrong, might as well disconnect
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "Failed to confirm vote for video: " + videoId
|
||||
+ " user: " + userId + " solution: " + solution, ex);
|
||||
+ " solution: " + solution, ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
package app.revanced.integrations.settings;
|
||||
|
||||
public enum ReturnType {
|
||||
|
||||
BOOLEAN,
|
||||
INTEGER,
|
||||
STRING,
|
||||
LONG,
|
||||
FLOAT;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,129 @@
|
||||
package app.revanced.integrations.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
/**
|
||||
* Shared categories, and helper methods.
|
||||
*
|
||||
* The various save methods store numbers as Strings,
|
||||
* which is required if using {@link android.preference.PreferenceFragment}.
|
||||
*
|
||||
* If saved numbers will not be used with a preference fragment,
|
||||
* then store the primitive numbers using {@link #preferences}.
|
||||
*/
|
||||
public enum SharedPrefCategory {
|
||||
YOUTUBE("youtube"),
|
||||
RETURN_YOUTUBE_DISLIKE("ryd"),
|
||||
SPONSOR_BLOCK("sponsor-block"),
|
||||
REVANCED_PREFS("revanced_prefs");
|
||||
|
||||
@NonNull
|
||||
public final String prefName;
|
||||
@NonNull
|
||||
public final SharedPreferences preferences;
|
||||
|
||||
SharedPrefCategory(@NonNull String prefName) {
|
||||
this.prefName = Objects.requireNonNull(prefName);
|
||||
preferences = Objects.requireNonNull(ReVancedUtils.getContext()).getSharedPreferences(prefName, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
private void saveObjectAsString(@NonNull String key, @Nullable Object value) {
|
||||
preferences.edit().putString(key, (value == null ? null : value.toString())).apply();
|
||||
}
|
||||
|
||||
public void saveBoolean(@NonNull String key, boolean value) {
|
||||
preferences.edit().putBoolean(key, value).apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value a NULL parameter removes the value from the preferences
|
||||
*/
|
||||
public void saveIntegerString(@NonNull String key, @Nullable Integer value) {
|
||||
saveObjectAsString(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value a NULL parameter removes the value from the preferences
|
||||
*/
|
||||
public void saveLongString(@NonNull String key, @Nullable Long value) {
|
||||
saveObjectAsString(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value a NULL parameter removes the value from the preferences
|
||||
*/
|
||||
public void saveFloatString(@NonNull String key, @Nullable Float value) {
|
||||
saveObjectAsString(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value a NULL parameter removes the value from the preferences
|
||||
*/
|
||||
public void saveString(@NonNull String key, @Nullable String value) {
|
||||
saveObjectAsString(key, value);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getString(@NonNull String key, @NonNull String _default) {
|
||||
Objects.requireNonNull(_default);
|
||||
return preferences.getString(key, _default);
|
||||
}
|
||||
|
||||
|
||||
public boolean getBoolean(@NonNull String key, boolean _default) {
|
||||
return preferences.getBoolean(key, _default);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Integer getIntegerString(@NonNull String key, @NonNull Integer _default) {
|
||||
try {
|
||||
String value = preferences.getString(key, null);
|
||||
if (value != null) {
|
||||
return Integer.valueOf(value);
|
||||
}
|
||||
return _default;
|
||||
} catch (ClassCastException ex) {
|
||||
return preferences.getInt(key, _default); // old data, previously stored as primitive
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Long getLongString(@NonNull String key, @NonNull Long _default) {
|
||||
try {
|
||||
String value = preferences.getString(key, null);
|
||||
if (value != null) {
|
||||
return Long.valueOf(value);
|
||||
}
|
||||
return _default;
|
||||
} catch (ClassCastException ex) {
|
||||
return preferences.getLong(key, _default);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Float getFloatString(@NonNull String key, @NonNull Float _default) {
|
||||
try {
|
||||
String value = preferences.getString(key, null);
|
||||
if (value != null) {
|
||||
return Float.valueOf(value);
|
||||
}
|
||||
return _default;
|
||||
} catch (ClassCastException ex) {
|
||||
return preferences.getFloat(key, _default);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return prefName;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package app.revanced.integrations.settingsmenu;
|
||||
|
||||
import android.content.Context;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -17,6 +16,9 @@ import app.revanced.integrations.utils.ThemeHelper;
|
||||
|
||||
public class ReVancedSettingActivity {
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void setTheme(LicenseActivity base) {
|
||||
final var whiteTheme = "Theme.YouTube.Settings";
|
||||
final var darkTheme = "Theme.YouTube.Settings.Dark";
|
||||
@@ -24,11 +26,14 @@ public class ReVancedSettingActivity {
|
||||
final var theme = ThemeHelper.isDarkTheme() ? darkTheme : whiteTheme;
|
||||
|
||||
LogHelper.printDebug(() -> "Using theme: " + theme);
|
||||
base.setTheme(getIdentifier(theme, "style"));
|
||||
base.setTheme(ReVancedUtils.getResourceIdentifier(theme, "style"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void initializeSettings(LicenseActivity base) {
|
||||
base.setContentView(getIdentifier("revanced_settings_with_toolbar", "layout"));
|
||||
base.setContentView(ReVancedUtils.getResourceIdentifier("revanced_settings_with_toolbar", "layout"));
|
||||
|
||||
PreferenceFragment preferenceFragment;
|
||||
String preferenceIdentifier;
|
||||
@@ -46,7 +51,7 @@ public class ReVancedSettingActivity {
|
||||
}
|
||||
|
||||
try {
|
||||
TextView toolbar = getTextView((ViewGroup) base.findViewById(getIdentifier("toolbar", "id")));
|
||||
TextView toolbar = getTextView((ViewGroup) base.findViewById(ReVancedUtils.getResourceIdentifier("toolbar", "id")));
|
||||
if (toolbar == null) {
|
||||
// FIXME
|
||||
// https://github.com/revanced/revanced-patches/issues/1384
|
||||
@@ -58,7 +63,7 @@ public class ReVancedSettingActivity {
|
||||
LogHelper.printException(() -> "Could not set Toolbar title", e);
|
||||
}
|
||||
|
||||
base.getFragmentManager().beginTransaction().replace(getIdentifier("revanced_settings_fragments", "id"), preferenceFragment).commit();
|
||||
base.getFragmentManager().beginTransaction().replace(ReVancedUtils.getResourceIdentifier("revanced_settings_fragments", "id"), preferenceFragment).commit();
|
||||
}
|
||||
|
||||
|
||||
@@ -86,10 +91,4 @@ public class ReVancedSettingActivity {
|
||||
public static TextView getTextView(ViewGroup viewGroup) {
|
||||
return getView(TextView.class, viewGroup);
|
||||
}
|
||||
|
||||
private static int getIdentifier(String name, String defType) {
|
||||
Context appContext = ReVancedUtils.getContext();
|
||||
assert appContext != null;
|
||||
return appContext.getResources().getIdentifier(name, defType, appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user