feat: Mark All as Read — bulk action with optimistic UI and rollback
APIClient: - markAllRead(storyIds💊) — POST /me/read/bulk with device ID, timestamp, source label, and pill name so backend can record context Models: - PaginatedStories gains unreadCount, readSuppressedCount, lastReadSyncAt, activePill — backend now returns these so the UI can report honest state SignalFeedView: - Header "…" menu replaces the standalone settings button; menu contains "Mark all as read" (disabled while pending or when nothing is unread) and a Settings item - markAllRead() captures all visible unread IDs, optimistically inserts ReadStory for each, shows toast ("Marked N stories as read"), then fires the bulk API; on failure deletes the optimistic ReadStory records and shows an honest error toast ("Sync failed. Stories may reappear until retry.") - Toast auto-dismisses after 3.5s, appears at the bottom of the ZStack with a slide-up + opacity animation Cross-pill suppression was already in place — backend applies unread_story_condition() to every /stories request regardless of tags, so stories marked read in All disappear from Tech, Sport, etc. on the next pill fetch. Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
This commit is contained in:
@@ -136,6 +136,10 @@ struct PaginatedStories: Codable {
|
||||
let nextCursor: String?
|
||||
let hasMore: Bool
|
||||
let total: Int
|
||||
let unreadCount: Int?
|
||||
let readSuppressedCount: Int?
|
||||
let lastReadSyncAt: Date?
|
||||
let activePill: String?
|
||||
}
|
||||
|
||||
// MARK: - WebSocket Events
|
||||
|
||||
Reference in New Issue
Block a user