Skip to content

Commit 0d37379

Browse files
authored
Merge bugfix/splash-screen-setup into main (#4)
* Added `splash.xml` file, refactored `cleanup.gradle.kts` to have better name casing preservation and to update splash.xml with project name post-creation, corrected navigation issue in `NavigationRoot.kt` * Refactored `cleanup.gradle.kts` to have functions specialized for configuring certain types of files (class files, manifests, and resources), Minor formatting in `themes.xml` and `Theme.kt`
1 parent e550198 commit 0d37379

6 files changed

Lines changed: 143 additions & 47 deletions

File tree

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
android:label="@string/app_name"
1010
android:roundIcon="@mipmap/ic_launcher_round"
1111
android:supportsRtl="true"
12-
android:theme="@style/Theme.ComposeAndroidTemplate">
12+
android:theme="@style/Theme.ComposeAndroidTemplate.Starting">
1313
<activity
1414
android:name=".app.MainActivity"
1515
android:exported="true"
16-
android:theme="@style/Theme.ComposeAndroidTemplate">
16+
android:theme="@style/Theme.ComposeAndroidTemplate.Starting">
1717
<intent-filter>
1818
<action android:name="android.intent.action.MAIN" />
1919
<category android:name="android.intent.category.LAUNCHER" />

app/src/main/java/com/codermp/composeandroidtemplate/app/navigation/NavigationRoot.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.codermp.composeandroidtemplate.app.navigation
33
import androidx.compose.runtime.Composable
44
import androidx.navigation.NavHostController
55
import androidx.navigation.compose.NavHost
6+
import androidx.navigation.compose.composable
67

78
/**
89
* Composable function that defines the root navigation graph for the application.
@@ -19,5 +20,6 @@ fun NavigationRoot(
1920
/**
2021
* Define your navigation graphs &/or composable routes here.
2122
*/
23+
composable<Routes.Home> { }
2224
}
2325
}

app/src/main/java/com/codermp/composeandroidtemplate/core/presentation/designsystem/theme/Theme.kt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,6 @@ private val LightColorScheme = lightColorScheme(
2020
primary = Purple40,
2121
secondary = PurpleGrey40,
2222
tertiary = Pink40
23-
24-
/* Other default colors to override
25-
background = Color(0xFFFFFBFE),
26-
surface = Color(0xFFFFFBFE),
27-
onPrimary = Color.White,
28-
onSecondary = Color.White,
29-
onTertiary = Color.White,
30-
onBackground = Color(0xFF1C1B1F),
31-
onSurface = Color(0xFF1C1B1F),
32-
*/
3323
)
3424

3525
@Composable

app/src/main/res/values/splash.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<style name="Theme.ComposeAndroidTemplate.Starting" parent="Theme.SplashScreen">
4+
<item name="android:actionBarStyle">@style/Theme.AppCompat.NoActionBar</item>
5+
<!-- TODO: Add your windowSplashScreenBackground color property-->
6+
<!-- TODO: Add your windowSplashScreenAnimatedIcon drawable property-->
7+
<item name="windowSplashScreenBackground">@color/purple_700</item>
8+
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_launcher_foreground</item>
9+
<item name="postSplashScreenTheme">@style/Theme.ComposeAndroidTemplate</item>
10+
</style>
11+
</resources>

app/src/main/res/values/themes.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
3-
43
<style name="Theme.ComposeAndroidTemplate" parent="android:Theme.Material.Light.NoActionBar" />
54
</resources>

buildSrc/src/main/kotlin/cleanup.gradle.kts

Lines changed: 128 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ tasks.register("templateCleanup") {
2121
it[0].sanitized() to it[1].sanitized()
2222
}
2323

