From 8a8c7a7e5e7bc65bf2113a743280ed56db59c8c3 Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Wed, 4 Jan 2023 08:14:37 +0100 Subject: [PATCH] Better filter for notifications --- .../Models/Sources/Models/Notification.swift | 2 +- .../Notifications/NotificationRowView.swift | 43 +------------ .../Notifications/NotificationTypeExt.swift | 64 +++++++++++++++++++ .../Notifications/NotificationsListView.swift | 38 ++++++----- .../NotificationsViewModel.swift | 8 +-- 5 files changed, 92 insertions(+), 63 deletions(-) create mode 100644 Packages/Notifications/Sources/Notifications/NotificationTypeExt.swift diff --git a/Packages/Models/Sources/Models/Notification.swift b/Packages/Models/Sources/Models/Notification.swift index 123e298d..eb2c4bfe 100644 --- a/Packages/Models/Sources/Models/Notification.swift +++ b/Packages/Models/Sources/Models/Notification.swift @@ -1,7 +1,7 @@ import Foundation public struct Notification: Codable, Identifiable { - public enum NotificationType: String { + public enum NotificationType: String, CaseIterable { case follow, follow_request, mention, reblog, status, favourite, poll, update } diff --git a/Packages/Notifications/Sources/Notifications/NotificationRowView.swift b/Packages/Notifications/Sources/Notifications/NotificationRowView.swift index 527f9ea8..90151198 100644 --- a/Packages/Notifications/Sources/Notifications/NotificationRowView.swift +++ b/Packages/Notifications/Sources/Notifications/NotificationRowView.swift @@ -76,6 +76,7 @@ struct NotificationRowView: View { if let status = notification.status { HStack { StatusRowView(viewModel: .init(status: status, isCompact: true)) + .foregroundColor(type == .mention ? theme.labelColor : .gray) Spacer() } } else { @@ -102,48 +103,6 @@ struct NotificationRowView: View { } } -extension Models.Notification.NotificationType { - func label() -> String { - switch self { - case .status: - return "posted a status" - case .mention: - return "mentioned you" - case .reblog: - return "boosted" - case .follow: - return "followed you" - case .follow_request: - return "request to follow you" - case .favourite: - return "starred" - case .poll: - return "poll ended" - case .update: - return "edited a post" - } - } - - func iconName() -> String { - switch self { - case .status: - return "pencil" - case .mention: - return "at" - case .reblog: - return "arrow.left.arrow.right.circle.fill" - case .follow, .follow_request: - return "person.fill.badge.plus" - case .favourite: - return "star.fill" - case .poll: - return "chart.bar.fill" - case .update: - return "pencil.line" - } - } -} - struct NotificationRowView_Previews: PreviewProvider { static var previews: some View { NotificationRowView(notification: .placeholder()) diff --git a/Packages/Notifications/Sources/Notifications/NotificationTypeExt.swift b/Packages/Notifications/Sources/Notifications/NotificationTypeExt.swift new file mode 100644 index 00000000..548324b1 --- /dev/null +++ b/Packages/Notifications/Sources/Notifications/NotificationTypeExt.swift @@ -0,0 +1,64 @@ +import Models + +extension Models.Notification.NotificationType { + func label() -> String { + switch self { + case .status: + return "posted a status" + case .mention: + return "mentioned you" + case .reblog: + return "boosted" + case .follow: + return "followed you" + case .follow_request: + return "request to follow you" + case .favourite: + return "starred" + case .poll: + return "poll ended" + case .update: + return "edited a post" + } + } + + func iconName() -> String { + switch self { + case .status: + return "pencil" + case .mention: + return "at" + case .reblog: + return "arrow.left.arrow.right.circle.fill" + case .follow, .follow_request: + return "person.fill.badge.plus" + case .favourite: + return "star.fill" + case .poll: + return "chart.bar.fill" + case .update: + return "pencil.line" + } + } + + func menuTitle() -> String { + switch self { + case .status: + return "Post" + case .mention: + return "Mention" + case .reblog: + return "Boost" + case .follow: + return "Follow" + case .follow_request: + return "Follow Request" + case .favourite: + return "Favorite" + case .poll: + return "Poll" + case .update: + return "Post Edited" + } + } +} diff --git a/Packages/Notifications/Sources/Notifications/NotificationsListView.swift b/Packages/Notifications/Sources/Notifications/NotificationsListView.swift index 0e93e107..bf40f5b8 100644 --- a/Packages/Notifications/Sources/Notifications/NotificationsListView.swift +++ b/Packages/Notifications/Sources/Notifications/NotificationsListView.swift @@ -16,25 +16,33 @@ public struct NotificationsListView: View { public var body: some View { ScrollView { LazyVStack { - if client.isAuth { - Picker("", selection: $viewModel.tab) { - ForEach(NotificationsViewModel.Tab.allCases, id: \.self) { tab in - Text(tab.rawValue) - } - } - .pickerStyle(.segmented) - Group { - notificationsView - } - .padding(.top, 16) - } else { - Text("Please Sign In to see your notifications") - .font(.title3) + Group { + notificationsView } + .padding(.top, 16) } .padding(.horizontal, .layoutPadding) .padding(.top, .layoutPadding) } + .navigationTitle(viewModel.selectedType?.menuTitle() ?? "All Notifications") + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarTitleMenu { + Button { + viewModel.selectedType = nil + } label: { + Label("All Notifications", systemImage: "bell.fill") + } + Divider() + ForEach(Notification.NotificationType.allCases, id: \.self) { type in + Button { + viewModel.selectedType = type + } label: { + Label(type.menuTitle(), systemImage: type.iconName()) + } + } + } + } .background(theme.primaryBackgroundColor) .task { viewModel.client = client @@ -48,8 +56,6 @@ public struct NotificationsListView: View { viewModel.handleEvent(event: latestEvent) } }) - .navigationTitle(Text("Notifications")) - .navigationBarTitleDisplayMode(.inline) } @ViewBuilder diff --git a/Packages/Notifications/Sources/Notifications/NotificationsViewModel.swift b/Packages/Notifications/Sources/Notifications/NotificationsViewModel.swift index e007ae4f..c5dd2d4a 100644 --- a/Packages/Notifications/Sources/Notifications/NotificationsViewModel.swift +++ b/Packages/Notifications/Sources/Notifications/NotificationsViewModel.swift @@ -27,7 +27,7 @@ class NotificationsViewModel: ObservableObject { } } @Published var state: State = .loading - @Published var tab: Tab = .all { + @Published var selectedType: Models.Notification.NotificationType? { didSet { notifications = [] Task { @@ -35,11 +35,11 @@ class NotificationsViewModel: ObservableObject { } } } + private var queryTypes: [String]? { + selectedType != nil ? [selectedType!.rawValue] : nil + } private var notifications: [Models.Notification] = [] - private var queryTypes: [String]? { - tab == .mentions ? ["mention"] : nil - } func fetchNotifications() async { guard let client else { return }