feat(tasks): P1 фундамент — 3-state видимость коллекций + разрешение по счётчикам
SmartListMode (HIDDEN/VISIBLE/AUTO) по семантике веб server-show 0/1/2. TasksSmartLists.counts()/visibleKeys() — сводка и разрешение видимых коллекций. 25 юнит-тестов зелёные. Далее: агрегация в VM + вывод в TasksListNavView. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -29,23 +29,36 @@ enum class SmartListKey(val title: String, val icon: String) {
|
||||
COMPLETED("Завершенные", "check-done-gray.svg"),
|
||||
}
|
||||
|
||||
/** Какие умные списки показывать в панели (шит «Параметры задач»). По умолчанию — все. */
|
||||
/**
|
||||
* Режим видимости умной коллекции в панели — как в веб-Tasks (server `show` 0/1/2):
|
||||
* [HIDDEN] всегда скрыта · [VISIBLE] всегда видима · [AUTO] видима только при count > 0.
|
||||
*/
|
||||
enum class SmartListMode { HIDDEN, VISIBLE, AUTO }
|
||||
|
||||
/**
|
||||
* Настройка видимости умных коллекций (шит «Параметры задач»). Хранит только НЕ-дефолтные
|
||||
* режимы — для компактной сериализации в SharedPreferences. Умолчание — [DEFAULT_MODE].
|
||||
*/
|
||||
data class SmartListVisibility(
|
||||
private val hidden: Set<SmartListKey> = emptySet(),
|
||||
private val modes: Map<SmartListKey, SmartListMode> = emptyMap(),
|
||||
) {
|
||||
fun isVisible(key: SmartListKey): Boolean = key !in hidden
|
||||
fun mode(key: SmartListKey): SmartListMode = modes[key] ?: DEFAULT_MODE
|
||||
|
||||
fun withVisible(key: SmartListKey, visible: Boolean): SmartListVisibility =
|
||||
SmartListVisibility(if (visible) hidden - key else hidden + key)
|
||||
fun withMode(key: SmartListKey, mode: SmartListMode): SmartListVisibility =
|
||||
SmartListVisibility(
|
||||
if (mode == DEFAULT_MODE) modes - key else modes + (key to mode),
|
||||
)
|
||||
|
||||
/** Ключи скрытых списков — для сериализации в SharedPreferences. */
|
||||
fun hiddenKeys(): Set<SmartListKey> = hidden
|
||||
/** Только заданные вручную (не-дефолтные) режимы — для персиста. */
|
||||
fun explicitModes(): Map<SmartListKey, SmartListMode> = modes
|
||||
|
||||
companion object {
|
||||
val ALL_VISIBLE = SmartListVisibility()
|
||||
/** Умолчание: AUTO (показывать при непустом счётчике) — сверить с сервером live. */
|
||||
val DEFAULT_MODE = SmartListMode.AUTO
|
||||
val DEFAULT = SmartListVisibility()
|
||||
|
||||
fun of(hidden: Collection<SmartListKey>): SmartListVisibility =
|
||||
SmartListVisibility(hidden.toSet())
|
||||
fun of(modes: Map<SmartListKey, SmartListMode>): SmartListVisibility =
|
||||
SmartListVisibility(modes.filterValues { it != DEFAULT_MODE })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +87,25 @@ object TasksSmartLists {
|
||||
fun count(key: SmartListKey, tasks: List<TaskItem>, today: LocalDate): Int =
|
||||
tasks.count { matches(key, it, today) }
|
||||
|
||||
/** Счётчики всех коллекций сразу (по агрегату задач всех списков). */
|
||||
fun counts(tasks: List<TaskItem>, today: LocalDate): Map<SmartListKey, Int> =
|
||||
SmartListKey.entries.associateWith { key -> count(key, tasks, today) }
|
||||
|
||||
/**
|
||||
* Коллекции для показа в панели (в порядке enum) с учётом режима видимости и счётчиков:
|
||||
* VISIBLE — всегда, AUTO — при count > 0, HIDDEN — никогда.
|
||||
*/
|
||||
fun visibleKeys(
|
||||
visibility: SmartListVisibility,
|
||||
counts: Map<SmartListKey, Int>,
|
||||
): List<SmartListKey> = SmartListKey.entries.filter { key ->
|
||||
when (visibility.mode(key)) {
|
||||
SmartListMode.VISIBLE -> true
|
||||
SmartListMode.HIDDEN -> false
|
||||
SmartListMode.AUTO -> (counts[key] ?: 0) > 0
|
||||
}
|
||||
}
|
||||
|
||||
/** Уже стартовала: нет start, либо start сегодня/в прошлом. */
|
||||
private fun TaskItem.hasStarted(today: LocalDate): Boolean {
|
||||
val start = startLocalDate() ?: return true
|
||||
|
||||
Reference in New Issue
Block a user