summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Hutch.xcodeproj/project.pbxproj16
-rw-r--r--Hutch/Views/Tickets/TicketListViewModel.swift31
2 files changed, 34 insertions, 13 deletions
diff --git a/Hutch.xcodeproj/project.pbxproj b/Hutch.xcodeproj/project.pbxproj
index befab2b..8f98e1b 100644
--- a/Hutch.xcodeproj/project.pbxproj
+++ b/Hutch.xcodeproj/project.pbxproj
@@ -515,7 +515,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 68;
+ CURRENT_PROJECT_VERSION = 69;
DEVELOPMENT_TEAM = ZCNAX3VL9D;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -532,7 +532,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 3.1.0;
+ MARKETING_VERSION = 3.1.1;
PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
PRODUCT_NAME = "$(TARGET_NAME)";
STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -552,7 +552,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 68;
+ CURRENT_PROJECT_VERSION = 69;
DEVELOPMENT_TEAM = ZCNAX3VL9D;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -569,7 +569,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 3.1.0;
+ MARKETING_VERSION = 3.1.1;
PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
PRODUCT_NAME = "$(TARGET_NAME)";
STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -632,7 +632,7 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 68;
+ CURRENT_PROJECT_VERSION = 69;
DEVELOPMENT_TEAM = ZCNAX3VL9D;
GENERATE_INFOPLIST_FILE = NO;
INFOPLIST_FILE = HutchWidgetExtension/Info.plist;
@@ -642,7 +642,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 3.1.0;
+ MARKETING_VERSION = 3.1.1;
PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -661,7 +661,7 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 68;
+ CURRENT_PROJECT_VERSION = 69;
DEVELOPMENT_TEAM = ZCNAX3VL9D;
GENERATE_INFOPLIST_FILE = NO;
INFOPLIST_FILE = HutchWidgetExtension/Info.plist;
@@ -671,7 +671,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 3.1.0;
+ MARKETING_VERSION = 3.1.1;
PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
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