From 0b26c02d5a60b73e588c945b82fcf8c42366db0f Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 11 Jul 2026 17:56:05 +0000 Subject: [PATCH] Feed smart-hidden chores into the chore list's hidden section Chores filtered out by smart visibility previously vanished with no way to reveal them from the chores screen, and the collapsed section's label still described the old fixed 60-day distant rule. The section now shows everything the active visibility mechanic hides: all chores beyond their cadence lead time when smart visibility is on, or the legacy distant chores when it is off, with the label matching the active mechanic. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01PkGAjWNwYwrFbDihgjqqvs --- .../dash/ui/screens/chores/ChoreListScreen.kt | 22 ++++---- .../ui/screens/chores/ChoreListViewModel.kt | 50 ++++++++++++------- .../unreleased/hidden-chores-section.json | 9 ++++ 3 files changed, 53 insertions(+), 28 deletions(-) create mode 100644 changelog/unreleased/hidden-chores-section.json diff --git a/app/src/main/java/com/mapgie/dash/ui/screens/chores/ChoreListScreen.kt b/app/src/main/java/com/mapgie/dash/ui/screens/chores/ChoreListScreen.kt index bbca99e..d4abd4f 100644 --- a/app/src/main/java/com/mapgie/dash/ui/screens/chores/ChoreListScreen.kt +++ b/app/src/main/java/com/mapgie/dash/ui/screens/chores/ChoreListScreen.kt @@ -234,7 +234,7 @@ fun ChoreListScreen( else -> { val displayed = uiState.displayed - val distantChores = uiState.distantChores + val hiddenChores = uiState.hiddenChores LazyColumn( modifier = Modifier.fillMaxSize(), contentPadding = PaddingValues(bottom = 88.dp) @@ -281,24 +281,28 @@ fun ChoreListScreen( } } - if (distantChores.isNotEmpty()) { + if (hiddenChores.isNotEmpty()) { item { TextButton( - onClick = { viewModel.toggleShowDistant() }, + onClick = { viewModel.toggleShowHidden() }, modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp) ) { Text( - if (uiState.showDistant) - "Hide distant (${distantChores.size})" - else - "${distantChores.size} not due for 60+ days", + when { + uiState.showHidden -> + "Collapse hidden chores (${hiddenChores.size})" + uiState.smartVisibility -> + "${hiddenChores.size} hidden until closer to due" + else -> + "${hiddenChores.size} not due for 60+ days" + }, style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurfaceVariant ) } } - if (uiState.showDistant) { - items(distantChores, key = { "distant_${it.id}" }) { chore -> + if (uiState.showHidden) { + items(hiddenChores, key = { "hidden_${it.id}" }) { chore -> SwipeToLogCard( chore = chore, showOwner = uiState.ownerFilter == OwnerFilter.ALL, diff --git a/app/src/main/java/com/mapgie/dash/ui/screens/chores/ChoreListViewModel.kt b/app/src/main/java/com/mapgie/dash/ui/screens/chores/ChoreListViewModel.kt index b40e895..b54aa46 100644 --- a/app/src/main/java/com/mapgie/dash/ui/screens/chores/ChoreListViewModel.kt +++ b/app/src/main/java/com/mapgie/dash/ui/screens/chores/ChoreListViewModel.kt @@ -51,7 +51,7 @@ data class ChoreUiState( val zenMode: Boolean = false, val zenSortAscending: Boolean = true, val showDueCountdown: Boolean = false, - val showDistant: Boolean = false, + val showHidden: Boolean = false, // Off until settings load so chores aren't hidden with unconfigured lead times val smartVisibility: Boolean = false, val choreLeadDays: Map = emptyMap(), @@ -60,31 +60,43 @@ data class ChoreUiState( val pinnedChoreId: String? = null, val scanHistory: List = emptyList() ) { - val distantChores: List + private val ownerFiltered: List get() { var result = active if (ownerFilter == OwnerFilter.ME && ownerHandle.isNotBlank()) { result = result.filter { it.owner == null || it.owner == ownerHandle } } - return result.filter { it.isDistant() } + return result + } + + /** True if this chore belongs in the main list under its cadence bucket's lead time. */ + private fun withinLeadTime(chore: Chore): Boolean { + val last = chore.lastScanned ?: return true + val intervalDays = chore.intervalDays ?: return true + val bucket = CadenceBucket.forInterval(intervalDays) + val leadDays = choreLeadDays[bucket] ?: bucket.defaultLeadDays + val dueInstant = last.plus((intervalDays * 24).toLong(), ChronoUnit.HOURS) + return Duration.between(Instant.now(), dueInstant).toDays() <= leadDays + } + + /** + * Chores kept out of the main list but revealable via the collapsed section: + * everything beyond its lead time when smart visibility is on, otherwise only + * the legacy distant (due 60+ days out) chores. + */ + val hiddenChores: List + get() = if (smartVisibility) { + ownerFiltered.filterNot(::withinLeadTime) + } else { + ownerFiltered.filter { it.isDistant() } } val displayed: List get() { - var result = active - if (ownerFilter == OwnerFilter.ME && ownerHandle.isNotBlank()) { - result = result.filter { it.owner == null || it.owner == ownerHandle } - } - result = result.filter { !it.isDistant() } - if (smartVisibility) { - result = result.filter { chore -> - val last = chore.lastScanned ?: return@filter true - val intervalDays = chore.intervalDays ?: return@filter true - val bucket = CadenceBucket.forInterval(intervalDays) - val leadDays = choreLeadDays[bucket] ?: bucket.defaultLeadDays - val dueInstant = last.plus((intervalDays * 24).toLong(), ChronoUnit.HOURS) - Duration.between(Instant.now(), dueInstant).toDays() <= leadDays - } + var result = if (smartVisibility) { + ownerFiltered.filter(::withinLeadTime) + } else { + ownerFiltered.filter { !it.isDistant() } } result = when (filter) { ChoreFilter.ALL -> result @@ -320,7 +332,7 @@ class ChoreListViewModel @Inject constructor( viewModelScope.launch { settingsRepository.setShowDueCountdown(enabled) } } - fun toggleShowDistant() { - _uiState.update { it.copy(showDistant = !it.showDistant) } + fun toggleShowHidden() { + _uiState.update { it.copy(showHidden = !it.showHidden) } } } \ No newline at end of file diff --git a/changelog/unreleased/hidden-chores-section.json b/changelog/unreleased/hidden-chores-section.json new file mode 100644 index 0000000..cd2846b --- /dev/null +++ b/changelog/unreleased/hidden-chores-section.json @@ -0,0 +1,9 @@ +{ + "bump": "patch", + "changed": [ + "The collapsed section at the bottom of the chores list now reveals everything hidden by smart visibility, not just chores due 60+ days out, and its label reflects why chores are hidden" + ], + "fixed": [ + "Chores hidden by smart visibility could not be viewed or logged from the chores screen" + ] +}