diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt index 79770b1d9..4556027a3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt @@ -5,15 +5,18 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.fingerprint.MethodFingerprint +import app.revanced.patcher.patch.PatchException import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.shared.litho.LithoFilterPatch import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsButtonFingerprint -import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsInfoPanelFingerprint import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsPaidPromotionFingerprint import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsPivotFingerprint import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsPivotLegacyFingerprint +import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsTabletFingerprint +import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsTabletParentFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR @@ -23,9 +26,6 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelD import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelDynShare import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelForcedMuteButton import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPivotButton -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerBadge -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerBadge2 -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerInfoPanel import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelRightDislikeIcon import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelRightLikeIcon import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.RightComment @@ -37,6 +37,9 @@ import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference @Suppress("unused") object ShortsComponentPatch : BaseBytecodePatch( @@ -48,16 +51,15 @@ object ShortsComponentPatch : BaseBytecodePatch( SettingsPatch::class, SharedResourceIdPatch::class, ShortsNavigationBarPatch::class, - ShortsSubscriptionsButtonPatch::class, ShortsToolBarPatch::class ), compatiblePackages = COMPATIBLE_PACKAGE, fingerprints = setOf( ShortsButtonFingerprint, - ShortsInfoPanelFingerprint, ShortsPaidPromotionFingerprint, ShortsPivotFingerprint, - ShortsPivotLegacyFingerprint + ShortsPivotLegacyFingerprint, + ShortsSubscriptionsTabletParentFingerprint ) ) { private const val BUTTON_FILTER_CLASS_DESCRIPTOR = @@ -67,14 +69,14 @@ object ShortsComponentPatch : BaseBytecodePatch( override fun execute(context: BytecodeContext) { - /** - * Comment button - */ + // region patch for hide comments button (non-litho) + ShortsButtonFingerprint.hideButton(RightComment, "hideShortsCommentsButton", false) - /** - * Dislike button - */ + // endregion + + // region patch for hide dislike button (non-litho) + ShortsButtonFingerprint.resultOrThrow().let { it.mutableMethod.apply { val constIndex = getWideLiteralInstructionIndex(ReelRightDislikeIcon) @@ -93,14 +95,10 @@ object ShortsComponentPatch : BaseBytecodePatch( } } - /** - * Info panel - */ - ShortsInfoPanelFingerprint.hideButtons(ReelPlayerInfoPanel, "hideShortsInfoPanel(Landroid/view/ViewGroup;)Landroid/view/ViewGroup;") + // endregion + + // region patch for hide like button (non-litho) - /** - * Like button - */ ShortsButtonFingerprint.resultOrThrow().let { it.mutableMethod.apply { val insertIndex = getWideLiteralInstructionIndex(ReelRightLikeIcon) @@ -118,15 +116,10 @@ object ShortsComponentPatch : BaseBytecodePatch( } } - /** - * Paid promotion - */ - ShortsPaidPromotionFingerprint.hideButtons(ReelPlayerBadge, "hideShortsPaidPromotionBanner(Landroid/view/ViewStub;)Landroid/view/ViewStub;") - ShortsPaidPromotionFingerprint.hideButtons(ReelPlayerBadge2, "hideShortsPaidPromotionBanner(Landroid/view/ViewStub;)Landroid/view/ViewStub;") + // endregion + + // region patch for hide sound button - /** - * Sound button - */ ShortsPivotLegacyFingerprint.result?.let { it.mutableMethod.apply { val targetIndex = getWideLiteralInstructionIndex(ReelForcedMuteButton) @@ -152,16 +145,97 @@ object ShortsComponentPatch : BaseBytecodePatch( } } - /** - * Remix button - */ + // endregion + + // region patch for hide remix button (non-litho) + ShortsButtonFingerprint.hideButton(ReelDynRemix, "hideShortsRemixButton", true) - /** - * Share button - */ + // endregion + + // region patch for hide share button (non-litho) + ShortsButtonFingerprint.hideButton(ReelDynShare, "hideShortsShareButton", true) + // endregion + + // region patch for hide paid promotion label (non-litho) + + ShortsPaidPromotionFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + when (returnType) { + "Landroid/widget/TextView;" -> { + val insertIndex = implementation!!.instructions.size - 1 + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex + 1, """ + invoke-static {v$insertRegister}, $SHORTS_CLASS_DESCRIPTOR->hideShortsPaidPromotionLabel(Landroid/widget/TextView;)V + return-object v$insertRegister + """ + ) + removeInstruction(insertIndex) + } + "V" -> { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->hideShortsPaidPromotionLabel()Z + move-result v0 + if-eqz v0, :show + return-void + """, ExternalLabel("show", getInstruction(0)) + ) + } + else -> { + throw PatchException("Unknown returnType: $returnType") + } + } + } + } + + // endregion + + // region patch for hide subscribe button (non-litho) + + // This method is deprecated since YouTube v18.31.xx. + if (!SettingsPatch.upward1831) { + ShortsSubscriptionsTabletParentFingerprint.resultOrThrow().let { parentResult -> + lateinit var subscriptionFieldReference: FieldReference + + parentResult.mutableMethod.apply { + val targetIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.ReelPlayerFooter) - 1 + subscriptionFieldReference = + (getInstruction(targetIndex)).reference as FieldReference + } + + ShortsSubscriptionsTabletFingerprint.also { + it.resolve( + context, + parentResult.classDef + ) + }.resultOrThrow().mutableMethod.apply { + implementation!!.instructions.filter { instruction -> + val fieldReference = + (instruction as? ReferenceInstruction)?.reference as? FieldReference + instruction.opcode == Opcode.IGET + && fieldReference == subscriptionFieldReference + }.forEach { instruction -> + val insertIndex = implementation!!.instructions.indexOf(instruction) + 1 + val register = (instruction as TwoRegisterInstruction).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$register}, $SHORTS_CLASS_DESCRIPTOR->hideShortsSubscribeButton(I)I + move-result v$register + """ + ) + } + } + } + } + + // endregion + LithoFilterPatch.addFilter(BUTTON_FILTER_CLASS_DESCRIPTOR) LithoFilterPatch.addFilter(SHELF_FILTER_CLASS_DESCRIPTOR) diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsSubscriptionsButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsSubscriptionsButtonPatch.kt deleted file mode 100644 index e51a1bedf..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsSubscriptionsButtonPatch.kt +++ /dev/null @@ -1,83 +0,0 @@ -package app.revanced.patches.youtube.shorts.components - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsFingerprint -import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsTabletFingerprint -import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsTabletParentFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerFooter -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerPausedStateButton -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.FieldReference - -@Patch(dependencies = [SettingsPatch::class]) -object ShortsSubscriptionsButtonPatch : BytecodePatch( - setOf( - ShortsSubscriptionsFingerprint, - ShortsSubscriptionsTabletParentFingerprint - ) -) { - private lateinit var subscriptionFieldReference: FieldReference - - override fun execute(context: BytecodeContext) { - ShortsSubscriptionsFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = getWideLiteralInstructionIndex(ReelPlayerPausedStateButton) + 2 - val insertRegister = getInstruction(insertIndex).registerA - - addInstruction( - insertIndex + 1, - "invoke-static {v$insertRegister}, $SHORTS_CLASS_DESCRIPTOR->hideShortsSubscriptionsButton(Landroid/view/View;)V" - ) - } - } - - /** - * Deprecated in YouTube v18.31.xx+ - */ - if (!SettingsPatch.upward1831) { - ShortsSubscriptionsTabletParentFingerprint.resultOrThrow().let { parentResult -> - parentResult.mutableMethod.apply { - val targetIndex = getWideLiteralInstructionIndex(ReelPlayerFooter) - 1 - subscriptionFieldReference = - (getInstruction(targetIndex)).reference as FieldReference - } - - ShortsSubscriptionsTabletFingerprint.also { - it.resolve( - context, - parentResult.classDef - ) - }.resultOrThrow().mutableMethod.apply { - implementation!!.instructions.filter { instruction -> - val fieldReference = - (instruction as? ReferenceInstruction)?.reference as? FieldReference - instruction.opcode == Opcode.IGET - && fieldReference == subscriptionFieldReference - }.forEach { instruction -> - val insertIndex = implementation!!.instructions.indexOf(instruction) + 1 - val register = (instruction as TwoRegisterInstruction).registerA - - addInstructions( - insertIndex, """ - invoke-static {v$register}, $SHORTS_CLASS_DESCRIPTOR->hideShortsSubscriptionsButton(I)I - move-result v$register - """ - ) - } - } - } - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsInfoPanelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsInfoPanelFingerprint.kt deleted file mode 100644 index 03a2bc7ba..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsInfoPanelFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.shorts.components.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerInfoPanel -import app.revanced.util.fingerprint.LiteralValueFingerprint -import com.android.tools.smali.dexlib2.AccessFlags - -internal object ShortsInfoPanelFingerprint : LiteralValueFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - literalSupplier = { ReelPlayerInfoPanel } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsPaidPromotionFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsPaidPromotionFingerprint.kt index 9a7f329f6..ab351ff88 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsPaidPromotionFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsPaidPromotionFingerprint.kt @@ -1,17 +1,13 @@ package app.revanced.patches.youtube.shorts.components.fingerprints -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerBadge -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerBadge2 -import app.revanced.util.containsWideLiteralInstructionIndex -import com.android.tools.smali.dexlib2.AccessFlags +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.BadgeLabel +import app.revanced.util.fingerprint.LiteralValueFingerprint -internal object ShortsPaidPromotionFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - customFingerprint = { methodDef, _ -> - methodDef.containsWideLiteralInstructionIndex(ReelPlayerBadge) - && methodDef.containsWideLiteralInstructionIndex(ReelPlayerBadge2) - }, +/** + * The method by which patches are applied is different between the minimum supported version and the maximum supported version. + * There are two classes where R.id.badge_label[BadgeLabel] is used, + * but due to the structure of ReVanced Patcher, the patch is applied to the method found first. + */ +internal object ShortsPaidPromotionFingerprint : LiteralValueFingerprint( + literalSupplier = { BadgeLabel } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsSubscriptionsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsSubscriptionsFingerprint.kt deleted file mode 100644 index 4cba80e0f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsSubscriptionsFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.youtube.shorts.components.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerPausedStateButton -import app.revanced.util.fingerprint.LiteralValueFingerprint -import com.android.tools.smali.dexlib2.AccessFlags - -internal object ShortsSubscriptionsFingerprint : LiteralValueFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = emptyList(), - literalSupplier = { ReelPlayerPausedStateButton } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt index 47d31f4b4..15a8565e8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt @@ -25,6 +25,7 @@ object SharedResourceIdPatch : ResourcePatch() { var AutoNavPreviewStub = -1L var AutoNavToggle = -1L var BackgroundCategory = -1L + var BadgeLabel = -1L var Bar = -1L var BarContainerHeight = -1L var BottomSheetFooterText = -1L @@ -66,11 +67,7 @@ object SharedResourceIdPatch : ResourcePatch() { var ReelDynShare = -1L var ReelForcedMuteButton = -1L var ReelPivotButton = -1L - var ReelPlayerBadge = -1L - var ReelPlayerBadge2 = -1L var ReelPlayerFooter = -1L - var ReelPlayerInfoPanel = -1L - var ReelPlayerPausedStateButton = -1L var ReelRightDislikeIcon = -1L var ReelRightLikeIcon = -1L var ReelTimeBarPlayedColor = -1L @@ -99,6 +96,7 @@ object SharedResourceIdPatch : ResourcePatch() { AutoNavPreviewStub = getId(ID, "autonav_preview_stub") AutoNavToggle = getId(ID, "autonav_toggle") BackgroundCategory = getId(STRING, "pref_background_and_offline_category") + BadgeLabel = getId(ID, "badge_label") Bar = getId(LAYOUT, "bar") BarContainerHeight = getId(DIMEN, "bar_container_height") BottomSheetFooterText = getId(ID, "bottom_sheet_footer_text") @@ -142,11 +140,7 @@ object SharedResourceIdPatch : ResourcePatch() { ReelDynShare = getId(ID, "reel_dyn_share") ReelForcedMuteButton = getId(ID, "reel_player_forced_mute_button") ReelPivotButton = getId(ID, "reel_pivot_button") - ReelPlayerBadge = getId(ID, "reel_player_badge") - ReelPlayerBadge2 = getId(ID, "reel_player_badge2") ReelPlayerFooter = getId(LAYOUT, "reel_player_dyn_footer_vert_stories3") - ReelPlayerInfoPanel = getId(ID, "reel_player_info_panel") - ReelPlayerPausedStateButton = getId(ID, "reel_player_paused_state_buttons") ReelRightDislikeIcon = getId(DRAWABLE, "reel_right_dislike_icon") ReelRightLikeIcon = getId(DRAWABLE, "reel_right_like_icon") ReelTimeBarPlayedColor = getId(COLOR, "reel_time_bar_played_color") diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index f207c74bc..b63a9328b 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -808,55 +808,14 @@ Please download %2$s from the website." Disable resuming Shorts player Shorts player will not resume on app startup Shorts player will resume on app startup - Hide comments button - Comments button is hidden. - Comments button is shown. - Hide dislike button - Dislike button is hidden. - Dislike button is shown. - Hide info panels - Info panels are hidden. - Info panels are shown. - Hide join button - Join button is hidden. - Join button is shown. - Hide like button - Like button is hidden. - Like button is shown. - Hide paid promotion banner - Paid promotion banner is hidden. - Paid promotion banner is shown. - Hide remix button - Remix button is hidden. - Remix button is shown. - Hide share button - Share button is hidden. - Share button is shown. - Hide sound button - Sound button is hidden. - Sound button is shown. - Hide subscriptions button - Subscriptions button is hidden. - Subscriptions button is shown. - Hide thanks button - Thanks button is hidden. - Thanks button is shown. - Hide toolbar - Toolbar is hidden. - Toolbar is shown. - Hide navigation bar - Navigation bar is hidden. - Navigation bar is shown. - - Shorts shelf - Hide or show shorts shelf in the feed, search, etc. + + Shorts shelf Hide shorts shelf "Hides Shorts shelves. Limitation: Official headers in search results will be hidden." - Hide in home feed and related videos Hidden in home feed and related videos. Shown in home feed and related videos. @@ -870,6 +829,82 @@ Limitation: Official headers in search results will be hidden." Hidden in watch history. Shown in watch history. + + Shorts player + Hide or show components in the shorts player. + + Hide join button + Join button is hidden. + Join button is shown. + Hide subscribe button + Subscribe button is hidden. + Subscribe button is shown. + Hide paused overlay buttons + Paused overlay buttons are hidden. + Paused overlay buttons are shown. + Hide paid promotion label + Paid promotion label is hidden. + Paid promotion label is shown. + Hide shop button + Shop button is hidden. + Shop button is shown. + Hide tagged products + Tagged products are hidden. + Tagged products are shown. + Hide location label + Location label is hidden. + Location label is shown. + Hide save sound to playlist button + Save sound to playlist is hidden. + Save sound to playlist is shown. + Hide search suggestions + Search suggestions are hidden. + Search suggestions are shown. + Hide info panels + Info panels are hidden. + Info panels are shown. + Hide channel bar + Channel bar is hidden. + Channel bar is shown. + Hide video title + Title is hidden. + Title is shown. + Hide sound metadata label + Metadata label is hidden. + Metadata label is shown. + Hide full video link label + Video link label is hidden. + Video link label is shown. + + + Action buttons + Hide like button + Like button is hidden. + Like button is shown. + Hide dislike button + Dislike button is hidden. + Dislike button is shown. + Hide comments button + Comments button is hidden. + Comments button is shown. + Hide remix button + Remix button is hidden. + Remix button is shown. + Hide share button + Share button is hidden. + Share button is shown. + Hide sound button + Sound button is hidden. + Sound button is shown. + + + Hide toolbar + Toolbar is hidden. + Toolbar is shown. + Hide navigation bar + Navigation bar is hidden. + Navigation bar is shown. + Swipe controls diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 0f1cf6350..b534005d2 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -369,12 +369,34 @@ PREFERENCE_SCREEN: SHORTS --> + + + + + + SETTINGS: HIDE_SHORTS_COMPONENTS -->