fix(YouTube - Custom branding icon): Patch option restoreOldSplashAnimation not working in YouTube 19.32.39+

This commit is contained in:
inotia00
2024-12-21 14:00:38 +09:00
parent 6f84f0a0b8
commit e48048b430
9 changed files with 138 additions and 115 deletions

View File

@ -13,15 +13,14 @@ import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus
import app.revanced.patches.music.utils.settings.settingsPatch import app.revanced.patches.music.utils.settings.settingsPatch
import app.revanced.util.ResourceGroup import app.revanced.util.ResourceGroup
import app.revanced.util.Utils.trimIndentMultiline import app.revanced.util.Utils.trimIndentMultiline
import app.revanced.util.copyAdaptiveIcon
import app.revanced.util.copyResources import app.revanced.util.copyResources
import app.revanced.util.getAdaptiveIconResourceFile
import app.revanced.util.getResourceGroup import app.revanced.util.getResourceGroup
import app.revanced.util.underBarOrThrow import app.revanced.util.underBarOrThrow
import app.revanced.util.valueOrThrow import app.revanced.util.valueOrThrow
import org.w3c.dom.Element import org.w3c.dom.Element
import java.io.File import java.io.File
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.StandardCopyOption
private const val ADAPTIVE_ICON_BACKGROUND_FILE_NAME = private const val ADAPTIVE_ICON_BACKGROUND_FILE_NAME =
"adaptiveproduct_youtube_music_background_color_108" "adaptiveproduct_youtube_music_background_color_108"
@ -251,31 +250,11 @@ val customBrandingIconPatch = resourcePatch(
return@execute return@execute
} }
mapOf( copyAdaptiveIcon(
ADAPTIVE_ICON_BACKGROUND_FILE_NAME to getAdaptiveIconResourceFile( ADAPTIVE_ICON_BACKGROUND_FILE_NAME,
"res/mipmap-anydpi/ic_launcher_release.xml", ADAPTIVE_ICON_FOREGROUND_FILE_NAME,
"background" mipmapDirectories
), )
ADAPTIVE_ICON_FOREGROUND_FILE_NAME to getAdaptiveIconResourceFile(
"res/mipmap-anydpi/ic_launcher_release.xml",
"foreground"
)
).forEach { (oldIconResourceFile, newIconResourceFile) ->
if (oldIconResourceFile != newIconResourceFile) {
mipmapDirectories.forEach {
val mipmapDirectory = resourceDirectory.resolve(it)
Files.move(
mipmapDirectory
.resolve("$oldIconResourceFile.png")
.toPath(),
mipmapDirectory
.resolve("$newIconResourceFile.png")
.toPath(),
StandardCopyOption.REPLACE_EXISTING
)
}
}
}
// endregion // endregion
} }

View File

