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
50 Commits
v0.101.0
...
v0.104.1-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb7063b2b3 | ||
|
|
3b37a3b41f | ||
|
|
13e4be8567 | ||
|
|
be7b6f2a20 | ||
|
|
b9f6c62060 | ||
|
|
8493f57879 | ||
|
|
436a84ee07 | ||
|
|
f2603d3d79 | ||
|
|
246deb1602 | ||
|
|
050766de1d | ||
|
|
6952c50595 | ||
|
|
7fc8e882d8 | ||
|
|
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 |
4
.github/workflows/pull_request.yml
vendored
4
.github/workflows/pull_request.yml
vendored
@@ -26,5 +26,5 @@ jobs:
|
||||
|
||||
## Dependencies before merge
|
||||
|
||||
- [] https://github.com/revanced/revanced-patches
|
||||
pr_draft: true
|
||||
- [ ] https://github.com/revanced/revanced-patches
|
||||
pr_draft: true
|
||||
|
||||
153
CHANGELOG.md
153
CHANGELOG.md
@@ -1,3 +1,156 @@
|
||||
## [0.104.1-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.104.0...v0.104.1-dev.1) (2023-04-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/return-youtube-dislike:** fix dislikes using wrong font if dark mode is enabled during video playback ([#368](https://github.com/revanced/revanced-integrations/issues/368)) ([3b37a3b](https://github.com/revanced/revanced-integrations/commit/3b37a3b41f7bfbc4a6d6d12e2deb2acd9bb2ccc8))
|
||||
|
||||
# [0.104.0](https://github.com/revanced/revanced-integrations/compare/v0.103.0...v0.104.0) (2023-04-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **spoof-wifi-connection:** fixed crash when wifi is disabled ([#363](https://github.com/revanced/revanced-integrations/issues/363)) ([7fc8e88](https://github.com/revanced/revanced-integrations/commit/7fc8e882d8d268484b6e273fdb0371db2feef1d3))
|
||||
* **youtube/hide-video-action-buttons:** fix hide action buttons not working for some users ([#366](https://github.com/revanced/revanced-integrations/issues/366)) ([246deb1](https://github.com/revanced/revanced-integrations/commit/246deb16020adda26d9d0a0449157f4855678d18))
|
||||
* **youtube/sponsorblock:** Include milliseconds in the voting menu ([#362](https://github.com/revanced/revanced-integrations/issues/362)) ([6952c50](https://github.com/revanced/revanced-integrations/commit/6952c505957153d7fdeb7ee42b3f824c155993f5))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/wide-searchbar:** rename patch ([8493f57](https://github.com/revanced/revanced-integrations/commit/8493f57879f0075c73932240b61bf0c52efda0ed))
|
||||
* **youtube:** remove non working patch `hide-my-mix` ([436a84e](https://github.com/revanced/revanced-integrations/commit/436a84ee0785e5b0bed1b9a4a02b5be86eff4a4a))
|
||||
|
||||
# [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)
|
||||
|
||||
|
||||
|
||||
@@ -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(
|
||||
@@ -61,7 +62,11 @@ public final class GeneralAdsPatch extends Filter {
|
||||
"hero_promo_image",
|
||||
"statement_banner",
|
||||
"carousel_footered_layout",
|
||||
"text_image_button_layout"
|
||||
"text_image_button_layout",
|
||||
"primetime_promo",
|
||||
"feature_grid_interstitial",
|
||||
"product_details",
|
||||
"brand_video_shelf"
|
||||
);
|
||||
var movieAds = new BlockRule(
|
||||
SettingsEnum.ADREMOVER_MOVIE_REMOVAL,
|
||||
@@ -69,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(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.widget.Toast;
|
||||
|
||||
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 by the player.
|
||||
* Known issue: video preview not showing when using the seekbar.
|
||||
* Protobuf parameters used for autoplay in scrim.
|
||||
* Prepend this parameter to mute video playback (for autoplay in feed)
|
||||
*/
|
||||
private static final String PROTOBUF_PARAMETER_GENERAL = "CgIQBg";
|
||||
private static final String PROTOBUF_PARAMETER_SCRIM = "SAFgAXgB";
|
||||
|
||||
/**
|
||||
* Protobuf parameter of shorts and YouTube stories.
|
||||
@@ -21,9 +22,11 @@ public class SpoofSignatureVerificationPatch {
|
||||
|
||||
/**
|
||||
* Target Protobuf parameters.
|
||||
* Used by the generic player.
|
||||
*/
|
||||
private static final String PROTOBUF_PARAMETER_TARGET = "YADI";
|
||||
private static final String[] PROTOBUF_PARAMETER_TARGETS = {
|
||||
"YAHI", // Autoplay in feed
|
||||
"SAFg" // Autoplay in scrim
|
||||
};
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
@@ -35,8 +38,19 @@ public class SpoofSignatureVerificationPatch {
|
||||
if (!SettingsEnum.SIGNATURE_SPOOFING.getBoolean()) {
|
||||
return originalValue;
|
||||
}
|
||||
|
||||
LogHelper.printDebug(() -> "Original protobuf parameter value: " + originalValue);
|
||||
if (originalValue.startsWith(PROTOBUF_PARAMETER_TARGET) || originalValue.isEmpty()) {
|
||||
|
||||
// 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) {
|
||||
@@ -67,17 +81,98 @@ public class SpoofSignatureVerificationPatch {
|
||||
}
|
||||
|
||||
SettingsEnum.SIGNATURE_SPOOFING.saveValue(true);
|
||||
ReVancedUtils.runOnMainThread(() -> {
|
||||
Toast.makeText(
|
||||
ReVancedUtils.getContext(),
|
||||
"Spoofing app signature to prevent playback issues", Toast.LENGTH_LONG
|
||||
).show();
|
||||
// it would be great if the video could be forcefully reloaded, but currently there is no code to do this
|
||||
});
|
||||
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,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,40 +1,24 @@
|
||||
package app.revanced.integrations.patches.playback.speed;
|
||||
|
||||
import android.widget.Toast;
|
||||
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 {
|
||||
|
||||
/**
|
||||
* The current playback speed
|
||||
* PreferenceList entries and values, of all available playback speeds.
|
||||
*/
|
||||
private static float currentPlaybackSpeed = getLastRememberedPlaybackSpeed();
|
||||
|
||||
private final static float DEFAULT_PLAYBACK_SPEED = (float) SettingsEnum.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_VALUE.getDefaultValue();
|
||||
private static String[] preferenceListEntries, preferenceListEntryValues;
|
||||
|
||||
@Nullable
|
||||
private static String currentVideoId;
|
||||
|
||||
private static void showToast(final String message) {
|
||||
Toast.makeText(ReVancedUtils.getContext(), message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private static float getLastRememberedPlaybackSpeed() {
|
||||
return SettingsEnum.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_VALUE.getFloat();
|
||||
}
|
||||
|
||||
private static void rememberPlaybackSpeed() {
|
||||
SettingsEnum.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_VALUE.saveValue(currentPlaybackSpeed);
|
||||
}
|
||||
|
||||
private static boolean rememberLastSelectedPlaybackSpeed() {
|
||||
return SettingsEnum.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED.getBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
* Called when a new video loads.
|
||||
@@ -43,41 +27,51 @@ public final class RememberPlaybackSpeedPatch {
|
||||
if (videoId.equals(currentVideoId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentVideoId = videoId;
|
||||
currentPlaybackSpeed = getLastRememberedPlaybackSpeed();
|
||||
VideoInformation.overridePlaybackSpeed(SettingsEnum.PLAYBACK_SPEED_DEFAULT.getFloat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
* Called when a playback speed is selected.
|
||||
* Called when user selects a playback speed.
|
||||
*
|
||||
* @param playbackSpeed The playback speed to set.
|
||||
* @param playbackSpeed The playback speed the user selected
|
||||
*/
|
||||
public static void setPlaybackSpeed(final float playbackSpeed) {
|
||||
LogHelper.printDebug(() -> "Playback speed changed to: " + playbackSpeed);
|
||||
|
||||
currentPlaybackSpeed = playbackSpeed;
|
||||
|
||||
if (rememberLastSelectedPlaybackSpeed()) {
|
||||
rememberPlaybackSpeed();
|
||||
|
||||
showToast("Remembering playback speed: " + playbackSpeed + "x");
|
||||
} else {
|
||||
if (getLastRememberedPlaybackSpeed() == DEFAULT_PLAYBACK_SPEED) return;
|
||||
|
||||
showToast("Applying playback speed: " + playbackSpeed + "x");
|
||||
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.
|
||||
* Called when playback first starts,
|
||||
* and also called immediately after the user selects a new video speed.
|
||||
*
|
||||
* @return The currently set playback speed.
|
||||
* Overrides the video speed. Called after video loads, and immediately after user selects a different playback speed
|
||||
*/
|
||||
public static float getCurrentPlaybackSpeed() {
|
||||
return currentPlaybackSpeed;
|
||||
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
@@ -1,6 +1,6 @@
|
||||
package app.revanced.integrations.settingsmenu;
|
||||
|
||||
import static app.revanced.integrations.sponsorblock.StringRef.str;
|
||||
import static app.revanced.integrations.utils.StringRef.str;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
@@ -15,7 +15,7 @@ import android.preference.SwitchPreference;
|
||||
import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike;
|
||||
import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.SharedPrefHelper;
|
||||
import app.revanced.integrations.settings.SharedPrefCategory;
|
||||
|
||||
public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
|
||||
|
||||
@@ -35,27 +35,25 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
|
||||
private SwitchPreference compactLayoutPreference;
|
||||
|
||||
private void updateUIState() {
|
||||
final boolean rydIsEnabled = SettingsEnum.RYD_ENABLED.getBoolean();
|
||||
|
||||
enabledPreference.setSummary(rydIsEnabled
|
||||
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(rydIsEnabled);
|
||||
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(rydIsEnabled);
|
||||
compactLayoutPreference.setEnabled(SettingsEnum.RYD_USE_COMPACT_LAYOUT.isAvailable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getPreferenceManager().setSharedPreferencesName(SharedPrefHelper.SharedPrefNames.RYD.getName());
|
||||
getPreferenceManager().setSharedPreferencesName(SharedPrefCategory.RETURN_YOUTUBE_DISLIKE.prefName);
|
||||
|
||||
Activity context = this.getActivity();
|
||||
PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(context);
|
||||
@@ -78,8 +76,8 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
|
||||
percentagePreference.setChecked(SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.getBoolean());
|
||||
percentagePreference.setTitle(str("revanced_ryd_dislike_percentage_title"));
|
||||
percentagePreference.setOnPreferenceChangeListener((pref, newValue) -> {
|
||||
SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.saveValue((Boolean)newValue);
|
||||
|
||||
SettingsEnum.RYD_SHOW_DISLIKE_PERCENTAGE.saveValue(newValue);
|
||||
ReturnYouTubeDislike.clearCache();
|
||||
updateUIState();
|
||||
return true;
|
||||
});
|
||||
@@ -89,8 +87,8 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
|
||||
compactLayoutPreference.setChecked(SettingsEnum.RYD_USE_COMPACT_LAYOUT.getBoolean());
|
||||
compactLayoutPreference.setTitle(str("revanced_ryd_compact_layout_title"));
|
||||
compactLayoutPreference.setOnPreferenceChangeListener((pref, newValue) -> {
|
||||
SettingsEnum.RYD_USE_COMPACT_LAYOUT.saveValue((Boolean)newValue);
|
||||
|
||||
SettingsEnum.RYD_USE_COMPACT_LAYOUT.saveValue(newValue);
|
||||
ReturnYouTubeDislike.clearCache();
|
||||
updateUIState();
|
||||
return true;
|
||||
});
|
||||
@@ -102,7 +100,7 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
|
||||
// About category
|
||||
|
||||
PreferenceCategory aboutCategory = new PreferenceCategory(context);
|
||||
aboutCategory.setTitle(str("about"));
|
||||
aboutCategory.setTitle(str("revanced_ryd_about"));
|
||||
preferenceScreen.addPreference(aboutCategory);
|
||||
|
||||
// ReturnYouTubeDislike Website
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,13 +19,13 @@ class PlayerControlsVisibilityObserverImpl(
|
||||
* id of the direct parent of controls_layout, R.id.youtube_controls_overlay
|
||||
*/
|
||||
private val controlsLayoutParentId =
|
||||
ReVancedUtils.getResourceIdByName(activity, "id", "youtube_controls_overlay")
|
||||
ReVancedUtils.getResourceIdentifier(activity, "youtube_controls_overlay", "id")
|
||||
|
||||
/**
|
||||
* id of R.id.controls_layout
|
||||
*/
|
||||
private val controlsLayoutId =
|
||||
ReVancedUtils.getResourceIdByName(activity, "id", "controls_layout")
|
||||
ReVancedUtils.getResourceIdentifier(activity, "controls_layout", "id")
|
||||
|
||||
/**
|
||||
* reference to the controls layout view
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user