@@ -15,62 +15,69 @@ import java.io.File
1515 name = " Change header" ,
1616 description = " Applies a custom header in the top left corner within the app. Defaults to the ReVanced header." ,
1717 compatiblePackages = [
18- CompatiblePackage (" com.google.android.youtube" )
18+ CompatiblePackage (" com.google.android.youtube" ),
1919 ],
20- use = false
20+ use = false ,
2121)
2222@Suppress(" unused" )
2323object ChangeHeaderPatch : ResourcePatch() {
24- private const val HEADER_NAME = " yt_wordmark_header"
25- private const val PREMIUM_HEADER_NAME = " yt_premium_wordmark_header"
26- private const val REVANCED_HEADER_NAME = " ReVanced"
27- private const val REVANCED_BORDERLESS_HEADER_NAME = " ReVanced (borderless logo)"
28-
29- private val targetResourceDirectoryNames = arrayOf(
30- " xxxhdpi" ,
31- " xxhdpi" ,
32- " xhdpi" ,
33- " mdpi" ,
34- " hdpi" ,
35- ).map { dpi ->
36- " drawable-$dpi "
37- }
24+ private const val HEADER_FILE_NAME = " yt_wordmark_header"
25+ private const val PREMIUM_HEADER_FILE_NAME = " yt_premium_wordmark_header"
26+
27+ private const val HEADER_OPTION = " header*"
28+ private const val PREMIUM_HEADER_OPTION = " premium*header"
29+ private const val REVANCED_HEADER_OPTION = " revanced*"
30+ private const val REVANCED_BORDERLESS_HEADER_OPTION = " revanced*borderless"
31+
32+ private val targetResourceDirectoryNames = mapOf (
33+ " xxxhdpi" to " 512px x 192px" ,
34+ " xxhdpi" to " 387px x 144px" ,
35+ " xhdpi" to " 258px x 96px" ,
36+ " hdpi" to " 194px x 72px" ,
37+ " mdpi" to " 129px x 48px" ,
38+ ).map { (dpi, dim) ->
39+ " drawable-$dpi " to dim
40+ }.toMap()
3841
3942 private val variants = arrayOf(" light" , " dark" )
4043
4144 private val header by stringPatchOption(
4245 key = " header" ,
43- default = REVANCED_BORDERLESS_HEADER_NAME ,
46+ default = REVANCED_BORDERLESS_HEADER_OPTION ,
4447 values = mapOf (
45- " YouTube" to HEADER_NAME ,
46- " YouTube Premium" to PREMIUM_HEADER_NAME ,
47- " ReVanced" to REVANCED_HEADER_NAME ,
48- " ReVanced (borderless logo)" to REVANCED_BORDERLESS_HEADER_NAME ,
48+ " YouTube" to HEADER_OPTION ,
49+ " YouTube Premium" to PREMIUM_HEADER_OPTION ,
50+ " ReVanced" to REVANCED_HEADER_OPTION ,
51+ " ReVanced (borderless logo)" to REVANCED_BORDERLESS_HEADER_OPTION ,
4952 ),
5053 title = " Header" ,
5154 description = """
52- Either a header name or a path to a custom header folder to use in the top bar.
53- The path to a folder must contain one or more of the following folders matching the DPI of your device:
54-
55- ${targetResourceDirectoryNames.joinToString(" \n " ) { " - $it " }}
56-
57- These folders must contain the following files:
58-
59- ${variants.joinToString(" \n " ) { variant -> " - ${HEADER_NAME } _$variant .png" }}
55+ The header to apply to the app.
56+
57+ 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:
58+
59+ ${targetResourceDirectoryNames.keys.joinToString(" \n " ) { " - $it " }}
60+
61+ Each of the folders must contain all of the following files:
62+
63+ ${variants.joinToString(" \n " ) { variant -> " - ${HEADER_FILE_NAME } _$variant .png" }}
64+
65+ The image dimensions must be as follows:
66+ ${targetResourceDirectoryNames.map { (dpi, dim) -> " - $dpi : $dim " }.joinToString(" \n " )}
6067 """ .trimIndentMultiline(),
6168 required = true ,
6269 )
6370
6471 override fun execute (context : ResourceContext ) {
6572 // The directories to copy the header to.
66- val targetResourceDirectories = targetResourceDirectoryNames.mapNotNull {
73+ val targetResourceDirectories = targetResourceDirectoryNames.keys. mapNotNull {
6774 context[" res" ].resolve(it).takeIf (File ::exists)
6875 }
6976 // The files to replace in the target directories.
70- val targetResourceFiles = targetResourceDirectoryNames.map { directoryName ->
77+ val targetResourceFiles = targetResourceDirectoryNames.keys. map { directoryName ->
7178 ResourceGroup (
7279 directoryName,
73- * variants.map { variant -> " ${HEADER_NAME } _$variant .png" }.toTypedArray()
80+ * variants.map { variant -> " ${HEADER_FILE_NAME } _$variant .png" }.toTypedArray(),
7481 )
7582 }
7683
@@ -89,8 +96,8 @@ object ChangeHeaderPatch : ResourcePatch() {
8996 }
9097
9198 // Functions to overwrite the header to the different variants.
92- val toPremium = { overwriteFromTo(PREMIUM_HEADER_NAME , HEADER_NAME ) }
93- val toHeader = { overwriteFromTo(HEADER_NAME , PREMIUM_HEADER_NAME ) }
99+ val toPremium = { overwriteFromTo(PREMIUM_HEADER_FILE_NAME , HEADER_FILE_NAME ) }
100+ val toHeader = { overwriteFromTo(HEADER_FILE_NAME , PREMIUM_HEADER_FILE_NAME ) }
94101 val toReVanced = {
95102 // Copy the ReVanced header to the resource directories.
96103 targetResourceFiles.forEach { context.copyResources(" change-header/revanced" , it) }
@@ -106,32 +113,38 @@ object ChangeHeaderPatch : ResourcePatch() {
106113 toHeader()
107114 }
108115 val toCustom = {
109- var copiedReplacementImages = false
110- // For all the resource groups in the custom header folder, copy them to the resource directories.
111- File (header!! ).listFiles { file -> file.isDirectory }?.forEach { folder ->
112- val targetDirectory = context[" res" ].resolve(folder.name)
113- // Skip if the target directory (DPI) doesn't exist.
114- if (! targetDirectory.exists()) return @forEach
115-
116- folder.listFiles { file -> file.isFile }?.forEach {
117- val targetResourceFile = targetDirectory.resolve(it.name)
118-
119- it.copyTo(targetResourceFile, true )
120- copiedReplacementImages = true
116+ val sourceFolders = File (header!! ).listFiles { file -> file.isDirectory }
117+ ? : throw PatchException (" The provided path is not a directory: $header " )
118+
119+ var copiedFiles = false
120+
121+ // For each source folder, copy the files to the target resource directories.
122+ sourceFolders.forEach { dpiSourceFolder ->
123+ val targetDpiFolder = context[" res" ].resolve(dpiSourceFolder.name)
124+ if (! targetDpiFolder.exists()) return @forEach
125+
126+ val imgSourceFiles = dpiSourceFolder.listFiles { file -> file.isFile }!!
127+ imgSourceFiles.forEach { imgSourceFile ->
128+ val imgTargetFile = targetDpiFolder.resolve(imgSourceFile.name)
129+ imgSourceFile.copyTo(imgTargetFile, true )
130+
131+ copiedFiles = true
121132 }
122133 }
123134
124- if (! copiedReplacementImages) throw PatchException (" Could not find any custom images resources in directory: $header " )
135+ if (! copiedFiles) {
136+ throw PatchException (" No header files were copied from the provided path: $header ." )
137+ }
125138
126139 // Overwrite the premium with the custom header as well.
127140 toHeader()
128141 }
129142
130143 when (header) {
131- HEADER_NAME -> toHeader
132- PREMIUM_HEADER_NAME -> toPremium
133- REVANCED_HEADER_NAME -> toReVanced
134- REVANCED_BORDERLESS_HEADER_NAME -> toReVancedBorderless
144+ HEADER_OPTION -> toHeader
145+ PREMIUM_HEADER_OPTION -> toPremium
146+ REVANCED_HEADER_OPTION -> toReVanced
147+ REVANCED_BORDERLESS_HEADER_OPTION -> toReVancedBorderless
135148 else -> toCustom
136149 }()
137150 }
0 commit comments