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
30 Commits
v0.108.0-d
...
v0.109.0-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7a940ca06 | ||
|
|
40def9e036 | ||
|
|
8ff9ebc592 | ||
|
|
f5df20134c | ||
|
|
592e7ed85b | ||
|
|
31251f0214 | ||
|
|
fa44f1227b | ||
|
|
b3c7e7f638 | ||
|
|
3bd94b2f6a | ||
|
|
60f25a2af0 | ||
|
|
301a0327bc | ||
|
|
7dc71e6861 | ||
|
|
69cc56c921 | ||
|
|
307315c43c | ||
|
|
985c0d0c48 | ||
|
|
191cc711de | ||
|
|
d9a75ea46a | ||
|
|
c7cabc0b57 | ||
|
|
cd93917148 | ||
|
|
932e3356a1 | ||
|
|
0c55d70370 | ||
|
|
d63f24f7be | ||
|
|
80689eff5b | ||
|
|
71e94e8d67 | ||
|
|
6d32f1ebc2 | ||
|
|
b47a781ba7 | ||
|
|
eb02c92773 | ||
|
|
ac13d10305 | ||
|
|
5ec90db28a | ||
|
|
5652c32345 |
131
CHANGELOG.md
131
CHANGELOG.md
@@ -1,3 +1,134 @@
|
||||
# [0.109.0-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.109.0-dev.2...v0.109.0-dev.3) (2023-05-27)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/hide-seekbar:** more fine grained hiding of seekbar ([#409](https://github.com/revanced/revanced-integrations/issues/409)) ([40def9e](https://github.com/revanced/revanced-integrations/commit/40def9e036129e9f70549db5fd219f18618e931d))
|
||||
|
||||
# [0.109.0-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.109.0-dev.1...v0.109.0-dev.2) (2023-05-27)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/hide-shorts-components:** hide shorts info panel ([#415](https://github.com/revanced/revanced-integrations/issues/415)) ([f5df201](https://github.com/revanced/revanced-integrations/commit/f5df20134c376c351b5d7d9881c45876463734f9))
|
||||
|
||||
# [0.109.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.108.1-dev.2...v0.109.0-dev.1) (2023-05-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **remove-screen-capture-restriction:** remove app constraint ([#411](https://github.com/revanced/revanced-integrations/issues/411)) ([31251f0](https://github.com/revanced/revanced-integrations/commit/31251f0214b6d37a9407975a23dbdd43e3cad611))
|
||||
|
||||
## [0.108.1-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.108.1-dev.1...v0.108.1-dev.2) (2023-05-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/downloads:** rename patch to `external-downloads` ([#414](https://github.com/revanced/revanced-integrations/issues/414)) ([b3c7e7f](https://github.com/revanced/revanced-integrations/commit/b3c7e7f63828d299199f80d09c1349de22d8d198))
|
||||
|
||||
## [0.108.1-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.108.0...v0.108.1-dev.1) (2023-05-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/hide-player-buttons:** fix previous/next button showing if previous video exists ([#412](https://github.com/revanced/revanced-integrations/issues/412)) ([60f25a2](https://github.com/revanced/revanced-integrations/commit/60f25a2af0bee0301bb84ac69b586343485003bb))
|
||||
|
||||
# [0.108.0](https://github.com/revanced/revanced-integrations/compare/v0.107.0...v0.108.0) (2023-05-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **twitter:** correctly resolve to integrations methods ([cd93917](https://github.com/revanced/revanced-integrations/commit/cd93917148e2f7695effb15183f53b84ddb9800a))
|
||||
* **youtube/hide-ads:** don't filter for `reels_player_overlay` ([415c194](https://github.com/revanced/revanced-integrations/commit/415c1948fccdc8eb27b76b043996017c5c56eac3))
|
||||
* **youtube/remember-video-quality:** do not show 'auto' in video resolution picker if a default quality is set ([#400](https://github.com/revanced/revanced-integrations/issues/400)) ([e30d120](https://github.com/revanced/revanced-integrations/commit/e30d1201c992f4896a0b7106230377d78506cd6f))
|
||||
* **youtube/remember-video-quality:** fix default video quality/speed being applied when resuming app ([#392](https://github.com/revanced/revanced-integrations/issues/392)) ([c97d1b7](https://github.com/revanced/revanced-integrations/commit/c97d1b7ee5be6a0f097f2995321608bc74f5822c))
|
||||
* **youtube/return-youtube-dislike:** fix dislikes not showing for video opened from feed autoplay ([#408](https://github.com/revanced/revanced-integrations/issues/408)) ([307315c](https://github.com/revanced/revanced-integrations/commit/307315c43c68a47c983384351a617f5c5f508b4f))
|
||||
* **youtube/return-youtube-dislike:** fix potential error toast when using old UI layout ([#384](https://github.com/revanced/revanced-integrations/issues/384)) ([6c36bee](https://github.com/revanced/revanced-integrations/commit/6c36beeda139156bfbb5a17bc89aa63c25afa83c))
|
||||
* **youtube/return-youtube-dislikes:** fix temporarily frozen video after opening a shorts ([#396](https://github.com/revanced/revanced-integrations/issues/396)) ([6a94bd2](https://github.com/revanced/revanced-integrations/commit/6a94bd2237be9cde6256c83fcec72b3f0de83496))
|
||||
* **youtube/settings:** fix non functional back button in settings ([#404](https://github.com/revanced/revanced-integrations/issues/404)) ([0c55d70](https://github.com/revanced/revanced-integrations/commit/0c55d70370dad9275dfb5bc3817f71d4290f5a13))
|
||||
* **youtube/sponsorblock:** fix skip button in wrong location when full screen and comments visible ([#387](https://github.com/revanced/revanced-integrations/issues/387)) ([486b79b](https://github.com/revanced/revanced-integrations/commit/486b79b4e4927d4c05cfb4d5222a1d74fe60e327))
|
||||
* **youtube/sponsorblock:** fix toast shown when scrubbing thru a paused video ([#401](https://github.com/revanced/revanced-integrations/issues/401)) ([7da5673](https://github.com/revanced/revanced-integrations/commit/7da56738a14a36fbf66f05d28fd886baaafbee3f))
|
||||
* **youtube/spoof-app-version:** restore watch history preview ([#394](https://github.com/revanced/revanced-integrations/issues/394)) ([4c7f737](https://github.com/revanced/revanced-integrations/commit/4c7f737913a0c3690f8230c51f6dd217e8b04c7a))
|
||||
* **youtube/swipe-controls:** restart when "press to swipe" preference is changed ([#399](https://github.com/revanced/revanced-integrations/issues/399)) ([a3d754c](https://github.com/revanced/revanced-integrations/commit/a3d754c209e443135759850c7634708b23330a7c))
|
||||
* **youtube/theme:** apply custom seekbar color to video thumbnails ([#391](https://github.com/revanced/revanced-integrations/issues/391)) ([ae99408](https://github.com/revanced/revanced-integrations/commit/ae994086360b45340ed1ed896c35917d785bb4f9))
|
||||
* **youtube/theme:** fix app crash if user clears seekbar color ([#390](https://github.com/revanced/revanced-integrations/issues/390)) ([e2f5290](https://github.com/revanced/revanced-integrations/commit/e2f52905dc445f881666c06877c3a69306335dcb))
|
||||
* **youtube/theme:** fix toast shown on fresh app install ([#381](https://github.com/revanced/revanced-integrations/issues/381)) ([2dc431f](https://github.com/revanced/revanced-integrations/commit/2dc431f1bf54c12dfc45c4511a0b0792e214be4f))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add capability to filter from protobuf buffer ([5652c32](https://github.com/revanced/revanced-integrations/commit/5652c323455b58f6760d4938c79d704c22fd546c))
|
||||
* **reddit:** add `sanitize-sharing-links` patch ([#407](https://github.com/revanced/revanced-integrations/issues/407)) ([191cc71](https://github.com/revanced/revanced-integrations/commit/191cc711de1ecbf6632fc27d32ee4f0c81413c57))
|
||||
* **twitch:** add `auto-claim-channel-points` patch ([#398](https://github.com/revanced/revanced-integrations/issues/398)) ([d7f050b](https://github.com/revanced/revanced-integrations/commit/d7f050ba2ff513c91cccbf0095fc7756dbb47400))
|
||||
* **twitter/hide-recommended-users:** hide "Who to follow" ([c7cabc0](https://github.com/revanced/revanced-integrations/commit/c7cabc0b5799464ed75d290dfae5fcd2faa4fc94))
|
||||
* **youtube/copy-video-url:** add tap and hold functionality to copy video url buttons ([#403](https://github.com/revanced/revanced-integrations/issues/403)) ([80689ef](https://github.com/revanced/revanced-integrations/commit/80689eff5b2deb971feb1fc59e987ef835506bae))
|
||||
* **youtube/hide-player-overlay:** make it toggleable in settings ([#382](https://github.com/revanced/revanced-integrations/issues/382)) ([1b4aa0f](https://github.com/revanced/revanced-integrations/commit/1b4aa0fcc6b89acd4156e93685b1da7519aa7148))
|
||||
* **youtube/hide-shorts-components:** hide navigation bar ([ac13d10](https://github.com/revanced/revanced-integrations/commit/ac13d1030561905a81059ad0db31a749833a31cd))
|
||||
* **youtube/settings:** add reset button to edit preference dialog ([#383](https://github.com/revanced/revanced-integrations/issues/383)) ([cb5a4d0](https://github.com/revanced/revanced-integrations/commit/cb5a4d0c9b3b340928695fcb1d10b164a6dcef27))
|
||||
* **youtube/video-speed:** change custom video speeds inside app settings ([#393](https://github.com/revanced/revanced-integrations/issues/393)) ([b42790f](https://github.com/revanced/revanced-integrations/commit/b42790fbca0f6c854d41871834fd6266dd2ea106))
|
||||
* **youtube:** `hide-load-more-button` patch ([#389](https://github.com/revanced/revanced-integrations/issues/389)) ([7da9d44](https://github.com/revanced/revanced-integrations/commit/7da9d440eedfc895b49aac40498f0279156ad117))
|
||||
* **youtube:** add `hide-filter-bar` patch ([9649c3d](https://github.com/revanced/revanced-integrations/commit/9649c3dbc8406c3639c4fff9dd179d6d29886e60))
|
||||
* **youtube:** add `hide-shorts-components` patch ([5ec90db](https://github.com/revanced/revanced-integrations/commit/5ec90db28a46e8f5d79f4793c141a7411a2da05d))
|
||||
* **youtube:** add options to disable toasts on connection errors ([#402](https://github.com/revanced/revanced-integrations/issues/402)) ([ae18edd](https://github.com/revanced/revanced-integrations/commit/ae18edd047d7979307bc28f28db17bae2c5cc226))
|
||||
* **youtube:** import / export of revanced settings ([#388](https://github.com/revanced/revanced-integrations/issues/388)) ([c3f08d8](https://github.com/revanced/revanced-integrations/commit/c3f08d8d7e8116496611b85508fbd54bb3a71992))
|
||||
* **youtube:** support version `18.19.35` ([b47a781](https://github.com/revanced/revanced-integrations/commit/b47a781ba710e6fb66e144ef95cdd51af358e4de))
|
||||
|
||||
# [0.108.0-dev.24](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.23...v0.108.0-dev.24) (2023-05-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/return-youtube-dislike:** fix dislikes not showing for video opened from feed autoplay ([#408](https://github.com/revanced/revanced-integrations/issues/408)) ([307315c](https://github.com/revanced/revanced-integrations/commit/307315c43c68a47c983384351a617f5c5f508b4f))
|
||||
|
||||
# [0.108.0-dev.23](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.22...v0.108.0-dev.23) (2023-05-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **reddit:** add `sanitize-sharing-links` patch ([#407](https://github.com/revanced/revanced-integrations/issues/407)) ([191cc71](https://github.com/revanced/revanced-integrations/commit/191cc711de1ecbf6632fc27d32ee4f0c81413c57))
|
||||
|
||||
# [0.108.0-dev.22](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.21...v0.108.0-dev.22) (2023-05-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **twitter:** correctly resolve to integrations methods ([cd93917](https://github.com/revanced/revanced-integrations/commit/cd93917148e2f7695effb15183f53b84ddb9800a))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **twitter/hide-recommended-users:** hide "Who to follow" ([c7cabc0](https://github.com/revanced/revanced-integrations/commit/c7cabc0b5799464ed75d290dfae5fcd2faa4fc94))
|
||||
|
||||
# [0.108.0-dev.21](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.20...v0.108.0-dev.21) (2023-05-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/settings:** fix non functional back button in settings ([#404](https://github.com/revanced/revanced-integrations/issues/404)) ([0c55d70](https://github.com/revanced/revanced-integrations/commit/0c55d70370dad9275dfb5bc3817f71d4290f5a13))
|
||||
|
||||
# [0.108.0-dev.20](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.19...v0.108.0-dev.20) (2023-05-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/copy-video-url:** add tap and hold functionality to copy video url buttons ([#403](https://github.com/revanced/revanced-integrations/issues/403)) ([80689ef](https://github.com/revanced/revanced-integrations/commit/80689eff5b2deb971feb1fc59e987ef835506bae))
|
||||
|
||||
# [0.108.0-dev.19](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.18...v0.108.0-dev.19) (2023-05-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube:** support version `18.19.35` ([b47a781](https://github.com/revanced/revanced-integrations/commit/b47a781ba710e6fb66e144ef95cdd51af358e4de))
|
||||
|
||||
# [0.108.0-dev.18](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.17...v0.108.0-dev.18) (2023-05-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add capability to filter from protobuf buffer ([5652c32](https://github.com/revanced/revanced-integrations/commit/5652c323455b58f6760d4938c79d704c22fd546c))
|
||||
* **youtube/hide-shorts-components:** hide navigation bar ([ac13d10](https://github.com/revanced/revanced-integrations/commit/ac13d1030561905a81059ad0db31a749833a31cd))
|
||||
* **youtube:** add `hide-shorts-components` patch ([5ec90db](https://github.com/revanced/revanced-integrations/commit/5ec90db28a46e8f5d79f4793c141a7411a2da05d))
|
||||
|
||||
# [0.108.0-dev.17](https://github.com/revanced/revanced-integrations/compare/v0.108.0-dev.16...v0.108.0-dev.17) (2023-05-16)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package app.revanced.all.screencapture.removerestriction;
|
||||
|
||||
import android.media.AudioAttributes;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
public final class RemoveScreencaptureRestrictionPatch {
|
||||
// Member of AudioAttributes.Builder
|
||||
@RequiresApi(api = Build.VERSION_CODES.Q)
|
||||
public static AudioAttributes.Builder setAllowedCapturePolicy(final AudioAttributes.Builder builder, final int capturePolicy) {
|
||||
builder.setAllowedCapturePolicy(AudioAttributes.ALLOW_CAPTURE_BY_ALL);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
// Member of AudioManager static class
|
||||
public static void setAllowedCapturePolicy(final int capturePolicy) {
|
||||
// Ignore request
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
final class ButtonsPatch extends Filter {
|
||||
private final BlockRule actionBarRule;
|
||||
|
||||
public ButtonsPatch() {
|
||||
actionBarRule = new BlockRule(null, "video_action_bar");
|
||||
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 canHideActionBar() {
|
||||
for (BlockRule rule : pathRegister) if (!rule.isEnabled()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(final String path, final String identifier) {
|
||||
// If everything is hidden, then also hide the video bar itself.
|
||||
if (canHideActionBar() && actionBarRule.check(identifier).isBlocked()) return true;
|
||||
|
||||
return pathRegister.contains(path);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
final class CommentsPatch extends Filter {
|
||||
|
||||
public CommentsPatch() {
|
||||
var comments = new BlockRule(SettingsEnum.HIDE_COMMENTS_SECTION, "video_metadata_carousel", "_comments");
|
||||
var previewComment = new BlockRule(
|
||||
SettingsEnum.HIDE_PREVIEW_COMMENT,
|
||||
"|carousel_item",
|
||||
"comments_entry_point_teaser",
|
||||
"comments_entry_point_simplebox"
|
||||
);
|
||||
|
||||
this.pathRegister.registerAll(
|
||||
comments,
|
||||
previewComment
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean filter(String path, String _identifier) {
|
||||
if (!pathRegister.contains(path)) return false;
|
||||
|
||||
LogHelper.printDebug(() -> "Blocked: " + path);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2,22 +2,46 @@ package app.revanced.integrations.patches;
|
||||
|
||||
import static app.revanced.integrations.utils.StringRef.str;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
public class CopyVideoUrlPatch {
|
||||
public static void copyUrl(Boolean withTimestamp) {
|
||||
|
||||
public static void copyUrl(boolean withTimestamp) {
|
||||
try {
|
||||
String url = String.format("https://youtu.be/%s", VideoInformation.getVideoId());
|
||||
if (withTimestamp) {
|
||||
long seconds = VideoInformation.getVideoTime() / 1000;
|
||||
url += String.format("?t=%s", seconds);
|
||||
StringBuilder builder = new StringBuilder("https://youtu.be/");
|
||||
builder.append(VideoInformation.getVideoId());
|
||||
final long currentVideoTimeInSeconds = VideoInformation.getVideoTime() / 1000;
|
||||
if (withTimestamp && currentVideoTimeInSeconds > 0) {
|
||||
final long hour = currentVideoTimeInSeconds / (60 * 60);
|
||||
final long minute = (currentVideoTimeInSeconds / 60) % 60;
|
||||
final long second = currentVideoTimeInSeconds % 60;
|
||||
builder.append("?t=");
|
||||
if (hour > 0) {
|
||||
builder.append(hour).append("h");
|
||||
}
|
||||
if (minute > 0) {
|
||||
builder.append(minute).append("m");
|
||||
}
|
||||
if (second > 0) {
|
||||
builder.append(second).append("s");
|
||||
}
|
||||
}
|
||||
|
||||
ReVancedUtils.setClipboard(url);
|
||||
ReVancedUtils.showToastShort(str("share_copy_url_success"));
|
||||
ReVancedUtils.setClipboard(builder.toString());
|
||||
// Do not show a toast if using Android 13+ as it shows it's own toast.
|
||||
// But if the user copied with a timestamp then show a toast.
|
||||
// Unfortunately this will show 2 toasts on Android 13+, but no way around this.
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2 || (withTimestamp && currentVideoTimeInSeconds > 0)) {
|
||||
ReVancedUtils.showToastShort(withTimestamp && currentVideoTimeInSeconds > 0
|
||||
? str("revanced_share_copy_url_timestamp_success")
|
||||
: str("revanced_share_copy_url_success"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogHelper.printException(() -> "Failed to generate video url", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.view.View;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
public final class GeneralAdsPatch extends Filter {
|
||||
private final String[] IGNORE = {
|
||||
"home_video_with_context",
|
||||
"related_video_with_context",
|
||||
"comment_thread", // skip blocking anything in the comments
|
||||
"|comment.", // skip blocking anything in the comments replies
|
||||
"library_recent_shelf",
|
||||
};
|
||||
|
||||
private final BlockRule custom = new CustomBlockRule(
|
||||
SettingsEnum.CUSTOM_FILTER,
|
||||
SettingsEnum.CUSTOM_FILTER_STRINGS
|
||||
);
|
||||
|
||||
public GeneralAdsPatch() {
|
||||
var communityPosts = new BlockRule(SettingsEnum.HIDE_COMMUNITY_POSTS, "post_base_wrapper");
|
||||
var communityGuidelines = new BlockRule(SettingsEnum.HIDE_COMMUNITY_GUIDELINES, "community_guidelines");
|
||||
var subscribersCommunityGuidelines = new BlockRule(SettingsEnum.HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES, "sponsorships_comments_upsell");
|
||||
var channelMemberShelf = new BlockRule(SettingsEnum.HIDE_CHANNEL_MEMBER_SHELF, "member_recognition_shelf");
|
||||
var compactBanner = new BlockRule(SettingsEnum.HIDE_COMPACT_BANNER, "compact_banner");
|
||||
var inFeedSurvey = new BlockRule(SettingsEnum.HIDE_FEED_SURVEY, "in_feed_survey", "slimline_survey");
|
||||
var medicalPanel = new BlockRule(SettingsEnum.HIDE_MEDICAL_PANELS, "medical_panel");
|
||||
var merchandise = new BlockRule(SettingsEnum.HIDE_MERCHANDISE_BANNERS, "product_carousel");
|
||||
var infoPanel = new BlockRule(SettingsEnum.HIDE_HIDE_INFO_PANELS, "publisher_transparency_panel", "single_item_information_panel");
|
||||
var channelGuidelines = new BlockRule(SettingsEnum.HIDE_HIDE_CHANNEL_GUIDELINES, "channel_guidelines_entry_banner");
|
||||
var audioTrackButton = new BlockRule(SettingsEnum.HIDE_AUDIO_TRACK_BUTTON, "multi_feed_icon_button");
|
||||
var artistCard = new BlockRule(SettingsEnum.HIDE_ARTIST_CARDS, "official_card");
|
||||
var chapterTeaser = new BlockRule(SettingsEnum.HIDE_CHAPTER_TEASER, "expandable_metadata", "macro_markers_carousel");
|
||||
var viewProducts = new BlockRule(SettingsEnum.HIDE_PRODUCTS_BANNER, "product_item", "products_in_video");
|
||||
var webLinkPanel = new BlockRule(SettingsEnum.HIDE_WEB_SEARCH_RESULTS, "web_link_panel");
|
||||
var channelBar = new BlockRule(SettingsEnum.HIDE_CHANNEL_BAR, "channel_bar");
|
||||
var relatedVideos = new BlockRule(SettingsEnum.HIDE_RELATED_VIDEOS, "fullscreen_related_videos");
|
||||
var quickActions = new BlockRule(SettingsEnum.HIDE_QUICK_ACTIONS, "quick_actions");
|
||||
var imageShelf = new BlockRule(SettingsEnum.HIDE_IMAGE_SHELF, "image_shelf");
|
||||
var graySeparator = new BlockRule(SettingsEnum.HIDE_GRAY_SEPARATOR,
|
||||
"cell_divider" // layout residue (gray line above the buttoned ad),
|
||||
);
|
||||
var paidContent = new BlockRule(SettingsEnum.HIDE_PAID_CONTENT, "paid_content_overlay");
|
||||
var latestPosts = new BlockRule(SettingsEnum.HIDE_HIDE_LATEST_POSTS, "post_shelf");
|
||||
var selfSponsor = new BlockRule(SettingsEnum.HIDE_SELF_SPONSOR, "cta_shelf_card");
|
||||
var buttonedAd = new BlockRule(SettingsEnum.HIDE_BUTTONED_ADS,
|
||||
"_buttoned_layout",
|
||||
"full_width_square_image_layout",
|
||||
"_ad_with",
|
||||
"video_display_button_group_layout",
|
||||
"landscape_image_wide_button_layout"
|
||||
);
|
||||
var generalAds = new BlockRule(
|
||||
SettingsEnum.HIDE_GENERAL_ADS,
|
||||
"ads_video_with_context",
|
||||
"banner_text_icon",
|
||||
"square_image_layout",
|
||||
"watch_metadata_app_promo",
|
||||
"video_display_full_layout",
|
||||
"hero_promo_image",
|
||||
"statement_banner",
|
||||
"carousel_footered_layout",
|
||||
"text_image_button_layout",
|
||||
"primetime_promo",
|
||||
"product_details",
|
||||
"full_width_portrait_image_layout",
|
||||
"brand_video_shelf"
|
||||
);
|
||||
var movieAds = new BlockRule(
|
||||
SettingsEnum.HIDE_MOVIES_SECTION,
|
||||
"browsy_bar",
|
||||
"compact_movie",
|
||||
"horizontal_movie_shelf",
|
||||
"movie_and_show_upsell_card",
|
||||
"compact_tvfilm_item",
|
||||
"offer_module_root"
|
||||
);
|
||||
|
||||
this.pathRegister.registerAll(
|
||||
generalAds,
|
||||
buttonedAd,
|
||||
channelBar,
|
||||
communityPosts,
|
||||
paidContent,
|
||||
latestPosts,
|
||||
movieAds,
|
||||
chapterTeaser,
|
||||
communityGuidelines,
|
||||
quickActions,
|
||||
relatedVideos,
|
||||
compactBanner,
|
||||
inFeedSurvey,
|
||||
viewProducts,
|
||||
medicalPanel,
|
||||
merchandise,
|
||||
infoPanel,
|
||||
channelGuidelines,
|
||||
audioTrackButton,
|
||||
artistCard,
|
||||
selfSponsor,
|
||||
webLinkPanel,
|
||||
imageShelf,
|
||||
subscribersCommunityGuidelines,
|
||||
channelMemberShelf
|
||||
);
|
||||
|
||||
var carouselAd = new BlockRule(SettingsEnum.HIDE_GENERAL_ADS,
|
||||
"carousel_ad"
|
||||
);
|
||||
var shorts = new BlockRule(SettingsEnum.HIDE_SHORTS,
|
||||
"shorts_shelf",
|
||||
"inline_shorts",
|
||||
"shorts_grid"
|
||||
);
|
||||
|
||||
this.identifierRegister.registerAll(
|
||||
shorts,
|
||||
graySeparator,
|
||||
carouselAd
|
||||
);
|
||||
}
|
||||
|
||||
public boolean filter(final String path, final String identifier) {
|
||||
BlockResult result;
|
||||
|
||||
if (custom.isEnabled() && custom.check(path).isBlocked())
|
||||
result = BlockResult.CUSTOM;
|
||||
else if (ReVancedUtils.containsAny(path, IGNORE))
|
||||
result = BlockResult.IGNORED;
|
||||
else if (pathRegister.contains(path) || identifierRegister.contains(identifier))
|
||||
result = BlockResult.DEFINED;
|
||||
else
|
||||
result = BlockResult.UNBLOCKED;
|
||||
|
||||
LogHelper.printDebug(() -> String.format("%s (ID: %s): %s", result.message, identifier, path));
|
||||
|
||||
return result.filter;
|
||||
}
|
||||
|
||||
private enum BlockResult {
|
||||
UNBLOCKED(false, "Unblocked"),
|
||||
IGNORED(false, "Ignored"),
|
||||
DEFINED(true, "Blocked"),
|
||||
CUSTOM(true, "Custom");
|
||||
|
||||
final Boolean filter;
|
||||
final String message;
|
||||
|
||||
BlockResult(boolean filter, String message) {
|
||||
this.filter = filter;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide a view.
|
||||
*
|
||||
* @param condition The setting to check for hiding the view.
|
||||
* @param view The view to hide.
|
||||
*/
|
||||
private static void hideView(SettingsEnum condition, View view) {
|
||||
if (!condition.getBoolean()) return;
|
||||
|
||||
LogHelper.printDebug(() -> "Hiding view with setting: " + condition);
|
||||
|
||||
ReVancedUtils.HideViewByLayoutParams(view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the view, which shows ads in the homepage.
|
||||
*
|
||||
* @param view The view, which shows ads.
|
||||
*/
|
||||
public static void hideAdAttributionView(View view) {
|
||||
hideView(SettingsEnum.HIDE_GENERAL_ADS, view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the view, which shows reels in the homepage.
|
||||
*
|
||||
* @param view The view, which shows reels.
|
||||
*/
|
||||
public static void hideReelView(View view) {
|
||||
hideView(SettingsEnum.HIDE_SHORTS, view);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@ import app.revanced.integrations.utils.ReVancedUtils;
|
||||
public class HideAlbumCardsPatch {
|
||||
public static void hideAlbumCard(View view) {
|
||||
if (!SettingsEnum.HIDE_ALBUM_CARDS.getBoolean()) return;
|
||||
ReVancedUtils.HideViewByLayoutParams(view);
|
||||
ReVancedUtils.hideViewByLayoutParams(view);
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,6 @@ public class HideBreakingNewsPatch {
|
||||
public static void hideBreakingNews(View view) {
|
||||
if (!SettingsEnum.HIDE_BREAKING_NEWS.getBoolean()
|
||||
|| isSpoofingOldVersionWithHorizontalCardListWatchHistory()) return;
|
||||
ReVancedUtils.HideViewByLayoutParams(view);
|
||||
ReVancedUtils.hideViewByLayoutParams(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,6 @@ public class HideCrowdfundingBoxPatch {
|
||||
//Used by app.revanced.patches.youtube.layout.hidecrowdfundingbox.patch.HideCrowdfundingBoxPatch
|
||||
public static void hideCrowdfundingBox(View view) {
|
||||
if (!SettingsEnum.HIDE_CROWDFUNDING_BOX.getBoolean()) return;
|
||||
ReVancedUtils.HideViewByLayoutParams(view);
|
||||
ReVancedUtils.hideViewByLayoutParams(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ public final class HideFilterBarPatch {
|
||||
public static void hideInRelatedVideos(final View chipView) {
|
||||
if (!SettingsEnum.HIDE_FILTER_BAR_FEED_IN_RELATED_VIDEOS.getBoolean()) return;
|
||||
|
||||
ReVancedUtils.HideViewByLayoutParams(chipView);
|
||||
ReVancedUtils.hideViewByLayoutParams(chipView);
|
||||
}
|
||||
|
||||
public static int hideInSearch(final int height) {
|
||||
|
||||
@@ -8,6 +8,6 @@ import app.revanced.integrations.utils.ReVancedUtils;
|
||||
public class HideLoadMoreButtonPatch {
|
||||
public static void hideLoadMoreButton(View view){
|
||||
if(!SettingsEnum.HIDE_LOAD_MORE_BUTTON.getBoolean()) return;
|
||||
ReVancedUtils.HideViewByLayoutParams(view);
|
||||
ReVancedUtils.hideViewByLayoutParams(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public final class HidePlayerButtonsPatch {
|
||||
|
||||
public static boolean hideButtons() {
|
||||
return SettingsEnum.HIDE_PLAYER_BUTTONS.getBoolean();
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static boolean previousOrNextButtonIsVisible(boolean previousOrNextButtonVisible) {
|
||||
if (SettingsEnum.HIDE_PLAYER_BUTTONS.getBoolean()) {
|
||||
return false;
|
||||
}
|
||||
return previousOrNextButtonVisible;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class HideShortsCommentsButtonPatch {
|
||||
//Used by app.revanced.patches.youtube.layout.comments.patch.CommentsPatch
|
||||
public static void hideShortsCommentsButton(View view) {
|
||||
if (!SettingsEnum.HIDE_SHORTS_COMMENTS_BUTTON.getBoolean()) return;
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.Spliterator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
class BlockRule {
|
||||
final static class BlockResult {
|
||||
private final boolean blocked;
|
||||
private final SettingsEnum setting;
|
||||
|
||||
public BlockResult(final SettingsEnum setting, final boolean blocked) {
|
||||
this.setting = setting;
|
||||
this.blocked = blocked;
|
||||
}
|
||||
|
||||
public SettingsEnum getSetting() {
|
||||
return setting;
|
||||
}
|
||||
|
||||
public boolean isBlocked() {
|
||||
return blocked;
|
||||
}
|
||||
}
|
||||
|
||||
protected final SettingsEnum setting;
|
||||
private final String[] blocks;
|
||||
|
||||
/**
|
||||
* Initialize a new rule for components.
|
||||
*
|
||||
* @param setting The setting which controls the blocking of this component.
|
||||
* @param blocks The rules to block the component on.
|
||||
*/
|
||||
public BlockRule(final SettingsEnum setting, final String... blocks) {
|
||||
this.setting = setting;
|
||||
this.blocks = blocks;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return setting.getBoolean();
|
||||
}
|
||||
|
||||
public BlockResult check(final String string) {
|
||||
return new BlockResult(setting, string != null && ReVancedUtils.containsAny(string, blocks));
|
||||
}
|
||||
}
|
||||
|
||||
final class CustomBlockRule extends BlockRule {
|
||||
/**
|
||||
* Initialize a new rule for components.
|
||||
*
|
||||
* @param setting The setting which controls the blocking of the components.
|
||||
* @param filter The setting which contains the list of component names.
|
||||
*/
|
||||
public CustomBlockRule(final SettingsEnum setting, final SettingsEnum filter) {
|
||||
super(setting, filter.getString().split(","));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class Filter {
|
||||
final protected LithoBlockRegister pathRegister = new LithoBlockRegister();
|
||||
final protected LithoBlockRegister identifierRegister = new LithoBlockRegister();
|
||||
|
||||
abstract boolean filter(final String path, final String identifier);
|
||||
}
|
||||
|
||||
final class LithoBlockRegister implements Iterable<BlockRule> {
|
||||
private final ArrayList<BlockRule> blocks = new ArrayList<>();
|
||||
|
||||
public void registerAll(BlockRule... blocks) {
|
||||
this.blocks.addAll(Arrays.asList(blocks));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Iterator<BlockRule> iterator() {
|
||||
return blocks.iterator();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@Override
|
||||
public void forEach(@NonNull Consumer<? super BlockRule> action) {
|
||||
blocks.forEach(action);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@NonNull
|
||||
@Override
|
||||
public Spliterator<BlockRule> spliterator() {
|
||||
return blocks.spliterator();
|
||||
}
|
||||
|
||||
public boolean contains(String path) {
|
||||
for (var rule : this) {
|
||||
if (!rule.isEnabled()) continue;
|
||||
|
||||
var result = rule.check(path);
|
||||
if (result.isBlocked()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public final class LithoFilterPatch {
|
||||
private static final Filter[] filters = new Filter[]{
|
||||
new GeneralAdsPatch(),
|
||||
new ButtonsPatch(),
|
||||
new CommentsPatch(),
|
||||
};
|
||||
|
||||
public static boolean filter(final StringBuilder pathBuilder, final String identifier) {
|
||||
var path = pathBuilder.toString();
|
||||
if (path.isEmpty()) return false;
|
||||
|
||||
LogHelper.printDebug(() -> String.format("Searching (ID: %s): %s", identifier, path));
|
||||
|
||||
for (var filter : filters) {
|
||||
if (filter.filter(path, identifier)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,8 @@ package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class SeekbarTappingPatch {
|
||||
|
||||
//Used by app.revanced.patches.youtube.interaction.seekbar.patch.EnableSeekbarTappingPatch
|
||||
public static boolean isTapSeekingEnabled() {
|
||||
return SettingsEnum.TAP_SEEKING.getBoolean();
|
||||
public final class SeekbarTappingPatch {
|
||||
public static boolean seekbarTappingEnabled() {
|
||||
return SettingsEnum.SEEKBAR_TAPPING.getBoolean();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,54 @@
|
||||
package app.revanced.integrations.patches.components;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
final class ButtonsFilter extends Filter {
|
||||
private final StringFilterGroup actionBarRule;
|
||||
|
||||
public ButtonsFilter() {
|
||||
actionBarRule = new StringFilterGroup(
|
||||
null,
|
||||
"video_action_bar"
|
||||
);
|
||||
|
||||
pathFilterGroups.addAll(
|
||||
new StringFilterGroup(
|
||||
SettingsEnum.HIDE_LIKE_DISLIKE_BUTTON,
|
||||
"|like_button",
|
||||
"dislike_button"
|
||||
),
|
||||
new StringFilterGroup(
|
||||
SettingsEnum.HIDE_DOWNLOAD_BUTTON,
|
||||
"download_button"
|
||||
),
|
||||
new StringFilterGroup(
|
||||
SettingsEnum.HIDE_PLAYLIST_BUTTON,
|
||||
"save_to_playlist_button"
|
||||
),
|
||||
new StringFilterGroup(
|
||||
SettingsEnum.HIDE_CLIP_BUTTON,
|
||||
"|clip_button.eml|"
|
||||
),
|
||||
new StringFilterGroup(
|
||||
SettingsEnum.HIDE_ACTION_BUTTONS,
|
||||
"ContainerType|video_action_button",
|
||||
"|CellType|CollectionType|CellType|ContainerType|button.eml|"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private boolean isEveryFilterGroupEnabled() {
|
||||
for (StringFilterGroup rule : pathFilterGroups)
|
||||
if (!rule.isEnabled()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFiltered(final String path, final String identifier, final byte[] _protobufBufferArray) {
|
||||
if (isEveryFilterGroupEnabled())
|
||||
if (actionBarRule.check(identifier).isFiltered()) return true;
|
||||
|
||||
return super.isFiltered(path, identifier, _protobufBufferArray);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package app.revanced.integrations.patches.components;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
final class CommentsFilter extends Filter {
|
||||
|
||||
public CommentsFilter() {
|
||||
var comments = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_COMMENTS_SECTION,
|
||||
"video_metadata_carousel",
|
||||
"_comments"
|
||||
);
|
||||
|
||||
var previewComment = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_PREVIEW_COMMENT,
|
||||
"|carousel_item",
|
||||
"comments_entry_point_teaser",
|
||||
"comments_entry_point_simplebox"
|
||||
);
|
||||
|
||||
this.pathFilterGroups.addAll(
|
||||
comments,
|
||||
previewComment
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,100 @@
|
||||
package app.revanced.integrations.patches.components;
|
||||
|
||||
import static app.revanced.integrations.utils.ReVancedUtils.hideViewBy1dpUnderCondition;
|
||||
import static app.revanced.integrations.utils.ReVancedUtils.hideViewUnderCondition;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
|
||||
import com.google.android.libraries.youtube.rendering.ui.pivotbar.PivotBar;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public final class ShortsFilter extends Filter {
|
||||
public static PivotBar pivotBar;
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
|
||||
private final StringFilterGroup reelChannelBar = new StringFilterGroup(
|
||||
null,
|
||||
"reel_channel_bar"
|
||||
);
|
||||
|
||||
private final StringFilterGroup infoPanel = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS_INFO_PANEL,
|
||||
"shorts_info_panel_overview"
|
||||
);
|
||||
|
||||
public ShortsFilter() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return;
|
||||
|
||||
final var thanksButton = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS_THANKS_BUTTON,
|
||||
"suggested_action"
|
||||
);
|
||||
|
||||
final var subscribeButton = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS_SUBSCRIBE_BUTTON,
|
||||
"subscribe_button"
|
||||
);
|
||||
|
||||
final var joinButton = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS_JOIN_BUTTON,
|
||||
"sponsor_button"
|
||||
);
|
||||
|
||||
final var shorts = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS,
|
||||
"shorts_shelf",
|
||||
"inline_shorts",
|
||||
"shorts_grid"
|
||||
);
|
||||
|
||||
this.pathFilterGroups.addAll(joinButton, subscribeButton);
|
||||
this.identifierFilterGroups.addAll(shorts, thanksButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(final String path, final String identifier, final byte[] protobufBufferArray) {
|
||||
// Filter the path only when reelChannelBar is visible.
|
||||
if (reelChannelBar.check(path).isFiltered())
|
||||
if (this.pathFilterGroups.contains(path)) return true;
|
||||
|
||||
// Shorts info panel path appears outside of reelChannelBar path.
|
||||
if (infoPanel.isEnabled() && infoPanel.check(path).isFiltered()) return true;
|
||||
|
||||
return this.identifierFilterGroups.contains(identifier);
|
||||
}
|
||||
|
||||
public static void hideShortsShelf(final View shortsShelfView) {
|
||||
hideViewBy1dpUnderCondition(SettingsEnum.HIDE_SHORTS, shortsShelfView);
|
||||
}
|
||||
|
||||
// Additional components that have to be hidden by setting their visibility
|
||||
|
||||
public static void hideShortsCommentsButton(final View commentsButtonView) {
|
||||
hideViewUnderCondition(SettingsEnum.HIDE_SHORTS_COMMENTS_BUTTON, commentsButtonView);
|
||||
}
|
||||
|
||||
public static void hideShortsRemixButton(final View remixButtonView) {
|
||||
hideViewUnderCondition(SettingsEnum.HIDE_SHORTS_REMIX_BUTTON, remixButtonView);
|
||||
}
|
||||
|
||||
public static void hideShortsShareButton(final View shareButtonView) {
|
||||
hideViewUnderCondition(SettingsEnum.HIDE_SHORTS_SHARE_BUTTON, shareButtonView);
|
||||
}
|
||||
|
||||
public static void hideNavigationBar() {
|
||||
if (!SettingsEnum.HIDE_SHORTS_NAVIGATION_BAR.getBoolean()) return;
|
||||
if (pivotBar == null) return;
|
||||
|
||||
pivotBar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
public static View hideNavigationBar(final View navigationBarView) {
|
||||
if (SettingsEnum.HIDE_SHORTS_NAVIGATION_BAR.getBoolean())
|
||||
return null; // Hides the navigation bar.
|
||||
|
||||
return navigationBarView;
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ public class ProgressBarDrawable extends Drawable {
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
if (SettingsEnum.HIDE_SEEKBAR.getBoolean()) {
|
||||
if (SettingsEnum.HIDE_SEEKBAR_THUMBNAIL.getBoolean()) {
|
||||
return;
|
||||
}
|
||||
paint.setColor(SeekbarColorPatch.getCustomSeekbarColor());
|
||||
|
||||
@@ -51,12 +51,31 @@ public final class SeekbarColorPatch {
|
||||
return customSeekbarColor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*
|
||||
* Overrides color when seekbar is clicked, and all Litho components that use the YouTube seekbar color.
|
||||
* Overrides all Litho components that use the YouTube seekbar color.
|
||||
* Used only for the video thumbnails seekbar.
|
||||
*
|
||||
* If {@link SettingsEnum#HIDE_SEEKBAR_THUMBNAIL} is enabled, this returns a fully transparent color.
|
||||
*/
|
||||
public static int getSeekbarColorOverride(int colorValue) {
|
||||
public static int getLithoColor(int colorValue) {
|
||||
if (colorValue == ORIGINAL_SEEKBAR_COLOR) {
|
||||
if (SettingsEnum.HIDE_SEEKBAR_THUMBNAIL.getBoolean()) {
|
||||
return 0x00000000;
|
||||
}
|
||||
return getSeekbarColorValue(ORIGINAL_SEEKBAR_COLOR);
|
||||
}
|
||||
return colorValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*
|
||||
* Overrides color when video player seekbar is clicked.
|
||||
*/
|
||||
public static int getVideoPlayerSeekbarClickedColor(int colorValue) {
|
||||
return colorValue == ORIGINAL_SEEKBAR_COLOR
|
||||
? getSeekbarColorValue(ORIGINAL_SEEKBAR_COLOR)
|
||||
: colorValue;
|
||||
@@ -65,18 +84,20 @@ public final class SeekbarColorPatch {
|
||||
/**
|
||||
* Injection point.
|
||||
*
|
||||
* If {@link SettingsEnum#HIDE_SEEKBAR} is enabled, this returns a fully transparent color.
|
||||
*
|
||||
* Otherwise the original color is changed to the custom seekbar color, while retaining
|
||||
* Overrides color used for the video player seekbar.
|
||||
*/
|
||||
public static int getVideoPlayerSeekbarColor(int originalColor) {
|
||||
return getSeekbarColorValue(originalColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Color parameter is changed to the custom seekbar color, while retaining
|
||||
* the brightness and alpha changes of the parameter value compared to the original seekbar color.
|
||||
*/
|
||||
public static int getSeekbarColorValue(int originalColor) {
|
||||
private static int getSeekbarColorValue(int originalColor) {
|
||||
try {
|
||||
if (SettingsEnum.HIDE_SEEKBAR.getBoolean()) {
|
||||
return 0x00000000;
|
||||
}
|
||||
if (customSeekbarColor == ORIGINAL_SEEKBAR_COLOR) {
|
||||
return originalColor; // Nothing to do
|
||||
return originalColor; // nothing to do
|
||||
}
|
||||
final int alphaDifference = Color.alpha(originalColor) - Color.alpha(ORIGINAL_SEEKBAR_COLOR);
|
||||
|
||||
|
||||
@@ -239,12 +239,6 @@ public class ReturnYouTubeDislike {
|
||||
public static void newVideoLoaded(@NonNull String videoId) {
|
||||
Objects.requireNonNull(videoId);
|
||||
|
||||
PlayerType currentPlayerType = PlayerType.getCurrent();
|
||||
if (currentPlayerType == PlayerType.INLINE_MINIMAL) {
|
||||
LogHelper.printDebug(() -> "Ignoring inline playback of video: " + videoId);
|
||||
setCurrentVideoId(null);
|
||||
return;
|
||||
}
|
||||
synchronized (videoIdLockObject) {
|
||||
if (videoId.equals(currentVideoId)) {
|
||||
return; // already loaded
|
||||
@@ -254,13 +248,14 @@ public class ReturnYouTubeDislike {
|
||||
setCurrentVideoId(null);
|
||||
return;
|
||||
}
|
||||
PlayerType currentPlayerType = PlayerType.getCurrent();
|
||||
LogHelper.printDebug(() -> "New video loaded: " + videoId + " playerType: " + currentPlayerType);
|
||||
setCurrentVideoId(videoId);
|
||||
|
||||
// If a Short is opened while a regular video is on screen, this will incorrectly set this as false.
|
||||
// But this check is needed to fix unusual situations of opening/closing the app
|
||||
// while both a regular video and a short are on screen.
|
||||
dislikeDataIsShort = PlayerType.getCurrent().isNoneHiddenOrMinimized();
|
||||
dislikeDataIsShort = currentPlayerType.isNoneHiddenOrMinimized();
|
||||
|
||||
RYDCachedFetch entry = futureCache.get(videoId);
|
||||
if (entry != null && entry.futureInProgressOrFinishedSuccessfully()) {
|
||||
|
||||
@@ -16,6 +16,11 @@ import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.integrations.sponsorblock.SponsorBlockSettings;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
import app.revanced.integrations.utils.StringRef;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@@ -24,19 +29,15 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import app.revanced.integrations.sponsorblock.SponsorBlockSettings;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
import app.revanced.integrations.utils.StringRef;
|
||||
|
||||
public enum SettingsEnum {
|
||||
// External downloader
|
||||
EXTERNAL_DOWNLOADER("revanced_external_downloader", BOOLEAN, TRUE),
|
||||
EXTERNAL_DOWNLOADER("revanced_external_downloader", BOOLEAN, FALSE),
|
||||
EXTERNAL_DOWNLOADER_PACKAGE_NAME("revanced_external_downloader_name", STRING,
|
||||
"org.schabi.newpipe" /* NewPipe */, parents(EXTERNAL_DOWNLOADER)),
|
||||
|
||||
// Copy video URL
|
||||
COPY_VIDEO_URL("revanced_copy_video_url", BOOLEAN, TRUE),
|
||||
COPY_VIDEO_URL("revanced_copy_video_url", BOOLEAN, FALSE),
|
||||
COPY_VIDEO_URL_TIMESTAMP("revanced_copy_video_url_timestamp", BOOLEAN, TRUE),
|
||||
|
||||
// Video
|
||||
@@ -82,7 +83,6 @@ public enum SettingsEnum {
|
||||
HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES("revanced_hide_subscribers_community_guidelines", BOOLEAN, TRUE),
|
||||
HIDE_PRODUCTS_BANNER("revanced_hide_products_banner", BOOLEAN, TRUE),
|
||||
HIDE_WEB_SEARCH_RESULTS("revanced_hide_web_search_results", BOOLEAN, TRUE),
|
||||
HIDE_SHORTS("revanced_hide_shorts", BOOLEAN, TRUE, true),
|
||||
HIDE_QUICK_ACTIONS("revanced_hide_quick_actions", BOOLEAN, FALSE),
|
||||
HIDE_RELATED_VIDEOS("revanced_hide_related_videos", BOOLEAN, FALSE),
|
||||
|
||||
@@ -116,10 +116,10 @@ public enum SettingsEnum {
|
||||
HIDE_PLAYER_OVERLAY("revanced_hide_player_overlay", BOOLEAN, FALSE, true),
|
||||
HIDE_PREVIEW_COMMENT("revanced_hide_preview_comment", BOOLEAN, FALSE, true),
|
||||
HIDE_SEEKBAR("revanced_hide_seekbar", BOOLEAN, FALSE, true),
|
||||
HIDE_SEEKBAR_THUMBNAIL("revanced_hide_seekbar_thumbnail", BOOLEAN, FALSE, true),
|
||||
HIDE_HOME_BUTTON("revanced_hide_home_button", BOOLEAN, FALSE, true),
|
||||
HIDE_SHORTS_BUTTON("revanced_hide_shorts_button", BOOLEAN, TRUE, true),
|
||||
HIDE_SUBSCRIPTIONS_BUTTON("revanced_hide_subscriptions_button", BOOLEAN, FALSE, true),
|
||||
HIDE_SHORTS_COMMENTS_BUTTON("revanced_hide_shorts_comments_button", BOOLEAN, FALSE),
|
||||
HIDE_TIMESTAMP("revanced_hide_timestamp", BOOLEAN, FALSE),
|
||||
HIDE_VIDEO_WATERMARK("revanced_hide_video_watermark", BOOLEAN, TRUE),
|
||||
HIDE_WATCH_IN_VR("revanced_hide_watch_in_vr", BOOLEAN, FALSE, true),
|
||||
@@ -133,13 +133,22 @@ public enum SettingsEnum {
|
||||
HIDE_FILTER_BAR_FEED_IN_FEED("revanced_hide_filter_bar_feed_in_feed", BOOLEAN, FALSE, true),
|
||||
HIDE_FILTER_BAR_FEED_IN_SEARCH("revanced_hide_filter_bar_feed_in_search", BOOLEAN, FALSE, true),
|
||||
HIDE_FILTER_BAR_FEED_IN_RELATED_VIDEOS("revanced_hide_filter_bar_feed_in_related_videos", BOOLEAN, FALSE, true),
|
||||
HIDE_SHORTS_JOIN_BUTTON("revanced_hide_shorts_join_button", BOOLEAN, TRUE),
|
||||
HIDE_SHORTS_SUBSCRIBE_BUTTON("revanced_hide_shorts_subscribe_button", BOOLEAN, FALSE),
|
||||
HIDE_SHORTS_THANKS_BUTTON("revanced_hide_shorts_thanks_button", BOOLEAN, TRUE),
|
||||
HIDE_SHORTS_COMMENTS_BUTTON("revanced_hide_shorts_comments_button", BOOLEAN, FALSE),
|
||||
HIDE_SHORTS_REMIX_BUTTON("revanced_hide_shorts_remix_button", BOOLEAN, TRUE),
|
||||
HIDE_SHORTS_SHARE_BUTTON("revanced_hide_shorts_share_button", BOOLEAN, FALSE),
|
||||
HIDE_SHORTS_INFO_PANEL("revanced_hide_shorts_info_panel", BOOLEAN, TRUE),
|
||||
HIDE_SHORTS_NAVIGATION_BAR("revanced_hide_shorts_navigation_bar", BOOLEAN, TRUE, true),
|
||||
HIDE_SHORTS("revanced_hide_shorts", BOOLEAN, FALSE, true),
|
||||
|
||||
// Misc
|
||||
AUTO_CAPTIONS("revanced_auto_captions", BOOLEAN, FALSE),
|
||||
DISABLE_ZOOM_HAPTICS("revanced_disable_zoom_haptics", BOOLEAN, TRUE),
|
||||
EXTERNAL_BROWSER("revanced_external_browser", BOOLEAN, TRUE, true),
|
||||
AUTO_REPEAT("revanced_auto_repeat", BOOLEAN, FALSE),
|
||||
TAP_SEEKING("revanced_tap_seeking", BOOLEAN, TRUE),
|
||||
SEEKBAR_TAPPING("revanced_seekbar_tapping", BOOLEAN, TRUE),
|
||||
SPOOF_SIGNATURE_VERIFICATION("revanced_spoof_signature_verification", BOOLEAN, TRUE, "revanced_spoof_signature_verification_user_dialog_message"),
|
||||
|
||||
// Swipe controls
|
||||
@@ -343,7 +352,7 @@ public enum SettingsEnum {
|
||||
// TODO END
|
||||
//
|
||||
|
||||
private static SettingsEnum[] parents(SettingsEnum ... parents) {
|
||||
private static SettingsEnum[] parents(SettingsEnum... parents) {
|
||||
return parents;
|
||||
}
|
||||
|
||||
@@ -386,26 +395,32 @@ public enum SettingsEnum {
|
||||
SettingsEnum(String path, ReturnType returnType, Object defaultValue) {
|
||||
this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, false, null, null);
|
||||
}
|
||||
|
||||
SettingsEnum(String path, ReturnType returnType, Object defaultValue,
|
||||
boolean rebootApp) {
|
||||
this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, null,null);
|
||||
this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, null, null);
|
||||
}
|
||||
|
||||
SettingsEnum(String path, ReturnType returnType, Object defaultValue,
|
||||
String userDialogMessage) {
|
||||
this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, false, userDialogMessage, null);
|
||||
}
|
||||
|
||||
SettingsEnum(String path, ReturnType returnType, Object defaultValue,
|
||||
SettingsEnum[] parents) {
|
||||
this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, false, null, parents);
|
||||
}
|
||||
|
||||
SettingsEnum(String path, ReturnType returnType, Object defaultValue,
|
||||
boolean rebootApp, String userDialogMessage) {
|
||||
this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, userDialogMessage, null);
|
||||
}
|
||||
|
||||
SettingsEnum(String path, ReturnType returnType, Object defaultValue,
|
||||
boolean rebootApp, SettingsEnum[] parents) {
|
||||
this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, null, parents);
|
||||
}
|
||||
|
||||
SettingsEnum(String path, ReturnType returnType, Object defaultValue,
|
||||
boolean rebootApp, String userDialogMessage, SettingsEnum[] parents) {
|
||||
this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, userDialogMessage, parents);
|
||||
@@ -414,20 +429,24 @@ public enum SettingsEnum {
|
||||
SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName) {
|
||||
this(path, returnType, defaultValue, prefName, false, null, null);
|
||||
}
|
||||
|
||||
SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName,
|
||||
boolean rebootApp) {
|
||||
this(path, returnType, defaultValue, prefName, rebootApp, null, null);
|
||||
}
|
||||
|
||||
SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName,
|
||||
String userDialogMessage) {
|
||||
this(path, returnType, defaultValue, prefName, false, userDialogMessage, null);
|
||||
}
|
||||
|
||||
SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName,
|
||||
SettingsEnum[] parents) {
|
||||
this(path, returnType, defaultValue, prefName, false, null, parents);
|
||||
}
|
||||
|
||||
SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName,
|
||||
boolean rebootApp, @Nullable String userDialogMessage, @Nullable SettingsEnum[] parents) {
|
||||
boolean rebootApp, @Nullable String userDialogMessage, @Nullable SettingsEnum[] parents) {
|
||||
this.path = Objects.requireNonNull(path);
|
||||
this.returnType = Objects.requireNonNull(returnType);
|
||||
this.value = this.defaultValue = Objects.requireNonNull(defaultValue);
|
||||
@@ -536,7 +555,7 @@ public enum SettingsEnum {
|
||||
|
||||
{DEPRECATED_EXTERNAL_BROWSER, EXTERNAL_BROWSER},
|
||||
{DEPRECATED_AUTO_REPEAT, AUTO_REPEAT},
|
||||
{DEPRECATED_TAP_SEEKING, TAP_SEEKING},
|
||||
{DEPRECATED_TAP_SEEKING, SEEKBAR_TAPPING},
|
||||
{DEPRECATED_HDR_AUTO_BRIGHTNESS, HDR_AUTO_BRIGHTNESS},
|
||||
|
||||
{DEPRECATED_RYD_USER_ID, RYD_USER_ID},
|
||||
@@ -599,10 +618,10 @@ public enum SettingsEnum {
|
||||
|
||||
/**
|
||||
* Sets, but does _not_ persistently save the value.
|
||||
*
|
||||
* <p>
|
||||
* This intentionally is a static method, to deter accidental usage
|
||||
* when {@link #saveValue(Object)} was intended.
|
||||
*
|
||||
* <p>
|
||||
* This method is only to be used by the Settings preference code.
|
||||
*/
|
||||
public static void setValue(@NonNull SettingsEnum setting, @NonNull String newValue) {
|
||||
@@ -627,6 +646,7 @@ public enum SettingsEnum {
|
||||
throw new IllegalStateException(setting.name());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only to be used by the Settings preference code.
|
||||
*/
|
||||
@@ -664,7 +684,7 @@ public enum SettingsEnum {
|
||||
|
||||
/**
|
||||
* @return if this setting can be configured and used.
|
||||
*
|
||||
* <p>
|
||||
* Not to be confused with {@link #getBoolean()}
|
||||
*/
|
||||
public boolean isAvailable() {
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package app.revanced.integrations.settingsmenu;
|
||||
|
||||
import static app.revanced.integrations.utils.ReVancedUtils.getChildView;
|
||||
import static app.revanced.integrations.utils.ReVancedUtils.getResourceIdentifier;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.libraries.social.licenses.LicenseActivity;
|
||||
import java.util.Objects;
|
||||
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
import app.revanced.integrations.utils.ThemeHelper;
|
||||
|
||||
public class ReVancedSettingActivity {
|
||||
@@ -19,76 +20,68 @@ public class ReVancedSettingActivity {
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void setTheme(LicenseActivity base) {
|
||||
final var whiteTheme = "Theme.YouTube.Settings";
|
||||
final var darkTheme = "Theme.YouTube.Settings.Dark";
|
||||
|
||||
final var theme = ThemeHelper.isDarkTheme() ? darkTheme : whiteTheme;
|
||||
|
||||
LogHelper.printDebug(() -> "Using theme: " + theme);
|
||||
base.setTheme(ReVancedUtils.getResourceIdentifier(theme, "style"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void initializeSettings(LicenseActivity base) {
|
||||
base.setContentView(ReVancedUtils.getResourceIdentifier("revanced_settings_with_toolbar", "layout"));
|
||||
|
||||
PreferenceFragment preferenceFragment;
|
||||
String preferenceIdentifier;
|
||||
|
||||
String dataString = base.getIntent().getDataString();
|
||||
if (dataString.equalsIgnoreCase("sponsorblock_settings")) {
|
||||
preferenceIdentifier = "sb_settings";
|
||||
preferenceFragment = new SponsorBlockSettingsFragment();
|
||||
} else if (dataString.equalsIgnoreCase("ryd_settings")) {
|
||||
preferenceIdentifier = "revanced_ryd_settings_title";
|
||||
preferenceFragment = new ReturnYouTubeDislikeSettingsFragment();
|
||||
} else {
|
||||
preferenceIdentifier = "revanced_settings";
|
||||
preferenceFragment = new ReVancedSettingsFragment();
|
||||
}
|
||||
|
||||
public static void initializeSettings(Activity licenseActivity) {
|
||||
try {
|
||||
TextView toolbar = getTextView((ViewGroup) base.findViewById(ReVancedUtils.getResourceIdentifier("toolbar", "id")));
|
||||
if (toolbar == null) {
|
||||
// FIXME
|
||||
// https://github.com/revanced/revanced-patches/issues/1384
|
||||
LogHelper.printDebug(() -> "Could not find toolbar");
|
||||
} else {
|
||||
toolbar.setText(preferenceIdentifier);
|
||||
ThemeHelper.setActivityTheme(licenseActivity);
|
||||
licenseActivity.setContentView(
|
||||
getResourceIdentifier("revanced_settings_with_toolbar", "layout"));
|
||||
setBackButton(licenseActivity);
|
||||
|
||||
PreferenceFragment fragment;
|
||||
String toolbarTitleResourceName;
|
||||
String dataString = licenseActivity.getIntent().getDataString();
|
||||
switch (dataString) {
|
||||
case "sponsorblock_settings":
|
||||
toolbarTitleResourceName = "revanced_sponsorblock_settings_title";
|
||||
fragment = new SponsorBlockSettingsFragment();
|
||||
break;
|
||||
case "ryd_settings":
|
||||
toolbarTitleResourceName = "revanced_ryd_settings_title";
|
||||
fragment = new ReturnYouTubeDislikeSettingsFragment();
|
||||
break;
|
||||
case "revanced_settings":
|
||||
toolbarTitleResourceName = "revanced_settings_title";
|
||||
fragment = new ReVancedSettingsFragment();
|
||||
break;
|
||||
default:
|
||||
LogHelper.printException(() -> "Unknown setting: " + dataString);
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogHelper.printException(() -> "Could not set Toolbar title", e);
|
||||
|
||||
setToolbarTitle(licenseActivity, toolbarTitleResourceName);
|
||||
licenseActivity.getFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(getResourceIdentifier("revanced_settings_fragments", "id"), fragment)
|
||||
.commit();
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "onCreate failure", ex);
|
||||
}
|
||||
|
||||
base.getFragmentManager().beginTransaction().replace(ReVancedUtils.getResourceIdentifier("revanced_settings_fragments", "id"), preferenceFragment).commit();
|
||||
}
|
||||
|
||||
private static void setToolbarTitle(Activity activity, String toolbarTitleResourceName) {
|
||||
ViewGroup toolbar = activity.findViewById(getToolbarResourceId());
|
||||
TextView toolbarTextView = Objects.requireNonNull(getChildView(toolbar, view -> view instanceof TextView));
|
||||
toolbarTextView.setText(getResourceIdentifier(toolbarTitleResourceName, "string"));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static <T extends View> T getView(Class<T> typeClass, ViewGroup viewGroup) {
|
||||
if (viewGroup == null) {
|
||||
return null;
|
||||
@SuppressLint("UseCompatLoadingForDrawables")
|
||||
private static void setBackButton(Activity activity) {
|
||||
ViewGroup toolbar = activity.findViewById(getToolbarResourceId());
|
||||
ImageButton imageButton = Objects.requireNonNull(getChildView(toolbar, view -> view instanceof ImageButton));
|
||||
final int backButtonResource = getResourceIdentifier(ThemeHelper.isDarkTheme()
|
||||
? "yt_outline_arrow_left_white_24"
|
||||
: "yt_outline_arrow_left_black_24",
|
||||
"drawable");
|
||||
imageButton.setImageDrawable(activity.getResources().getDrawable(backButtonResource));
|
||||
imageButton.setOnClickListener(view -> activity.onBackPressed());
|
||||
}
|
||||
|
||||
private static int getToolbarResourceId() {
|
||||
final int toolbarResourceId = getResourceIdentifier("revanced_toolbar", "id");
|
||||
if (toolbarResourceId == 0) {
|
||||
throw new IllegalStateException("Could not find back button resource");
|
||||
}
|
||||
int childCount = viewGroup.getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View childAt = viewGroup.getChildAt(i);
|
||||
if (childAt.getClass() == typeClass) {
|
||||
return (T) childAt;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return toolbarResourceId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ImageButton getImageButton(ViewGroup viewGroup) {
|
||||
return getView(ImageButton.class, viewGroup);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextView getTextView(ViewGroup viewGroup) {
|
||||
return getView(TextView.class, viewGroup);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,11 @@
|
||||
package app.revanced.integrations.sponsorblock;
|
||||
|
||||
import static app.revanced.integrations.utils.StringRef.str;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import app.revanced.integrations.patches.VideoInformation;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.shared.PlayerType;
|
||||
@@ -29,6 +18,11 @@ import app.revanced.integrations.sponsorblock.ui.SponsorBlockViewController;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
import static app.revanced.integrations.utils.StringRef.str;
|
||||
|
||||
/**
|
||||
* Handles showing, scheduling, and skipping of all {@link SponsorSegment} for the current video.
|
||||
*
|
||||
@@ -619,10 +613,7 @@ public class SegmentPlaybackController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void setSponsorBarAbsoluteLeft(Rect rect) {
|
||||
private static void setSponsorBarAbsoluteLeft(Rect rect) {
|
||||
final int left = rect.left;
|
||||
if (sponsorBarAbsoluteLeft != left) {
|
||||
LogHelper.printDebug(() -> "setSponsorBarAbsoluteLeft: " + left);
|
||||
@@ -630,10 +621,7 @@ public class SegmentPlaybackController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void setSponsorBarAbsoluteRight(Rect rect) {
|
||||
private static void setSponsorBarAbsoluteRight(Rect rect) {
|
||||
final int right = rect.right;
|
||||
if (sponsorAbsoluteBarRight != right) {
|
||||
LogHelper.printDebug(() -> "setSponsorBarAbsoluteRight: " + right);
|
||||
|
||||
@@ -10,7 +10,11 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.*;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.Toast;
|
||||
import android.widget.Toolbar;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -24,6 +28,8 @@ import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class ReVancedUtils {
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
@@ -32,6 +38,35 @@ public class ReVancedUtils {
|
||||
private ReVancedUtils() {
|
||||
} // utility class
|
||||
|
||||
/**
|
||||
* Hide a view by setting its layout height and width to 1dp.
|
||||
*
|
||||
* @param condition The setting to check for hiding the view.
|
||||
* @param view The view to hide.
|
||||
*/
|
||||
public static void hideViewBy1dpUnderCondition(SettingsEnum condition, View view) {
|
||||
if (!condition.getBoolean()) return;
|
||||
|
||||
LogHelper.printDebug(() -> "Hiding view with setting: " + condition);
|
||||
|
||||
hideViewByLayoutParams(view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide a view by setting its visibility to GONE.
|
||||
*
|
||||
* @param condition The setting to check for hiding the view.
|
||||
* @param view The view to hide.
|
||||
*/
|
||||
public static void hideViewUnderCondition(SettingsEnum condition, View view) {
|
||||
if (!condition.getBoolean()) return;
|
||||
|
||||
LogHelper.printDebug(() -> "Hiding view with setting: " + condition);
|
||||
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* General purpose pool for network calls and other background tasks.
|
||||
* All tasks run at max thread priority.
|
||||
@@ -99,6 +134,24 @@ public class ReVancedUtils {
|
||||
return getContext().getResources().getDimension(getResourceIdentifier(resourceIdentifierName, "dimen"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The first child view that matches the filter.
|
||||
*/
|
||||
@Nullable
|
||||
public static <T extends View> T getChildView(@NonNull ViewGroup viewGroup, @NonNull MatchFilter filter) {
|
||||
for (int i = 0, childCount = viewGroup.getChildCount(); i < childCount; i++) {
|
||||
View childAt = viewGroup.getChildAt(i);
|
||||
if (filter.matches(childAt)) {
|
||||
return (T) childAt;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public interface MatchFilter<T> {
|
||||
boolean matches(T object);
|
||||
}
|
||||
|
||||
public static Context getContext() {
|
||||
if (context != null) {
|
||||
return context;
|
||||
@@ -119,6 +172,7 @@ public class ReVancedUtils {
|
||||
|
||||
@Nullable
|
||||
private static Boolean isRightToLeftTextLayout;
|
||||
|
||||
/**
|
||||
* If the device language uses right to left text layout (hebrew, arabic, etc)
|
||||
*/
|
||||
@@ -245,7 +299,7 @@ public class ReVancedUtils {
|
||||
* Hide a view by setting its layout params to 1x1
|
||||
* @param view The view to hide.
|
||||
*/
|
||||
public static void HideViewByLayoutParams(View view) {
|
||||
public static void hideViewByLayoutParams(View view) {
|
||||
if (view instanceof LinearLayout) {
|
||||
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(1, 1);
|
||||
view.setLayoutParams(layoutParams);
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
package app.revanced.integrations.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
public class ThemeHelper {
|
||||
private static int themeValue;
|
||||
|
||||
public static void setTheme(int value) {
|
||||
if (themeValue != value) {
|
||||
themeValue = value;
|
||||
LogHelper.printDebug(() -> "Theme value: " + themeValue);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setTheme(Object value) {
|
||||
final int newOrdinalValue = ((Enum) value).ordinal();
|
||||
if (themeValue != newOrdinalValue) {
|
||||
themeValue = newOrdinalValue;
|
||||
LogHelper.printDebug(() -> "Theme value: " + themeValue);
|
||||
LogHelper.printDebug(() -> "Theme value: " + newOrdinalValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,4 +17,11 @@ public class ThemeHelper {
|
||||
return themeValue == 1;
|
||||
}
|
||||
|
||||
public static void setActivityTheme(Activity activity) {
|
||||
final var theme = isDarkTheme()
|
||||
? "Theme.YouTube.Settings.Dark"
|
||||
: "Theme.YouTube.Settings";
|
||||
activity.setTheme(ReVancedUtils.getResourceIdentifier(theme, "style"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,14 +4,17 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
public abstract class BottomControlButton {
|
||||
private static final Animation fadeIn;
|
||||
private static final Animation fadeOut;
|
||||
@@ -40,7 +43,8 @@ public abstract class BottomControlButton {
|
||||
}
|
||||
|
||||
public BottomControlButton(@NonNull ViewGroup bottomControlsViewGroup, @NonNull String imageViewButtonId,
|
||||
@NonNull SettingsEnum booleanSetting, @NonNull View.OnClickListener onClickListener) {
|
||||
@NonNull SettingsEnum booleanSetting, @NonNull View.OnClickListener onClickListener,
|
||||
@Nullable View.OnLongClickListener longClickListener) {
|
||||
LogHelper.printDebug(() -> "Initializing button: " + imageViewButtonId);
|
||||
|
||||
if (booleanSetting.returnType != SettingsEnum.ReturnType.BOOLEAN) {
|
||||
@@ -53,6 +57,9 @@ public abstract class BottomControlButton {
|
||||
ReVancedUtils.getResourceIdentifier(imageViewButtonId, "id")
|
||||
));
|
||||
imageView.setOnClickListener(onClickListener);
|
||||
if (longClickListener != null) {
|
||||
imageView.setOnLongClickListener(longClickListener);
|
||||
}
|
||||
imageView.setVisibility(View.GONE);
|
||||
|
||||
buttonRef = new WeakReference<>(imageView);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package app.revanced.integrations.videoplayer;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -17,16 +18,20 @@ public class CopyVideoUrlButton extends BottomControlButton {
|
||||
viewGroup,
|
||||
"copy_video_url_button",
|
||||
SettingsEnum.COPY_VIDEO_URL,
|
||||
view -> CopyVideoUrlPatch.copyUrl(false)
|
||||
view -> CopyVideoUrlPatch.copyUrl(false),
|
||||
view -> {
|
||||
CopyVideoUrlPatch.copyUrl(true);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void initializeButton(Object obj) {
|
||||
public static void initializeButton(View view) {
|
||||
try {
|
||||
instance = new CopyVideoUrlButton((ViewGroup) obj);
|
||||
instance = new CopyVideoUrlButton((ViewGroup) view);
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "initializeButton failure", ex);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package app.revanced.integrations.videoplayer;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -17,14 +18,18 @@ public class CopyVideoUrlTimestampButton extends BottomControlButton {
|
||||
bottomControlsViewGroup,
|
||||
"copy_video_url_timestamp_button",
|
||||
SettingsEnum.COPY_VIDEO_URL_TIMESTAMP,
|
||||
view -> CopyVideoUrlPatch.copyUrl(true)
|
||||
view -> CopyVideoUrlPatch.copyUrl(true),
|
||||
view -> {
|
||||
CopyVideoUrlPatch.copyUrl(false);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void initializeButton(Object bottomControlsViewGroup) {
|
||||
public static void initializeButton(View bottomControlsViewGroup) {
|
||||
try {
|
||||
instance = new CopyVideoUrlTimestampButton((ViewGroup) bottomControlsViewGroup);
|
||||
} catch (Exception ex) {
|
||||
|
||||
@@ -13,25 +13,26 @@ import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
import app.revanced.integrations.utils.StringRef;
|
||||
|
||||
public class DownloadButton extends BottomControlButton {
|
||||
public class ExternalDownloadButton extends BottomControlButton {
|
||||
@Nullable
|
||||
private static DownloadButton instance;
|
||||
private static ExternalDownloadButton instance;
|
||||
|
||||
public DownloadButton(ViewGroup viewGroup) {
|
||||
public ExternalDownloadButton(ViewGroup viewGroup) {
|
||||
super(
|
||||
viewGroup,
|
||||
"download_button",
|
||||
"external_download_button",
|
||||
SettingsEnum.EXTERNAL_DOWNLOADER,
|
||||
DownloadButton::onDownloadClick
|
||||
ExternalDownloadButton::onDownloadClick,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static void initializeButton(Object obj) {
|
||||
public static void initializeButton(View view) {
|
||||
try {
|
||||
instance = new DownloadButton((ViewGroup) obj);
|
||||
instance = new ExternalDownloadButton((ViewGroup) view);
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "initializeButton failure", ex);
|
||||
}
|
||||
@@ -45,7 +46,7 @@ public class DownloadButton extends BottomControlButton {
|
||||
}
|
||||
|
||||
private static void onDownloadClick(View view) {
|
||||
LogHelper.printDebug(() -> "Download button clicked");
|
||||
LogHelper.printDebug(() -> "External download button clicked");
|
||||
|
||||
final var context = view.getContext();
|
||||
var downloaderPackageName = SettingsEnum.EXTERNAL_DOWNLOADER_PACKAGE_NAME.getString();
|
||||
@@ -54,12 +55,12 @@ public class DownloadButton extends BottomControlButton {
|
||||
try {
|
||||
packageEnabled = context.getPackageManager().getApplicationInfo(downloaderPackageName, 0).enabled;
|
||||
} catch (PackageManager.NameNotFoundException error) {
|
||||
LogHelper.printDebug(() -> "Downloader could not be found: " + error);
|
||||
LogHelper.printDebug(() -> "External downloader could not be found: " + error);
|
||||
}
|
||||
|
||||
// If the package is not installed, show the toast
|
||||
if (!packageEnabled) {
|
||||
ReVancedUtils.showToastLong(downloaderPackageName + " " + StringRef.str("downloader_not_installed_warning"));
|
||||
ReVancedUtils.showToastLong(downloaderPackageName + " " + StringRef.str("external_downloader_not_installed_warning"));
|
||||
return;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user