From 8323c0fc2628b02ef58e6b52e9c59f299d37330f Mon Sep 17 00:00:00 2001 From: Aaron Veil <70171475+anddea@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:20:46 +0300 Subject: [PATCH] feat(YouTube - Hide feed components): Add `Match full word` option for keyword filtering --- .../components/KeywordContentFilter.java | 32 +++++++++++++++---- .../youtube/settings/Settings.java | 1 + 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/components/KeywordContentFilter.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/KeywordContentFilter.java index e7cb55c340..360701226e 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/components/KeywordContentFilter.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/KeywordContentFilter.java @@ -7,10 +7,10 @@ import androidx.annotation.Nullable; import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import app.revanced.integrations.shared.patches.components.Filter; import app.revanced.integrations.shared.patches.components.StringFilterGroup; @@ -150,6 +150,7 @@ public final class KeywordContentFilter extends Filter { private volatile String lastKeywordPhrasesParsed; private volatile ByteTrieSearch bufferSearch; + private volatile List regexPatterns; private static void logNavigationState(String state) { // Enable locally to debug filtering. Default off to reduce log spam. @@ -221,6 +222,9 @@ private synchronized void parseKeywords() { // Must be synchronized since Litho ByteTrieSearch search = new ByteTrieSearch(); String[] split = rawKeywords.split("\n"); + + List patterns = new ArrayList<>(); + if (split.length != 0) { // Linked Set so log statement are more organized and easier to read. Set keywords = new LinkedHashSet<>(10 * split.length); @@ -256,6 +260,8 @@ private synchronized void parseKeywords() { // Must be synchronized since Litho } for (String keyword : keywords) { + String regex = "(?:^|\\s)(" + Pattern.quote(keyword) + ")(?:$|\\s)"; + patterns.add(Pattern.compile(regex)); // Use a callback to get the keyword that matched. // TrieSearch could have this built in, but that's slightly more complicated since // the strings are stored as a byte array and embedded in the search tree. @@ -273,6 +279,7 @@ private synchronized void parseKeywords() { // Must be synchronized since Litho } bufferSearch = search; + regexPatterns = patterns; timeToResumeFiltering = 0; filteredVideosPercentage = 0; lastKeywordPhrasesParsed = rawKeywords; // Must set last. @@ -378,10 +385,21 @@ public boolean isFiltered(String path, @Nullable String identifier, String allVa return false; } - MutableReference matchRef = new MutableReference<>(); - if (bufferSearch.matches(protobufBufferArray, matchRef)) { - updateStats(true, matchRef.value); - return super.isFiltered(path, identifier, allValue, protobufBufferArray, matchedGroup, contentType, contentIndex); + if (Settings.HIDE_KEYWORD_CONTENT_FULL_WORD.get()) { + String content = new String(protobufBufferArray, StandardCharsets.UTF_8); + for (Pattern pattern : regexPatterns) { + Matcher matcher = pattern.matcher(content); + if (matcher.find()) { + updateStats(true, matcher.group(1)); + return super.isFiltered(path, identifier, allValue, protobufBufferArray, matchedGroup, contentType, contentIndex); + } + } + } else { + MutableReference matchRef = new MutableReference<>(); + if (bufferSearch.matches(protobufBufferArray, matchRef)) { + updateStats(true, matchRef.value); + return super.isFiltered(path, identifier, allValue, protobufBufferArray, matchedGroup, contentType, contentIndex); + } } updateStats(false, null); diff --git a/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java b/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java index f9faf20d84..f189577b05 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java +++ b/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java @@ -113,6 +113,7 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_KEYWORD_CONTENT_COMMENTS = new BooleanSetting("revanced_hide_keyword_content_comments", FALSE); public static final StringSetting HIDE_KEYWORD_CONTENT_PHRASES = new StringSetting("revanced_hide_keyword_content_phrases", "", parentsAny(HIDE_KEYWORD_CONTENT_HOME, HIDE_KEYWORD_CONTENT_SEARCH, HIDE_KEYWORD_CONTENT_SUBSCRIPTIONS, HIDE_KEYWORD_CONTENT_COMMENTS)); + public static final BooleanSetting HIDE_KEYWORD_CONTENT_FULL_WORD = new BooleanSetting("revanced_hide_keyword_content_full_word", FALSE); public static final BooleanSetting HIDE_RECOMMENDED_VIDEO = new BooleanSetting("revanced_hide_recommended_video", FALSE); public static final BooleanSetting HIDE_LOW_VIEWS_VIDEO = new BooleanSetting("revanced_hide_low_views_video", TRUE);