fix(ui): sync Activity uiMode to in-app theme at startup (C-DARKART-002 architectural fix)

This commit is contained in:
null 2026-06-28 16:35:01 -05:00
parent 4ee600125d
commit c3a3c38e0e
1 changed files with 26 additions and 1 deletions

View File

@ -5,6 +5,7 @@ import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.biometric.BiometricManager import androidx.biometric.BiometricManager
import androidx.biometric.BiometricPrompt import androidx.biometric.BiometricPrompt
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -37,8 +38,10 @@ import app.closer.notifications.PartnerNotificationPayload
import app.closer.notifications.PartnerNotificationType import app.closer.notifications.PartnerNotificationType
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import app.closer.domain.repository.AppSettings import app.closer.domain.repository.AppSettings
import app.closer.domain.repository.AuthRepository import app.closer.domain.repository.AuthRepository
import app.closer.domain.repository.SettingsRepository import app.closer.domain.repository.SettingsRepository
@ -92,14 +95,30 @@ class MainActivity : AppCompatActivity() {
registerFcmToken() registerFcmToken()
pendingDeepLink.value = deepLinkRouteFromIntent(intent) pendingDeepLink.value = deepLinkRouteFromIntent(intent)
if (BuildConfig.DEBUG) attemptDebugAutoLogin() 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 { setContent {
val settings by settingsRepository.settings.collectAsState(initial = AppSettings()) val settings by settingsRepository.settings.collectAsState(initial = initialSettings)
val systemInDarkTheme = isSystemInDarkTheme() val systemInDarkTheme = isSystemInDarkTheme()
val useDarkTheme = when (settings.themeMode) { val useDarkTheme = when (settings.themeMode) {
ThemeMode.DEVICE -> systemInDarkTheme ThemeMode.DEVICE -> systemInDarkTheme
ThemeMode.LIGHT -> false ThemeMode.LIGHT -> false
ThemeMode.DARK -> true 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) } var sessionVerified by remember { mutableStateOf(false) }
val needsBiometricLock = settings.biometricLoginEnabled 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) { override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent) super.onNewIntent(intent)
setIntent(intent) setIntent(intent)