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
115 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
878ac2a9fa | ||
|
|
b663880741 | ||
|
|
9ab8a646ed | ||
|
|
2002bf8063 | ||
|
|
693ef08c6c | ||
|
|
84377b2da4 | ||
|
|
71e81a6473 | ||
|
|
5839f6ca4a | ||
|
|
d125d20974 | ||
|
|
5dd68e23f8 | ||
|
|
98ce2df47d | ||
|
|
0a6022c258 | ||
|
|
a550d16c3f | ||
|
|
04a89af1c9 | ||
|
|
bf368e8dd4 | ||
|
|
4afa162f46 | ||
|
|
66f5808863 | ||
|
|
57c56b630a | ||
|
|
edaf70fd10 | ||
|
|
c309646d35 | ||
|
|
934b981605 | ||
|
|
57969661dd | ||
|
|
376168fecf | ||
|
|
e8342ec15b | ||
|
|
d64a0f9599 | ||
|
|
b93b03dc19 | ||
|
|
a098594706 | ||
|
|
8805851a09 | ||
|
|
a9d24872a8 | ||
|
|
080e22b1bf | ||
|
|
5a028ab834 | ||
|
|
7840bc48ba | ||
|
|
718c5a75c1 | ||
|
|
2f32786661 | ||
|
|
3a2536a86e | ||
|
|
37869dc5b8 | ||
|
|
9dc9ce364c | ||
|
|
00ea006b8c | ||
|
|
617a4eb5d0 | ||
|
|
1351358268 | ||
|
|
35aa4f92c6 | ||
|
|
bca96cc8b4 | ||
|
|
cea3a5edc7 | ||
|
|
44dfea907d | ||
|
|
b2eab33e02 | ||
|
|
a87e366035 | ||
|
|
d4a23ed5c9 | ||
|
|
767201ce05 | ||
|
|
64cfe9c579 | ||
|
|
25978ae4a4 | ||
|
|
1f48749958 | ||
|
|
ee1f895e87 | ||
|
|
645669bbc0 | ||
|
|
d4c3b74a9a | ||
|
|
24367cea3f | ||
|
|
1e3970c3f2 | ||
|
|
c3e88c79e9 | ||
|
|
b8f0e632c1 | ||
|
|
c0c778b3e6 | ||
|
|
fe74f6d8a6 | ||
|
|
5f1e35ae36 | ||
|
|
6ceff7c9b3 | ||
|
|
d9349d4e88 | ||
|
|
b59ee31d57 | ||
|
|
2c8b23426f | ||
|
|
72a3cd0fac | ||
|
|
6272e4b467 | ||
|
|
cf892de4bb | ||
|
|
e978ed2c14 | ||
|
|
570f9eaba1 | ||
|
|
571cf12dca | ||
|
|
09c7605f1f | ||
|
|
66040302a9 | ||
|
|
98b31c17b9 | ||
|
|
c517c03e6f | ||
|
|
f10b202c93 | ||
|
|
3fb337b856 | ||
|
|
d82b9898a8 | ||
|
|
0a90289dc5 | ||
|
|
dfd6e7fcce | ||
|
|
e93ce3eaa9 | ||
|
|
695c59efd4 | ||
|
|
22bc4405cf | ||
|
|
63ee425050 | ||
|
|
7f18520646 | ||
|
|
d18bc1856b | ||
|
|
af86dd8ec6 | ||
|
|
2ebadaf07f | ||
|
|
197f0034a1 | ||
|
|
06c5a9b2b8 | ||
|
|
cb404086ad | ||
|
|
18192ac73e | ||
|
|
e357ac664b | ||
|
|
2f2a595c89 | ||
|
|
502feaf444 | ||
|
|
b4e03412ee | ||
|
|
f8cb38e57a | ||
|
|
9e5e81875a | ||
|
|
c3c16563ea | ||
|
|
302b57d8f0 | ||
|
|
d86655874b | ||
|
|
cc2bab4e39 | ||
|
|
85971bcd5e | ||
|
|
f475c28f3d | ||
|
|
ac81695747 | ||
|
|
3427f885fb | ||
|
|
9bdac3356d | ||
|
|
fd69010def | ||
|
|
6aa0ca9556 | ||
|
|
98eaf9c3f2 | ||
|
|
8e36da0b19 | ||
|
|
1433b34c7e | ||
|
|
6da66be067 | ||
|
|
b5a93a0cd9 | ||
|
|
ac69b36773 |
21
.github/workflows/release.yml
vendored
21
.github/workflows/release.yml
vendored
@@ -15,25 +15,24 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/cancel-workflow-action@0.9.0
|
||||
with:
|
||||
access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Checkout Repo
|
||||
- name: Cancel previou runs
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up JDK 11
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '11'
|
||||
java-version: '17'
|
||||
distribution: 'zulu'
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "lts/*"
|
||||
node-version: "latest"
|
||||
cache: 'npm'
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew --no-daemon build
|
||||
run: ./gradlew build --no-daemon
|
||||
- name: Setup semantic-release
|
||||
run: npm install -g semantic-release @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D
|
||||
run: npm install semantic-release @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D
|
||||
- name: Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
304
CHANGELOG.md
304
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@@ -45,4 +45,7 @@ android {
|
||||
dependencies {
|
||||
compileOnly(project(mapOf("path" to ":dummy")))
|
||||
compileOnly("androidx.annotation:annotation:1.5.0")
|
||||
compileOnly("androidx.appcompat:appcompat:1.5.1")
|
||||
compileOnly("com.squareup.okhttp3:okhttp:4.10.0")
|
||||
compileOnly("com.squareup.retrofit2:retrofit:2.9.0")
|
||||
}
|
||||
|
||||
@@ -8,8 +8,6 @@ import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.Toolbar;
|
||||
|
||||
import app.revanced.integrations.patches.HideShortsButtonPatch;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
public class AdRemoverAPI {
|
||||
@@ -37,7 +35,7 @@ public class AdRemoverAPI {
|
||||
ViewGroup.LayoutParams layoutParams5 = new ViewGroup.LayoutParams(1, 1);
|
||||
view.setLayoutParams(layoutParams5);
|
||||
} else {
|
||||
LogHelper.debug(AdRemoverAPI.class, "HideViewWithLayout1dp - Id: " + view.getId() + " Type: " + view.getClass().getName());
|
||||
LogHelper.printDebug(() -> "HideViewWithLayout1dp - Id: " + view.getId() + " Type: " + view.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.adremover.AdRemoverAPI;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class BrandingWaterMarkPatch {
|
||||
|
||||
//Used by: app.revanced.patches.youtube.layout.watermark.patch.HideWatermarkPatch
|
||||
// Used by: app.revanced.patches.youtube.layout.watermark.patch.HideWatermarkPatch
|
||||
public static boolean isBrandingWatermarkShown() {
|
||||
return SettingsEnum.BRANDING_SHOWN.getBoolean();
|
||||
return SettingsEnum.HIDE_VIDEO_WATERMARK.getBoolean() == false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
private boolean hideActionBar() {
|
||||
for (BlockRule rule : rules) 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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,37 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import java.util.Timer;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
public final class FixPlaybackPatch {
|
||||
private static Thread currentThread = null;
|
||||
public static void newVideoLoaded(final String _videoId) {
|
||||
private static String videoId;
|
||||
|
||||
public static void newVideoLoaded(final String videoId) {
|
||||
if (!SettingsEnum.FIX_PLAYBACK.getBoolean()) return;
|
||||
|
||||
if (videoId.equals(FixPlaybackPatch.videoId)) return;
|
||||
else FixPlaybackPatch.videoId = videoId;
|
||||
|
||||
if (currentThread != null) {
|
||||
currentThread.interrupt();
|
||||
}
|
||||
|
||||
currentThread = new Thread(() -> {
|
||||
while (true) {
|
||||
var currentVideoLength = PlayerControllerPatch.getCurrentVideoLength();
|
||||
if (currentVideoLength > 1) {
|
||||
PlayerControllerPatch.seekTo(currentVideoLength);
|
||||
PlayerControllerPatch.seekTo(1);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
while (true) {
|
||||
var currentVideoTime = VideoInformation.getVideoTime();
|
||||
|
||||
try {
|
||||
Thread.sleep(200);
|
||||
} catch (InterruptedException e) {
|
||||
LogHelper.debug(FixPlaybackPatch.class, "Thread was interrupted");
|
||||
if (currentVideoTime > -1) {
|
||||
VideoInformation.seekTo(Integer.MAX_VALUE);
|
||||
VideoInformation.seekTo(currentVideoTime);
|
||||
return;
|
||||
}
|
||||
|
||||
Thread.sleep(10);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
LogHelper.printDebug(() -> "Thread was interrupted");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import app.revanced.integrations.settings.SettingsEnum;
|
||||
public class FullscreenPanelsRemoverPatch {
|
||||
|
||||
public static int getFullscreenPanelsVisibility() {
|
||||
return SettingsEnum.FULLSCREEN_PANELS_SHOWN.getBoolean() ? View.VISIBLE : View.GONE;
|
||||
return SettingsEnum.HIDE_FULLSCREEN_PANELS.getBoolean() ? View.GONE : View.VISIBLE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import app.revanced.integrations.adremover.AdRemoverAPI;
|
||||
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
|
||||
"download_",
|
||||
"library_recent_shelf",
|
||||
"playlist_add_to_option_wrapper" // do not block on "add to playlist" flyout menu
|
||||
};
|
||||
|
||||
private final BlockRule custom = new CustomBlockRule(
|
||||
SettingsEnum.ADREMOVER_CUSTOM_ENABLED,
|
||||
SettingsEnum.ADREMOVER_CUSTOM_REMOVAL
|
||||
);
|
||||
|
||||
public GeneralAdsPatch() {
|
||||
var communityPosts = new BlockRule(SettingsEnum.ADREMOVER_COMMUNITY_POSTS_REMOVAL, "post_base_wrapper");
|
||||
var communityGuidelines = new BlockRule(SettingsEnum.ADREMOVER_COMMUNITY_GUIDELINES_REMOVAL, "community_guidelines");
|
||||
var compactBanner = new BlockRule(SettingsEnum.ADREMOVER_COMPACT_BANNER_REMOVAL, "compact_banner");
|
||||
var inFeedSurvey = new BlockRule(SettingsEnum.ADREMOVER_FEED_SURVEY_REMOVAL, "in_feed_survey");
|
||||
var medicalPanel = new BlockRule(SettingsEnum.ADREMOVER_MEDICAL_PANEL_REMOVAL, "medical_panel");
|
||||
var paidContent = new BlockRule(SettingsEnum.ADREMOVER_PAID_CONTENT_REMOVAL, "paid_content_overlay");
|
||||
var merchandise = new BlockRule(SettingsEnum.ADREMOVER_MERCHANDISE_REMOVAL, "product_carousel");
|
||||
var infoPanel = new BlockRule(SettingsEnum.ADREMOVER_INFO_PANEL_REMOVAL, "publisher_transparency_panel", "single_item_information_panel");
|
||||
var suggestions = new BlockRule(SettingsEnum.ADREMOVER_SUGGESTIONS_REMOVAL, "horizontal_video_shelf");
|
||||
var latestPosts = new BlockRule(SettingsEnum.ADREMOVER_HIDE_LATEST_POSTS, "post_shelf");
|
||||
var channelGuidelines = new BlockRule(SettingsEnum.ADREMOVER_HIDE_CHANNEL_GUIDELINES, "channel_guidelines_entry_banner");
|
||||
var artistCard = new BlockRule(SettingsEnum.HIDE_ARTIST_CARD, "official_card");
|
||||
var selfSponsor = new BlockRule(SettingsEnum.ADREMOVER_SELF_SPONSOR_REMOVAL, "cta_shelf_card");
|
||||
var chapterTeaser = new BlockRule(SettingsEnum.ADREMOVER_CHAPTER_TEASER_REMOVAL, "expandable_metadata");
|
||||
var graySeparator = new BlockRule(SettingsEnum.ADREMOVER_GRAY_SEPARATOR,
|
||||
"cell_divider" // layout residue (gray line above the buttoned ad),
|
||||
);
|
||||
var buttonedAd = new BlockRule(SettingsEnum.ADREMOVER_BUTTONED_REMOVAL,
|
||||
"video_display_full_buttoned_layout",
|
||||
"full_width_square_image_layout",
|
||||
"_ad_with",
|
||||
"landscape_image_wide_button_layout"
|
||||
);
|
||||
var generalAds = new BlockRule(
|
||||
SettingsEnum.ADREMOVER_GENERAL_ADS_REMOVAL,
|
||||
"ads_video_with_context",
|
||||
"banner_text_icon",
|
||||
"square_image_layout",
|
||||
"watch_metadata_app_promo",
|
||||
"video_display_full_layout"
|
||||
);
|
||||
var movieAds = new BlockRule(
|
||||
SettingsEnum.ADREMOVER_MOVIE_REMOVAL,
|
||||
"browsy_bar",
|
||||
"compact_movie",
|
||||
"horizontal_movie_shelf",
|
||||
"movie_and_show_upsell_card",
|
||||
"compact_tvfilm_item"
|
||||
);
|
||||
|
||||
this.pathRegister.registerAll(
|
||||
generalAds,
|
||||
buttonedAd,
|
||||
communityPosts,
|
||||
paidContent,
|
||||
suggestions,
|
||||
latestPosts,
|
||||
movieAds,
|
||||
chapterTeaser,
|
||||
communityGuidelines,
|
||||
compactBanner,
|
||||
inFeedSurvey,
|
||||
medicalPanel,
|
||||
merchandise,
|
||||
infoPanel,
|
||||
channelGuidelines,
|
||||
artistCard,
|
||||
selfSponsor
|
||||
);
|
||||
|
||||
var carouselAd = new BlockRule(SettingsEnum.ADREMOVER_GENERAL_ADS_REMOVAL,
|
||||
"carousel_ad"
|
||||
);
|
||||
var shorts = new BlockRule(SettingsEnum.ADREMOVER_SHORTS_REMOVAL,
|
||||
"reels_player_overlay",
|
||||
"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;
|
||||
|
||||
log(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;
|
||||
|
||||
log("Hiding view with setting: " + condition);
|
||||
|
||||
AdRemoverAPI.HideViewWithLayout1dp(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.ADREMOVER_GENERAL_ADS_REMOVAL, 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.ADREMOVER_SHORTS_REMOVAL, view);
|
||||
}
|
||||
|
||||
private static void log(String message) {
|
||||
LogHelper.printDebug(() -> message);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,6 @@ import app.revanced.integrations.settings.SettingsEnum;
|
||||
public class HideAutoplayButtonPatch {
|
||||
|
||||
public static boolean isButtonShown() {
|
||||
return SettingsEnum.AUTOPLAY_BUTTON_SHOWN.getBoolean();
|
||||
return SettingsEnum.HIDE_AUTOPLAY_BUTTON.getBoolean() == false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class HideCastButtonPatch {
|
||||
|
||||
//Used by app.revanced.patches.youtube.layout.castbutton.patch.HideCastButonPatch
|
||||
// Used by app.revanced.patches.youtube.layout.castbutton.patch.HideCastButonPatch
|
||||
public static int getCastButtonOverrideV2(int original) {
|
||||
return SettingsEnum.CAST_BUTTON_SHOWN.getBoolean() ? original : View.GONE;
|
||||
return SettingsEnum.HIDE_CAST_BUTTON.getBoolean() ? View.GONE : original;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ public class HideCreateButtonPatch {
|
||||
|
||||
//Used by app.revanced.patches.youtube.layout.createbutton.patch.CreateButtonRemoverPatch
|
||||
public static void hideCreateButton(View view) {
|
||||
boolean enabled = SettingsEnum.CREATE_BUTTON_ENABLED.getBoolean();
|
||||
String message = "Create button: " + (enabled ? "shown" : "hidden");
|
||||
LogHelper.debug(HideCreateButtonPatch.class, message);
|
||||
view.setVisibility(enabled ? View.VISIBLE : View.GONE);
|
||||
boolean hidden = SettingsEnum.HIDE_CREATE_BUTTON.getBoolean();
|
||||
String message = "Create button: " + (hidden ? "hidden" : "shown");
|
||||
LogHelper.printDebug(() -> message);
|
||||
view.setVisibility(hidden ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class HideEmailAddressPatch {
|
||||
//Used by app.revanced.patches.youtube.layout.personalinformation.patch.HideEmailAddressPatch
|
||||
public static boolean hideEmailAddress() {
|
||||
return SettingsEnum.HIDE_EMAIL_ADDRESS.getBoolean();
|
||||
public static int hideEmailAddress(int originalValue) {
|
||||
if (SettingsEnum.HIDE_EMAIL_ADDRESS.getBoolean())
|
||||
return 8;
|
||||
return originalValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class HideEndscreenCardsPatch {
|
||||
//Used by app.revanced.patches.youtube.layout.hideendscreencards.bytecode.patch.HideEndscreenCardsPatch
|
||||
public static void hideEndscreen(View view) {
|
||||
if (!SettingsEnum.HIDE_ENDSCREEN_CARDS.getBoolean()) return;
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
@@ -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 HideHomeAdsPatch {
|
||||
|
||||
/**
|
||||
* Used by package app.revanced.extensions.Extensions
|
||||
*
|
||||
* @param view
|
||||
*/
|
||||
public static void HideHomeAds(View view) {
|
||||
if (!SettingsEnum.HOME_ADS_REMOVAL.getBoolean()) return;
|
||||
AdRemoverAPI.HideViewWithLayout1dp(view);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class HideInfoCardSuggestionsPatch {
|
||||
|
||||
public static void hideInfoCardSuggestions(View view) {
|
||||
if (!SettingsEnum.INFO_CARDS_SHOWN.getBoolean()) {
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class HideInfocardsPatch {
|
||||
public static void hideInfocardsIncognito(View view) {
|
||||
if (!SettingsEnum.HIDE_INFO_CARDS.getBoolean()) return;
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
public static boolean hideInfocardsMethodCall() {
|
||||
return SettingsEnum.HIDE_INFO_CARDS.getBoolean();
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public class HideReelsPatch {
|
||||
* @param view
|
||||
*/
|
||||
public static void HideReel(View view) {
|
||||
if (!SettingsEnum.REEL_BUTTON_SHOWN.getBoolean()) {
|
||||
if (SettingsEnum.HIDE_REEL_BUTTON.getBoolean()) {
|
||||
AdRemoverAPI.HideViewWithLayout1dp(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,19 @@ package app.revanced.integrations.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import app.revanced.integrations.adremover.AdRemoverAPI;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
public class HideShortsButtonPatch {
|
||||
|
||||
//Used by app.revanced.patches.youtube.layout.shorts.button.patch.ShortsButtonRemoverPatch
|
||||
// Used by app.revanced.patches.youtube.layout.shorts.button.patch.ShortsButtonRemoverPatch
|
||||
public static void hideShortsButton(View view) {
|
||||
if (lastPivotTab != null && lastPivotTab.name() == "TAB_SHORTS") {
|
||||
boolean show = SettingsEnum.SHORTS_BUTTON_SHOWN.getBoolean();
|
||||
String message = show ? "Shorts button: shown" : "Shorts button: hidden";
|
||||
LogHelper.debug(HideShortsButtonPatch.class, message);
|
||||
if (!show) {
|
||||
view.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||
boolean hide = SettingsEnum.HIDE_SHORTS_BUTTON.getBoolean();
|
||||
String message = hide ? "Shorts button: hidden" : "Shorts button: shown";
|
||||
LogHelper.printDebug(() -> message);
|
||||
if (hide) {
|
||||
view.setVisibility(hide ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,25 +15,7 @@ import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
/**
|
||||
* Helper functions.
|
||||
*/
|
||||
final class Extensions {
|
||||
static boolean any(LithoBlockRegister register, String path) {
|
||||
for (var rule : register) {
|
||||
if (!rule.isEnabled()) continue;
|
||||
|
||||
var result = rule.check(path);
|
||||
if (result.isBlocked()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
final class BlockRule {
|
||||
class BlockRule {
|
||||
final static class BlockResult {
|
||||
private final boolean blocked;
|
||||
private final SettingsEnum setting;
|
||||
@@ -52,7 +34,7 @@ final class BlockRule {
|
||||
}
|
||||
}
|
||||
|
||||
private final SettingsEnum setting;
|
||||
protected final SettingsEnum setting;
|
||||
private final String[] blocks;
|
||||
|
||||
/**
|
||||
@@ -75,8 +57,22 @@ final class BlockRule {
|
||||
}
|
||||
}
|
||||
|
||||
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 LithoBlockRegister register = new LithoBlockRegister();
|
||||
final protected LithoBlockRegister pathRegister = new LithoBlockRegister();
|
||||
final protected LithoBlockRegister identifierRegister = new LithoBlockRegister();
|
||||
|
||||
abstract boolean filter(final String path, final String identifier);
|
||||
}
|
||||
@@ -106,19 +102,33 @@ final class LithoBlockRegister implements Iterable<BlockRule> {
|
||||
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 GeneralBytecodeAdsPatch(),
|
||||
new ButtonsPatch()
|
||||
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.debug(LithoFilterPatch.class, String.format("Searching (ID: %s): %s", identifier, path));
|
||||
LogHelper.printDebug(() -> String.format("Searching (ID: %s): %s", identifier, path));
|
||||
|
||||
for (var filter : filters) {
|
||||
if (filter.filter(path, identifier)) return true;
|
||||
@@ -128,162 +138,3 @@ public final class LithoFilterPatch {
|
||||
}
|
||||
}
|
||||
|
||||
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.register.registerAll(
|
||||
like,
|
||||
dislikeRule,
|
||||
download,
|
||||
playlist
|
||||
);
|
||||
}
|
||||
|
||||
private boolean hideActionBar() {
|
||||
for (BlockRule rule : rules) 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;
|
||||
|
||||
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.debug(ButtonsPatch.class, "Hiding share button");
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
if ((currentIsActionButton && ActionButton.doNotBlockCounter <= 0 && actionButtonsRule.isEnabled()) || Extensions.any(register, path)) {
|
||||
LogHelper.debug(ButtonsPatch.class, "Blocked: " + path);
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
static class ActionButton {
|
||||
public static int doNotBlockCounter = 4;
|
||||
}
|
||||
}
|
||||
|
||||
class GeneralBytecodeAdsPatch extends Filter {
|
||||
private final BlockRule identifierBlock;
|
||||
|
||||
public GeneralBytecodeAdsPatch() {
|
||||
var communityPosts = new BlockRule(SettingsEnum.ADREMOVER_COMMUNITY_POSTS_REMOVAL, "post_base_wrapper");
|
||||
var communityGuidelines = new BlockRule(SettingsEnum.ADREMOVER_COMMUNITY_GUIDELINES_REMOVAL, "community_guidelines");
|
||||
var compactBanner = new BlockRule(SettingsEnum.ADREMOVER_COMPACT_BANNER_REMOVAL, "compact_banner");
|
||||
var inFeedSurvey = new BlockRule(SettingsEnum.ADREMOVER_FEED_SURVEY_REMOVAL, "in_feed_survey");
|
||||
var medicalPanel = new BlockRule(SettingsEnum.ADREMOVER_MEDICAL_PANEL_REMOVAL, "medical_panel");
|
||||
var paidContent = new BlockRule(SettingsEnum.ADREMOVER_PAID_CONTECT_REMOVAL, "paid_content_overlay");
|
||||
var merchandise = new BlockRule(SettingsEnum.ADREMOVER_MERCHANDISE_REMOVAL, "product_carousel");
|
||||
var shorts = new BlockRule(SettingsEnum.ADREMOVER_SHORTS_SHELF_REMOVAL, "shorts_shelf");
|
||||
var infoPanel = new BlockRule(SettingsEnum.ADREMOVER_INFO_PANEL_REMOVAL, "publisher_transparency_panel", "single_item_information_panel");
|
||||
var suggestions = new BlockRule(SettingsEnum.ADREMOVER_SUGGESTIONS_REMOVAL, "horizontal_video_shelf");
|
||||
var latestPosts = new BlockRule(SettingsEnum.ADREMOVER_HIDE_LATEST_POSTS, "post_shelf");
|
||||
var channelGuidelines = new BlockRule(SettingsEnum.ADREMOVER_HIDE_CHANNEL_GUIDELINES, "channel_guidelines_entry_banner");
|
||||
var 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"
|
||||
);
|
||||
var artistCard = new BlockRule(SettingsEnum.HIDE_ARTIST_CARD, "official_card");
|
||||
var generalAds = new BlockRule(
|
||||
SettingsEnum.ADREMOVER_GENERAL_ADS_REMOVAL,
|
||||
// could be required
|
||||
//"full_width_square_image_layout",
|
||||
"video_display_full_buttoned_layout",
|
||||
"_ad",
|
||||
"ad_",
|
||||
"ads_video_with_context",
|
||||
"banner_text_icon",
|
||||
"cell_divider",
|
||||
"reels_player_overlay",
|
||||
"shelf_header",
|
||||
"watch_metadata_app_promo",
|
||||
"video_display_full_layout"
|
||||
);
|
||||
var movieAds = new BlockRule(
|
||||
SettingsEnum.ADREMOVER_MOVIE_REMOVAL,
|
||||
"browsy_bar",
|
||||
"compact_movie",
|
||||
"horizontal_movie_shelf",
|
||||
"movie_and_show_upsell_card"
|
||||
);
|
||||
|
||||
this.register.registerAll(
|
||||
generalAds,
|
||||
communityPosts,
|
||||
paidContent,
|
||||
shorts,
|
||||
suggestions,
|
||||
latestPosts,
|
||||
movieAds,
|
||||
comments,
|
||||
communityGuidelines,
|
||||
compactBanner,
|
||||
inFeedSurvey,
|
||||
medicalPanel,
|
||||
merchandise,
|
||||
infoPanel,
|
||||
channelGuidelines,
|
||||
previewComment,
|
||||
artistCard
|
||||
);
|
||||
|
||||
// Block for the ComponentContext.identifier field
|
||||
identifierBlock = new BlockRule(SettingsEnum.ADREMOVER_GENERAL_ADS_REMOVAL, "carousel_ad");
|
||||
}
|
||||
|
||||
public boolean filter(final String path, final String identifier) {
|
||||
// Do not block on these
|
||||
if (ReVancedUtils.containsAny(path,
|
||||
"home_video_with_context",
|
||||
"related_video_with_context",
|
||||
"search_video_with_context",
|
||||
"download_",
|
||||
"library_recent_shelf",
|
||||
"menu",
|
||||
"root",
|
||||
"-count",
|
||||
"-space",
|
||||
"-button"
|
||||
)) return false;
|
||||
|
||||
for (var rule : register) {
|
||||
if (!rule.isEnabled()) continue;
|
||||
|
||||
var result = rule.check(path);
|
||||
if (result.isBlocked()) {
|
||||
LogHelper.debug(GeneralBytecodeAdsPatch.class, "Blocked: " + path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (identifierBlock.check(identifier).isBlocked()) {
|
||||
LogHelper.debug(GeneralBytecodeAdsPatch.class, "Blocked: " + identifier);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,72 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.util.Log;
|
||||
import static app.revanced.integrations.utils.ReVancedUtils.getContext;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import app.revanced.integrations.utils.ThemeHelper;
|
||||
|
||||
public class LithoThemePatch {
|
||||
// color constants used in relation with litho components
|
||||
private static final int[] WHITECONSTANTS = {
|
||||
-1, // comments chip background
|
||||
-394759, // music related results panel background
|
||||
-83886081, // video chapters list background
|
||||
private static final int[] WHITE_VALUES = {
|
||||
-1, // comments chip background
|
||||
-394759, // music related results panel background
|
||||
-83886081, // video chapters list background
|
||||
};
|
||||
|
||||
private static final int[] DARKCONSTANTS = {
|
||||
-14606047, // comments chip background
|
||||
-15198184, // music related results panel background
|
||||
-15790321, // comments chip background (new layout)
|
||||
-98492127 // video chapters list background
|
||||
private static final int[] DARK_VALUES = {
|
||||
-14145496, // explore drawer background
|
||||
-14606047, // comments chip background
|
||||
-15198184, // music related results panel background
|
||||
-15790321, // comments chip background (new layout)
|
||||
-98492127 // video chapters list background
|
||||
};
|
||||
|
||||
// background colors
|
||||
private static int whiteColor = 0;
|
||||
private static int blackColor = 0;
|
||||
|
||||
// Used by app.revanced.patches.youtube.layout.theme.patch.LithoThemePatch
|
||||
/**
|
||||
* Change the color of Litho components.
|
||||
* If the color of the component matches one of the values, return the background color .
|
||||
*
|
||||
* @param originalValue The original color value.
|
||||
* @return The new or original color value
|
||||
*/
|
||||
public static int applyLithoTheme(int originalValue) {
|
||||
var isDarkTheme = ThemeHelper.isDarkTheme();
|
||||
|
||||
if ((isDarkTheme && anyEquals(originalValue, DARKCONSTANTS)) || (!isDarkTheme && anyEquals(originalValue, WHITECONSTANTS)))
|
||||
return 0;
|
||||
if (ThemeHelper.isDarkTheme()) {
|
||||
if (anyEquals(originalValue, DARK_VALUES)) return getBlackColor();
|
||||
} else {
|
||||
if (anyEquals(originalValue, WHITE_VALUES)) return getWhiteColor();
|
||||
}
|
||||
return originalValue;
|
||||
}
|
||||
|
||||
private static int getBlackColor() {
|
||||
if (blackColor == 0) blackColor = getColor("yt_black1");
|
||||
return blackColor;
|
||||
}
|
||||
|
||||
private static int getWhiteColor() {
|
||||
if (whiteColor == 0) whiteColor = getColor("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;
|
||||
|
||||
@@ -20,9 +20,9 @@ public class MicroGSupport {
|
||||
assert context != null;
|
||||
try {
|
||||
context.getPackageManager().getPackageInfo(MICROG_PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
|
||||
LogHelper.debug(ReVancedUtils.class, "MicroG is installed on the device");
|
||||
LogHelper.printDebug(() -> "MicroG is installed on the device");
|
||||
} catch (PackageManager.NameNotFoundException exception) {
|
||||
LogHelper.printException(ReVancedUtils.class, "MicroG was not found", exception);
|
||||
LogHelper.printException(() -> ("MicroG was not found"), exception);
|
||||
Toast.makeText(context, str("microg_not_installed_warning"), Toast.LENGTH_LONG).show();
|
||||
|
||||
var intent = new Intent(Intent.ACTION_VIEW);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class OpenLinksDirectlyPatch {
|
||||
|
||||
public static String parseRedirectUri(String uri) {
|
||||
if (SettingsEnum.OPEN_LINKS_DIRECTLY.getBoolean()) {
|
||||
Matcher matcher = Pattern.compile("&q=(http.+?)&v=").matcher(uri);
|
||||
return matcher.find() ? URLDecoder.decode(matcher.group(1)) : uri;
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ public class PlayerTypeHookPatch {
|
||||
final PlayerType newType = PlayerType.safeParseFromString(type.toString());
|
||||
if (newType != null) {
|
||||
PlayerType.setCurrent(newType);
|
||||
LogHelper.debug(PlayerTypeHookPatch.class, "YouTubePlayerOverlaysLayout player type was updated to " + newType);
|
||||
LogHelper.printDebug(() -> "YouTubePlayerOverlaysLayout player type was updated to " + newType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,17 @@ import java.lang.reflect.Method;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
/**
|
||||
* Hooking class for the player controller.
|
||||
* Hooking class for the current playing video.
|
||||
*/
|
||||
public final class PlayerControllerPatch {
|
||||
public final class VideoInformation {
|
||||
private static final String SEEK_METHOD_NAME = "seekTo";
|
||||
|
||||
private static WeakReference<Object> playerController;
|
||||
private static Method seekMethod;
|
||||
|
||||
private static long videoLength = 1;
|
||||
private static long videoTime = -1;
|
||||
|
||||
|
||||
/**
|
||||
* Hook into PlayerController.onCreate() method.
|
||||
@@ -26,26 +29,36 @@ public final class PlayerControllerPatch {
|
||||
public static void playerController_onCreateHook(final Object thisRef) {
|
||||
playerController = new WeakReference<>(thisRef);
|
||||
videoLength = 1;
|
||||
videoTime = -1;
|
||||
|
||||
try {
|
||||
seekMethod = thisRef.getClass().getMethod(SEEK_METHOD_NAME, Long.TYPE);
|
||||
seekMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
LogHelper.debug(PlayerControllerPatch.class, "Failed to initialize: " + ex.getMessage());
|
||||
LogHelper.printDebug(() -> "Failed to initialize: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current video length.
|
||||
* Set the video length.
|
||||
*
|
||||
* @param length The length of the video in milliseconds.
|
||||
*/
|
||||
public static void setCurrentVideoLength(final long length) {
|
||||
LogHelper.debug(PlayerControllerPatch.class, "Setting current video length to " + length);
|
||||
|
||||
public static void setVideoLength(final long length) {
|
||||
LogHelper.printDebug(() -> "Setting current video length to " + length);
|
||||
videoLength = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the video time.
|
||||
*
|
||||
* @param time The time of the video in milliseconds.
|
||||
*/
|
||||
public static void setVideoTime(final long time) {
|
||||
LogHelper.printDebug(() -> "Current video time " + time);
|
||||
videoTime = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek on the current video.
|
||||
*
|
||||
@@ -54,15 +67,15 @@ public final class PlayerControllerPatch {
|
||||
public static void seekTo(final long millisecond) {
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (seekMethod == null) {
|
||||
LogHelper.debug(PlayerControllerPatch.class, "seekMethod was null");
|
||||
LogHelper.printDebug(() -> "seekMethod was null");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
LogHelper.debug(PlayerControllerPatch.class, "Seeking to " + millisecond);
|
||||
LogHelper.printDebug(() -> "Seeking to " + millisecond);
|
||||
seekMethod.invoke(playerController.get(), millisecond);
|
||||
} catch (Exception ex) {
|
||||
LogHelper.debug(PlayerControllerPatch.class, "Failed to seek: " + ex.getMessage());
|
||||
LogHelper.printDebug(() -> "Failed to seek: " + ex.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -70,9 +83,18 @@ public final class PlayerControllerPatch {
|
||||
/**
|
||||
* Get the length of the current video playing.
|
||||
*
|
||||
* @return The length of the video in milliseconds.
|
||||
* @return The length of the video in milliseconds. 1 if not set yet.
|
||||
*/
|
||||
public static long getCurrentVideoLength() {
|
||||
return videoLength;
|
||||
return videoLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time of the current video playing.
|
||||
*
|
||||
* @return The time of the video in milliseconds. -1 if not set yet.
|
||||
*/
|
||||
public static long getVideoTime() {
|
||||
return videoTime;
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,9 @@ public class VideoSpeedPatch {
|
||||
return speed;
|
||||
}
|
||||
ReVancedUtils.setNewVideo(false);
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed: " + speed);
|
||||
LogHelper.printDebug(() -> "Speed: " + speed);
|
||||
float preferredSpeed = SettingsEnum.PREFERRED_VIDEO_SPEED.getFloat();
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Preferred speed: " + preferredSpeed);
|
||||
LogHelper.printDebug(() -> "Preferred speed: " + preferredSpeed);
|
||||
if (preferredSpeed == -2.0f) {
|
||||
return speed;
|
||||
}
|
||||
@@ -48,18 +48,20 @@ public class VideoSpeedPatch {
|
||||
int index = 0;
|
||||
while (it.hasNext()) {
|
||||
float streamSpeed2 = it.next();
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed at index " + index + ": " + streamSpeed2);
|
||||
final int logIndex = index;
|
||||
LogHelper.printDebug(() -> "Speed at index " + logIndex + ": " + streamSpeed2);
|
||||
index++;
|
||||
}
|
||||
int speed3 = -1;
|
||||
for (float streamSpeed3 : iStreamSpeeds) {
|
||||
if (streamSpeed3 <= preferredSpeed) {
|
||||
speed3++;
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed loop at index " + speed3 + ": " + streamSpeed3);
|
||||
final int speed3ToLog = speed3;
|
||||
LogHelper.printDebug(() -> "Speed loop at index " + speed3ToLog + ": " + streamSpeed3);
|
||||
}
|
||||
}
|
||||
if (speed3 == -1) {
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed was not found");
|
||||
LogHelper.printDebug(() -> "Speed was not found");
|
||||
speed2 = 3;
|
||||
} else {
|
||||
speed2 = speed3;
|
||||
@@ -68,14 +70,13 @@ public class VideoSpeedPatch {
|
||||
Method[] declaredMethods = qInterface.getClass().getDeclaredMethods();
|
||||
for (Method method : declaredMethods) {
|
||||
if (method.getName().length() <= 2) {
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Method name: " + method.getName());
|
||||
LogHelper.printDebug(() -> "Method name: " + method.getName());
|
||||
try {
|
||||
try {
|
||||
method.invoke(qInterface, videoSpeeds[speed2]);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ignored) {
|
||||
} catch (Exception e6) {
|
||||
e = e6;
|
||||
LogHelper.printException(VideoSpeedPatch.class, e.getMessage());
|
||||
} catch (final Exception e6) {
|
||||
LogHelper.printException(() -> (e6.getMessage()));
|
||||
return speed2;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
@@ -85,7 +86,7 @@ public class VideoSpeedPatch {
|
||||
} catch (Exception e10) {
|
||||
e = e10;
|
||||
}
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed changed to: " + speed2);
|
||||
LogHelper.printDebug(() -> "Speed changed to: " + speed2);
|
||||
return speed2;
|
||||
}
|
||||
|
||||
@@ -97,15 +98,15 @@ public class VideoSpeedPatch {
|
||||
int i = 0;
|
||||
if (!ReVancedUtils.isNewVideoStarted() || userChangedSpeed) {
|
||||
if (SettingsEnum.DEBUG.getBoolean() && userChangedSpeed) {
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Skipping speed change because user changed it: " + speed);
|
||||
LogHelper.printDebug(() -> "Skipping speed change because user changed it: " + speed);
|
||||
}
|
||||
userChangedSpeed = false;
|
||||
return -1.0f;
|
||||
}
|
||||
ReVancedUtils.setNewVideo(false);
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed: " + speed);
|
||||
LogHelper.printDebug(() -> "Speed: " + speed);
|
||||
float preferredSpeed = SettingsEnum.PREFERRED_VIDEO_SPEED.getFloat();
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Preferred speed: " + preferredSpeed);
|
||||
LogHelper.printDebug(() -> "Preferred speed: " + preferredSpeed);
|
||||
if (preferredSpeed == -2.0f) {
|
||||
return -1.0f;
|
||||
}
|
||||
@@ -136,7 +137,8 @@ public class VideoSpeedPatch {
|
||||
int index = 0;
|
||||
for (Float iStreamSpeed : iStreamSpeeds) {
|
||||
float streamSpeed2 = iStreamSpeed;
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed at index " + index + ": " + streamSpeed2);
|
||||
final int indexToLog = index;
|
||||
LogHelper.printDebug(() -> "Speed at index " + indexToLog + ": " + streamSpeed2);
|
||||
index++;
|
||||
}
|
||||
int newSpeedIndex = -1;
|
||||
@@ -144,18 +146,21 @@ public class VideoSpeedPatch {
|
||||
float streamSpeed3 = iStreamSpeed;
|
||||
if (streamSpeed3 <= preferredSpeed) {
|
||||
newSpeedIndex++;
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed loop at index " + newSpeedIndex + ": " + streamSpeed3);
|
||||
final int newSpeedIndexToLog = newSpeedIndex;
|
||||
LogHelper.printDebug(() -> "Speed loop at index " + newSpeedIndexToLog + ": " + streamSpeed3);
|
||||
}
|
||||
}
|
||||
if (newSpeedIndex == -1) {
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed was not found");
|
||||
LogHelper.printDebug(() -> "Speed was not found");
|
||||
newSpeedIndex = 3;
|
||||
}
|
||||
if (newSpeedIndex == speed) {
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Trying to set speed to what it already is, skipping...: " + newSpeedIndex);
|
||||
final int newSpeedIndexToLog = newSpeedIndex;
|
||||
LogHelper.printDebug(() -> "Trying to set speed to what it already is, skipping...: " + newSpeedIndexToLog);
|
||||
return -1.0f;
|
||||
}
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed changed to: " + newSpeedIndex);
|
||||
final int newSpeedIndexToLog = newSpeedIndex;
|
||||
LogHelper.printDebug(() -> "Speed changed to: " + newSpeedIndexToLog);
|
||||
return getSpeedByIndex(newSpeedIndex);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class ZoomHapticsPatch {
|
||||
public static boolean shouldVibrate() {
|
||||
return !SettingsEnum.DISABLE_ZOOM_HAPTICS.getBoolean();
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public class DownloadsPatch {
|
||||
* @param videoId The current video id
|
||||
*/
|
||||
public static void setVideoId(String videoId) {
|
||||
LogHelper.debug(DownloadsPatch.class, "newVideoLoaded - " + videoId);
|
||||
LogHelper.printDebug(() -> "newVideoLoaded - " + videoId);
|
||||
|
||||
DownloadsPatch.videoId = videoId;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package app.revanced.integrations.patches;
|
||||
package app.revanced.integrations.patches.playback.quality;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -10,19 +10,19 @@ import app.revanced.integrations.utils.LogHelper;
|
||||
public class OldQualityLayoutPatch {
|
||||
public static void showOldQualityMenu(ListView listView)
|
||||
{
|
||||
if (!SettingsEnum.OLD_STYLE_QUALITY_SETTINGS.getBoolean()) return;
|
||||
if (!SettingsEnum.OLD_STYLE_VIDEO_QUALITY_PLAYER_SETTINGS.getBoolean()) return;
|
||||
|
||||
listView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
|
||||
@Override
|
||||
public void onChildViewAdded(View parent, View child) {
|
||||
LogHelper.debug(OldQualityLayoutPatch.class, "Added: " + child);
|
||||
LogHelper.printDebug(() -> "Added: " + child);
|
||||
|
||||
parent.setVisibility(View.GONE);
|
||||
|
||||
final var indexOfAdvancedQualityMenuItem = 4;
|
||||
if (listView.indexOfChild(child) != indexOfAdvancedQualityMenuItem) return;
|
||||
|
||||
LogHelper.debug(OldQualityLayoutPatch.class, "Found advanced menu: " + child);
|
||||
LogHelper.printDebug(() -> "Found advanced menu: " + child);
|
||||
|
||||
final var qualityItemMenuPosition = 4;
|
||||
listView.performItemClick(null, qualityItemMenuPosition, 0);
|
||||
@@ -1,4 +1,4 @@
|
||||
package app.revanced.integrations.patches;
|
||||
package app.revanced.integrations.patches.playback.quality;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
@@ -15,7 +15,7 @@ import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
import app.revanced.integrations.utils.SharedPrefHelper;
|
||||
|
||||
public class VideoQualityPatch {
|
||||
public class RememberVideoQualityPatch {
|
||||
|
||||
public static int selectedQuality1 = -2;
|
||||
private static Boolean newVideo = false;
|
||||
@@ -27,22 +27,22 @@ public class VideoQualityPatch {
|
||||
try {
|
||||
SharedPrefHelper.saveString(context, SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, "wifi_quality", defaultQuality + "");
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(VideoQualityPatch.class, "Failed to change default WI-FI quality:" + ex);
|
||||
LogHelper.printException(() -> ("Failed to change default WI-FI quality:" + ex));
|
||||
Toast.makeText(context, "Failed to change default WI-FI quality:", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
LogHelper.debug(VideoQualityPatch.class, "Changing default Wi-Fi quality to: " + defaultQuality);
|
||||
LogHelper.printDebug(() -> "Changing default Wi-Fi quality to: " + defaultQuality);
|
||||
Toast.makeText(context, "Changing default Wi-Fi quality to: " + defaultQuality, Toast.LENGTH_SHORT).show();
|
||||
} else if (isConnectedMobile(context)) {
|
||||
try {
|
||||
SharedPrefHelper.saveString(context, SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, "mobile_quality", defaultQuality + "");
|
||||
} catch (Exception ex) {
|
||||
LogHelper.debug(VideoQualityPatch.class, "Failed to change default mobile data quality" + ex);
|
||||
LogHelper.printDebug(() -> "Failed to change default mobile data quality" + ex);
|
||||
Toast.makeText(context, "Failed to change default mobile data quality", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
LogHelper.debug(VideoQualityPatch.class, "Changing default mobile data quality to:" + defaultQuality);
|
||||
LogHelper.printDebug(() -> "Changing default mobile data quality to:" + defaultQuality);
|
||||
Toast.makeText(context, "Changing default mobile data quality to:" + defaultQuality, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
LogHelper.debug(VideoQualityPatch.class, "No internet connection.");
|
||||
LogHelper.printDebug(() -> "No internet connection.");
|
||||
Toast.makeText(context, "No internet connection.", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
userChangedQuality = false;
|
||||
@@ -76,34 +76,37 @@ public class VideoQualityPatch {
|
||||
int selectedQuality2 = qualities.length - selectedQuality1 + 1;
|
||||
index++;
|
||||
if (selectedQuality2 == index) {
|
||||
LogHelper.debug(VideoQualityPatch.class, "Quality index is: " + index + " and corresponding value is: " + convertedQuality);
|
||||
final int indexToLog = index; // must be final for lambda
|
||||
LogHelper.printDebug(() -> "Quality index is: " + indexToLog + " and corresponding value is: " + convertedQuality);
|
||||
changeDefaultQuality(convertedQuality);
|
||||
return selectedQuality2;
|
||||
}
|
||||
}
|
||||
}
|
||||
newVideo = false;
|
||||
LogHelper.debug(VideoQualityPatch.class, "Quality: " + quality);
|
||||
final int qualityToLog = quality;
|
||||
LogHelper.printDebug(() -> "Quality: " + qualityToLog);
|
||||
Context context = ReVancedUtils.getContext();
|
||||
if (context == null) {
|
||||
LogHelper.printException(VideoQualityPatch.class, "Context is null or settings not initialized, returning quality: " + quality);
|
||||
LogHelper.printException(() -> ("Context is null or settings not initialized, returning quality: " + qualityToLog));
|
||||
return quality;
|
||||
}
|
||||
if (isConnectedWifi(context)) {
|
||||
preferredQuality = SharedPrefHelper.getInt(context, SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, "wifi_quality", -2);
|
||||
LogHelper.debug(VideoQualityPatch.class, "Wi-Fi connection detected, preferred quality: " + preferredQuality);
|
||||
LogHelper.printDebug(() -> "Wi-Fi connection detected, preferred quality: " + preferredQuality);
|
||||
} else if (isConnectedMobile(context)) {
|
||||
preferredQuality = SharedPrefHelper.getInt(context, SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, "mobile_quality", -2);
|
||||
LogHelper.debug(VideoQualityPatch.class, "Mobile data connection detected, preferred quality: " + preferredQuality);
|
||||
LogHelper.printDebug(() -> "Mobile data connection detected, preferred quality: " + preferredQuality);
|
||||
} else {
|
||||
LogHelper.debug(VideoQualityPatch.class, "No Internet connection!");
|
||||
LogHelper.printDebug(() -> "No Internet connection!");
|
||||
return quality;
|
||||
}
|
||||
if (preferredQuality == -2) {
|
||||
return quality;
|
||||
}
|
||||
for (int streamQuality2 : iStreamQualities) {
|
||||
LogHelper.debug(VideoQualityPatch.class, "Quality at index " + index + ": " + streamQuality2);
|
||||
final int indexToLog = index;
|
||||
LogHelper.printDebug(() -> "Quality at index " + indexToLog + ": " + streamQuality2);
|
||||
index++;
|
||||
}
|
||||
for (Integer iStreamQuality : iStreamQualities) {
|
||||
@@ -116,24 +119,25 @@ public class VideoQualityPatch {
|
||||
return quality;
|
||||
}
|
||||
int qualityIndex = iStreamQualities.indexOf(quality);
|
||||
LogHelper.debug(VideoQualityPatch.class, "Index of quality " + quality + " is " + qualityIndex);
|
||||
final int qualityToLog2 = quality;
|
||||
LogHelper.printDebug(() -> "Index of quality " + qualityToLog2 + " is " + qualityIndex);
|
||||
try {
|
||||
Class<?> cl = qInterface.getClass();
|
||||
Method m = cl.getMethod(qIndexMethod, Integer.TYPE);
|
||||
LogHelper.debug(VideoQualityPatch.class, "Method is: " + qIndexMethod);
|
||||
LogHelper.printDebug(() -> "Method is: " + qIndexMethod);
|
||||
m.invoke(qInterface, iStreamQualities.get(qualityIndex));
|
||||
LogHelper.debug(VideoQualityPatch.class, "Quality changed to: " + qualityIndex);
|
||||
LogHelper.printDebug(() -> "Quality changed to: " + qualityIndex);
|
||||
return qualityIndex;
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(VideoQualityPatch.class, "Failed to set quality", ex);
|
||||
LogHelper.printException(() -> ("Failed to set quality"), ex);
|
||||
Toast.makeText(context, "Failed to set quality", Toast.LENGTH_SHORT).show();
|
||||
return qualityIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public static void userChangedQuality(int selectedQuality) {
|
||||
// Do not remember a **new** quality if REMEMBER_VIDEO_QUALITY is true
|
||||
if (SettingsEnum.REMEMBER_VIDEO_QUALITY.getBoolean()) return;
|
||||
// Do not remember a **new** quality if REMEMBER_VIDEO_QUALITY is false
|
||||
if (SettingsEnum.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.getBoolean() == false) return;
|
||||
|
||||
selectedQuality1 = selectedQuality;
|
||||
userChangedQuality = true;
|
||||
@@ -0,0 +1,5 @@
|
||||
package app.revanced.integrations.patches.playback.speed;
|
||||
|
||||
public class CustomVideoSpeedPatch {
|
||||
public static final float[] videoSpeeds = { 0, 0 }; // Values are useless as they are being overridden by the respective patch
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user