24+
val nameCasePreserved = repository.split("/")[1].sanitizedPreservingCase()
25+
2426
file(path = "gradle/libs.versions.toml").replace(
2527
oldValue = "com.codermp.composeandroidtemplate",
2628
newValue = "com.$owner.$name"
@@ -31,7 +33,10 @@ tasks.register("templateCleanup") {
3133
)
3234

3335
changePackageName(owner = owner, name = name)
34-
changeManifestFile(name = name)
36+
changeManifestFile(name = nameCasePreserved)
37+
changeAppClassFile(name = nameCasePreserved)
38+
changeThemeFile(name = nameCasePreserved)
39+
changeResourceFiles(name = nameCasePreserved)
3540

3641
// cleanup the cleanup :)
3742
file(path = ".github/workflows/cleanup.yml").delete()
@@ -43,18 +48,43 @@ tasks.register("templateCleanup") {
4348
}
4449
}
4550

51+
/**
52+
* [String] extension function that sanitizes a string by removing all non-alphanumeric characters and
53+
* converting it to lowercase.
54+
*/
4655
fun String.sanitized() = replace(
4756
regex = Regex(pattern = "[^A-Za-z0-9]"),
4857
replacement = ""
4958
).lowercase()
5059

60+
/**
61+
* [String] extension function that sanitizes a string by removing all non-alphanumeric characters
62+
* while preserving the case. This is useful for cases where the original case of the string is
63+
* important, such as in class names.
64+
*/
65+
fun String.sanitizedPreservingCase() = split(regex = Regex("[^A-Za-z0-9]"))
66+
.filter { it.isNotEmpty() }
67+
.joinToString("")
68+
69+
/**
70+
* [File] extension function that replaces all occurrences of `oldValue` with `newValue` in the file.
71+
* @param oldValue The string to be replaced.
72+
* @param newValue The string to replace with.
73+
*/
5174
fun File.replace(oldValue: String, newValue: String) {
5275
writeText(text = readText().replace(oldValue, newValue))
5376
}
5477

55-
fun srcDirectories() = projectDir.listFiles()!!
78+
/**
79+
* Returns a list of source directories in the project.
80+
* It excludes the `buildSrc` directory to avoid unnecessary processing.
81+
*/
82+
fun srcDirectories() = projectDir
83+
.listFiles()!!
5684
.filter { it.isDirectory && it.name != "buildSrc" }
57-
.flatMap { it.listFiles()!!.filter { it.isDirectory && it.name == "src" } }
85+
.flatMap {
86+
it.listFiles()!!.filter { it.isDirectory && it.name == "src" }
87+
}
5888

