fix(android settings): remove open delay — seed theme instead of a loading gate
The previous flicker fix gated the whole settings form behind a 'loaded' spinner, which read as a small lag when opening Settings (it waited for DataStore's first emit even though it's already warm). Instead, expose the applied theme id (NsColors.themeId, set in applyNsTheme) and seed the ViewModel's initial state with it, so the theme picker no longer jumps from the default — no gate, no spinner, no delay. Remaining text fields fill within a frame from the warm DataStore. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
711a084686
commit
d195518dfb
3 files changed
+5
-12
No files matched your search
@@ -67,15 +67,6 @@ fun SettingsScreen(onOpenStats: () -> Unit = {}) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the persisted settings before drawing the form — otherwise the default state
|
|
||||||
// (e.g. theme = Dark Ocean) flashes for a frame and then jumps to the real values.
|
|
||||||
if (!state.loaded) {
|
|
||||||
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
|
||||||
CircularProgressIndicator(color = NsAccent)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import androidx.compose.ui.graphics.Color
|
|||||||
|
|
||||||
// ── Dynamic theme state — Compose tracks reads automatically ─────────────────
|
// ── Dynamic theme state — Compose tracks reads automatically ─────────────────
|
||||||
object NsColors {
|
object NsColors {
|
||||||
|
var themeId by mutableStateOf("dark-ocean") // currently applied theme id (readable)
|
||||||
var accent by mutableStateOf(Color(0xFF4F8EF7))
|
var accent by mutableStateOf(Color(0xFF4F8EF7))
|
||||||
var accentDim by mutableStateOf(Color(0xFF2A6CD6))
|
var accentDim by mutableStateOf(Color(0xFF2A6CD6))
|
||||||
var bg by mutableStateOf(Color(0xFF070D14))
|
var bg by mutableStateOf(Color(0xFF070D14))
|
||||||
@@ -88,6 +89,7 @@ val NS_THEMES = listOf(
|
|||||||
|
|
||||||
fun applyNsTheme(themeId: String) {
|
fun applyNsTheme(themeId: String) {
|
||||||
val t = NS_THEMES.find { it.id == themeId } ?: NS_THEMES.first()
|
val t = NS_THEMES.find { it.id == themeId } ?: NS_THEMES.first()
|
||||||
|
NsColors.themeId = t.id
|
||||||
NsColors.accent = t.accent
|
NsColors.accent = t.accent
|
||||||
NsColors.accentDim = t.accentDim
|
NsColors.accentDim = t.accentDim
|
||||||
NsColors.bg = t.bg
|
NsColors.bg = t.bg
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import androidx.lifecycle.viewModelScope
|
|||||||
import com.novasonic.app.api.AbsClient
|
import com.novasonic.app.api.AbsClient
|
||||||
import com.novasonic.app.app
|
import com.novasonic.app.app
|
||||||
import com.novasonic.app.data.PrefsStore
|
import com.novasonic.app.data.PrefsStore
|
||||||
|
import com.novasonic.app.ui.theme.NsColors
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.engine.android.Android
|
import io.ktor.client.engine.android.Android
|
||||||
import io.ktor.client.plugins.HttpTimeout
|
import io.ktor.client.plugins.HttpTimeout
|
||||||
@@ -35,7 +36,6 @@ data class SettingsUiState(
|
|||||||
val absUrl: String = "",
|
val absUrl: String = "",
|
||||||
val absApiKey: String = "",
|
val absApiKey: String = "",
|
||||||
val absChapterTrackMode: Boolean = false,
|
val absChapterTrackMode: Boolean = false,
|
||||||
val loaded: Boolean = false,
|
|
||||||
val isSaving: Boolean = false,
|
val isSaving: Boolean = false,
|
||||||
val savedOk: Boolean = false,
|
val savedOk: Boolean = false,
|
||||||
val error: String? = null,
|
val error: String? = null,
|
||||||
@@ -48,7 +48,8 @@ class SettingsViewModel(app: Application) : AndroidViewModel(app) {
|
|||||||
|
|
||||||
private val repo = app.app.repository
|
private val repo = app.app.repository
|
||||||
|
|
||||||
private val _state = MutableStateFlow(SettingsUiState())
|
// Seed the theme with the already-applied one so the picker doesn't jump before DataStore emits.
|
||||||
|
private val _state = MutableStateFlow(SettingsUiState(theme = NsColors.themeId))
|
||||||
val state: StateFlow<SettingsUiState> = _state
|
val state: StateFlow<SettingsUiState> = _state
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -67,7 +68,6 @@ class SettingsViewModel(app: Application) : AndroidViewModel(app) {
|
|||||||
absUrl = s.absUrl,
|
absUrl = s.absUrl,
|
||||||
absApiKey = s.absApiKey,
|
absApiKey = s.absApiKey,
|
||||||
absChapterTrackMode = s.absChapterTrackMode,
|
absChapterTrackMode = s.absChapterTrackMode,
|
||||||
loaded = true,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user