Files
FrenoCorp/Lendair/ViewModels/NotificationsViewModel.swift
Michael Freno ad6b4c9c1c fix: Address code review findings for NotificationsView (FRE-4737)
- P0: Add default param to protocol list(params:) for compile fix
- P1: Fix onDelete async closure, implement deletion logic
- P2: Remove redundant objectWillChange.send() (Published handles it)
- P2: Make RelativeDateTimeFormatter static singleton (per-row perf)
- P3: Replace deprecated NavigationView with NavigationStack
2026-05-10 04:38:12 -04:00

81 lines
2.4 KiB
Swift

import Foundation
import SwiftUI
@MainActor
class NotificationsViewModel: ObservableObject {
@Published var notifications: [NotificationItem] = []
@Published var isLoading: Bool = false
@Published var badgeCount: Int = 0
@Published var lastRefreshDate: Date?
@Published var error: NotificationError?
private let notificationsService: NotificationsServiceProtocol
init(notificationsService: NotificationsServiceProtocol = NotificationsService()) {
self.notificationsService = notificationsService
}
func fetchNotifications() async {
isLoading = true
error = nil
defer {
isLoading = false
lastRefreshDate = Date()
}
do {
let fetchedNotifications = try await notificationsService.list()
notifications = fetchedNotifications.sorted { $0.createdAt > $1.createdAt }
badgeCount = notifications.filter { !$0.isRead }.count
} catch let error as NotificationError {
self.error = error
} catch {
print("Failed to fetch notifications: \(error)")
}
}
func refresh() async {
await fetchNotifications()
}
func fetchUnreadCount() async {
do {
let count = try await notificationsService.getUnreadCount()
badgeCount = count
} catch {
print("Failed to fetch unread count: \(error)")
}
}
func markAsRead(id: String) async {
guard let index = notifications.firstIndex(where: { $0.id == id }) else { return }
do {
try await notificationsService.markAsRead(id: id)
notifications[index].isRead = true
badgeCount = max(0, badgeCount - 1)
} catch {
print("Failed to mark notification as read: \(error)")
}
}
func markAllAsRead() async {
let unreadIds = notifications.filter { !$0.isRead }.map { $0.id }
guard !unreadIds.isEmpty else { return }
do {
try await notificationsService.markAllAsRead()
for index in notifications.indices {
notifications[index].isRead = true
}
badgeCount = 0
} catch {
print("Failed to mark all as read: \(error)")
}
}
var unreadCount: Int {
notifications.filter { !$0.isRead }.count
}
}