mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-11 13:46:17 +00:00
feat: Use modern style settings dialogs (#5109)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
This commit is contained in:
@@ -694,6 +694,7 @@ public final class app/revanced/patches/shared/misc/pairip/license/DisableLicens
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/shared/misc/settings/SettingsPatchKt {
|
||||
public static final fun overrideThemeColors (Ljava/lang/String;Ljava/lang/String;)V
|
||||
public static final fun settingsPatch (Ljava/util/List;Ljava/util/Set;)Lapp/revanced/patcher/patch/ResourcePatch;
|
||||
public static final fun settingsPatch (Lkotlin/Pair;Ljava/util/Set;)Lapp/revanced/patcher/patch/ResourcePatch;
|
||||
public static synthetic fun settingsPatch$default (Ljava/util/List;Ljava/util/Set;ILjava/lang/Object;)Lapp/revanced/patcher/patch/ResourcePatch;
|
||||
@@ -1678,6 +1679,7 @@ public final class app/revanced/util/BytecodeUtilsKt {
|
||||
public static final fun returnEarly (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;F)V
|
||||
public static final fun returnEarly (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)V
|
||||
public static final fun returnEarly (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;J)V
|
||||
public static final fun returnEarly (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/String;)V
|
||||
public static final fun returnEarly (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;S)V
|
||||
public static final fun returnEarly (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Z)V
|
||||
public static synthetic fun returnEarly$default (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ZILjava/lang/Object;)V
|
||||
@@ -1687,6 +1689,7 @@ public final class app/revanced/util/BytecodeUtilsKt {
|
||||
public static final fun returnLate (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;F)V
|
||||
public static final fun returnLate (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)V
|
||||
public static final fun returnLate (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;J)V
|
||||
public static final fun returnLate (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/String;)V
|
||||
public static final fun returnLate (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;S)V
|
||||
public static final fun returnLate (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Z)V
|
||||
public static final fun transformMethods (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lkotlin/jvm/functions/Function1;)V
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.idaustria.detection.signature
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
@Suppress("unused")
|
||||
val spoofSignaturePatch = bytecodePatch(
|
||||
@@ -24,12 +24,6 @@ val spoofSignaturePatch = bytecodePatch(
|
||||
"77ef1be61b2c01ebdabddcbf53cc4b6fd9a3c445606ee77b3758162c80ad8f8137b3c6864e92db904807dcb2be9d7717dd21" +
|
||||
"bf42c121d620ddfb7914f7a95c713d9e1c1b7bdb4a03d618e40cf7e9e235c0b5687e03b7ab3,publicExponent=10001}"
|
||||
|
||||
spoofSignatureFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$expectedSignature"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
spoofSignatureFingerprint.method.returnEarly(expectedSignature)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.nunl.firebase
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
@Suppress("unused")
|
||||
val spoofCertificatePatch = bytecodePatch(
|
||||
@@ -12,13 +12,7 @@ val spoofCertificatePatch = bytecodePatch(
|
||||
|
||||
execute {
|
||||
getFingerprintHashForPackageFingerprints.forEach { fingerprint ->
|
||||
fingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "eae41fc018df2731a9b6ae1ac327da44a288667b"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
fingerprint.method.returnEarly("eae41fc018df2731a9b6ae1ac327da44a288667b")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package app.revanced.patches.photomath.detection.deviceid
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.photomath.detection.signature.signatureDetectionPatch
|
||||
import app.revanced.util.returnEarly
|
||||
import kotlin.random.Random
|
||||
|
||||
@Suppress("unused")
|
||||
@@ -15,12 +15,6 @@ val getDeviceIdPatch = bytecodePatch(
|
||||
compatibleWith("com.microblink.photomath")
|
||||
|
||||
execute {
|
||||
getDeviceIdFingerprint.method.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "${Random.nextLong().toString(16)}"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
getDeviceIdFingerprint.method.returnEarly(Random.nextLong().toString(16))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package app.revanced.patches.piccomafr.misc
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.stringOption
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
@Suppress("unused")
|
||||
val spoofAndroidDeviceIdPatch = bytecodePatch(
|
||||
@@ -39,12 +40,6 @@ val spoofAndroidDeviceIdPatch = bytecodePatch(
|
||||
) { it!!.matches("[A-Fa-f0-9]{16}".toRegex()) }
|
||||
|
||||
execute {
|
||||
getAndroidIdFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$androidDeviceId"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
getAndroidIdFingerprint.method.returnEarly(androidDeviceId!!)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package app.revanced.patches.reddit.customclients.boostforreddit.api
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.util.returnEarly
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "http://rubenmayayo.com") { clientIdOption ->
|
||||
@@ -14,13 +14,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "http://rubenmayayo.com")
|
||||
execute {
|
||||
// region Patch client id.
|
||||
|
||||
getClientIdFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$clientId"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
getClientIdFingerprint.method.returnEarly(clientId!!)
|
||||
|
||||
// endregion
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package app.revanced.patches.reddit.customclients.joeyforreddit.api
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
|
||||
import app.revanced.patches.reddit.customclients.joeyforreddit.detection.piracy.disablePiracyDetectionPatch
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "https://127.0.0.1:65023/authorize_callback") { clientIdOption ->
|
||||
dependsOn(disablePiracyDetectionPatch)
|
||||
@@ -19,13 +18,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "https://127.0.0.1:65023/a
|
||||
execute {
|
||||
// region Patch client id.
|
||||
|
||||
getClientIdFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$clientId"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
getClientIdFingerprint.method.returnEarly(clientId!!)
|
||||
|
||||
// endregion
|
||||
|
||||
@@ -35,13 +28,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "https://127.0.0.1:65023/a
|
||||
val randomName = (0..100000).random()
|
||||
val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
|
||||
|
||||
authUtilityUserAgentFingerprint.method.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$userAgent"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
authUtilityUserAgentFingerprint.method.returnEarly(userAgent)
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@ package app.revanced.patches.reddit.customclients.redditisfun.api
|
||||
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.Match
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.returnEarly
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
|
||||
@@ -54,13 +54,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "redditisfun://auth") { cl
|
||||
val randomName = (0..100000).random()
|
||||
val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
|
||||
|
||||
getUserAgentFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$userAgent"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
getUserAgentFingerprint.method.returnEarly(userAgent)
|
||||
|
||||
// endregion
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.reddit.customclients.slide.api
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "http://www.ccrama.me") { clientIdOption ->
|
||||
compatibleWith("me.ccrama.redditslide")
|
||||
@@ -9,12 +9,6 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "http://www.ccrama.me") {
|
||||
val clientId by clientIdOption
|
||||
|
||||
execute {
|
||||
getClientIdFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$clientId"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
getClientIdFingerprint.method.returnEarly(clientId!!)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package app.revanced.patches.reddit.customclients.sync.syncforreddit.api
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.patches.reddit.customclients.sync.detection.piracy.disablePiracyDetectionPatch
|
||||
import app.revanced.util.returnEarly
|
||||
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.reference.StringReference
|
||||
import java.util.*
|
||||
import java.util.Base64
|
||||
|
||||
val spoofClientPatch = spoofClientPatch(
|
||||
redirectUri = "http://redditsync/auth",
|
||||
@@ -28,13 +28,8 @@ val spoofClientPatch = spoofClientPatch(
|
||||
|
||||
getBearerTokenFingerprint.match(getAuthorizationStringFingerprint.originalClassDef).method.apply {
|
||||
val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8))
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "Basic $auth"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
returnEarly("Basic $auth")
|
||||
|
||||
val occurrenceIndex =
|
||||
getAuthorizationStringFingerprint.stringMatches!!.first().index
|
||||
|
||||
@@ -63,23 +58,19 @@ val spoofClientPatch = spoofClientPatch(
|
||||
val randomName = (0..100000).random()
|
||||
val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
|
||||
|
||||
getUserAgentFingerprint.method.replaceInstruction(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$userAgent"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
getUserAgentFingerprint.method.returnEarly(userAgent)
|
||||
|
||||
// endregion
|
||||
|
||||
// region Patch Imgur API URL.
|
||||
|
||||
val apiUrlIndex = imgurImageAPIFingerprint.stringMatches!!.first().index
|
||||
imgurImageAPIFingerprint.method.replaceInstruction(
|
||||
apiUrlIndex,
|
||||
"const-string v1, \"https://api.imgur.com/3/image\"",
|
||||
)
|
||||
imgurImageAPIFingerprint.let {
|
||||
val apiUrlIndex = it.stringMatches!!.first().index
|
||||
it.method.replaceInstruction(
|
||||
apiUrlIndex,
|
||||
"const-string v1, \"https://api.imgur.com/3/image\"",
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ fun checkEnvironmentPatch(
|
||||
|
||||
fun invokeCheck() = mainActivityOnCreateFingerprint.method.addInstruction(
|
||||
0,
|
||||
"invoke-static/range { p0 .. p0 },$EXTENSION_CLASS_DESCRIPTOR->check(Landroid/app/Activity;)V",
|
||||
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->check(Landroid/app/Activity;)V",
|
||||
)
|
||||
|
||||
setPatchInfo()
|
||||
|
||||
@@ -3,11 +3,11 @@ package app.revanced.patches.shared.misc.extension
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.FingerprintBuilder
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.util.returnEarly
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import java.net.URLDecoder
|
||||
import java.util.jar.JarFile
|
||||
@@ -80,14 +80,7 @@ fun sharedExtensionPatch(
|
||||
}
|
||||
|
||||
val manifestValue = getPatchesManifestEntry("Version")
|
||||
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$manifestValue"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
returnEarly(manifestValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package app.revanced.patches.shared.misc.settings
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patches.shared.misc.extension.EXTENSION_CLASS_DESCRIPTOR
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val themeLightColorResourceNameFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||
returns("Ljava/lang/String;")
|
||||
parameters()
|
||||
custom { method, classDef ->
|
||||
method.name == "getThemeLightColorResourceName" && classDef.type == EXTENSION_CLASS_DESCRIPTOR
|
||||
}
|
||||
}
|
||||
|
||||
internal val themeDarkColorResourceNameFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||
returns("Ljava/lang/String;")
|
||||
parameters()
|
||||
custom { method, classDef ->
|
||||
method.name == "getThemeDarkColorResourceName" && classDef.type == EXTENSION_CLASS_DESCRIPTOR
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package app.revanced.patches.shared.misc.settings
|
||||
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patches.all.misc.resources.addResource
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
@@ -13,6 +14,7 @@ import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.getNode
|
||||
import app.revanced.util.insertFirst
|
||||
import app.revanced.util.returnEarly
|
||||
import org.w3c.dom.Node
|
||||
|
||||
// TODO: Delete this on next major version bump.
|
||||
@@ -22,6 +24,30 @@ fun settingsPatch (
|
||||
preferences: Set<BasePreference>,
|
||||
) = settingsPatch(listOf(rootPreference), preferences)
|
||||
|
||||
private var themeForegroundColor : String? = null
|
||||
private var themeBackgroundColor : String? = null
|
||||
|
||||
/**
|
||||
* Sets the default theme colors used in various ReVanced specific settings menus.
|
||||
* By default these colors are white and black, but instead can be set to the
|
||||
* same color the target app uses for it's own settings.
|
||||
*/
|
||||
fun overrideThemeColors(foregroundColor: String, backgroundColor: String) {
|
||||
themeForegroundColor = foregroundColor
|
||||
themeBackgroundColor = backgroundColor
|
||||
}
|
||||
|
||||
private val settingsColorPatch = bytecodePatch {
|
||||
finalize {
|
||||
if (themeForegroundColor != null) {
|
||||
themeLightColorResourceNameFingerprint.method.returnEarly(themeForegroundColor!!)
|
||||
}
|
||||
if (themeBackgroundColor != null) {
|
||||
themeDarkColorResourceNameFingerprint.method.returnEarly(themeBackgroundColor!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A resource patch that adds settings to a settings fragment.
|
||||
*
|
||||
@@ -33,12 +59,28 @@ fun settingsPatch (
|
||||
rootPreferences: List<Pair<BasePreference, String>>? = null,
|
||||
preferences: Set<BasePreference>,
|
||||
) = resourcePatch {
|
||||
dependsOn(addResourcesPatch)
|
||||
dependsOn(addResourcesPatch, settingsColorPatch)
|
||||
|
||||
execute {
|
||||
copyResources(
|
||||
"settings",
|
||||
ResourceGroup("xml", "revanced_prefs.xml", "revanced_prefs_icons.xml"),
|
||||
ResourceGroup("drawable",
|
||||
// CustomListPreference resources.
|
||||
"revanced_ic_dialog_alert.xml",
|
||||
"revanced_settings_arrow_time.xml",
|
||||
"revanced_settings_circle_background.xml",
|
||||
"revanced_settings_cursor.xml",
|
||||
"revanced_settings_custom_checkmark.xml",
|
||||
"revanced_settings_search_icon.xml",
|
||||
"revanced_settings_toolbar_arrow_left.xml",
|
||||
),
|
||||
ResourceGroup("layout",
|
||||
"revanced_custom_list_item_checked.xml",
|
||||
// Color picker.
|
||||
"revanced_color_dot_widget.xml",
|
||||
"revanced_color_picker.xml",
|
||||
)
|
||||
)
|
||||
|
||||
addResources("shared", "misc.settings.settingsResourcePatch")
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.w3c.dom.Document
|
||||
* @param summaryKey The preference summary key.
|
||||
* @param icon The preference icon resource name.
|
||||
* @param layout Layout declaration.
|
||||
* @param tag The preference tag.
|
||||
* @param tag The preference class type.
|
||||
* @param entriesKey The entries array key.
|
||||
* @param entryValuesKey The entry values array key.
|
||||
*/
|
||||
@@ -20,10 +20,12 @@ import org.w3c.dom.Document
|
||||
class ListPreference(
|
||||
key: String? = null,
|
||||
titleKey: String = "${key}_title",
|
||||
summaryKey: String? = "${key}_summary",
|
||||
/** Summary key is ignored and will be removed soon */
|
||||
//@Deprecated
|
||||
summaryKey: String? = null,
|
||||
icon: String? = null,
|
||||
layout: String? = null,
|
||||
tag: String = "ListPreference",
|
||||
tag: String = "app.revanced.extension.shared.settings.preference.CustomDialogListPreference",
|
||||
val entriesKey: String? = "${key}_entries",
|
||||
val entryValuesKey: String? = "${key}_entry_values"
|
||||
) : BasePreference(key, titleKey, summaryKey, icon, layout, tag) {
|
||||
|
||||
@@ -25,7 +25,7 @@ val embeddedAdsPatch = bytecodePatch(
|
||||
addResources("twitch", "ad.embedded.embeddedAdsPatch")
|
||||
|
||||
PreferenceScreen.ADS.SURESTREAM.addPreferences(
|
||||
ListPreference("revanced_block_embedded_ads", summaryKey = null),
|
||||
ListPreference("revanced_block_embedded_ads"),
|
||||
)
|
||||
|
||||
// Inject OkHttp3 application interceptor
|
||||
|
||||
@@ -34,10 +34,7 @@ val showDeletedMessagesPatch = bytecodePatch(
|
||||
addResources("twitch", "chat.antidelete.showDeletedMessagesPatch")
|
||||
|
||||
PreferenceScreen.CHAT.GENERAL.addPreferences(
|
||||
ListPreference(
|
||||
key = "revanced_show_deleted_messages",
|
||||
summaryKey = null,
|
||||
),
|
||||
ListPreference("revanced_show_deleted_messages")
|
||||
)
|
||||
|
||||
// Spoiler mode: Force set hasModAccess member to true in constructor
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.warnwetter.misc.firebasegetcert
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
val firebaseGetCertPatch = bytecodePatch(
|
||||
description = "Spoofs the X-Android-Cert header.",
|
||||
@@ -10,13 +10,7 @@ val firebaseGetCertPatch = bytecodePatch(
|
||||
|
||||
execute {
|
||||
listOf(getRegistrationCertFingerprint, getMessagingCertFingerprint).forEach { match ->
|
||||
match.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "0799DDF0414D3B3475E88743C91C0676793ED450"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
match.method.returnEarly("0799DDF0414D3B3475E88743C91C0676793ED450")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,14 @@ import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPref
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.TextPreference
|
||||
import app.revanced.patches.youtube.misc.playercontrols.*
|
||||
import app.revanced.patches.youtube.misc.playercontrols.addBottomControl
|
||||
import app.revanced.patches.youtube.misc.playercontrols.initializeBottomControl
|
||||
import app.revanced.patches.youtube.misc.playercontrols.injectVisibilityCheckCall
|
||||
import app.revanced.patches.youtube.misc.playercontrols.playerControlsPatch
|
||||
import app.revanced.patches.youtube.misc.playercontrols.playerControlsResourcePatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityFingerprint
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
import app.revanced.patches.youtube.video.information.videoInformationPatch
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.copyResources
|
||||
@@ -83,12 +87,10 @@ val downloadsPatch = bytecodePatch(
|
||||
injectVisibilityCheckCall(BUTTON_DESCRIPTOR)
|
||||
|
||||
// Main activity is used to launch downloader intent.
|
||||
mainActivityFingerprint.method.apply {
|
||||
addInstruction(
|
||||
implementation!!.instructions.lastIndex,
|
||||
"invoke-static { p0 }, $EXTENSION_CLASS_DESCRIPTOR->activityCreated(Landroid/app/Activity;)V",
|
||||
)
|
||||
}
|
||||
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||
1,
|
||||
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->activityCreated(Landroid/app/Activity;)V"
|
||||
)
|
||||
|
||||
offlineVideoEndpointFingerprint.method.apply {
|
||||
addInstructionsWithLabels(
|
||||
|
||||
@@ -14,7 +14,7 @@ import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_43_or_greater
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityFingerprint
|
||||
import app.revanced.patches.youtube.shared.mainActivityConstructorFingerprint
|
||||
import app.revanced.util.*
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
@@ -43,10 +43,7 @@ private val swipeControlsResourcePatch = resourcePatch {
|
||||
SwitchPreference("revanced_swipe_haptic_feedback"),
|
||||
SwitchPreference("revanced_swipe_save_and_restore_brightness"),
|
||||
SwitchPreference("revanced_swipe_lowest_value_enable_auto_brightness"),
|
||||
ListPreference(
|
||||
"revanced_swipe_overlay_style",
|
||||
summaryKey = null,
|
||||
),
|
||||
ListPreference("revanced_swipe_overlay_style"),
|
||||
TextPreference("revanced_swipe_overlay_background_opacity", inputType = InputType.NUMBER),
|
||||
TextPreference("revanced_swipe_overlay_progress_brightness_color",
|
||||
tag = "app.revanced.extension.shared.settings.preference.ColorPickerPreference",
|
||||
@@ -103,7 +100,7 @@ val swipeControlsPatch = bytecodePatch(
|
||||
|
||||
execute {
|
||||
val wrapperClass = swipeControlsHostActivityFingerprint.classDef
|
||||
val targetClass = mainActivityFingerprint.classDef
|
||||
val targetClass = mainActivityConstructorFingerprint.classDef
|
||||
|
||||
// Inject the wrapper class from the extension into the class hierarchy of MainActivity.
|
||||
wrapperClass.setSuperClass(targetClass.superclass)
|
||||
|
||||
@@ -47,10 +47,7 @@ val changeFormFactorPatch = bytecodePatch(
|
||||
addResources("youtube", "layout.formfactor.changeFormFactorPatch")
|
||||
|
||||
PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
||||
ListPreference(
|
||||
"revanced_change_form_factor",
|
||||
summaryKey = null,
|
||||
)
|
||||
ListPreference("revanced_change_form_factor")
|
||||
)
|
||||
|
||||
hookNavigationButtonCreated(EXTENSION_CLASS_DESCRIPTOR)
|
||||
|
||||
@@ -184,23 +184,18 @@ val miniplayerPatch = bytecodePatch(
|
||||
|
||||
preferences +=
|
||||
if (is_20_03_or_greater) {
|
||||
ListPreference(
|
||||
"revanced_miniplayer_type",
|
||||
summaryKey = null,
|
||||
)
|
||||
ListPreference("revanced_miniplayer_type")
|
||||
} else if (is_19_43_or_greater) {
|
||||
ListPreference(
|
||||
"revanced_miniplayer_type",
|
||||
summaryKey = null,
|
||||
key = "revanced_miniplayer_type",
|
||||
entriesKey = "revanced_miniplayer_type_legacy_19_43_entries",
|
||||
entryValuesKey = "revanced_miniplayer_type_legacy_19_43_entry_values",
|
||||
entryValuesKey = "revanced_miniplayer_type_legacy_19_43_entry_values"
|
||||
)
|
||||
} else {
|
||||
ListPreference(
|
||||
"revanced_miniplayer_type",
|
||||
summaryKey = null,
|
||||
key = "revanced_miniplayer_type",
|
||||
entriesKey = "revanced_miniplayer_type_legacy_19_16_entries",
|
||||
entryValuesKey = "revanced_miniplayer_type_legacy_19_16_entry_values",
|
||||
entryValuesKey = "revanced_miniplayer_type_legacy_19_16_entry_values"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -49,10 +49,7 @@ internal val exitFullscreenPatch = bytecodePatch(
|
||||
addResources("youtube", "layout.player.fullscreen.exitFullscreenPatch")
|
||||
|
||||
PreferenceScreen.PLAYER.addPreferences(
|
||||
ListPreference(
|
||||
"revanced_exit_fullscreen",
|
||||
summaryKey = null,
|
||||
)
|
||||
ListPreference("revanced_exit_fullscreen")
|
||||
)
|
||||
|
||||
autoRepeatFingerprint.match(autoRepeatParentFingerprint.originalClassDef).method.apply {
|
||||
|
||||
@@ -70,8 +70,7 @@ val shortsAutoplayPatch = bytecodePatch(
|
||||
// Main activity is used to check if app is in pip mode.
|
||||
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||
1,
|
||||
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
||||
"setMainActivity(Landroid/app/Activity;)V",
|
||||
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->setMainActivity(Landroid/app/Activity;)V",
|
||||
)
|
||||
|
||||
val reelEnumClass = reelEnumConstructorFingerprint.originalClassDef.type
|
||||
|
||||
@@ -79,14 +79,10 @@ val openShortsInRegularPlayerPatch = bytecodePatch(
|
||||
|
||||
PreferenceScreen.SHORTS.addPreferences(
|
||||
if (is_19_46_or_greater) {
|
||||
ListPreference(
|
||||
key = "revanced_shorts_player_type",
|
||||
summaryKey = null,
|
||||
)
|
||||
ListPreference("revanced_shorts_player_type")
|
||||
} else {
|
||||
ListPreference(
|
||||
key = "revanced_shorts_player_type",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_shorts_player_type_legacy_entries",
|
||||
entryValuesKey = "revanced_shorts_player_type_legacy_entry_values"
|
||||
)
|
||||
|
||||
@@ -83,7 +83,7 @@ val spoofAppVersionPatch = bytecodePatch(
|
||||
if (is_19_43_or_greater) {
|
||||
ListPreference(
|
||||
key = "revanced_spoof_app_version_target",
|
||||
summaryKey = null,
|
||||
summaryKey = null
|
||||
)
|
||||
} else {
|
||||
ListPreference(
|
||||
|
||||
@@ -53,7 +53,6 @@ val changeStartPagePatch = bytecodePatch(
|
||||
preferences = setOf(
|
||||
ListPreference(
|
||||
key = "revanced_change_start_page",
|
||||
summaryKey = null,
|
||||
tag = "app.revanced.extension.shared.settings.preference.SortedListPreference"
|
||||
),
|
||||
SwitchPreference("revanced_change_start_page_always")
|
||||
|
||||
@@ -24,26 +24,6 @@ internal val lithoThemeFingerprint = fingerprint {
|
||||
}
|
||||
}
|
||||
|
||||
internal val themeHelperDarkColorFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||
returns("Ljava/lang/String;")
|
||||
parameters()
|
||||
custom { method, _ ->
|
||||
method.name == "darkThemeResourceName" &&
|
||||
method.definingClass == "Lapp/revanced/extension/youtube/ThemeHelper;"
|
||||
}
|
||||
}
|
||||
|
||||
internal val themeHelperLightColorFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||
returns("Ljava/lang/String;")
|
||||
parameters()
|
||||
custom { method, _ ->
|
||||
method.name == "lightThemeResourceName" &&
|
||||
method.definingClass == "Lapp/revanced/extension/youtube/ThemeHelper;"
|
||||
}
|
||||
}
|
||||
|
||||
internal const val GRADIENT_LOADING_SCREEN_AB_CONSTANT = 45412406L
|
||||
|
||||
internal val useGradientLoadingScreenFingerprint = fingerprint {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package app.revanced.patches.youtube.layout.theme
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
@@ -8,6 +7,7 @@ import app.revanced.patcher.patch.stringOption
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.settings.overrideThemeColors
|
||||
import app.revanced.patches.shared.misc.settings.preference.BasePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.InputType
|
||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||
@@ -22,16 +22,17 @@ import app.revanced.patches.youtube.misc.playservice.is_19_47_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.util.childElementsSequence
|
||||
import app.revanced.util.forEachChildElement
|
||||
import app.revanced.util.insertLiteralOverride
|
||||
import org.w3c.dom.Element
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/theme/ThemePatch;"
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/theme/ThemePatch;"
|
||||
|
||||
val themePatch = bytecodePatch(
|
||||
name = "Theme",
|
||||
description = "Adds options for theming and applies a custom background theme (dark background theme defaults to amoled black).",
|
||||
description = "Adds options for theming and applies a custom background theme " +
|
||||
"(dark background theme defaults to amoled black).",
|
||||
) {
|
||||
val amoledBlackColor = "@android:color/black"
|
||||
val whiteColor = "@android:color/white"
|
||||
@@ -109,27 +110,23 @@ val themePatch = bytecodePatch(
|
||||
)
|
||||
)
|
||||
|
||||
overrideThemeColors(lightThemeBackgroundColor!!, darkThemeBackgroundColor!!)
|
||||
|
||||
// Edit theme colors via resources.
|
||||
document("res/values/colors.xml").use { document ->
|
||||
|
||||
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
||||
|
||||
val children = resourcesNode.childNodes
|
||||
for (i in 0 until children.length) {
|
||||
val node = children.item(i) as? Element ?: continue
|
||||
resourcesNode.childElementsSequence().forEach { node ->
|
||||
when (node.getAttribute("name")) {
|
||||
"yt_black0", "yt_black1", "yt_black1_opacity95", "yt_black1_opacity98",
|
||||
"yt_black2", "yt_black3", "yt_black4", "yt_status_bar_background_dark",
|
||||
"material_grey_850",
|
||||
-> node.textContent = darkThemeBackgroundColor
|
||||
|
||||
node.textContent =
|
||||
when (node.getAttribute("name")) {
|
||||
"yt_black0", "yt_black1", "yt_black1_opacity95", "yt_black1_opacity98", "yt_black2", "yt_black3",
|
||||
"yt_black4", "yt_status_bar_background_dark", "material_grey_850",
|
||||
-> darkThemeBackgroundColor ?: continue
|
||||
|
||||
"yt_white1", "yt_white1_opacity95", "yt_white1_opacity98",
|
||||
"yt_white2", "yt_white3", "yt_white4",
|
||||
-> lightThemeBackgroundColor ?: continue
|
||||
|
||||
else -> continue
|
||||
}
|
||||
"yt_white1", "yt_white1_opacity95", "yt_white1_opacity98",
|
||||
"yt_white2", "yt_white3", "yt_white4",
|
||||
-> node.textContent = lightThemeBackgroundColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,67 +148,56 @@ val themePatch = bytecodePatch(
|
||||
}
|
||||
}
|
||||
|
||||
val splashBackgroundColor = "revanced_splash_background_color"
|
||||
|
||||
// Add a dynamic background color to the colors.xml file.
|
||||
lightThemeBackgroundColor?.let {
|
||||
addColorResource("res/values/colors.xml", splashBackgroundColor, it)
|
||||
}
|
||||
|
||||
darkThemeBackgroundColor?.let {
|
||||
addColorResource("res/values-night/colors.xml", splashBackgroundColor, it)
|
||||
}
|
||||
val splashBackgroundColorKey = "revanced_splash_background_color"
|
||||
addColorResource("res/values/colors.xml", splashBackgroundColorKey, lightThemeBackgroundColor!!)
|
||||
addColorResource("res/values-night/colors.xml", splashBackgroundColorKey, darkThemeBackgroundColor!!)
|
||||
|
||||
// Edit splash screen files and change the background color,
|
||||
// if the background colors are set.
|
||||
if (darkThemeBackgroundColor != null && lightThemeBackgroundColor != null) {
|
||||
val splashScreenResourceFiles = listOf(
|
||||
"res/drawable/quantum_launchscreen_youtube.xml",
|
||||
"res/drawable-sw600dp/quantum_launchscreen_youtube.xml",
|
||||
)
|
||||
|
||||
splashScreenResourceFiles.forEach editSplashScreen@{ resourceFile ->
|
||||
document(resourceFile).use { document ->
|
||||
document.getElementsByTagName("layer-list").item(0).forEachChildElement { node ->
|
||||
if (node.hasAttribute("android:drawable")) {
|
||||
node.setAttribute("android:drawable", "@color/$splashBackgroundColor")
|
||||
return@editSplashScreen
|
||||
}
|
||||
arrayOf(
|
||||
"res/drawable/quantum_launchscreen_youtube.xml",
|
||||
"res/drawable-sw600dp/quantum_launchscreen_youtube.xml",
|
||||
).forEach editSplashScreen@{ resourceFileName ->
|
||||
document(resourceFileName).use { document ->
|
||||
document.getElementsByTagName("layer-list").item(0).forEachChildElement { node ->
|
||||
if (node.hasAttribute("android:drawable")) {
|
||||
node.setAttribute("android:drawable", "@color/$splashBackgroundColorKey")
|
||||
return@editSplashScreen
|
||||
}
|
||||
|
||||
throw PatchException("Failed to modify launch screen")
|
||||
}
|
||||
}
|
||||
|
||||
// Fix the splash screen dark mode background color.
|
||||
// In 19.32+ the dark mode splash screen is white and fades to black.
|
||||
// Maybe it's a bug in YT, or maybe it intentionally. Who knows.
|
||||
document("res/values-night-v27/styles.xml").use { document ->
|
||||
// Create a night mode specific override for the splash screen background.
|
||||
val style = document.createElement("style")
|
||||
style.setAttribute("name", "Theme.YouTube.Home")
|
||||
style.setAttribute("parent", "@style/Base.V27.Theme.YouTube.Home")
|
||||
|
||||
// Fix status and navigation bar showing white on some Android devices,
|
||||
// such as SDK 28 Android 10 medium tablet.
|
||||
val colorSplashBackgroundColor = "@color/$splashBackgroundColor"
|
||||
arrayOf(
|
||||
"android:navigationBarColor" to colorSplashBackgroundColor,
|
||||
"android:windowBackground" to colorSplashBackgroundColor,
|
||||
"android:colorBackground" to colorSplashBackgroundColor,
|
||||
"colorPrimaryDark" to colorSplashBackgroundColor,
|
||||
"android:windowLightStatusBar" to "false",
|
||||
).forEach { (name, value) ->
|
||||
val styleItem = document.createElement("item")
|
||||
styleItem.setAttribute("name", name)
|
||||
styleItem.textContent = value
|
||||
style.appendChild(styleItem)
|
||||
}
|
||||
|
||||
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
||||
resourcesNode.appendChild(style)
|
||||
throw PatchException("Failed to modify launch screen")
|
||||
}
|
||||
}
|
||||
|
||||
// Fix the splash screen dark mode background color.
|
||||
// In 19.32+ the dark mode splash screen is white and fades to black.
|
||||
// Maybe it's a bug in YT, or maybe it intentionally. Who knows.
|
||||
document("res/values-night-v27/styles.xml").use { document ->
|
||||
// Create a night mode specific override for the splash screen background.
|
||||
val style = document.createElement("style")
|
||||
style.setAttribute("name", "Theme.YouTube.Home")
|
||||
style.setAttribute("parent", "@style/Base.V27.Theme.YouTube.Home")
|
||||
|
||||
// Fix status and navigation bar showing white on some Android devices,
|
||||
// such as SDK 28 Android 10 medium tablet.
|
||||
val colorSplashBackgroundColor = "@color/$splashBackgroundColorKey"
|
||||
arrayOf(
|
||||
"android:navigationBarColor" to colorSplashBackgroundColor,
|
||||
"android:windowBackground" to colorSplashBackgroundColor,
|
||||
"android:colorBackground" to colorSplashBackgroundColor,
|
||||
"colorPrimaryDark" to colorSplashBackgroundColor,
|
||||
"android:windowLightStatusBar" to "false",
|
||||
).forEach { (name, value) ->
|
||||
val styleItem = document.createElement("item")
|
||||
styleItem.setAttribute("name", name)
|
||||
styleItem.textContent = value
|
||||
style.appendChild(styleItem)
|
||||
}
|
||||
|
||||
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
||||
resourcesNode.appendChild(style)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -237,10 +223,7 @@ val themePatch = bytecodePatch(
|
||||
|
||||
if (is_19_47_or_greater) {
|
||||
PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
||||
ListPreference(
|
||||
key = "splash_screen_animation_style",
|
||||
summaryKey = null
|
||||
)
|
||||
ListPreference("splash_screen_animation_style")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -257,21 +240,6 @@ val themePatch = bytecodePatch(
|
||||
)
|
||||
}
|
||||
|
||||
arrayOf(
|
||||
themeHelperLightColorFingerprint to lightThemeBackgroundColor,
|
||||
themeHelperDarkColorFingerprint to darkThemeBackgroundColor,
|
||||
).forEach { (fingerprint, color) ->
|
||||
fingerprint.method.apply {
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$color"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
lithoColorOverrideHook(EXTENSION_CLASS_DESCRIPTOR, "getValue")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,34 +50,29 @@ val alternativeThumbnailsPatch = bytecodePatch(
|
||||
val values = "revanced_alt_thumbnail_options_entry_values"
|
||||
PreferenceScreen.ALTERNATIVE_THUMBNAILS.addPreferences(
|
||||
ListPreference(
|
||||
"revanced_alt_thumbnail_home",
|
||||
summaryKey = null,
|
||||
key = "revanced_alt_thumbnail_home",
|
||||
entriesKey = entries,
|
||||
entryValuesKey = values,
|
||||
entryValuesKey = values
|
||||
),
|
||||
ListPreference(
|
||||
"revanced_alt_thumbnail_subscription",
|
||||
summaryKey = null,
|
||||
key = "revanced_alt_thumbnail_subscription",
|
||||
entriesKey = entries,
|
||||
entryValuesKey = values,
|
||||
entryValuesKey = values
|
||||
),
|
||||
ListPreference(
|
||||
"revanced_alt_thumbnail_library",
|
||||
summaryKey = null,
|
||||
key = "revanced_alt_thumbnail_library",
|
||||
entriesKey = entries,
|
||||
entryValuesKey = values,
|
||||
entryValuesKey = values
|
||||
),
|
||||
ListPreference(
|
||||
"revanced_alt_thumbnail_player",
|
||||
summaryKey = null,
|
||||
key = "revanced_alt_thumbnail_player",
|
||||
entriesKey = entries,
|
||||
entryValuesKey = values,
|
||||
entryValuesKey = values
|
||||
),
|
||||
ListPreference(
|
||||
"revanced_alt_thumbnail_search",
|
||||
summaryKey = null,
|
||||
key = "revanced_alt_thumbnail_search",
|
||||
entriesKey = entries,
|
||||
entryValuesKey = values,
|
||||
entryValuesKey = values
|
||||
),
|
||||
NonInteractivePreference(
|
||||
"revanced_alt_thumbnail_dearrow_about",
|
||||
@@ -89,7 +84,7 @@ val alternativeThumbnailsPatch = bytecodePatch(
|
||||
TextPreference("revanced_alt_thumbnail_dearrow_api_url"),
|
||||
NonInteractivePreference("revanced_alt_thumbnail_stills_about"),
|
||||
SwitchPreference("revanced_alt_thumbnail_stills_fast"),
|
||||
ListPreference("revanced_alt_thumbnail_stills_time", summaryKey = null),
|
||||
ListPreference("revanced_alt_thumbnail_stills_time"),
|
||||
)
|
||||
|
||||
addImageUrlHook(EXTENSION_CLASS_DESCRIPTOR)
|
||||
|
||||
@@ -4,15 +4,6 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import app.revanced.patcher.fingerprint
|
||||
|
||||
internal val onBackPressedFingerprint = fingerprint {
|
||||
returns("V")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
opcodes(Opcode.RETURN_VOID)
|
||||
custom { method, classDef ->
|
||||
method.name == "onBackPressed" && classDef.endsWith("MainActivity;")
|
||||
}
|
||||
}
|
||||
|
||||
internal val scrollPositionFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL)
|
||||
returns("V")
|
||||
|
||||
@@ -2,6 +2,7 @@ package app.revanced.patches.youtube.misc.fix.backtoexitgesture
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnBackPressedFingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@@ -10,7 +11,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/FixBackToExitGesturePatch;"
|
||||
|
||||
internal val fixBackToExitGesturePatch = bytecodePatch(
|
||||
description = "Fixes the swipe back to exit gesture.",
|
||||
description = "Fixes the swipe back to exit gesture."
|
||||
) {
|
||||
|
||||
execute {
|
||||
@@ -36,12 +37,12 @@ internal val fixBackToExitGesturePatch = bytecodePatch(
|
||||
"invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->onScrollingViews()V"
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onBackPressedFingerprint.let {
|
||||
it.method.addInstruction(
|
||||
it.patternMatch!!.endIndex,
|
||||
mainActivityOnBackPressedFingerprint.method.apply {
|
||||
val index = indexOfFirstInstructionOrThrow(Opcode.RETURN_VOID)
|
||||
addInstruction(
|
||||
index,
|
||||
"invoke-static { p0 }, $EXTENSION_CLASS_DESCRIPTOR->onBackPressed(Landroid/app/Activity;)V"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -42,15 +42,6 @@ internal val initializeButtonsFingerprint = fingerprint {
|
||||
literal { imageOnlyTabResourceId }
|
||||
}
|
||||
|
||||
internal val mainActivityOnBackPressedFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("V")
|
||||
parameters()
|
||||
custom { method, classDef ->
|
||||
method.name == "onBackPressed" && classDef.endsWith("MainActivity;")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension method, used for callback into to other patches.
|
||||
* Specifically, [navigationButtonsPatch].
|
||||
|
||||
@@ -15,6 +15,7 @@ import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_35_or_greater
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnBackPressedFingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
|
||||
@@ -3,7 +3,6 @@ package app.revanced.patches.youtube.misc.settings
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.util.literal
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val licenseActivityOnCreateFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
@@ -18,13 +17,9 @@ internal val setThemeFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("L")
|
||||
parameters()
|
||||
opcodes(Opcode.RETURN_OBJECT)
|
||||
literal { appearanceStringId }
|
||||
}
|
||||
|
||||
/**
|
||||
* Added in YouTube v19.04.38.
|
||||
*/
|
||||
internal const val CAIRO_CONFIG_LITERAL_VALUE = 45532100L
|
||||
|
||||
internal val cairoFragmentConfigFingerprint = fingerprint {
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package app.revanced.patches.youtube.misc.settings
|
||||
|
||||
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.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
@@ -13,15 +11,32 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.mapping.get
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||
import app.revanced.patches.shared.misc.settings.preference.*
|
||||
import app.revanced.patches.shared.misc.settings.overrideThemeColors
|
||||
import app.revanced.patches.shared.misc.settings.preference.BasePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
|
||||
import app.revanced.patches.shared.misc.settings.preference.InputType
|
||||
import app.revanced.patches.shared.misc.settings.preference.IntentPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.TextPreference
|
||||
import app.revanced.patches.shared.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.misc.check.checkEnvironmentPatch
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.fix.playbackspeed.fixPlaybackSpeedWhilePlayingPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.util.*
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.addInstructionsAtControlFlowLabel
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.copyXmlNode
|
||||
import app.revanced.util.findElementByAttributeValueOrThrow
|
||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||
import app.revanced.util.inputStreamFromBundledResource
|
||||
import app.revanced.util.insertLiteralOverride
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||
@@ -30,7 +45,9 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
|
||||
// Used by a fingerprint() from SettingsPatch.
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/settings/LicenseActivityHook;"
|
||||
|
||||
internal var appearanceStringId = -1L
|
||||
private set
|
||||
|
||||
@@ -69,13 +86,13 @@ private val settingsResourcePatch = resourcePatch {
|
||||
)
|
||||
|
||||
execute {
|
||||
// Used for a fingerprint from SettingsPatch.
|
||||
appearanceStringId = resourceMappings["string", "app_theme_appearance_dark"]
|
||||
|
||||
// Use same colors as stock YouTube.
|
||||
overrideThemeColors("@color/yt_white1", "@color/yt_black3")
|
||||
|
||||
arrayOf(
|
||||
ResourceGroup("drawable",
|
||||
"revanced_settings_circle_background.xml",
|
||||
"revanced_settings_cursor.xml",
|
||||
"revanced_settings_icon.xml",
|
||||
"revanced_settings_screen_00_about.xml",
|
||||
"revanced_settings_screen_01_ads.xml",
|
||||
@@ -92,11 +109,10 @@ private val settingsResourcePatch = resourcePatch {
|
||||
"revanced_settings_screen_12_video.xml",
|
||||
),
|
||||
ResourceGroup("layout",
|
||||
"revanced_color_dot_widget.xml",
|
||||
"revanced_color_picker.xml",
|
||||
"revanced_preference_with_icon_no_search_result.xml",
|
||||
"revanced_search_suggestion_item.xml",
|
||||
"revanced_settings_with_toolbar.xml"),
|
||||
"revanced_settings_with_toolbar.xml"
|
||||
),
|
||||
ResourceGroup("menu", "revanced_search_menu.xml")
|
||||
).forEach { resourceGroup ->
|
||||
copyResources("settings", resourceGroup)
|
||||
@@ -170,12 +186,6 @@ val settingsPatch = bytecodePatch(
|
||||
checkEnvironmentPatch,
|
||||
)
|
||||
|
||||
val extensionPackage = "app/revanced/extension/youtube"
|
||||
val activityHookClassDescriptor = "L$extensionPackage/settings/LicenseActivityHook;"
|
||||
|
||||
val themeHelperDescriptor = "L$extensionPackage/ThemeHelper;"
|
||||
val setThemeMethodName = "setTheme"
|
||||
|
||||
execute {
|
||||
addResources("youtube", "misc.settings.settingsPatch")
|
||||
|
||||
@@ -185,7 +195,7 @@ val settingsPatch = bytecodePatch(
|
||||
icon = "@drawable/revanced_settings_screen_00_about",
|
||||
layout = "@layout/preference_with_icon",
|
||||
summaryKey = null,
|
||||
tag = "app.revanced.extension.youtube.settings.preference.ReVancedYouTubeAboutPreference",
|
||||
tag = "app.revanced.extension.shared.settings.preference.ReVancedAboutPreference",
|
||||
selectable = true,
|
||||
)
|
||||
|
||||
@@ -210,31 +220,10 @@ val settingsPatch = bytecodePatch(
|
||||
),
|
||||
ListPreference(
|
||||
key = "revanced_language",
|
||||
summaryKey = null,
|
||||
tag = "app.revanced.extension.shared.settings.preference.SortedListPreference"
|
||||
)
|
||||
)
|
||||
|
||||
setThemeFingerprint.method.let { setThemeMethod ->
|
||||
setThemeMethod.implementation!!.instructions.mapIndexedNotNull { i, instruction ->
|
||||
if (instruction.opcode == Opcode.RETURN_OBJECT) i else null
|
||||
}.asReversed().forEach { returnIndex ->
|
||||
// The following strategy is to replace the return instruction with the setTheme instruction,
|
||||
// then add a return instruction after the setTheme instruction.
|
||||
// This is done because the return instruction is a target of another instruction.
|
||||
|
||||
setThemeMethod.apply {
|
||||
// This register is returned by the setTheme method.
|
||||
val register = getInstruction<OneRegisterInstruction>(returnIndex).registerA
|
||||
replaceInstruction(
|
||||
returnIndex,
|
||||
"invoke-static { v$register }, " +
|
||||
"$themeHelperDescriptor->$setThemeMethodName(Ljava/lang/Enum;)V",
|
||||
)
|
||||
addInstruction(returnIndex + 1, "return-object v$register")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Modify the license activity and remove all existing layout code.
|
||||
// Must modify an existing activity and cannot add a new activity to the manifest,
|
||||
@@ -243,9 +232,9 @@ val settingsPatch = bytecodePatch(
|
||||
licenseActivityOnCreateFingerprint.method.addInstructions(
|
||||
1,
|
||||
"""
|
||||
invoke-static { p0 }, $activityHookClassDescriptor->initialize(Landroid/app/Activity;)V
|
||||
invoke-static { p0 }, $EXTENSION_CLASS_DESCRIPTOR->initialize(Landroid/app/Activity;)V
|
||||
return-void
|
||||
""",
|
||||
"""
|
||||
)
|
||||
|
||||
// Remove other methods as they will break as the onCreate method is modified above.
|
||||
@@ -267,7 +256,7 @@ val settingsPatch = bytecodePatch(
|
||||
).toMutable().apply {
|
||||
addInstructions(
|
||||
"""
|
||||
invoke-static { p1 }, $activityHookClassDescriptor->getAttachBaseContext(Landroid/content/Context;)Landroid/content/Context;
|
||||
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->getAttachBaseContext(Landroid/content/Context;)Landroid/content/Context;
|
||||
move-result-object p1
|
||||
invoke-super { p0, p1 }, $superclass->attachBaseContext(Landroid/content/Context;)V
|
||||
return-void
|
||||
@@ -278,10 +267,23 @@ val settingsPatch = bytecodePatch(
|
||||
methods.add(attachBaseContext)
|
||||
}
|
||||
|
||||
// Update shared dark mode status based on YT theme.
|
||||
// This is needed because YT allows forcing light/dark mode
|
||||
// which then differs from the system dark mode status.
|
||||
setThemeFingerprint.method.apply {
|
||||
findInstructionIndicesReversedOrThrow(Opcode.RETURN_OBJECT).forEach { index ->
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
addInstructionsAtControlFlowLabel(
|
||||
index,
|
||||
"invoke-static { v$register }, ${EXTENSION_CLASS_DESCRIPTOR}->updateLightDarkModeStatus(Ljava/lang/Enum;)V",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Add setting to force cairo settings fragment on/off.
|
||||
cairoFragmentConfigFingerprint.method.insertLiteralOverride(
|
||||
CAIRO_CONFIG_LITERAL_VALUE,
|
||||
"$activityHookClassDescriptor->useCairoSettingsFragment(Z)Z"
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->useCairoSettingsFragment(Z)Z"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -48,10 +48,7 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
|
||||
sorting = PreferenceScreenPreference.Sorting.UNSORTED,
|
||||
preferences = setOf(
|
||||
SwitchPreference("revanced_spoof_video_streams"),
|
||||
ListPreference(
|
||||
"revanced_spoof_video_streams_client_type",
|
||||
summaryKey = null,
|
||||
),
|
||||
ListPreference("revanced_spoof_video_streams_client_type"),
|
||||
NonInteractivePreference(
|
||||
// Requires a key and title but the actual text is chosen at runtime.
|
||||
key = "revanced_spoof_video_streams_about_android",
|
||||
@@ -59,7 +56,6 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
|
||||
),
|
||||
ListPreference(
|
||||
key = "revanced_spoof_video_streams_language",
|
||||
summaryKey = null,
|
||||
// Language strings are declared in Setting patch.
|
||||
entriesKey = "revanced_language_entries",
|
||||
entryValuesKey = "revanced_language_entry_values",
|
||||
|
||||
@@ -44,11 +44,20 @@ internal val layoutConstructorFingerprint = fingerprint {
|
||||
strings("1.0x")
|
||||
}
|
||||
|
||||
internal val mainActivityFingerprint = fingerprint {
|
||||
internal val mainActivityConstructorFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||
parameters()
|
||||
custom { _, classDef ->
|
||||
classDef.endsWith("MainActivity;")
|
||||
classDef.endsWith("/MainActivity;")
|
||||
}
|
||||
}
|
||||
|
||||
internal val mainActivityOnBackPressedFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("V")
|
||||
parameters()
|
||||
custom { method, classDef ->
|
||||
method.name == "onBackPressed" && classDef.endsWith("/MainActivity;")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +65,7 @@ internal val mainActivityOnCreateFingerprint = fingerprint {
|
||||
returns("V")
|
||||
parameters("Landroid/os/Bundle;")
|
||||
custom { method, classDef ->
|
||||
method.name == "onCreate" && classDef.endsWith("MainActivity;")
|
||||
method.name == "onCreate" && classDef.endsWith("/MainActivity;")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,29 +37,25 @@ val rememberVideoQualityPatch = bytecodePatch {
|
||||
settingsMenuVideoQualityGroup.addAll(listOf(
|
||||
ListPreference(
|
||||
key = "revanced_video_quality_default_mobile",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_video_quality_default_entries",
|
||||
entryValuesKey = "revanced_video_quality_default_entry_values",
|
||||
entryValuesKey = "revanced_video_quality_default_entry_values"
|
||||
),
|
||||
ListPreference(
|
||||
key = "revanced_video_quality_default_wifi",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_video_quality_default_entries",
|
||||
entryValuesKey = "revanced_video_quality_default_entry_values",
|
||||
entryValuesKey = "revanced_video_quality_default_entry_values"
|
||||
),
|
||||
SwitchPreference("revanced_remember_video_quality_last_selected"),
|
||||
|
||||
ListPreference(
|
||||
key = "revanced_shorts_quality_default_mobile",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_shorts_quality_default_entries",
|
||||
entryValuesKey = "revanced_shorts_quality_default_entry_values",
|
||||
),
|
||||
ListPreference(
|
||||
key = "revanced_shorts_quality_default_wifi",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_shorts_quality_default_entries",
|
||||
entryValuesKey = "revanced_shorts_quality_default_entry_values",
|
||||
entryValuesKey = "revanced_shorts_quality_default_entry_values"
|
||||
),
|
||||
SwitchPreference("revanced_remember_shorts_quality_last_selected")
|
||||
))
|
||||
|
||||
@@ -34,7 +34,6 @@ internal val rememberPlaybackSpeedPatch = bytecodePatch {
|
||||
listOf(
|
||||
ListPreference(
|
||||
key = "revanced_playback_speed_default",
|
||||
summaryKey = null,
|
||||
// Entries and values are set by the extension code based on the actual speeds available.
|
||||
entriesKey = null,
|
||||
entryValuesKey = null,
|
||||
|
||||
@@ -742,16 +742,22 @@ private const val RETURN_TYPE_MISMATCH = "Mismatch between override type and Met
|
||||
*
|
||||
* For methods that return an object or any array type, calling this method with `false`
|
||||
* will force the method to return a `null` value.
|
||||
*
|
||||
* @see returnLate
|
||||
*/
|
||||
fun MutableMethod.returnEarly(value: Boolean = false) {
|
||||
val returnType = returnType.first()
|
||||
check(returnType == 'Z' || (!value && (returnType in setOf('V', 'L', '[')))) { RETURN_TYPE_MISMATCH }
|
||||
check(returnType == 'Z' || (!value && (returnType == 'V' || returnType == 'L' || returnType != '['))) {
|
||||
RETURN_TYPE_MISMATCH
|
||||
}
|
||||
overrideReturnValue(value.toHexString(), false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the first instruction of a method with a constant `Byte` return value.
|
||||
* None of the method code will ever execute.
|
||||
*
|
||||
* @see returnLate
|
||||
*/
|
||||
fun MutableMethod.returnEarly(value: Byte) {
|
||||
check(returnType.first() == 'B') { RETURN_TYPE_MISMATCH }
|
||||
@@ -761,6 +767,8 @@ fun MutableMethod.returnEarly(value: Byte) {
|
||||
/**
|
||||
* Overrides the first instruction of a method with a constant `Short` return value.
|
||||
* None of the method code will ever execute.
|
||||
*
|
||||
* @see returnLate
|
||||
*/
|
||||
fun MutableMethod.returnEarly(value: Short) {
|
||||
check(returnType.first() == 'S') { RETURN_TYPE_MISMATCH }
|
||||
@@ -770,6 +778,8 @@ fun MutableMethod.returnEarly(value: Short) {
|
||||
/**
|
||||
* Overrides the first instruction of a method with a constant `Char` return value.
|
||||
* None of the method code will ever execute.
|
||||
*
|
||||
* @see returnLate
|
||||
*/
|
||||
fun MutableMethod.returnEarly(value: Char) {
|
||||
check(returnType.first() == 'C') { RETURN_TYPE_MISMATCH }
|
||||
@@ -779,6 +789,8 @@ fun MutableMethod.returnEarly(value: Char) {
|
||||
/**
|
||||
* Overrides the first instruction of a method with a constant `Int` return value.
|
||||
* None of the method code will ever execute.
|
||||
*
|
||||
* @see returnLate
|
||||
*/
|
||||
fun MutableMethod.returnEarly(value: Int) {
|
||||
check(returnType.first() == 'I') { RETURN_TYPE_MISMATCH }
|
||||
@@ -788,6 +800,8 @@ fun MutableMethod.returnEarly(value: Int) {
|
||||
/**
|
||||
* Overrides the first instruction of a method with a constant `Long` return value.
|
||||
* None of the method code will ever execute.
|
||||
*
|
||||
* @see returnLate
|
||||
*/
|
||||
fun MutableMethod.returnEarly(value: Long) {
|
||||
check(returnType.first() == 'J') { RETURN_TYPE_MISMATCH }
|
||||
@@ -797,6 +811,8 @@ fun MutableMethod.returnEarly(value: Long) {
|
||||
/**
|
||||
* Overrides the first instruction of a method with a constant `Float` return value.
|
||||
* None of the method code will ever execute.
|
||||
*
|
||||
* @see returnLate
|
||||
*/
|
||||
fun MutableMethod.returnEarly(value: Float) {
|
||||
check(returnType.first() == 'F') { RETURN_TYPE_MISMATCH }
|
||||
@@ -806,12 +822,30 @@ fun MutableMethod.returnEarly(value: Float) {
|
||||
/**
|
||||
* Overrides the first instruction of a method with a constant `Double` return value.
|
||||
* None of the method code will ever execute.
|
||||
*
|
||||
* @see returnLate
|
||||
*/
|
||||
fun MutableMethod.returnEarly(value: Double) {
|
||||
check(returnType.first() == 'J') { RETURN_TYPE_MISMATCH }
|
||||
overrideReturnValue(value.toString(), false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the first instruction of a method with a constant String return value.
|
||||
* None of the method code will ever execute.
|
||||
*
|
||||
* Target method must have return type
|
||||
* Ljava/lang/String; or Ljava/lang/CharSequence;
|
||||
*
|
||||
* @see returnLate
|
||||
*/
|
||||
fun MutableMethod.returnEarly(value: String) {
|
||||
check(returnType == "Ljava/lang/String;" || returnType == "Ljava/lang/CharSequence;") {
|
||||
RETURN_TYPE_MISMATCH
|
||||
}
|
||||
overrideReturnValue(value, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides all return statements with a constant `Boolean` value.
|
||||
* All method code is executed the same as unpatched.
|
||||
@@ -826,7 +860,9 @@ fun MutableMethod.returnLate(value: Boolean) {
|
||||
if (returnType == 'V') {
|
||||
error("Cannot return late for Method of void type")
|
||||
}
|
||||
check(returnType == 'Z' || (!value && returnType in setOf('L', '['))) { RETURN_TYPE_MISMATCH }
|
||||
check(returnType == 'Z' || (!value && (returnType == 'L' || returnType == '['))) {
|
||||
RETURN_TYPE_MISMATCH
|
||||
}
|
||||
|
||||
overrideReturnValue(value.toHexString(), true)
|
||||
}
|
||||
@@ -908,8 +944,29 @@ fun MutableMethod.returnLate(value: Double) {
|
||||
overrideReturnValue(value.toString(), true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides all return statements with a constant String value.
|
||||
* All method code is executed the same as unpatched.
|
||||
*
|
||||
* Target method must have return type
|
||||
* Ljava/lang/String; or Ljava/lang/CharSequence;
|
||||
*
|
||||
* @see returnEarly
|
||||
*/
|
||||
fun MutableMethod.returnLate(value: String) {
|
||||
check(returnType == "Ljava/lang/String;" || returnType == "Ljava/lang/CharSequence;") {
|
||||
RETURN_TYPE_MISMATCH
|
||||
}
|
||||
overrideReturnValue(value, true)
|
||||
}
|
||||
|
||||
private fun MutableMethod.overrideReturnValue(value: String, returnLate: Boolean) {
|
||||
val instructions = when (returnType.first()) {
|
||||
val instructions = if (returnType == "Ljava/lang/String;" || returnType == "Ljava/lang/CharSequence;" ) {
|
||||
"""
|
||||
const-string v0, "$value"
|
||||
return-object v0
|
||||
"""
|
||||
} else when (returnType.first()) {
|
||||
// If return type is an object, always return null.
|
||||
'L', '[' -> {
|
||||
"""
|
||||
|
||||
@@ -33,11 +33,12 @@ Second \"item\" text"</string>
|
||||
<patch id="misc.settings.settingsResourcePatch">
|
||||
<string name="revanced_settings_submenu_title">Settings</string>
|
||||
<string name="revanced_settings_title" translatable="false">ReVanced</string>
|
||||
<string name="revanced_settings_confirm_user_dialog_title">Do you wish to proceed?</string>
|
||||
<string name="revanced_settings_confirm_user_dialog_title">Are you sure you want to proceed?</string>
|
||||
<string name="revanced_settings_reset">Reset</string>
|
||||
<string name="revanced_settings_reset_color">Reset color</string>
|
||||
<string name="revanced_settings_color_invalid">Invalid color</string>
|
||||
<string name="revanced_settings_restart_title">Refresh and restart</string>
|
||||
<string name="revanced_settings_restart_title">Restart required</string>
|
||||
<string name="revanced_settings_restart_dialog_message">Restart the app for this change to take affect.</string>
|
||||
<string name="revanced_settings_restart">Restart</string>
|
||||
<string name="revanced_settings_import">Import</string>
|
||||
<string name="revanced_settings_import_copy">Copy</string>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M26.5977,6.29688 L43.8672,36.2031 C45.0195,38.2031,43.5781,40.7031,41.2695,40.7031 L6.73047,40.7031 C4.42188,40.7031,2.98047,38.2031,4.13281,36.2031 L21.4023,6.29688 C22.5547,4.29688,25.4453,4.29688,26.5977,6.29688 Z M24,30 C22.8945,30,22,30.8945,22,32 C22,33.1055,22.8945,34,24,34 C25.1055,34,26,33.1055,26,32 C26,30.8945,25.1055,30,24,30 Z M24,16 C22.9727,16,22.1289,16.7734,22.0117,17.7656 L22,18 L22,26 C22,27.1055,22.8945,28,24,28 C25.0273,28,25.8711,27.2266,25.9883,26.2344 L26,26 L26,18 C26,16.8945,25.1055,16,24,16 Z M24,16" />
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M14.97,16.95L10,13.87V7h2v5.76l4.03,2.49L14.97,16.95zM22,12c0,5.51 -4.49,10 -10,10S2,17.51 2,12h1c0,4.96 4.04,9 9,9s9,-4.04 9,-9s-4.04,-9 -9,-9C8.81,3 5.92,4.64 4.28,7.38C4.17,7.56 4.06,7.75 3.97,7.94C3.96,7.96 3.95,7.98 3.94,8H8v1H1.96V3h1v4.74C3,7.65 3.03,7.57 3.07,7.49C3.18,7.27 3.3,7.07 3.42,6.86C5.22,3.86 8.51,2 12,2C17.51,2 22,6.49 22,12z"/>
|
||||
</vector>
|
||||
@@ -2,6 +2,6 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle"
|
||||
android:id="@+id/revanced_settings_cursor">
|
||||
<solid android:color="?ytTextPrimary" />
|
||||
<solid android:color="?android:attr/textColorPrimary" />
|
||||
<size android:width="1dp" />
|
||||
</shape>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"/>
|
||||
</vector>
|
||||
@@ -11,14 +11,14 @@
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M19.5872,3.99233 C19.6801,3.77185,19.8789,3.44672,19.7613,3.20362 C19.6963,3.06937,19.5861,3.00019,19.3558,3.00019 L19.1405,3.00019 C18.9457,3.00019,18.773,3.11962,18.6933,3.30335 C17.9185,5.13604,13.8142,14.8277,12.4461,18.066 C12.3664,18.2497,12.1937,18.3646,11.9989,18.3646 C11.8085,18.3646,11.6314,18.2498,11.5562,18.066 C10.1837,14.8278,6.08386,5.13603,5.30905,3.30335 C5.22936,3.11962,5.05669,3.00019,4.86188,3.00019 L4.64558,3.00019 C4.41535,3.00019,4.30543,3.06946,4.24052,3.20362 C4.1229,3.44674,4.32165,3.77185,4.41463,3.99233 C5.88012,7.46938,10.2054,17.7051,11.206,20.066 C11.3123,20.3232,11.5285,20.6,11.803,20.6 L12.2,20.6 C12.4701,20.6,12.6907,20.3232,12.797,20.066 C13.7932,17.7051,18.1217,7.4694,19.5872,3.9923 Z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeMiterLimit="2" />
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M7.44206,3 C7.23397,3,7.04036,3.11405,6.9341,3.30237 C6.83227,3.49069,6.83227,3.72094,6.9341,3.90926 C7.99669,5.81085,10.4352,10.1975,11.4933,12.0991 C11.5996,12.2874,11.7911,12.4015,11.9992,12.4015 C12.2117,12.4015,12.4009,12.2875,12.5072,12.0991 C13.5654,10.1975,16.0062,5.81085,17.0643,3.90926 C17.1706,3.72094,17.1706,3.49069,17.0643,3.30237 C16.9625,3.11405,16.7665,3,16.5584,3 Z M8.91225,4.09059 L15.1052,4.09059 C15.2375,4.09059,15.361,4.16305,15.4258,4.28281 C15.4934,4.40257,15.4934,4.54965,15.4258,4.66941 C14.7529,5.8787,13.0031,8.89953,12.3302,10.1088 C12.2626,10.2286,12.1427,10.3032,12.0075,10.3032 C11.8752,10.3032,11.7545,10.2286,11.6869,10.1088 C11.014,8.89952,9.2653,5.8787,8.58956,4.66941 C8.52481,4.54965,8.52481,4.40257,8.58956,4.28281 C8.65713,4.16305,8.77992,4.09059,8.91225,4.09059 Z"
|
||||
android:strokeWidth="1"
|
||||
|
||||
@@ -22,6 +22,6 @@ Copyright 2022 Google
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M13,17h-2v-6h2V17zM13,7h-2v2h2V7zM12,3c-4.96,0 -9,4.04 -9,9s4.04,9 9,9c4.96,0 9,-4.04 9,-9S16.96,3 12,3M12,2c5.52,0 10,4.48 10,10s-4.48,10 -10,10C6.48,22 2,17.52 2,12S6.48,2 12,2L12,2z" />
|
||||
</vector>
|
||||
|
||||
@@ -22,6 +22,6 @@ Copyright 2022 Google
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M17.9219,12.5 L17.9219,11.5 L21.1523,11.5 L21.1523,12.5 Z M19.0078,18.9609 L16.4219,17.0234 L17.0469,16.2305 L19.6289,18.168 Z M16.9688,7.69141 L16.3477,6.89844 L18.9297,4.96094 L19.5547,5.75391 Z M5.5,17.9609 L5.5,14.1523 L4.46094,14.1523 C4.01563,14.1523,3.63281,13.9961,3.31641,13.6836 C3.00391,13.3672,2.84766,12.9844,2.84766,12.5391 L2.84766,11.4609 C2.84766,11.0156,3.00391,10.6328,3.31641,10.3164 C3.63281,10.0039,4.01563,9.84766,4.46094,9.84766 L8.19141,9.84766 L12.1523,7.5 L12.1523,16.5 L8.19141,14.1523 L6.5,14.1523 L6.5,17.9609 Z M11.1523,14.7188 L11.1523,9.28125 L8.47266,10.8477 L4.46094,10.8477 C4.30859,10.8477,4.16797,10.9102,4.03906,11.0391 C3.91016,11.168,3.84766,11.3086,3.84766,11.4609 L3.84766,12.5391 C3.84766,12.6914,3.91016,12.832,4.03906,12.9609 C4.16797,13.0898,4.30859,13.1523,4.46094,13.1523 L8.47266,13.1523 Z M13.9219,14.8867 L13.9219,9.11328 C14.2578,9.42188,14.5273,9.82813,14.7305,10.332 C14.9375,10.8398,15.0391,11.3945,15.0391,12 C15.0391,12.6055,14.9375,13.1602,14.7305,13.668 C14.5273,14.1719,14.2578,14.5781,13.9219,14.8867 Z M7.5,12 Z M7.5,12" />
|
||||
</vector>
|
||||
@@ -12,10 +12,10 @@ Copyright 2023 Ajay Ramachandran <dev@ajay.app>
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:strokeColor="?ytTextPrimary"
|
||||
android:strokeColor="?android:attr/textColorPrimary"
|
||||
android:strokeWidth="1"
|
||||
android:pathData="M12.0814,1.99794 C9.37251,1.99794,6.97872,3.32778,5.20335,5.14149 C3.42798,6.9552,1.99794,9.39989,1.99794,12.1677 C1.99794,14.9355,3.10403,17.7107,4.87939,19.5244 C6.65476,21.3381,9.37195,21.9549,12.0814,21.9549 C14.7908,21.9549,17.0848,20.9067,18.8601,19.093 C20.6355,17.2793,22.002,14.9355,22.002,12.1677 C22.002,9.40046,20.8525,6.83638,19.0766,5.02267 C17.3013,3.20894,14.7903,1.99794,12.0814,1.99794 Z M11.9105,5.02102 C13.838,5.02102,15.5196,6.09439,16.7829,7.35711 C18.0462,8.61984,18.8878,10.3004,18.8878,12.2279 C18.8878,14.1554,18.2513,16.0427,16.988,17.3054 C15.7247,18.5681,13.8374,18.9333,11.9105,18.9333 C9.98355,18.9333,8.36976,18.2962,7.10645,17.0335 C5.84314,15.7708,5.11222,14.1554,5.11222,12.2278 C5.11222,10.3003,5.63697,8.47868,6.8997,7.21537 C8.16239,5.95218,9.98293,5.02102,11.9105,5.02102 Z" />
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M15.3108,11.899 C15.3108,13.6514,13.8411,15.1264,12.0887,15.1264 C10.3363,15.1264,8.97704,13.6515,8.97704,11.899 C8.97704,10.1466,10.3363,8.71961,12.0887,8.71961 C13.8411,8.71961,15.3108,10.1466,15.3108,11.899 Z" />
|
||||
</vector>
|
||||
|
||||
@@ -22,6 +22,6 @@ Copyright 2022 Google
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M4.85,19.775Q4.15,19.775 3.688,19.312Q3.225,18.85 3.225,18.15V12.55H4.225V18.15Q4.225,18.375 4.425,18.575Q4.625,18.775 4.85,18.775H12.45V19.775ZM8.625,16Q7.925,16 7.463,15.537Q7,15.075 7,14.375V8.775H8V14.375Q8,14.625 8.188,14.812Q8.375,15 8.625,15H16.225V16ZM12.375,12.225Q11.7,12.225 11.238,11.762Q10.775,11.3 10.775,10.625V5.85Q10.775,5.15 11.238,4.687Q11.7,4.225 12.375,4.225H19.15Q19.85,4.225 20.312,4.687Q20.775,5.15 20.775,5.85V10.625Q20.775,11.3 20.312,11.762Q19.85,12.225 19.15,12.225ZM12.375,11.225H19.15Q19.375,11.225 19.575,11.037Q19.775,10.85 19.775,10.625V7.225H11.775V10.625Q11.775,10.85 11.963,11.037Q12.15,11.225 12.375,11.225Z"/>
|
||||
</vector>
|
||||
|
||||
@@ -22,6 +22,6 @@ Copyright 2022 Google
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M12,9.5c1.38,0 2.5,1.12 2.5,2.5s-1.12,2.5 -2.5,2.5S9.5,13.38 9.5,12S10.62,9.5 12,9.5M12,8.5c-1.93,0 -3.5,1.57 -3.5,3.5s1.57,3.5 3.5,3.5s3.5,-1.57 3.5,-3.5S13.93,8.5 12,8.5L12,8.5zM13.22,3l0.55,2.2l0.13,0.51l0.5,0.18c0.61,0.23 1.19,0.56 1.72,0.98l0.4,0.32l0.5,-0.14l2.17,-0.62l1.22,2.11l-1.63,1.59l-0.37,0.36l0.08,0.51c0.05,0.32 0.08,0.64 0.08,0.98s-0.03,0.66 -0.08,0.98l-0.08,0.51l0.37,0.36l1.63,1.59l-1.22,2.11l-2.17,-0.62l-0.5,-0.14l-0.4,0.32c-0.53,0.43 -1.11,0.76 -1.72,0.98l-0.5,0.18l-0.13,0.51L13.22,21h-2.44l-0.55,-2.2l-0.13,-0.51l-0.5,-0.18C9,17.88 8.42,17.55 7.88,17.12l-0.4,-0.32l-0.5,0.14l-2.17,0.62L3.6,15.44l1.63,-1.59l0.37,-0.36l-0.08,-0.51C5.47,12.66 5.44,12.33 5.44,12s0.03,-0.66 0.08,-0.98l0.08,-0.51l-0.37,-0.36L3.6,8.56l1.22,-2.11l2.17,0.62l0.5,0.14l0.4,-0.32C8.42,6.45 9,6.12 9.61,5.9l0.5,-0.18l0.13,-0.51L10.78,3H13.22M14,2h-4L9.26,4.96c-0.73,0.27 -1.4,0.66 -2,1.14L4.34,5.27l-2,3.46l2.19,2.13C4.47,11.23 4.44,11.61 4.44,12s0.03,0.77 0.09,1.14l-2.19,2.13l2,3.46l2.92,-0.83c0.6,0.48 1.27,0.87 2,1.14L10,22h4l0.74,-2.96c0.73,-0.27 1.4,-0.66 2,-1.14l2.92,0.83l2,-3.46l-2.19,-2.13c0.06,-0.37 0.09,-0.75 0.09,-1.14s-0.03,-0.77 -0.09,-1.14l2.19,-2.13l-2,-3.46L16.74,6.1c-0.6,-0.48 -1.27,-0.87 -2,-1.14L14,2L14,2z" />
|
||||
</vector>
|
||||
|
||||
@@ -22,6 +22,6 @@ Copyright 2022 Google
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M11.5,20.5 L11.5,15.5 L12.5,15.5 L12.5,17.5 L20.5,17.5 L20.5,18.5 L12.5,18.5 L12.5,20.5 Z M3.5,18.5 L3.5,17.5 L8.5,17.5 L8.5,18.5 Z M7.5,14.5 L7.5,12.5 L3.5,12.5 L3.5,11.5 L7.5,11.5 L7.5,9.5 L8.5,9.5 L8.5,14.5 Z M11.5,12.5 L11.5,11.5 L20.5,11.5 L20.5,12.5 Z M15.5,8.5 L15.5,3.5 L16.5,3.5 L16.5,5.5 L20.5,5.5 L20.5,6.5 L16.5,6.5 L16.5,8.5 Z M3.5,6.5 L3.5,5.5 L12.5,5.5 L12.5,6.5 Z M3.5,6.5" />
|
||||
</vector>
|
||||
|
||||
@@ -21,9 +21,9 @@ Copyright 2022 Google
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M8.54688,22.2031 C7.00781,22.2031,5.51172,21.375,4.73047,19.9219 C3.66797,17.9414,4.32031,15.4531,6.21875,14.25 C6.23047,14.2422,6.24219,14.2344,6.25391,14.2305 C6.40625,14.1523,6.55469,14.0703,6.70703,13.9844 C6.59375,13.9219,6.48438,13.8594,6.37109,13.793 C5.20703,13.1211,4.49219,12.1758,4.29688,11.0508 C4.04297,9.55078,4.04297,7.65625,6.32031,6.28516 C8.07031,5.23828,9.86719,4.21484,11.6016,3.22266 C12.1797,2.89453,12.7539,2.56641,13.332,2.23438 C14.5313,1.54688,16.0195,1.51953,17.3008,2.16016 C18.5977,2.80469,19.4805,4.01563,19.6641,5.40625 C19.9297,7.17578,19.0469,8.94531,17.4609,9.80469 C17.3594,9.86328,17.2578,9.91797,17.1602,9.97656 C17.2539,10.0313,17.3477,10.0859,17.4414,10.1406 C18.7422,10.8711,19.5664,12.1172,19.6953,13.5547 C19.8242,14.9766,19.25,16.332,18.1211,17.2734 C17.7617,17.5664,17.3633,17.793,16.9805,18.0078 C16.8672,18.0703,16.7578,18.1328,16.6484,18.1953 C14.8711,19.2344,12.7617,20.457,10.5859,21.6875 C9.9375,22.0352,9.23828,22.2031,8.54688,22.2031 Z M6.69141,15.0313 C5.20703,15.9805,4.69922,17.9375,5.53125,19.4922 C6.42578,21.1484,8.49609,21.7773,10.1445,20.8906 C12.3086,19.668,14.4141,18.4453,16.1875,17.4102 C16.3008,17.3438,16.418,17.2773,16.5313,17.2148 C16.8984,17.0078,17.2461,16.8125,17.543,16.5703 C18.4336,15.8281,18.8906,14.7578,18.7891,13.6367 C18.6836,12.5039,18.0313,11.5156,16.9922,10.9336 C16.8281,10.8359,16.6641,10.7383,16.4961,10.6367 C16.3516,10.5508,16.2031,10.4609,16.043,10.3711 C15.9063,10.2891,15.8203,10.1445,15.8164,9.98438 C15.8125,9.82422,15.8984,9.67188,16.0352,9.58984 C16.3516,9.39063,16.6641,9.20703,17.0195,9.00781 C18.2773,8.32813,18.9727,6.92969,18.7617,5.53125 C18.6172,4.4375,17.9219,3.48438,16.8984,2.97656 C15.8828,2.47266,14.7188,2.49219,13.7813,3.02344 C13.207,3.35547,12.6289,3.68359,12.0547,4.01172 C10.3242,5.00391,8.53125,6.02344,6.78906,7.06641 C5.34375,7.9375,4.88281,9.04688,5.19531,10.8984 C5.34375,11.7539,5.89063,12.4648,6.82422,13 C7.15234,13.1875,7.47656,13.375,7.83984,13.5898 C7.97656,13.6719,8.0625,13.8203,8.0625,13.9805 C8.0625,14.1406,7.98047,14.2891,7.83984,14.375 C7.44531,14.6133,7.08203,14.8281,6.69141,15.0313 Z M6.69141,15.0313" />
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M10.0703,15.3555 C9.99219,15.3555,9.91406,15.3359,9.84375,15.2969 C9.69922,15.2148,9.61328,15.0625,9.61328,14.9023 L9.61328,9.08594 C9.61328,8.92188,9.69922,8.76953,9.83984,8.69141 C9.98438,8.60938,10.1563,8.60938,10.2969,8.69141 L15.3281,11.5898 C15.4688,11.6719,15.5547,11.8242,15.5547,11.9844 C15.5586,12.1484,15.4688,12.3008,15.3281,12.3789 L10.2969,15.2969 C10.2266,15.3359,10.1484,15.3555,10.0703,15.3555 Z M10.5234,9.875 L10.5234,14.1094 L14.1914,11.9883 Z M10.5234,9.875" />
|
||||
</vector>
|
||||
|
||||
@@ -22,6 +22,6 @@ Copyright 2022 Google
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M4.5,14Q3.65,14 3.075,13.425Q2.5,12.85 2.5,12Q2.5,11.15 3.075,10.575Q3.65,10 4.5,10Q5.2,10 5.738,10.425Q6.275,10.85 6.425,11.5H21.5V12.5H6.425Q6.275,13.15 5.738,13.575Q5.2,14 4.5,14Z"/>
|
||||
</vector>
|
||||
|
||||
@@ -22,6 +22,6 @@ Copyright 2022 Google
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M3,21 L3,20.1328 L5.3125,20.1328 C4.33203,18.9844,3.54297,17.7266,2.95703,16.3516 C2.37109,14.9805,2.07813,13.5313,2.07813,12.0078 C2.07813,10.4883,2.37109,9.04297,2.95703,7.67578 C3.54297,6.30859,4.33203,5.04688,5.3125,3.88281 L3,3.88281 L3,3 L7.09766,3 L7.09766,7.11719 L6.23047,7.11719 L6.23047,4.17578 C5.25,5.28906,4.45703,6.50391,3.85156,7.82422 C3.24609,9.14063,2.94141,10.5352,2.94141,12.0078 C2.94141,13.4844,3.24609,14.875,3.85156,16.1875 C4.45703,17.4961,5.25,18.7031,6.23047,19.8047 L6.23047,16.9023 L7.09766,16.9023 L7.09766,21 Z M16.2969,19.8047 C15.9883,19.9141,15.668,19.9648,15.3359,19.9531 C15,19.9453,14.6836,19.8711,14.3789,19.7266 L8.0625,16.7891 L8.35938,16.1953 C8.46094,16.0156,8.59375,15.8711,8.75781,15.7656 C8.92188,15.6563,9.10547,15.5938,9.30859,15.5781 L12.1602,15.2578 L9.30469,7.44922 C9.25391,7.3125,9.26172,7.18359,9.32031,7.0625 C9.38281,6.94531,9.48047,6.85938,9.61719,6.80859 C9.75391,6.76172,9.88281,6.76563,10.0039,6.82813 C10.1211,6.88672,10.207,6.98438,10.2539,7.12109 L13.5508,16.1797 L9.80078,16.5078 L14.8086,18.8242 C14.9766,18.8984,15.1602,18.9453,15.3672,18.957 C15.5703,18.9727,15.7617,18.9453,15.9414,18.8711 L19.3867,17.6211 C20.043,17.3867,20.5195,16.957,20.8086,16.332 C21.1016,15.7109,21.1289,15.0703,20.8945,14.4102 L19.5195,10.6602 C19.4688,10.5234,19.4727,10.3945,19.5234,10.2734 C19.5781,10.1523,19.6719,10.0703,19.8125,10.0195 C19.9492,9.97266,20.0781,9.97266,20.1992,10.0273 C20.3203,10.0781,20.4023,10.1758,20.4531,10.3125 L21.8281,14.0625 C22.1719,14.9844,22.1406,15.8789,21.7383,16.75 C21.332,17.6172,20.668,18.2188,19.7422,18.5547 Z M14.5273,13.5469 L13.1563,9.76953 C13.1094,9.63281,13.1133,9.50391,13.1758,9.38281 C13.2344,9.26563,13.332,9.17969,13.4727,9.13281 C13.6094,9.08203,13.7383,9.08594,13.8555,9.14844 C13.9766,9.20703,14.0586,9.30469,14.1094,9.44141 L15.4844,13.1914 Z M17.1992,12.5586 L16.1719,9.73438 C16.125,9.59766,16.1289,9.46875,16.1914,9.35547 C16.25,9.23828,16.3477,9.16016,16.4844,9.11328 C16.625,9.0625,16.7539,9.06641,16.8711,9.12109 C16.9922,9.17188,17.0781,9.26563,17.125,9.40625 L18.1484,12.2266 Z M17.0898,15.2578 Z M17.0898,15.2578" />
|
||||
</vector>
|
||||
|
||||
@@ -22,6 +22,6 @@ Copyright 2022 Google
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M3.625,15Q3,15 2.5,14.5Q2,14 2,13.375V12.15Q2,12.025 2.025,11.862Q2.05,11.7 2.1,11.55L4.85,5.075Q5.05,4.625 5.538,4.312Q6.025,4 6.55,4H16.575V15L10.3,21.2L9.875,20.75Q9.725,20.625 9.638,20.4Q9.55,20.175 9.55,20V19.85L10.575,15ZM15.575,5H6.55Q6.325,5 6.1,5.112Q5.875,5.225 5.775,5.5L3,12V13.375Q3,13.65 3.175,13.825Q3.35,14 3.625,14H11.8L10.65,19.45L15.575,14.575ZM15.575,14.575V14Q15.575,14 15.575,13.825Q15.575,13.65 15.575,13.375V12V5.5Q15.575,5.225 15.575,5.112Q15.575,5 15.575,5ZM16.575,15V14H20V5H16.575V4H21V15Z"/>
|
||||
</vector>
|
||||
|
||||
@@ -11,6 +11,6 @@ Copyright 2021 Ajay Ramachandran <dev@ajay.app>
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M 12.000145,2.0000008 C 8.8230689,1.9990926 5.6959192,2.7864027 2.9017488,4.2906678 2.3373945,4.5948398 1.9899198,5.1860103 2.000223,5.8244635 2.0930396,12.358829 5.4926743,18.31271 11.094442,21.749998 c 0.557183,0.333336 1.253849,0.333336 1.811031,0 5.601767,-3.438045 9.001096,-9.391169 9.094295,-15.9255345 0.01052,-0.6386247 -0.337035,-1.2300179 -0.9016,-1.5341683 -2.794107,-1.5040456 -5.92111,-2.2912233 -9.098023,-2.2902944 z m 0.08082,0.8705548 c 3.003625,0.013255 5.957553,0.7636027 8.599879,2.1845129 0.277414,0.151228 0.448533,0.4421907 0.44513,0.7568723 C 21.034684,12.23921 17.58825,17.8544 12.446767,21.009378 c -0.274165,0.167124 -0.619386,0.167124 -0.893551,0 C 6.4117365,17.854399 2.9652339,12.239209 2.8739372,5.8119397 2.8705209,5.4972741 3.0416092,5.2063196 3.3189962,5.0550685 6.0095892,3.608201 9.0224769,2.8570356 12.080969,2.8705556 Z M 9.6351953,6.7701615 v 8.3406435 l 7.2606727,-4.170358 z"/>
|
||||
</vector>
|
||||
|
||||
@@ -22,6 +22,6 @@ Copyright 2022 Google
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M16.3,11.95 L12.075,7.725 16.3,3.5 20.525,7.725ZM4.625,10.625V4.625H10.625V10.625ZM13.375,19.375V13.375H19.375V19.375ZM4.625,19.375V13.375H10.625V19.375ZM5.625,9.625H9.625V5.625H5.625ZM16.325,10.575 L19.15,7.75 16.325,4.925 13.5,7.75ZM14.375,18.375H18.375V14.375H14.375ZM5.625,18.375H9.625V14.375H5.625ZM9.625,9.625ZM13.5,7.75ZM9.625,14.375ZM14.375,14.375Z"/>
|
||||
</vector>
|
||||
|
||||
@@ -22,6 +22,6 @@ Copyright 2022 Google
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?ytTextPrimary"
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M12,19H4.625Q3.925,19 3.463,18.538Q3,18.075 3,17.375V6.625Q3,5.925 3.463,5.463Q3.925,5 4.625,5H19.375Q20.075,5 20.538,5.463Q21,5.925 21,6.625V11H20V6.625Q20,6.35 19.825,6.175Q19.65,6 19.375,6H4.625Q4.35,6 4.175,6.175Q4,6.35 4,6.625V17.375Q4,17.65 4.175,17.825Q4.35,18 4.625,18H12ZM10,15.575V8.425L15.575,12ZM17.85,20.8 L17.75,19.95Q17.175,19.825 16.8,19.6Q16.425,19.375 16.1,19.025L15.3,19.4L14.725,18.525L15.45,17.95Q15.25,17.425 15.25,16.925Q15.25,16.425 15.45,15.9L14.725,15.3L15.3,14.45L16.1,14.8Q16.425,14.475 16.8,14.25Q17.175,14.025 17.75,13.9L17.85,13.05H18.85L18.95,13.9Q19.525,14.025 19.9,14.25Q20.275,14.475 20.6,14.825L21.4,14.45L21.975,15.325L21.25,15.9Q21.45,16.425 21.45,16.925Q21.45,17.425 21.25,17.95L21.975,18.525L21.4,19.4L20.6,19.025Q20.275,19.375 19.9,19.6Q19.525,19.825 18.95,19.95L18.85,20.8ZM18.35,19.075Q19.225,19.075 19.863,18.438Q20.5,17.8 20.5,16.925Q20.5,16.05 19.863,15.413Q19.225,14.775 18.35,14.775Q17.475,14.775 16.837,15.413Q16.2,16.05 16.2,16.925Q16.2,17.8 16.837,18.438Q17.475,19.075 18.35,19.075Z"/>
|
||||
</vector>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:pathData="M11.0882,3 C6.62072,3,3,6.62368,3,11.0911 C3,15.5615,6.62368,19.1822,11.0911,19.1822 C13.172,19.1822,15.0691,18.3954,16.5029,17.1039 L20.094,20.695 C21.1138,19.6754,19.8953,20.8968,21,19.7921 L17.3822,16.1773 C18.5074,14.7874,19.1822,13.018,19.1822,11.0911 C19.1793,6.62072,15.5556,3,11.0882,3 Z M11.0882,4.27895 C14.851,4.27895,17.9004,7.32829,17.9004,11.0911 C17.9004,14.851,14.8511,17.9003,11.0882,17.9003 C7.32537,17.9003,4.27603,14.851,4.27603,11.0911 C4.27898,7.32827,7.32833,4.28189,11.0882,4.27893 Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M11.5,3.5 L3.5,11.5 L11.5,19.5 L12.3145,18.6914 L5.69531,12.0723 L21,12.0723 L21,10.9277 L5.69531,10.9277 L12.3145,4.30859 Z"/>
|
||||
</vector>
|
||||
@@ -1,27 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
'android.R.style.ThemeOverlay_Material_Dialog' is a theme added in Android 6.0+.
|
||||
|
||||
'android:windowBackground' is the background color of the alert dialog.
|
||||
If not overridden, the background color of the parent theme 'android.R.style.ThemeOverlay_Material_Dialog' is used.
|
||||
|
||||
'R.attr.ytRaisedBackground' is the background color of the YouTube alert dialog.
|
||||
|
||||
'android:windowIsTranslucent' makes the dialog window transparent.
|
||||
|
||||
'android:background' needs to be transparent for the 'contextual action bar' to be displayed properly.
|
||||
|
||||
Referenced documentation and framework source code:
|
||||
https://android.googlesource.com/platform/frameworks/base/+/android-6.0.1_r81/core/res/res/values/themes_material.xml#1142
|
||||
https://developer.android.com/reference/android/R.style#ThemeOverlay_Material_Dialog
|
||||
https://developer.android.com/about/versions/marshmallow/android-6.0-changes#behavior-text-selection
|
||||
-->
|
||||
<resources>
|
||||
<style name="revanced_edit_text_dialog_style" parent="@android:style/ThemeOverlay.Material.Dialog">
|
||||
<item name="android:windowBackground">?ytRaisedBackground</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:background">@android:color/transparent</item>
|
||||
</style>
|
||||
<style name="revanced_searchbar_cursor">
|
||||
<item name="android:textCursorDrawable">@drawable/revanced_settings_cursor</item>
|
||||
<item name="android:textSize">16sp</item>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
android:layout_gravity="center"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<View
|
||||
android:id="@+id/revanced_color_dot_widget"
|
||||
android:layout_width="20dp"
|
||||
@@ -15,4 +16,5 @@
|
||||
android:elevation="2dp"
|
||||
android:translationZ="2dp"
|
||||
android:outlineProvider="background" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<app.revanced.extension.shared.settings.preference.ColorPickerView
|
||||
android:id="@+id/color_picker_view"
|
||||
android:id="@+id/revanced_color_picker_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/revanced_check_icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/revanced_settings_custom_checkmark"
|
||||
android:visibility="gone"
|
||||
android:contentDescription="@null" />
|
||||
|
||||
<View
|
||||
android:id="@+id/revanced_check_icon_placeholder"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/revanced_item_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,10 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="54dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
android:minHeight="54dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -12,6 +13,7 @@
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginHorizontal="18dp"
|
||||
android:contentDescription="@null" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="0dp"
|
||||
@@ -19,21 +21,24 @@
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingVertical="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/medium_font_size"
|
||||
android:textColor="?ytTextPrimary"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textAlignment="viewStart" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
android:textColor="?ytTextSecondary"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textAlignment="viewStart"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:contentDescription="History icon"
|
||||
android:src="@drawable/yt_outline_arrow_time_vd_theme_24" />
|
||||
android:src="@drawable/revanced_settings_arrow_time" />
|
||||
|
||||
<!-- Suggestion text -->
|
||||
<TextView
|
||||
|
||||
@@ -13,17 +13,17 @@
|
||||
<FrameLayout
|
||||
android:id="@+id/revanced_toolbar_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/yt_white1"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:background="@android:color/white"
|
||||
android:elevation="0dp">
|
||||
|
||||
<!-- Toolbar -->
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/revanced_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/ytBrandBackgroundSolid"
|
||||
app:navigationIcon="@drawable/yt_outline_arrow_left_black_24"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:background="@android:color/white"
|
||||
app:navigationIcon="@drawable/revanced_settings_toolbar_arrow_left"
|
||||
app:title="@string/revanced_settings_title" />
|
||||
|
||||
<!-- Container for SearchView -->
|
||||
@@ -60,4 +60,4 @@
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
</merge>
|
||||
</merge>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/action_search"
|
||||
android:icon="@drawable/yt_outline_search_black_24"
|
||||
android:icon="@drawable/revanced_settings_search_icon"
|
||||
android:title=""
|
||||
android:showAsAction="always"/>
|
||||
</menu>
|
||||
</menu>
|
||||
|
||||
Reference in New Issue
Block a user