Skip to content

Commit df53fdf

Browse files
committed
feat(YouTube/Hide comments components): add Hide highlighted search links setting inotia00/ReVanced_Extended#2435
1 parent 620aeae commit df53fdf

File tree

7 files changed

+125
-6
lines changed

7 files changed

+125
-6
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
package app.revanced.patches.shared.textcomponent.fingerprints
1+
package app.revanced.patches.shared.fingerprints
22

33
import app.revanced.patcher.fingerprint.MethodFingerprint
4-
import app.revanced.patches.shared.textcomponent.fingerprints.SpannableStringBuilderFingerprint.indexOfSpannableStringInstruction
4+
import app.revanced.patches.shared.fingerprints.SpannableStringBuilderFingerprint.indexOfSpannableStringInstruction
55
import app.revanced.util.getReference
66
import app.revanced.util.indexOfFirstInstruction
77
import com.android.tools.smali.dexlib2.Opcode

src/main/kotlin/app/revanced/patches/shared/textcomponent/TextComponentPatch.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
88
import app.revanced.patcher.patch.BytecodePatch
99
import app.revanced.patcher.patch.PatchException
1010
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
11-
import app.revanced.patches.shared.textcomponent.fingerprints.SpannableStringBuilderFingerprint
11+
import app.revanced.patches.shared.fingerprints.SpannableStringBuilderFingerprint
1212
import app.revanced.patches.shared.textcomponent.fingerprints.TextComponentConstructorFingerprint
1313
import app.revanced.patches.shared.textcomponent.fingerprints.TextComponentContextFingerprint
1414
import app.revanced.util.alsoResolve
@@ -33,7 +33,8 @@ object TextComponentPatch : BytecodePatch(
3333

3434
SpannableStringBuilderFingerprint.resultOrThrow().mutableMethod.apply {
3535
spannedMethod = this
36-
spannedIndex = SpannableStringBuilderFingerprint.indexOfSpannableStringInstruction(this)
36+
spannedIndex =
37+
SpannableStringBuilderFingerprint.indexOfSpannableStringInstruction(this)
3738
spannedRegister = getInstruction<FiveRegisterInstruction>(spannedIndex).registerC
3839
spannedContextRegister =
3940
getInstruction<TwoRegisterInstruction>(0).registerA
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package app.revanced.patches.shared.textcomponent.fingerprints
2+
3+
import app.revanced.patcher.fingerprint.MethodFingerprint
4+
import app.revanced.patches.shared.textcomponent.fingerprints.InclusiveSpanFingerprint.STARTS_WITH_PARAMETER_LIST
5+
import app.revanced.patches.shared.textcomponent.fingerprints.InclusiveSpanFingerprint.indexOfSetSpanInstruction
6+
import app.revanced.util.getReference
7+
import app.revanced.util.indexOfFirstInstructionReversed
8+
import app.revanced.util.parametersEqual
9+
import com.android.tools.smali.dexlib2.Opcode
10+
import com.android.tools.smali.dexlib2.iface.Method
11+
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
12+
13+
internal object InclusiveSpanFingerprint : MethodFingerprint(
14+
returnType = "V",
15+
// 19.14 and earlier parameters are:
16+
// "Landroid/text/SpannableString;",
17+
// "Ljava/lang/Object;",
18+
// "I",
19+
// "I"
20+
21+
// 19.15+ parameters are:
22+
// "Landroid/text/SpannableString;",
23+
// "Ljava/lang/Object;",
24+
// "I",
25+
// "I",
26+
// "Z"
27+
customFingerprint = custom@{ methodDef, _ ->
28+
val parameterTypes = methodDef.parameterTypes
29+
val parameterSize = parameterTypes.size
30+
if (parameterSize != 4 && parameterSize != 5) {
31+
return@custom false
32+
}
33+
val startsWithMethodParameterList = parameterTypes.slice(0..3)
34+
35+
if (!parametersEqual(STARTS_WITH_PARAMETER_LIST, startsWithMethodParameterList)) {
36+
return@custom false
37+
}
38+
indexOfSetSpanInstruction(methodDef) >= 0
39+
},
40+
) {
41+
internal const val SET_SPAN_METHOD_CALL =
42+
"Landroid/text/SpannableString;->setSpan(Ljava/lang/Object;III)V"
43+
44+
private val STARTS_WITH_PARAMETER_LIST = listOf(
45+
"Landroid/text/SpannableString;",
46+
"Ljava/lang/Object;",
47+
"I",
48+
"I"
49+
)
50+
51+
fun indexOfSetSpanInstruction(methodDef: Method) =
52+
methodDef.indexOfFirstInstructionReversed {
53+
opcode == Opcode.INVOKE_VIRTUAL &&
54+
getReference<MethodReference>().toString() == SET_SPAN_METHOD_CALL
55+
}
56+
}

src/main/kotlin/app/revanced/patches/youtube/player/comments/CommentsComponentPatch.kt

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,29 @@ import app.revanced.patcher.data.BytecodeContext
44
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
55
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
66
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
7+
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
8+
import app.revanced.patches.shared.fingerprints.SpannableStringBuilderFingerprint
79
import app.revanced.patches.shared.litho.LithoFilterPatch
10+
import app.revanced.patches.shared.textcomponent.TextComponentPatch
811
import app.revanced.patches.youtube.player.comments.fingerprints.ShortsLiveStreamEmojiPickerOnClickListenerFingerprint
912
import app.revanced.patches.youtube.player.comments.fingerprints.ShortsLiveStreamEmojiPickerOpacityFingerprint
1013
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
1114
import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
1215
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
16+
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_PATH
1317
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
1418
import app.revanced.patches.youtube.utils.settings.SettingsPatch
19+
import app.revanced.util.getFiveRegisters
20+
import app.revanced.util.getReference
1521
import app.revanced.util.getWalkerMethod
1622
import app.revanced.util.indexOfFirstInstructionOrThrow
23+
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
1724
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
1825
import app.revanced.util.patch.BaseBytecodePatch
1926
import app.revanced.util.resultOrThrow
2027
import com.android.tools.smali.dexlib2.Opcode
2128
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
29+
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
2230

2331
@Suppress("unused")
2432
object CommentsComponentPatch : BaseBytecodePatch(
@@ -27,19 +35,59 @@ object CommentsComponentPatch : BaseBytecodePatch(
2735
dependencies = setOf(
2836
LithoFilterPatch::class,
2937
SettingsPatch::class,
30-
SharedResourceIdPatch::class
38+
SharedResourceIdPatch::class,
39+
TextComponentPatch::class,
3140
),
3241
compatiblePackages = COMPATIBLE_PACKAGE,
3342
fingerprints = setOf(
3443
ShortsLiveStreamEmojiPickerOnClickListenerFingerprint,
35-
ShortsLiveStreamEmojiPickerOpacityFingerprint
44+
ShortsLiveStreamEmojiPickerOpacityFingerprint,
45+
SpannableStringBuilderFingerprint,
3646
)
3747
) {
3848
private const val FILTER_CLASS_DESCRIPTOR =
3949
"$COMPONENTS_PATH/CommentsFilter;"
50+
private const val INTEGRATIONS_SEARCH_LINKS_CLASS_DESCRIPTOR =
51+
"$PLAYER_PATH/SearchLinksPatch;"
4052

4153
override fun execute(context: BytecodeContext) {
4254

55+
TextComponentPatch.hookSpannableString(
56+
INTEGRATIONS_SEARCH_LINKS_CLASS_DESCRIPTOR,
57+
"setConversionContext"
58+
)
59+
60+
SpannableStringBuilderFingerprint.resultOrThrow().mutableMethod.apply {
61+
val spannedIndex =
62+
SpannableStringBuilderFingerprint.indexOfSpannableStringInstruction(this)
63+
val setInclusiveSpanIndex = indexOfFirstInstructionOrThrow(spannedIndex) {
64+
val reference = getReference<MethodReference>()
65+
opcode == Opcode.INVOKE_STATIC &&
66+
reference?.returnType == "V" &&
67+
reference.parameterTypes.size > 3 &&
68+
reference.parameterTypes.firstOrNull() == "Landroid/text/SpannableString;"
69+
}
70+
// In YouTube 18.29.38, YouTube 19.41.39, the target method is in class 'La;'
71+
// 'getWalkerMethod' should be used until the dependency is updated to ReVanced Patcher 20+.
72+
// https://github.com/ReVanced/revanced-patcher/issues/309
73+
val setInclusiveSpanMethod =
74+
getWalkerMethod(context, setInclusiveSpanIndex)
75+
76+
setInclusiveSpanMethod.apply {
77+
val insertIndex = indexOfFirstInstructionReversedOrThrow {
78+
opcode == Opcode.INVOKE_VIRTUAL &&
79+
getReference<MethodReference>().toString() == "Landroid/text/SpannableString;->setSpan(Ljava/lang/Object;III)V"
80+
}
81+
replaceInstruction(
82+
insertIndex,
83+
"invoke-static { ${getFiveRegisters(insertIndex)} }, " +
84+
INTEGRATIONS_SEARCH_LINKS_CLASS_DESCRIPTOR +
85+
"->" +
86+
"hideSearchLinks(Landroid/text/SpannableString;Ljava/lang/Object;III)V"
87+
)
88+
}
89+
}
90+
4391
// region patch for emoji picker button in shorts
4492

4593
ShortsLiveStreamEmojiPickerOpacityFingerprint.resultOrThrow().let {

src/main/kotlin/app/revanced/util/BytecodeUtils.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,16 @@ fun MutableMethod.getWalkerMethod(context: BytecodeContext, offset: Int): Mutabl
509509
}
510510
}
511511

512+
/**
513+
* Taken from BiliRoamingX:
514+
* https://github.com/BiliRoamingX/BiliRoamingX/blob/ae58109f3acdd53ec2d2b3fb439c2a2ef1886221/patches/src/main/kotlin/app/revanced/patches/bilibili/utils/Extenstions.kt#L151
515+
*/
516+
fun MutableMethod.getFiveRegisters(index: Int) =
517+
with (getInstruction<FiveRegisterInstruction>(index)) {
518+
arrayOf(registerC, registerD, registerE, registerF, registerG)
519+
.take(registerCount).joinToString(",") { "v$it" }
520+
}
521+
512522
fun BytecodeContext.addStaticFieldToIntegration(
513523
className: String,
514524
methodName: String,

src/main/resources/youtube/settings/host/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,9 @@ Settings → Autoplay → Autoplay next video"</string>
791791
<string name="revanced_hide_comments_by_members_title">Hide Comments by members banner</string>
792792
<string name="revanced_hide_comments_by_members_summary_on">Comments by members banner is hidden.</string>
793793
<string name="revanced_hide_comments_by_members_summary_off">Comments by members banner is shown.</string>
794+
<string name="revanced_hide_comment_highlighted_search_links_title">Hide highlighted search links</string>
795+
<string name="revanced_hide_comment_highlighted_search_links_summary_on">Highlighted search links are hidden.</string>
796+
<string name="revanced_hide_comment_highlighted_search_links_summary_off">Highlighted search links are shown.</string>
794797
<string name="revanced_hide_comments_section_title">Hide Comments section</string>
795798
<string name="revanced_hide_comments_section_summary_on">Comments section is hidden.</string>
796799
<string name="revanced_hide_comments_section_summary_off">Comments section is shown.</string>

src/main/resources/youtube/settings/xml/revanced_prefs.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@
321321
<PreferenceScreen android:title="@string/revanced_preference_screen_comments_title" android:key="revanced_preference_screen_comments" android:summary="@string/revanced_preference_screen_comments_summary">
322322
<SwitchPreference android:title="@string/revanced_hide_channel_guidelines_title" android:key="revanced_hide_channel_guidelines" android:summaryOn="@string/revanced_hide_channel_guidelines_summary_on" android:summaryOff="@string/revanced_hide_channel_guidelines_summary_off" />
323323
<SwitchPreference android:title="@string/revanced_hide_comments_by_members_title" android:key="revanced_hide_comments_by_members" android:summaryOn="@string/revanced_hide_comments_by_members_summary_on" android:summaryOff="@string/revanced_hide_comments_by_members_summary_off" />
324+
<SwitchPreference android:title="@string/revanced_hide_comment_highlighted_search_links_title" android:key="revanced_hide_comment_highlighted_search_links" android:summaryOn="@string/revanced_hide_comment_highlighted_search_links_summary_on" android:summaryOff="@string/revanced_hide_comment_highlighted_search_links_summary_off" />
324325
<SwitchPreference android:title="@string/revanced_hide_comments_section_title" android:key="revanced_hide_comments_section" android:summaryOn="@string/revanced_hide_comments_section_summary_on" android:summaryOff="@string/revanced_hide_comments_section_summary_off" />
325326
<SwitchPreference android:title="@string/revanced_hide_comments_section_in_home_feed_title" android:key="revanced_hide_comments_section_in_home_feed" android:summaryOn="@string/revanced_hide_comments_section_in_home_feed_summary_on" android:summaryOff="@string/revanced_hide_comments_section_in_home_feed_summary_off" />
326327
<SwitchPreference android:title="@string/revanced_hide_preview_comment_title" android:key="revanced_hide_preview_comment" android:summaryOn="@string/revanced_hide_preview_comment_on" android:summaryOff="@string/revanced_hide_preview_comment_off" />

0 commit comments

Comments
 (0)