@ -5,27 +5,27 @@ import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.stringOption import app.revanced.patcher.patch.stringOption
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.patch.PatchList.CUSTOM_BRANDING_ICON_FOR_YOUTUBE import app.revanced.patches.youtube.utils.patch.PatchList.CUSTOM_BRANDING_ICON_FOR_YOUTUBE
import app.revanced.patches.youtube.utils.playservice.is_19_17_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_32_or_greater
import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
import app.revanced.patches.youtube.utils.settings.ResourceUtils.updatePatchStatusIcon import app.revanced.patches.youtube.utils.settings.ResourceUtils.updatePatchStatusIcon
import app.revanced.patches.youtube.utils.settings.settingsPatch import app.revanced.patches.youtube.utils.settings.settingsPatch
import app.revanced.util.ResourceGroup import app.revanced.util.ResourceGroup
import app.revanced.util.Utils.trimIndentMultiline import app.revanced.util.Utils.trimIndentMultiline
import app.revanced.util.copyAdaptiveIcon
import app.revanced.util.copyFile import app.revanced.util.copyFile
import app.revanced.util.copyResources import app.revanced.util.copyResources
import app.revanced.util.copyXmlNode
import app.revanced.util.getAdaptiveIconResourceFile
import app.revanced.util.getResourceGroup import app.revanced.util.getResourceGroup
import app.revanced.util.underBarOrThrow import app.revanced.util.underBarOrThrow
import app.revanced.util.valueOrThrow import app.revanced.util.valueOrThrow
import java.nio.file.Files import org.w3c.dom.Element
import java.nio.file.StandardCopyOption
private const val ADAPTIVE_ICON_BACKGROUND_FILE_NAME = private const val ADAPTIVE_ICON_BACKGROUND_FILE_NAME =
"adaptiveproduct_youtube_background_color_108" "adaptiveproduct_youtube_background_color_108"
private const val ADAPTIVE_ICON_FOREGROUND_FILE_NAME = private const val ADAPTIVE_ICON_FOREGROUND_FILE_NAME =
"adaptiveproduct_youtube_foreground_color_108" "adaptiveproduct_youtube_foreground_color_108"
private const val ADAPTIVE_ICON_MONOCHROME_FILE_NAME =
"adaptive_monochrome_ic_youtube_launcher"
private const val DEFAULT_ICON = "revancify_blue" private const val DEFAULT_ICON = "revancify_blue"
private val availableIcon = mapOf( private val availableIcon = mapOf(
@ -99,7 +99,6 @@ val customBrandingIconPatch = resourcePatch(
versionCheckPatch, versionCheckPatch,
) )
val appIconOption = stringOption( val appIconOption = stringOption(
key = "appIcon", key = "appIcon",
default = DEFAULT_ICON, default = DEFAULT_ICON,
@ -131,7 +130,7 @@ val customBrandingIconPatch = resourcePatch(
key = "restoreOldSplashAnimation", key = "restoreOldSplashAnimation",
default = true, default = true,
title = "Restore old splash animation", title = "Restore old splash animation",
description = "Restore the old style splash animation. Supports from YouTube 18.29.38 to YouTube 19.16.39.", description = "Restore the old style splash animation.",
required = true, required = true,
) )
@ -164,7 +163,7 @@ val customBrandingIconPatch = resourcePatch(
arrayOf( arrayOf(
ResourceGroup( ResourceGroup(
"drawable", "drawable",
"adaptive_monochrome_ic_youtube_launcher.xml" "$ADAPTIVE_ICON_MONOCHROME_FILE_NAME.xml"
) )
).forEach { resourceGroup -> ).forEach { resourceGroup ->
copyResources("$appIconResourcePath/monochrome", resourceGroup) copyResources("$appIconResourcePath/monochrome", resourceGroup)
@ -177,30 +176,72 @@ val customBrandingIconPatch = resourcePatch(
copyResources("$appIconResourcePath/splash", it) copyResources("$appIconResourcePath/splash", it)
} }
} }
document("res/values/styles.xml").use { document ->
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
val childNodes = resourcesNode.childNodes
for (i in 0 until childNodes.length) {
val node = childNodes.item(i) as? Element ?: continue
val nodeAttributeName = node.getAttribute("name")
if (nodeAttributeName.startsWith("Theme.YouTube.Launcher")) {
val style = document.createElement("style")
style.setAttribute("name", nodeAttributeName)
style.setAttribute("parent", "@style/Base.Theme.YouTube.Launcher")
resourcesNode.removeChild(node)
resourcesNode.appendChild(style)
}
}
}
} }
// Change splash screen. // Change splash screen.
if (restoreOldSplashAnimationOption == true) { if (restoreOldSplashAnimationOption == true) {
if (!is_19_17_or_greater) { oldSplashAnimationResourceGroups.let { resourceGroups ->
oldSplashAnimationResourceGroups.let { resourceGroups -> resourceGroups.forEach {
resourceGroups.forEach { copyResources("$appIconResourcePath/splash", it)
copyResources("$appIconResourcePath/splash", it)
}
} }
}
copyXmlNode( val styleMap = mutableMapOf<String, String>()
"$appIconResourcePath/splash", styleMap["Base.Theme.YouTube.Launcher"] = "@style/Theme.AppCompat.DayNight.NoActionBar"
"values-v31/styles.xml",
"resources" if (is_19_32_or_greater) {
) styleMap["Theme.YouTube.Home"] = "@style/Base.V27.Theme.YouTube.Home"
} else { }
println("WARNING: \"Restore old splash animation\" is not supported in this version. Use YouTube 19.16.39 or earlier.")
styleMap.forEach { (nodeAttributeName, nodeAttributeParent) ->
document("res/values-v31/styles.xml").use { document ->
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
val style = document.createElement("style")
style.setAttribute("name", nodeAttributeName)
style.setAttribute("parent", nodeAttributeParent)
val primaryItem = document.createElement("item")
primaryItem.setAttribute("name", "android:windowSplashScreenAnimatedIcon")
primaryItem.textContent = "@drawable/avd_anim"
val secondaryItem = document.createElement("item")
secondaryItem.setAttribute("name", "android:windowSplashScreenAnimationDuration")
secondaryItem.textContent = if (appIcon.startsWith("revancify"))
"1500"
else
"1000"
style.appendChild(primaryItem)
style.appendChild(secondaryItem)
resourcesNode.appendChild(style)
}
} }
} }
updatePatchStatusIcon(appIcon) updatePatchStatusIcon(appIcon)
} }
// region fix app icon
if (!is_19_34_or_greater) { if (!is_19_34_or_greater) {
return@execute return@execute
} }
@ -208,30 +249,14 @@ val customBrandingIconPatch = resourcePatch(
return@execute return@execute
} }
mapOf( copyAdaptiveIcon(
ADAPTIVE_ICON_BACKGROUND_FILE_NAME to getAdaptiveIconResourceFile( ADAPTIVE_ICON_BACKGROUND_FILE_NAME,
"res/mipmap-anydpi/ic_launcher.xml", ADAPTIVE_ICON_FOREGROUND_FILE_NAME,
"background" mipmapDirectories,
), ADAPTIVE_ICON_MONOCHROME_FILE_NAME
ADAPTIVE_ICON_FOREGROUND_FILE_NAME to getAdaptiveIconResourceFile( )
"res/mipmap-anydpi/ic_launcher.xml",
"foreground" // endregion
)
).forEach { (oldIconResourceFile, newIconResourceFile) ->
if (oldIconResourceFile != newIconResourceFile) {
mipmapDirectories.forEach {
val mipmapDirectory = get("res").resolve(it)
Files.copy(
mipmapDirectory
.resolve("$oldIconResourceFile.png")
.toPath(),
mipmapDirectory
.resolve("$newIconResourceFile.png")
.toPath(),
StandardCopyOption.REPLACE_EXISTING
)
}
}
}
} }
} }

