fix(YouTube - Hide Shorts components): Shorts shelves are sometimes not hidden
Co-authored-by: inotia00 <108592928+inotia00@users.noreply.github.com>
This commit is contained in:
parent
e52114076e
commit
09bce22aeb
7 changed files with 62 additions and 81 deletions
|
|
@ -9,5 +9,13 @@ public final class ConversionContext {
|
|||
StringBuilder patch_getPathBuilder();
|
||||
|
||||
String patch_getIdentifier();
|
||||
|
||||
default boolean isHomeFeedOrRelatedVideo() {
|
||||
return toString().contains("horizontalCollectionSwipeProtector=null");
|
||||
}
|
||||
|
||||
default boolean isSubscriptionOrLibrary() {
|
||||
return toString().contains("heightConstraint=null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,18 +26,12 @@ import java.util.List;
|
|||
public abstract class Filter {
|
||||
|
||||
public enum FilterContentType {
|
||||
CONTEXT,
|
||||
IDENTIFIER,
|
||||
PATH,
|
||||
ACCESSIBILITY,
|
||||
PROTOBUFFER
|
||||
}
|
||||
|
||||
/**
|
||||
* Context callbacks. Do not add to this instance,
|
||||
* and instead use {@link #addContextCallbacks(StringFilterGroup...)}.
|
||||
*/
|
||||
protected final List<StringFilterGroup> contextCallbacks = new ArrayList<>();
|
||||
/**
|
||||
* Identifier callbacks. Do not add to this instance,
|
||||
* and instead use {@link #addIdentifierCallbacks(StringFilterGroup...)}.
|
||||
|
|
@ -49,14 +43,6 @@ public abstract class Filter {
|
|||
*/
|
||||
public final List<StringFilterGroup> pathCallbacks = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Adds callbacks to {@link #isFiltered(ContextInterface, String, String, String, byte[], StringFilterGroup, FilterContentType, int)}
|
||||
* if any of the groups are found.
|
||||
*/
|
||||
protected final void addContextCallbacks(StringFilterGroup... groups) {
|
||||
contextCallbacks.addAll(Arrays.asList(groups));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds callbacks to {@link #isFiltered(ContextInterface, String, String, String, byte[], StringFilterGroup, FilterContentType, int)}
|
||||
* if any of the groups are found.
|
||||
|
|
|
|||
|
|
@ -41,9 +41,11 @@ public class LayoutReloadObserverPatch {
|
|||
return;
|
||||
}
|
||||
|
||||
if (PlayerType.getCurrent() == PlayerType.WATCH_WHILE_MINIMIZED &&
|
||||
isActionBarVisible.compareAndSet(false, true)) {
|
||||
Utils.runOnMainThreadDelayed(() -> isActionBarVisible.compareAndSet(true, false), 500);
|
||||
PlayerType playerType = PlayerType.getCurrent();
|
||||
if (playerType == PlayerType.WATCH_WHILE_MINIMIZED || playerType == PlayerType.WATCH_WHILE_PICTURE_IN_PICTURE) {
|
||||
if (isActionBarVisible.compareAndSet(false, true)) {
|
||||
Utils.runOnMainThreadDelayed(() -> isActionBarVisible.compareAndSet(true, false), 250);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,26 +134,17 @@ public final class DescriptionComponentsFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isFiltered(ContextInterface contextInterface,
|
||||
String identifier,
|
||||
String accessibility,
|
||||
String path,
|
||||
byte[] buffer,
|
||||
StringFilterGroup matchedGroup,
|
||||
FilterContentType contentType,
|
||||
int contentIndex) {
|
||||
// The description panel can be opened in both the regular player and Shorts.
|
||||
// If the description panel is opened in a Shorts, PlayerType is 'HIDDEN',
|
||||
// so 'PlayerType.getCurrent().isMaximizedOrFullscreen()' does not guarantee that the description panel is open.
|
||||
// Instead, use the engagement id to check if the description panel is opened.
|
||||
if (!EngagementPanel.isDescription()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// PlayerType when the description panel is opened: NONE, HIDDEN,
|
||||
// WATCH_WHILE_MAXIMIZED, WATCH_WHILE_FULLSCREEN, WATCH_WHILE_SLIDING_MAXIMIZED_FULLSCREEN.
|
||||
PlayerType playerType = PlayerType.getCurrent();
|
||||
if (!playerType.isNoneOrHidden() && !playerType.isMaximizedOrFullscreen()) {
|
||||
public boolean isFiltered(ContextInterface contextInterface,
|
||||
String identifier,
|
||||
String accessibility,
|
||||
String path,
|
||||
byte[] buffer,
|
||||
StringFilterGroup matchedGroup,
|
||||
FilterContentType contentType,
|
||||
int contentIndex) {
|
||||
// Immediately after the layout is refreshed, litho components are updated before the UI is drawn.
|
||||
// In this case, EngagementPanel.isDescription() cannot be used, and isActionBarVisible.get() should be used.
|
||||
if (!EngagementPanel.isDescription() && !(PlayerType.getCurrent().isMaximizedOrFullscreen() || isActionBarVisible.get() || ShortsPlayerState.isOpen())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,19 +65,16 @@ public final class HorizontalShelvesFilter extends Filter {
|
|||
);
|
||||
}
|
||||
|
||||
private boolean hideShelves() {
|
||||
private boolean hideShelves(ContextInterface contextInterface) {
|
||||
if (!Settings.HIDE_HORIZONTAL_SHELVES.get()) {
|
||||
return false;
|
||||
}
|
||||
// Must check player type first, as search bar can be active behind the player.
|
||||
if (PlayerType.getCurrent().isMaximizedOrFullscreen() || isActionBarVisible.get()) {
|
||||
return false;
|
||||
}
|
||||
// Must check second, as search can be from any tab.
|
||||
if (NavigationBar.isSearchBarActive()) {
|
||||
return true;
|
||||
}
|
||||
return NavigationButton.getSelectedNavigationButton() != NavigationButton.LIBRARY;
|
||||
return contextInterface.isHomeFeedOrRelatedVideo()
|
||||
|| PlayerType.getCurrent().isMaximizedOrFullscreen()
|
||||
|| isActionBarVisible.get()
|
||||
|| NavigationBar.isSearchBarActive()
|
||||
|| NavigationBar.isBackButtonVisible()
|
||||
|| NavigationButton.getSelectedNavigationButton() != NavigationButton.LIBRARY;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -95,15 +92,9 @@ public final class HorizontalShelvesFilter extends Filter {
|
|||
if (generalBuffers.check(buffer).isFiltered()) {
|
||||
return true;
|
||||
}
|
||||
if (EngagementPanel.isDescription()) {
|
||||
PlayerType playerType = PlayerType.getCurrent();
|
||||
// PlayerType when the description panel is opened: NONE, HIDDEN,
|
||||
// WATCH_WHILE_MAXIMIZED, WATCH_WHILE_FULLSCREEN, WATCH_WHILE_SLIDING_MAXIMIZED_FULLSCREEN.
|
||||
if (!playerType.isMaximizedOrFullscreen() && !playerType.isNoneOrHidden()) {
|
||||
return false;
|
||||
}
|
||||
return descriptionBuffers.check(buffer).isFiltered();
|
||||
if (descriptionBuffers.check(buffer).isFiltered()) {
|
||||
return EngagementPanel.isDescription() || PlayerType.getCurrent().isMaximizedOrFullscreen() || isActionBarVisible.get() || ShortsPlayerState.isOpen();
|
||||
}
|
||||
return hideShelves();
|
||||
return hideShelves(contextInterface);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ public final class LayoutComponentsFilter extends Filter {
|
|||
private final StringFilterGroup chipBar;
|
||||
private final StringFilterGroup channelProfile;
|
||||
private final StringFilterGroupList channelProfileGroupList;
|
||||
private final StringFilterGroupList communityPostStringFilterGroup;
|
||||
|
||||
public LayoutComponentsFilter() {
|
||||
exceptions.addPatterns(
|
||||
|
|
@ -142,16 +141,6 @@ public final class LayoutComponentsFilter extends Filter {
|
|||
"poll_post_responsive_root.e",
|
||||
"shared_post_root.e"
|
||||
);
|
||||
communityPostStringFilterGroup = new StringFilterGroupList();
|
||||
communityPostStringFilterGroup.addAll(
|
||||
new StringFilterGroup(
|
||||
null,
|
||||
// home
|
||||
"horizontalCollectionSwipeProtector=null",
|
||||
// subscriptions
|
||||
"heightConstraint=null"
|
||||
)
|
||||
);
|
||||
|
||||
final var subscribersCommunityGuidelines = new StringFilterGroup(
|
||||
Settings.HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES,
|
||||
|
|
@ -419,7 +408,7 @@ public final class LayoutComponentsFilter extends Filter {
|
|||
}
|
||||
|
||||
if (matchedGroup == communityPosts) {
|
||||
return communityPostStringFilterGroup.check(contextInterface.toString()).isFiltered();
|
||||
return contextInterface.isHomeFeedOrRelatedVideo() || contextInterface.isSubscriptionOrLibrary();
|
||||
}
|
||||
|
||||
if (exceptions.matches(path)) return false; // Exceptions are not filtered.
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ public final class ShortsFilter extends Filter {
|
|||
private final StringFilterGroup shortsCompactFeedVideo;
|
||||
private final ByteArrayFilterGroup shortsCompactFeedVideoBuffer;
|
||||
private final StringFilterGroup channelProfile;
|
||||
private final ByteArrayFilterGroup channelProfileShelfHeader;
|
||||
|
||||
private final StringFilterGroup autoDubbedLabel;
|
||||
private final StringFilterGroup subscribeButton;
|
||||
|
|
@ -95,6 +96,11 @@ public final class ShortsFilter extends Filter {
|
|||
"shorts_pivot_item"
|
||||
);
|
||||
|
||||
channelProfileShelfHeader = new ByteArrayFilterGroup(
|
||||
Settings.HIDE_SHORTS_CHANNEL,
|
||||
"Shorts"
|
||||
);
|
||||
|
||||
// Feed Shorts shelf header.
|
||||
// Use a different filter group for this pattern, as it requires an additional check after matching.
|
||||
shelfHeaderIdentifier = new StringFilterGroup(
|
||||
|
|
@ -412,8 +418,12 @@ public final class ShortsFilter extends Filter {
|
|||
if (contentIndex != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (matchedGroup == channelProfile) {
|
||||
// Check ConversationContext to not hide shelf header in channel profile
|
||||
// This value does not exist in the shelf header in the channel profile
|
||||
if (!contextInterface.isHomeFeedOrRelatedVideo()) {
|
||||
return false;
|
||||
}
|
||||
} else if (matchedGroup == channelProfile) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -433,7 +443,15 @@ public final class ShortsFilter extends Filter {
|
|||
}
|
||||
|
||||
if (matchedGroup == shortsCompactFeedVideo) {
|
||||
return shouldHideShortsFeedItems() && shortsCompactFeedVideoBuffer.check(buffer).isFiltered();
|
||||
return shouldHideShortsFeedItems()
|
||||
&& shortsCompactFeedVideoBuffer.check(buffer).isFiltered()
|
||||
// The litho path of the feed video is 'video_lockup_with_attachment.e'.
|
||||
// It appears shortsCompactFeedVideoBuffer is used after 20 seconds during autoplay in the feed in YouTube 20.44.38.
|
||||
// If the Shorts shelf is hidden on the Home feed, the video in the feed will be hidden after 20 seconds have passed since autoplay began in the feed.
|
||||
//
|
||||
// When a video is autoplaying in the feed, no new components are drawn on the screen.
|
||||
// Therefore, filtering is skipped when the current PlayerType is [INLINE_MINIMAL].
|
||||
&& PlayerType.getCurrent() != PlayerType.INLINE_MINIMAL;
|
||||
}
|
||||
|
||||
if (matchedGroup == shelfHeaderPath) {
|
||||
|
|
@ -442,6 +460,11 @@ public final class ShortsFilter extends Filter {
|
|||
if (contentIndex != 0) {
|
||||
return false;
|
||||
}
|
||||
// Check ConversationContext to not hide shelf header in channel profile
|
||||
// This value does not exist in the shelf header in the channel profile
|
||||
if (!contextInterface.isHomeFeedOrRelatedVideo()) {
|
||||
return channelProfileShelfHeader.check(buffer).isFiltered();
|
||||
}
|
||||
|
||||
return shouldHideShortsFeedItems();
|
||||
}
|
||||
|
|
@ -456,7 +479,7 @@ public final class ShortsFilter extends Filter {
|
|||
}
|
||||
|
||||
if (matchedGroup == useButtons) {
|
||||
return path.contains("button.e") && useButtonsBuffer.check(buffer).isFiltered();
|
||||
return path.contains("|button.e") && useButtonsBuffer.check(buffer).isFiltered();
|
||||
}
|
||||
|
||||
if (matchedGroup == suggestedAction) {
|
||||
|
|
@ -493,15 +516,6 @@ public final class ShortsFilter extends Filter {
|
|||
if (!hideHome && !hideSubscriptions && !hideSearch && !hideVideoDescription && !hideHistory) {
|
||||
return false;
|
||||
}
|
||||
// The Litho path of the feed video is 'video_lockup_with_attachment.e'.
|
||||
// It appears shortsCompactFeedVideoBuffer is used after 20 seconds during autoplay in the feed in YouTube 20.44.38.
|
||||
// If the Shorts shelf is hidden on the Home feed, the video in the feed will be hidden after 20 seconds have passed since autoplay began in the feed.
|
||||
//
|
||||
// When a video is autoplaying in the feed, no new components are drawn on the screen.
|
||||
// Therefore, filtering is skipped when the current PlayerType is INLINE_MINIMAL.
|
||||
if (PlayerType.getCurrent() == PlayerType.INLINE_MINIMAL) {
|
||||
return false;
|
||||
}
|
||||
if (hideHome && hideSubscriptions && hideSearch && hideVideoDescription && hideHistory) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue