fix: refresh the Settings problem count on return

The hub read the self-check once, so after fixing something in the
self-check screen it kept showing the old number of problems. It now
re-reads on every resume, as the self-check screen does.
This commit is contained in:
2026-10-21 17:32:37 +02:00
parent f9f2bdc9a8
commit 3a9b7e16ea
2 changed files with 25 additions and 6 deletions
@@ -29,6 +29,7 @@ import androidx.compose.material.icons.filled.Timer
import androidx.compose.material.icons.filled.Translate
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -42,6 +43,9 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import de.jeanlucmakiola.clockula.R
import de.jeanlucmakiola.clockula.domain.Ringtones
@@ -87,6 +91,17 @@ fun SettingsScreen(
val previewPlaying by viewModel.previewPlaying.collectAsStateWithLifecycle()
val zonePicker by viewModel.zonePicker.collectAsStateWithLifecycle()
var section by rememberSaveable { mutableStateOf<SettingsSection?>(null) }
val lifecycleOwner = LocalLifecycleOwner.current
// The hub's problem count, re-read on return from the self-check screen or
// from a system settings page it sent the user to.
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME) viewModel.refreshSelfCheck()
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose { lifecycleOwner.lifecycle.removeObserver(observer) }
}
// Registered unconditionally, for the same reason the alarm editor's is
// (M5 D20): the picker's open flag is ViewModel state that does not
@@ -57,9 +57,9 @@ class SettingsViewModel @Inject internal constructor(
) : ViewModel() {
/**
* Null until the one-off self-check read completes. Not live/ticking —
* the row only needs to be right when the hub is opened; the self-check
* screen itself re-reads on every visit.
* Null until the first self-check read completes. Not live/ticking:
* the hub re-reads it on every `ON_RESUME` ([refreshSelfCheck]), so a fix
* made in the self-check screen or in system settings shows on return.
*/
private val selfCheckProblemCount = MutableStateFlow<Int?>(null)
@@ -80,13 +80,17 @@ class SettingsViewModel @Inject internal constructor(
internal val launcherIcon: StateFlow<LauncherIcon> = _launcherIcon.asStateFlow()
init {
refreshSelfCheck()
viewModelScope.launch {
_launcherIcon.value = withContext(io) { launcherIcons.current() }
}
}
fun refreshSelfCheck() {
viewModelScope.launch {
val results = SelfCheck.evaluate(deviceState.read())
selfCheckProblemCount.value = results.count { it.status == CheckStatus.PROBLEM }
}
viewModelScope.launch {
_launcherIcon.value = withContext(io) { launcherIcons.current() }
}
}
private val _ringtonePicker = MutableStateFlow<Pair<DefaultRingtoneKind, RingtonePickerUiState>?>(null)