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
This commit is contained in:
@@ -3,7 +3,7 @@ import Foundation
|
||||
// MARK: - Service Protocol
|
||||
|
||||
protocol NotificationsServiceProtocol: Sendable {
|
||||
func list(params: NotificationListParams) async throws -> [NotificationItem]
|
||||
func list(params: NotificationListParams = NotificationListParams()) async throws -> [NotificationItem]
|
||||
func markAsRead(id: String) async throws
|
||||
func markAllAsRead() async throws
|
||||
func getUnreadCount() async throws -> Int
|
||||
|
||||
@@ -54,7 +54,6 @@ class NotificationsViewModel: ObservableObject {
|
||||
try await notificationsService.markAsRead(id: id)
|
||||
notifications[index].isRead = true
|
||||
badgeCount = max(0, badgeCount - 1)
|
||||
objectWillChange.send()
|
||||
} catch {
|
||||
print("Failed to mark notification as read: \(error)")
|
||||
}
|
||||
@@ -70,7 +69,6 @@ class NotificationsViewModel: ObservableObject {
|
||||
notifications[index].isRead = true
|
||||
}
|
||||
badgeCount = 0
|
||||
objectWillChange.send()
|
||||
} catch {
|
||||
print("Failed to mark all as read: \(error)")
|
||||
}
|
||||
|
||||
@@ -43,10 +43,14 @@ struct NotificationRowView: View {
|
||||
}
|
||||
|
||||
private func formatTimestamp(_ date: Date) -> String {
|
||||
Self.formatter.localizedString(for: date, relativeTo: Date())
|
||||
}
|
||||
|
||||
private static let formatter: RelativeDateTimeFormatter = {
|
||||
let formatter = RelativeDateTimeFormatter()
|
||||
formatter.unitsStyle = .abbreviated
|
||||
return formatter.localizedString(for: date, relativeTo: Date())
|
||||
}
|
||||
return formatter
|
||||
}()
|
||||
}
|
||||
|
||||
#Preview {
|
||||
|
||||
@@ -9,7 +9,7 @@ struct NotificationsView: View {
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
NavigationStack {
|
||||
Group {
|
||||
if viewModel.notifications.isEmpty && !viewModel.isLoading {
|
||||
emptyStateView
|
||||
@@ -18,7 +18,6 @@ struct NotificationsView: View {
|
||||
}
|
||||
}
|
||||
.navigationTitle("Notifications")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
if !viewModel.notifications.isEmpty {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
@@ -57,7 +56,15 @@ struct NotificationsView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.onDelete(perform: deleteNotifications)
|
||||
.onDelete { offsets in
|
||||
Task {
|
||||
for index in offsets {
|
||||
let notification = viewModel.notifications[index]
|
||||
await viewModel.markAsRead(id: notification.id)
|
||||
}
|
||||
viewModel.notifications.remove(atOffsets: offsets)
|
||||
}
|
||||
}
|
||||
}
|
||||
.listStyle(.insetGrouped)
|
||||
.refreshable {
|
||||
@@ -82,16 +89,7 @@ struct NotificationsView: View {
|
||||
.multilineTextAlignment(.center)
|
||||
.padding(.horizontal, 32)
|
||||
}
|
||||
.padding(.vertical, 60)
|
||||
}
|
||||
|
||||
private func deleteNotifications(at offsets: IndexSet) async {
|
||||
// TODO: Implement notification deletion logic
|
||||
// This would typically call a delete API endpoint
|
||||
for index in offsets {
|
||||
let notification = viewModel.notifications[index]
|
||||
// await notificationsService.delete(id: notification.id)
|
||||
}
|
||||
.padding(.vertical, 60)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user