diff options
| author | Christian Cleberg <[email protected]> | 2026-04-13 19:13:09 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-13 19:13:09 -0500 |
| commit | 6ec9754ce34f331641b000eddef3d44bca2631a5 (patch) | |
| tree | 83e5a78eb2f486e45c6f8192eb055012f0c4ace5 /Hutch | |
| parent | a6ad2b9815d72575206bdca860eef9db850cdf1c (diff) | |
| download | hutch-6ec9754ce34f331641b000eddef3d44bca2631a5.tar.gz hutch-6ec9754ce34f331641b000eddef3d44bca2631a5.tar.bz2 hutch-6ec9754ce34f331641b000eddef3d44bca2631a5.zip | |
fix(tickets): load all pages on tracker open for accurate Open tab
todo.sr.ht only exposes cursor-based `tracker.tickets` (no status filter),
so client-side Open filtering missed older open tickets when only the first
page was loaded. Paginate until the cursor is exhausted in loadTickets().
Fixes: https://todo.sr.ht/~ccleberg/hutch/62
Diffstat (limited to 'Hutch')
| -rw-r--r-- | Hutch/Views/Tickets/TicketListViewModel.swift | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/Hutch/Views/Tickets/TicketListViewModel.swift b/Hutch/Views/Tickets/TicketListViewModel.swift index 30e90a7..18a0a5b 100644 --- a/Hutch/Views/Tickets/TicketListViewModel.swift +++ b/Hutch/Views/Tickets/TicketListViewModel.swift @@ -299,13 +299,34 @@ final class TicketListViewModel { hasMore = true do { - let page = try await fetchPage(cursor: nil) - tickets = page.results - cursor = page.cursor - hasMore = page.cursor != nil + // todo.sr.ht exposes `tickets(cursor:)` only (see Docs/API/todo.json) — no server-side + // status filter. The Open tab filters client-side, so we paginate until the cursor is + // exhausted; otherwise older open tickets never appear in the first page (25 items). + var accumulated: [TicketSummary] = [] + var nextCursor: String? + + repeat { + let page = try await fetchPage(cursor: nextCursor) + + let existingIDs = Set(accumulated.map(\.id)) + let newTickets = page.results.filter { !existingIDs.contains($0.id) } + + if newTickets.isEmpty && !page.results.isEmpty { + break + } + + accumulated.append(contentsOf: newTickets) + nextCursor = page.cursor + } while nextCursor != nil + + tickets = accumulated + cursor = nextCursor + hasMore = nextCursor != nil reconcileSelectionWithLoadedTickets() } catch { - self.error = error.userFacingMessage + if !Task.isCancelled { + self.error = error.userFacingMessage + } } isLoading = false |
