diff --git a/frontend/app/src/main/java/com/example/speechbuddy/AuthActivity.kt b/frontend/app/src/main/java/com/example/speechbuddy/AuthActivity.kt index c0086d7a..45d36c79 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/AuthActivity.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/AuthActivity.kt @@ -8,6 +8,7 @@ import androidx.activity.compose.setContent import androidx.activity.viewModels import com.example.speechbuddy.compose.SpeechBuddyAuth import com.example.speechbuddy.ui.SpeechBuddyTheme +import com.example.speechbuddy.viewmodel.DisplaySettingsViewModel import com.example.speechbuddy.viewmodel.LoginViewModel import dagger.hilt.android.AndroidEntryPoint @@ -15,6 +16,7 @@ import dagger.hilt.android.AndroidEntryPoint class AuthActivity : BaseActivity() { private val loginViewModel: LoginViewModel by viewModels() + private val displaySettingsViewModel: DisplaySettingsViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -23,7 +25,10 @@ class AuthActivity : BaseActivity() { checkPreviousAuthUser() setContent { - SpeechBuddyTheme { + SpeechBuddyTheme( + settingsRepository = settingsRepository, + initialDarkMode = getInitialDarkMode() + ) { SpeechBuddyAuth() } } @@ -41,6 +46,10 @@ class AuthActivity : BaseActivity() { finish() } + private fun getInitialDarkMode(): Boolean { + return displaySettingsViewModel.getDarkMode() + } + private fun checkPreviousAuthUser() { loginViewModel.checkPreviousUser() } diff --git a/frontend/app/src/main/java/com/example/speechbuddy/HomeActivity.kt b/frontend/app/src/main/java/com/example/speechbuddy/HomeActivity.kt index 019ccb77..eff5d85f 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/HomeActivity.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/HomeActivity.kt @@ -9,6 +9,7 @@ import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.annotation.RequiresApi +import androidx.compose.runtime.mutableStateOf import androidx.core.view.WindowCompat import androidx.lifecycle.Observer import com.example.speechbuddy.compose.SpeechBuddyHome @@ -26,28 +27,16 @@ class HomeActivity : BaseActivity() { super.onCreate(savedInstanceState) - val isBeingReloadedForDarkModeChange = intent.getBooleanExtra("isBeingReloadedForDarkModeChange", false) - setContent { SpeechBuddyTheme( - darkTheme = getDarkMode() + settingsRepository = settingsRepository, + initialDarkMode = getInitialDarkMode() ) { - SpeechBuddyHome(getInitialPage(), isBeingReloadedForDarkModeChange) + SpeechBuddyHome(getInitialPage()) } } subscribeObservers() - - val previousDarkMode = getDarkMode() - - val darkModeObserver = Observer { darkMode -> - if (darkMode != previousDarkMode) { - recreateHomeActivity() - } - } - - settingsRepository.darkModeLiveData.observeForever(darkModeObserver) - } private fun subscribeObservers() { @@ -62,20 +51,13 @@ class HomeActivity : BaseActivity() { finish() } - private fun recreateHomeActivity() { - val intent = Intent(this, HomeActivity::class.java) - intent.putExtra("isBeingReloadedForDarkModeChange", true) - startActivity(intent) - finish() + private fun getInitialPage(): Boolean { + return displaySettingsViewModel.getInitialPage() } - private fun getDarkMode(): Boolean { + private fun getInitialDarkMode(): Boolean { return displaySettingsViewModel.getDarkMode() } - - private fun getInitialPage(): Boolean { - return displaySettingsViewModel.getInitialPage() - } // hides keyboard override fun dispatchTouchEvent(event: MotionEvent): Boolean { diff --git a/frontend/app/src/main/java/com/example/speechbuddy/compose/SpeechBuddyHome.kt b/frontend/app/src/main/java/com/example/speechbuddy/compose/SpeechBuddyHome.kt index 9e9f0fa8..bac0cbbd 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/compose/SpeechBuddyHome.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/compose/SpeechBuddyHome.kt @@ -47,8 +47,7 @@ data class BottomNavItem( @OptIn(ExperimentalMaterial3Api::class) @Composable fun SpeechBuddyHome( - initialPage: Boolean, - isBeingReloadedForDarkModeChange: Boolean + initialPage: Boolean ) { val navController = rememberNavController() val navItems = listOf( @@ -93,8 +92,7 @@ fun SpeechBuddyHome( bottomPaddingValues = paddingValues, initialPage = initialPage, showBottomNavBar = { bottomNavBarState.value = true }, - hideBottomNavBar = { bottomNavBarState.value = false }, - isBeingReloadedForDarkModeChange = isBeingReloadedForDarkModeChange + hideBottomNavBar = { bottomNavBarState.value = false } ) } } @@ -151,12 +149,9 @@ private fun SpeechBuddyHomeNavHost( initialPage: Boolean, showBottomNavBar: () -> Unit, hideBottomNavBar: () -> Unit, - isBeingReloadedForDarkModeChange: Boolean, ) { val startDestination = - if (isBeingReloadedForDarkModeChange) { - "settings" - } else if (initialPage) { + if (initialPage) { "symbol_selection" } else { "text_to_speech" @@ -182,8 +177,7 @@ private fun SpeechBuddyHomeNavHost( } composable("settings") { SettingsScreen( - bottomPaddingValues = bottomPaddingValues, - isBeingReloadedForDarkModeChange = isBeingReloadedForDarkModeChange + bottomPaddingValues = bottomPaddingValues ) } } diff --git a/frontend/app/src/main/java/com/example/speechbuddy/compose/landing/LandingScreen.kt b/frontend/app/src/main/java/com/example/speechbuddy/compose/landing/LandingScreen.kt index f1b79213..2ec6c9e3 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/compose/landing/LandingScreen.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/compose/landing/LandingScreen.kt @@ -57,12 +57,4 @@ fun LandingScreen( } } } -} - -@Preview -@Composable -private fun LandingScreenPreview() { - SpeechBuddyTheme { - LandingScreen(onLoginClick = {}) - } } \ No newline at end of file diff --git a/frontend/app/src/main/java/com/example/speechbuddy/compose/settings/SettingsRow.kt b/frontend/app/src/main/java/com/example/speechbuddy/compose/settings/SettingsRow.kt index 1da30674..1dc1d9e9 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/compose/settings/SettingsRow.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/compose/settings/SettingsRow.kt @@ -43,17 +43,4 @@ fun SettingsRowText( style = MaterialTheme.typography.bodyMedium ) } -} - -@Preview(showBackground = true) -@Composable -fun SettingsRowPreview() { - SpeechBuddyTheme { - SettingsRow( - label = "이메일", - content = { - SettingsRowText(text = "example@gmail.com") - } - ) - } } \ No newline at end of file diff --git a/frontend/app/src/main/java/com/example/speechbuddy/compose/settings/SettingsScreen.kt b/frontend/app/src/main/java/com/example/speechbuddy/compose/settings/SettingsScreen.kt index 0e3264e4..f541ed2a 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/compose/settings/SettingsScreen.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/compose/settings/SettingsScreen.kt @@ -14,14 +14,12 @@ import androidx.navigation.compose.rememberNavController @RequiresApi(Build.VERSION_CODES.O) @Composable fun SettingsScreen( - bottomPaddingValues: PaddingValues, - isBeingReloadedForDarkModeChange: Boolean + bottomPaddingValues: PaddingValues ) { val navController = rememberNavController() SettingsScreenNavHost( navController = navController, - bottomPaddingValues = bottomPaddingValues, - isBeingReloadedForDarkModeChange = isBeingReloadedForDarkModeChange + bottomPaddingValues = bottomPaddingValues ) } @@ -29,17 +27,11 @@ fun SettingsScreen( @Composable private fun SettingsScreenNavHost( navController: NavHostController, - bottomPaddingValues: PaddingValues, - isBeingReloadedForDarkModeChange: Boolean + bottomPaddingValues: PaddingValues ) { - val flag = remember{ mutableStateOf(false) } - val startDestination = if (isBeingReloadedForDarkModeChange && !flag.value) "display" else "main" - if (isBeingReloadedForDarkModeChange && !flag.value) { - flag.value = true - } val navigateToMain = { navController.navigate("main") } - NavHost(navController = navController, startDestination = startDestination) { + NavHost(navController = navController, startDestination = "main") { composable("main") { MainSettings( navController = navController, diff --git a/frontend/app/src/main/java/com/example/speechbuddy/compose/symbolselection/SymbolSearchTextField.kt b/frontend/app/src/main/java/com/example/speechbuddy/compose/symbolselection/SymbolSearchTextField.kt index c4683866..96f44130 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/compose/symbolselection/SymbolSearchTextField.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/compose/symbolselection/SymbolSearchTextField.kt @@ -49,15 +49,4 @@ fun SymbolSearchTextField( unfocusedBorderColor = MaterialTheme.colorScheme.surfaceVariant ) ) -} - -@Preview(showBackground = true) -@Composable -fun SymbolSearchTextFieldPreview() { - SpeechBuddyTheme { - SymbolSearchTextField( - value = "검색어", - onValueChange = {} - ) - } } \ No newline at end of file diff --git a/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/AlertDialogUi.kt b/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/AlertDialogUi.kt index 64e9d0e4..679ccb60 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/AlertDialogUi.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/AlertDialogUi.kt @@ -51,19 +51,4 @@ fun AlertDialogUi( }, containerColor = MaterialTheme.colorScheme.inverseOnSurface ) -} - -@Preview -@Composable -fun AlertDialogUiPreview() { - SpeechBuddyTheme { - AlertDialogUi( - title = "title", - text = "text", - dismissButtonText = "dismiss", - confirmButtonText = "confirm", - onDismiss = {}, - onConfirm = {} - ) - } } \ No newline at end of file diff --git a/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/ButtonUi.kt b/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/ButtonUi.kt index 288d00bd..1fa7761e 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/ButtonUi.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/ButtonUi.kt @@ -153,17 +153,4 @@ fun ButtonUi( Text(text = text, style = MaterialTheme.typography.titleMedium) } } -} - -@Preview -@Composable -fun ButtonUiPreview() { - SpeechBuddyTheme { - ButtonUi( - text = "커스텀 버튼", - onClick = {}, - isError = true, - level = ButtonLevel.SECONDARY - ) - } } \ No newline at end of file diff --git a/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/TextFieldUi.kt b/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/TextFieldUi.kt index e8d573f4..5ced6cf4 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/TextFieldUi.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/TextFieldUi.kt @@ -98,28 +98,4 @@ private fun getTextFieldColors(isValid: Boolean): TextFieldColors { focusedSupportingTextColor = MaterialTheme.colorScheme.tertiary, unfocusedSupportingTextColor = MaterialTheme.colorScheme.outline ) -} - -@Preview(showBackground = true) -@Composable -fun TextFieldUiPreview() { - SpeechBuddyTheme { - TextFieldUi( - value = "wrongaddress@email.com", - onValueChange = {}, - label = { Text("이메일") }, - supportingButton = { - ButtonUi( - text = "인증번호 발송", - onClick = {}, - isError = true, - level = ButtonLevel.TERTIARY - ) - }, - supportingText = { Text("잘못된 이메일 주소입니다.") }, - isError = true, - isValid = false, - isHidden = false, - ) - } } \ No newline at end of file diff --git a/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/TitleUi.kt b/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/TitleUi.kt index 3bcc636c..fd56442f 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/TitleUi.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/TitleUi.kt @@ -38,15 +38,4 @@ fun TitleUi( ) } } -} - -@Preview(showBackground = true) -@Composable -fun TitleUiPreview() { - SpeechBuddyTheme { - TitleUi( - title = stringResource(id = R.string.signup), - description = stringResource(id = R.string.signup_description) - ) - } } \ No newline at end of file diff --git a/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/TopAppBarUi.kt b/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/TopAppBarUi.kt index a06f15e3..09de2469 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/TopAppBarUi.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/compose/utils/TopAppBarUi.kt @@ -73,12 +73,4 @@ fun TopAppBarUi( titleContentColor = MaterialTheme.colorScheme.onSecondaryContainer ) ) -} - -@Preview -@Composable -fun TopAppBarUiPreview() { - SpeechBuddyTheme { - TopAppBarUi(title = "title", onBackClick = {}) - } } \ No newline at end of file diff --git a/frontend/app/src/main/java/com/example/speechbuddy/repository/SettingsRepository.kt b/frontend/app/src/main/java/com/example/speechbuddy/repository/SettingsRepository.kt index b77db5c9..4af84754 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/repository/SettingsRepository.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/repository/SettingsRepository.kt @@ -36,16 +36,11 @@ class SettingsRepository @Inject constructor( private val settingsRemoteSource: SettingsRemoteSource, private val converters: Converters, ) { - - private val _darkModeLiveData = MutableLiveData() - val darkModeLiveData: LiveData - get() = _darkModeLiveData - suspend fun setDarkMode(value: Boolean) { - CoroutineScope(Dispatchers.Main).launch { - if (_darkModeLiveData.value != value) { - _darkModeLiveData.value = value - } + if (value) { + settingsPrefManager.saveDarkMode(true) + } else { + settingsPrefManager.saveDarkMode(false) } settingsPrefManager.saveDarkMode(value) } @@ -72,6 +67,12 @@ class SettingsRepository @Inject constructor( } } + fun getDarkModeForChange(): Flow { + return settingsPrefManager.settingsPreferencesFlow.map { settingsPreferences -> + settingsPreferences.darkMode + } + } + fun getInitialPage(): Flow> { return settingsPrefManager.settingsPreferencesFlow.map { settingsPreferences -> Resource.success(settingsPreferences.initialPage) diff --git a/frontend/app/src/main/java/com/example/speechbuddy/ui/Theme.kt b/frontend/app/src/main/java/com/example/speechbuddy/ui/Theme.kt index 32bf4f76..2d7f063c 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/ui/Theme.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/ui/Theme.kt @@ -9,11 +9,19 @@ import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView import androidx.core.view.WindowCompat +import androidx.lifecycle.Observer +import com.example.speechbuddy.repository.SettingsRepository +import kotlinx.coroutines.flow.first private val _lightColorScheme = lightColorScheme( primary = md_theme_light_primary, @@ -81,18 +89,22 @@ private val _darkColorScheme = darkColorScheme( @Composable fun SpeechBuddyTheme( + settingsRepository: SettingsRepository, + initialDarkMode: Boolean, darkTheme: Boolean = isSystemInDarkTheme(), // Dynamic color is available on Android 12+ dynamicColor: Boolean = false, content: @Composable () -> Unit ) { + val darkModeState by settingsRepository.getDarkModeForChange().collectAsState(initialDarkMode) + val colorScheme = when { dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { val context = LocalContext.current if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) } - darkTheme -> _darkColorScheme + darkModeState -> _darkColorScheme else -> _lightColorScheme } val view = LocalView.current @@ -109,4 +121,5 @@ fun SpeechBuddyTheme( typography = Typography, content = content ) -} \ No newline at end of file +} +