mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-04 16:44:29 +02:00
feat(YouTube/Hide layout components): filter home/search results by keywords
This commit is contained in:
parent
017ef705f8
commit
3bb394643e
@ -21,13 +21,16 @@ object LayoutComponentsPatch : BaseBytecodePatch(
|
||||
"$COMPONENTS_PATH/ChannelBarFilter;"
|
||||
private const val CUSTOM_FILTER_CLASS_DESCRIPTOR =
|
||||
"$COMPONENTS_PATH/CustomFilter;"
|
||||
private const val FILTER_CLASS_DESCRIPTOR =
|
||||
private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR =
|
||||
"$COMPONENTS_PATH/LayoutComponentsFilter;"
|
||||
private const val KEYWORD_FILTER_CLASS_NAME =
|
||||
"$COMPONENTS_PATH/KeywordContentFilter;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
LithoFilterPatch.addFilter(CHANNEL_BAR_FILTER_CLASS_DESCRIPTOR)
|
||||
LithoFilterPatch.addFilter(CUSTOM_FILTER_CLASS_DESCRIPTOR)
|
||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
||||
LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR)
|
||||
LithoFilterPatch.addFilter(KEYWORD_FILTER_CLASS_NAME)
|
||||
|
||||
/**
|
||||
* Add settings
|
||||
|
@ -1,26 +1,16 @@
|
||||
package app.revanced.patches.youtube.navigation.navigationbuttons
|
||||
|
||||
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.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.youtube.navigation.navigationbuttons.fingerprints.AutoMotiveFingerprint
|
||||
import app.revanced.patches.youtube.navigation.navigationbuttons.fingerprints.PivotBarButtonViewFingerprint
|
||||
import app.revanced.patches.youtube.navigation.navigationbuttons.fingerprints.PivotBarEnumFingerprint
|
||||
import app.revanced.patches.youtube.utils.fingerprints.PivotBarCreateButtonViewFingerprint
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ImageOnlyTab
|
||||
import app.revanced.patches.youtube.utils.navigation.NavigationBarHookPatch
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getStringInstructionIndex
|
||||
import app.revanced.util.getTargetIndex
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.Opcode.MOVE_RESULT_OBJECT
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@Suppress("unused")
|
||||
@ -29,60 +19,13 @@ object NavigationButtonsPatch : BaseBytecodePatch(
|
||||
description = "Adds options to hide and change navigation buttons (such as the Shorts button).",
|
||||
dependencies = setOf(
|
||||
SettingsPatch::class,
|
||||
SharedResourceIdPatch::class
|
||||
NavigationBarHookPatch::class
|
||||
),
|
||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||
fingerprints = setOf(
|
||||
AutoMotiveFingerprint,
|
||||
PivotBarCreateButtonViewFingerprint
|
||||
)
|
||||
fingerprints = setOf(AutoMotiveFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
|
||||
PivotBarCreateButtonViewFingerprint.resultOrThrow().let { parentResult ->
|
||||
|
||||
/**
|
||||
* Home, Shorts, Subscriptions Button
|
||||
*/
|
||||
with(
|
||||
arrayOf(
|
||||
PivotBarEnumFingerprint,
|
||||
PivotBarButtonViewFingerprint
|
||||
).onEach {
|
||||
it.resolve(
|
||||
context,
|
||||
parentResult.mutableMethod,
|
||||
parentResult.mutableClass
|
||||
)
|
||||
}.map {
|
||||
it.resultOrThrow().scanResult.patternScanResult!!
|
||||
}
|
||||
) {
|
||||
val enumScanResult = this[0]
|
||||
val buttonViewResult = this[1]
|
||||
|
||||
val enumHookInsertIndex = enumScanResult.startIndex + 2
|
||||
val buttonHookInsertIndex = buttonViewResult.endIndex
|
||||
|
||||
mapOf(
|
||||
BUTTON_HOOK to buttonHookInsertIndex,
|
||||
ENUM_HOOK to enumHookInsertIndex
|
||||
).forEach { (hook, insertIndex) ->
|
||||
parentResult.mutableMethod.injectHook(hook, insertIndex)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Button
|
||||
*/
|
||||
parentResult.mutableMethod.apply {
|
||||
val constIndex = getWideLiteralInstructionIndex(ImageOnlyTab)
|
||||
val insertIndex = getTargetIndex(constIndex, Opcode.INVOKE_VIRTUAL) + 2
|
||||
injectHook(CREATE_BUTTON_HOOK, insertIndex)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch create button with notifications button
|
||||
*/
|
||||
@ -93,13 +36,17 @@ object NavigationButtonsPatch : BaseBytecodePatch(
|
||||
|
||||
addInstructions(
|
||||
insertIndex, """
|
||||
invoke-static {v$register}, $NAVIGATION_CLASS_DESCRIPTOR->switchCreateNotification(Z)Z
|
||||
invoke-static {v$register}, $NAVIGATION_CLASS_DESCRIPTOR->switchCreateWithNotificationButton(Z)Z
|
||||
move-result v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Hook navigation button created, in order to hide them.
|
||||
NavigationBarHookPatch.hookNavigationButtonCreated(NAVIGATION_CLASS_DESCRIPTOR)
|
||||
|
||||
|
||||
/**
|
||||
* Add settings
|
||||
*/
|
||||
@ -113,40 +60,4 @@ object NavigationButtonsPatch : BaseBytecodePatch(
|
||||
SettingsPatch.updatePatchStatus("Hide navigation buttons")
|
||||
|
||||
}
|
||||
|
||||
private const val REGISTER_TEMPLATE_REPLACEMENT: String = "REGISTER_INDEX"
|
||||
|
||||
private const val ENUM_HOOK =
|
||||
"sput-object v$REGISTER_TEMPLATE_REPLACEMENT, $NAVIGATION_CLASS_DESCRIPTOR" +
|
||||
"->" +
|
||||
"lastPivotTab:Ljava/lang/Enum;"
|
||||
|
||||
private const val BUTTON_HOOK =
|
||||
"invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, $NAVIGATION_CLASS_DESCRIPTOR" +
|
||||
"->" +
|
||||
"hideNavigationButton(Landroid/view/View;)V"
|
||||
|
||||
private const val CREATE_BUTTON_HOOK =
|
||||
"invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, $NAVIGATION_CLASS_DESCRIPTOR" +
|
||||
"->" +
|
||||
"hideCreateButton(Landroid/view/View;)V"
|
||||
|
||||
/**
|
||||
* Injects an instruction into insertIndex of the hook.
|
||||
* @param hook The hook to insert.
|
||||
* @param insertIndex The index to insert the instruction at.
|
||||
* [MOVE_RESULT_OBJECT] has to be the previous instruction before [insertIndex].
|
||||
*/
|
||||
private fun MutableMethod.injectHook(hook: String, insertIndex: Int) {
|
||||
val injectTarget = this
|
||||
|
||||
// Register to pass to the hook
|
||||
val registerIndex = insertIndex - 1 // MOVE_RESULT_OBJECT is always the previous instruction
|
||||
val register = injectTarget.getInstruction<OneRegisterInstruction>(registerIndex).registerA
|
||||
|
||||
injectTarget.addInstruction(
|
||||
insertIndex,
|
||||
hook.replace("REGISTER_INDEX", register.toString()),
|
||||
)
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package app.revanced.patches.youtube.navigation.navigationbuttons.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object PivotBarButtonViewFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_VIRTUAL_RANGE,
|
||||
Opcode.MOVE_RESULT_OBJECT, // target reference
|
||||
null,
|
||||
)
|
||||
)
|
@ -1,15 +0,0 @@
|
||||
package app.revanced.patches.youtube.navigation.navigationbuttons.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object PivotBarEnumFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IF_NEZ, // target reference
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
)
|
||||
)
|
@ -8,7 +8,7 @@ import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patches.youtube.shorts.components.fingerprints.BottomNavigationBarFingerprint
|
||||
import app.revanced.patches.youtube.shorts.components.fingerprints.RenderBottomNavigationBarFingerprint
|
||||
import app.revanced.patches.youtube.shorts.components.fingerprints.SetPivotBarFingerprint
|
||||
import app.revanced.patches.youtube.utils.fingerprints.PivotBarCreateButtonViewFingerprint
|
||||
import app.revanced.patches.youtube.utils.fingerprints.InitializeButtonsFingerprint
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
||||
import app.revanced.util.getWalkerMethod
|
||||
@ -18,13 +18,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
object ShortsNavigationBarPatch : BytecodePatch(
|
||||
setOf(
|
||||
BottomNavigationBarFingerprint,
|
||||
PivotBarCreateButtonViewFingerprint,
|
||||
InitializeButtonsFingerprint,
|
||||
RenderBottomNavigationBarFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
|
||||
PivotBarCreateButtonViewFingerprint.resultOrThrow().let { parentResult ->
|
||||
InitializeButtonsFingerprint.resultOrThrow().let { parentResult ->
|
||||
SetPivotBarFingerprint.also { it.resolve(context, parentResult.classDef) }.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
|
@ -5,8 +5,9 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.Image
|
||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object PivotBarCreateButtonViewFingerprint : LiteralValueFingerprint(
|
||||
returnType = "V",
|
||||
internal object InitializeButtonsFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "V",
|
||||
parameters = emptyList(),
|
||||
literalSupplier = { ImageOnlyTab }
|
||||
)
|
@ -1,12 +1,12 @@
|
||||
package app.revanced.patches.youtube.utils.flyoutpanel
|
||||
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
|
||||
import app.revanced.patches.youtube.utils.flyoutpanel.fingerprints.PlaybackRateBottomSheetClassFingerprint
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH
|
||||
|
@ -0,0 +1,138 @@
|
||||
package app.revanced.patches.youtube.utils.navigation
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.youtube.utils.fingerprints.InitializeButtonsFingerprint
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH
|
||||
import app.revanced.patches.youtube.utils.navigation.fingerprints.ActionBarSearchResultsFingerprint
|
||||
import app.revanced.patches.youtube.utils.navigation.fingerprints.NavigationEnumFingerprint
|
||||
import app.revanced.patches.youtube.utils.navigation.fingerprints.PivotBarButtonsCreateDrawableViewFingerprint
|
||||
import app.revanced.patches.youtube.utils.navigation.fingerprints.PivotBarButtonsCreateResourceViewFingerprint
|
||||
import app.revanced.patches.youtube.utils.navigation.fingerprints.PivotBarConstructorFingerprint
|
||||
import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
||||
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.Instruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
|
||||
@Patch(
|
||||
description = "Hooks the active navigation or search bar.",
|
||||
dependencies = [
|
||||
PlayerTypeHookPatch::class,
|
||||
SharedResourceIdPatch::class
|
||||
],
|
||||
)
|
||||
@Suppress("unused")
|
||||
object NavigationBarHookPatch : BytecodePatch(
|
||||
setOf(
|
||||
ActionBarSearchResultsFingerprint,
|
||||
NavigationEnumFingerprint,
|
||||
PivotBarButtonsCreateDrawableViewFingerprint,
|
||||
PivotBarButtonsCreateResourceViewFingerprint,
|
||||
PivotBarConstructorFingerprint
|
||||
),
|
||||
) {
|
||||
internal const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"$INTEGRATIONS_PATH/shared/NavigationBar;"
|
||||
|
||||
private const val INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR =
|
||||
"$INTEGRATIONS_PATH/shared/NavigationBar\$NavigationButton;"
|
||||
|
||||
private lateinit var navigationTabCreatedCallback: MutableMethod
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
fun MutableMethod.addHook(hook: Hook, insertPredicate: Instruction.() -> Boolean) {
|
||||
val filtered = getInstructions().filter(insertPredicate)
|
||||
if (filtered.isEmpty()) throw PatchException("Could not find insert indexes")
|
||||
filtered.forEach {
|
||||
val insertIndex = it.location.index + 2
|
||||
val register = getInstruction<OneRegisterInstruction>(insertIndex - 1).registerA
|
||||
|
||||
addInstruction(
|
||||
insertIndex,
|
||||
"invoke-static { v$register }, " +
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->${hook.methodName}(${hook.parameters})V",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
InitializeButtonsFingerprint.apply {
|
||||
resolve(context, PivotBarConstructorFingerprint.resultOrThrow().classDef)
|
||||
}.resultOrThrow().mutableMethod.apply {
|
||||
// Hook the current navigation bar enum value. Note, the 'You' tab does not have an enum value.
|
||||
val navigationEnumClassName = NavigationEnumFingerprint.resultOrThrow().mutableClass.type
|
||||
addHook(Hook.SET_LAST_APP_NAVIGATION_ENUM) {
|
||||
opcode == Opcode.INVOKE_STATIC &&
|
||||
getReference<MethodReference>()?.definingClass == navigationEnumClassName
|
||||
}
|
||||
|
||||
// Hook the creation of navigation tab views.
|
||||
val drawableTabMethod = PivotBarButtonsCreateDrawableViewFingerprint.resultOrThrow().mutableMethod
|
||||
addHook(Hook.NAVIGATION_TAB_LOADED) predicate@{
|
||||
MethodUtil.methodSignaturesMatch(
|
||||
getReference<MethodReference>() ?: return@predicate false,
|
||||
drawableTabMethod,
|
||||
)
|
||||
}
|
||||
|
||||
val imageResourceTabMethod = PivotBarButtonsCreateResourceViewFingerprint.resultOrThrow().method
|
||||
addHook(Hook.NAVIGATION_IMAGE_RESOURCE_TAB_LOADED) predicate@{
|
||||
MethodUtil.methodSignaturesMatch(
|
||||
getReference<MethodReference>() ?: return@predicate false,
|
||||
imageResourceTabMethod,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Hook the search bar.
|
||||
|
||||
// Two different layouts are used at the hooked code.
|
||||
// Insert before the first ViewGroup method call after inflating,
|
||||
// so this works regardless which layout is used.
|
||||
ActionBarSearchResultsFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val instructionIndex = getTargetIndexWithMethodReferenceName("setLayoutDirection")
|
||||
val viewRegister = getInstruction<FiveRegisterInstruction>(instructionIndex).registerC
|
||||
|
||||
addInstruction(
|
||||
instructionIndex,
|
||||
"invoke-static { v$viewRegister }, " +
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V",
|
||||
)
|
||||
}
|
||||
|
||||
navigationTabCreatedCallback = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)?.mutableClass?.methods?.first { method ->
|
||||
method.name == "navigationTabCreatedCallback"
|
||||
} ?: throw PatchException("Could not find navigationTabCreatedCallback method")
|
||||
}
|
||||
|
||||
val hookNavigationButtonCreated: (String) -> Unit by lazy {
|
||||
navigationTabCreatedCallback
|
||||
{ integrationsClassDescriptor ->
|
||||
navigationTabCreatedCallback.addInstruction(
|
||||
0,
|
||||
"invoke-static { p0, p1 }, " +
|
||||
"$integrationsClassDescriptor->navigationTabCreated" +
|
||||
"(${INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private enum class Hook(val methodName: String, val parameters: String) {
|
||||
SET_LAST_APP_NAVIGATION_ENUM("setLastAppNavigationEnum", "Ljava/lang/Enum;"),
|
||||
NAVIGATION_TAB_LOADED("navigationTabLoaded", "Landroid/view/View;"),
|
||||
NAVIGATION_IMAGE_RESOURCE_TAB_LOADED("navigationImageResourceTabLoaded", "Landroid/view/View;"),
|
||||
SEARCH_BAR_RESULTS_VIEW_LOADED("searchBarResultsViewLoaded", "Landroid/view/View;"),
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.youtube.utils.navigation.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ActionBarSearchResultsViewMic
|
||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object ActionBarSearchResultsFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "Landroid/view/View;",
|
||||
parameters = listOf("Landroid/view/LayoutInflater;"),
|
||||
literalSupplier = { ActionBarSearchResultsViewMic }
|
||||
)
|
@ -0,0 +1,21 @@
|
||||
package app.revanced.patches.youtube.utils.navigation.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* Resolves to the Enum class that looks up ordinal -> instance.
|
||||
*/
|
||||
internal object NavigationEnumFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.STATIC or AccessFlags.CONSTRUCTOR,
|
||||
strings = listOf(
|
||||
"PIVOT_HOME",
|
||||
"TAB_SHORTS",
|
||||
"CREATION_TAB_LARGE",
|
||||
"PIVOT_SUBSCRIPTIONS",
|
||||
"TAB_ACTIVITY",
|
||||
"VIDEO_LIBRARY_WHITE",
|
||||
"INCOGNITO_CIRCLE"
|
||||
)
|
||||
)
|
@ -0,0 +1,17 @@
|
||||
package app.revanced.patches.youtube.utils.navigation.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object PivotBarButtonsCreateDrawableViewFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
// Method has different number of parameters in some app targets.
|
||||
// Parameters are checked in custom fingerprint.
|
||||
returnType = "Landroid/view/View;",
|
||||
customFingerprint = { methodDef, classDef ->
|
||||
classDef.type == "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;" &&
|
||||
// Only one method has a Drawable parameter.
|
||||
methodDef.parameterTypes.firstOrNull() == "Landroid/graphics/drawable/Drawable;"
|
||||
}
|
||||
)
|
@ -0,0 +1,14 @@
|
||||
package app.revanced.patches.youtube.utils.navigation.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object PivotBarButtonsCreateResourceViewFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("L", "Z", "I", "L"),
|
||||
returnType = "Landroid/view/View;",
|
||||
customFingerprint = { _, classDef ->
|
||||
classDef.type == "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;"
|
||||
}
|
||||
)
|
@ -0,0 +1,10 @@
|
||||
package app.revanced.patches.youtube.utils.navigation.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object PivotBarConstructorFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
strings = listOf("com.google.android.apps.youtube.app.endpoint.flags")
|
||||
)
|
@ -18,6 +18,7 @@ import app.revanced.patches.shared.mapping.ResourceType.STYLE
|
||||
object SharedResourceIdPatch : ResourcePatch() {
|
||||
var AccountSwitcherAccessibility = -1L
|
||||
var ActionBarRingo = -1L
|
||||
var ActionBarSearchResultsViewMic = -1L
|
||||
var AdAttribution = -1L
|
||||
var Appearance = -1L
|
||||
var AppRelatedEndScreenResults = -1L
|
||||
@ -92,6 +93,7 @@ object SharedResourceIdPatch : ResourcePatch() {
|
||||
|
||||
AccountSwitcherAccessibility = getId(STRING, "account_switcher_accessibility_label")
|
||||
ActionBarRingo = getId(LAYOUT, "action_bar_ringo")
|
||||
ActionBarSearchResultsViewMic = getId(LAYOUT, "action_bar_search_results_view_mic")
|
||||
AdAttribution = getId(ID, "ad_attribution")
|
||||
Appearance = getId(STRING, "app_theme_appearance_dark")
|
||||
AppRelatedEndScreenResults = getId(LAYOUT, "app_related_endscreen_results")
|
||||
|
@ -82,7 +82,7 @@ Tap here to learn more about DeArrow."</string>
|
||||
<string name="revanced_channel_bar_title">Channel bar</string>
|
||||
<string name="revanced_channel_profile_title">Channel profile</string>
|
||||
<string name="revanced_comments_title">Comments</string>
|
||||
<string name="revanced_custom_filter_strings_summary">Configure which components to filter, separated by new lines.</string>
|
||||
<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_strings_title">Edit custom filter</string>
|
||||
<string name="revanced_custom_filter_toast_invalid_syntax" formatted="false">Invalid custom filter: %s.</string>
|
||||
<string name="revanced_custom_filter_summary_off">Custom filter is disabled.</string>
|
||||
@ -475,6 +475,33 @@ Some components may not be hidden."</string>
|
||||
<string name="revanced_hide_join_button_summary_off">Join button is shown.</string>
|
||||
<string name="revanced_hide_join_button_summary_on">Join button is hidden.</string>
|
||||
<string name="revanced_hide_join_button_title">Hide join button</string>
|
||||
|
||||
<!-- TODO: After refactoring the Preference Screen, rename the settings to be consistent. -->
|
||||
<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>
|
||||
<string name="revanced_hide_keyword_content_home_summary_on">Videos in the home tab are filtered by keywords.</string>
|
||||
<string name="revanced_hide_keyword_content_home_summary_off">Videos in the home tab are not filtered by keywords.</string>
|
||||
<string name="revanced_hide_keyword_content_subscriptions_title">Hide subscription videos by keywords</string>
|
||||
<string name="revanced_hide_keyword_content_subscriptions_summary_on">Videos in the subscriptions tab are filtered by keywords.</string>
|
||||
<string name="revanced_hide_keyword_content_subscriptions_summary_off">Videos in the subscriptions tab are not filtered by keywords.</string>
|
||||
<string name="revanced_hide_keyword_content_search_title">Hide search results by keywords</string>
|
||||
<string name="revanced_hide_keyword_content_search_summary_on">Search results are filtered by keywords.</string>
|
||||
<string name="revanced_hide_keyword_content_search_summary_off">Search results are not filtered by keywords.</string>
|
||||
<string name="revanced_hide_keyword_content_phrases_title">Keywords to hide</string>
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">"Keywords and phrases to hide, separated by new lines.
|
||||
Words with uppercase letters in the middle must be entered with the casing (ie: iPhone, TikTok, LeBlanc)."</string>
|
||||
<string name="revanced_hide_keyword_content_about_title">About keyword filtering</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">"Home / Subscription / Search results are filtered to hide content that matches keyword phrases.
|
||||
|
||||
Limitations:
|
||||
• Some Shorts may not be hidden.
|
||||
• Some UI components may not be hidden.
|
||||
• Searching for a keyword may show no results."</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Invalid keyword. Cannot use: \'%s\' as a filter</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">Invalid keyword. \'%1$s\' is less than %2$d characters</string>
|
||||
|
||||
|
||||
<string name="revanced_hide_latest_posts_summary_off">Latest posts are shown.</string>
|
||||
<string name="revanced_hide_latest_posts_summary_on">Latest posts are hidden.</string>
|
||||
<string name="revanced_hide_latest_posts_title">Hide latest posts</string>
|
||||
@ -848,12 +875,12 @@ Known issues:
|
||||
<string name="revanced_swipe_overlay_text_size_title">Swipe overlay text size</string>
|
||||
<string name="revanced_swipe_overlay_timeout_summary">The amount of milliseconds the overlay is visible.</string>
|
||||
<string name="revanced_swipe_overlay_timeout_title">Swipe overlay timeout</string>
|
||||
<string name="revanced_switching_create_notification_summary">"Swap the positions of the create button and notification button by spoofing the device's information.
|
||||
<string name="revanced_switch_create_with_notifications_button_summary">"Switch the positions of the create button and notification button by spoofing device information.
|
||||
|
||||
• Even if you change this setting, it may not take effect until you reboot the device.
|
||||
• Disabling this setting loads more ads from the server side.
|
||||
• You should disable this setting to make video ads visible."</string>
|
||||
<string name="revanced_switching_create_notification_title">Switch create with notifications button</string>
|
||||
<string name="revanced_switch_create_with_notifications_button_title">Switch create with notifications</string>
|
||||
<string name="revanced_tool_used">Tool used</string>
|
||||
<string name="revanced_video">Video</string>
|
||||
|
||||
|
@ -264,6 +264,14 @@
|
||||
|
||||
<!-- SETTINGS: HIDE_LAYOUT_COMPONENTS
|
||||
<PreferenceCategory android:layout="@layout/revanced_settings_preferences_category" android:title="@string/revanced_layout_title" />
|
||||
<PreferenceScreen android:title="@string/revanced_hide_keyword_content_screen_title" android:key="revanced_hide_keyword_content_screen" android:summary="@string/revanced_hide_keyword_content_screen_summary">
|
||||
<PreferenceCategory android:layout="@layout/revanced_settings_preferences_category" android:title="@string/revanced_hide_keyword_content_screen_title" />
|
||||
<SwitchPreference android:title="@string/revanced_hide_keyword_content_home_title" android:key="revanced_hide_keyword_content_home" android:summaryOn="@string/revanced_hide_keyword_content_home_summary_on" android:summaryOff="@string/revanced_hide_keyword_content_home_summary_off" />
|
||||
<SwitchPreference android:title="@string/revanced_hide_keyword_content_subscriptions_title" android:key="revanced_hide_keyword_content_subscriptions" android:summaryOn="@string/revanced_hide_keyword_content_subscriptions_summary_on" android:summaryOff="@string/revanced_hide_keyword_content_subscriptions_summary_off" />
|
||||
<SwitchPreference android:title="@string/revanced_hide_keyword_content_search_title" android:key="revanced_hide_keyword_content_search" android:summaryOn="@string/revanced_hide_keyword_content_search_summary_on" android:summaryOff="@string/revanced_hide_keyword_content_search_summary_off" />
|
||||
<app.revanced.integrations.shared.settings.preference.ResettableEditTextPreference android:title="@string/revanced_hide_keyword_content_phrases_title" android:key="revanced_hide_keyword_content_phrases" android:summary="@string/revanced_hide_keyword_content_phrases_summary" android:inputType="textMultiLine" />
|
||||
<Preference android:title="@string/revanced_hide_keyword_content_about_title" android:selectable="false" android:summary="@string/revanced_hide_keyword_content_about_summary" />
|
||||
</PreferenceScreen>
|
||||
<SwitchPreference android:title="@string/revanced_custom_filter_title" android:key="revanced_custom_filter" android:defaultValue="false" android:summaryOn="@string/revanced_custom_filter_summary_on" android:summaryOff="@string/revanced_custom_filter_summary_off" />
|
||||
<app.revanced.integrations.shared.settings.preference.ResettableEditTextPreference android:title="@string/revanced_custom_filter_strings_title" android:key="revanced_custom_filter_strings" android:summary="@string/revanced_custom_filter_strings_summary" android:defaultValue="" android:inputType="textMultiLine" />
|
||||
<SwitchPreference android:title="@string/revanced_hide_album_card_title" android:key="revanced_hide_album_card" android:defaultValue="true" android:summaryOn="@string/revanced_hide_album_card_summary_on" android:summaryOff="@string/revanced_hide_album_card_summary_off" />
|
||||
@ -554,7 +562,7 @@
|
||||
<SwitchPreference android:title="@string/revanced_hide_notifications_button_title" android:key="revanced_hide_notifications_button" android:defaultValue="false" android:summaryOn="@string/revanced_hide_notifications_button_summary_on" android:summaryOff="@string/revanced_hide_notifications_button_summary_off" />
|
||||
<SwitchPreference android:title="@string/revanced_hide_shorts_button_title" android:key="revanced_hide_shorts_button" android:defaultValue="false" android:summaryOn="@string/revanced_hide_shorts_button_summary_on" android:summaryOff="@string/revanced_hide_shorts_button_summary_off" />
|
||||
<SwitchPreference android:title="@string/revanced_hide_subscriptions_button_title" android:key="revanced_hide_subscriptions_button" android:defaultValue="false" android:summaryOn="@string/revanced_hide_subscriptions_button_summary_on" android:summaryOff="@string/revanced_hide_subscriptions_button_summary_off" />
|
||||
<SwitchPreference android:title="@string/revanced_switching_create_notification_title" android:key="revanced_switching_create_notification" android:defaultValue="true" android:summary="@string/revanced_switching_create_notification_summary" />SETTINGS: HIDE_NAVIGATION_BUTTONS -->
|
||||
<SwitchPreference android:title="@string/revanced_switch_create_with_notifications_button_title" android:key="revanced_switch_create_with_notifications_button" android:defaultValue="true" android:summary="@string/revanced_switch_create_with_notifications_button_summary" />SETTINGS: HIDE_NAVIGATION_BUTTONS -->
|
||||
|
||||
<!-- PREFERENCE: NAVIGATION_SETTINGS
|
||||
</PreferenceScreen>PREFERENCE: NAVIGATION_SETTINGS -->
|
||||
|
Loading…
x
Reference in New Issue
Block a user