mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-13 05:37:40 +02:00
feat(YouTube - Shorts components): add Custom actions
setting (YouTube 19.05.36+)
This commit is contained in:
@ -5,16 +5,17 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.youtube.utils.bottomSheetMenuItemBuilderFingerprint
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.extension.Constants.FEED_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.indexOfSpannedCharSequenceInstruction
|
||||
import app.revanced.patches.youtube.utils.patch.PatchList.HIDE_FEED_FLYOUT_MENU
|
||||
import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch
|
||||
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
|
||||
import app.revanced.patches.youtube.utils.settings.settingsPatch
|
||||
import app.revanced.util.fingerprint.matchOrNull
|
||||
import app.revanced.util.fingerprint.matchOrThrow
|
||||
import app.revanced.util.fingerprint.methodOrThrow
|
||||
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.formats.Instruction35c
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@ -33,27 +34,16 @@ val feedFlyoutMenuPatch = bytecodePatch(
|
||||
|
||||
// region patch for phone
|
||||
|
||||
val bottomSheetMenuItemBuilderMatch =
|
||||
bottomSheetMenuItemBuilderLegacyFingerprint.matchOrNull()
|
||||
?: bottomSheetMenuItemBuilderFingerprint.matchOrThrow()
|
||||
bottomSheetMenuItemBuilderFingerprint.methodOrThrow().apply {
|
||||
val insertIndex = indexOfSpannedCharSequenceInstruction(this) + 2
|
||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex - 1).registerA
|
||||
|
||||
bottomSheetMenuItemBuilderMatch.let {
|
||||
it.method.apply {
|
||||
val targetIndex = it.patternMatch!!.endIndex
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
val targetParameter =
|
||||
getInstruction<ReferenceInstruction>(targetIndex - 1).reference
|
||||
if (!targetParameter.toString().endsWith("Ljava/lang/CharSequence;"))
|
||||
throw PatchException("Method signature parameter did not match: $targetParameter")
|
||||
|
||||
addInstructions(
|
||||
targetIndex + 1, """
|
||||
invoke-static {v$targetRegister}, $FEED_CLASS_DESCRIPTOR->hideFlyoutMenu(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
|
||||
move-result-object v$targetRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
addInstructions(
|
||||
insertIndex, """
|
||||
invoke-static {v$insertRegister}, $FEED_CLASS_DESCRIPTOR->hideFlyoutMenu(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
|
||||
move-result-object v$insertRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
@ -6,39 +6,6 @@ import app.revanced.util.or
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
/**
|
||||
* Compatible with YouTube v19.11.43~
|
||||
*/
|
||||
internal val bottomSheetMenuItemBuilderFingerprint = legacyFingerprint(
|
||||
name = "bottomSheetMenuItemBuilderFingerprint",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "L",
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT
|
||||
),
|
||||
strings = listOf("Text missing for BottomSheetMenuItem with iconType: ")
|
||||
)
|
||||
|
||||
/**
|
||||
* Compatible with ~YouTube v19.10.39
|
||||
*/
|
||||
internal val bottomSheetMenuItemBuilderLegacyFingerprint = legacyFingerprint(
|
||||
name = "bottomSheetMenuItemBuilderLegacyFingerprint",
|
||||
returnType = "L",
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT
|
||||
),
|
||||
strings = listOf("ElementTransformer, ElementPresenter and InteractionLogger cannot be null")
|
||||
)
|
||||
|
||||
internal val contextualMenuItemBuilderFingerprint = legacyFingerprint(
|
||||
name = "contextualMenuItemBuilderFingerprint",
|
||||
returnType = "V",
|
||||
|
@ -1,7 +1,6 @@
|
||||
package app.revanced.patches.youtube.shorts.components
|
||||
|
||||
import app.revanced.patches.youtube.utils.resourceid.badgeLabel
|
||||
import app.revanced.patches.youtube.utils.resourceid.bottomBarContainer
|
||||
import app.revanced.patches.youtube.utils.resourceid.metaPanel
|
||||
import app.revanced.patches.youtube.utils.resourceid.reelDynRemix
|
||||
import app.revanced.patches.youtube.utils.resourceid.reelDynShare
|
||||
@ -19,14 +18,18 @@ import app.revanced.util.or
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
// multiFingerprint
|
||||
internal val bottomBarContainerHeightFingerprint = legacyFingerprint(
|
||||
name = "bottomBarContainerHeightFingerprint",
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Landroid/view/View;", "Landroid/os/Bundle;"),
|
||||
strings = listOf("r_pfvc"),
|
||||
literals = listOf(bottomBarContainer),
|
||||
internal val bottomSheetMenuListBuilderFingerprint = legacyFingerprint(
|
||||
name = "bottomSheetMenuListBuilderFingerprint",
|
||||
returnType = "L",
|
||||
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
|
||||
parameters = emptyList(),
|
||||
opcodes = listOf(
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_EQZ,
|
||||
),
|
||||
strings = listOf("Bottom Sheet Menu is empty. No menu items were supported."),
|
||||
)
|
||||
|
||||
internal val reelEnumConstructorFingerprint = legacyFingerprint(
|
||||
|
@ -6,6 +6,7 @@ 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.extensions.InstructionExtensions.removeInstructions
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
@ -14,11 +15,13 @@ import app.revanced.patches.shared.litho.addLithoFilter
|
||||
import app.revanced.patches.shared.litho.lithoFilterPatch
|
||||
import app.revanced.patches.shared.textcomponent.hookSpannableString
|
||||
import app.revanced.patches.shared.textcomponent.textComponentPatch
|
||||
import app.revanced.patches.youtube.utils.bottomSheetMenuItemBuilderFingerprint
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.extension.Constants.COMPONENTS_PATH
|
||||
import app.revanced.patches.youtube.utils.extension.Constants.SHORTS_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.extension.Constants.SHORTS_PATH
|
||||
import app.revanced.patches.youtube.utils.extension.Constants.UTILS_PATH
|
||||
import app.revanced.patches.youtube.utils.indexOfSpannedCharSequenceInstruction
|
||||
import app.revanced.patches.youtube.utils.lottie.LOTTIE_ANIMATION_VIEW_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.lottie.lottieAnimationViewHookPatch
|
||||
import app.revanced.patches.youtube.utils.navigation.addBottomBarContainerHook
|
||||
@ -26,9 +29,12 @@ import app.revanced.patches.youtube.utils.navigation.navigationBarHookPatch
|
||||
import app.revanced.patches.youtube.utils.patch.PatchList.SHORTS_COMPONENTS
|
||||
import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch
|
||||
import app.revanced.patches.youtube.utils.playservice.is_18_31_or_greater
|
||||
import app.revanced.patches.youtube.utils.playservice.is_18_49_or_greater
|
||||
import app.revanced.patches.youtube.utils.playservice.is_19_25_or_greater
|
||||
import app.revanced.patches.youtube.utils.playservice.is_19_28_or_greater
|
||||
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
||||
import app.revanced.patches.youtube.utils.recyclerview.bottomSheetRecyclerViewHook
|
||||
import app.revanced.patches.youtube.utils.recyclerview.bottomSheetRecyclerViewPatch
|
||||
import app.revanced.patches.youtube.utils.resourceid.bottomBarContainer
|
||||
import app.revanced.patches.youtube.utils.resourceid.metaPanel
|
||||
import app.revanced.patches.youtube.utils.resourceid.reelDynRemix
|
||||
@ -49,9 +55,13 @@ import app.revanced.patches.youtube.utils.settings.ResourceUtils.getContext
|
||||
import app.revanced.patches.youtube.utils.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.video.information.hookShortsVideoInformation
|
||||
import app.revanced.patches.youtube.video.information.videoInformationPatch
|
||||
import app.revanced.patches.youtube.video.videoid.hookPlayerResponseVideoId
|
||||
import app.revanced.patches.youtube.video.videoid.videoIdPatch
|
||||
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.cloneMutable
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.findMethodOrThrow
|
||||
import app.revanced.util.findMutableMethodOf
|
||||
import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall
|
||||
import app.revanced.util.fingerprint.matchOrThrow
|
||||
@ -73,6 +83,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
||||
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.RegisterRangeInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
@ -130,6 +141,153 @@ private val shortsAnimationPatch = bytecodePatch(
|
||||
}
|
||||
}
|
||||
|
||||
private const val SHORTS_PLAYER_FLYOUT_MENU_FILTER_CLASS_DESCRIPTOR =
|
||||
"$COMPONENTS_PATH/ShortsCustomActionsFilter;"
|
||||
private const val EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR =
|
||||
"$SHORTS_PATH/CustomActionsPatch;"
|
||||
|
||||
private val shortsCustomActionsPatch = bytecodePatch(
|
||||
description = "shortsCustomActionsPatch"
|
||||
) {
|
||||
dependsOn(
|
||||
bottomSheetRecyclerViewPatch,
|
||||
lithoFilterPatch,
|
||||
playerTypeHookPatch,
|
||||
videoIdPatch,
|
||||
videoInformationPatch,
|
||||
versionCheckPatch,
|
||||
)
|
||||
|
||||
execute {
|
||||
if (!is_18_49_or_greater) {
|
||||
return@execute
|
||||
}
|
||||
|
||||
bottomSheetMenuListBuilderFingerprint.matchOrThrow().let {
|
||||
it.method.apply {
|
||||
val addListIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "add"
|
||||
}
|
||||
val addListReference = getInstruction<ReferenceInstruction>(addListIndex).reference
|
||||
|
||||
val getObjectIndex = indexOfFirstInstructionReversedOrThrow(addListIndex) {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.returnType == "Ljava/lang/Object;"
|
||||
}
|
||||
val getObjectReference = getInstruction<ReferenceInstruction>(getObjectIndex).reference as MethodReference
|
||||
|
||||
val bottomSheetMenuInitializeIndex = indexOfFirstInstructionOrThrow {
|
||||
val reference = getReference<MethodReference>()
|
||||
opcode == Opcode.INVOKE_STATIC_RANGE &&
|
||||
reference?.returnType == "V" &&
|
||||
reference.parameterTypes[1] == "Ljava/lang/Object;"
|
||||
}
|
||||
val bottomSheetMenuObjectRegister = getInstruction<RegisterRangeInstruction>(bottomSheetMenuInitializeIndex).startRegister
|
||||
val bottomSheetMenuObject = (getInstruction<ReferenceInstruction>(bottomSheetMenuInitializeIndex).reference as MethodReference).parameterTypes[0]!!
|
||||
|
||||
val bottomSheetMenuListIndex = it.patternMatch!!.startIndex
|
||||
val bottomSheetMenuListField = (getInstruction<ReferenceInstruction>(bottomSheetMenuListIndex).reference as FieldReference)
|
||||
|
||||
val bottomSheetMenuClass = bottomSheetMenuListField.definingClass
|
||||
val bottomSheetMenuList = bottomSheetMenuListField.type
|
||||
|
||||
val bottomSheetMenuClassRegister = getInstruction<TwoRegisterInstruction>(bottomSheetMenuListIndex).registerB
|
||||
val bottomSheetMenuListRegister = getInstruction<TwoRegisterInstruction>(bottomSheetMenuListIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
bottomSheetMenuListIndex + 1,
|
||||
"invoke-static {v$bottomSheetMenuClassRegister, v$bottomSheetMenuListRegister}, " +
|
||||
"$EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR->addFlyoutMenu(Ljava/lang/Object;Ljava/lang/Object;)V"
|
||||
)
|
||||
|
||||
addInstruction(
|
||||
bottomSheetMenuInitializeIndex + 1,
|
||||
"invoke-static {v$bottomSheetMenuObjectRegister}, " +
|
||||
"$EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR->setFlyoutMenuObject(Ljava/lang/Object;)V"
|
||||
)
|
||||
|
||||
val addFlyoutMenuMethod = findMethodOrThrow(EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR) {
|
||||
name == "addFlyoutMenu" &&
|
||||
accessFlags == AccessFlags.PRIVATE or AccessFlags.STATIC
|
||||
}
|
||||
|
||||
val customActionClass = with(addFlyoutMenuMethod) {
|
||||
val thirdParameter = parameters[2]
|
||||
|
||||
addInstructions(
|
||||
3, """
|
||||
check-cast p0, $bottomSheetMenuClass
|
||||
check-cast v0, $bottomSheetMenuObject
|
||||
invoke-virtual {p0, v0, p2}, $bottomSheetMenuClass->buildFlyoutMenu(${bottomSheetMenuObject}${thirdParameter})${getObjectReference.definingClass}
|
||||
move-result-object v0
|
||||
invoke-virtual {v0}, $getObjectReference
|
||||
move-result-object v0
|
||||
check-cast p1, $bottomSheetMenuList
|
||||
invoke-virtual {p1, v0}, $addListReference
|
||||
return-void
|
||||
"""
|
||||
)
|
||||
|
||||
thirdParameter
|
||||
}
|
||||
|
||||
val bottomSheetMenuItemBuilderMethod = bottomSheetMenuItemBuilderFingerprint
|
||||
.methodOrThrow()
|
||||
|
||||
val newParameter = bottomSheetMenuItemBuilderMethod.parameters + listOf(customActionClass)
|
||||
|
||||
it.classDef.methods.add(
|
||||
bottomSheetMenuItemBuilderMethod
|
||||
.cloneMutable(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
name = "buildFlyoutMenu",
|
||||
registerCount = bottomSheetMenuItemBuilderMethod.implementation!!.registerCount + 1,
|
||||
parameters = newParameter,
|
||||
).apply {
|
||||
val drawableIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_DIRECT &&
|
||||
getReference<MethodReference>()?.returnType == "Landroid/graphics/drawable/Drawable;"
|
||||
}
|
||||
val drawableRegister = getInstruction<OneRegisterInstruction>(drawableIndex + 1).registerA
|
||||
|
||||
addInstructions(
|
||||
drawableIndex + 2, """
|
||||
invoke-virtual {p2}, $customActionClass->getDrawable()Landroid/graphics/drawable/Drawable;
|
||||
move-result-object v$drawableRegister
|
||||
"""
|
||||
)
|
||||
|
||||
val charSequenceIndex = indexOfSpannedCharSequenceInstruction(this)
|
||||
val charSequenceRegister = getInstruction<OneRegisterInstruction>(charSequenceIndex + 1).registerA
|
||||
|
||||
val insertIndex = charSequenceIndex + 2
|
||||
|
||||
if (getInstruction<ReferenceInstruction>(insertIndex).reference.toString().startsWith("Lapp/revanced")) {
|
||||
removeInstructions(insertIndex, 2)
|
||||
}
|
||||
|
||||
addInstructions(
|
||||
insertIndex, """
|
||||
invoke-virtual {p2}, $customActionClass->getLabel()Ljava/lang/String;
|
||||
move-result-object v$charSequenceRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
bottomSheetRecyclerViewHook("$EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V")
|
||||
|
||||
hookPlayerResponseVideoId("$SHORTS_PLAYER_FLYOUT_MENU_FILTER_CLASS_DESCRIPTOR->newPlayerResponseVideoId(Ljava/lang/String;Z)V")
|
||||
hookShortsVideoInformation("$SHORTS_PLAYER_FLYOUT_MENU_FILTER_CLASS_DESCRIPTOR->newShortsVideoStarted(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZ)V")
|
||||
|
||||
addLithoFilter(SHORTS_PLAYER_FLYOUT_MENU_FILTER_CLASS_DESCRIPTOR)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private val shortsNavigationBarPatch = bytecodePatch(
|
||||
description = "shortsNavigationBarPatch"
|
||||
) {
|
||||
@ -344,6 +502,7 @@ val shortsComponentPatch = bytecodePatch(
|
||||
|
||||
dependsOn(
|
||||
shortsAnimationPatch,
|
||||
shortsCustomActionsPatch,
|
||||
shortsNavigationBarPatch,
|
||||
shortsRepeatPatch,
|
||||
shortsTimeStampPatch,
|
||||
@ -412,6 +571,10 @@ val shortsComponentPatch = bytecodePatch(
|
||||
settingArray += "SETTINGS: SHORTS_TIME_STAMP"
|
||||
}
|
||||
|
||||
if (is_18_49_or_greater) {
|
||||
settingArray += "SETTINGS: SHORTS_CUSTOM_ACTIONS"
|
||||
}
|
||||
|
||||
// region patch for hide comments button (non-litho)
|
||||
|
||||
shortsButtonFingerprint.hideButton(rightComment, "hideShortsCommentsButton", false)
|
||||
|
@ -21,6 +21,31 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal val bottomSheetMenuItemBuilderFingerprint = legacyFingerprint(
|
||||
name = "bottomSheetMenuItemBuilderFingerprint",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "L",
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT
|
||||
),
|
||||
strings = listOf("Text missing for BottomSheetMenuItem."),
|
||||
customFingerprint = { method, _ ->
|
||||
indexOfSpannedCharSequenceInstruction(method) >= 0
|
||||
}
|
||||
)
|
||||
|
||||
fun indexOfSpannedCharSequenceInstruction(method: Method) =
|
||||
method.indexOfFirstInstruction {
|
||||
val reference = getReference<MethodReference>()
|
||||
opcode == Opcode.INVOKE_STATIC &&
|
||||
reference?.parameterTypes?.size == 1 &&
|
||||
reference.returnType == "Ljava/lang/CharSequence;"
|
||||
}
|
||||
|
||||
internal val engagementPanelBuilderFingerprint = legacyFingerprint(
|
||||
name = "engagementPanelBuilderFingerprint",
|
||||
returnType = "L",
|
||||
|
@ -1041,7 +1041,7 @@ Tap and hold to copy video URL with timestamp."</string>
|
||||
Tap and hold to copy video timestamp."</string>
|
||||
<string name="revanced_overlay_button_mute_volume_title">Show mute volume button</string>
|
||||
<string name="revanced_overlay_button_mute_volume_summary">Tap to mute volume of the current video. Tap again to unmute.</string>
|
||||
<string name="revanced_overlay_button_external_downloader_title">Show external download button</string>
|
||||
<string name="revanced_overlay_button_external_downloader_title">Show external downloader button</string>
|
||||
<string name="revanced_overlay_button_external_downloader_summary">Tap to launch external downloader.</string>
|
||||
<string name="revanced_overlay_button_speed_dialog_title">Show speed dialog button</string>
|
||||
<string name="revanced_overlay_button_speed_dialog_summary">"Tap to open speed dialog.
|
||||
@ -1354,6 +1354,37 @@ Info:
|
||||
<string name="revanced_shorts_double_tap_to_like_animation_entry_5">Heart (Tint)</string>
|
||||
<string name="revanced_shorts_double_tap_to_like_animation_entry_6">Hidden</string>
|
||||
|
||||
<!-- PreferenceScreen: Shorts, PreferenceCategory: Shorts, PreferenceScreen: Shorts player, PreferenceCategory: Custom actions -->
|
||||
<string name="revanced_preference_category_custom_actions">Custom actions</string>
|
||||
<string name="revanced_enable_shorts_custom_actions_flyout_menu_title">Enable custom actions in flyout menu</string>
|
||||
<string name="revanced_enable_shorts_custom_actions_flyout_menu_summary_on">"Custom actions are enabled in flyout menu.
|
||||
|
||||
Limitations:
|
||||
• Does not work if app version is spoofed to 18.49.37 or earlier.
|
||||
• Does not work with livestream."</string>
|
||||
<string name="revanced_enable_shorts_custom_actions_flyout_menu_summary_off">Custom actions are disabled in flyout menu.</string>
|
||||
<string name="revanced_shorts_custom_actions_toolbar_dialog_title">Custom actions</string>
|
||||
<string name="revanced_shorts_custom_actions_copy_video_url_label">Copy video URL</string>
|
||||
<string name="revanced_shorts_custom_actions_copy_video_url_title">Show copy video URL menu</string>
|
||||
<string name="revanced_shorts_custom_actions_copy_video_url_summary_on">Copy video URL menu is shown.</string>
|
||||
<string name="revanced_shorts_custom_actions_copy_video_url_summary_off">Copy video URL menu is hidden.</string>
|
||||
<string name="revanced_shorts_custom_actions_copy_video_url_timestamp_label">Copy timestamp URL</string>
|
||||
<string name="revanced_shorts_custom_actions_copy_video_url_timestamp_title">Show copy timestamp URL menu</string>
|
||||
<string name="revanced_shorts_custom_actions_copy_video_url_timestamp_summary_on">Copy timestamp URL menu is shown.</string>
|
||||
<string name="revanced_shorts_custom_actions_copy_video_url_timestamp_summary_off">Copy timestamp URL menu is hidden.</string>
|
||||
<string name="revanced_shorts_custom_actions_external_downloader_label">External downloader</string>
|
||||
<string name="revanced_shorts_custom_actions_external_downloader_title">Show external downloader menu</string>
|
||||
<string name="revanced_shorts_custom_actions_external_downloader_summary_on">External downloader menu is shown.</string>
|
||||
<string name="revanced_shorts_custom_actions_external_downloader_summary_off">External downloader menu is hidden.</string>
|
||||
<string name="revanced_shorts_custom_actions_open_video_label">Open video</string>
|
||||
<string name="revanced_shorts_custom_actions_open_video_title">Show open video menu</string>
|
||||
<string name="revanced_shorts_custom_actions_open_video_summary_on">Open video menu is shown.</string>
|
||||
<string name="revanced_shorts_custom_actions_open_video_summary_off">Open video menu is hidden.</string>
|
||||
<string name="revanced_shorts_custom_actions_repeat_state_label">Repeat state</string>
|
||||
<string name="revanced_shorts_custom_actions_repeat_state_title">Show repeat state menu</string>
|
||||
<string name="revanced_shorts_custom_actions_repeat_state_summary_on">Repeat state menu is shown.</string>
|
||||
<string name="revanced_shorts_custom_actions_repeat_state_summary_off">Repeat state menu is hidden.</string>
|
||||
|
||||
<!-- PreferenceScreen: Shorts, PreferenceCategory: Shorts, PreferenceScreen: Shorts player, PreferenceCategory: Experimental Flags -->
|
||||
<string name="revanced_enable_shorts_time_stamp_title">Enable timestamps</string>
|
||||
<string name="revanced_enable_shorts_time_stamp_summary_on">"Timestamp is enabled.
|
||||
|
@ -580,9 +580,18 @@
|
||||
<PreferenceCategory android:title="@string/revanced_preference_category_animation_feedback" android:layout="@layout/revanced_settings_preferences_category"/>
|
||||
<SwitchPreference android:title="@string/revanced_disable_shorts_like_button_fountain_animation_title" android:key="revanced_disable_shorts_like_button_fountain_animation" android:summaryOn="@string/revanced_disable_shorts_like_button_fountain_animation_summary_on" android:summaryOff="@string/revanced_disable_shorts_like_button_fountain_animation_summary_off" />
|
||||
<SwitchPreference android:title="@string/revanced_hide_shorts_play_pause_button_background_title" android:key="revanced_hide_shorts_play_pause_button_background" android:summaryOn="@string/revanced_hide_shorts_play_pause_button_background_summary_on" android:summaryOff="@string/revanced_hide_shorts_play_pause_button_background_summary_off" />
|
||||
<ListPreference android:entries="@array/revanced_shorts_double_tap_to_like_animation_entries" android:title="@string/revanced_shorts_double_tap_to_like_animation_title" android:key="revanced_shorts_double_tap_to_like_animation" android:entryValues="@array/revanced_shorts_double_tap_to_like_animation_entry_values" />
|
||||
<ListPreference android:entries="@array/revanced_shorts_double_tap_to_like_animation_entries" android:title="@string/revanced_shorts_double_tap_to_like_animation_title" android:key="revanced_shorts_double_tap_to_like_animation" android:entryValues="@array/revanced_shorts_double_tap_to_like_animation_entry_values" />SETTINGS: SHORTS_COMPONENTS -->
|
||||
|
||||
<PreferenceCategory android:title="@string/revanced_preference_category_experimental_flag" android:layout="@layout/revanced_settings_preferences_category"/>SETTINGS: SHORTS_COMPONENTS -->
|
||||
<!-- SETTINGS: SHORTS_CUSTOM_ACTIONS
|
||||
<PreferenceCategory android:title="@string/revanced_preference_category_custom_actions" android:layout="@layout/revanced_settings_preferences_category"/>
|
||||
<SwitchPreference android:title="@string/revanced_enable_shorts_custom_actions_flyout_menu_title" android:key="revanced_enable_shorts_custom_actions_flyout_menu" android:summaryOn="@string/revanced_enable_shorts_custom_actions_flyout_menu_summary_on" android:summaryOff="@string/revanced_enable_shorts_custom_actions_flyout_menu_summary_off" />
|
||||
<SwitchPreference android:title="@string/revanced_shorts_custom_actions_copy_video_url_title" android:key="revanced_shorts_custom_actions_copy_video_url" android:summaryOn="@string/revanced_shorts_custom_actions_copy_video_url_summary_on" android:summaryOff="@string/revanced_shorts_custom_actions_copy_video_url_summary_off" />
|
||||
<SwitchPreference android:title="@string/revanced_shorts_custom_actions_copy_video_url_timestamp_title" android:key="revanced_shorts_custom_actions_copy_video_url_timestamp" android:summaryOn="@string/revanced_shorts_custom_actions_copy_video_url_timestamp_summary_on" android:summaryOff="@string/revanced_shorts_custom_actions_copy_video_url_timestamp_summary_off" />
|
||||
<SwitchPreference android:title="@string/revanced_shorts_custom_actions_external_downloader_title" android:key="revanced_shorts_custom_actions_external_downloader" android:summaryOn="@string/revanced_shorts_custom_actions_external_downloader_summary_on" android:summaryOff="@string/revanced_shorts_custom_actions_external_downloader_summary_off" />
|
||||
<SwitchPreference android:title="@string/revanced_shorts_custom_actions_open_video_title" android:key="revanced_shorts_custom_actions_open_video" android:summaryOn="@string/revanced_shorts_custom_actions_open_video_summary_on" android:summaryOff="@string/revanced_shorts_custom_actions_open_video_summary_off" />
|
||||
<SwitchPreference android:title="@string/revanced_shorts_custom_actions_repeat_state_title" android:key="revanced_shorts_custom_actions_repeat_state" android:summaryOn="@string/revanced_shorts_custom_actions_repeat_state_summary_on" android:summaryOff="@string/revanced_shorts_custom_actions_repeat_state_summary_off" />
|
||||
|
||||
<PreferenceCategory android:title="@string/revanced_preference_category_experimental_flag" android:layout="@layout/revanced_settings_preferences_category"/>SETTINGS: SHORTS_CUSTOM_ACTIONS -->
|
||||
|
||||
<!-- SETTINGS: SHORTS_TIME_STAMP
|
||||
<SwitchPreference android:title="@string/revanced_enable_shorts_time_stamp_title" android:key="revanced_enable_shorts_time_stamp" android:summaryOn="@string/revanced_enable_shorts_time_stamp_summary_on" android:summaryOff="@string/revanced_enable_shorts_time_stamp_summary_off" />
|
||||
|
Reference in New Issue
Block a user