chore: merge branch dev to main (#431)

This commit is contained in:
oSumAtrIX 2023-07-08 04:32:50 +02:00 committed by GitHub
commit cfc7081971
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 430 additions and 399 deletions

9
.gitattributes vendored Normal file
View File

@ -0,0 +1,9 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# Linux start script should use lf
/gradlew text eol=lf
# These are Windows script files and should use crlf
*.bat text eol=crlf

View File

@ -1,3 +1,31 @@
# [0.112.0-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.112.0-dev.2...v0.112.0-dev.3) (2023-07-08)
### Bug Fixes
* **youtube/hide-layout-components:** hide mix playlists ([789e0c8](https://github.com/revanced/revanced-integrations/commit/789e0c8bcb1c2e964abcc496144d2f614c36fc0e))
# [0.112.0-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.112.0-dev.1...v0.112.0-dev.2) (2023-07-07)
### Features
* **youtube:** support version `18.23.35` ([#433](https://github.com/revanced/revanced-integrations/issues/433)) ([dec7348](https://github.com/revanced/revanced-integrations/commit/dec73482038b3cc8b2031fd876643f89d937d142))
# [0.112.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.111.3-dev.1...v0.112.0-dev.1) (2023-07-05)
### Features
* remove unnecessary notice ([be3955f](https://github.com/revanced/revanced-integrations/commit/be3955fee45d22966006156a5475ef91b6f2b981))
## [0.111.3-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.111.2...v0.111.3-dev.1) (2023-07-05)
### Bug Fixes
* **youtube/hide-ads:** remove duplicate filter ([#432](https://github.com/revanced/revanced-integrations/issues/432)) ([ea7ee56](https://github.com/revanced/revanced-integrations/commit/ea7ee56276a4a88f156a06c8f614360561231908))
## [0.111.2](https://github.com/revanced/revanced-integrations/compare/v0.111.1...v0.111.2) (2023-07-03)

View File

@ -2,22 +2,21 @@ package app.revanced.integrations.patches.components;
import android.os.Build;
import android.view.View;
import androidx.annotation.RequiresApi;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.ReVancedUtils;
@RequiresApi(api = Build.VERSION_CODES.N)
public final class LayoutComponentsFilter extends Filter {
private final String[] exceptions;
private final CustomFilterGroup custom;
// region Mix playlists
private final ByteArrayAsStringFilterGroup mixPlaylists;
private final ByteArrayAsStringFilterGroup imageHosting;
// endregion
private static final ByteArrayAsStringFilterGroup mixPlaylists = new ByteArrayAsStringFilterGroup(
SettingsEnum.HIDE_MIX_PLAYLISTS,
"&list="
);
@RequiresApi(api = Build.VERSION_CODES.N)
public LayoutComponentsFilter() {
@ -137,21 +136,6 @@ public final class LayoutComponentsFilter extends Filter {
"cell_divider" // layout residue (gray line above the buttoned ad),
);
// region Mix playlists
mixPlaylists = new ByteArrayAsStringFilterGroup(
SettingsEnum.HIDE_MIX_PLAYLISTS,
"&list=",
"YouTube Music"
);
imageHosting = new ByteArrayAsStringFilterGroup(
SettingsEnum.HIDE_MIX_PLAYLISTS, // Unused
"ggpht.com"
);
// endregion
this.pathFilterGroups.addAll(
channelBar,
communityPosts,
@ -174,27 +158,7 @@ public final class LayoutComponentsFilter extends Filter {
channelMemberShelf
);
final var carouselAd = new StringFilterGroup(
SettingsEnum.HIDE_GENERAL_ADS,
"carousel_ad"
);
this.identifierFilterGroups.addAll(
graySeparator,
carouselAd
);
}
private boolean isMixPlaylistFiltered(final byte[] _protobufBufferArray) {
if (!mixPlaylists.isEnabled()) return false;
// Two checks are required to prevent false positives.
// First check if the current buffer potentially contains a mix playlist.
if (!mixPlaylists.check(_protobufBufferArray).isFiltered()) return false;
// Ensure that the buffer actually contains a mix playlist.
return imageHosting.check(_protobufBufferArray).isFiltered();
this.identifierFilterGroups.addAll(graySeparator);
}
@Override
@ -205,18 +169,12 @@ public final class LayoutComponentsFilter extends Filter {
if (ReVancedUtils.containsAny(path, exceptions))
return false; // Exceptions are not filtered.
if (super.isFiltered(path, identifier, _protobufBufferArray))
return true;
return isMixPlaylistFiltered(_protobufBufferArray);
return super.isFiltered(path, identifier, _protobufBufferArray);
}
/**
* Hide the view, which shows ads in the homepage.
*
* @param view The view, which shows ads.
*/
public static void hideAdAttributionView(View view) {
ReVancedUtils.hideViewBy1dpUnderCondition(SettingsEnum.HIDE_GENERAL_ADS, view);
// Called from a different place then the other filters.
public static boolean filterMixPlaylists(final byte[] bytes) {
return mixPlaylists.isEnabled() && mixPlaylists.check(bytes).isFiltered();
}
}

View File

@ -1,11 +1,9 @@
package app.revanced.integrations.patches.components;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@ -14,6 +12,10 @@ import java.util.Iterator;
import java.util.Spliterator;
import java.util.function.Consumer;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils;
abstract class FilterGroup<T> {
final static class FilterGroupResult {
private final boolean filtered;
@ -49,7 +51,7 @@ abstract class FilterGroup<T> {
}
public boolean isEnabled() {
return setting.getBoolean();
return setting == null || setting.getBoolean();
}
public abstract FilterGroupResult check(final T stack);
@ -208,7 +210,7 @@ abstract class Filter {
/**
* Check if the given path, identifier or protobuf buffer is filtered by any
* {@link FilterGroup}.
* {@link FilterGroup}. Method is called off the main thread.
*
* @return True if filtered, false otherwise.
*/
@ -239,9 +241,12 @@ public final class LithoFilterPatch {
new DummyFilter() // Replaced by patch.
};
/**
* Injection point. Called off the main thread.
*/
@SuppressWarnings("unused")
public static boolean filter(final StringBuilder pathBuilder, final String identifier,
final ByteBuffer protobufBuffer) {
final ByteBuffer protobufBuffer) {
// TODO: Maybe this can be moved to the Filter class, to prevent unnecessary
// string creation
// because some filters might not need the path.

View File

@ -0,0 +1,23 @@
package app.revanced.integrations.patches.components;
import app.revanced.integrations.settings.SettingsEnum;
// Abuse LithoFilter for OldVideoQualityMenuPatch.
public final class VideoQualityMenuFilterPatch 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 isVideoQualityMenuVisible;
public VideoQualityMenuFilterPatch() {
pathFilterGroups.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);
return false;
}
}

View File

@ -0,0 +1,21 @@
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;
}
}

View File

@ -1,35 +0,0 @@
package app.revanced.integrations.patches.playback.quality;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
public class OldQualityLayoutPatch {
public static void showOldQualityMenu(ListView listView)
{
if (!SettingsEnum.SHOW_OLD_VIDEO_MENU.getBoolean()) return;
listView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
@Override
public void onChildViewAdded(View parent, View child) {
LogHelper.printDebug(() -> "Added: " + child);
parent.setVisibility(View.GONE);
final var indexOfAdvancedQualityMenuItem = 4;
if (listView.indexOfChild(child) != indexOfAdvancedQualityMenuItem) return;
LogHelper.printDebug(() -> "Found advanced menu: " + child);
final var qualityItemMenuPosition = 4;
listView.performItemClick(null, qualityItemMenuPosition, 0);
}
@Override
public void onChildViewRemoved(View parent, View child) {}
});
}
}

View File

@ -0,0 +1,94 @@
package app.revanced.integrations.patches.playback.quality;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.LinearLayout;
import android.widget.ListView;
import androidx.annotation.NonNull;
import app.revanced.integrations.patches.components.VideoQualityMenuFilterPatch;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
import com.facebook.litho.ComponentHost;
import kotlin.Deprecated;
// This patch contains the logic to show the old video quality menu.
// Two methods are required, because the quality menu is a RecyclerView in the new YouTube version
// and a ListView in the old one.
public final class OldVideoQualityMenuPatch {
public static void onFlyoutMenuCreate(final LinearLayout linearLayout) {
if (!SettingsEnum.SHOW_OLD_VIDEO_QUALITY_MENU.getBoolean()) return;
// 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.
linearLayout.setVisibility(View.GONE);
// Click the "Advanced" quality menu to show the "old" quality menu.
((ComponentHost) recyclerView.getChildAt(0)).getChildAt(3).performClick();
LogHelper.printDebug(() -> "Advanced quality menu in new type of quality menu clicked");
}
});
}
public static void addRecyclerListener(@NonNull LinearLayout linearLayout,
int expectedLayoutChildCount, int recyclerViewIndex,
@NonNull RecyclerViewGlobalLayoutListener listener) {
if (linearLayout.getChildCount() != expectedLayoutChildCount) return;
var layoutChild = linearLayout.getChildAt(recyclerViewIndex);
if (!(layoutChild instanceof RecyclerView)) return;
final var recyclerView = (RecyclerView) layoutChild;
recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
try {
listener.recyclerOnGlobalLayout(recyclerView);
} catch (Exception ex) {
LogHelper.printException(() -> "addRecyclerListener failure", ex);
} finally {
// Remove the listener because it will be added again.
recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
}
);
}
public interface RecyclerViewGlobalLayoutListener {
void recyclerOnGlobalLayout(@NonNull RecyclerView recyclerView);
}
@Deprecated(message = "This patch is deprecated because the quality menu is not a ListView anymore")
public static void showOldVideoQualityMenu(final ListView listView) {
if (!SettingsEnum.SHOW_OLD_VIDEO_QUALITY_MENU.getBoolean()) return;
listView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
@Override
public void onChildViewAdded(View parent, View child) {
LogHelper.printDebug(() -> "Added listener to old type of quality menu");
parent.setVisibility(View.GONE);
final var indexOfAdvancedQualityMenuItem = 4;
if (listView.indexOfChild(child) != indexOfAdvancedQualityMenuItem) return;
LogHelper.printDebug(() -> "Found advanced menu item in old type of quality menu");
final var qualityItemMenuPosition = 4;
listView.performItemClick(null, qualityItemMenuPosition, 0);
}
@Override
public void onChildViewRemoved(View parent, View child) {
}
});
}
}

View File

@ -38,13 +38,8 @@ public class RememberVideoQualityPatch {
private static List<Integer> videoQualities;
private static void changeDefaultQuality(int defaultQuality) {
NetworkType networkType = ReVancedUtils.getNetworkType();
if (networkType == NetworkType.NONE) {
ReVancedUtils.showToastShort("No internet connection");
return;
}
String networkTypeMessage;
if (networkType == NetworkType.MOBILE) {
if (ReVancedUtils.getNetworkType() == NetworkType.MOBILE) {
mobileQualitySetting.saveValue(defaultQuality);
networkTypeMessage = "mobile";
} else {
@ -139,15 +134,24 @@ public class RememberVideoQualityPatch {
}
/**
* Injection point.
* Injection point. Old quality menu.
*/
public static void userChangedQuality(int selectedQuality) {
public static void userChangedQuality(int selectedQualityIndex) {
if (!SettingsEnum.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.getBoolean()) return;
userSelectedQualityIndex = selectedQuality;
userSelectedQualityIndex = selectedQualityIndex;
userChangedDefaultQuality = true;
}
/**
* Injection point. New quality menu.
*/
public static void userChangedQualityInNewFlyout(int selectedQuality) {
if (!SettingsEnum.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.getBoolean()) return;
changeDefaultQuality(selectedQuality); // Quality is human readable resolution (ie: 1080).
}
/**
* Injection point.
*/

View File

@ -1,11 +1,19 @@
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 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;
@ -37,7 +45,7 @@ public class CustomVideoSpeedPatch {
private static String[] preferenceListEntries, preferenceListEntryValues;
static {
loadSpeeds();
loadCustomSpeeds();
}
private static void resetCustomSpeeds(@NonNull String toastMessage) {
@ -45,7 +53,7 @@ public class CustomVideoSpeedPatch {
SettingsEnum.CUSTOM_PLAYBACK_SPEEDS.saveValue(SettingsEnum.CUSTOM_PLAYBACK_SPEEDS.defaultValue);
}
private static void loadSpeeds() {
private static void loadCustomSpeeds() {
try {
String[] speedStrings = SettingsEnum.CUSTOM_PLAYBACK_SPEEDS.getString().split("\\s+");
Arrays.sort(speedStrings);
@ -61,7 +69,7 @@ public class CustomVideoSpeedPatch {
if (speed >= MAXIMUM_PLAYBACK_SPEED) {
resetCustomSpeeds("Custom speeds must be less than " + MAXIMUM_PLAYBACK_SPEED
+ ". Using default values.");
loadSpeeds();
loadCustomSpeeds();
return;
}
minVideoSpeed = Math.min(minVideoSpeed, speed);
@ -71,7 +79,7 @@ public class CustomVideoSpeedPatch {
} catch (Exception ex) {
LogHelper.printInfo(() -> "parse error", ex);
resetCustomSpeeds("Invalid custom video speeds. Using default values.");
loadSpeeds();
loadCustomSpeeds();
}
}
@ -100,4 +108,32 @@ public class CustomVideoSpeedPatch {
preference.setEntries(preferenceListEntries);
preference.setEntryValues(preferenceListEntryValues);
}
/*
* To reduce copy 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);
// Close the new video speed menu and instead show the old one.
showOldVideoSpeedMenu();
// 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() {
LogHelper.printDebug(() -> "Old video quality menu shown");
// Rest of the implementation added by patch.
}
}

View File

@ -42,7 +42,9 @@ public enum SettingsEnum {
// Video
HDR_AUTO_BRIGHTNESS("revanced_hdr_auto_brightness", BOOLEAN, TRUE),
SHOW_OLD_VIDEO_MENU("revanced_show_old_video_menu", BOOLEAN, TRUE),
SHOW_OLD_VIDEO_QUALITY_MENU("revanced_show_old_video_quality_menu", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_SHOW_OLD_VIDEO_QUALITY_MENU("revanced_show_old_video_menu", BOOLEAN, TRUE),
REMEMBER_VIDEO_QUALITY_LAST_SELECTED("revanced_remember_video_quality_last_selected", BOOLEAN, TRUE),
VIDEO_QUALITY_DEFAULT_WIFI("revanced_video_quality_default_wifi", INTEGER, -2),
VIDEO_QUALITY_DEFAULT_MOBILE("revanced_video_quality_default_mobile", INTEGER, -2),
@ -51,9 +53,6 @@ public enum SettingsEnum {
CUSTOM_PLAYBACK_SPEEDS("revanced_custom_playback_speeds", STRING,
"0.25\n0.5\n0.75\n0.9\n0.95\n1.0\n1.05\n1.1\n1.25\n1.5\n1.75\n2.0\n3.0\n4.0\n5.0", true),
// Whitelist
//WHITELIST("revanced_whitelist_ads", BOOLEAN, FALSE), // TODO: Unused currently
// Ads
HIDE_BUTTONED_ADS("revanced_hide_buttoned_ads", BOOLEAN, TRUE),
HIDE_GENERAL_ADS("revanced_hide_general_ads", BOOLEAN, TRUE),
@ -207,156 +206,7 @@ public enum SettingsEnum {
SB_HIDE_EXPORT_WARNING("sb_hide_export_warning", BOOLEAN, FALSE, SPONSOR_BLOCK),
SB_SEEN_GUIDELINES("sb_seen_guidelines", BOOLEAN, FALSE, SPONSOR_BLOCK),
SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS("sb_local_time_saved_number_segments", INTEGER, 0, SPONSOR_BLOCK),
SB_LOCAL_TIME_SAVED_MILLISECONDS("sb_local_time_saved_milliseconds", LONG, 0L, SPONSOR_BLOCK),
//
// TODO: eventually, delete these
//
@Deprecated
DEPRECATED_ADREMOVER_BUTTONED_REMOVAL("revanced_adremover_buttoned", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_ADREMOVER_GENERAL_ADS_REMOVAL("revanced_adremover_ad_removal", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_ADREMOVER_PAID_CONTENT("revanced_adremover_paid_content", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_ADREMOVER_HIDE_LATEST_POSTS("revanced_adremover_hide_latest_posts", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_ADREMOVER_SELF_SPONSOR("revanced_adremover_self_sponsor", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_ADREMOVER_CUSTOM_ENABLED("revanced_adremover_custom_enabled", BOOLEAN, FALSE),
@Deprecated
DEPRECATED_ADREMOVER_CUSTOM_REMOVAL("revanced_adremover_custom_strings", STRING, "", true),
@Deprecated
DEPRECATED_REMOVE_VIDEO_ADS("revanced_video_ads_removal", BOOLEAN, TRUE, true),
@Deprecated
DEPRECATED_HIDE_CHANNEL_MEMBER_SHELF("revanced_adremover_channel_member_shelf_removal", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_CHAPTER_TEASER("revanced_adremover_chapter_teaser", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_COMMUNITY_GUIDELINES("revanced_adremover_community_guidelines", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_COMMUNITY_POSTS("revanced_adremover_community_posts_removal", BOOLEAN, FALSE),
@Deprecated
DEPRECATED_HIDE_COMPACT_BANNER("revanced_adremover_compact_banner_removal", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_EMERGENCY_BOX("revanced_adremover_emergency_box_removal", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_FEED_SURVEY_REMOVAL("revanced_adremover_feed_survey", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_GRAY_SEPARATOR("revanced_adremover_separator", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_HIDE_CHANNEL_GUIDELINES("revanced_adremover_hide_channel_guidelines", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_INFO_PANEL_REMOVAL("revanced_adremover_info_panel", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_MEDICAL_PANEL_REMOVAL("revanced_adremover_medical_panel", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_MERCHANDISE_REMOVAL("revanced_adremover_merchandise", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_MOVIE_REMOVAL("revanced_adremover_movie", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES_REMOVAL("revanced_adremover_subscribers_community_guidelines_removal", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_VIEW_PRODUCTS("revanced_adremover_view_products", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_WEB_SEARCH_RESULTS("revanced_adremover_web_search_result", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HIDE_SHORTS("revanced_adremover_shorts", BOOLEAN, TRUE, true),
@Deprecated
DEPRECATED_HIDE_INFO_CARDS("revanced_hide_infocards", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_DISABLE_RESUMING_SHORTS_PLAYER("revanced_disable_startup_shorts_player", BOOLEAN, FALSE),
@Deprecated
DEPRECATED_ETERNAL_DOWNLOADER("revanced_downloads_enabled", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_EXTERNAL_DOWNLOADER_PACKAGE_NAME("revanced_downloads_package_name", STRING, "org.schabi.newpipe"),
@Deprecated
DEPRECATED_SHOW_OLD_VIDEO_MENU("revanced_use_old_style_quality_settings", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_VIDEO_QUALITY_DEFAULT_WIFI("revanced_default_video_quality_wifi", INTEGER, -2),
@Deprecated
DEPRECATED_VIDEO_QUALITY_DEFAULT_MOBILE("revanced_default_video_quality_mobile", INTEGER, -2),
@Deprecated
DEPRECATED_PLAYBACK_SPEED_DEFAULT("revanced_default_playback_speed", FLOAT, 1.0f),
@Deprecated
DEPRECATED_COPY_VIDEO_URL("revanced_copy_video_url_enabled", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_COPY_VIDEO_URL_TIMESTAMP("revanced_copy_video_url_timestamp_enabled", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_AUTO_CAPTIONS("revanced_autocaptions_enabled", BOOLEAN, FALSE),
@Deprecated
DEPRECATED_PLAYER_POPUP_PANELS("revanced_player_popup_panels_enabled", BOOLEAN, FALSE),
@Deprecated
DEPRECATED_SWIPE_BRIGHTNESS("revanced_enable_swipe_brightness", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_SWIPE_VOLUME("revanced_enable_swipe_volume", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_PRESS_TO_SWIPE("revanced_enable_press_to_swipe", BOOLEAN, FALSE),
@Deprecated
DEPRECATED_SWIPE_HAPTIC_FEEDBACK("revanced_enable_swipe_haptic_feedback", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_DEBUG("revanced_debug_enabled", BOOLEAN, FALSE),
@Deprecated
DEPRECATED_DEBUG_STACKTRACE("revanced_debug_stacktrace_enabled", BOOLEAN, FALSE),
@Deprecated
DEPRECATED_DEBUG_TOAST_ON_ERROR("revanced_debug_toast_on_error_enabled", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_EXTERNAL_BROWSER("revanced_enable_external_browser", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_AUTO_REPEAT("revanced_pref_auto_repeat", BOOLEAN, FALSE),
@Deprecated
DEPRECATED_TAP_SEEKING("revanced_enable_tap_seeking", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_HDR_AUTO_BRIGHTNESS("revanced_pref_hdr_autobrightness", BOOLEAN, TRUE),
@Deprecated
DEPRECATED_RYD_USER_ID("ryd_userId", STRING, "", RETURN_YOUTUBE_DISLIKE),
@Deprecated
DEPRECATED_RYD_DISLIKE_PERCENTAGE("ryd_show_dislike_percentage", BOOLEAN, FALSE, RETURN_YOUTUBE_DISLIKE),
@Deprecated
DEPRECATED_RYD_COMPACT_LAYOUT("ryd_use_compact_layout", BOOLEAN, FALSE, RETURN_YOUTUBE_DISLIKE),
@Deprecated
DEPRECATED_SB_ENABLED("sb-enabled", BOOLEAN, TRUE, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_VOTING_BUTTON("sb-voting-enabled", BOOLEAN, FALSE, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_CREATE_NEW_SEGMENT("sb-new-segment-enabled", BOOLEAN, FALSE, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_COMPACT_SKIP_BUTTON("sb-use-compact-skip-button", BOOLEAN, FALSE, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_MIN_DURATION("sb-min-duration", FLOAT, 0F, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_VIDEO_LENGTH_WITHOUT_SEGMENTS("sb-length-without-segments", BOOLEAN, TRUE, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_API_URL("sb-api-host-url", STRING, "https://sponsor.ajay.app", SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_TOAST_ON_SKIP("show-toast", BOOLEAN, TRUE, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_AUTO_HIDE_SKIP_BUTTON("sb-auto-hide-skip-segment-button", BOOLEAN, TRUE, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_TRACK_SKIP_COUNT("count-skips", BOOLEAN, TRUE, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_ADJUST_NEW_SEGMENT_STEP("new-segment-step-accuracy", INTEGER, 150, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_LAST_VIP_CHECK("sb-last-vip-check", LONG, 0L, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_IS_VIP("sb-is-vip", BOOLEAN, FALSE, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS("sb-skipped-segments", INTEGER, 0, SPONSOR_BLOCK),
@Deprecated
DEPRECATED_SB_LOCAL_TIME_SAVED_MILLISECONDS("sb-skipped-segments-time", LONG, 0L, SPONSOR_BLOCK);
//
// TODO END
//
SB_LOCAL_TIME_SAVED_MILLISECONDS("sb_local_time_saved_milliseconds", LONG, 0L, SPONSOR_BLOCK);
private static SettingsEnum[] parents(SettingsEnum... parents) {
return parents;
@ -498,31 +348,31 @@ public enum SettingsEnum {
setting.load();
}
// TODO: eventually delete this.
// region Migration
SettingsEnum[][] renamedSettings = {
// TODO: do _not_ delete this SB private user id migration property until sometime in 2024.
// This is the only setting that cannot be reconfigured if lost,
// and more time should be given for users who rarely upgrade.
{DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID},
};
// TODO: do _not_ delete this SB private user id migration property until sometime in 2024.
// This is the only setting that cannot be reconfigured if lost,
// and more time should be given for users who rarely upgrade.
migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID);
for (SettingsEnum[] oldNewSetting : renamedSettings) {
SettingsEnum oldSetting = oldNewSetting[0];
SettingsEnum newSetting = oldNewSetting[1];
if (!oldSetting.isSetToDefault()) {
LogHelper.printInfo(() -> "Migrating old setting of '" + oldSetting.value
+ "' from: " + oldSetting + " into replacement setting: " + newSetting);
newSetting.saveValue(oldSetting.value);
oldSetting.saveValue(oldSetting.defaultValue); // reset old value
}
}
// TODO: delete DEPRECATED_SHOW_OLD_VIDEO_QUALITY_MENU (When? anytime).
migrateOldSettingToNew(DEPRECATED_SHOW_OLD_VIDEO_QUALITY_MENU, SHOW_OLD_VIDEO_QUALITY_MENU);
// endregion
}
/**
* Migrate a setting value if the path is renamed but otherwise the old and new settings are identical.
*/
private static void migrateOldSettingToNew(SettingsEnum oldSetting, SettingsEnum newSetting) {
if (!oldSetting.isSetToDefault()) {
LogHelper.printInfo(() -> "Migrating old setting of '" + oldSetting.value
+ "' from: " + oldSetting + " into replacement setting: " + newSetting);
newSetting.saveValue(oldSetting.value);
oldSetting.saveValue(oldSetting.defaultValue); // reset old value
}
}
private void load() {
switch (returnType) {
case BOOLEAN:

View File

@ -180,6 +180,11 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
if (entryIndex >= 0) {
listPreference.setSummary(listPreference.getEntries()[entryIndex]);
listPreference.setValue(objectStringValue);
} else {
// Value is not an available option.
// User manually edited import data, or options changed and current selection is no longer available.
// Still show the value in the summary so it's clear that something is selected.
listPreference.setSummary(objectStringValue);
}
}

View File

@ -427,16 +427,6 @@ public class SponsorBlockSettingsFragment extends PreferenceFragment {
return false;
});
}
{
Preference preference = new Preference(context);
category.addPreference(preference);
preference.setSummary(str("sb_about_made_by"));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
preference.setSingleLineTitle(false);
}
preference.setSelectable(false);
}
}
private void openGuidelines() {

View File

@ -8,15 +8,16 @@ import app.revanced.integrations.utils.LogHelper
*/
enum class PlayerType {
/**
* Includes Shorts and Stories playback.
* Either no video, or a Short is playing.
*/
NONE,
/**
* A Shorts or Stories, if a regular video is minimized and a Short/Story is then opened.
* A Short is playing. Occurs if a regular video is first opened
* and then a Short is opened (without first closing the regular video).
*/
HIDDEN,
/**
* When spoofing to an old version of YouTube, and watching a short with a regular video in the background,
* 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]).
*/
WATCH_WHILE_MINIMIZED,
@ -76,7 +77,7 @@ enum class PlayerType {
* Useful to check if a short is currently playing.
*
* Does not include the first moment after a short is opened when a regular video is minimized on screen,
* or while watching a short with a regular video present on a spoofed old version of YouTube.
* or while watching a short with a regular video present on a spoofed 16.x version of YouTube.
* To include those situations instead use [isNoneHiddenOrMinimized].
*/
fun isNoneOrHidden(): Boolean {
@ -84,12 +85,13 @@ enum class PlayerType {
}
/**
* Check if the current player type is [NONE], [HIDDEN], [WATCH_WHILE_MINIMIZED], [WATCH_WHILE_SLIDING_MINIMIZED_DISMISSED].
* Check if the current player type is
* [NONE], [HIDDEN], [WATCH_WHILE_MINIMIZED], [WATCH_WHILE_SLIDING_MINIMIZED_DISMISSED].
*
* Useful to check if a Short is being played,
* although can return false positive if the player is minimized.
* although will return false positive if a regular video is opened and minimized (and no short is playing).
*
* @return If nothing, a Short, a Story,
* @return If nothing, a Short,
* or a regular video is minimized video or sliding off screen to a dismissed or hidden state.
*/
fun isNoneHiddenOrMinimized(): Boolean {

View File

@ -4,7 +4,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:8.0.1")
classpath("com.android.tools.build:gradle:7.4.2")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.20")
}
}

View File

@ -0,0 +1,19 @@
package android.support.v7.widget;
import android.content.Context;
import android.view.View;
public class RecyclerView extends View {
public RecyclerView(Context context) {
super(context);
}
public View getChildAt(@SuppressWarnings("unused") final int index) {
return null;
}
public int getChildCount() {
return 0;
}
}

View File

@ -0,0 +1,10 @@
package com.facebook.litho;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
public final class ComponentHost extends RecyclerView {
public ComponentHost(Context context) {
super(context);
}
}

View File

@ -1,3 +1,4 @@
org.gradle.jvmargs = -Xmx2048m
org.gradle.parallel = true
org.gradle.caching = true
android.useAndroidX = true
version = 0.111.2
version = 0.112.0-dev.3

Binary file not shown.

View File

@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

24
gradlew vendored
View File

@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@ -80,13 +80,10 @@ do
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@ -133,22 +130,29 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@ -193,6 +197,10 @@ if "$cygwin" || "$msys" ; then
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in

183
gradlew.bat vendored
View File

@ -1,91 +1,92 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega