mirror of
https://github.com/revanced/revanced-integrations.git
synced 2024-08-31 11:35:24 +02:00
feat(YouTube - Hide Shorts components): Selectively hide Shorts for home / subscription / search (#592)
This commit is contained in:
parent
4ae7d5b178
commit
1ee99aa6f0
@ -112,6 +112,37 @@ final class KeywordContentFilter extends Filter {
|
||||
|
||||
private volatile ByteTrieSearch bufferSearch;
|
||||
|
||||
private static void logNavigationState(String state) {
|
||||
// Enable locally to debug filtering. Default off to reduce log spam.
|
||||
final boolean LOG_NAVIGATION_STATE = false;
|
||||
// noinspection ConstantValue
|
||||
if (LOG_NAVIGATION_STATE) {
|
||||
Logger.printDebug(() -> "Navigation state: " + state);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hideKeywordSettingIsActive() {
|
||||
if (NavigationBar.isSearchBarActive()) {
|
||||
// Must check first. Search bar can be active with almost any tab.
|
||||
logNavigationState("Search");
|
||||
return Settings.HIDE_KEYWORD_CONTENT_SEARCH.get();
|
||||
} else if (PlayerType.getCurrent().isMaximizedOrFullscreen()) {
|
||||
// For now, consider the under video results the same as the home feed.
|
||||
logNavigationState("Player active");
|
||||
return Settings.HIDE_KEYWORD_CONTENT_HOME.get();
|
||||
} else if (NavigationButton.HOME.isSelected()) {
|
||||
logNavigationState("Home tab");
|
||||
return Settings.HIDE_KEYWORD_CONTENT_HOME.get();
|
||||
} else if (NavigationButton.SUBSCRIPTIONS.isSelected()) {
|
||||
logNavigationState("Subscription tab");
|
||||
return Settings.HIDE_SUBSCRIPTIONS_BUTTON.get();
|
||||
} else {
|
||||
// User is in the Library or Notifications tab.
|
||||
logNavigationState("Ignored tab");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change first letter of the first word to use title case.
|
||||
*/
|
||||
@ -224,15 +255,6 @@ final class KeywordContentFilter extends Filter {
|
||||
addPathCallbacks(startsWithFilter, containsFilter);
|
||||
}
|
||||
|
||||
private static void logNavigationState(String state) {
|
||||
// Enable locally to debug filtering. Default off to reduce log spam.
|
||||
final boolean LOG_NAVIGATION_STATE = false;
|
||||
// noinspection ConstantValue
|
||||
if (LOG_NAVIGATION_STATE) {
|
||||
Logger.printDebug(() -> "Navigation state: " + state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
@ -240,34 +262,7 @@ final class KeywordContentFilter extends Filter {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NavigationBar.isSearchBarActive()) {
|
||||
// Search bar can be active with almost any tab active.
|
||||
if (!Settings.HIDE_KEYWORD_CONTENT_SEARCH.get()) {
|
||||
return false;
|
||||
}
|
||||
logNavigationState("Search");
|
||||
} else if (PlayerType.getCurrent().isMaximizedOrFullscreen()) {
|
||||
// For now, consider the under video results the same as the home feed.
|
||||
if (!Settings.HIDE_KEYWORD_CONTENT_HOME.get()) {
|
||||
return false;
|
||||
}
|
||||
logNavigationState("Player active");
|
||||
} else if (NavigationButton.HOME.isSelected()) {
|
||||
// Could use a Switch statement, but there is only 2 tabs of interest.
|
||||
if (!Settings.HIDE_KEYWORD_CONTENT_HOME.get()) {
|
||||
return false;
|
||||
}
|
||||
logNavigationState("Home tab");
|
||||
} else if (NavigationButton.SUBSCRIPTIONS.isSelected()) {
|
||||
if (!Settings.HIDE_SUBSCRIPTIONS_BUTTON.get()) {
|
||||
return false;
|
||||
}
|
||||
logNavigationState("Subscription tab");
|
||||
} else {
|
||||
// User is in the Library or Notifications tab.
|
||||
logNavigationState("Ignored tab");
|
||||
return false;
|
||||
}
|
||||
if (!hideKeywordSettingIsActive()) return false;
|
||||
|
||||
// Field is intentionally compared using reference equality.
|
||||
if (Settings.HIDE_KEYWORD_CONTENT_PHRASES.get() != lastKeywordPhrasesParsed) {
|
||||
@ -281,4 +276,5 @@ final class KeywordContentFilter extends Filter {
|
||||
|
||||
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
|
||||
}
|
||||
|
||||
}
|
@ -1,15 +1,19 @@
|
||||
package app.revanced.integrations.youtube.patches.components;
|
||||
|
||||
import static app.revanced.integrations.shared.Utils.hideViewUnderCondition;
|
||||
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import app.revanced.integrations.youtube.settings.Settings;
|
||||
import com.google.android.libraries.youtube.rendering.ui.pivotbar.PivotBar;
|
||||
|
||||
import static app.revanced.integrations.shared.Utils.hideViewBy1dpUnderCondition;
|
||||
import static app.revanced.integrations.shared.Utils.hideViewUnderCondition;
|
||||
import app.revanced.integrations.shared.Utils;
|
||||
import app.revanced.integrations.youtube.settings.Settings;
|
||||
import app.revanced.integrations.youtube.shared.NavigationBar;
|
||||
import app.revanced.integrations.youtube.shared.PlayerType;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@ -35,8 +39,10 @@ public final class ShortsFilter extends Filter {
|
||||
private final ByteArrayFilterGroupList videoActionButtonGroupList = new ByteArrayFilterGroupList();
|
||||
|
||||
public ShortsFilter() {
|
||||
// Identifier components.
|
||||
|
||||
var shorts = new StringFilterGroup(
|
||||
Settings.HIDE_SHORTS,
|
||||
null, // Setting is based on navigation state.
|
||||
"shorts_shelf",
|
||||
"inline_shorts",
|
||||
"shorts_grid",
|
||||
@ -46,7 +52,7 @@ public final class ShortsFilter extends Filter {
|
||||
// Feed Shorts shelf header.
|
||||
// Use a different filter group for this pattern, as it requires an additional check after matching.
|
||||
shelfHeader = new StringFilterGroup(
|
||||
Settings.HIDE_SHORTS,
|
||||
null,
|
||||
"shelf_header.eml"
|
||||
);
|
||||
|
||||
@ -58,14 +64,14 @@ public final class ShortsFilter extends Filter {
|
||||
|
||||
addIdentifierCallbacks(shorts, shelfHeader, thanksButton);
|
||||
|
||||
// Path components.
|
||||
|
||||
// Shorts that appear in the feed/search when the device is using tablet layout.
|
||||
shortsCompactFeedVideoPath = new StringFilterGroup(Settings.HIDE_SHORTS,
|
||||
"compact_video.eml");
|
||||
shortsCompactFeedVideoPath = new StringFilterGroup(null, "compact_video.eml");
|
||||
// Filter out items that use the 'frame0' thumbnail.
|
||||
// This is a valid thumbnail for both regular videos and Shorts,
|
||||
// but it appears these thumbnails are used only for Shorts.
|
||||
shortsCompactFeedVideoBuffer = new ByteArrayFilterGroup(Settings.HIDE_SHORTS,
|
||||
"/frame0.jpg");
|
||||
shortsCompactFeedVideoBuffer = new ByteArrayFilterGroup(null, "/frame0.jpg");
|
||||
|
||||
// Shorts player components.
|
||||
joinButton = new StringFilterGroup(
|
||||
@ -174,7 +180,8 @@ public final class ShortsFilter extends Filter {
|
||||
) return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
|
||||
|
||||
if (matchedGroup == shortsCompactFeedVideoPath) {
|
||||
if (contentIndex == 0 && shortsCompactFeedVideoBuffer.check(protobufBufferArray).isFiltered()) {
|
||||
if (shouldHideShortsFeedItems() && contentIndex == 0
|
||||
&& shortsCompactFeedVideoBuffer.check(protobufBufferArray).isFiltered()) {
|
||||
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
|
||||
}
|
||||
return false;
|
||||
@ -195,22 +202,41 @@ public final class ShortsFilter extends Filter {
|
||||
) {
|
||||
if (path.startsWith(REEL_CHANNEL_BAR_PATH)) return super.isFiltered(
|
||||
identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex
|
||||
);
|
||||
); // else, return false.
|
||||
}
|
||||
|
||||
return false;
|
||||
} else if (matchedGroup == shelfHeader) {
|
||||
// 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 (contentIndex != 0) return false;
|
||||
} else {
|
||||
// Feed/search path components.
|
||||
if (matchedGroup == shelfHeader) {
|
||||
// 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 (contentIndex != 0) return false;
|
||||
}
|
||||
|
||||
if (!shouldHideShortsFeedItems()) return false;
|
||||
}
|
||||
|
||||
// Super class handles logging.
|
||||
return super.isFiltered(identifier, path, protobufBufferArray, matchedGroup, contentType, contentIndex);
|
||||
}
|
||||
|
||||
private static boolean shouldHideShortsFeedItems() {
|
||||
if (NavigationBar.isSearchBarActive()) { // Must check search first.
|
||||
return Settings.HIDE_SHORTS_SEARCH.get();
|
||||
} else if (PlayerType.getCurrent().isMaximizedOrFullscreen()
|
||||
|| NavigationBar.NavigationButton.HOME.isSelected()) {
|
||||
return Settings.HIDE_SHORTS_HOME.get();
|
||||
} else if (NavigationBar.NavigationButton.SUBSCRIPTIONS.isSelected()) {
|
||||
return Settings.HIDE_SHORTS_SUBSCRIPTIONS.get();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void hideShortsShelf(final View shortsShelfView) {
|
||||
hideViewBy1dpUnderCondition(Settings.HIDE_SHORTS, shortsShelfView);
|
||||
if (shouldHideShortsFeedItems()) {
|
||||
Utils.hideViewByLayoutParams(shortsShelfView);
|
||||
}
|
||||
}
|
||||
|
||||
// region Hide the buttons in older versions of YouTube. New versions use Litho.
|
||||
|
@ -98,11 +98,11 @@ public class Settings extends BaseSettings {
|
||||
public static final BooleanSetting HIDE_IMAGE_SHELF = new BooleanSetting("revanced_hide_image_shelf", TRUE);
|
||||
public static final BooleanSetting HIDE_INFO_CARDS = new BooleanSetting("revanced_hide_info_cards", TRUE);
|
||||
public static final BooleanSetting HIDE_JOIN_MEMBERSHIP_BUTTON = new BooleanSetting("revanced_hide_join_membership_button", TRUE);
|
||||
public static final BooleanSetting HIDE_KEYWORD_CONTENT_SEARCH = new BooleanSetting("revanced_hide_keyword_content_search", FALSE);
|
||||
public static final BooleanSetting HIDE_KEYWORD_CONTENT_HOME = new BooleanSetting("revanced_hide_keyword_content_home", FALSE);
|
||||
public static final BooleanSetting HIDE_KEYWORD_CONTENT_SUBSCRIPTIONS = new BooleanSetting("revanced_hide_keyword_content_subscriptions", FALSE);
|
||||
public static final BooleanSetting HIDE_KEYWORD_CONTENT_SEARCH = new BooleanSetting("revanced_hide_keyword_content_search", FALSE);
|
||||
public static final StringSetting HIDE_KEYWORD_CONTENT_PHRASES = new StringSetting("revanced_hide_keyword_content_phrases", "",
|
||||
parentsAny(HIDE_KEYWORD_CONTENT_SEARCH, HIDE_KEYWORD_CONTENT_HOME, HIDE_KEYWORD_CONTENT_SUBSCRIPTIONS));
|
||||
parentsAny(HIDE_KEYWORD_CONTENT_HOME, HIDE_KEYWORD_CONTENT_SUBSCRIPTIONS, HIDE_KEYWORD_CONTENT_SEARCH));
|
||||
public static final BooleanSetting HIDE_LOAD_MORE_BUTTON = new BooleanSetting("revanced_hide_load_more_button", TRUE, true);
|
||||
public static final BooleanSetting HIDE_MEDICAL_PANELS = new BooleanSetting("revanced_hide_medical_panels", TRUE);
|
||||
public static final BooleanSetting HIDE_MIX_PLAYLISTS = new BooleanSetting("revanced_hide_mix_playlists", TRUE);
|
||||
@ -141,7 +141,10 @@ public class Settings extends BaseSettings {
|
||||
public static final BooleanSetting HIDE_TRANSCIPT_SECTION = new BooleanSetting("revanced_hide_transcript_section", TRUE);
|
||||
|
||||
// Shorts
|
||||
public static final BooleanSetting HIDE_SHORTS = new BooleanSetting("revanced_hide_shorts", FALSE, true);
|
||||
@Deprecated public static final BooleanSetting DEPRECATED_HIDE_SHORTS = new BooleanSetting("revanced_hide_shorts", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_HOME = new BooleanSetting("revanced_hide_shorts_home", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SUBSCRIPTIONS = new BooleanSetting("revanced_hide_shorts_subscriptions", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SEARCH = new BooleanSetting("revanced_hide_shorts_search", FALSE);
|
||||
public static final BooleanSetting HIDE_SHORTS_JOIN_BUTTON = new BooleanSetting("revanced_hide_shorts_join_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SUBSCRIBE_BUTTON = new BooleanSetting("revanced_hide_shorts_subscribe_button", TRUE);
|
||||
public static final BooleanSetting HIDE_SHORTS_SUBSCRIBE_BUTTON_PAUSED = new BooleanSetting("revanced_hide_shorts_subscribe_button_paused", FALSE);
|
||||
@ -362,6 +365,14 @@ public class Settings extends BaseSettings {
|
||||
// Remove any previously saved announcement consumer (a random generated string).
|
||||
Setting.preferences.saveString("revanced_announcement_consumer", null);
|
||||
|
||||
// Shorts
|
||||
if (DEPRECATED_HIDE_SHORTS.get()) {
|
||||
Logger.printInfo(() -> "Migrating hide Shorts setting");
|
||||
DEPRECATED_HIDE_SHORTS.resetToDefault();
|
||||
HIDE_SHORTS_HOME.save(true);
|
||||
HIDE_SHORTS_SUBSCRIPTIONS.save(true);
|
||||
HIDE_SHORTS_SEARCH.save(true);
|
||||
}
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user