diff --git a/composeApp/src/commonMain/kotlin/dev/therealashik/github/App.kt b/composeApp/src/commonMain/kotlin/dev/therealashik/github/App.kt index 2642f28..80835bd 100755 --- a/composeApp/src/commonMain/kotlin/dev/therealashik/github/App.kt +++ b/composeApp/src/commonMain/kotlin/dev/therealashik/github/App.kt @@ -5,6 +5,8 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.darkColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController @@ -20,13 +22,21 @@ import dev.therealashik.github.settings.AddPatScreen import dev.therealashik.github.settings.CodeOptionsScreen import dev.therealashik.github.settings.NotificationOptionsScreen import dev.therealashik.github.settings.SettingsScreen +import dev.therealashik.github.settings.ThemePreference +import dev.therealashik.github.settings.ThemeStateHolder private val LightColorScheme = lightColorScheme() private val DarkColorScheme = darkColorScheme() @Composable fun App() { - val colorScheme = if (isSystemInDarkTheme()) DarkColorScheme else LightColorScheme + val themePreference by ThemeStateHolder.themePreference.collectAsState() + + val colorScheme = when (themePreference) { + ThemePreference.SYSTEM -> if (isSystemInDarkTheme()) DarkColorScheme else LightColorScheme + ThemePreference.LIGHT -> LightColorScheme + ThemePreference.DARK -> DarkColorScheme + } MaterialTheme(colorScheme = colorScheme) { val navController = rememberNavController() diff --git a/composeApp/src/commonMain/kotlin/dev/therealashik/github/settings/SettingsScreen.kt b/composeApp/src/commonMain/kotlin/dev/therealashik/github/settings/SettingsScreen.kt index 93f79b3..476306c 100644 --- a/composeApp/src/commonMain/kotlin/dev/therealashik/github/settings/SettingsScreen.kt +++ b/composeApp/src/commonMain/kotlin/dev/therealashik/github/settings/SettingsScreen.kt @@ -30,7 +30,9 @@ fun SettingsScreen( viewModel: SettingsViewModel = viewModel { SettingsViewModel() } ) { val uiState by viewModel.uiState.collectAsState() + val themePreference by viewModel.themePreference.collectAsState() var showAccountsSheet by remember { mutableStateOf(false) } + var showThemeDialog by remember { mutableStateOf(false) } // Refresh token state when returning to this screen val lifecycle = LocalLifecycleOwner.current.lifecycle @@ -92,7 +94,7 @@ fun SettingsScreen( SettingsRow( title = stringResource(Res.string.settings_theme), subtitle = uiState.themeValue, - onClick = { /* TODO */ } + onClick = { showThemeDialog = true } ) SettingsRow( title = stringResource(Res.string.settings_code_options), @@ -159,6 +161,51 @@ fun SettingsScreen( } } } + + if (showThemeDialog) { + AlertDialog( + onDismissRequest = { showThemeDialog = false }, + title = { Text(text = stringResource(Res.string.settings_theme)) }, + text = { + Column { + ThemePreference.values().forEach { preference -> + Row( + Modifier + .fillMaxWidth() + .clickable { + viewModel.setTheme(preference) + showThemeDialog = false + } + .padding(vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + RadioButton( + selected = preference == themePreference, + onClick = { + viewModel.setTheme(preference) + showThemeDialog = false + } + ) + Spacer(modifier = Modifier.width(8.dp)) + Text( + text = when (preference) { + ThemePreference.SYSTEM -> stringResource(Res.string.settings_follow_system) + ThemePreference.LIGHT -> "Light" + ThemePreference.DARK -> "Dark" + }, + style = MaterialTheme.typography.bodyLarge + ) + } + } + } + }, + confirmButton = { + TextButton(onClick = { showThemeDialog = false }) { + Text(stringResource(Res.string.content_description_close)) + } + } + ) + } } @Composable diff --git a/composeApp/src/commonMain/kotlin/dev/therealashik/github/settings/SettingsViewModel.kt b/composeApp/src/commonMain/kotlin/dev/therealashik/github/settings/SettingsViewModel.kt index b4fb0e9..ebc72f8 100644 --- a/composeApp/src/commonMain/kotlin/dev/therealashik/github/settings/SettingsViewModel.kt +++ b/composeApp/src/commonMain/kotlin/dev/therealashik/github/settings/SettingsViewModel.kt @@ -19,11 +19,28 @@ class SettingsViewModel : ViewModel() { private val _uiState = MutableStateFlow(SettingsUiState()) val uiState: StateFlow = _uiState.asStateFlow() + val themePreference: StateFlow = ThemeStateHolder.themePreference.asStateFlow() + private val _signOutEvent = MutableSharedFlow() val signOutEvent: SharedFlow = _signOutEvent.asSharedFlow() init { refresh() + + viewModelScope.launch { + themePreference.collect { pref -> + val displayString = when (pref) { + ThemePreference.SYSTEM -> "Follow system" + ThemePreference.LIGHT -> "Light" + ThemePreference.DARK -> "Dark" + } + _uiState.value = _uiState.value.copy(themeValue = displayString) + } + } + } + + fun setTheme(preference: ThemePreference) { + ThemeStateHolder.themePreference.value = preference } fun refresh() { diff --git a/composeApp/src/commonMain/kotlin/dev/therealashik/github/settings/ThemePreference.kt b/composeApp/src/commonMain/kotlin/dev/therealashik/github/settings/ThemePreference.kt new file mode 100644 index 0000000..71882b8 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/dev/therealashik/github/settings/ThemePreference.kt @@ -0,0 +1,13 @@ +package dev.therealashik.github.settings + +import kotlinx.coroutines.flow.MutableStateFlow + +enum class ThemePreference { + SYSTEM, + LIGHT, + DARK +} + +object ThemeStateHolder { + val themePreference = MutableStateFlow(ThemePreference.SYSTEM) +}