5989
@Suppress("NestedBlockDepth")
6090
/**
@@ -63,12 +93,18 @@ fun srcDirectories() = projectDir.listFiles()!!
6393
* @param name The name of the repository, usually the project name.
6494
*/
6595
fun changePackageName(owner: String, name: String) {
66-
srcDirectories().forEach {
67-
it.walk().filter {
68-
it.isFile && (it.extension == "kt" || it.extension == "kts" || it.extension == "xml")
69-
}.forEach {
70-
it.replace("com.codermp.composeandroidtemplate", "com.$owner.$name")
71-
}
96+
srcDirectories().forEach { directory ->
97+
directory
98+
.walk()
99+
.filter {
100+
it.isFile && (it.extension == "kt" || it.extension == "kts" || it.extension == "xml")
101+
}
102+
.forEach { file ->
103+
file.replace(
104+
oldValue = "com.codermp.composeandroidtemplate",
105+
newValue = "com.$owner.$name"
106+
)
107+
}
72108
}
73109
srcDirectories().forEach { srcDir ->
74110
srcDir
@@ -112,42 +148,100 @@ fun changePackageName(owner: String, name: String) {
112148
* @param name The name of the repository, usually the project name.
113149
*/
114150
fun changeManifestFile(name: String) {
115-
val capitalizedName = name.split("-", "_")
116-
.joinToString("") { it.replaceFirstChar { char -> char.uppercaseChar() } }
117-
118-
// Update AndroidManifest.xml files
119-
projectDir.walk()
151+
// Update AndroidManifest.xml file
152+
projectDir
153+
.walk()
120154
.filter { it.name == "AndroidManifest.xml" }
121155
.forEach { manifestFile ->
122156
manifestFile.replace(
123157
oldValue = "android:name=\".app.TemplateApp\"",
124-
newValue = "android:name=\".app.${capitalizedName}App\""
158+
newValue = "android:name=\".app.${name}App\""
159+
)
160+
manifestFile.replace(
161+
oldValue = "android:theme=\"@style/Theme.ComposeAndroidTemplate.Starting\"",
162+
newValue = "android:theme=\"@style/Theme.$name.Starting\"",
125163
)
126164
}
165+
}
127166

128-
// Update strings.xml files
129-
projectDir.walk()
167+
/**
168+
* Change the main application class file to reflect the new project name.
169+
* @param name The name of the repository, usually the project name.
170+
*/
171+
fun changeAppClassFile(name: String) {
172+
// Rename TemplateApp class file
173+
srcDirectories()
174+
.forEach { srcDir ->
175+
srcDir
176+
.walk()
177+
.filter { it.isFile && it.name == "TemplateApp.kt" }
178+
.forEach { templateAppFile ->
179+
// Update class name inside the file
180+
templateAppFile.replace(
181+
oldValue = "class TemplateApp", newValue = "class ${name}App"
182+
)
183+
templateAppFile.replace(
184+
oldValue = "this@TemplateApp", newValue = "this@${name}App"
185+
)
186+
187+
// Rename the file itself
188+
val newFile = File(templateAppFile.parent, "${name}App.kt")
189+
templateAppFile.renameTo(newFile)
190+
}
191+
}
192+
}
193+
194+
/**
195+
* Change the Compose theme file to reflect the new project name.
196+
* @param name The name of the repository, usually the project name.
197+
*/
198+
fun changeThemeFile(name: String) {
199+
srcDirectories()
200+
.forEach { srcDir ->
201+
srcDir
202+
.walk()
203+
.filter { it.isFile && it.name == "Theme.kt" }
204+
.forEach { themeFile ->
205+
themeFile.replace(
206+
oldValue = "ComposeAndroidTemplateTheme", newValue = "${name}Theme"
207+
)
208+
}
209+
}
210+
}
211+
212+
/**
213+
* Change the resource files such as themes.xml, strings.xml, and splash.xml.
214+
* @param name The name of the repository, usually the project name.
215+
*/
216+
fun changeResourceFiles(name: String) {
217+
// Update themes.xml file
218+
projectDir
219+
.walk()
220+
.filter { it.name == "themes.xml" }
221+
.forEach { themesFile ->
222+
themesFile.replace(
223+
oldValue = "Theme.ComposeAndroidTemplate", newValue = "Theme.$name"
224+
)
225+
}
226+
227+
// Update strings.xml file
228+
projectDir
229+
.walk()
130230
.filter { it.name == "strings.xml" }
131231
.forEach { stringsFile ->
132232
stringsFile.replace(
133-
oldValue = "Compose Android Template",
134-
newValue = name.split("-", "_")
135-
.joinToString(" ") { it.replaceFirstChar { char -> char.uppercaseChar() } }
233+
oldValue = "Compose Android Template", newValue = name
136234
)
137235
}
138236

139-
// Rename TemplateApp class files
140-
srcDirectories().forEach { srcDir ->
141-
srcDir.walk()
142-
.filter { it.isFile && it.name == "TemplateApp.kt" }
143-
.forEach { templateAppFile ->
144-
// Update class name inside the file
145-
templateAppFile.replace("class TemplateApp", "class ${capitalizedName}App")
146-
templateAppFile.replace("this@TemplateApp", "this@${capitalizedName}App")
147-
148-
// Rename the file itself
149-
val newFile = File(templateAppFile.parent, "${capitalizedName}App.kt")
150-
templateAppFile.renameTo(newFile)
151-
}
152-
}
237+
// Update splash.xml file
238+
projectDir
239+
.walk()
240+
.filter { it.name == "splash.xml" }
241+
.forEach { splashFile ->
242+
splashFile.replace(
243+
oldValue = "Theme.ComposeAndroidTemplate.Starting",
244+
newValue = "Theme.${name}.Starting"
245+
)
246+
}
153247
}

0 commit comments

Comments
 (0)