From 3a9b7e16eae3fd2c9d00de5161c5b248eb007440 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Wed, 21 Oct 2026 17:32:37 +0200 Subject: [PATCH] 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. --- .../clockula/ui/settings/SettingsScreen.kt | 15 +++++++++++++++ .../clockula/ui/settings/SettingsViewModel.kt | 16 ++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt b/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt index b3b3ead..eaeda0d 100644 --- a/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt +++ b/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsScreen.kt @@ -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(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 diff --git a/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsViewModel.kt b/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsViewModel.kt index 11373d6..7d90968 100644 --- a/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsViewModel.kt +++ b/app/src/main/java/de/jeanlucmakiola/clockula/ui/settings/SettingsViewModel.kt @@ -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(null) @@ -80,13 +80,17 @@ class SettingsViewModel @Inject internal constructor( internal val launcherIcon: StateFlow = _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?>(null)