Skip to content
This repository has been archived by the owner on Dec 11, 2024. It is now read-only.

Commit

Permalink
feat(YouTube - Shorts components): Add Hide in channel setting (Hid…
Browse files Browse the repository at this point in the history
…e the Shorts shelf on the channel home tab)
  • Loading branch information
anddea committed Oct 23, 2024
1 parent c52b282 commit 0d93d8e
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import app.revanced.integrations.shared.patches.components.Filter;
import app.revanced.integrations.shared.patches.components.StringFilterGroup;
import app.revanced.integrations.shared.settings.BooleanSetting;
import app.revanced.integrations.shared.utils.Logger;
import app.revanced.integrations.shared.utils.StringTrieSearch;
import app.revanced.integrations.youtube.settings.Settings;
import app.revanced.integrations.youtube.shared.RootView;
Expand All @@ -15,50 +14,48 @@
public final class ShortsShelfFilter extends Filter {
private static final String BROWSE_ID_HISTORY = "FEhistory";
private static final String BROWSE_ID_LIBRARY = "FElibrary";
private static final String BROWSE_ID_NOTIFICATION_INBOX = "FEnotifications_inbox";
private static final String BROWSE_ID_SUBSCRIPTIONS = "FEsubscriptions";
private static final String CONVERSATION_CONTEXT_FEED_IDENTIFIER =
"horizontalCollectionSwipeProtector=null";
private static final String SHELF_HEADER_PATH = "shelf_header.eml";
private final StringFilterGroup shortsCompactFeedVideoPath;
private final ByteArrayFilterGroup shortsCompactFeedVideoBuffer;
private final StringFilterGroup shelfHeader;
private final StringFilterGroup compactFeedVideoPath;
private final ByteArrayFilterGroup compactFeedVideoBuffer;
private final StringFilterGroup shelfHeaderIdentifier;
private final StringFilterGroup shelfHeaderPath;
private static final StringTrieSearch feedGroup = new StringTrieSearch();
private static final BooleanSetting hideShortsShelf = Settings.HIDE_SHORTS_SHELF;
private static final BooleanSetting hideChannel = Settings.HIDE_SHORTS_SHELF_CHANNEL;
private static final boolean hideHomeAndRelatedVideos = Settings.HIDE_SHORTS_SHELF_HOME_RELATED_VIDEOS.get();
private static final boolean hideSubscriptions = Settings.HIDE_SHORTS_SHELF_SUBSCRIPTIONS.get();
private static final boolean hideSearch = Settings.HIDE_SHORTS_SHELF_SEARCH.get();
private static final boolean hideHistory = Settings.HIDE_SHORTS_SHELF_HISTORY.get();
private final StringTrieSearch exceptions = new StringTrieSearch();
private static final ByteArrayFilterGroup channelProfileShelfHeader =
new ByteArrayFilterGroup(
hideChannel,
"Shorts"
);

public ShortsShelfFilter() {
if (!hideHistory) {
exceptions.addPattern("library_recent_shelf.eml");
}

feedGroup.addPattern(CONVERSATION_CONTEXT_FEED_IDENTIFIER);

// Feed Shorts shelf header.
// Use a different filter group for this pattern, as it requires an additional check after matching.
shelfHeader = new StringFilterGroup(
hideShortsShelf,
SHELF_HEADER_PATH
final StringFilterGroup channelProfile = new StringFilterGroup(
hideChannel,
"shorts_pivot_item"
);

final StringFilterGroup shorts = new StringFilterGroup(
shelfHeaderIdentifier = new StringFilterGroup(
hideShortsShelf,
"shorts_shelf",
"inline_shorts",
"shorts_grid",
"shorts_video_cell"
// "shorts_pivot_item" appears when you click 'Shorts' in the category bar in the search results, and also in the channel profile.
// RVX does not hide the shelf header in the channel profile, so only the 'Shorts' header is left in the channel profile.
// This doesn't look good, so just don't hide this component.
// "shorts_pivot_item"
SHELF_HEADER_PATH
);

addIdentifierCallbacks(shelfHeader, shorts);
addIdentifierCallbacks(channelProfile, shelfHeaderIdentifier);

shortsCompactFeedVideoPath = new StringFilterGroup(
compactFeedVideoPath = new StringFilterGroup(
hideShortsShelf,
// Shorts that appear in the feed/search when the device is using tablet layout.
"compact_video.eml",
Expand All @@ -69,38 +66,72 @@ public ShortsShelfFilter() {
// 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(
compactFeedVideoBuffer = new ByteArrayFilterGroup(
hideShortsShelf,
"/frame0.jpg"
);

addPathCallbacks(shortsCompactFeedVideoPath);
// Feed Shorts shelf header.
// Use a different filter group for this pattern, as it requires an additional check after matching.
shelfHeaderPath = new StringFilterGroup(
hideShortsShelf,
SHELF_HEADER_PATH
);

final StringFilterGroup shorts = new StringFilterGroup(
hideShortsShelf,
"shorts_shelf",
"inline_shorts",
"shorts_grid",
"shorts_video_cell"
);

addPathCallbacks(compactFeedVideoPath, shelfHeaderPath, shorts);
}

@Override
public boolean isFiltered(String path, @Nullable String identifier, String allValue, byte[] protobufBufferArray,
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
if (exceptions.matches(path))
if (exceptions.matches(path)) {
return false;
if (!shouldHideShortsFeedItems())
}
// Check channel profile components first
if (matchedGroup == shelfHeaderPath) {
// 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 (!channelProfileShelfHeader.check(protobufBufferArray).isFiltered()) {
return false;
}
if (feedGroup.matches(allValue)) {
return false;
}
return super.isFiltered(path, identifier, allValue, protobufBufferArray, matchedGroup, contentType, contentIndex);
}
// Check feed components
if (!hideShelves()) {
return false;

if (matchedGroup == shortsCompactFeedVideoPath) {
if (shortsCompactFeedVideoBuffer.check(protobufBufferArray).isFiltered())
}
if (matchedGroup == compactFeedVideoPath) {
if (compactFeedVideoBuffer.check(protobufBufferArray).isFiltered()) {
return super.isFiltered(path, identifier, allValue, protobufBufferArray, matchedGroup, contentType, contentIndex);
}
return false;
} else if (matchedGroup == shelfHeader) {
} else if (matchedGroup == shelfHeaderIdentifier) {
// Check ConversationContext to not hide shelf header in channel profile
// This value does not exist in the shelf header in the channel profile
if (!feedGroup.matches(allValue))
if (!feedGroup.matches(allValue)) {
return false;
}
}

// Super class handles logging.
return super.isFiltered(path, identifier, allValue, protobufBufferArray, matchedGroup, contentType, contentIndex);
}

private static boolean shouldHideShortsFeedItems() {
private static boolean hideShelves() {
if (hideHomeAndRelatedVideos && hideSubscriptions && hideSearch && hideHistory) {
// Shorts suggestions can load in the background if a video is opened and
// then immediately minimized before any suggestions are loaded.
Expand Down Expand Up @@ -130,9 +161,8 @@ private static boolean shouldHideShortsFeedItems() {
}

final String browseId = RootView.getBrowseId();
Logger.printDebug(() -> "Current browseId: " + browseId);
switch (browseId) {
case BROWSE_ID_HISTORY, BROWSE_ID_LIBRARY -> {
case BROWSE_ID_HISTORY, BROWSE_ID_LIBRARY, BROWSE_ID_NOTIFICATION_INBOX -> {
return hideHistory;
}
case BROWSE_ID_SUBSCRIPTIONS -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting DISABLE_RESUMING_SHORTS_PLAYER = new BooleanSetting("revanced_disable_resuming_shorts_player", TRUE);
public static final BooleanSetting HIDE_SHORTS_FLOATING_BUTTON = new BooleanSetting("revanced_hide_shorts_floating_button", TRUE);
public static final BooleanSetting HIDE_SHORTS_SHELF = new BooleanSetting("revanced_hide_shorts_shelf", TRUE, true);
public static final BooleanSetting HIDE_SHORTS_SHELF_CHANNEL = new BooleanSetting("revanced_hide_shorts_shelf_channel", FALSE, true);
public static final BooleanSetting HIDE_SHORTS_SHELF_HOME_RELATED_VIDEOS = new BooleanSetting("revanced_hide_shorts_shelf_home_related_videos", TRUE, true);
public static final BooleanSetting HIDE_SHORTS_SHELF_SUBSCRIPTIONS = new BooleanSetting("revanced_hide_shorts_shelf_subscriptions", TRUE, true);
public static final BooleanSetting HIDE_SHORTS_SHELF_SEARCH = new BooleanSetting("revanced_hide_shorts_shelf_search", TRUE, true);
Expand Down

0 comments on commit 0d93d8e

Please sign in to comment.