feat(YouTube - Hide layout components): Add option to hide Yoodles (YouTube Doodles) (#3743)

Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
LisoUseInAIKyrios 2024-10-05 20:09:06 -04:00 committed by GitHub
parent 4c5631e73a
commit b8c89164cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 74 additions and 4 deletions

View file

@ -2184,6 +2184,7 @@ public final class app/revanced/util/BytecodeUtilsKt {
public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
public static final fun findOpcodeIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)Ljava/util/List;
public static final fun findOpcodeIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException;
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;)I
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I

View file

@ -18,13 +18,18 @@ import app.revanced.patches.youtube.layout.hide.general.fingerprints.HideShowMor
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElementFromBufferFingerprint
import app.revanced.patches.youtube.layout.hide.general.fingerprints.PlayerOverlayFingerprint
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ShowWatermarkFingerprint
import app.revanced.patches.youtube.layout.hide.general.fingerprints.YoodlesImageViewFingerprint
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.util.findOpcodeIndicesReversed
import app.revanced.util.getReference
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch(
name = "Hide layout components",
@ -70,7 +75,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
)
@Suppress("unused")
object HideLayoutComponentsPatch : BytecodePatch(
setOf(ParseElementFromBufferFingerprint, PlayerOverlayFingerprint, HideShowMoreButtonFingerprint),
setOf(
ParseElementFromBufferFingerprint,
PlayerOverlayFingerprint,
HideShowMoreButtonFingerprint,
YoodlesImageViewFingerprint,
),
) {
private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/components/LayoutComponentsFilter;"
@ -128,6 +138,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
SwitchPreference("revanced_hide_search_result_recommendations"),
SwitchPreference("revanced_hide_search_result_shelf_header"),
SwitchPreference("revanced_hide_show_more_button"),
SwitchPreference("revanced_hide_yoodles"),
PreferenceScreen(
key = "revanced_hide_keyword_content_screen",
sorting = Sorting.UNSORTED,
@ -226,5 +237,28 @@ object HideLayoutComponentsPatch : BytecodePatch(
}
// endregion
// region 'Yoodles'
YoodlesImageViewFingerprint.resultOrThrow().mutableMethod.apply {
findOpcodeIndicesReversed{
opcode == Opcode.INVOKE_VIRTUAL
&& getReference<MethodReference>()?.name == "setImageDrawable"
}.forEach { insertIndex ->
val register = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
addInstructionsWithLabels(
insertIndex,
"""
invoke-static { v$register }, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->hideYoodles(Landroid/graphics/drawable/Drawable;)Landroid/graphics/drawable/Drawable;
move-result-object v$register
if-eqz v$register, :hide
""",
ExternalLabel("hide", getInstruction(insertIndex + 1)),
)
}
}
// endregion
}
}

View file

@ -17,10 +17,17 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
internal object HideLayoutComponentsResourcePatch : ResourcePatch() {
internal var expandButtonDownId: Long = -1
var youTubeLogo = -1L
override fun execute(context: ResourceContext) {
expandButtonDownId = ResourceMappingPatch[
"layout",
"expand_button_down",
]
youTubeLogo = ResourceMappingPatch[
"id",
"youtube_logo"
]
}
}

View file

@ -0,0 +1,13 @@
package app.revanced.patches.youtube.layout.hide.general.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.general.HideLayoutComponentsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object YoodlesImageViewFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L", "L"),
returnType = "Landroid/view/View;",
literalSupplier = { HideLayoutComponentsResourcePatch.youTubeLogo }
)

View file

@ -224,18 +224,25 @@ fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, predicate: Instru
/**
* @return The list of indices of the opcode in reverse order.
*/
fun Method.findOpcodeIndicesReversed(opcode: Opcode): List<Int> {
fun Method.findOpcodeIndicesReversed(opcode: Opcode): List<Int> =
findOpcodeIndicesReversed { this.opcode == opcode }
/**
* @return The list of indices of the opcode in reverse order.
*/
fun Method.findOpcodeIndicesReversed(filter: Instruction.() -> Boolean): List<Int> {
val indexes = implementation!!.instructions
.withIndex()
.filter { (_, instruction) -> instruction.opcode == opcode }
.filter { (_, instruction) -> filter(instruction) }
.map { (index, _) -> index }
.reversed()
if (indexes.isEmpty()) throw PatchException("No ${opcode.name} instructions found in: $this")
if (indexes.isEmpty()) throw PatchException("No matching instructions found in: $this")
return indexes
}
/**
* Return the resolved method early.
*/

View file

@ -231,6 +231,13 @@ This is because Crowdin requires temporarily flattening this file and removing t
<string name="revanced_hide_transcript_section_summary_off">Transcript section is shown</string>
<string name="revanced_hide_description_components_screen_title">Video description</string>
<string name="revanced_hide_description_components_screen_summary">Hide or show video description components</string>
<!-- Yes, YouTube gave this feature the goofy name of "Yoodles". https://logos.fandom.com/wiki/YouTube/Yoodles -->
<string name="revanced_hide_yoodles_title">Hide Yoodles (YouTube Doodles)</string>
<string name="revanced_hide_yoodles_summary_on">Search bar Yoodles are hidden</string>
<string name="revanced_hide_yoodles_summary_off">Search bar Yoodles will be periodically shown</string>
<string name="revanced_hide_yoodles_user_dialog_message">YouTube Yoodles show up a few days each year.\n\nIf a Yoodle is currently showing in your region and this hide setting is on, then the filter bar below the search bar will also be hidden.</string>
<string name="revanced_custom_filter_screen_title">Custom filter</string>
<string name="revanced_custom_filter_screen_summary">Hide components using custom filters</string>
<string name="revanced_custom_filter_title">Enable custom filter</string>
@ -240,6 +247,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
<!-- 'Component path builder strings' is the technical name for identifying the Litho UI layout items to hide. This is an advanced feature and most users will never use this. -->
<string name="revanced_custom_filter_strings_summary">List of component path builder strings to filter separated by new line</string>
<string name="revanced_custom_filter_toast_invalid_syntax">Invalid custom filter: %s</string>
<string name="revanced_hide_keyword_content_screen_title">Hide keyword content</string>
<string name="revanced_hide_keyword_content_screen_summary">Hide search and feed videos using keyword filters</string>
<string name="revanced_hide_keyword_content_home_title">Hide home videos by keywords</string>