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
81 Commits
v0.112.1-d
...
v0.117.1-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20e2ecf199 | ||
|
|
61d997e1db | ||
|
|
04c81b39e9 | ||
|
|
b7a176ff3e | ||
|
|
1afd520c7b | ||
|
|
dc955d1bc2 | ||
|
|
f3fc0d1f7d | ||
|
|
ca4927e2a9 | ||
|
|
6e8d13bfbb | ||
|
|
90a7e604d3 | ||
|
|
6801ed8d28 | ||
|
|
ba8f4f9b5f | ||
|
|
a178a223c2 | ||
|
|
fb3b7b4c80 | ||
|
|
297d76f176 | ||
|
|
acae4b1bc8 | ||
|
|
d4570de0a7 | ||
|
|
a249b1648d | ||
|
|
aa9d892cde | ||
|
|
aff6e98f64 | ||
|
|
44dccb3d65 | ||
|
|
61e961a9e3 | ||
|
|
420b9263b6 | ||
|
|
fbc6855c4a | ||
|
|
ebd425b7ff | ||
|
|
13afac906a | ||
|
|
7510c0632f | ||
|
|
33e3c6b061 | ||
|
|
842f5f7616 | ||
|
|
d354356b2d | ||
|
|
95dae4896e | ||
|
|
2188607340 | ||
|
|
efa60dc64a | ||
|
|
2ba44526d5 | ||
|
|
8648434f99 | ||
|
|
97880eaf72 | ||
|
|
7ca6a080a3 | ||
|
|
8e5ca65286 | ||
|
|
c1af6e699d | ||
|
|
769a2006ce | ||
|
|
8517e8a149 | ||
|
|
9e56c40d88 | ||
|
|
3c69108caa | ||
|
|
6959808f0c | ||
|
|
e0d77a0060 | ||
|
|
2ab34fce31 | ||
|
|
cf76cbe72f | ||
|
|
c16c038396 | ||
|
|
d2a8c33109 | ||
|
|
d3f523f9dd | ||
|
|
1c2976526e | ||
|
|
18f29004b8 | ||
|
|
0207496926 | ||
|
|
b2085aeebf | ||
|
|
ac8de0a3b7 | ||
|
|
d4bc6cff68 | ||
|
|
e906c6d3a2 | ||
|
|
fdc56bf68e | ||
|
|
ea7bc57375 | ||
|
|
8ef81235d7 | ||
|
|
c7d2a9b310 | ||
|
|
d7fc06a647 | ||
|
|
67cf3e2eb4 | ||
|
|
dcd97f3143 | ||
|
|
e1011e42df | ||
|
|
e2f25cd5ae | ||
|
|
2a784a47d1 | ||
|
|
dc591ac7ed | ||
|
|
8c61561d63 | ||
|
|
8920e1dfe8 | ||
|
|
59f7733f99 | ||
|
|
6104e263ce | ||
|
|
a0f831ac3f | ||
|
|
2f39f32a52 | ||
|
|
821a32ee40 | ||
|
|
d3533824f4 | ||
|
|
7a28c2fa13 | ||
|
|
5056adbc3c | ||
|
|
9f21c7268e | ||
|
|
42750409b7 | ||
|
|
630776fd35 |
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@@ -30,7 +30,6 @@ jobs:
|
||||
${{ runner.home }}/.gradle/caches
|
||||
${{ runner.home }}/.gradle/wrapper
|
||||
.gradle
|
||||
build
|
||||
node_modules
|
||||
key: ${{ runner.os }}-gradle-npm-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'package-lock.json') }}
|
||||
- name: Setup Java
|
||||
@@ -38,7 +37,7 @@ jobs:
|
||||
- name: Build with Gradle
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: ./gradlew clean --no-daemon
|
||||
run: ./gradlew build clean
|
||||
- name: Setup semantic-release
|
||||
run: npm install
|
||||
- name: Release
|
||||
|
||||
294
CHANGELOG.md
294
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,6 @@ plugins {
|
||||
|
||||
android {
|
||||
compileSdk = 33
|
||||
buildToolsVersion = "33.0.1"
|
||||
namespace = "app.revanced.integrations"
|
||||
|
||||
defaultConfig {
|
||||
@@ -44,7 +43,7 @@ android {
|
||||
dependencies {
|
||||
compileOnly(project(mapOf("path" to ":dummy")))
|
||||
compileOnly("androidx.annotation:annotation:1.6.0")
|
||||
compileOnly("androidx.appcompat:appcompat:1.7.0-alpha02")
|
||||
compileOnly("androidx.appcompat:appcompat:1.7.0-alpha03")
|
||||
compileOnly("com.squareup.okhttp3:okhttp:5.0.0-alpha.11")
|
||||
compileOnly("com.squareup.retrofit2:retrofit:2.9.0")
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.widget.ImageView;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
public class CustomPlayerOverlayOpacityPatch {
|
||||
private static final int DEFAULT_OPACITY = (int) SettingsEnum.PLAYER_OVERLAY_OPACITY.defaultValue;
|
||||
|
||||
public static void changeOpacity(ImageView imageView) {
|
||||
int opacity = SettingsEnum.PLAYER_OVERLAY_OPACITY.getInt();
|
||||
|
||||
if (opacity < 0 || opacity > 100) {
|
||||
ReVancedUtils.showToastLong("Player overlay opacity must be between 0-100");
|
||||
SettingsEnum.PLAYER_OVERLAY_OPACITY.saveValue(DEFAULT_OPACITY);
|
||||
opacity = DEFAULT_OPACITY;
|
||||
}
|
||||
|
||||
imageView.setImageAlpha((opacity * 255) / 100);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public final class EnableTabletLayoutPatch {
|
||||
public static boolean enableTabletLayout() {
|
||||
return SettingsEnum.TABLET_LAYOUT.getBoolean();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.widget.ImageView;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class HidePlayerOverlayPatch {
|
||||
public static void hidePlayerOverlay(ImageView view) {
|
||||
if (!SettingsEnum.HIDE_PLAYER_OVERLAY.getBoolean()) return;
|
||||
view.setImageResource(android.R.color.transparent);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class HideWatchInVRPatch {
|
||||
public static boolean hideWatchInVR() {
|
||||
return SettingsEnum.HIDE_WATCH_IN_VR.getBoolean();
|
||||
}
|
||||
}
|
||||
@@ -4,16 +4,14 @@ import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class OpenLinksExternallyPatch {
|
||||
/**
|
||||
* Override 'android.support.customtabs.action.CustomTabsService',
|
||||
* in order to open links in the default browser. This is done by returning an empty string,
|
||||
* for the service that handles custom tabs in the Android support library
|
||||
* which opens links in the default service instead.
|
||||
* Return the intent to open links with. If empty, the link will be opened with the default browser.
|
||||
*
|
||||
* @param original The original custom tabs service.
|
||||
* @return The new, default service to open links with or the original service.
|
||||
* @param originalIntent The original intent to open links with.
|
||||
* @return The intent to open links with. Empty means the link will be opened with the default browser.
|
||||
*/
|
||||
public static String enableExternalBrowser(String original) {
|
||||
if (SettingsEnum.EXTERNAL_BROWSER.getBoolean()) original = "";
|
||||
return original;
|
||||
public static String getIntent(String originalIntent) {
|
||||
if (SettingsEnum.EXTERNAL_BROWSER.getBoolean()) return "";
|
||||
|
||||
return originalIntent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +202,13 @@ public class ReturnYouTubeDislikePatch {
|
||||
*/
|
||||
public static boolean setShortsDislikes(@NonNull View likeDislikeView) {
|
||||
try {
|
||||
if (!SettingsEnum.RYD_ENABLED.getBoolean() || !SettingsEnum.RYD_SHORTS.getBoolean()) {
|
||||
if (!SettingsEnum.RYD_ENABLED.getBoolean()) {
|
||||
return false;
|
||||
}
|
||||
if (!SettingsEnum.RYD_SHORTS.getBoolean()) {
|
||||
// Must clear the data here, in case a new video was loaded while PlayerType
|
||||
// suggested the video was not a short (can happen when spoofing to an old app version).
|
||||
ReturnYouTubeDislike.setCurrentVideoId(null);
|
||||
return false;
|
||||
}
|
||||
LogHelper.printDebug(() -> "setShortsDislikes");
|
||||
@@ -302,7 +308,7 @@ public class ReturnYouTubeDislikePatch {
|
||||
if (!videoId.equals(currentVideoId)) {
|
||||
currentVideoId = videoId;
|
||||
|
||||
final boolean noneHiddenOrMinimized = PlayerType.getCurrent().isNoneHiddenOrMinimized();
|
||||
final boolean noneHiddenOrMinimized = PlayerType.getCurrent().isNoneOrHidden();
|
||||
if (noneHiddenOrMinimized && !SettingsEnum.RYD_SHORTS.getBoolean()) {
|
||||
ReturnYouTubeDislike.setCurrentVideoId(null);
|
||||
return;
|
||||
|
||||
@@ -2,6 +2,10 @@ package app.revanced.integrations.patches;
|
||||
|
||||
import static app.revanced.integrations.utils.ReVancedUtils.containsAny;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.shared.PlayerType;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
@@ -67,4 +71,25 @@ public class SpoofSignatureVerificationPatch {
|
||||
return originalValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*/
|
||||
public static boolean getSeekbarThumbnailOverrideValue() {
|
||||
return SettingsEnum.SPOOF_SIGNATURE_VERIFICATION.getBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection point.
|
||||
*
|
||||
* @param view seekbar thumbnail view. Includes both shorts and regular videos.
|
||||
*/
|
||||
public static void seekbarImageViewCreated(ImageView view) {
|
||||
if (SettingsEnum.SPOOF_SIGNATURE_VERIFICATION.getBoolean()) {
|
||||
view.setVisibility(View.GONE);
|
||||
// Also hide the border around the thumbnail (otherwise a 1 pixel wide bordered frame is visible).
|
||||
ViewGroup parentLayout = (ViewGroup) view.getParent();
|
||||
parentLayout.setPadding(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,27 +2,32 @@ package app.revanced.integrations.patches.components;
|
||||
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
import app.revanced.integrations.utils.StringTrieSearch;
|
||||
|
||||
|
||||
public final class AdsFilter extends Filter {
|
||||
private final String[] exceptions;
|
||||
private final StringTrieSearch exceptions = new StringTrieSearch();
|
||||
|
||||
public AdsFilter() {
|
||||
exceptions = new String[]{
|
||||
exceptions.addPatterns(
|
||||
"home_video_with_context", // Don't filter anything in the home page video component.
|
||||
"related_video_with_context", // Don't filter anything in the related video component.
|
||||
"comment_thread", // Don't filter anything in the comments.
|
||||
"|comment.", // Don't filter anything in the comments replies.
|
||||
"library_recent_shelf",
|
||||
};
|
||||
"library_recent_shelf"
|
||||
);
|
||||
|
||||
final var buttonedAd = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_BUTTONED_ADS,
|
||||
"_buttoned_layout",
|
||||
"full_width_square_image_layout",
|
||||
"_ad_with",
|
||||
"text_image_button_group_layout",
|
||||
"video_display_button_group_layout",
|
||||
"landscape_image_wide_button_layout"
|
||||
);
|
||||
@@ -81,7 +86,7 @@ public final class AdsFilter extends Filter {
|
||||
"cta_shelf_card"
|
||||
);
|
||||
|
||||
this.pathFilterGroups.addAll(
|
||||
this.pathFilterGroupList.addAll(
|
||||
generalAds,
|
||||
buttonedAd,
|
||||
merchandise,
|
||||
@@ -90,15 +95,16 @@ public final class AdsFilter extends Filter {
|
||||
webLinkPanel,
|
||||
movieAds
|
||||
);
|
||||
this.identifierFilterGroups.addAll(carouselAd);
|
||||
this.identifierFilterGroupList.addAll(carouselAd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFiltered(final String path, final String identifier, final byte[] _protobufBufferArray) {
|
||||
if (ReVancedUtils.containsAny(path, exceptions))
|
||||
public boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
|
||||
FilterGroupList matchedList, FilterGroup matchedGroup, int matchedIndex) {
|
||||
if (exceptions.matches(path))
|
||||
return false;
|
||||
|
||||
return super.isFiltered(path, identifier, _protobufBufferArray);
|
||||
return super.isFiltered(identifier, path, protobufBufferArray, matchedList, matchedGroup, matchedIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,54 +1,114 @@
|
||||
package app.revanced.integrations.patches.components;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
final class ButtonsFilter extends Filter {
|
||||
private final StringFilterGroup actionBarRule;
|
||||
private static final String VIDEO_ACTION_BAR_PATH = "video_action_bar.eml";
|
||||
|
||||
private final StringFilterGroup actionBarGroup;
|
||||
private final StringFilterGroup bufferFilterPathGroup;
|
||||
private final ByteArrayFilterGroupList bufferButtonsGroupList = new ByteArrayFilterGroupList();
|
||||
|
||||
public ButtonsFilter() {
|
||||
actionBarRule = new StringFilterGroup(
|
||||
actionBarGroup = new StringFilterGroup(
|
||||
null,
|
||||
"video_action_bar"
|
||||
VIDEO_ACTION_BAR_PATH
|
||||
);
|
||||
identifierFilterGroupList.addAll(actionBarGroup);
|
||||
|
||||
pathFilterGroups.addAll(
|
||||
|
||||
bufferFilterPathGroup = new StringFilterGroup(
|
||||
null,
|
||||
"|CellType|CollectionType|CellType|ContainerType|button.eml|"
|
||||
);
|
||||
pathFilterGroupList.addAll(
|
||||
new StringFilterGroup(
|
||||
SettingsEnum.HIDE_LIKE_DISLIKE_BUTTON,
|
||||
"|like_button",
|
||||
"dislike_button"
|
||||
"|segmented_like_dislike_button"
|
||||
),
|
||||
new StringFilterGroup(
|
||||
SettingsEnum.HIDE_DOWNLOAD_BUTTON,
|
||||
"download_button"
|
||||
"|download_button.eml|"
|
||||
),
|
||||
new StringFilterGroup(
|
||||
SettingsEnum.HIDE_PLAYLIST_BUTTON,
|
||||
"save_to_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|"
|
||||
bufferFilterPathGroup
|
||||
);
|
||||
|
||||
bufferButtonsGroupList.addAll(
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_LIVE_CHAT_BUTTON,
|
||||
"yt_outline_message_bubble_overlap"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_REPORT_BUTTON,
|
||||
"yt_outline_flag"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_SHARE_BUTTON,
|
||||
"yt_outline_share"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_REMIX_BUTTON,
|
||||
"yt_outline_youtube_shorts_plus"
|
||||
),
|
||||
// Check for clip button both here and using a path filter,
|
||||
// as there's a chance the path is a generic action button and won't contain 'clip_button'
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_CLIP_BUTTON,
|
||||
"yt_outline_scissors"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_SHOP_BUTTON,
|
||||
"yt_outline_bag"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_THANKS_BUTTON,
|
||||
"yt_outline_dollar_sign_heart"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private boolean isEveryFilterGroupEnabled() {
|
||||
for (StringFilterGroup rule : pathFilterGroups)
|
||||
if (!rule.isEnabled()) return false;
|
||||
for (var group : pathFilterGroupList)
|
||||
if (!group.isEnabled()) return false;
|
||||
|
||||
for (var group : bufferButtonsGroupList)
|
||||
if (!group.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;
|
||||
public boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
|
||||
FilterGroupList matchedList, FilterGroup matchedGroup, int matchedIndex) {
|
||||
// If the current matched group is the action bar group,
|
||||
// in case every filter group is enabled, hide the action bar.
|
||||
if (matchedGroup == actionBarGroup) {
|
||||
if (!isEveryFilterGroupEnabled()) {
|
||||
return false;
|
||||
}
|
||||
} else if (matchedGroup == bufferFilterPathGroup) {
|
||||
// Make sure the current path is the right one
|
||||
// to avoid false positives.
|
||||
if (!path.startsWith(VIDEO_ACTION_BAR_PATH)) return false;
|
||||
|
||||
return super.isFiltered(path, identifier, _protobufBufferArray);
|
||||
// In case the group list has no match, return false.
|
||||
if (!bufferButtonsGroupList.check(protobufBufferArray).isFiltered()) return false;
|
||||
}
|
||||
|
||||
return super.isFiltered(identifier, path, protobufBufferArray, matchedList, matchedGroup, matchedIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ final class CommentsFilter extends Filter {
|
||||
"comments_entry_point_simplebox"
|
||||
);
|
||||
|
||||
this.pathFilterGroups.addAll(
|
||||
this.pathFilterGroupList.addAll(
|
||||
comments,
|
||||
previewComment
|
||||
);
|
||||
|
||||
@@ -2,15 +2,16 @@ package app.revanced.integrations.patches.components;
|
||||
|
||||
|
||||
import android.os.Build;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.StringTrieSearch;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
public final class LayoutComponentsFilter extends Filter {
|
||||
private final String[] exceptions;
|
||||
|
||||
private final StringTrieSearch exceptions = new StringTrieSearch();
|
||||
private final CustomFilterGroup custom;
|
||||
|
||||
private static final ByteArrayAsStringFilterGroup mixPlaylists = new ByteArrayAsStringFilterGroup(
|
||||
@@ -20,13 +21,13 @@ public final class LayoutComponentsFilter extends Filter {
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
public LayoutComponentsFilter() {
|
||||
exceptions = new String[]{
|
||||
exceptions.addPatterns(
|
||||
"home_video_with_context",
|
||||
"related_video_with_context",
|
||||
"comment_thread", // skip filtering anything in the comments
|
||||
"|comment.", // skip filtering anything in the comments replies
|
||||
"library_recent_shelf",
|
||||
};
|
||||
"library_recent_shelf"
|
||||
);
|
||||
|
||||
custom = new CustomFilterGroup(
|
||||
SettingsEnum.CUSTOM_FILTER,
|
||||
@@ -136,7 +137,12 @@ public final class LayoutComponentsFilter extends Filter {
|
||||
"cell_divider" // layout residue (gray line above the buttoned ad),
|
||||
);
|
||||
|
||||
this.pathFilterGroups.addAll(
|
||||
final var chipsShelf = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_CHIPS_SHELF,
|
||||
"chips_shelf"
|
||||
);
|
||||
|
||||
this.pathFilterGroupList.addAll(
|
||||
channelBar,
|
||||
communityPosts,
|
||||
paidContent,
|
||||
@@ -155,26 +161,32 @@ public final class LayoutComponentsFilter extends Filter {
|
||||
artistCard,
|
||||
imageShelf,
|
||||
subscribersCommunityGuidelines,
|
||||
channelMemberShelf
|
||||
channelMemberShelf,
|
||||
custom
|
||||
);
|
||||
|
||||
this.identifierFilterGroups.addAll(graySeparator);
|
||||
this.identifierFilterGroupList.addAll(
|
||||
graySeparator,
|
||||
chipsShelf
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFiltered(final String path, final String identifier, final byte[] _protobufBufferArray) {
|
||||
if (custom.isEnabled() && custom.check(path).isFiltered())
|
||||
return true;
|
||||
|
||||
if (ReVancedUtils.containsAny(path, exceptions))
|
||||
public boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
|
||||
FilterGroupList matchedList, FilterGroup matchedGroup, int matchedIndex) {
|
||||
if (matchedGroup != custom && exceptions.matches(path))
|
||||
return false; // Exceptions are not filtered.
|
||||
|
||||
return super.isFiltered(path, identifier, _protobufBufferArray);
|
||||
return super.isFiltered(identifier, path, protobufBufferArray, matchedList, matchedGroup, matchedIndex);
|
||||
}
|
||||
|
||||
|
||||
// Called from a different place then the other filters.
|
||||
/**
|
||||
* Injection point.
|
||||
*
|
||||
* Called from a different place then the other filters.
|
||||
*/
|
||||
public static boolean filterMixPlaylists(final byte[] bytes) {
|
||||
return mixPlaylists.isEnabled() && mixPlaylists.check(bytes).isFiltered();
|
||||
return mixPlaylists.check(bytes).isFiltered();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,24 @@
|
||||
package app.revanced.integrations.patches.components;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
// Abuse LithoFilter for CustomPlaybackSpeedPatch.
|
||||
public final class PlaybackSpeedMenuFilterPatch extends Filter {
|
||||
// Must be volatile or synchronized, as litho filtering runs off main thread and this field is then access from the main thread.
|
||||
public static volatile boolean isPlaybackSpeedMenuVisible;
|
||||
|
||||
public PlaybackSpeedMenuFilterPatch() {
|
||||
pathFilterGroupList.addAll(new StringFilterGroup(
|
||||
null,
|
||||
"playback_speed_sheet_content.eml-js"
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
|
||||
FilterGroupList matchedList, FilterGroup matchedGroup, int matchedIndex) {
|
||||
isPlaybackSpeedMenuVisible = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package app.revanced.integrations.patches.components;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class PlayerFlyoutMenuItemsFilter extends Filter {
|
||||
|
||||
// Search the buffer only if the flyout menu identifier is found.
|
||||
// Handle the searching in this class instead of adding to the global filter group (which searches all the time)
|
||||
private final ByteArrayFilterGroupList flyoutFilterGroupList = new ByteArrayFilterGroupList();
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
public PlayerFlyoutMenuItemsFilter() {
|
||||
identifierFilterGroupList.addAll(new StringFilterGroup(null, "overflow_menu_item.eml|"));
|
||||
|
||||
flyoutFilterGroupList.addAll(
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_QUALITY_MENU,
|
||||
"yt_outline_gear"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_CAPTIONS_MENU,
|
||||
"closed_caption"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_LOOP_VIDEO_MENU,
|
||||
"yt_outline_arrow_repeat_1_"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_AMBIENT_MODE_MENU,
|
||||
"yt_outline_screen_light"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_REPORT_MENU,
|
||||
"yt_outline_flag"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_HELP_MENU,
|
||||
"yt_outline_question_circle"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_MORE_INFO_MENU,
|
||||
"yt_outline_info_circle"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_SPEED_MENU,
|
||||
"yt_outline_play_arrow_half_circle"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_AUDIO_TRACK_MENU,
|
||||
"yt_outline_person_radar"
|
||||
),
|
||||
new ByteArrayAsStringFilterGroup(
|
||||
SettingsEnum.HIDE_WATCH_IN_VR_MENU,
|
||||
"yt_outline_vr"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
|
||||
FilterGroupList matchedList, FilterGroup matchedGroup, int matchedIndex) {
|
||||
// Only 1 group is added to the parent class, so the matched group must be the overflow menu.
|
||||
if (matchedIndex == 0 && flyoutFilterGroupList.check(protobufBufferArray).isFiltered()) {
|
||||
// Super class handles logging.
|
||||
return super.isFiltered(identifier, path, protobufBufferArray, matchedList, matchedGroup, matchedIndex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,76 +1,91 @@
|
||||
package app.revanced.integrations.patches.components;
|
||||
|
||||
import android.view.View;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import com.google.android.libraries.youtube.rendering.ui.pivotbar.PivotBar;
|
||||
|
||||
import static app.revanced.integrations.utils.ReVancedUtils.hideViewBy1dpUnderCondition;
|
||||
import static app.revanced.integrations.utils.ReVancedUtils.hideViewUnderCondition;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.libraries.youtube.rendering.ui.pivotbar.PivotBar;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public final class ShortsFilter extends Filter {
|
||||
// Set by patch.
|
||||
public static PivotBar pivotBar;
|
||||
final StringFilterGroupList shortsFilterGroup = new StringFilterGroupList();
|
||||
private final StringFilterGroup reelChannelBar = new StringFilterGroup(
|
||||
null,
|
||||
"reel_channel_bar"
|
||||
);
|
||||
private static final String REEL_CHANNEL_BAR_PATH = "reel_channel_bar.eml";
|
||||
public static PivotBar pivotBar; // Set by patch.
|
||||
|
||||
private final StringFilterGroup channelBar;
|
||||
private final StringFilterGroup soundButton;
|
||||
private final StringFilterGroup infoPanel;
|
||||
private final StringFilterGroup shortsShelfHeader;
|
||||
|
||||
public ShortsFilter() {
|
||||
final var thanksButton = new StringFilterGroup(
|
||||
// Home / subscription feed components.
|
||||
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 soundButton = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS_SOUND_BUTTON,
|
||||
"reel_pivot_button"
|
||||
);
|
||||
|
||||
final var infoPanel = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS_INFO_PANEL,
|
||||
"shorts_info_panel_overview"
|
||||
);
|
||||
|
||||
final var channelBar = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS_CHANNEL_BAR,
|
||||
"reel_channel_bar"
|
||||
);
|
||||
|
||||
final var shorts = new StringFilterGroup(
|
||||
var shorts = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS,
|
||||
"shorts_shelf",
|
||||
"inline_shorts",
|
||||
"shorts_grid",
|
||||
"shorts_video_cell"
|
||||
"shorts_video_cell",
|
||||
"shorts_pivot_item"
|
||||
);
|
||||
// Use a different filter group for this pattern, as it requires an additional check after matching.
|
||||
shortsShelfHeader = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS,
|
||||
"shelf_header.eml"
|
||||
);
|
||||
identifierFilterGroupList.addAll(shorts, shortsShelfHeader, thanksButton);
|
||||
|
||||
shortsFilterGroup.addAll(soundButton, infoPanel);
|
||||
pathFilterGroups.addAll(joinButton, subscribeButton, channelBar);
|
||||
identifierFilterGroups.addAll(shorts, thanksButton);
|
||||
|
||||
// Shorts player components.
|
||||
var joinButton = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS_JOIN_BUTTON,
|
||||
"sponsor_button"
|
||||
);
|
||||
var subscribeButton = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS_SUBSCRIBE_BUTTON,
|
||||
"subscribe_button"
|
||||
);
|
||||
channelBar = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS_CHANNEL_BAR,
|
||||
REEL_CHANNEL_BAR_PATH
|
||||
);
|
||||
soundButton = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS_SOUND_BUTTON,
|
||||
"reel_pivot_button"
|
||||
);
|
||||
infoPanel = new StringFilterGroup(
|
||||
SettingsEnum.HIDE_SHORTS_INFO_PANEL,
|
||||
"shorts_info_panel_overview"
|
||||
);
|
||||
pathFilterGroupList.addAll(joinButton, subscribeButton, channelBar, soundButton, infoPanel);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(final String path, final String identifier,
|
||||
final byte[] protobufBufferArray) {
|
||||
boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
|
||||
FilterGroupList matchedList, FilterGroup matchedGroup, int matchedIndex) {
|
||||
if (matchedList == pathFilterGroupList) {
|
||||
// Always filter if matched.
|
||||
if (matchedGroup == soundButton || matchedGroup == infoPanel || matchedGroup == channelBar)
|
||||
return super.isFiltered(path, identifier, protobufBufferArray, matchedList, matchedGroup, matchedIndex);
|
||||
|
||||
// Filter the path only when reelChannelBar is visible.
|
||||
if (reelChannelBar.check(path).isFiltered())
|
||||
if (this.pathFilterGroups.contains(path)) return true;
|
||||
// Filter other path groups from pathFilterGroupList, only when reelChannelBar is visible
|
||||
// to avoid false positives.
|
||||
if (!path.startsWith(REEL_CHANNEL_BAR_PATH))
|
||||
return false;
|
||||
} else if (matchedGroup == shortsShelfHeader) {
|
||||
// Because the header is used in watch history and possibly other places, check for the index,
|
||||
// which is 0 when the shelf header is used for Shorts.
|
||||
if (matchedIndex != 0) return false;
|
||||
}
|
||||
|
||||
if (shortsFilterGroup.contains(path)) return true;
|
||||
|
||||
return this.identifierFilterGroups.contains(identifier);
|
||||
// Super class handles logging.
|
||||
return super.isFiltered(path, identifier, protobufBufferArray, matchedList, matchedGroup, matchedIndex);
|
||||
}
|
||||
|
||||
public static void hideShortsShelf(final View shortsShelfView) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package app.revanced.integrations.patches.components;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
// Abuse LithoFilter for OldVideoQualityMenuPatch.
|
||||
@@ -8,15 +10,16 @@ public final class VideoQualityMenuFilterPatch extends Filter {
|
||||
public static volatile boolean isVideoQualityMenuVisible;
|
||||
|
||||
public VideoQualityMenuFilterPatch() {
|
||||
pathFilterGroups.addAll(new StringFilterGroup(
|
||||
pathFilterGroupList.addAll(new StringFilterGroup(
|
||||
SettingsEnum.SHOW_OLD_VIDEO_QUALITY_MENU,
|
||||
"quick_quality_sheet_content.eml-js"
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(final String path, final String identifier, final byte[] protobufBufferArray) {
|
||||
isVideoQualityMenuVisible = super.isFiltered(path, identifier, protobufBufferArray);
|
||||
boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
|
||||
FilterGroupList matchedList, FilterGroup matchedGroup, int matchedIndex) {
|
||||
isVideoQualityMenuVisible = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package app.revanced.integrations.patches.components;
|
||||
|
||||
// Abuse LithoFilter for CustomVideoSpeedPatch.
|
||||
public final class VideoSpeedMenuFilterPatch extends Filter {
|
||||
// Must be volatile or synchronized, as litho filtering runs off main thread and this field is then access from the main thread.
|
||||
public static volatile boolean isVideoSpeedMenuVisible;
|
||||
|
||||
public VideoSpeedMenuFilterPatch() {
|
||||
pathFilterGroups.addAll(new StringFilterGroup(
|
||||
null,
|
||||
"playback_speed_sheet_content.eml-js"
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(final String path, final String identifier, final byte[] protobufBufferArray) {
|
||||
isVideoSpeedMenuVisible = super.isFiltered(path, identifier, protobufBufferArray);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,8 @@ public final class OldVideoQualityMenuPatch {
|
||||
// The quality menu is a RecyclerView with 3 children. The third child is the "Advanced" quality menu.
|
||||
addRecyclerListener(linearLayout, 3, 2, recyclerView -> {
|
||||
// Check if the current view is the quality menu.
|
||||
if (VideoQualityMenuFilterPatch.isVideoQualityMenuVisible) {// Hide the video quality menu.
|
||||
if (VideoQualityMenuFilterPatch.isVideoQualityMenuVisible) {
|
||||
VideoQualityMenuFilterPatch.isVideoQualityMenuVisible = false;
|
||||
linearLayout.setVisibility(View.GONE);
|
||||
|
||||
// Click the "Advanced" quality menu to show the "old" quality menu.
|
||||
|
||||
@@ -1,24 +1,21 @@
|
||||
package app.revanced.integrations.patches.playback.speed;
|
||||
|
||||
import static app.revanced.integrations.patches.playback.quality.OldVideoQualityMenuPatch.addRecyclerListener;
|
||||
|
||||
import android.preference.ListPreference;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import app.revanced.integrations.patches.components.PlaybackSpeedMenuFilterPatch;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
import com.facebook.litho.ComponentHost;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import app.revanced.integrations.patches.components.VideoSpeedMenuFilterPatch;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
import static app.revanced.integrations.patches.playback.quality.OldVideoQualityMenuPatch.addRecyclerListener;
|
||||
|
||||
public class CustomVideoSpeedPatch {
|
||||
public class CustomPlaybackSpeedPatch {
|
||||
/**
|
||||
* Maximum playback speed, exclusive value. Custom speeds must be less than this value.
|
||||
*/
|
||||
@@ -27,17 +24,17 @@ public class CustomVideoSpeedPatch {
|
||||
/**
|
||||
* Custom playback speeds.
|
||||
*/
|
||||
public static float[] customVideoSpeeds;
|
||||
public static float[] customPlaybackSpeeds;
|
||||
|
||||
/**
|
||||
* Minimum value of {@link #customVideoSpeeds}
|
||||
* Minimum value of {@link #customPlaybackSpeeds}
|
||||
*/
|
||||
public static float minVideoSpeed;
|
||||
public static float minPlaybackSpeed;
|
||||
|
||||
/**
|
||||
* Maxium value of {@link #customVideoSpeeds}
|
||||
* Maxium value of {@link #customPlaybackSpeeds}
|
||||
*/
|
||||
public static float maxVideoSpeed;
|
||||
public static float maxPlaybackSpeed;
|
||||
|
||||
/**
|
||||
* PreferenceList entries and values, of all available playback speeds.
|
||||
@@ -60,10 +57,10 @@ public class CustomVideoSpeedPatch {
|
||||
if (speedStrings.length == 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
customVideoSpeeds = new float[speedStrings.length];
|
||||
customPlaybackSpeeds = new float[speedStrings.length];
|
||||
for (int i = 0, length = speedStrings.length; i < length; i++) {
|
||||
final float speed = Float.parseFloat(speedStrings[i]);
|
||||
if (speed <= 0 || arrayContains(customVideoSpeeds, speed)) {
|
||||
if (speed <= 0 || arrayContains(customPlaybackSpeeds, speed)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (speed >= MAXIMUM_PLAYBACK_SPEED) {
|
||||
@@ -72,13 +69,13 @@ public class CustomVideoSpeedPatch {
|
||||
loadCustomSpeeds();
|
||||
return;
|
||||
}
|
||||
minVideoSpeed = Math.min(minVideoSpeed, speed);
|
||||
maxVideoSpeed = Math.max(maxVideoSpeed, speed);
|
||||
customVideoSpeeds[i] = speed;
|
||||
minPlaybackSpeed = Math.min(minPlaybackSpeed, speed);
|
||||
maxPlaybackSpeed = Math.max(maxPlaybackSpeed, speed);
|
||||
customPlaybackSpeeds[i] = speed;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printInfo(() -> "parse error", ex);
|
||||
resetCustomSpeeds("Invalid custom video speeds. Using default values.");
|
||||
resetCustomSpeeds("Invalid custom playback speeds. Using default values.");
|
||||
loadCustomSpeeds();
|
||||
}
|
||||
}
|
||||
@@ -95,10 +92,10 @@ public class CustomVideoSpeedPatch {
|
||||
*/
|
||||
public static void initializeListPreference(ListPreference preference) {
|
||||
if (preferenceListEntries == null) {
|
||||
preferenceListEntries = new String[customVideoSpeeds.length];
|
||||
preferenceListEntryValues = new String[customVideoSpeeds.length];
|
||||
preferenceListEntries = new String[customPlaybackSpeeds.length];
|
||||
preferenceListEntryValues = new String[customPlaybackSpeeds.length];
|
||||
int i = 0;
|
||||
for (float speed : customVideoSpeeds) {
|
||||
for (float speed : customPlaybackSpeeds) {
|
||||
String speedString = String.valueOf(speed);
|
||||
preferenceListEntries[i] = speedString + "x";
|
||||
preferenceListEntryValues[i] = speedString;
|
||||
@@ -110,28 +107,29 @@ public class CustomVideoSpeedPatch {
|
||||
}
|
||||
|
||||
/*
|
||||
* To reduce copy paste between two similar code paths.
|
||||
* To reduce copy and paste between two similar code paths.
|
||||
*/
|
||||
public static void onFlyoutMenuCreate(final LinearLayout linearLayout) {
|
||||
// The playback rate menu is a RecyclerView with 2 children. The third child is the "Advanced" quality menu.
|
||||
addRecyclerListener(linearLayout, 2, 1, recyclerView -> {
|
||||
if (VideoSpeedMenuFilterPatch.isVideoSpeedMenuVisible &&
|
||||
recyclerView.getChildCount() == 1 &&
|
||||
recyclerView.getChildAt(0) instanceof ComponentHost
|
||||
) {
|
||||
linearLayout.setVisibility(View.GONE);
|
||||
if (PlaybackSpeedMenuFilterPatch.isPlaybackSpeedMenuVisible) {
|
||||
PlaybackSpeedMenuFilterPatch.isPlaybackSpeedMenuVisible = false;
|
||||
|
||||
// Close the new video speed menu and instead show the old one.
|
||||
showOldVideoSpeedMenu();
|
||||
if (recyclerView.getChildCount() == 1 && recyclerView.getChildAt(0) instanceof ComponentHost) {
|
||||
linearLayout.setVisibility(View.GONE);
|
||||
|
||||
// DismissView [R.id.touch_outside] is the 1st ChildView of the 3rd ParentView.
|
||||
((ViewGroup) linearLayout.getParent().getParent().getParent())
|
||||
.getChildAt(0).performClick();
|
||||
// Close the new Playback speed menu and instead show the old one.
|
||||
showOldPlaybackSpeedMenu();
|
||||
|
||||
// DismissView [R.id.touch_outside] is the 1st ChildView of the 3rd ParentView.
|
||||
((ViewGroup) linearLayout.getParent().getParent().getParent())
|
||||
.getChildAt(0).performClick();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void showOldVideoSpeedMenu() {
|
||||
public static void showOldPlaybackSpeedMenu() {
|
||||
LogHelper.printDebug(() -> "Old video quality menu shown");
|
||||
|
||||
// Rest of the implementation added by patch.
|
||||
@@ -18,6 +18,7 @@ import app.revanced.integrations.settings.SettingsEnum;
|
||||
*/
|
||||
public class ProgressBarDrawable extends Drawable {
|
||||
|
||||
|
||||
private final Paint paint = new Paint();
|
||||
|
||||
@Override
|
||||
@@ -25,7 +26,7 @@ public class ProgressBarDrawable extends Drawable {
|
||||
if (SettingsEnum.HIDE_SEEKBAR_THUMBNAIL.getBoolean()) {
|
||||
return;
|
||||
}
|
||||
paint.setColor(SeekbarColorPatch.getCustomSeekbarColor());
|
||||
paint.setColor(SeekbarColorPatch.getSeekbarColor());
|
||||
canvas.drawRect(getBounds(), paint);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,10 @@ import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
public final class SeekbarColorPatch {
|
||||
|
||||
private static final boolean USE_SEEKBAR_CUSTOM_COLOR = SettingsEnum.SEEKBAR_CUSTOM_COLOR.getBoolean();
|
||||
|
||||
/**
|
||||
* Default color of seekbar.
|
||||
* Default color of the seekbar.
|
||||
*/
|
||||
private static final int ORIGINAL_SEEKBAR_COLOR = 0xFFFF0000;
|
||||
|
||||
@@ -19,9 +21,11 @@ public final class SeekbarColorPatch {
|
||||
private static final float ORIGINAL_SEEKBAR_COLOR_BRIGHTNESS;
|
||||
|
||||
/**
|
||||
* Color value of {@link SettingsEnum#SEEKBAR_COLOR}
|
||||
* If {@link SettingsEnum#SEEKBAR_CUSTOM_COLOR} is enabled,
|
||||
* this is the color value of {@link SettingsEnum#SEEKBAR_CUSTOM_COLOR_VALUE}.
|
||||
* Otherwise this is {@link #ORIGINAL_SEEKBAR_COLOR}.
|
||||
*/
|
||||
private static int customSeekbarColor;
|
||||
private static int seekbarColor = ORIGINAL_SEEKBAR_COLOR;
|
||||
|
||||
/**
|
||||
* Custom seekbar hue, saturation, and brightness values.
|
||||
@@ -33,22 +37,24 @@ public final class SeekbarColorPatch {
|
||||
Color.colorToHSV(ORIGINAL_SEEKBAR_COLOR, hsv);
|
||||
ORIGINAL_SEEKBAR_COLOR_BRIGHTNESS = hsv[2];
|
||||
|
||||
loadCustomSeekbarColorHSV();
|
||||
}
|
||||
|
||||
private static void loadCustomSeekbarColorHSV() {
|
||||
try {
|
||||
customSeekbarColor = Color.parseColor(SettingsEnum.SEEKBAR_COLOR.getString());
|
||||
Color.colorToHSV(customSeekbarColor, customSeekbarColorHSV);
|
||||
} catch (Exception ex) {
|
||||
ReVancedUtils.showToastShort("Invalid seekbar color value. Using default value.");
|
||||
SettingsEnum.SEEKBAR_COLOR.saveValue(SettingsEnum.SEEKBAR_COLOR.defaultValue);
|
||||
loadCustomSeekbarColorHSV();
|
||||
if (USE_SEEKBAR_CUSTOM_COLOR) {
|
||||
loadCustomSeekbarColor();
|
||||
}
|
||||
}
|
||||
|
||||
public static int getCustomSeekbarColor() {
|
||||
return customSeekbarColor;
|
||||
private static void loadCustomSeekbarColor() {
|
||||
try {
|
||||
seekbarColor = Color.parseColor(SettingsEnum.SEEKBAR_CUSTOM_COLOR_VALUE.getString());
|
||||
Color.colorToHSV(seekbarColor, customSeekbarColorHSV);
|
||||
} catch (Exception ex) {
|
||||
ReVancedUtils.showToastShort("Invalid seekbar color value. Using default value.");
|
||||
SettingsEnum.SEEKBAR_CUSTOM_COLOR_VALUE.saveValue(SettingsEnum.SEEKBAR_CUSTOM_COLOR_VALUE.defaultValue);
|
||||
loadCustomSeekbarColor();
|
||||
}
|
||||
}
|
||||
|
||||
public static int getSeekbarColor() {
|
||||
return seekbarColor;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +102,7 @@ public final class SeekbarColorPatch {
|
||||
*/
|
||||
private static int getSeekbarColorValue(int originalColor) {
|
||||
try {
|
||||
if (customSeekbarColor == ORIGINAL_SEEKBAR_COLOR) {
|
||||
if (!USE_SEEKBAR_CUSTOM_COLOR || originalColor == seekbarColor) {
|
||||
return originalColor; // nothing to do
|
||||
}
|
||||
final int alphaDifference = Color.alpha(originalColor) - Color.alpha(ORIGINAL_SEEKBAR_COLOR);
|
||||
@@ -111,7 +117,7 @@ public final class SeekbarColorPatch {
|
||||
hsv[1] = customSeekbarColorHSV[1];
|
||||
hsv[2] = clamp(customSeekbarColorHSV[2] + brightnessDifference, 0, 1);
|
||||
|
||||
final int replacementAlpha = clamp(Color.alpha(customSeekbarColor) + alphaDifference, 0, 255);
|
||||
final int replacementAlpha = clamp(Color.alpha(seekbarColor) + alphaDifference, 0, 255);
|
||||
final int replacementColor = Color.HSVToColor(replacementAlpha, hsv);
|
||||
LogHelper.printDebug(() -> String.format("Original color: #%08X replacement color: #%08X",
|
||||
originalColor, replacementColor));
|
||||
|
||||
@@ -255,7 +255,7 @@ public class ReturnYouTubeDislike {
|
||||
// If a Short is opened while a regular video is on screen, this will incorrectly set this as false.
|
||||
// But this check is needed to fix unusual situations of opening/closing the app
|
||||
// while both a regular video and a short are on screen.
|
||||
dislikeDataIsShort = currentPlayerType.isNoneHiddenOrMinimized();
|
||||
dislikeDataIsShort = currentPlayerType.isNoneOrHidden();
|
||||
|
||||
RYDCachedFetch entry = futureCache.get(videoId);
|
||||
if (entry != null && entry.futureInProgressOrFinishedSuccessfully()) {
|
||||
@@ -371,7 +371,7 @@ public class ReturnYouTubeDislike {
|
||||
// Must make a local copy of videoId, since it may change between now and when the vote thread runs.
|
||||
String videoIdToVoteFor = getCurrentVideoId();
|
||||
if (videoIdToVoteFor == null ||
|
||||
(SettingsEnum.RYD_SHORTS.getBoolean() && dislikeDataIsShort != PlayerType.getCurrent().isNoneHiddenOrMinimized())) {
|
||||
(SettingsEnum.RYD_SHORTS.getBoolean() && dislikeDataIsShort != PlayerType.getCurrent().isNoneOrHidden())) {
|
||||
// User enabled RYD after starting playback of a video.
|
||||
// Or shorts was loaded with regular video present, then shorts was closed,
|
||||
// and then user voted on the now visible original video.
|
||||
|
||||
@@ -1,26 +1,12 @@
|
||||
package app.revanced.integrations.settings;
|
||||
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static app.revanced.integrations.settings.SettingsEnum.ReturnType.BOOLEAN;
|
||||
import static app.revanced.integrations.settings.SettingsEnum.ReturnType.FLOAT;
|
||||
import static app.revanced.integrations.settings.SettingsEnum.ReturnType.INTEGER;
|
||||
import static app.revanced.integrations.settings.SettingsEnum.ReturnType.LONG;
|
||||
import static app.revanced.integrations.settings.SettingsEnum.ReturnType.STRING;
|
||||
import static app.revanced.integrations.settings.SharedPrefCategory.RETURN_YOUTUBE_DISLIKE;
|
||||
import static app.revanced.integrations.settings.SharedPrefCategory.SPONSOR_BLOCK;
|
||||
import static app.revanced.integrations.utils.StringRef.str;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import app.revanced.integrations.sponsorblock.SponsorBlockSettings;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
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;
|
||||
|
||||
@@ -29,6 +15,13 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static app.revanced.integrations.settings.SettingsEnum.ReturnType.*;
|
||||
import static app.revanced.integrations.settings.SharedPrefCategory.RETURN_YOUTUBE_DISLIKE;
|
||||
import static app.revanced.integrations.settings.SharedPrefCategory.SPONSOR_BLOCK;
|
||||
import static app.revanced.integrations.utils.StringRef.str;
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
|
||||
|
||||
public enum SettingsEnum {
|
||||
// External downloader
|
||||
@@ -89,12 +82,18 @@ public enum SettingsEnum {
|
||||
|
||||
// Action buttons
|
||||
HIDE_LIKE_DISLIKE_BUTTON("revanced_hide_like_dislike_button", BOOLEAN, FALSE),
|
||||
HIDE_LIVE_CHAT_BUTTON("revanced_hide_live_chat_button", BOOLEAN, FALSE),
|
||||
HIDE_SHARE_BUTTON("revanced_hide_share_button", BOOLEAN, FALSE),
|
||||
HIDE_REPORT_BUTTON("revanced_hide_report_button", BOOLEAN, FALSE),
|
||||
HIDE_REMIX_BUTTON("revanced_hide_remix_button", BOOLEAN, TRUE),
|
||||
HIDE_DOWNLOAD_BUTTON("revanced_hide_download_button", BOOLEAN, FALSE),
|
||||
HIDE_THANKS_BUTTON("revanced_hide_thanks_button", BOOLEAN, TRUE),
|
||||
HIDE_CLIP_BUTTON("revanced_hide_clip_button", BOOLEAN, TRUE),
|
||||
HIDE_PLAYLIST_BUTTON("revanced_hide_playlist_button", BOOLEAN, FALSE),
|
||||
HIDE_CLIP_BUTTON("revanced_hide_clip_button", BOOLEAN, FALSE, "revanced_hide_clip_button_user_dialog_message"),
|
||||
HIDE_ACTION_BUTTONS("revanced_hide_action_buttons", BOOLEAN, FALSE),
|
||||
HIDE_SHOP_BUTTON("revanced_hide_shop_button", BOOLEAN, TRUE),
|
||||
|
||||
// Layout
|
||||
PLAYER_OVERLAY_OPACITY("revanced_player_overlay_opacity", INTEGER, 100, true),
|
||||
DISABLE_RESUMING_SHORTS_PLAYER("revanced_disable_resuming_shorts_player", BOOLEAN, FALSE),
|
||||
HIDE_ALBUM_CARDS("revanced_hide_album_cards", BOOLEAN, FALSE, true),
|
||||
HIDE_ARTIST_CARDS("revanced_hide_artist_cards", BOOLEAN, FALSE),
|
||||
@@ -105,6 +104,7 @@ public enum SettingsEnum {
|
||||
HIDE_CAST_BUTTON("revanced_hide_cast_button", BOOLEAN, TRUE, true),
|
||||
HIDE_COMMENTS_SECTION("revanced_hide_comments_section", BOOLEAN, FALSE, true),
|
||||
HIDE_CREATE_BUTTON("revanced_hide_create_button", BOOLEAN, TRUE, true),
|
||||
HIDE_CHIPS_SHELF("revanced_hide_chips_shelf", BOOLEAN, TRUE),
|
||||
HIDE_CROWDFUNDING_BOX("revanced_hide_crowdfunding_box", BOOLEAN, FALSE, true),
|
||||
HIDE_EMAIL_ADDRESS("revanced_hide_email_address", BOOLEAN, FALSE),
|
||||
HIDE_ENDSCREEN_CARDS("revanced_hide_endscreen_cards", BOOLEAN, TRUE),
|
||||
@@ -114,23 +114,23 @@ public enum SettingsEnum {
|
||||
HIDE_INFO_CARDS("revanced_hide_info_cards", BOOLEAN, TRUE),
|
||||
HIDE_LOAD_MORE_BUTTON("revanced_hide_load_more_button", BOOLEAN, TRUE, true),
|
||||
HIDE_PLAYER_BUTTONS("revanced_hide_player_buttons", BOOLEAN, FALSE),
|
||||
HIDE_PLAYER_OVERLAY("revanced_hide_player_overlay", BOOLEAN, FALSE, true),
|
||||
HIDE_PREVIEW_COMMENT("revanced_hide_preview_comment", BOOLEAN, FALSE, true),
|
||||
HIDE_SEEKBAR("revanced_hide_seekbar", BOOLEAN, FALSE, true),
|
||||
HIDE_SEEKBAR_THUMBNAIL("revanced_hide_seekbar_thumbnail", BOOLEAN, FALSE, true),
|
||||
HIDE_SEEKBAR("revanced_hide_seekbar", BOOLEAN, FALSE),
|
||||
HIDE_SEEKBAR_THUMBNAIL("revanced_hide_seekbar_thumbnail", BOOLEAN, FALSE),
|
||||
HIDE_HOME_BUTTON("revanced_hide_home_button", BOOLEAN, FALSE, true),
|
||||
HIDE_SHORTS_BUTTON("revanced_hide_shorts_button", BOOLEAN, TRUE, true),
|
||||
HIDE_SUBSCRIPTIONS_BUTTON("revanced_hide_subscriptions_button", BOOLEAN, FALSE, true),
|
||||
HIDE_TIMESTAMP("revanced_hide_timestamp", BOOLEAN, FALSE),
|
||||
HIDE_VIDEO_WATERMARK("revanced_hide_video_watermark", BOOLEAN, TRUE),
|
||||
HIDE_WATCH_IN_VR("revanced_hide_watch_in_vr", BOOLEAN, FALSE, true),
|
||||
PLAYER_POPUP_PANELS("revanced_hide_player_popup_panels", BOOLEAN, FALSE),
|
||||
SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON("revanced_switch_create_with_notifications_button", BOOLEAN, TRUE, true),
|
||||
SPOOF_APP_VERSION("revanced_spoof_app_version", BOOLEAN, FALSE, true, "revanced_spoof_app_version_user_dialog_message"),
|
||||
SPOOF_APP_VERSION_TARGET("revanced_spoof_app_version_target", STRING, "17.30.35", true, parents(SPOOF_APP_VERSION)),
|
||||
SPOOF_APP_VERSION_TARGET("revanced_spoof_app_version_target", STRING, "17.08.35", true, parents(SPOOF_APP_VERSION)),
|
||||
USE_TABLET_MINIPLAYER("revanced_tablet_miniplayer", BOOLEAN, FALSE, true),
|
||||
TABLET_LAYOUT("revanced_tablet_layout", BOOLEAN, FALSE, true, "revanced_tablet_layout_user_dialog_message"),
|
||||
WIDE_SEARCHBAR("revanced_wide_searchbar", BOOLEAN, FALSE, true),
|
||||
SEEKBAR_COLOR("revanced_seekbar_color", STRING, "#FF0000", true),
|
||||
SEEKBAR_CUSTOM_COLOR("revanced_seekbar_custom_color", BOOLEAN, TRUE, true),
|
||||
SEEKBAR_CUSTOM_COLOR_VALUE("revanced_seekbar_custom_color_value", STRING, "#FF0000", true, parents(SEEKBAR_CUSTOM_COLOR)),
|
||||
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),
|
||||
@@ -146,13 +146,30 @@ public enum SettingsEnum {
|
||||
HIDE_SHORTS_NAVIGATION_BAR("revanced_hide_shorts_navigation_bar", BOOLEAN, TRUE, true),
|
||||
HIDE_SHORTS("revanced_hide_shorts", BOOLEAN, FALSE, true),
|
||||
|
||||
ALT_THUMBNAIL("revanced_alt_thumbnail", BOOLEAN, FALSE),
|
||||
ALT_THUMBNAIL_TYPE("revanced_alt_thumbnail_type", INTEGER, 2, parents(ALT_THUMBNAIL)),
|
||||
ALT_THUMBNAIL_FAST_QUALITY("revanced_alt_thumbnail_fast_quality", BOOLEAN, FALSE, parents(ALT_THUMBNAIL)),
|
||||
|
||||
//Player flyout menu items
|
||||
HIDE_QUALITY_MENU("revanced_hide_player_flyout_quality", BOOLEAN, FALSE),
|
||||
HIDE_CAPTIONS_MENU("revanced_hide_player_flyout_captions", BOOLEAN, FALSE),
|
||||
HIDE_LOOP_VIDEO_MENU("revanced_hide_player_flyout_loop_video", BOOLEAN, FALSE),
|
||||
HIDE_AMBIENT_MODE_MENU("revanced_hide_player_flyout_ambient_mode", BOOLEAN, FALSE),
|
||||
HIDE_REPORT_MENU("revanced_hide_player_flyout_report", BOOLEAN, TRUE),
|
||||
HIDE_HELP_MENU("revanced_hide_player_flyout_help", BOOLEAN, TRUE),
|
||||
HIDE_SPEED_MENU("revanced_hide_player_flyout_speed", BOOLEAN, FALSE),
|
||||
HIDE_MORE_INFO_MENU("revanced_hide_player_flyout_more_info", BOOLEAN, TRUE),
|
||||
HIDE_AUDIO_TRACK_MENU("revanced_hide_player_flyout_audio_track", BOOLEAN, FALSE),
|
||||
HIDE_WATCH_IN_VR_MENU("revanced_hide_player_flyout_watch_in_vr", BOOLEAN, 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),
|
||||
SEEKBAR_TAPPING("revanced_seekbar_tapping", BOOLEAN, TRUE),
|
||||
SPOOF_SIGNATURE_VERIFICATION("revanced_spoof_signature_verification", BOOLEAN, TRUE, "revanced_spoof_signature_verification_user_dialog_message"),
|
||||
SPOOF_SIGNATURE_VERIFICATION("revanced_spoof_signature_verification", BOOLEAN, TRUE, true,
|
||||
"revanced_spoof_signature_verification_user_dialog_message"),
|
||||
|
||||
// Swipe controls
|
||||
SWIPE_BRIGHTNESS("revanced_swipe_brightness", BOOLEAN, TRUE),
|
||||
@@ -175,6 +192,7 @@ public enum SettingsEnum {
|
||||
// Debugging
|
||||
DEBUG("revanced_debug", BOOLEAN, FALSE),
|
||||
DEBUG_STACKTRACE("revanced_debug_stacktrace", BOOLEAN, FALSE, parents(DEBUG)),
|
||||
DEBUG_PROTOBUFFER("revanced_debug_protobuffer", BOOLEAN, FALSE, parents(DEBUG)),
|
||||
DEBUG_TOAST_ON_ERROR("revanced_debug_toast_on_error", BOOLEAN, TRUE, "revanced_debug_toast_on_error_user_dialog_message"),
|
||||
|
||||
// ReturnYoutubeDislike
|
||||
|
||||
@@ -80,12 +80,24 @@ public enum SharedPrefCategory {
|
||||
@NonNull
|
||||
public String getString(@NonNull String key, @NonNull String _default) {
|
||||
Objects.requireNonNull(_default);
|
||||
return preferences.getString(key, _default);
|
||||
try {
|
||||
return preferences.getString(key, _default);
|
||||
} catch (ClassCastException ex) {
|
||||
// Value stored is a completely different type (should never happen).
|
||||
removeConflictingPreferenceKeyValue(key);
|
||||
return _default;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean getBoolean(@NonNull String key, boolean _default) {
|
||||
return preferences.getBoolean(key, _default);
|
||||
try {
|
||||
return preferences.getBoolean(key, _default);
|
||||
} catch (ClassCastException ex) {
|
||||
// Value stored is a completely different type (should never happen).
|
||||
removeConflictingPreferenceKeyValue(key);
|
||||
return _default;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
||||
@@ -24,7 +24,7 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.apps.youtube.app.application.Shell_HomeActivity;
|
||||
|
||||
import app.revanced.integrations.patches.playback.speed.CustomVideoSpeedPatch;
|
||||
import app.revanced.integrations.patches.playback.speed.CustomPlaybackSpeedPatch;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.settings.SharedPrefCategory;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
@@ -135,7 +135,7 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
|
||||
// if the preference was included, then initialize it based on the available playback speed
|
||||
Preference defaultSpeedPreference = findPreference(SettingsEnum.PLAYBACK_SPEED_DEFAULT.path);
|
||||
if (defaultSpeedPreference instanceof ListPreference) {
|
||||
CustomVideoSpeedPatch.initializeListPreference((ListPreference) defaultSpeedPreference);
|
||||
CustomPlaybackSpeedPatch.initializeListPreference((ListPreference) defaultSpeedPreference);
|
||||
}
|
||||
|
||||
// Set current value from SettingsEnum
|
||||
|
||||
@@ -18,7 +18,7 @@ enum class PlayerType {
|
||||
HIDDEN,
|
||||
/**
|
||||
* When spoofing to 16.x YouTube and watching a short with a regular video in the background,
|
||||
* the type will be this (and not [HIDDEN]).
|
||||
* the type can be this (and not [HIDDEN]).
|
||||
*/
|
||||
WATCH_WHILE_MINIMIZED,
|
||||
WATCH_WHILE_MAXIMIZED,
|
||||
|
||||
@@ -50,7 +50,7 @@ public class SegmentPlaybackController {
|
||||
private static SponsorSegment[] segments;
|
||||
|
||||
/**
|
||||
* Highlight segment, if one exists.
|
||||
* Highlight segment, if one exists and the skip behavior is not set to {@link CategoryBehaviour#SHOW_IN_SEEKBAR}.
|
||||
*/
|
||||
@Nullable
|
||||
private static SponsorSegment highlightSegment;
|
||||
@@ -112,10 +112,13 @@ public class SegmentPlaybackController {
|
||||
segments = videoSegments;
|
||||
calculateTimeWithoutSegments();
|
||||
|
||||
for (SponsorSegment segment : videoSegments) {
|
||||
if (segment.category == SegmentCategory.HIGHLIGHT) {
|
||||
highlightSegment = segment;
|
||||
return;
|
||||
if (SegmentCategory.HIGHLIGHT.behaviour == CategoryBehaviour.SKIP_AUTOMATICALLY
|
||||
|| SegmentCategory.HIGHLIGHT.behaviour == CategoryBehaviour.MANUAL_SKIP) {
|
||||
for (SponsorSegment segment : videoSegments) {
|
||||
if (segment.category == SegmentCategory.HIGHLIGHT) {
|
||||
highlightSegment = segment;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
highlightSegment = null;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package app.revanced.integrations.utils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class ByteTrieSearch extends TrieSearch<byte[]> {
|
||||
|
||||
private static final class ByteTrieNode extends TrieNode<byte[]> {
|
||||
TrieNode<byte[]> createNode() {
|
||||
return new ByteTrieNode();
|
||||
}
|
||||
char getCharValue(byte[] text, int index) {
|
||||
return (char) text[index];
|
||||
}
|
||||
}
|
||||
|
||||
public ByteTrieSearch() {
|
||||
super(new ByteTrieNode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPattern(@NonNull byte[] pattern) {
|
||||
super.addPattern(pattern, pattern.length, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPattern(@NonNull byte[] pattern, @NonNull TriePatternMatchedCallback<byte[]> callback) {
|
||||
super.addPattern(pattern, pattern.length, Objects.requireNonNull(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(@NonNull byte[] textToSearch, int startIndex, int endIndex, @Nullable Object callbackParameter) {
|
||||
return super.matches(textToSearch, textToSearch.length, startIndex, endIndex, callbackParameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(@NonNull byte[] textToSearch, int startIndex) {
|
||||
return matches(textToSearch, startIndex, textToSearch.length, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(@NonNull byte[] textToSearch, @Nullable Object callbackParameter) {
|
||||
return matches(textToSearch,0, textToSearch.length, callbackParameter);
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user