Skip to content

Commit c78a2c5

Browse files
committed
Add dynamic color/theme support for android
1 parent 78b6bec commit c78a2c5

10 files changed

Lines changed: 103 additions & 22 deletions

File tree

composeApp/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ kotlin {
5959
implementation(libs.koin.androidx.compose)
6060
implementation(libs.androidx.activity.compose)
6161
implementation(libs.androidx.preference)
62+
implementation(libs.androidx.material3)
6263
}
6364
}
6465

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.linuxcommandlibrary.app.ui.theme
2+
3+
import android.os.Build
4+
import androidx.compose.material.darkColors
5+
import androidx.compose.material.lightColors
6+
import androidx.compose.material3.dynamicDarkColorScheme
7+
import androidx.compose.material3.dynamicLightColorScheme
8+
import androidx.compose.runtime.Composable
9+
import androidx.compose.ui.platform.LocalContext
10+
11+
@Composable
12+
actual fun dynamicThemeColors(darkTheme: Boolean): DynamicThemeColors? {
13+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return null
14+
15+
val context = LocalContext.current
16+
val m3Scheme = if (darkTheme) {
17+
dynamicDarkColorScheme(context)
18+
} else {
19+
dynamicLightColorScheme(context)
20+
}
21+
22+
val colors = if (darkTheme) {
23+
darkColors(
24+
primary = BrandRed,
25+
primaryVariant = BrandDarkRed,
26+
secondary = m3Scheme.onSurface,
27+
background = m3Scheme.background,
28+
surface = m3Scheme.surface,
29+
)
30+
} else {
31+
lightColors(
32+
primary = BrandRed,
33+
primaryVariant = BrandDarkRed,
34+
secondary = m3Scheme.onSurface,
35+
background = m3Scheme.background,
36+
surface = m3Scheme.surface,
37+
)
38+
}
39+
40+
val customColors = CustomColors(
41+
navBarBackground = m3Scheme.surfaceContainer,
42+
)
43+
44+
return DynamicThemeColors(colors = colors, customColors = customColors)
45+
}

