From 62871429a48c92ec1209fac0adaefb87f1bd2e55 Mon Sep 17 00:00:00 2001 From: mona-apk Date: Tue, 27 Sep 2022 04:10:06 +0900 Subject: [PATCH 01/16] feat: add "setting_item_dynamic_color" to strings.xml --- core/model/src/commonMain/resources/MR/base/strings.xml | 1 + core/model/src/commonMain/resources/MR/en/strings.xml | 1 + core/model/src/commonMain/resources/MR/zh/strings.xml | 2 ++ 3 files changed, 4 insertions(+) diff --git a/core/model/src/commonMain/resources/MR/base/strings.xml b/core/model/src/commonMain/resources/MR/base/strings.xml index a499e43d..1981bd3d 100644 --- a/core/model/src/commonMain/resources/MR/base/strings.xml +++ b/core/model/src/commonMain/resources/MR/base/strings.xml @@ -54,6 +54,7 @@ 設定 + ダイナミックカラー ダークモード 言語設定 システムのデフォルト diff --git a/core/model/src/commonMain/resources/MR/en/strings.xml b/core/model/src/commonMain/resources/MR/en/strings.xml index 8ac9640f..ed33d2dc 100644 --- a/core/model/src/commonMain/resources/MR/en/strings.xml +++ b/core/model/src/commonMain/resources/MR/en/strings.xml @@ -54,6 +54,7 @@ Setting + Dynamic Color Dark Mode Language System Default diff --git a/core/model/src/commonMain/resources/MR/zh/strings.xml b/core/model/src/commonMain/resources/MR/zh/strings.xml index e3094e9c..9216fc81 100644 --- a/core/model/src/commonMain/resources/MR/zh/strings.xml +++ b/core/model/src/commonMain/resources/MR/zh/strings.xml @@ -55,6 +55,8 @@ 设置 + + Dynamic Color 深色模式 语言设置 系统默认设置 From 6dd714476eb7c4cd5127c3a1975a7470ce262e05 Mon Sep 17 00:00:00 2001 From: mona-apk Date: Tue, 27 Sep 2022 04:14:03 +0900 Subject: [PATCH 02/16] feat: create DynamicColorSetting Composable --- .../confsched2022/feature/setting/Setting.kt | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt index f55d0004..33484c33 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt @@ -11,15 +11,19 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.selection.selectable import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Colorize import androidx.compose.material.icons.filled.Language import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.Icon import androidx.compose.material3.RadioButton +import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview @@ -72,6 +76,7 @@ fun Setting( horizontalAlignment = Alignment.Start ) { LanguageSetting() + DynamicColorSetting() } } } @@ -159,6 +164,34 @@ private fun LanguageSelector( } } +// TODO +@Composable +private fun DynamicColorSetting(modifier: Modifier = Modifier) { + var isDynamicColorEnabled by remember { + mutableStateOf(true) + } + + Row( + modifier = modifier + .padding(16.dp) + .fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(28.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon(imageVector = Icons.Default.Colorize, contentDescription = null) + Text( + text = stringResource(resource = Strings.setting_item_dynamic_color), + modifier = Modifier.weight(1f), + ) + Switch( + checked = isDynamicColorEnabled, + onCheckedChange = { + isDynamicColorEnabled = it + }, + ) + } +} + @Preview @Composable private fun SettingPreview() { From 9f475b8ae6acfdef6254293446c4ac6e7b62d225 Mon Sep 17 00:00:00 2001 From: mona-apk Date: Tue, 27 Sep 2022 04:15:45 +0900 Subject: [PATCH 03/16] fix: change the order of modifiers --- .../droidkaigi/confsched2022/feature/setting/Setting.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt index 33484c33..8c33f1c4 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt @@ -89,9 +89,9 @@ private fun LanguageSetting( Row( modifier = modifier - .padding(vertical = 8.dp) - .fillMaxWidth() - .clickable { openDialog.value = true }, + .clickable { openDialog.value = true } + .padding(16.dp) + .fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { From c93a6520da09e00c96d976931fab4abac6cf901e Mon Sep 17 00:00:00 2001 From: mona-apk Date: Tue, 27 Sep 2022 05:53:27 +0900 Subject: [PATCH 04/16] feat: create ViewModel and UiState --- .../feature/setting/SettingUiModel.kt | 5 +++ .../feature/setting/SettingViewModel.kt | 39 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingUiModel.kt create mode 100644 feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingUiModel.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingUiModel.kt new file mode 100644 index 00000000..c8021329 --- /dev/null +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingUiModel.kt @@ -0,0 +1,5 @@ +package io.github.droidkaigi.confsched2022.feature.setting + +data class SettingUiModel( + val isDynamicColorEnabled: Boolean, +) diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt new file mode 100644 index 00000000..dbf4d8d6 --- /dev/null +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt @@ -0,0 +1,39 @@ +package io.github.droidkaigi.confsched2022.feature.setting + +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import app.cash.molecule.AndroidUiDispatcher +import app.cash.molecule.RecompositionClock.ContextClock +import dagger.hilt.android.lifecycle.HiltViewModel +import io.github.droidkaigi.confsched2022.model.Filters +import io.github.droidkaigi.confsched2022.model.TimetableItemId +import io.github.droidkaigi.confsched2022.ui.moleculeComposeState +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class SettingViewModel @Inject constructor( +) : ViewModel() { + private val moleculeScope = + CoroutineScope(viewModelScope.coroutineContext + AndroidUiDispatcher.Main) + + val uiModel: State + private val isDynamicColorEnabled: MutableState + + init { + // TODO: initialize isDynamicColorEnabled + isDynamicColorEnabled = mutableStateOf(true) + uiModel = moleculeScope.moleculeComposeState(clock = ContextClock) { + SettingUiModel(isDynamicColorEnabled = isDynamicColorEnabled.value) + } + } + + fun onDynamicColorToggle() { + // TODO: change + isDynamicColorEnabled.value = !isDynamicColorEnabled.value + } +} \ No newline at end of file From a8a96cc747f1d8a30ec2bbca1db6d0c863117afa Mon Sep 17 00:00:00 2001 From: mona-apk Date: Tue, 27 Sep 2022 05:56:01 +0900 Subject: [PATCH 05/16] refactor: use ViewModel and UiState --- .../confsched2022/feature/setting/Setting.kt | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt index 8c33f1c4..6ed6ce61 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.os.LocaleListCompat +import androidx.hilt.navigation.compose.hiltViewModel import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.compose.stringResource import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold @@ -52,8 +53,11 @@ fun SettingScreenRoot( fun Setting( showNavigationIcon: Boolean, modifier: Modifier = Modifier, + viewModel: SettingViewModel = hiltViewModel(), onNavigationIconClick: () -> Unit ) { + val state: SettingUiModel by viewModel.uiModel + KaigiScaffold( modifier = modifier, topBar = { @@ -76,7 +80,10 @@ fun Setting( horizontalAlignment = Alignment.Start ) { LanguageSetting() - DynamicColorSetting() + DynamicColorSetting( + isDynamicColorEnabled = state.isDynamicColorEnabled, + onDynamicToggleClick = viewModel::onDynamicColorToggle, + ) } } } @@ -166,11 +173,11 @@ private fun LanguageSelector( // TODO @Composable -private fun DynamicColorSetting(modifier: Modifier = Modifier) { - var isDynamicColorEnabled by remember { - mutableStateOf(true) - } - +private fun DynamicColorSetting( + isDynamicColorEnabled: Boolean, + onDynamicToggleClick: () -> Unit, + modifier: Modifier = Modifier, +) { Row( modifier = modifier .padding(16.dp) @@ -186,7 +193,7 @@ private fun DynamicColorSetting(modifier: Modifier = Modifier) { Switch( checked = isDynamicColorEnabled, onCheckedChange = { - isDynamicColorEnabled = it + onDynamicToggleClick() }, ) } From 51b88d07c17dc24eaea851840eb79f75864e2567 Mon Sep 17 00:00:00 2001 From: mona-apk Date: Tue, 27 Sep 2022 06:57:06 +0900 Subject: [PATCH 06/16] refactor: rename --- .../confsched2022/feature/setting/SettingViewModel.kt | 9 +++------ .../{SettingUiModel.kt => SharedSettingUiModel.kt} | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) rename feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/{SettingUiModel.kt => SharedSettingUiModel.kt} (75%) diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt index dbf4d8d6..3fad4303 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt @@ -8,27 +8,24 @@ import androidx.lifecycle.viewModelScope import app.cash.molecule.AndroidUiDispatcher import app.cash.molecule.RecompositionClock.ContextClock import dagger.hilt.android.lifecycle.HiltViewModel -import io.github.droidkaigi.confsched2022.model.Filters -import io.github.droidkaigi.confsched2022.model.TimetableItemId import io.github.droidkaigi.confsched2022.ui.moleculeComposeState import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class SettingViewModel @Inject constructor( +class SharedSettingViewModel @Inject constructor( ) : ViewModel() { private val moleculeScope = CoroutineScope(viewModelScope.coroutineContext + AndroidUiDispatcher.Main) - val uiModel: State + val uiModel: State private val isDynamicColorEnabled: MutableState init { // TODO: initialize isDynamicColorEnabled isDynamicColorEnabled = mutableStateOf(true) uiModel = moleculeScope.moleculeComposeState(clock = ContextClock) { - SettingUiModel(isDynamicColorEnabled = isDynamicColorEnabled.value) + SharedSettingUiModel(isDynamicColorEnabled = isDynamicColorEnabled.value) } } diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingUiModel.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SharedSettingUiModel.kt similarity index 75% rename from feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingUiModel.kt rename to feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SharedSettingUiModel.kt index c8021329..c3dadc9d 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingUiModel.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SharedSettingUiModel.kt @@ -1,5 +1,5 @@ package io.github.droidkaigi.confsched2022.feature.setting -data class SettingUiModel( +data class SharedSettingUiModel( val isDynamicColorEnabled: Boolean, ) From 287c212ec4621c5bba048d4a7d0ab51365b6d1c3 Mon Sep 17 00:00:00 2001 From: mona-apk Date: Tue, 27 Sep 2022 06:58:55 +0900 Subject: [PATCH 07/16] refactor: state hoisting and replace old class --- .../confsched2022/feature/setting/Setting.kt | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt index 6ed6ce61..fdc08a3a 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt @@ -1,5 +1,6 @@ package io.github.droidkaigi.confsched2022.feature.setting +import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -23,9 +24,9 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.os.LocaleListCompat @@ -40,24 +41,28 @@ import io.github.droidkaigi.confsched2022.strings.Strings @Composable fun SettingScreenRoot( + viewModel: SharedSettingViewModel = hiltViewModel(viewModelStoreOwner = LocalContext.current as AppCompatActivity), showNavigationIcon: Boolean = true, onNavigationIconClick: () -> Unit = {} ) { + val state: SharedSettingUiModel by viewModel.uiModel + Setting( + sharedSettingUiModel = state, showNavigationIcon = showNavigationIcon, - onNavigationIconClick = onNavigationIconClick + onNavigationIconClick = onNavigationIconClick, + onDynamicToggleClick = viewModel::onDynamicColorToggle, ) } @Composable fun Setting( + sharedSettingUiModel: SharedSettingUiModel, showNavigationIcon: Boolean, + onNavigationIconClick: () -> Unit, + onDynamicToggleClick: () -> Unit, modifier: Modifier = Modifier, - viewModel: SettingViewModel = hiltViewModel(), - onNavigationIconClick: () -> Unit ) { - val state: SettingUiModel by viewModel.uiModel - KaigiScaffold( modifier = modifier, topBar = { @@ -81,8 +86,8 @@ fun Setting( ) { LanguageSetting() DynamicColorSetting( - isDynamicColorEnabled = state.isDynamicColorEnabled, - onDynamicToggleClick = viewModel::onDynamicColorToggle, + isDynamicColorEnabled = sharedSettingUiModel.isDynamicColorEnabled, + onDynamicToggleClick = onDynamicToggleClick, ) } } From 575691eebfa11340efefe416d9aa02599294fd45 Mon Sep 17 00:00:00 2001 From: mona-apk Date: Tue, 27 Sep 2022 07:12:09 +0900 Subject: [PATCH 08/16] feat: enable to switch Dynamic Color --- .../github/droidkaigi/confsched2022/KaigiApp.kt | 9 ++++++++- .../confsched2022/designsystem/theme/Theme.kt | 16 +++++++++++----- .../feature/setting/SettingViewModel.kt | 10 +++++++++- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/app-android/src/main/java/io/github/droidkaigi/confsched2022/KaigiApp.kt b/app-android/src/main/java/io/github/droidkaigi/confsched2022/KaigiApp.kt index 81944882..b201b537 100644 --- a/app-android/src/main/java/io/github/droidkaigi/confsched2022/KaigiApp.kt +++ b/app-android/src/main/java/io/github/droidkaigi/confsched2022/KaigiApp.kt @@ -44,6 +44,7 @@ import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -54,6 +55,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.rememberNavController @@ -72,6 +74,8 @@ import io.github.droidkaigi.confsched2022.feature.map.mapGraph import io.github.droidkaigi.confsched2022.feature.sessions.SessionsNavGraph import io.github.droidkaigi.confsched2022.feature.sessions.sessionsNavGraph import io.github.droidkaigi.confsched2022.feature.setting.SettingNavGraph +import io.github.droidkaigi.confsched2022.feature.setting.SharedSettingUiModel +import io.github.droidkaigi.confsched2022.feature.setting.SharedSettingViewModel import io.github.droidkaigi.confsched2022.feature.setting.settingNavGraph import io.github.droidkaigi.confsched2022.feature.sponsors.SponsorsNavGraph import io.github.droidkaigi.confsched2022.feature.sponsors.sponsorsNavGraph @@ -91,11 +95,14 @@ import kotlinx.coroutines.launch @Composable fun KaigiApp( windowSizeClass: WindowSizeClass, + sharedSettingViewModel: SharedSettingViewModel = hiltViewModel(), kaigiAppScaffoldState: KaigiAppScaffoldState = rememberKaigiAppScaffoldState(), kaigiExternalNavigationController: KaigiExternalNavigationController = rememberKaigiExternalNavigationController(), ) { - KaigiTheme { + val sharedSettingState: SharedSettingUiModel by sharedSettingViewModel.uiModel + + KaigiTheme(isDynamicColorEnabled = sharedSettingState.isDynamicColorEnabled) { val usePersistentNavigationDrawer = windowSizeClass.usePersistentNavigationDrawer KaigiAppDrawer( kaigiAppScaffoldState = kaigiAppScaffoldState, diff --git a/core/designsystem/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/designsystem/theme/Theme.kt b/core/designsystem/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/designsystem/theme/Theme.kt index a139a3e3..c89b773d 100644 --- a/core/designsystem/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/designsystem/theme/Theme.kt +++ b/core/designsystem/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/designsystem/theme/Theme.kt @@ -2,8 +2,10 @@ package io.github.droidkaigi.confsched2022.designsystem.theme import androidx.compose.material3.MaterialTheme import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext private val DarkColorPalette = darkColorScheme( primary = Color(KaigiColors.primaryKeyColor80), @@ -35,12 +37,16 @@ private val DarkColorPalette = darkColorScheme( fun KaigiTheme( // Currently, we are not supporting light theme // darkTheme: Boolean = isSystemInDarkTheme(), + isDynamicColorEnabled: Boolean = false, content: @Composable () -> Unit ) { + val colorScheme = if (isDynamicColorEnabled) { + dynamicDarkColorScheme(LocalContext.current) + } else { + DarkColorPalette + } + MaterialTheme( - colorScheme = DarkColorPalette, - typography = Typography, - shapes = Shapes, - content = content + colorScheme = colorScheme, typography = Typography, shapes = Shapes, content = content ) -} +} \ No newline at end of file diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt index 3fad4303..af213b09 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt @@ -1,5 +1,8 @@ package io.github.droidkaigi.confsched2022.feature.setting +import android.os.Build +import android.os.Build.VERSION_CODES +import androidx.annotation.ChecksSdkIntAtLeast import androidx.compose.runtime.MutableState import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf @@ -23,7 +26,7 @@ class SharedSettingViewModel @Inject constructor( init { // TODO: initialize isDynamicColorEnabled - isDynamicColorEnabled = mutableStateOf(true) + isDynamicColorEnabled = mutableStateOf(isSupportedDynamicColor()) uiModel = moleculeScope.moleculeComposeState(clock = ContextClock) { SharedSettingUiModel(isDynamicColorEnabled = isDynamicColorEnabled.value) } @@ -33,4 +36,9 @@ class SharedSettingViewModel @Inject constructor( // TODO: change isDynamicColorEnabled.value = !isDynamicColorEnabled.value } + + @ChecksSdkIntAtLeast(api = VERSION_CODES.S) + private fun isSupportedDynamicColor(): Boolean { + return Build.VERSION.SDK_INT >= VERSION_CODES.S + } } \ No newline at end of file From 9c4524f677ed76bf25bf672b2ef2b4a7c349ee6d Mon Sep 17 00:00:00 2001 From: mona-apk Date: Tue, 27 Sep 2022 11:15:24 +0900 Subject: [PATCH 09/16] feat: add Dynamic Color setting to SettingsDatastore --- .../confsched2022/data/SettingsDatastore.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/SettingsDatastore.kt b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/SettingsDatastore.kt index 5e606d38..185ba38d 100644 --- a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/SettingsDatastore.kt +++ b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/SettingsDatastore.kt @@ -61,10 +61,22 @@ public class SettingsDatastore(private val flowSettings: FlowSettings) { ) } + public fun dynamicColorEnabled(): Flow { + return flowSettings.getBooleanFlow(KEY_DYNAMIC_COLOR, false) + } + + public suspend fun setDynamicColorEnabled(dynamicColorEnabled: Boolean) { + flowSettings.putBoolean( + KEY_DYNAMIC_COLOR, + dynamicColorEnabled, + ) + } + public companion object { public const val NAME: String = "PREFERENCES_NAME" private const val KEY_AUTHENTICATED = "KEY_AUTHENTICATED" private const val KEY_DEVICE_ID = "KEY_DEVICE_ID" + private const val KEY_DYNAMIC_COLOR = "KEY_DYNAMIC_COLOR" private const val KEY = "favorites" private const val DELIMITER = "," } From db6c954dc4bc3343a4498ea19dfe7eb5dcffef0b Mon Sep 17 00:00:00 2001 From: mona-apk Date: Tue, 27 Sep 2022 11:17:19 +0900 Subject: [PATCH 10/16] feat: create DynamicColorSettingRepository --- .../data/setting/di/SettingDataModule.kt | 24 +++++++++++++++++++ .../DataDynamicColorSettingRepository.kt | 17 +++++++++++++ .../model/DynamicColorSettingRepository.kt | 8 +++++++ 3 files changed, 49 insertions(+) create mode 100644 core/data/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/data/setting/di/SettingDataModule.kt create mode 100644 core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/setting/DataDynamicColorSettingRepository.kt create mode 100644 core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/DynamicColorSettingRepository.kt diff --git a/core/data/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/data/setting/di/SettingDataModule.kt b/core/data/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/data/setting/di/SettingDataModule.kt new file mode 100644 index 00000000..5b21d17b --- /dev/null +++ b/core/data/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/data/setting/di/SettingDataModule.kt @@ -0,0 +1,24 @@ +package io.github.droidkaigi.confsched2022.data.setting.di + +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import io.github.droidkaigi.confsched2022.data.SettingsDatastore +import io.github.droidkaigi.confsched2022.data.setting.DataDynamicColorSettingRepository +import io.github.droidkaigi.confsched2022.model.DynamicColorSettingRepository +import javax.inject.Singleton + +@InstallIn(SingletonComponent::class) +@Module +public class SettingDataModule { + @Provides + @Singleton + public fun provideSessionsRepository( + settingsDatastore: SettingsDatastore + ): DynamicColorSettingRepository { + return DataDynamicColorSettingRepository( + settingsDatastore = settingsDatastore + ) + } +} diff --git a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/setting/DataDynamicColorSettingRepository.kt b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/setting/DataDynamicColorSettingRepository.kt new file mode 100644 index 00000000..e34436a2 --- /dev/null +++ b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/setting/DataDynamicColorSettingRepository.kt @@ -0,0 +1,17 @@ +package io.github.droidkaigi.confsched2022.data.setting + +import io.github.droidkaigi.confsched2022.data.SettingsDatastore +import io.github.droidkaigi.confsched2022.model.DynamicColorSettingRepository +import kotlinx.coroutines.flow.Flow + +public class DataDynamicColorSettingRepository( + private val settingsDatastore: SettingsDatastore +): DynamicColorSettingRepository { + override fun dynamicEnabledFlow(): Flow { + return settingsDatastore.dynamicColorEnabled() + } + + override suspend fun setDynamicColorEnabled(dynamicColorEnabled: Boolean) { + settingsDatastore.setDynamicColorEnabled(dynamicColorEnabled = dynamicColorEnabled) + } +} diff --git a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/DynamicColorSettingRepository.kt b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/DynamicColorSettingRepository.kt new file mode 100644 index 00000000..77efc83f --- /dev/null +++ b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/DynamicColorSettingRepository.kt @@ -0,0 +1,8 @@ +package io.github.droidkaigi.confsched2022.model + +import kotlinx.coroutines.flow.Flow + +public interface DynamicColorSettingRepository { + public fun dynamicEnabledFlow(): Flow + public suspend fun setDynamicColorEnabled(dynamicColorEnabled: Boolean) +} From 1b3bc455ea62492d3811fbedd077efffc740cd13 Mon Sep 17 00:00:00 2001 From: mona-apk Date: Tue, 27 Sep 2022 11:19:11 +0900 Subject: [PATCH 11/16] feat: control DynamicColorSetting from ViewModel --- .../confsched2022/feature/setting/Setting.kt | 12 ++++++---- .../feature/setting/SettingViewModel.kt | 22 ++++++++++++------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt index fdc08a3a..a231ea4f 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt @@ -1,5 +1,7 @@ package io.github.droidkaigi.confsched2022.feature.setting +import android.os.Build.VERSION +import android.os.Build.VERSION_CODES import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.compose.foundation.clickable @@ -85,10 +87,12 @@ fun Setting( horizontalAlignment = Alignment.Start ) { LanguageSetting() - DynamicColorSetting( - isDynamicColorEnabled = sharedSettingUiModel.isDynamicColorEnabled, - onDynamicToggleClick = onDynamicToggleClick, - ) + if (VERSION.SDK_INT >= VERSION_CODES.S) { + DynamicColorSetting( + isDynamicColorEnabled = sharedSettingUiModel.isDynamicColorEnabled, + onDynamicToggleClick = onDynamicToggleClick, + ) + } } } } diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt index af213b09..9de1f441 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt @@ -3,38 +3,44 @@ package io.github.droidkaigi.confsched2022.feature.setting import android.os.Build import android.os.Build.VERSION_CODES import androidx.annotation.ChecksSdkIntAtLeast -import androidx.compose.runtime.MutableState import androidx.compose.runtime.State -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.cash.molecule.AndroidUiDispatcher import app.cash.molecule.RecompositionClock.ContextClock import dagger.hilt.android.lifecycle.HiltViewModel +import io.github.droidkaigi.confsched2022.model.DynamicColorSettingRepository import io.github.droidkaigi.confsched2022.ui.moleculeComposeState import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class SharedSettingViewModel @Inject constructor( + private val dynamicColorSettingRepository: DynamicColorSettingRepository, ) : ViewModel() { private val moleculeScope = CoroutineScope(viewModelScope.coroutineContext + AndroidUiDispatcher.Main) val uiModel: State - private val isDynamicColorEnabled: MutableState + private val dynamicColorEnabledFlow: Flow = + dynamicColorSettingRepository.dynamicEnabledFlow() init { - // TODO: initialize isDynamicColorEnabled - isDynamicColorEnabled = mutableStateOf(isSupportedDynamicColor()) uiModel = moleculeScope.moleculeComposeState(clock = ContextClock) { - SharedSettingUiModel(isDynamicColorEnabled = isDynamicColorEnabled.value) + val dynamicColorEnabled by dynamicColorEnabledFlow.collectAsState(initial = isSupportedDynamicColor()) + SharedSettingUiModel(isDynamicColorEnabled = dynamicColorEnabled) } } fun onDynamicColorToggle() { - // TODO: change - isDynamicColorEnabled.value = !isDynamicColorEnabled.value + viewModelScope.launch { + dynamicColorSettingRepository.setDynamicColorEnabled(!dynamicColorEnabledFlow.first()) + } } @ChecksSdkIntAtLeast(api = VERSION_CODES.S) From 959db16e26284839dc495c7e1db8e06f78f5ade2 Mon Sep 17 00:00:00 2001 From: mona-apk Date: Tue, 27 Sep 2022 22:28:48 +0900 Subject: [PATCH 12/16] style: code format --- .../data/setting/DataDynamicColorSettingRepository.kt | 2 +- .../droidkaigi/confsched2022/designsystem/theme/Theme.kt | 2 +- .../droidkaigi/confsched2022/feature/setting/Setting.kt | 3 ++- .../{SettingViewModel.kt => SharedSettingViewModel.kt} | 5 +++-- 4 files changed, 7 insertions(+), 5 deletions(-) rename feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/{SettingViewModel.kt => SharedSettingViewModel.kt} (93%) diff --git a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/setting/DataDynamicColorSettingRepository.kt b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/setting/DataDynamicColorSettingRepository.kt index e34436a2..12860ef6 100644 --- a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/setting/DataDynamicColorSettingRepository.kt +++ b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/setting/DataDynamicColorSettingRepository.kt @@ -6,7 +6,7 @@ import kotlinx.coroutines.flow.Flow public class DataDynamicColorSettingRepository( private val settingsDatastore: SettingsDatastore -): DynamicColorSettingRepository { +) : DynamicColorSettingRepository { override fun dynamicEnabledFlow(): Flow { return settingsDatastore.dynamicColorEnabled() } diff --git a/core/designsystem/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/designsystem/theme/Theme.kt b/core/designsystem/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/designsystem/theme/Theme.kt index c89b773d..56ebe7d8 100644 --- a/core/designsystem/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/designsystem/theme/Theme.kt +++ b/core/designsystem/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/designsystem/theme/Theme.kt @@ -49,4 +49,4 @@ fun KaigiTheme( MaterialTheme( colorScheme = colorScheme, typography = Typography, shapes = Shapes, content = content ) -} \ No newline at end of file +} diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt index a231ea4f..e332ee4b 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt @@ -43,7 +43,8 @@ import io.github.droidkaigi.confsched2022.strings.Strings @Composable fun SettingScreenRoot( - viewModel: SharedSettingViewModel = hiltViewModel(viewModelStoreOwner = LocalContext.current as AppCompatActivity), + viewModel: SharedSettingViewModel = + hiltViewModel(viewModelStoreOwner = LocalContext.current as AppCompatActivity), showNavigationIcon: Boolean = true, onNavigationIconClick: () -> Unit = {} ) { diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SharedSettingViewModel.kt similarity index 93% rename from feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt rename to feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SharedSettingViewModel.kt index 9de1f441..664e3e97 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingViewModel.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SharedSettingViewModel.kt @@ -32,7 +32,8 @@ class SharedSettingViewModel @Inject constructor( init { uiModel = moleculeScope.moleculeComposeState(clock = ContextClock) { - val dynamicColorEnabled by dynamicColorEnabledFlow.collectAsState(initial = isSupportedDynamicColor()) + val dynamicColorEnabled + by dynamicColorEnabledFlow.collectAsState(initial = isSupportedDynamicColor()) SharedSettingUiModel(isDynamicColorEnabled = dynamicColorEnabled) } } @@ -47,4 +48,4 @@ class SharedSettingViewModel @Inject constructor( private fun isSupportedDynamicColor(): Boolean { return Build.VERSION.SDK_INT >= VERSION_CODES.S } -} \ No newline at end of file +} From 188fbe05ca7e7d56927e2bac9da97adce1169c8a Mon Sep 17 00:00:00 2001 From: mona-apk Date: Wed, 28 Sep 2022 10:20:45 +0900 Subject: [PATCH 13/16] feat: add NewApi SuppressLint --- .../droidkaigi/confsched2022/designsystem/theme/Theme.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/designsystem/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/designsystem/theme/Theme.kt b/core/designsystem/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/designsystem/theme/Theme.kt index 56ebe7d8..9916b4de 100644 --- a/core/designsystem/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/designsystem/theme/Theme.kt +++ b/core/designsystem/src/androidMain/kotlin/io/github/droidkaigi/confsched2022/designsystem/theme/Theme.kt @@ -1,5 +1,6 @@ package io.github.droidkaigi.confsched2022.designsystem.theme +import android.annotation.SuppressLint import androidx.compose.material3.MaterialTheme import androidx.compose.material3.darkColorScheme import androidx.compose.material3.dynamicDarkColorScheme @@ -33,8 +34,9 @@ private val DarkColorPalette = darkColorScheme( outline = Color(KaigiColors.neutralVariantKeyColor60), ) +@SuppressLint("NewApi") @Composable -fun KaigiTheme( +public fun KaigiTheme( // Currently, we are not supporting light theme // darkTheme: Boolean = isSystemInDarkTheme(), isDynamicColorEnabled: Boolean = false, From b7502a6df2552c97a89a38bf99cf629172c004f7 Mon Sep 17 00:00:00 2001 From: takahirom Date: Wed, 28 Sep 2022 10:45:31 +0900 Subject: [PATCH 14/16] Refactor and add tricks --- .../droidkaigi/confsched2022/KaigiApp.kt | 8 ++++---- .../confsched2022/data/SettingsDatastore.kt | 8 +++++++- ...{SharedSettingUiModel.kt => AppUiModel.kt} | 2 +- ...ttingViewModel.kt => KaigiAppViewModel.kt} | 19 ++++++++---------- .../confsched2022/feature/setting/Setting.kt | 20 +++++++++---------- 5 files changed, 30 insertions(+), 27 deletions(-) rename feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/{SharedSettingUiModel.kt => AppUiModel.kt} (75%) rename feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/{SharedSettingViewModel.kt => KaigiAppViewModel.kt} (73%) diff --git a/app-android/src/main/java/io/github/droidkaigi/confsched2022/KaigiApp.kt b/app-android/src/main/java/io/github/droidkaigi/confsched2022/KaigiApp.kt index b201b537..86a453fe 100644 --- a/app-android/src/main/java/io/github/droidkaigi/confsched2022/KaigiApp.kt +++ b/app-android/src/main/java/io/github/droidkaigi/confsched2022/KaigiApp.kt @@ -73,9 +73,9 @@ import io.github.droidkaigi.confsched2022.feature.map.MapNavGraph import io.github.droidkaigi.confsched2022.feature.map.mapGraph import io.github.droidkaigi.confsched2022.feature.sessions.SessionsNavGraph import io.github.droidkaigi.confsched2022.feature.sessions.sessionsNavGraph +import io.github.droidkaigi.confsched2022.feature.setting.AppUiModel +import io.github.droidkaigi.confsched2022.feature.setting.KaigiAppViewModel import io.github.droidkaigi.confsched2022.feature.setting.SettingNavGraph -import io.github.droidkaigi.confsched2022.feature.setting.SharedSettingUiModel -import io.github.droidkaigi.confsched2022.feature.setting.SharedSettingViewModel import io.github.droidkaigi.confsched2022.feature.setting.settingNavGraph import io.github.droidkaigi.confsched2022.feature.sponsors.SponsorsNavGraph import io.github.droidkaigi.confsched2022.feature.sponsors.sponsorsNavGraph @@ -95,12 +95,12 @@ import kotlinx.coroutines.launch @Composable fun KaigiApp( windowSizeClass: WindowSizeClass, - sharedSettingViewModel: SharedSettingViewModel = hiltViewModel(), + kaigiAppViewModel: KaigiAppViewModel = hiltViewModel(), kaigiAppScaffoldState: KaigiAppScaffoldState = rememberKaigiAppScaffoldState(), kaigiExternalNavigationController: KaigiExternalNavigationController = rememberKaigiExternalNavigationController(), ) { - val sharedSettingState: SharedSettingUiModel by sharedSettingViewModel.uiModel + val sharedSettingState: AppUiModel by kaigiAppViewModel.uiModel KaigiTheme(isDynamicColorEnabled = sharedSettingState.isDynamicColorEnabled) { val usePersistentNavigationDrawer = windowSizeClass.usePersistentNavigationDrawer diff --git a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/SettingsDatastore.kt b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/SettingsDatastore.kt index 185ba38d..7f537d5e 100644 --- a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/SettingsDatastore.kt +++ b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/SettingsDatastore.kt @@ -1,12 +1,14 @@ package io.github.droidkaigi.confsched2022.data import com.russhwolf.settings.coroutines.FlowSettings +import io.github.droidkaigi.confsched2022.model.DroidKaigi2022Day import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.toImmutableSet import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map +import kotlinx.datetime.Clock public class SettingsDatastore(private val flowSettings: FlowSettings) { @@ -62,7 +64,11 @@ public class SettingsDatastore(private val flowSettings: FlowSettings) { } public fun dynamicColorEnabled(): Flow { - return flowSettings.getBooleanFlow(KEY_DYNAMIC_COLOR, false) + return flowSettings.getBooleanFlow( + key = KEY_DYNAMIC_COLOR, + // The trick + defaultValue = DroidKaigi2022Day.Day1.start < Clock.System.now() + ) } public suspend fun setDynamicColorEnabled(dynamicColorEnabled: Boolean) { diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SharedSettingUiModel.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/AppUiModel.kt similarity index 75% rename from feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SharedSettingUiModel.kt rename to feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/AppUiModel.kt index c3dadc9d..d74c0f01 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SharedSettingUiModel.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/AppUiModel.kt @@ -1,5 +1,5 @@ package io.github.droidkaigi.confsched2022.feature.setting -data class SharedSettingUiModel( +data class AppUiModel( val isDynamicColorEnabled: Boolean, ) diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SharedSettingViewModel.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/KaigiAppViewModel.kt similarity index 73% rename from feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SharedSettingViewModel.kt rename to feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/KaigiAppViewModel.kt index 664e3e97..21496b71 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SharedSettingViewModel.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/KaigiAppViewModel.kt @@ -15,32 +15,29 @@ import io.github.droidkaigi.confsched2022.model.DynamicColorSettingRepository import io.github.droidkaigi.confsched2022.ui.moleculeComposeState import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class SharedSettingViewModel @Inject constructor( +class KaigiAppViewModel @Inject constructor( private val dynamicColorSettingRepository: DynamicColorSettingRepository, ) : ViewModel() { private val moleculeScope = CoroutineScope(viewModelScope.coroutineContext + AndroidUiDispatcher.Main) - val uiModel: State private val dynamicColorEnabledFlow: Flow = dynamicColorSettingRepository.dynamicEnabledFlow() - init { - uiModel = moleculeScope.moleculeComposeState(clock = ContextClock) { - val dynamicColorEnabled - by dynamicColorEnabledFlow.collectAsState(initial = isSupportedDynamicColor()) - SharedSettingUiModel(isDynamicColorEnabled = dynamicColorEnabled) - } + val uiModel: State = moleculeScope.moleculeComposeState(clock = ContextClock) { + val dynamicColorSettingEnabled by dynamicColorEnabledFlow.collectAsState( + initial = false + ) + AppUiModel(isDynamicColorEnabled = dynamicColorSettingEnabled && isSupportedDynamicColor()) } - fun onDynamicColorToggle() { + fun onDynamicColorToggle(isDynamic: Boolean) { viewModelScope.launch { - dynamicColorSettingRepository.setDynamicColorEnabled(!dynamicColorEnabledFlow.first()) + dynamicColorSettingRepository.setDynamicColorEnabled(isDynamic) } } diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt index e332ee4b..cfa78dc0 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt @@ -43,27 +43,27 @@ import io.github.droidkaigi.confsched2022.strings.Strings @Composable fun SettingScreenRoot( - viewModel: SharedSettingViewModel = + viewModel: KaigiAppViewModel = hiltViewModel(viewModelStoreOwner = LocalContext.current as AppCompatActivity), showNavigationIcon: Boolean = true, onNavigationIconClick: () -> Unit = {} ) { - val state: SharedSettingUiModel by viewModel.uiModel + val state: AppUiModel by viewModel.uiModel Setting( - sharedSettingUiModel = state, + appUiModel = state, showNavigationIcon = showNavigationIcon, onNavigationIconClick = onNavigationIconClick, - onDynamicToggleClick = viewModel::onDynamicColorToggle, + onDynamicColorToggle = viewModel::onDynamicColorToggle, ) } @Composable fun Setting( - sharedSettingUiModel: SharedSettingUiModel, + appUiModel: AppUiModel, showNavigationIcon: Boolean, onNavigationIconClick: () -> Unit, - onDynamicToggleClick: () -> Unit, + onDynamicColorToggle: (Boolean) -> Unit, modifier: Modifier = Modifier, ) { KaigiScaffold( @@ -90,8 +90,8 @@ fun Setting( LanguageSetting() if (VERSION.SDK_INT >= VERSION_CODES.S) { DynamicColorSetting( - isDynamicColorEnabled = sharedSettingUiModel.isDynamicColorEnabled, - onDynamicToggleClick = onDynamicToggleClick, + isDynamicColorEnabled = appUiModel.isDynamicColorEnabled, + onDynamicColorToggle = onDynamicColorToggle, ) } } @@ -185,7 +185,7 @@ private fun LanguageSelector( @Composable private fun DynamicColorSetting( isDynamicColorEnabled: Boolean, - onDynamicToggleClick: () -> Unit, + onDynamicColorToggle: (Boolean) -> Unit, modifier: Modifier = Modifier, ) { Row( @@ -203,7 +203,7 @@ private fun DynamicColorSetting( Switch( checked = isDynamicColorEnabled, onCheckedChange = { - onDynamicToggleClick() + onDynamicColorToggle(it) }, ) } From ae0f0b3696c7ab33d4a23a53aa8b4611a217cef7 Mon Sep 17 00:00:00 2001 From: takahirom Date: Wed, 28 Sep 2022 10:53:39 +0900 Subject: [PATCH 15/16] Refactor default logic --- .../droidkaigi/confsched2022/data/SettingsDatastore.kt | 3 +-- .../droidkaigi/confsched2022/model/DroidKaigi2022Day.kt | 5 +++++ .../confsched2022/feature/setting/KaigiAppViewModel.kt | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/SettingsDatastore.kt b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/SettingsDatastore.kt index 7f537d5e..78fb1b8b 100644 --- a/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/SettingsDatastore.kt +++ b/core/data/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/data/SettingsDatastore.kt @@ -8,7 +8,6 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map -import kotlinx.datetime.Clock public class SettingsDatastore(private val flowSettings: FlowSettings) { @@ -67,7 +66,7 @@ public class SettingsDatastore(private val flowSettings: FlowSettings) { return flowSettings.getBooleanFlow( key = KEY_DYNAMIC_COLOR, // The trick - defaultValue = DroidKaigi2022Day.Day1.start < Clock.System.now() + defaultValue = DroidKaigi2022Day.defaultDyamicThemeDate() ) } diff --git a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/DroidKaigi2022Day.kt b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/DroidKaigi2022Day.kt index ac546b5f..7eeec0e7 100644 --- a/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/DroidKaigi2022Day.kt +++ b/core/model/src/commonMain/kotlin/io/github/droidkaigi/confsched2022/model/DroidKaigi2022Day.kt @@ -1,5 +1,6 @@ package io.github.droidkaigi.confsched2022.model +import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.datetime.LocalDateTime import kotlinx.datetime.TimeZone @@ -47,6 +48,10 @@ public enum class DroidKaigi2022Day( time in it.start..it.end } } + + public fun defaultDyamicThemeDate(): Boolean { + return Day1.start < Clock.System.now() + } } } diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/KaigiAppViewModel.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/KaigiAppViewModel.kt index 21496b71..483864fb 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/KaigiAppViewModel.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/KaigiAppViewModel.kt @@ -11,6 +11,7 @@ import androidx.lifecycle.viewModelScope import app.cash.molecule.AndroidUiDispatcher import app.cash.molecule.RecompositionClock.ContextClock import dagger.hilt.android.lifecycle.HiltViewModel +import io.github.droidkaigi.confsched2022.model.DroidKaigi2022Day import io.github.droidkaigi.confsched2022.model.DynamicColorSettingRepository import io.github.droidkaigi.confsched2022.ui.moleculeComposeState import kotlinx.coroutines.CoroutineScope @@ -30,7 +31,7 @@ class KaigiAppViewModel @Inject constructor( val uiModel: State = moleculeScope.moleculeComposeState(clock = ContextClock) { val dynamicColorSettingEnabled by dynamicColorEnabledFlow.collectAsState( - initial = false + initial = DroidKaigi2022Day.defaultDyamicThemeDate() ) AppUiModel(isDynamicColorEnabled = dynamicColorSettingEnabled && isSupportedDynamicColor()) } From 88275c57b77419676153e72e0e91a458bc6104ef Mon Sep 17 00:00:00 2001 From: takahirom Date: Wed, 28 Sep 2022 20:47:55 +0900 Subject: [PATCH 16/16] Make AppViewModel single source of truth --- .../droidkaigi/confsched2022/KaigiApp.kt | 10 ++++++---- .../confsched2022/feature/setting/Setting.kt | 20 ++++++++----------- .../feature/setting/SettingNavGraph.kt | 4 ++++ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/app-android/src/main/java/io/github/droidkaigi/confsched2022/KaigiApp.kt b/app-android/src/main/java/io/github/droidkaigi/confsched2022/KaigiApp.kt index 86a453fe..18835e46 100644 --- a/app-android/src/main/java/io/github/droidkaigi/confsched2022/KaigiApp.kt +++ b/app-android/src/main/java/io/github/droidkaigi/confsched2022/KaigiApp.kt @@ -100,9 +100,9 @@ fun KaigiApp( kaigiExternalNavigationController: KaigiExternalNavigationController = rememberKaigiExternalNavigationController(), ) { - val sharedSettingState: AppUiModel by kaigiAppViewModel.uiModel + val appUiModel: AppUiModel by kaigiAppViewModel.uiModel - KaigiTheme(isDynamicColorEnabled = sharedSettingState.isDynamicColorEnabled) { + KaigiTheme(isDynamicColorEnabled = appUiModel.isDynamicColorEnabled) { val usePersistentNavigationDrawer = windowSizeClass.usePersistentNavigationDrawer KaigiAppDrawer( kaigiAppScaffoldState = kaigiAppScaffoldState, @@ -158,8 +158,10 @@ fun KaigiApp( onNavigationIconClick = kaigiAppScaffoldState::onNavigationClick, ) settingNavGraph( - showNavigationIcon, - kaigiAppScaffoldState::onNavigationClick + appUiModel = appUiModel, + showNavigationIcon = true, + onDynamicColorToggle = kaigiAppViewModel::onDynamicColorToggle, + onNavigationIconClick = kaigiAppScaffoldState::onNavigationClick ) sponsorsNavGraph( showNavigationIcon = showNavigationIcon, diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt index cfa78dc0..828853cf 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/Setting.kt @@ -2,7 +2,6 @@ package io.github.droidkaigi.confsched2022.feature.setting import android.os.Build.VERSION import android.os.Build.VERSION_CODES -import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -23,16 +22,13 @@ import androidx.compose.material3.RadioButton import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.os.LocaleListCompat -import androidx.hilt.navigation.compose.hiltViewModel import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.compose.stringResource import io.github.droidkaigi.confsched2022.designsystem.components.KaigiScaffold @@ -43,18 +39,16 @@ import io.github.droidkaigi.confsched2022.strings.Strings @Composable fun SettingScreenRoot( - viewModel: KaigiAppViewModel = - hiltViewModel(viewModelStoreOwner = LocalContext.current as AppCompatActivity), + appUiModel: AppUiModel, + onDynamicColorToggle: (Boolean) -> Unit, showNavigationIcon: Boolean = true, onNavigationIconClick: () -> Unit = {} ) { - val state: AppUiModel by viewModel.uiModel - Setting( - appUiModel = state, + appUiModel = appUiModel, showNavigationIcon = showNavigationIcon, onNavigationIconClick = onNavigationIconClick, - onDynamicColorToggle = viewModel::onDynamicColorToggle, + onDynamicColorToggle = onDynamicColorToggle, ) } @@ -181,7 +175,6 @@ private fun LanguageSelector( } } -// TODO @Composable private fun DynamicColorSetting( isDynamicColorEnabled: Boolean, @@ -213,7 +206,10 @@ private fun DynamicColorSetting( @Composable private fun SettingPreview() { KaigiTheme { - SettingScreenRoot() + SettingScreenRoot( + appUiModel = AppUiModel(false), + onDynamicColorToggle = {} + ) } } diff --git a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingNavGraph.kt b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingNavGraph.kt index 42170c0c..5883e714 100644 --- a/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingNavGraph.kt +++ b/feature/setting/src/main/java/io/github/droidkaigi/confsched2022/feature/setting/SettingNavGraph.kt @@ -4,11 +4,15 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable fun NavGraphBuilder.settingNavGraph( + appUiModel: AppUiModel, showNavigationIcon: Boolean, + onDynamicColorToggle: (Boolean) -> Unit, onNavigationIconClick: () -> Unit ) { composable(route = SettingNavGraph.settingRoute) { SettingScreenRoot( + appUiModel = appUiModel, + onDynamicColorToggle = onDynamicColorToggle, showNavigationIcon = showNavigationIcon, onNavigationIconClick = onNavigationIconClick )