mirror of
https://github.com/revanced/revanced-patches
synced 2024-12-25 07:45:48 +01:00
feat(YouTube - Hide video action buttons): Hide individual action buttons (#2723)
This commit is contained in:
parent
5a811962c3
commit
220f694b12
@ -34,6 +34,30 @@ class HideButtonsPatch : ResourcePatch {
|
|||||||
StringResource("revanced_hide_like_dislike_button_summary_on", "Like and dislike buttons are hidden"),
|
StringResource("revanced_hide_like_dislike_button_summary_on", "Like and dislike buttons are hidden"),
|
||||||
StringResource("revanced_hide_like_dislike_button_summary_off", "Like and dislike buttons are shown")
|
StringResource("revanced_hide_like_dislike_button_summary_off", "Like and dislike buttons are shown")
|
||||||
),
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_live_chat_button",
|
||||||
|
StringResource("revanced_hide_live_chat_button_title", "Hide live chat button"),
|
||||||
|
StringResource("revanced_hide_live_chat_button_summary_on", "Live chat button is hidden"),
|
||||||
|
StringResource("revanced_hide_live_chat_button_summary_off", "Live chat button is shown")
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_share_button",
|
||||||
|
StringResource("revanced_hide_share_button_title", "Hide share button"),
|
||||||
|
StringResource("revanced_hide_share_button_summary_on", "Share button is hidden"),
|
||||||
|
StringResource("revanced_hide_share_button_summary_off", "Share button is shown")
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_report_button",
|
||||||
|
StringResource("revanced_hide_report_button_title", "Hide report button"),
|
||||||
|
StringResource("revanced_hide_report_button_summary_on", "Report button is hidden"),
|
||||||
|
StringResource("revanced_hide_report_button_summary_off", "Report button is shown")
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_remix_button",
|
||||||
|
StringResource("revanced_hide_remix_button_title", "Hide remix button"),
|
||||||
|
StringResource("revanced_hide_remix_button_summary_on", "Remix button is hidden"),
|
||||||
|
StringResource("revanced_hide_remix_button_summary_off", "Remix button is shown")
|
||||||
|
),
|
||||||
SwitchPreference(
|
SwitchPreference(
|
||||||
"revanced_hide_download_button",
|
"revanced_hide_download_button",
|
||||||
StringResource("revanced_hide_download_button_title", "Hide download button"),
|
StringResource("revanced_hide_download_button_title", "Hide download button"),
|
||||||
@ -41,24 +65,28 @@ class HideButtonsPatch : ResourcePatch {
|
|||||||
StringResource("revanced_hide_download_button_summary_off", "Download button is shown")
|
StringResource("revanced_hide_download_button_summary_off", "Download button is shown")
|
||||||
),
|
),
|
||||||
SwitchPreference(
|
SwitchPreference(
|
||||||
"revanced_hide_playlist_button",
|
"revanced_hide_thanks_button",
|
||||||
StringResource("revanced_hide_playlist_button_title", "Hide playlist button"),
|
StringResource("revanced_hide_thanks_button_title", "Hide thanks button"),
|
||||||
StringResource("revanced_hide_playlist_button_summary_on", "Playlist button is hidden"),
|
StringResource("revanced_hide_thanks_button_summary_on", "Thanks button is hidden"),
|
||||||
StringResource("revanced_hide_playlist_button_summary_off", "Playlist button is shown")
|
StringResource("revanced_hide_thanks_button_summary_off", "Thanks button is shown")
|
||||||
),
|
),
|
||||||
SwitchPreference(
|
SwitchPreference(
|
||||||
"revanced_hide_clip_button",
|
"revanced_hide_clip_button",
|
||||||
StringResource("revanced_hide_clip_button_title", "Hide clip button"),
|
StringResource("revanced_hide_clip_button_title", "Hide clip button"),
|
||||||
StringResource("revanced_hide_clip_button_summary_on", "Clip button is hidden"),
|
StringResource("revanced_hide_clip_button_summary_on", "Clip button is hidden"),
|
||||||
StringResource("revanced_hide_clip_button_summary_off", "Clip button is shown"),
|
StringResource("revanced_hide_clip_button_summary_off", "Clip button is shown"),
|
||||||
StringResource("revanced_hide_clip_button_user_dialog_message",
|
|
||||||
"Hiding the clip button might not work reliably. In the case it does not work, it can only be hidden by enabling \\'Hide all other action buttons\\'")
|
|
||||||
),
|
),
|
||||||
SwitchPreference(
|
SwitchPreference(
|
||||||
"revanced_hide_action_buttons",
|
"revanced_hide_playlist_button",
|
||||||
StringResource("revanced_hide_action_buttons_title", "Hide all other action buttons"),
|
StringResource("revanced_hide_playlist_button_title", "Hide save to playlist button"),
|
||||||
StringResource("revanced_hide_action_buttons_summary_on", "Share, remix, thanks, shop, live chat buttons are hidden"),
|
StringResource("revanced_hide_playlist_button_summary_on", "Save button is hidden"),
|
||||||
StringResource("revanced_hide_action_buttons_summary_off", "Share, remix, thanks, shop, live chat buttons are shown")
|
StringResource("revanced_hide_playlist_button_summary_off", "Save button is shown")
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_shop_button",
|
||||||
|
StringResource("revanced_hide_shop_button_title", "Hide shop button"),
|
||||||
|
StringResource("revanced_hide_shop_button_summary_on", "Shop button is hidden"),
|
||||||
|
StringResource("revanced_hide_shop_button_summary_off", "Shop button is shown")
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
StringResource("revanced_hide_buttons_preference_screen_summary", "Hide or show buttons under videos")
|
StringResource("revanced_hide_buttons_preference_screen_summary", "Hide or show buttons under videos")
|
||||||
|
@ -9,23 +9,19 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
|
|||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
|
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.*
|
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.*
|
||||||
import org.jf.dexlib2.AccessFlags
|
|
||||||
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
|
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
import org.jf.dexlib2.iface.instruction.Instruction
|
import org.jf.dexlib2.iface.instruction.Instruction
|
||||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
import org.jf.dexlib2.immutable.ImmutableField
|
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
|
|
||||||
@DependsOn([IntegrationsPatch::class])
|
@DependsOn([IntegrationsPatch::class])
|
||||||
@ -41,32 +37,29 @@ class LithoFilterPatch : BytecodePatch(
|
|||||||
* Additionally, the method contains a reference to the components identifier.
|
* Additionally, the method contains a reference to the components identifier.
|
||||||
* The identifier is used to filter components by their identifier.
|
* The identifier is used to filter components by their identifier.
|
||||||
*
|
*
|
||||||
* In addition to that, a static field is added to the class of this method. (See protobufBufferField).
|
* The protobuf buffer is passed along from a different injection point before the filtering occurs.
|
||||||
* This field holds a reference to the protobuf buffer object.
|
* The buffer is a large byte array that represents the component tree.
|
||||||
* The field is being set in another method that holds a reference to the protobuf buffer object.
|
|
||||||
* The object contains a large byte array that represents the component tree.
|
|
||||||
* This byte array is searched for strings that indicate the current component.
|
* This byte array is searched for strings that indicate the current component.
|
||||||
*
|
*
|
||||||
* The following pseudo code shows how the patch works:
|
* The following pseudo code shows how the patch works:
|
||||||
*
|
*
|
||||||
* class ComponentContextParser {
|
|
||||||
* public static ByteBuffer buffer; // Inserted by this patch.
|
|
||||||
*
|
|
||||||
* public ComponentContext parseBytesToComponentContext(...) {
|
|
||||||
* ...
|
|
||||||
* if (filter(identifier, pathBuilder, buffer)); // Inserted by this patch.
|
|
||||||
* return emptyComponent;
|
|
||||||
* ...
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* class SomeOtherClass {
|
* class SomeOtherClass {
|
||||||
* // Called before ComponentContextParser.parseBytesToComponentContext method.
|
* // Called before ComponentContextParser.parseBytesToComponentContext method.
|
||||||
* public void someOtherMethod(ByteBuffer byteBuffer) {
|
* public void someOtherMethod(ByteBuffer byteBuffer) {
|
||||||
* ComponentContextParser.buffer = byteBuffer; // Inserted by this patch.
|
* IntegrationsClass.setProtoBuffer(byteBuffer); // Inserted by this patch.
|
||||||
* ...
|
* ...
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
*
|
||||||
|
* class ComponentContextParser {
|
||||||
|
*
|
||||||
|
* public ComponentContext parseBytesToComponentContext(...) {
|
||||||
|
* ...
|
||||||
|
* if (IntegrationsClass.filter(identifier, pathBuilder)); // Inserted by this patch.
|
||||||
|
* return emptyComponent;
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
ComponentContextParserFingerprint.result?.also {
|
ComponentContextParserFingerprint.result?.also {
|
||||||
@ -78,21 +71,12 @@ class LithoFilterPatch : BytecodePatch(
|
|||||||
return fingerprint.toErrorResult()
|
return fingerprint.toErrorResult()
|
||||||
}
|
}
|
||||||
}?.let { bytesToComponentContextMethod ->
|
}?.let { bytesToComponentContextMethod ->
|
||||||
// region Add a static field that holds a reference to the protobuf buffer object.
|
|
||||||
val protobufBufferField = ImmutableField(
|
|
||||||
bytesToComponentContextMethod.mutableClass.type,
|
|
||||||
"buffer",
|
|
||||||
"Ljava/nio/ByteBuffer;",
|
|
||||||
AccessFlags.PUBLIC or AccessFlags.STATIC,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null
|
|
||||||
).toMutable()
|
|
||||||
bytesToComponentContextMethod.mutableClass.staticFields.add(protobufBufferField)
|
|
||||||
|
|
||||||
// Set the field with the reference to the protobuf buffer object.
|
// region Pass the buffer into Integrations.
|
||||||
|
|
||||||
ProtobufBufferReferenceFingerprint.result
|
ProtobufBufferReferenceFingerprint.result
|
||||||
?.mutableMethod?.addInstruction(0, "sput-object p2, $protobufBufferField")
|
?.mutableMethod?.addInstruction(0,
|
||||||
|
" invoke-static { p2 }, $INTEGRATIONS_CLASS_DESCRIPTOR->setProtoBuffer(Ljava/nio/ByteBuffer;)V")
|
||||||
?: return ProtobufBufferReferenceFingerprint.toErrorResult()
|
?: return ProtobufBufferReferenceFingerprint.toErrorResult()
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
@ -135,17 +119,13 @@ class LithoFilterPatch : BytecodePatch(
|
|||||||
// region Patch the method.
|
// region Patch the method.
|
||||||
|
|
||||||
// Insert the instructions that are responsible
|
// Insert the instructions that are responsible
|
||||||
// to return an EmptyComponent instead of the original component if the filter method returns false.
|
// to return an EmptyComponent instead of the original component if the filter method returns true.
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
insertHookIndex,
|
insertHookIndex,
|
||||||
"""
|
"""
|
||||||
# Register "free1" holds the protobuf buffer object
|
|
||||||
|
|
||||||
sget-object v$free1, $protobufBufferField
|
|
||||||
|
|
||||||
# Invoke the filter method.
|
# Invoke the filter method.
|
||||||
|
|
||||||
invoke-static { v$stringBuilderRegister, v$identifierRegister, v$free1 }, $FILTER_METHOD_DESCRIPTOR
|
invoke-static { v$identifierRegister, v$stringBuilderRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->filter(Ljava/lang/String;Ljava/lang/StringBuilder;)Z
|
||||||
move-result v$free1
|
move-result v$free1
|
||||||
|
|
||||||
if-eqz v$free1, :unfiltered
|
if-eqz v$free1, :unfiltered
|
||||||
@ -197,9 +177,7 @@ class LithoFilterPatch : BytecodePatch(
|
|||||||
private val Instruction.descriptor
|
private val Instruction.descriptor
|
||||||
get() = (this as ReferenceInstruction).reference.toString()
|
get() = (this as ReferenceInstruction).reference.toString()
|
||||||
|
|
||||||
private const val FILTER_METHOD_DESCRIPTOR =
|
const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/components/LithoFilterPatch;"
|
||||||
"Lapp/revanced/integrations/patches/components/LithoFilterPatch;" +
|
|
||||||
"->filter(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/nio/ByteBuffer;)Z"
|
|
||||||
|
|
||||||
internal lateinit var addFilter: (String) -> Unit
|
internal lateinit var addFilter: (String) -> Unit
|
||||||
private set
|
private set
|
||||||
|
Loading…
Reference in New Issue
Block a user