The phone's list learns a second order — sort boards by name or by recency

A segmented control above the mobile board list, remembered across
launches: Name keeps the index's stable title order, Recent sorts by
content-change date descending with undated boards last and ties held
stable against refresh reshuffling.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-08-08 12:21:35 -04:00
parent 09a21cf5a0
commit 8cf1457814
4 changed files with 70 additions and 2 deletions
+40
View File
@@ -35,6 +35,46 @@ struct BoardSummary: Identifiable, Sendable, Equatable {
let location: BoardLocation
}
/// How the boards tab orders its merged list. Raw values are persisted (`AppStorage`), so they are
/// API changing a case's raw value would silently reset every user's remembered choice.
enum BoardSortOrder: String, CaseIterable, Sendable {
case name
case recent
}
extension BoardSortOrder {
/// Orders `boards` for display without touching the two-home merge that produced them.
///
/// **`.name` is a no-op.** `BoardIndexStore` already publishes its list in title order
/// case/diacritic-insensitive, path as the tie-break so re-sorting here would just repeat work
/// already done upstream.
///
/// **`.recent` sorts by `modified` descending, with `nil` last.** Ties equal dates, and every
/// `nil` among them keep the incoming order: Swift's `sort` is not a stable sort, so the
/// comparator breaks ties on each board's original offset rather than leaving equal rows free to
/// swap places on every refresh.
nonisolated func sorted(_ boards: [BoardSummary]) -> [BoardSummary] {
switch self {
case .name:
return boards
case .recent:
return boards.enumerated().sorted { lhs, rhs in
switch (lhs.element.modified, rhs.element.modified) {
case let (l?, r?) where l != r:
return l > r
case (nil, .some):
return false
case (.some, nil):
return true
default:
return lhs.offset < rhs.offset
}
}.map(\.element)
}
}
}
/// Where a board is stored, and therefore whether it syncs.
///
/// **Told, never sniffed.** A location is what the home an entry was enumerated from *is*, so the