Add a specific tab for mention on macOS and iPadOS fix #111

This commit is contained in:
Thomas Ricouard 2023-01-19 07:24:24 +01:00
parent 22c9d51941
commit 3e3e353fdd
6 changed files with 44 additions and 20 deletions

View file

@ -4,6 +4,7 @@ import Network
import Notifications
import SwiftUI
import Timeline
import Models
struct NotificationsTab: View {
@EnvironmentObject private var client: Client
@ -13,9 +14,11 @@ struct NotificationsTab: View {
@StateObject private var routerPath = RouterPath()
@Binding var popToRootTab: Tab
let lockedType: Models.Notification.NotificationType?
var body: some View {
NavigationStack(path: $routerPath.path) {
NotificationsListView()
NotificationsListView(lockedType: lockedType)
.withAppRouter()
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
.toolbar {

View file

@ -5,7 +5,7 @@ import Status
import SwiftUI
enum Tab: Int, Identifiable, Hashable {
case timeline, notifications, explore, messages, settings, other
case timeline, notifications, mentions, explore, messages, settings, other
case trending, federated, local
case profile
@ -19,7 +19,7 @@ enum Tab: Int, Identifiable, Hashable {
static func loggedInTabs() -> [Tab] {
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
return [.timeline, .trending, .federated, .local, .notifications, .explore, .messages, .settings]
return [.timeline, .trending, .federated, .local, .notifications, .mentions, .explore, .messages, .settings]
} else {
return [.timeline, .notifications, .explore, .messages, .settings]
}
@ -37,7 +37,9 @@ enum Tab: Int, Identifiable, Hashable {
case .federated:
TimelineTab(popToRootTab: popToRootTab, timeline: .federated)
case .notifications:
NotificationsTab(popToRootTab: popToRootTab)
NotificationsTab(popToRootTab: popToRootTab, lockedType: nil)
case .mentions:
NotificationsTab(popToRootTab: popToRootTab, lockedType: .mention)
case .explore:
ExploreTab(popToRootTab: popToRootTab)
case .messages:
@ -62,6 +64,8 @@ enum Tab: Int, Identifiable, Hashable {
Label("Federated", systemImage: iconName)
case .notifications:
Label("Notifications", systemImage: iconName)
case .mentions:
Label("Notifications", systemImage: iconName)
case .explore:
Label("Explore", systemImage: iconName)
case .messages:
@ -85,6 +89,8 @@ enum Tab: Int, Identifiable, Hashable {
return "globe.americas"
case .notifications:
return "bell"
case .mentions:
return "at"
case .explore:
return "magnifyingglass"
case .messages:

View file

@ -21,7 +21,7 @@ public enum Notifications: Endpoint {
var params = makePaginationParam(sinceId: sinceId, maxId: maxId, mindId: nil) ?? []
if let types {
for type in types {
params.append(.init(name: "types[]", value: type))
params.append(.init(name: "exclude_types[]", value: type))
}
}
return params

View file

@ -46,7 +46,7 @@ extension Models.Notification.NotificationType {
case .status:
return "Post"
case .mention:
return "Mention"
return "Mentions"
case .reblog:
return "Boost"
case .follow:

View file

@ -12,7 +12,11 @@ public struct NotificationsListView: View {
@EnvironmentObject private var client: Client
@StateObject private var viewModel = NotificationsViewModel()
public init() {}
let lockedType: Models.Notification.NotificationType?
public init(lockedType: Models.Notification.NotificationType?) {
self.lockedType = lockedType
}
public var body: some View {
ScrollView {
@ -23,21 +27,23 @@ public struct NotificationsListView: View {
.padding(.top, .layoutPadding + 16)
.background(theme.primaryBackgroundColor)
}
.navigationTitle(viewModel.selectedType?.menuTitle() ?? "All Notifications")
.navigationTitle(lockedType?.menuTitle() ?? 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
if lockedType == nil {
ToolbarTitleMenu {
Button {
viewModel.selectedType = type
viewModel.selectedType = nil
} label: {
Label(type.menuTitle(), systemImage: type.iconName())
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())
}
}
}
}
@ -46,6 +52,9 @@ public struct NotificationsListView: View {
.background(theme.primaryBackgroundColor)
.task {
viewModel.client = client
if let lockedType {
viewModel.selectedType = lockedType
}
await viewModel.fetchNotifications()
}
.refreshable {

View file

@ -39,7 +39,12 @@ class NotificationsViewModel: ObservableObject {
}
private var queryTypes: [String]? {
selectedType != nil ? [selectedType!.rawValue] : nil
if let selectedType {
var excludedTypes = Models.Notification.NotificationType.allCases
excludedTypes.removeAll(where: { $0 == selectedType})
return excludedTypes.map{ $0.rawValue }
}
return nil
}
private var notifications: [Models.Notification] = []
@ -98,7 +103,8 @@ class NotificationsViewModel: ObservableObject {
}
func handleEvent(event: any StreamEvent) {
if let event = event as? StreamEventNotification,
if selectedType == nil,
let event = event as? StreamEventNotification,
!notifications.contains(where: { $0.id == event.notification.id })
{
notifications.insert(event.notification, at: 0)