mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-09 11:04:36 +02:00
fix(Patch options): some patch options in RVX Manager are marked with custom value
This commit is contained in:
parent
f7fe7e8caf
commit
8dc8bffea7
@ -9,6 +9,7 @@ import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.Utils.trimIndentMultiline
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
import app.revanced.util.underBarOrThrow
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
|
||||
@ -18,13 +19,13 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
||||
description = "Changes the YouTube Music app icon to the icon specified in options.json.",
|
||||
compatiblePackages = COMPATIBLE_PACKAGE
|
||||
) {
|
||||
private const val DEFAULT_ICON_KEY = "Revancify Blue"
|
||||
private const val DEFAULT_ICON = "revancify_blue"
|
||||
|
||||
private val availableIcon = mapOf(
|
||||
"AFN Blue" to "afn_blue",
|
||||
"AFN Red" to "afn_red",
|
||||
"MMT" to "mmt",
|
||||
DEFAULT_ICON_KEY to "revancify_blue",
|
||||
"Revancify Blue" to DEFAULT_ICON,
|
||||
"Revancify Red" to "revancify_red",
|
||||
"YouTube Music" to "youtube_music"
|
||||
)
|
||||
@ -93,9 +94,9 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
||||
)
|
||||
}
|
||||
|
||||
private val AppIcon by stringPatchOption(
|
||||
private val AppIcon = stringPatchOption(
|
||||
key = "AppIcon",
|
||||
default = DEFAULT_ICON_KEY,
|
||||
default = DEFAULT_ICON,
|
||||
values = availableIcon,
|
||||
title = "App icon",
|
||||
description = """
|
||||
@ -129,12 +130,15 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
||||
)
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
AppIcon?.let { appIcon ->
|
||||
val appIconValue = appIcon.lowercase().replace(" ", "_")
|
||||
val appIconResourcePath = "music/branding/$appIconValue"
|
||||
|
||||
// Check patch options first.
|
||||
val appIcon = AppIcon
|
||||
.underBarOrThrow()
|
||||
|
||||
val appIconResourcePath = "music/branding/$appIcon"
|
||||
|
||||
// Check if a custom path is used in the patch options.
|
||||
if (!availableIcon.containsValue(appIconValue)) {
|
||||
if (!availableIcon.containsValue(appIcon)) {
|
||||
launcherIconResourceGroups.let { resourceGroups ->
|
||||
try {
|
||||
val path = File(appIcon)
|
||||
@ -193,6 +197,5 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
||||
}
|
||||
}
|
||||
}
|
||||
} ?: throw PatchException("Invalid app icon path.")
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
package app.revanced.patches.music.layout.branding.name
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.shared.elements.StringsElementsUtils.removeStringsElements
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
import app.revanced.util.valueOrThrow
|
||||
|
||||
@Suppress("DEPRECATION", "unused")
|
||||
object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
@ -16,7 +16,7 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
private const val APP_NAME_NOTIFICATION = "ReVanced Extended Music"
|
||||
private const val APP_NAME_LAUNCHER = "RVX Music"
|
||||
|
||||
private val AppNameNotification by stringPatchOption(
|
||||
private val AppNameNotification = stringPatchOption(
|
||||
key = "AppNameNotification",
|
||||
default = APP_NAME_LAUNCHER,
|
||||
values = mapOf(
|
||||
@ -30,7 +30,7 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
required = true
|
||||
)
|
||||
|
||||
private val AppNameLauncher by stringPatchOption(
|
||||
private val AppNameLauncher = stringPatchOption(
|
||||
key = "AppNameLauncher",
|
||||
default = APP_NAME_LAUNCHER,
|
||||
values = mapOf(
|
||||
@ -46,12 +46,16 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
|
||||
// Check patch options first.
|
||||
val notificationName = AppNameNotification
|
||||
.valueOrThrow()
|
||||
val launcherName = AppNameLauncher
|
||||
.valueOrThrow()
|
||||
|
||||
context.removeStringsElements(
|
||||
arrayOf("app_launcher_name", "app_name")
|
||||
)
|
||||
|
||||
AppNameNotification?.let { notificationName ->
|
||||
AppNameLauncher?.let { launcherName ->
|
||||
context.xmlEditor["res/values/strings.xml"].use { editor ->
|
||||
val document = editor.file
|
||||
|
||||
@ -68,7 +72,5 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
.appendChild(stringElement)
|
||||
}
|
||||
}
|
||||
} ?: throw PatchException("Invalid launcher name.")
|
||||
} ?: throw PatchException("Invalid notification name.")
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import app.revanced.patches.music.utils.settings.ResourceUtils.sortPreferenceCat
|
||||
import app.revanced.patches.shared.elements.StringsElementsUtils.removeStringsElements
|
||||
import app.revanced.util.copyXmlNode
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
import app.revanced.util.valueOrThrow
|
||||
import org.w3c.dom.Element
|
||||
import java.io.Closeable
|
||||
import java.util.concurrent.Executors
|
||||
@ -30,7 +31,7 @@ object SettingsPatch : BaseResourcePatch(
|
||||
), Closeable {
|
||||
private const val DEFAULT_NAME = "ReVanced Extended"
|
||||
|
||||
private val RVXSettingsMenuName by stringPatchOption(
|
||||
private val RVXSettingsMenuName = stringPatchOption(
|
||||
key = "RVXSettingsMenuName",
|
||||
default = DEFAULT_NAME,
|
||||
title = "RVX settings menu name",
|
||||
@ -38,12 +39,20 @@ object SettingsPatch : BaseResourcePatch(
|
||||
required = true
|
||||
)
|
||||
|
||||
private lateinit var customName: String
|
||||
|
||||
lateinit var contexts: ResourceContext
|
||||
internal var upward0636 = false
|
||||
internal var upward0642 = false
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
|
||||
/**
|
||||
* check patch options
|
||||
*/
|
||||
customName = RVXSettingsMenuName
|
||||
.valueOrThrow()
|
||||
|
||||
/**
|
||||
* set resource context
|
||||
*/
|
||||
@ -193,7 +202,6 @@ object SettingsPatch : BaseResourcePatch(
|
||||
* change RVX settings menu name
|
||||
* since it must be invoked after the Translations patch, it must be the last in the order.
|
||||
*/
|
||||
RVXSettingsMenuName?.let { customName ->
|
||||
if (customName != DEFAULT_NAME) {
|
||||
contexts.removeStringsElements(
|
||||
arrayOf("revanced_extended_settings_title")
|
||||
@ -214,14 +222,18 @@ object SettingsPatch : BaseResourcePatch(
|
||||
}
|
||||
}
|
||||
}
|
||||
} ?: println("WARNING: Invalid RVX settings menu name. RVX settings menu name does not change.")
|
||||
|
||||
|
||||
/**
|
||||
* add import export settings
|
||||
*/
|
||||
addPreferenceWithIntent(
|
||||
CategoryType.MISC,
|
||||
"revanced_extended_settings_import_export"
|
||||
)
|
||||
|
||||
/**
|
||||
* sort preference
|
||||
*/
|
||||
CategoryType.entries.sorted().forEach {
|
||||
contexts.sortPreferenceCategory(it.value)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||
import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
import app.revanced.util.valueOrThrow
|
||||
import java.io.FileWriter
|
||||
import java.nio.file.Files
|
||||
|
||||
@ -17,7 +18,7 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
private const val ORIGINAL_APP_NAME = "Reddit"
|
||||
private const val APP_NAME = "RVX Reddit"
|
||||
|
||||
private val AppName by stringPatchOption(
|
||||
private val AppName = stringPatchOption(
|
||||
key = "AppName",
|
||||
default = ORIGINAL_APP_NAME,
|
||||
values = mapOf(
|
||||
@ -30,14 +31,14 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
)
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
val appName = if (AppName != null) {
|
||||
AppName!!
|
||||
} else {
|
||||
println("WARNING: Invalid app name. Does not apply patches.")
|
||||
ORIGINAL_APP_NAME
|
||||
val appName = AppName
|
||||
.valueOrThrow()
|
||||
|
||||
if (appName == ORIGINAL_APP_NAME) {
|
||||
println("INFO: App name will remain unchanged as it matches the original.")
|
||||
return
|
||||
}
|
||||
|
||||
if (appName != ORIGINAL_APP_NAME) {
|
||||
val resDirectory = context["res"]
|
||||
|
||||
val valuesV24Directory = resDirectory.resolve("values-v24")
|
||||
@ -66,8 +67,5 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
document.getElementsByTagName("resources").item(0).appendChild(stringElement)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println("INFO: App name will remain unchanged as it matches the original.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||
import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
import app.revanced.util.valueOrThrow
|
||||
import org.w3c.dom.Element
|
||||
import java.io.Closeable
|
||||
|
||||
@ -21,7 +22,7 @@ object ChangePackageNamePatch : BaseResourcePatch(
|
||||
private lateinit var context: ResourceContext
|
||||
private var redditPackageName = PACKAGE_NAME_REDDIT
|
||||
|
||||
private val PackageNameReddit by stringPatchOption(
|
||||
private val PackageNameReddit = stringPatchOption(
|
||||
key = "PackageNameReddit",
|
||||
default = PACKAGE_NAME_REDDIT,
|
||||
values = mapOf(
|
||||
@ -37,13 +38,14 @@ object ChangePackageNamePatch : BaseResourcePatch(
|
||||
override fun execute(context: ResourceContext) {
|
||||
this.context = context
|
||||
|
||||
if (PackageNameReddit != null) {
|
||||
redditPackageName = PackageNameReddit!!
|
||||
} else {
|
||||
println("WARNING: Invalid package name. Does not apply patches.")
|
||||
redditPackageName = PackageNameReddit
|
||||
.valueOrThrow()
|
||||
|
||||
if (redditPackageName == PACKAGE_NAME_REDDIT) {
|
||||
println("INFO: Package name will remain unchanged as it matches the original.")
|
||||
return
|
||||
}
|
||||
|
||||
if (redditPackageName != PACKAGE_NAME_REDDIT) {
|
||||
// Ensure device runs Android.
|
||||
try {
|
||||
// RVX Manager
|
||||
@ -51,13 +53,11 @@ object ChangePackageNamePatch : BaseResourcePatch(
|
||||
// For some reason, in Android AAPT2, a compilation error occurs when changing the [strings.xml] of the Reddit
|
||||
// This only affects RVX Manager, and has not yet found a valid workaround
|
||||
Class.forName("android.os.Environment")
|
||||
return
|
||||
} catch (_: ClassNotFoundException) {
|
||||
// CLI
|
||||
context.replacePackageName(redditPackageName)
|
||||
}
|
||||
} else {
|
||||
println("INFO: Package name will remain unchanged as it matches the original.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
|
@ -6,6 +6,7 @@ import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatc
|
||||
import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.reddit.utils.integrations.IntegrationsPatch
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
import app.revanced.util.valueOrThrow
|
||||
import kotlin.io.path.exists
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
@ -21,7 +22,7 @@ object SettingsPatch : BaseResourcePatch(
|
||||
) {
|
||||
private const val DEFAULT_NAME = "ReVanced Extended"
|
||||
|
||||
private val RVXSettingsMenuName by stringPatchOption(
|
||||
private val RVXSettingsMenuName = stringPatchOption(
|
||||
key = "RVXSettingsMenuName",
|
||||
default = DEFAULT_NAME,
|
||||
title = "RVX settings menu name",
|
||||
@ -32,11 +33,8 @@ object SettingsPatch : BaseResourcePatch(
|
||||
/**
|
||||
* Replace settings icon and label
|
||||
*/
|
||||
|
||||
var settingsLabel = DEFAULT_NAME
|
||||
|
||||
if (!RVXSettingsMenuName.isNullOrEmpty())
|
||||
settingsLabel = RVXSettingsMenuName!!
|
||||
val settingsLabel = RVXSettingsMenuName
|
||||
.valueOrThrow()
|
||||
|
||||
arrayOf("preferences", "preferences_logged_in").forEach { targetXML ->
|
||||
val resDirectory = context["res"]
|
||||
|
@ -1,12 +1,12 @@
|
||||
package app.revanced.patches.youtube.layout.actionbuttons
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.lowerCaseOrThrow
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
|
||||
@Suppress("unused")
|
||||
@ -16,15 +16,15 @@ object ShortsActionButtonsPatch : BaseResourcePatch(
|
||||
dependencies = setOf(SettingsPatch::class),
|
||||
compatiblePackages = COMPATIBLE_PACKAGE
|
||||
) {
|
||||
private const val DEFAULT_ICON_KEY = "Round"
|
||||
private const val DEFAULT_ICON = "round"
|
||||
|
||||
private val IconType by stringPatchOption(
|
||||
private val IconType = stringPatchOption(
|
||||
key = "IconType",
|
||||
default = DEFAULT_ICON_KEY,
|
||||
default = DEFAULT_ICON,
|
||||
values = mapOf(
|
||||
"Outline" to "outline",
|
||||
"OutlineCircle" to "outlinecircle",
|
||||
DEFAULT_ICON_KEY to "round"
|
||||
"Round" to DEFAULT_ICON
|
||||
),
|
||||
title = "Shorts icon style ",
|
||||
description = "The style of the icons for the action buttons in the Shorts player.",
|
||||
@ -32,8 +32,10 @@ object ShortsActionButtonsPatch : BaseResourcePatch(
|
||||
)
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
IconType?.let { iconType ->
|
||||
val selectedIconType = iconType.lowercase()
|
||||
|
||||
// Check patch options first.
|
||||
val iconType = IconType
|
||||
.lowerCaseOrThrow()
|
||||
|
||||
arrayOf(
|
||||
"xxxhdpi",
|
||||
@ -43,7 +45,7 @@ object ShortsActionButtonsPatch : BaseResourcePatch(
|
||||
"mdpi"
|
||||
).forEach { dpi ->
|
||||
context.copyResources(
|
||||
"youtube/shorts/actionbuttons/$selectedIconType",
|
||||
"youtube/shorts/actionbuttons/$iconType",
|
||||
ResourceGroup(
|
||||
"drawable-$dpi",
|
||||
"ic_remix_filled_white_shadowed.webp",
|
||||
@ -67,6 +69,7 @@ object ShortsActionButtonsPatch : BaseResourcePatch(
|
||||
"ic_right_share_32c.xml"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
context.copyResources(
|
||||
"youtube/shorts/actionbuttons/shared",
|
||||
@ -77,8 +80,6 @@ object ShortsActionButtonsPatch : BaseResourcePatch(
|
||||
"reel_search_bold_24dp.xml"
|
||||
)
|
||||
)
|
||||
}
|
||||
} ?: throw PatchException("Invalid icon type.")
|
||||
|
||||
SettingsPatch.updatePatchStatus(this)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package app.revanced.patches.youtube.layout.branding.icon
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.booleanPatchOption
|
||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
@ -9,26 +8,26 @@ import app.revanced.patches.youtube.utils.settings.ResourceUtils.updatePatchStat
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.Utils.trimIndentMultiline
|
||||
import app.revanced.util.copyFile
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.copyXmlNode
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import app.revanced.util.underBarOrThrow
|
||||
|
||||
@Suppress("DEPRECATION", "unused")
|
||||
@Suppress("unused")
|
||||
object CustomBrandingIconPatch : BaseResourcePatch(
|
||||
name = "Custom branding icon YouTube",
|
||||
description = "Changes the YouTube app icon to the icon specified in options.json.",
|
||||
dependencies = setOf(SettingsPatch::class),
|
||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||
) {
|
||||
private const val DEFAULT_ICON_KEY = "Revancify Blue"
|
||||
private const val DEFAULT_ICON = "revancify_blue"
|
||||
|
||||
private val availableIcon = mapOf(
|
||||
"AFN Blue" to "afn_blue",
|
||||
"AFN Red" to "afn_red",
|
||||
"MMT" to "mmt",
|
||||
DEFAULT_ICON_KEY to "revancify_blue",
|
||||
"Revancify Blue" to DEFAULT_ICON,
|
||||
"Revancify Red" to "revancify_red",
|
||||
"YouTube" to "youtube"
|
||||
)
|
||||
@ -109,9 +108,9 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
||||
|
||||
// region patch option
|
||||
|
||||
val AppIcon by stringPatchOption(
|
||||
val AppIcon = stringPatchOption(
|
||||
key = "AppIcon",
|
||||
default = DEFAULT_ICON_KEY,
|
||||
default = DEFAULT_ICON,
|
||||
values = availableIcon,
|
||||
title = "App icon",
|
||||
description = """
|
||||
@ -176,13 +175,16 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
||||
// endregion
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
AppIcon?.let { appIcon ->
|
||||
val appIconValue = appIcon.lowercase().replace(" ", "_")
|
||||
val appIconResourcePath = "youtube/branding/$appIconValue"
|
||||
|
||||
// Check patch options first.
|
||||
val appIcon = AppIcon
|
||||
.underBarOrThrow()
|
||||
|
||||
val appIconResourcePath = "youtube/branding/$appIcon"
|
||||
val stockResourcePath = "youtube/branding/stock"
|
||||
|
||||
// Check if a custom path is used in the patch options.
|
||||
if (!availableIcon.containsValue(appIconValue)) {
|
||||
if (!availableIcon.containsValue(appIcon)) {
|
||||
val copiedFiles = context.copyFile(
|
||||
launcherIconResourceGroups,
|
||||
appIcon,
|
||||
@ -250,38 +252,7 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
||||
context.copyXmlNode("$stockResourcePath/splash", "values-v31/styles.xml", "resources")
|
||||
}
|
||||
|
||||
context.updatePatchStatusIcon(appIconValue)
|
||||
}
|
||||
} ?: throw PatchException("Invalid app icon path.")
|
||||
}
|
||||
|
||||
private fun ResourceContext.copyFile(
|
||||
iconResourceGroup: List<ResourceGroup>,
|
||||
path: String,
|
||||
message: String
|
||||
): Boolean {
|
||||
iconResourceGroup.let { resourceGroups ->
|
||||
try {
|
||||
val filePath = File(path)
|
||||
val resourceDirectory = this["res"]
|
||||
|
||||
resourceGroups.forEach { group ->
|
||||
val fromDirectory = filePath.resolve(group.resourceDirectoryName)
|
||||
val toDirectory = resourceDirectory.resolve(group.resourceDirectoryName)
|
||||
|
||||
group.resources.forEach { iconFileName ->
|
||||
Files.write(
|
||||
toDirectory.resolve(iconFileName).toPath(),
|
||||
fromDirectory.resolve(iconFileName).readBytes()
|
||||
)
|
||||
context.updatePatchStatusIcon(appIcon)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (_: Exception) {
|
||||
println(message)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
package app.revanced.patches.youtube.layout.branding.name
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||
import app.revanced.patches.shared.elements.StringsElementsUtils.removeStringsElements
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.settings.ResourceUtils.updatePatchStatusLabel
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
import app.revanced.util.valueOrThrow
|
||||
|
||||
@Suppress("DEPRECATION", "unused")
|
||||
object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
@ -18,7 +18,7 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
) {
|
||||
private const val APP_NAME = "RVX"
|
||||
|
||||
private val AppName by stringPatchOption(
|
||||
private val AppName = stringPatchOption(
|
||||
key = "AppName",
|
||||
default = APP_NAME,
|
||||
values = mapOf(
|
||||
@ -33,16 +33,20 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
)
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
|
||||
// Check patch options first.
|
||||
val appName = AppName
|
||||
.valueOrThrow()
|
||||
|
||||
context.removeStringsElements(
|
||||
arrayOf("application_name")
|
||||
)
|
||||
|
||||
AppName?.let {
|
||||
context.xmlEditor["res/values/strings.xml"].use { editor ->
|
||||
val document = editor.file
|
||||
|
||||
mapOf(
|
||||
"application_name" to it
|
||||
"application_name" to appName
|
||||
).forEach { (k, v) ->
|
||||
val stringElement = document.createElement("string")
|
||||
|
||||
@ -52,7 +56,6 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
document.getElementsByTagName("resources").item(0).appendChild(stringElement)
|
||||
}
|
||||
}
|
||||
context.updatePatchStatusLabel(it)
|
||||
} ?: throw PatchException("Invalid app name.")
|
||||
context.updatePatchStatusLabel(appName)
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,15 @@ object DoubleTapLengthPatch : BaseResourcePatch(
|
||||
)
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
|
||||
// Check patch options first.
|
||||
val splits = DoubleTapLengthArrays
|
||||
?.replace(" ", "")
|
||||
?.split(",")
|
||||
?: throw PatchException("Invalid double-tap length array.")
|
||||
if (splits.isEmpty()) throw IllegalArgumentException("Invalid double-tap length elements")
|
||||
val lengthElements = splits.map { it }
|
||||
|
||||
val arrayPath = "res/values-v21/arrays.xml"
|
||||
val entriesName = "double_tap_length_entries"
|
||||
val entryValueName = "double_tap_length_values"
|
||||
@ -46,12 +55,6 @@ object DoubleTapLengthPatch : BaseResourcePatch(
|
||||
)
|
||||
)
|
||||
|
||||
val length = DoubleTapLengthArrays
|
||||
?: throw PatchException("Invalid double-tap length array.")
|
||||
|
||||
val splits = length.replace(" ", "").split(",")
|
||||
if (splits.isEmpty()) throw IllegalArgumentException("Invalid double-tap length elements")
|
||||
val lengthElements = splits.map { it }
|
||||
for (index in 0 until splits.count()) {
|
||||
context.addEntryValues(arrayPath, lengthElements[index], entryValueName)
|
||||
context.addEntryValues(arrayPath, lengthElements[index], entriesName)
|
||||
|
@ -1,13 +1,13 @@
|
||||
package app.revanced.patches.youtube.layout.theme
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||
import app.revanced.patches.youtube.layout.theme.BaseThemePatch.isMonetPatchIncluded
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.settings.ResourceUtils.updatePatchStatusTheme
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
import app.revanced.util.valueOrThrow
|
||||
import org.w3c.dom.Element
|
||||
|
||||
@Suppress("DEPRECATION", "unused")
|
||||
@ -38,7 +38,7 @@ object ThemePatch : BaseResourcePatch(
|
||||
private const val LIGHT_ORANGE_COLOR = "#FFFFE6CC"
|
||||
private const val LIGHT_RED_COLOR = "#FFFFD6D6"
|
||||
|
||||
private val DarkThemeBackgroundColor by stringPatchOption(
|
||||
private val DarkThemeBackgroundColor = stringPatchOption(
|
||||
key = "DarkThemeBackgroundColor",
|
||||
default = AMOLED_BLACK_COLOR,
|
||||
values = mapOf(
|
||||
@ -56,7 +56,7 @@ object ThemePatch : BaseResourcePatch(
|
||||
required = true
|
||||
)
|
||||
|
||||
private val LightThemeBackgroundColor by stringPatchOption(
|
||||
private val LightThemeBackgroundColor = stringPatchOption(
|
||||
key = "LightThemeBackgroundColor",
|
||||
default = WHITE_COLOR,
|
||||
values = mapOf(
|
||||
@ -111,11 +111,12 @@ object ThemePatch : BaseResourcePatch(
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
|
||||
// Check patch options first.
|
||||
val darkThemeColor = DarkThemeBackgroundColor
|
||||
?: throw PatchException("Invalid dark color.")
|
||||
.valueOrThrow()
|
||||
|
||||
val lightThemeColor = LightThemeBackgroundColor
|
||||
?: throw PatchException("Invalid light color.")
|
||||
.valueOrThrow()
|
||||
|
||||
arrayOf("values", "values-v31").forEach { path ->
|
||||
context.xmlEditor["res/$path/colors.xml"].use { editor ->
|
||||
|
@ -1,6 +1,7 @@
|
||||
package app.revanced.patches.youtube.layout.visual
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||
import app.revanced.patches.youtube.layout.branding.icon.CustomBrandingIconPatch
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
@ -9,6 +10,7 @@ import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.doRecursively
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
import app.revanced.util.underBarOrThrow
|
||||
import org.w3c.dom.Element
|
||||
|
||||
@Suppress("DEPRECATION", "unused")
|
||||
@ -19,14 +21,14 @@ object VisualPreferencesIconsPatch : BaseResourcePatch(
|
||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||
use = false
|
||||
) {
|
||||
private const val DEFAULT_ICON_KEY = "Extension"
|
||||
private const val DEFAULT_ICON = "extension"
|
||||
|
||||
private val RVXSettingsMenuIcon by stringPatchOption(
|
||||
private val RVXSettingsMenuIcon = stringPatchOption(
|
||||
key = "RVXSettingsMenuIcon",
|
||||
default = DEFAULT_ICON_KEY,
|
||||
default = DEFAULT_ICON,
|
||||
values = mapOf(
|
||||
"Custom branding icon" to "custom_branding_icon",
|
||||
DEFAULT_ICON_KEY to "extension",
|
||||
"Extension" to DEFAULT_ICON,
|
||||
"Gear" to "gear",
|
||||
"ReVanced" to "revanced",
|
||||
"ReVanced Colored" to "revanced_colored",
|
||||
@ -38,6 +40,13 @@ object VisualPreferencesIconsPatch : BaseResourcePatch(
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
|
||||
// Check patch options first.
|
||||
val selectedIconType = RVXSettingsMenuIcon
|
||||
.underBarOrThrow()
|
||||
|
||||
val customBrandingIconType = CustomBrandingIconPatch.AppIcon
|
||||
.underBarOrThrow()
|
||||
|
||||
// region copy shared resources.
|
||||
|
||||
arrayOf(
|
||||
@ -57,11 +66,9 @@ object VisualPreferencesIconsPatch : BaseResourcePatch(
|
||||
|
||||
// region copy RVX settings menu icon.
|
||||
|
||||
RVXSettingsMenuIcon?.lowercase()?.replace(" ", "_")?.let { selectedIconType ->
|
||||
CustomBrandingIconPatch.AppIcon?.lowercase()?.replace(" ", "_")?.let { appIconValue ->
|
||||
val fallbackIconPath = "youtube/visual/icons/extension"
|
||||
val iconPath = when (selectedIconType) {
|
||||
"custom_branding_icon" -> "youtube/branding/$appIconValue/settings"
|
||||
"custom_branding_icon" -> "youtube/branding/$customBrandingIconType/settings"
|
||||
else -> "youtube/visual/icons/$selectedIconType"
|
||||
}
|
||||
val resourceGroup = ResourceGroup(
|
||||
@ -81,8 +88,6 @@ object VisualPreferencesIconsPatch : BaseResourcePatch(
|
||||
// and will raise an error without fallback icon
|
||||
context.copyResources(fallbackIconPath, resourceGroup)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endregion.
|
||||
|
||||
|
@ -12,6 +12,7 @@ import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.copyXmlNode
|
||||
import app.revanced.util.doRecursively
|
||||
import app.revanced.util.lowerCaseOrThrow
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
import org.w3c.dom.Element
|
||||
|
||||
@ -37,27 +38,24 @@ object OverlayButtonsPatch : BaseResourcePatch(
|
||||
private const val DEFAULT_MARGIN = "0.0dip"
|
||||
private const val WIDER_MARGIN = "6.0dip"
|
||||
|
||||
private const val DEFAULT_ICON_KEY = "Bold"
|
||||
|
||||
// Mapping of icon types to their respective resource folder names
|
||||
private val iconTypes = mapOf(
|
||||
DEFAULT_ICON_KEY to "bold",
|
||||
"Rounded" to "rounded",
|
||||
"Thin" to "thin"
|
||||
)
|
||||
private const val DEFAULT_ICON = "bold"
|
||||
|
||||
// Option to select icon type
|
||||
private val IconType by stringPatchOption(
|
||||
private val IconType = stringPatchOption(
|
||||
key = "IconType",
|
||||
default = DEFAULT_ICON_KEY,
|
||||
values = iconTypes,
|
||||
default = DEFAULT_ICON,
|
||||
values = mapOf(
|
||||
"Bold" to DEFAULT_ICON,
|
||||
"Rounded" to "rounded",
|
||||
"Thin" to "thin"
|
||||
),
|
||||
title = "Icon type",
|
||||
description = "The icon type.",
|
||||
required = true
|
||||
)
|
||||
|
||||
// Option to set bottom margin
|
||||
private val BottomMargin by stringPatchOption(
|
||||
private val BottomMargin = stringPatchOption(
|
||||
key = "BottomMargin",
|
||||
default = DEFAULT_MARGIN,
|
||||
values = mapOf(
|
||||
@ -76,6 +74,13 @@ object OverlayButtonsPatch : BaseResourcePatch(
|
||||
*/
|
||||
override fun execute(context: ResourceContext) {
|
||||
|
||||
// Check patch options first.
|
||||
val iconType = IconType
|
||||
.lowerCaseOrThrow()
|
||||
|
||||
val marginBottom = BottomMargin
|
||||
.lowerCaseOrThrow()
|
||||
|
||||
// Inject hooks for overlay buttons.
|
||||
arrayOf(
|
||||
"AlwaysRepeat;",
|
||||
@ -101,9 +106,7 @@ object OverlayButtonsPatch : BaseResourcePatch(
|
||||
context.copyResources("youtube/overlaybuttons/shared", resourceGroup)
|
||||
}
|
||||
|
||||
// Apply the selected icon type to the overlay buttons
|
||||
IconType?.let { iconType ->
|
||||
val iconValue = iconType.lowercase()
|
||||
// Apply the selected icon type to the overlay buttons.
|
||||
val commonResources = arrayOf(
|
||||
"ic_fullscreen_vertical_button.png",
|
||||
"ic_vr.png",
|
||||
@ -123,7 +126,7 @@ object OverlayButtonsPatch : BaseResourcePatch(
|
||||
"yt_outline_screen_full_exit_white_24.png",
|
||||
"yt_outline_screen_full_white_24.png"
|
||||
)
|
||||
val specificResources = if (iconValue == "thin") {
|
||||
val specificResources = if (iconType == "thin") {
|
||||
arrayOf("yt_outline_screen_vertical_vd_theme_24.xml")
|
||||
} else {
|
||||
arrayOf("yt_outline_screen_vertical_vd_theme_24.png")
|
||||
@ -132,11 +135,10 @@ object OverlayButtonsPatch : BaseResourcePatch(
|
||||
resources.forEach { resource ->
|
||||
val folderName = if (resource.endsWith(".xml")) "drawable" else "drawable-xxhdpi"
|
||||
context.copyResources(
|
||||
"youtube/overlaybuttons/$iconValue",
|
||||
"youtube/overlaybuttons/$iconType",
|
||||
ResourceGroup(folderName, resource)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Merge XML nodes from the host to their respective XML files.
|
||||
context.copyXmlNode(
|
||||
@ -145,9 +147,6 @@ object OverlayButtonsPatch : BaseResourcePatch(
|
||||
"android.support.constraint.ConstraintLayout"
|
||||
)
|
||||
|
||||
val marginBottom = BottomMargin
|
||||
?: DEFAULT_MARGIN
|
||||
|
||||
// Modify the layout of fullscreen button for newer YouTube versions (19.09.xx+)
|
||||
arrayOf(
|
||||
"youtube_controls_cf_fullscreen_button.xml",
|
||||
|
@ -18,6 +18,7 @@ import app.revanced.util.copyResources
|
||||
import app.revanced.util.copyXmlNode
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
import app.revanced.util.valueOrThrow
|
||||
import org.w3c.dom.Element
|
||||
import java.io.Closeable
|
||||
import java.util.concurrent.Executors
|
||||
@ -38,7 +39,7 @@ object SettingsPatch : BaseResourcePatch(
|
||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||
requiresIntegrations = true
|
||||
), Closeable {
|
||||
private const val DEFAULT_ELEMENT = "About"
|
||||
private const val DEFAULT_ELEMENT = "@string/about_key"
|
||||
private const val DEFAULT_NAME = "ReVanced Extended"
|
||||
|
||||
private val SETTINGS_ELEMENTS_MAP = mapOf(
|
||||
@ -63,10 +64,10 @@ object SettingsPatch : BaseResourcePatch(
|
||||
"Live chat" to "@string/live_chat_key",
|
||||
"Captions" to "@string/captions_key",
|
||||
"Accessibility" to "@string/accessibility_settings_key",
|
||||
DEFAULT_ELEMENT to "@string/about_key"
|
||||
"About" to DEFAULT_ELEMENT
|
||||
)
|
||||
|
||||
private val InsertPosition by stringPatchOption(
|
||||
private val InsertPosition = stringPatchOption(
|
||||
key = "InsertPosition",
|
||||
default = DEFAULT_ELEMENT,
|
||||
values = SETTINGS_ELEMENTS_MAP,
|
||||
@ -75,7 +76,7 @@ object SettingsPatch : BaseResourcePatch(
|
||||
required = true
|
||||
)
|
||||
|
||||
private val RVXSettingsMenuName by stringPatchOption(
|
||||
private val RVXSettingsMenuName = stringPatchOption(
|
||||
key = "RVXSettingsMenuName",
|
||||
default = DEFAULT_NAME,
|
||||
title = "RVX settings menu name",
|
||||
@ -83,6 +84,8 @@ object SettingsPatch : BaseResourcePatch(
|
||||
required = true
|
||||
)
|
||||
|
||||
private lateinit var customName: String
|
||||
|
||||
internal lateinit var contexts: ResourceContext
|
||||
internal var upward1831 = false
|
||||
internal var upward1834 = false
|
||||
@ -94,6 +97,15 @@ object SettingsPatch : BaseResourcePatch(
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
|
||||
/**
|
||||
* check patch options
|
||||
*/
|
||||
customName = RVXSettingsMenuName
|
||||
.valueOrThrow()
|
||||
|
||||
val insertKey = InsertPosition
|
||||
.valueOrThrow()
|
||||
|
||||
/**
|
||||
* set resource context
|
||||
*/
|
||||
@ -148,16 +160,10 @@ object SettingsPatch : BaseResourcePatch(
|
||||
/**
|
||||
* initialize ReVanced Extended Settings
|
||||
*/
|
||||
val elementKey = SETTINGS_ELEMENTS_MAP[InsertPosition]
|
||||
?: InsertPosition
|
||||
?: SETTINGS_ELEMENTS_MAP[DEFAULT_ELEMENT]
|
||||
|
||||
elementKey?.let { insertKey ->
|
||||
context.addPreferenceFragment(
|
||||
"revanced_extended_settings",
|
||||
insertKey
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* remove ReVanced Extended Settings divider
|
||||
@ -220,7 +226,6 @@ object SettingsPatch : BaseResourcePatch(
|
||||
* change RVX settings menu name
|
||||
* since it must be invoked after the Translations patch, it must be the last in the order.
|
||||
*/
|
||||
RVXSettingsMenuName?.let { customName ->
|
||||
if (customName != DEFAULT_NAME) {
|
||||
contexts.removeStringsElements(
|
||||
arrayOf("revanced_extended_settings_title")
|
||||
@ -241,8 +246,6 @@ object SettingsPatch : BaseResourcePatch(
|
||||
}
|
||||
}
|
||||
}
|
||||
} ?: println("WARNING: Invalid RVX settings menu name. RVX settings menu name does not change.")
|
||||
|
||||
}
|
||||
|
||||
private fun setVersionInfo() {
|
||||
|
@ -3,15 +3,27 @@
|
||||
package app.revanced.util
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.options.PatchOption
|
||||
import app.revanced.patcher.util.DomFileEditor
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.Node
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardCopyOption
|
||||
|
||||
val classLoader: ClassLoader = object {}.javaClass.classLoader
|
||||
|
||||
fun PatchOption<String>.valueOrThrow() = value
|
||||
?: throw PatchException("Invalid patch option: $title.")
|
||||
|
||||
fun PatchOption<String>.lowerCaseOrThrow() = valueOrThrow()
|
||||
.lowercase()
|
||||
|
||||
fun PatchOption<String>.underBarOrThrow() = lowerCaseOrThrow()
|
||||
.replace(" ", "_")
|
||||
|
||||
fun Node.adoptChild(tagName: String, block: Element.() -> Unit) {
|
||||
val child = ownerDocument.createElement(tagName)
|
||||
child.block()
|
||||
@ -48,6 +60,36 @@ fun String.startsWithAny(vararg prefixes: String): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
fun ResourceContext.copyFile(
|
||||
resourceGroup: List<ResourceGroup>,
|
||||
path: String,
|
||||
warning: String
|
||||
): Boolean {
|
||||
resourceGroup.let { resourceGroups ->
|
||||
try {
|
||||
val filePath = File(path)
|
||||
val resourceDirectory = this["res"]
|
||||
|
||||
resourceGroups.forEach { group ->
|
||||
val fromDirectory = filePath.resolve(group.resourceDirectoryName)
|
||||
val toDirectory = resourceDirectory.resolve(group.resourceDirectoryName)
|
||||
|
||||
group.resources.forEach { iconFileName ->
|
||||
Files.write(
|
||||
toDirectory.resolve(iconFileName).toPath(),
|
||||
fromDirectory.resolve(iconFileName).readBytes()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (_: Exception) {
|
||||
println(warning)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy resources from the current class loader to the resource directory.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user