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

Commit 58d867f

Browse files
committed
feat(YouTube/Hide comments components): add Hide highlighted search links setting inotia00/ReVanced_Extended#2435
1 parent 173b851 commit 58d867f

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package app.revanced.integrations.youtube.patches.player;
2+
3+
import android.text.Spannable;
4+
import android.text.SpannableString;
5+
import android.text.style.AbsoluteSizeSpan;
6+
import android.text.style.ClickableSpan;
7+
import android.text.style.ForegroundColorSpan;
8+
import android.text.style.ImageSpan;
9+
import android.text.style.RelativeSizeSpan;
10+
import android.text.style.TypefaceSpan;
11+
12+
import androidx.annotation.NonNull;
13+
14+
import app.revanced.integrations.shared.utils.Logger;
15+
import app.revanced.integrations.youtube.settings.Settings;
16+
17+
@SuppressWarnings("unused")
18+
public class SearchLinksPatch {
19+
private static final boolean HIDE_COMMENT_HIGHLIGHTED_SEARCH_LINKS = Settings.HIDE_COMMENT_HIGHLIGHTED_SEARCH_LINKS.get();
20+
21+
/**
22+
* Located in front of the search icon.
23+
*/
24+
private static final String WORD_JOINER_CHARACTER = "\u2060";
25+
26+
/**
27+
* It doesn't seem necessary to use ThreadLocal.
28+
*/
29+
private static final ThreadLocal<String> conversionContextThreadLocal = new ThreadLocal<>();
30+
31+
/**
32+
* RelativeSizeSpan to be applied to the font assigned for the search icon, with a size of 0.
33+
*/
34+
private static final RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(0f);
35+
36+
37+
/**
38+
* Injection point.
39+
*
40+
* @param conversionContext ConversionContext is used to identify whether it is a comment thread or not.
41+
*/
42+
public static CharSequence setConversionContext(@NonNull Object conversionContext,
43+
@NonNull CharSequence original) {
44+
conversionContextThreadLocal.set(conversionContext.toString());
45+
return original;
46+
}
47+
48+
/**
49+
* Injection point.
50+
*
51+
* @param original Original SpannableString.
52+
* @param object Span such as {@link ClickableSpan}, {@link ForegroundColorSpan},
53+
* {@link AbsoluteSizeSpan}, {@link TypefaceSpan}, {@link ImageSpan}.
54+
* @param start Start index of {@link Spannable#setSpan(Object, int, int, int)}.
55+
* @param end End index of {@link Spannable#setSpan(Object, int, int, int)}.
56+
* @param flags Flags of {@link Spannable#setSpan(Object, int, int, int)}.
57+
*/
58+
public static void hideSearchLinks(SpannableString original, Object object,
59+
int start, int end, int flags) {
60+
try {
61+
if (HIDE_COMMENT_HIGHLIGHTED_SEARCH_LINKS &&
62+
isCommentThread() &&
63+
isWords(original, start, end) &&
64+
isSearchLinks(original, end)) {
65+
if (object instanceof ImageSpan) {
66+
Logger.printDebug(() -> "Hide the search icon by setting the font size to 0");
67+
original.setSpan(relativeSizeSpan, start, end, flags);
68+
return;
69+
}
70+
Logger.printDebug(() -> "Remove search link by skipping setSpan");
71+
return;
72+
}
73+
} catch (Exception ex) {
74+
Logger.printException(() -> "hideSearchLinks failure", ex);
75+
}
76+
original.setSpan(object, start, end, flags);
77+
}
78+
79+
/**
80+
* @return Whether it was invoked in a comment thread or not.
81+
*/
82+
private static boolean isCommentThread() {
83+
String conversionContext = conversionContextThreadLocal.get();
84+
return conversionContext != null &&
85+
conversionContext.contains("|comment.");
86+
}
87+
88+
/**
89+
* @return Whether Span applies to a word or not.
90+
*/
91+
private static boolean isWords(SpannableString original, int start, int end) {
92+
return start != 0 || end != original.length();
93+
}
94+
95+
/**
96+
* @return Whether the word contains a search icon or not.
97+
*/
98+
private static boolean isSearchLinks(SpannableString original, int end) {
99+
String originalString = original.toString();
100+
int wordJoinerIndex = originalString.indexOf(WORD_JOINER_CHARACTER);
101+
// There may be more than one highlight keyword in the comment.
102+
// Check the index of all highlight keywords.
103+
while (wordJoinerIndex != -1) {
104+
if (end - wordJoinerIndex == 2) return true;
105+
wordJoinerIndex = originalString.indexOf(WORD_JOINER_CHARACTER, wordJoinerIndex + 1);
106+
}
107+
return false;
108+
}
109+
}

app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ public class Settings extends BaseSettings {
289289
// PreferenceScreen: Player - Comments
290290
public static final BooleanSetting HIDE_CHANNEL_GUIDELINES = new BooleanSetting("revanced_hide_channel_guidelines", TRUE);
291291
public static final BooleanSetting HIDE_COMMENTS_BY_MEMBERS = new BooleanSetting("revanced_hide_comments_by_members", FALSE);
292+
public static final BooleanSetting HIDE_COMMENT_HIGHLIGHTED_SEARCH_LINKS = new BooleanSetting("revanced_hide_comment_highlighted_search_links", FALSE, true);
292293
public static final BooleanSetting HIDE_COMMENTS_SECTION = new BooleanSetting("revanced_hide_comments_section", FALSE);
293294
public static final BooleanSetting HIDE_COMMENTS_SECTION_IN_HOME_FEED = new BooleanSetting("revanced_hide_comments_section_in_home_feed", FALSE);
294295
public static final BooleanSetting HIDE_PREVIEW_COMMENT = new BooleanSetting("revanced_hide_preview_comment", FALSE);

0 commit comments

Comments
 (0)