diff --git a/app/src/main/java/app/closer/MainActivity.kt b/app/src/main/java/app/closer/MainActivity.kt index f48f56db..15b2dfc3 100644 --- a/app/src/main/java/app/closer/MainActivity.kt +++ b/app/src/main/java/app/closer/MainActivity.kt @@ -5,6 +5,7 @@ import android.os.Bundle import android.util.Log import androidx.activity.compose.setContent import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.app.AppCompatDelegate import androidx.biometric.BiometricManager import androidx.biometric.BiometricPrompt import androidx.compose.foundation.layout.Box @@ -37,8 +38,10 @@ import app.closer.notifications.PartnerNotificationPayload import app.closer.notifications.PartnerNotificationType import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import app.closer.domain.repository.AppSettings import app.closer.domain.repository.AuthRepository import app.closer.domain.repository.SettingsRepository @@ -92,14 +95,30 @@ class MainActivity : AppCompatActivity() { registerFcmToken() pendingDeepLink.value = deepLinkRouteFromIntent(intent) if (BuildConfig.DEBUG) attemptDebugAutoLogin() + // Drive the REAL Configuration uiMode from the in-app theme (Settings → Appearance) so that + // `painterResource` and the `drawable-night*` variants follow the app's own theme, not just + // the Compose color scheme. Without this, in-app-Dark + system-Light shows light artwork on a + // dark UI (C-DARKART-002). Read the persisted theme synchronously here so the placeholder + // (default DEVICE) can never fight the persisted night-mode default and cause a recreation + // flicker loop; runtime toggles are handled by the LaunchedEffect below. + val initialSettings = runBlocking { settingsRepository.settings.first() } + AppCompatDelegate.setDefaultNightMode(nightModeFor(initialSettings.themeMode)) setContent { - val settings by settingsRepository.settings.collectAsState(initial = AppSettings()) + val settings by settingsRepository.settings.collectAsState(initial = initialSettings) val systemInDarkTheme = isSystemInDarkTheme() val useDarkTheme = when (settings.themeMode) { ThemeMode.DEVICE -> systemInDarkTheme ThemeMode.LIGHT -> false ThemeMode.DARK -> true } + // Apply runtime theme changes to the Configuration uiMode too (AppCompat recreates the + // Activity with the new uiMode so artwork re-resolves the correct -night variant). + LaunchedEffect(settings.themeMode) { + val target = nightModeFor(settings.themeMode) + if (AppCompatDelegate.getDefaultNightMode() != target) { + AppCompatDelegate.setDefaultNightMode(target) + } + } var sessionVerified by remember { mutableStateOf(false) } val needsBiometricLock = settings.biometricLoginEnabled @@ -133,6 +152,12 @@ class MainActivity : AppCompatActivity() { } } + private fun nightModeFor(mode: ThemeMode): Int = when (mode) { + ThemeMode.DEVICE -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM + ThemeMode.LIGHT -> AppCompatDelegate.MODE_NIGHT_NO + ThemeMode.DARK -> AppCompatDelegate.MODE_NIGHT_YES + } + override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) setIntent(intent)