composeApp/src/commonMain/kotlin/com/linuxcommandlibrary/app/App.kt

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ fun App(initialDeeplink: String? = null) {
105105
Box(
106106
modifier = Modifier
107107
.fillMaxSize()
108-
.background(MaterialTheme.colors.primary)
108+
.background(LocalCustomColors.current.topBarBackground)
109109
.statusBarsPadding()
110110
.background(LocalCustomColors.current.navBarBackground)
111111
.navigationBarsPadding()
@@ -363,8 +363,9 @@ private fun GenericTopBar(
363363
overflow = TextOverflow.Ellipsis,
364364
)
365365
},
366-
backgroundColor = MaterialTheme.colors.primary,
367-
contentColor = Color.White,
366+
backgroundColor = LocalCustomColors.current.topBarBackground,
367+
contentColor = LocalCustomColors.current.topBarContent,
368+
elevation = 0.dp,
368369
navigationIcon = if (showBackIcon) {
369370
{
370371
IconButton(
@@ -422,8 +423,9 @@ private fun DetailTopBar(
422423
overflow = TextOverflow.Ellipsis,
423424
)
424425
},
425-
backgroundColor = MaterialTheme.colors.primary,
426-
contentColor = Color.White,
426+
backgroundColor = LocalCustomColors.current.topBarBackground,
427+
contentColor = LocalCustomColors.current.topBarContent,
428+
elevation = 0.dp,
427429
navigationIcon = {
428430
IconButton(
429431
modifier = Modifier.pointerHoverIcon(PointerIcon.Hand),
@@ -476,10 +478,11 @@ private fun SearchTopBar(
476478
) {
477479
val focusRequester = remember { FocusRequester() }
478480

481+
val topBarContent = LocalCustomColors.current.topBarContent
479482
Row(
480483
modifier = Modifier
481484
.fillMaxWidth()
482-
.background(MaterialTheme.colors.primary)
485+
.background(LocalCustomColors.current.topBarBackground)
483486
.heightIn(min = 56.dp)
484487
.padding(horizontal = 4.dp),
485488
verticalAlignment = Alignment.CenterVertically,
@@ -495,7 +498,7 @@ private fun SearchTopBar(
495498
Icon(
496499
imageVector = backIcon,
497500
contentDescription = "Back",
498-
tint = Color.White,
501+
tint = topBarContent,
499502
)
500503
}
501504
OutlinedTextField(
@@ -505,17 +508,17 @@ private fun SearchTopBar(
505508
.weight(1f)
506509
.focusRequester(focusRequester)
507510
.padding(start = 8.dp, end = 8.dp),
508-
placeholder = { Text("Search...", color = Color.White.copy(alpha = 0.7f)) },
509-
textStyle = MaterialTheme.typography.subtitle1.copy(color = Color.White),
511+
placeholder = { Text("Search...", color = topBarContent.copy(alpha = 0.7f)) },
512+
textStyle = MaterialTheme.typography.subtitle1.copy(color = topBarContent),
510513
colors = TextFieldDefaults.outlinedTextFieldColors(
511-
textColor = Color.White,
512-
cursorColor = Color.White,
514+
textColor = topBarContent,
515+
cursorColor = topBarContent,
513516
focusedBorderColor = Color.Transparent,
514517
unfocusedBorderColor = Color.Transparent,
515518
disabledBorderColor = Color.Transparent,
516519
backgroundColor = Color.Transparent,
517-
trailingIconColor = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
518-
placeholderColor = LocalContentColor.current.copy(alpha = 0.7f),
520+
trailingIconColor = topBarContent.copy(alpha = LocalContentAlpha.current),
521+
placeholderColor = topBarContent.copy(alpha = 0.7f),
519522
),
520523
maxLines = 1,
521524
singleLine = true,
@@ -528,7 +531,7 @@ private fun SearchTopBar(
528531
Icon(
529532
imageVector = Icons.Filled.Close,
530533
contentDescription = "Clear",
531-
tint = Color.White,
534+
tint = topBarContent,
532535
)
533536
}
534537
}
@@ -539,10 +542,10 @@ private fun SearchTopBar(
539542
.weight(1f)
540543
.padding(start = 16.dp)
541544
.semantics { contentDescription = "TopAppBarTitle" },
542-
style = MaterialTheme.typography.h6.copy(color = LocalContentColor.current),
545+
style = MaterialTheme.typography.h6,
543546
maxLines = 1,
544547
overflow = TextOverflow.Ellipsis,
545-
color = Color.White,
548+
color = topBarContent,
546549
)
547550
IconButton(
548551
modifier = Modifier.pointerHoverIcon(PointerIcon.Hand),
@@ -551,7 +554,7 @@ private fun SearchTopBar(
551554
Icon(
552555
imageVector = Icons.Filled.Search,
553556
contentDescription = "Search",
554-
tint = Color.White,
557+
tint = topBarContent,
555558
)
556559
}
557560
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.linuxcommandlibrary.app.ui.theme
2+
3+
import androidx.compose.material.Colors
4+
import androidx.compose.runtime.Composable
5+
6+
data class DynamicThemeColors(
7+
val colors: Colors,
8+
val customColors: CustomColors,
9+
)
10+
11+
@Composable
12+
expect fun dynamicThemeColors(darkTheme: Boolean): DynamicThemeColors?

composeApp/src/commonMain/kotlin/com/linuxcommandlibrary/app/ui/theme/LinuxTheme.kt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@ import com.linuxcommandlibrary.app.resources.Res
1717
import com.linuxcommandlibrary.app.resources.share_tech_mono
1818
import org.jetbrains.compose.resources.Font
1919

20+
val BrandRed = Color(0xFFe45151)
21+
val BrandDarkRed = Color(0xFFc62828)
22+
2023
data class CustomColors(
2124
val navBarBackground: Color = Color(0xFF00695C),
25+
val topBarBackground: Color = BrandRed,
26+
val topBarContent: Color = Color.White,
2227
)
2328

2429
val LocalCustomColors = compositionLocalOf { CustomColors() }
@@ -27,18 +32,19 @@ val LocalCustomColors = compositionLocalOf { CustomColors() }
2732
fun LinuxTheme(content: @Composable () -> Unit) {
2833
val darkMode = isSystemInDarkTheme()
2934
val darkColors = darkColors(
30-
primary = Color(0xFFe45151),
35+
primary = BrandRed,
3136
secondary = Color.White,
3237
background = Color(0xFF262626),
3338
surface = Color(0xFF262626),
3439
)
3540
val lightColors = lightColors(
36-
primary = Color(0xFFe45151),
41+
primary = BrandRed,
3742
secondary = Color.Black,
3843
background = Color.White,
3944
surface = Color.White,
4045
)
41-
val colorSchema = if (darkMode) darkColors else lightColors
46+
val dynamicColors = dynamicThemeColors(darkMode)
47+
val colorSchema = dynamicColors?.colors ?: if (darkMode) darkColors else lightColors
4248

4349
val techMonoFont = FontFamily(
4450
Font(Res.font.share_tech_mono),
@@ -55,7 +61,7 @@ fun LinuxTheme(content: @Composable () -> Unit) {
5561
subtitle2 = codeTextStyle,
5662
)
5763

58-
val customColors = if (darkMode) {
64+
val customColors = dynamicColors?.customColors ?: if (darkMode) {
5965
CustomColors(
6066
navBarBackground = Color(0xFF2D2D2D),
6167
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.linuxcommandlibrary.app.ui.theme
2+
3+
import androidx.compose.runtime.Composable
4+
5+
@Composable
6+
actual fun dynamicThemeColors(darkTheme: Boolean): DynamicThemeColors? = null
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.linuxcommandlibrary.app.ui.theme
2+
3+
import androidx.compose.runtime.Composable
4+
5+
@Composable
6+
actual fun dynamicThemeColors(darkTheme: Boolean): DynamicThemeColors? = null

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ uiToolingPreview = "1.10.5"
1818
spotless = "8.3.0"
1919
kotlinxCollectionsImmutable = "0.4.0"
2020
benManesVersions = "0.53.0"
21+
material3 = "1.4.0"
2122
mordant = "3.0.2"
2223

2324

2425
[libraries]
2526
kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinxSerializationCore" }
2627
mordant = { module = "com.github.ajalt.mordant:mordant", version.ref = "mordant" }
28+
androidx-material3 = { module = "androidx.compose.material3:material3", version.ref = "material3" }
2729
accompanist-appcompat-theme = { module = "com.google.accompanist:accompanist-appcompat-theme", version.ref = "accompanistAppcompatTheme" }
2830
accompanist-systemuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanistAppcompatTheme" }
2931
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activityCompose" }

iosApp/iosApp/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<key>CFBundlePackageType</key>
1818
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
1919
<key>CFBundleShortVersionString</key>
20-
<string>3.5.14</string>
20+
<string>3.5.16</string>
2121
<key>CFBundleVersion</key>
2222
<string>1</string>
2323
<key>LSRequiresIPhoneOS</key>

0 commit comments

Comments
 (0)