From 3b8bc08d4ed3a3a0f96d2f476e5059840b9f9d9b Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 20 Feb 2024 22:30:26 +0100 Subject: [PATCH] feat(YouTube - Change header): Improve patch option description --- .../branding/header/ChangeHeaderPatch.kt | 107 ++++++++++-------- 1 file changed, 60 insertions(+), 47 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt index 6f1e76a07..f02b982df 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt @@ -15,62 +15,69 @@ import java.io.File name = "Change header", description = "Applies a custom header in the top left corner within the app. Defaults to the ReVanced header.", compatiblePackages = [ - CompatiblePackage("com.google.android.youtube") + CompatiblePackage("com.google.android.youtube"), ], - use = false + use = false, ) @Suppress("unused") object ChangeHeaderPatch : ResourcePatch() { - private const val HEADER_NAME = "yt_wordmark_header" - private const val PREMIUM_HEADER_NAME = "yt_premium_wordmark_header" - private const val REVANCED_HEADER_NAME = "ReVanced" - private const val REVANCED_BORDERLESS_HEADER_NAME = "ReVanced (borderless logo)" + private const val HEADER_FILE_NAME = "yt_wordmark_header" + private const val PREMIUM_HEADER_FILE_NAME = "yt_premium_wordmark_header" - private val targetResourceDirectoryNames = arrayOf( - "xxxhdpi", - "xxhdpi", - "xhdpi", - "mdpi", - "hdpi", - ).map { dpi -> - "drawable-$dpi" - } + private const val HEADER_OPTION = "header*" + private const val PREMIUM_HEADER_OPTION = "premium*header" + private const val REVANCED_HEADER_OPTION = "revanced*" + private const val REVANCED_BORDERLESS_HEADER_OPTION = "revanced*borderless" + + private val targetResourceDirectoryNames = 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 header by stringPatchOption( key = "header", - default = REVANCED_BORDERLESS_HEADER_NAME, + default = REVANCED_BORDERLESS_HEADER_OPTION, values = mapOf( - "YouTube" to HEADER_NAME, - "YouTube Premium" to PREMIUM_HEADER_NAME, - "ReVanced" to REVANCED_HEADER_NAME, - "ReVanced (borderless logo)" to REVANCED_BORDERLESS_HEADER_NAME, + "YouTube" to HEADER_OPTION, + "YouTube Premium" to PREMIUM_HEADER_OPTION, + "ReVanced" to REVANCED_HEADER_OPTION, + "ReVanced (borderless logo)" to REVANCED_BORDERLESS_HEADER_OPTION, ), title = "Header", description = """ - Either a header name or a path to a custom header folder to use in the top bar. - The path to a folder must contain one or more of the following folders matching the DPI of your device: + 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: + + ${targetResourceDirectoryNames.keys.joinToString("\n") { "- $it" }} + + Each of the folders must contain all of the following files: + + ${variants.joinToString("\n") { variant -> "- ${HEADER_FILE_NAME}_$variant.png" }} - ${targetResourceDirectoryNames.joinToString("\n") { "- $it" }} - - These folders must contain the following files: - - ${variants.joinToString("\n") { variant -> "- ${HEADER_NAME}_$variant.png" }} + The image dimensions must be as follows: + ${targetResourceDirectoryNames.map { (dpi, dim) -> "- $dpi: $dim" }.joinToString("\n")} """.trimIndentMultiline(), required = true, ) override fun execute(context: ResourceContext) { // The directories to copy the header to. - val targetResourceDirectories = targetResourceDirectoryNames.mapNotNull { + val targetResourceDirectories = targetResourceDirectoryNames.keys.mapNotNull { context["res"].resolve(it).takeIf(File::exists) } // The files to replace in the target directories. - val targetResourceFiles = targetResourceDirectoryNames.map { directoryName -> + val targetResourceFiles = targetResourceDirectoryNames.keys.map { directoryName -> ResourceGroup( directoryName, - *variants.map { variant -> "${HEADER_NAME}_$variant.png" }.toTypedArray() + *variants.map { variant -> "${HEADER_FILE_NAME}_$variant.png" }.toTypedArray(), ) } @@ -89,8 +96,8 @@ object ChangeHeaderPatch : ResourcePatch() { } // Functions to overwrite the header to the different variants. - val toPremium = { overwriteFromTo(PREMIUM_HEADER_NAME, HEADER_NAME) } - val toHeader = { overwriteFromTo(HEADER_NAME, PREMIUM_HEADER_NAME) } + val toPremium = { overwriteFromTo(PREMIUM_HEADER_FILE_NAME, HEADER_FILE_NAME) } + val toHeader = { overwriteFromTo(HEADER_FILE_NAME, PREMIUM_HEADER_FILE_NAME) } val toReVanced = { // Copy the ReVanced header to the resource directories. targetResourceFiles.forEach { context.copyResources("change-header/revanced", it) } @@ -106,32 +113,38 @@ object ChangeHeaderPatch : ResourcePatch() { toHeader() } val toCustom = { - var copiedReplacementImages = false - // For all the resource groups in the custom header folder, copy them to the resource directories. - File(header!!).listFiles { file -> file.isDirectory }?.forEach { folder -> - val targetDirectory = context["res"].resolve(folder.name) - // Skip if the target directory (DPI) doesn't exist. - if (!targetDirectory.exists()) return@forEach + val sourceFolders = File(header!!).listFiles { file -> file.isDirectory } + ?: throw PatchException("The provided path is not a directory: $header") - folder.listFiles { file -> file.isFile }?.forEach { - val targetResourceFile = targetDirectory.resolve(it.name) + var copiedFiles = false - it.copyTo(targetResourceFile, true) - copiedReplacementImages = true + // For each source folder, copy the files to the target resource directories. + sourceFolders.forEach { dpiSourceFolder -> + val targetDpiFolder = context["res"].resolve(dpiSourceFolder.name) + if (!targetDpiFolder.exists()) return@forEach + + val imgSourceFiles = dpiSourceFolder.listFiles { file -> file.isFile }!! + imgSourceFiles.forEach { imgSourceFile -> + val imgTargetFile = targetDpiFolder.resolve(imgSourceFile.name) + imgSourceFile.copyTo(imgTargetFile, true) + + copiedFiles = true } } - if (!copiedReplacementImages) throw PatchException("Could not find any custom images resources in directory: $header") + if (!copiedFiles) { + throw PatchException("No header files were copied from the provided path: $header.") + } // Overwrite the premium with the custom header as well. toHeader() } when (header) { - HEADER_NAME -> toHeader - PREMIUM_HEADER_NAME -> toPremium - REVANCED_HEADER_NAME -> toReVanced - REVANCED_BORDERLESS_HEADER_NAME -> toReVancedBorderless + HEADER_OPTION -> toHeader + PREMIUM_HEADER_OPTION -> toPremium + REVANCED_HEADER_OPTION -> toReVanced + REVANCED_BORDERLESS_HEADER_OPTION -> toReVancedBorderless else -> toCustom }() }