From 1884853e4b35547935ede23adb630b2ba246e4cf Mon Sep 17 00:00:00 2001 From: Trey t Date: Sat, 25 Apr 2026 10:44:53 -0500 Subject: [PATCH] android: ResidenceViewModel.residenceTasksState derives from _allTasks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same screen contract, but the data flows from DataManager.allTasks through a combine(_allTasks, _currentResidenceId) into the existing StateFlow. No per-residence network call needed; the upstream getTasks() refresh propagates and the screen re-renders. Eliminates the gitea#2 race window on Android — same fix as the iOS TaskViewModel commit. Both platforms now react to _allTasks changes without manual refresh. --- .../honeyDue/viewmodel/ResidenceViewModel.kt | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/com/tt/honeyDue/viewmodel/ResidenceViewModel.kt b/composeApp/src/commonMain/kotlin/com/tt/honeyDue/viewmodel/ResidenceViewModel.kt index 8e1db03..9a3a850 100644 --- a/composeApp/src/commonMain/kotlin/com/tt/honeyDue/viewmodel/ResidenceViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/tt/honeyDue/viewmodel/ResidenceViewModel.kt @@ -70,15 +70,26 @@ class ResidenceViewModel( /** Drives the residence-scoped projections. */ private val _selectedResidenceId = MutableStateFlow(null) + /// Residence-scoped kanban derived from `DataManager.allTasks` filtered + /// by `_selectedResidenceId`. Single source of truth — eliminates the + /// gitea#2 race window where the per-residence cache slot could be + /// empty while `_allTasks` was populated. The per-residence cache + /// (`tasksByResidence`) was deleted in cec521b. val residenceTasksState: StateFlow> = - combine(_selectedResidenceId, dataManager.tasksByResidence) { id, map -> - if (id == null) ApiResult.Idle - else map[id]?.let { ApiResult.Success(it) } ?: ApiResult.Idle + combine(_selectedResidenceId, DataManager.allTasks) { id, all -> + when { + id == null -> ApiResult.Idle + all == null -> ApiResult.Loading + else -> { + val filtered = DataManager.getTasksForResidence(id) + if (filtered != null) ApiResult.Success(filtered) else ApiResult.Loading + } + } }.stateIn( viewModelScope, SharingStarted.Eagerly, _selectedResidenceId.value?.let { id -> - dataManager.tasksByResidence.value[id]?.let { ApiResult.Success(it) } + DataManager.getTasksForResidence(id)?.let { ApiResult.Success(it) } } ?: ApiResult.Idle, )