From f3b92cab5a057ce605b6d9e75e3b99161bf1422c Mon Sep 17 00:00:00 2001 From: Sculas Date: Thu, 8 Sep 2022 11:55:06 +0200 Subject: [PATCH] feat: Theme Patch (#440) * feat: Theme Patch * refactor: deprecate AmoledPatch * Update src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/ThemePatch.kt Co-authored-by: oSumAtrIX * refactor: apply requested changes Co-authored-by: oSumAtrIX --- .../layout/amoled/patch/AmoledPatch.kt | 24 ++----- .../theme/annotations/ThemeCompatibility.kt | 9 +++ .../youtube/layout/theme/patch/ThemePatch.kt | 63 +++++++++++++++++++ 3 files changed, 77 insertions(+), 19 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/theme/annotations/ThemeCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/ThemePatch.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt index a969f6d8a..1e66caf7b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt @@ -2,16 +2,16 @@ package app.revanced.patches.youtube.layout.amoled.patch import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.PatchDeprecated import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.impl.ResourceData import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.impl.ResourcePatch import app.revanced.patches.youtube.layout.amoled.annotations.AmoledCompatibility +import app.revanced.patches.youtube.layout.theme.patch.ThemePatch import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch -import org.w3c.dom.Element @Patch @DependsOn([FixLocaleConfigErrorPatch::class]) @@ -19,24 +19,10 @@ import org.w3c.dom.Element @Description("Enables pure black theme.") @AmoledCompatibility @Version("0.0.1") +@PatchDeprecated("Theme patch already includes the Amoled theme.", ThemePatch::class) class AmoledPatch : ResourcePatch() { override fun execute(data: ResourceData): PatchResult { - data.xmlEditor["res/values/colors.xml"].use { editor -> - val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element - - for (i in 0 until resourcesNode.childNodes.length) { - val node = resourcesNode.childNodes.item(i) - if (node !is Element) continue - - val element = resourcesNode.childNodes.item(i) as Element - element.textContent = when (element.getAttribute("name")) { - "yt_black1", "yt_black1_opacity95", "yt_black2", "yt_black3", "yt_black4", "yt_status_bar_background_dark" -> "@android:color/black" - "yt_selected_nav_label_dark" -> "#ffdf0000" - else -> continue - } - } - } - - return PatchResultSuccess() + ThemePatch.theme = ThemePatch.Themes.Amoled.name + return ThemePatch().execute(data) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/annotations/ThemeCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/annotations/ThemeCompatibility.kt new file mode 100644 index 000000000..5bf335060 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/annotations/ThemeCompatibility.kt @@ -0,0 +1,9 @@ +package app.revanced.patches.youtube.layout.theme.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility([Package("com.google.android.youtube")]) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class ThemeCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/ThemePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/ThemePatch.kt new file mode 100644 index 000000000..0d1ca8431 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/ThemePatch.kt @@ -0,0 +1,63 @@ +package app.revanced.patches.youtube.layout.theme.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.impl.ResourceData +import app.revanced.patcher.patch.* +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.impl.ResourcePatch +import app.revanced.patches.youtube.layout.theme.annotations.ThemeCompatibility +import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch +import org.w3c.dom.Element + +@Patch +@DependsOn([FixLocaleConfigErrorPatch::class]) +@Name("theme") +@Description("Enables a custom theme.") +@ThemeCompatibility +@Version("0.0.1") +class ThemePatch : ResourcePatch() { + override fun execute(data: ResourceData): PatchResult { + val theme = Themes.of(theme) ?: return PatchResultError("Theme '$theme' not found.") + + data.xmlEditor["res/values/colors.xml"].use { editor -> + val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element + + for (i in 0 until resourcesNode.childNodes.length) { + val node = resourcesNode.childNodes.item(i) as? Element ?: continue + node.textContent = theme.apply(node.getAttribute("name")) ?: continue + } + } + + return PatchResultSuccess() + } + + companion object : OptionsContainer() { + var theme: String by PatchOption.StringListOption( + key = "theme", + default = null, + options = Themes.names, + title = "Theme", + description = "Select a theme.", + required = true + ) + } + + enum class Themes(val apply: (String) -> String?) { + Amoled({ attr -> + when (attr) { + "yt_black1", "yt_black1_opacity95", "yt_black2", "yt_black3", "yt_black4", "yt_status_bar_background_dark" -> "@android:color/black" + "yt_selected_nav_label_dark" -> "#ffdf0000" + else -> null + } + }); + + companion object { + val names = values().map { it.name } + + fun of(name: String) = values().firstOrNull { it.name == name } + } + } +} \ No newline at end of file