mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-09 11:04:36 +02:00
feat(YouTube): split Custom header for YouTube
patch from the Custom branding icon for YouTube
patch
This commit is contained in:
parent
1e85df5fc5
commit
175f721cfd
@ -44,25 +44,6 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
|||||||
|
|
||||||
private val mipmapDirectories = sizeArray.map { "mipmap-$it" }
|
private val mipmapDirectories = sizeArray.map { "mipmap-$it" }
|
||||||
|
|
||||||
private val headerResourceDirectoryNames = mapOf(
|
|
||||||
"xxxhdpi" to "512px x 192px",
|
|
||||||
"xxhdpi" to "387px x 144px",
|
|
||||||
"xhdpi" to "258px x 96px",
|
|
||||||
"hdpi" to "194px x 72px",
|
|
||||||
"mdpi" to "129px x 48px",
|
|
||||||
).map { (dpi, dim) ->
|
|
||||||
"drawable-$dpi" to dim
|
|
||||||
}.toMap()
|
|
||||||
|
|
||||||
private val variants = arrayOf("light", "dark")
|
|
||||||
|
|
||||||
private val headerIconResourceFileNames = arrayOf(
|
|
||||||
"yt_premium_wordmark_header_dark",
|
|
||||||
"yt_premium_wordmark_header_light",
|
|
||||||
"yt_wordmark_header_dark",
|
|
||||||
"yt_wordmark_header_light"
|
|
||||||
).map { "$it.png" }.toTypedArray()
|
|
||||||
|
|
||||||
private val launcherIconResourceFileNames = arrayOf(
|
private val launcherIconResourceFileNames = arrayOf(
|
||||||
"adaptiveproduct_youtube_background_color_108",
|
"adaptiveproduct_youtube_background_color_108",
|
||||||
"adaptiveproduct_youtube_foreground_color_108",
|
"adaptiveproduct_youtube_foreground_color_108",
|
||||||
@ -98,8 +79,6 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val headerIconResourceGroups = drawableDirectories.getResourceGroup(headerIconResourceFileNames)
|
|
||||||
|
|
||||||
private val launcherIconResourceGroups = mipmapDirectories.getResourceGroup(launcherIconResourceFileNames)
|
private val launcherIconResourceGroups = mipmapDirectories.getResourceGroup(launcherIconResourceFileNames)
|
||||||
|
|
||||||
private val splashIconResourceGroups = drawableDirectories.getResourceGroup(splashIconResourceFileNames)
|
private val splashIconResourceGroups = drawableDirectories.getResourceGroup(splashIconResourceFileNames)
|
||||||
@ -127,35 +106,6 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
|||||||
required = true
|
required = true
|
||||||
)
|
)
|
||||||
|
|
||||||
private val ChangeHeader by booleanPatchOption(
|
|
||||||
key = "ChangeHeader",
|
|
||||||
default = false,
|
|
||||||
title = "Change header",
|
|
||||||
description = "Apply the custom branding icon to the header.",
|
|
||||||
required = true
|
|
||||||
)
|
|
||||||
|
|
||||||
private val CustomHeader by stringPatchOption(
|
|
||||||
key = "CustomHeader",
|
|
||||||
default = "",
|
|
||||||
title = "Custom header",
|
|
||||||
description = """
|
|
||||||
The header to apply to the app.
|
|
||||||
|
|
||||||
If a path to a folder is provided, the folder must contain one or more of the following folders, depending on the DPI of the device:
|
|
||||||
|
|
||||||
${headerResourceDirectoryNames.keys.joinToString("\n") { "- $it" }}
|
|
||||||
|
|
||||||
Each of the folders must contain all of the following files:
|
|
||||||
|
|
||||||
${headerIconResourceFileNames.joinToString("\n") { "- $it" }}
|
|
||||||
|
|
||||||
The image dimensions must be as follows:
|
|
||||||
${headerResourceDirectoryNames.map { (dpi, dim) -> "- $dpi: $dim" }.joinToString("\n")}
|
|
||||||
""".trimIndentMultiline(),
|
|
||||||
required = true
|
|
||||||
)
|
|
||||||
|
|
||||||
private val ChangeSplashIcon by booleanPatchOption(
|
private val ChangeSplashIcon by booleanPatchOption(
|
||||||
key = "ChangeSplashIcon",
|
key = "ChangeSplashIcon",
|
||||||
default = true,
|
default = true,
|
||||||
@ -210,27 +160,6 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
|||||||
context.copyResources("$appIconResourcePath/monochrome", resourceGroup)
|
context.copyResources("$appIconResourcePath/monochrome", resourceGroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change header.
|
|
||||||
if (ChangeHeader == true) {
|
|
||||||
CustomHeader?.let { customHeader ->
|
|
||||||
var copiedFiles = false
|
|
||||||
if (customHeader.isNotEmpty()) {
|
|
||||||
copiedFiles = context.copyFile(
|
|
||||||
headerIconResourceGroups,
|
|
||||||
customHeader,
|
|
||||||
"WARNING: Invalid header path: $customHeader. Does not apply patches."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (!copiedFiles) {
|
|
||||||
headerIconResourceGroups.let { resourceGroups ->
|
|
||||||
resourceGroups.forEach {
|
|
||||||
context.copyResources("$appIconResourcePath/header", it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change splash icon.
|
// Change splash icon.
|
||||||
if (ChangeSplashIcon == true) {
|
if (ChangeSplashIcon == true) {
|
||||||
splashIconResourceGroups.let { resourceGroups ->
|
splashIconResourceGroups.let { resourceGroups ->
|
||||||
|
@ -0,0 +1,126 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.header
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||||
|
import app.revanced.patches.youtube.utils.compatibility.Constants
|
||||||
|
import app.revanced.patches.youtube.utils.settings.ResourceUtils
|
||||||
|
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.patch.BaseResourcePatch
|
||||||
|
import app.revanced.util.underBarOrThrow
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
object ChangeHeaderPatch : BaseResourcePatch(
|
||||||
|
name = "Custom header for YouTube",
|
||||||
|
description = "Applies a custom header in the top left corner within the app.",
|
||||||
|
compatiblePackages = Constants.COMPATIBLE_PACKAGE,
|
||||||
|
use = false,
|
||||||
|
) {
|
||||||
|
private const val GENERIC_HEADER_FILE_NAME = "yt_wordmark_header"
|
||||||
|
private const val PREMIUM_HEADER_FILE_NAME = "yt_premium_wordmark_header"
|
||||||
|
|
||||||
|
private const val DEFAULT_HEADER_KEY = "Custom branding icon"
|
||||||
|
private const val DEFAULT_HEADER_VALUE = "custom_branding_icon"
|
||||||
|
|
||||||
|
private val genericHeaderResourceDirectoryNames = mapOf(
|
||||||
|
"xxxhdpi" to "488px x 192px",
|
||||||
|
"xxhdpi" to "366px x 144px",
|
||||||
|
"xhdpi" to "244px x 96px",
|
||||||
|
"hdpi" to "184px x 72px",
|
||||||
|
"mdpi" to "122px x 48px",
|
||||||
|
).map { (dpi, dim) ->
|
||||||
|
"drawable-$dpi" to dim
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
|
private val premiumHeaderResourceDirectoryNames = mapOf(
|
||||||
|
"xxxhdpi" to "516px x 192px",
|
||||||
|
"xxhdpi" to "387px x 144px",
|
||||||
|
"xhdpi" to "258px x 96px",
|
||||||
|
"hdpi" to "194px x 72px",
|
||||||
|
"mdpi" to "129px x 48px",
|
||||||
|
).map { (dpi, dim) ->
|
||||||
|
"drawable-$dpi" to dim
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
|
private val variants = arrayOf("light", "dark")
|
||||||
|
|
||||||
|
private val headerIconResourceGroups =
|
||||||
|
premiumHeaderResourceDirectoryNames.keys.map { directory ->
|
||||||
|
ResourceGroup(
|
||||||
|
directory,
|
||||||
|
*variants.map { variant -> "${GENERIC_HEADER_FILE_NAME}_$variant.png" }.toTypedArray(),
|
||||||
|
*variants.map { variant -> "${PREMIUM_HEADER_FILE_NAME}_$variant.png" }.toTypedArray(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val CustomHeader = stringPatchOption(
|
||||||
|
key = "CustomHeader",
|
||||||
|
default = DEFAULT_HEADER_VALUE,
|
||||||
|
values = mapOf(
|
||||||
|
DEFAULT_HEADER_KEY to DEFAULT_HEADER_VALUE
|
||||||
|
),
|
||||||
|
title = "Custom header",
|
||||||
|
description = """
|
||||||
|
The header to apply to the app.
|
||||||
|
|
||||||
|
Patch option '$DEFAULT_HEADER_KEY' applies only when:
|
||||||
|
|
||||||
|
1. Patch 'Custom branding icon for YouTube' is included.
|
||||||
|
2. Patch option for 'Custom branding icon for YouTube' is selected from the preset.
|
||||||
|
|
||||||
|
If a path to a folder is provided, the folder must contain one or more of the following folders, depending on the DPI of the device:
|
||||||
|
|
||||||
|
${premiumHeaderResourceDirectoryNames.keys.joinToString("\n") { "- $it" }}
|
||||||
|
|
||||||
|
Each of the folders must contain all of the following files:
|
||||||
|
|
||||||
|
[Generic header]
|
||||||
|
|
||||||
|
${variants.joinToString("\n") { variant -> "- ${GENERIC_HEADER_FILE_NAME}_$variant.png" }}
|
||||||
|
|
||||||
|
The image dimensions must be as follows:
|
||||||
|
|
||||||
|
${genericHeaderResourceDirectoryNames.map { (dpi, dim) -> "- $dpi: $dim" }.joinToString("\n")}
|
||||||
|
|
||||||
|
[Premium header]
|
||||||
|
|
||||||
|
${variants.joinToString("\n") { variant -> "- ${PREMIUM_HEADER_FILE_NAME}_$variant.png" }}
|
||||||
|
|
||||||
|
The image dimensions must be as follows:
|
||||||
|
${premiumHeaderResourceDirectoryNames.map { (dpi, dim) -> "- $dpi: $dim" }.joinToString("\n")}
|
||||||
|
""".trimIndentMultiline(),
|
||||||
|
required = true,
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun execute(context: ResourceContext) {
|
||||||
|
|
||||||
|
// Check patch options first.
|
||||||
|
val customHeader = CustomHeader
|
||||||
|
.underBarOrThrow()
|
||||||
|
|
||||||
|
val customBrandingIconType = ResourceUtils.getIconType()
|
||||||
|
val customBrandingIconIncluded =
|
||||||
|
customBrandingIconType != "default" && customBrandingIconType != "custom"
|
||||||
|
|
||||||
|
val warnings = "WARNING: Invalid header path: $customHeader. Does not apply patches."
|
||||||
|
|
||||||
|
if (customHeader != DEFAULT_HEADER_VALUE) {
|
||||||
|
context.copyFile(
|
||||||
|
headerIconResourceGroups,
|
||||||
|
customHeader,
|
||||||
|
warnings
|
||||||
|
)
|
||||||
|
} else if (customBrandingIconIncluded) {
|
||||||
|
headerIconResourceGroups.let { resourceGroups ->
|
||||||
|
resourceGroups.forEach {
|
||||||
|
context.copyResources("youtube/branding/$customBrandingIconType/header", it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println(warnings)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,9 @@ object ResourceUtils {
|
|||||||
|
|
||||||
var youtubePackageName = "com.google.android.youtube"
|
var youtubePackageName = "com.google.android.youtube"
|
||||||
|
|
||||||
|
private var iconType = "default"
|
||||||
|
fun getIconType() = iconType
|
||||||
|
|
||||||
fun ResourceContext.updatePackageName(
|
fun ResourceContext.updatePackageName(
|
||||||
fromPackageName: String,
|
fromPackageName: String,
|
||||||
toPackageName: String
|
toPackageName: String
|
||||||
@ -72,6 +75,7 @@ object ResourceUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun ResourceContext.updatePatchStatusIcon(iconName: String) {
|
fun ResourceContext.updatePatchStatusIcon(iconName: String) {
|
||||||
|
iconType = iconName
|
||||||
updatePatchStatusSettings("Icon", "@string/revanced_icon_$iconName")
|
updatePatchStatusSettings("Icon", "@string/revanced_icon_$iconName")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user