View File

@ -59,7 +59,18 @@ fun List<String>.getResourceGroup(fileNames: Array<String>) = map { directory ->
) )
} }
fun ResourcePatchContext.getAdaptiveIconResourceFile(path: String, tag: String): String { private fun ResourcePatchContext.getMipMapPath(): String {
var path: String
document("AndroidManifest.xml").use { document ->
val manifestElement = document.getNode("application") as Element
val mipmapResourceFile = manifestElement.getAttribute("android:icon").split("/")[1]
path = "res/mipmap-anydpi/$mipmapResourceFile.xml"
}
return path
}
private fun ResourcePatchContext.getAdaptiveIconResourceFile(tag: String): String {
val path = getMipMapPath()
document(path).use { document -> document(path).use { document ->
val adaptiveIcon = document val adaptiveIcon = document
.getElementsByTagName("adaptive-icon") .getElementsByTagName("adaptive-icon")
@ -76,6 +87,56 @@ fun ResourcePatchContext.getAdaptiveIconResourceFile(path: String, tag: String):
} }
} }
private fun ResourcePatchContext.getAdaptiveIconBackgroundResourceFile() =
getAdaptiveIconResourceFile("background")
private fun ResourcePatchContext.getAdaptiveIconForegroundResourceFile() =
getAdaptiveIconResourceFile("foreground")
private fun ResourcePatchContext.getAdaptiveIconMonoChromeResourceFile() =
getAdaptiveIconResourceFile("monochrome")
fun ResourcePatchContext.copyAdaptiveIcon(
adaptiveIconBackgroundFileName: String,
adaptiveIconForegroundFileName: String,
mipmapDirectories: List<String>,
adaptiveIconMonoChromeFileName: String? = null,
) {
mapOf(
adaptiveIconBackgroundFileName to getAdaptiveIconBackgroundResourceFile(),
adaptiveIconForegroundFileName to getAdaptiveIconForegroundResourceFile()
).forEach { (oldIconResourceFile, newIconResourceFile) ->
if (oldIconResourceFile != newIconResourceFile) {
mipmapDirectories.forEach {
val mipmapDirectory = get("res").resolve(it)
Files.copy(
mipmapDirectory
.resolve("$oldIconResourceFile.png")
.toPath(),
mipmapDirectory
.resolve("$newIconResourceFile.png")
.toPath(),
StandardCopyOption.REPLACE_EXISTING
)
}
}
}
if (adaptiveIconMonoChromeFileName != null &&
adaptiveIconMonoChromeFileName != getAdaptiveIconMonoChromeResourceFile()) {
val drawableDirectory = get("res").resolve("drawable")
Files.copy(
drawableDirectory
.resolve("$adaptiveIconMonoChromeFileName.xml")
.toPath(),
drawableDirectory
.resolve("${getAdaptiveIconMonoChromeResourceFile()}.xml")
.toPath(),
StandardCopyOption.REPLACE_EXISTING
)
}
}
fun ResourcePatchContext.appendAppVersion(appVersion: String) { fun ResourcePatchContext.appendAppVersion(appVersion: String) {
addEntryValues( addEntryValues(
"revanced_spoof_app_version_target_entries", "revanced_spoof_app_version_target_entries",

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Base.Theme.YouTube.Launcher" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowSplashScreenAnimatedIcon">@drawable/avd_anim</item>
<item name="android:windowSplashScreenAnimationDuration">1000</item>
</style>
</resources>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Base.Theme.YouTube.Launcher" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowSplashScreenAnimatedIcon">@drawable/avd_anim</item>
<item name="android:windowSplashScreenAnimationDuration">1000</item>
</style>
</resources>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Base.Theme.YouTube.Launcher" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowSplashScreenAnimatedIcon">@drawable/avd_anim</item>
<item name="android:windowSplashScreenAnimationDuration">1000</item>
</style>
</resources>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Base.Theme.YouTube.Launcher" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowSplashScreenAnimatedIcon">@drawable/avd_anim</item>
<item name="android:windowSplashScreenAnimationDuration">1500</item>
</style>
</resources>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Base.Theme.YouTube.Launcher" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowSplashScreenAnimatedIcon">@drawable/avd_anim</item>
<item name="android:windowSplashScreenAnimationDuration">1500</item>
</style>
</resources>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Base.Theme.YouTube.Launcher" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowSplashScreenAnimatedIcon">@drawable/avd_anim</item>
<item name="android:windowSplashScreenAnimationDuration">1000</item>
</style>
</resources>