diff --git a/apps/flipcash/features/currency-creator/src/main/kotlin/com/flipcash/app/currencycreator/CurrencyCreatorFlowScreen.kt b/apps/flipcash/features/currency-creator/src/main/kotlin/com/flipcash/app/currencycreator/CurrencyCreatorFlowScreen.kt index 33dbd589c0..dce8ec39cf 100644 --- a/apps/flipcash/features/currency-creator/src/main/kotlin/com/flipcash/app/currencycreator/CurrencyCreatorFlowScreen.kt +++ b/apps/flipcash/features/currency-creator/src/main/kotlin/com/flipcash/app/currencycreator/CurrencyCreatorFlowScreen.kt @@ -1,8 +1,10 @@ package com.flipcash.app.currencycreator +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider @@ -63,6 +65,7 @@ import com.getcode.opencode.model.financial.Fiat import com.getcode.opencode.model.financial.LocalFiat import com.getcode.opencode.model.financial.toFiat import com.getcode.theme.CodeTheme +import com.getcode.theme.rememberDynamicAccent import com.getcode.ui.core.unboundedClickable @Composable @@ -136,15 +139,24 @@ fun CurrencyCreatorFlowScreen( endContent = when (state.currentStep) { is CurrencyCreatorStep.BillCustomization -> { { + val (accent, onAccent) = rememberDynamicAccent( + fallbackAccent = CodeTheme.colors.secondary, + fallbackOnAccent = CodeTheme.colors.onAction, + ) + Text( - text = stringResource(R.string.action_done), + text = stringResource(R.string.action_next), style = CodeTheme.typography.textMedium, - color = Color.White, + color = onAccent, modifier = Modifier + .background(accent, shape = CircleShape) .unboundedClickable { topBarController.onEndAction?.invoke() } - .padding(5.dp), + .padding( + horizontal = CodeTheme.dimens.grid.x2, + vertical = CodeTheme.dimens.grid.x1 + ), ) } } diff --git a/ui/theme/build.gradle.kts b/ui/theme/build.gradle.kts index 56d6e90cfa..9407d9c15e 100644 --- a/ui/theme/build.gradle.kts +++ b/ui/theme/build.gradle.kts @@ -13,6 +13,7 @@ android { dependencies { debugImplementation(libs.compose.ui.tools) implementation(libs.compose.ui.tools.preview) implementation(libs.compose.material) + implementation(libs.compose.material3) implementation(libs.compose.accompanist) implementation(libs.androidx.appcompat) diff --git a/ui/theme/src/main/kotlin/com/getcode/theme/DynamicColor.kt b/ui/theme/src/main/kotlin/com/getcode/theme/DynamicColor.kt new file mode 100644 index 0000000000..d6eb61ad9e --- /dev/null +++ b/ui/theme/src/main/kotlin/com/getcode/theme/DynamicColor.kt @@ -0,0 +1,50 @@ +package com.getcode.theme + +import android.os.Build +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext + +/** + * The user's Material You (Monet) accent color, derived from their wallpaper / system theme. + * + * On Android 12+ (API 31) this reads the wallpaper-derived tonal palette via Material3's + * [dynamicDarkColorScheme] and returns its [accent] (`primary`) and [onAccent] (`onPrimary`). + * The app is dark-only, so we always take the *dark* dynamic scheme regardless of the system + * light/dark setting — its tonal steps read correctly on our dark surfaces. + * + * On API < 31 both fields fall back to [fallbackAccent] / [fallbackOnAccent]. + * + * Usage: + * ``` + * val (accent, onAccent) = rememberDynamicAccent( + * fallbackAccent = CodeTheme.colors.secondary, + * fallbackOnAccent = CodeTheme.colors.onAction, + * ) + * Button(colors = ButtonDefaults.buttonColors(containerColor = accent)) { + * Text("Save", color = onAccent) + * } + * ``` + */ +@Composable +fun rememberDynamicAccent( + fallbackAccent: Color, + fallbackOnAccent: Color = Color.White, +): DynamicAccent { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + return DynamicAccent(accent = fallbackAccent, onAccent = fallbackOnAccent) + } + val context = LocalContext.current + return remember(context) { + val scheme = dynamicDarkColorScheme(context) + DynamicAccent(accent = scheme.primary, onAccent = scheme.onPrimary) + } +} + +/** A wallpaper-derived accent paired with the content color that reads on top of it. */ +data class DynamicAccent( + val accent: Color, + val onAccent: Color, +)