mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2025-02-02 11:12:20 +00:00
Add a specific tab for mention on macOS and iPadOS fix #111
This commit is contained in:
parent
22c9d51941
commit
3e3e353fdd
6 changed files with 44 additions and 20 deletions
|
@ -4,6 +4,7 @@ import Network
|
||||||
import Notifications
|
import Notifications
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Timeline
|
import Timeline
|
||||||
|
import Models
|
||||||
|
|
||||||
struct NotificationsTab: View {
|
struct NotificationsTab: View {
|
||||||
@EnvironmentObject private var client: Client
|
@EnvironmentObject private var client: Client
|
||||||
|
@ -12,10 +13,12 @@ struct NotificationsTab: View {
|
||||||
@EnvironmentObject private var userPreferences: UserPreferences
|
@EnvironmentObject private var userPreferences: UserPreferences
|
||||||
@StateObject private var routerPath = RouterPath()
|
@StateObject private var routerPath = RouterPath()
|
||||||
@Binding var popToRootTab: Tab
|
@Binding var popToRootTab: Tab
|
||||||
|
|
||||||
|
let lockedType: Models.Notification.NotificationType?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $routerPath.path) {
|
NavigationStack(path: $routerPath.path) {
|
||||||
NotificationsListView()
|
NotificationsListView(lockedType: lockedType)
|
||||||
.withAppRouter()
|
.withAppRouter()
|
||||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import Status
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
enum Tab: Int, Identifiable, Hashable {
|
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 trending, federated, local
|
||||||
case profile
|
case profile
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ enum Tab: Int, Identifiable, Hashable {
|
||||||
|
|
||||||
static func loggedInTabs() -> [Tab] {
|
static func loggedInTabs() -> [Tab] {
|
||||||
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
|
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 {
|
} else {
|
||||||
return [.timeline, .notifications, .explore, .messages, .settings]
|
return [.timeline, .notifications, .explore, .messages, .settings]
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,9 @@ enum Tab: Int, Identifiable, Hashable {
|
||||||
case .federated:
|
case .federated:
|
||||||
TimelineTab(popToRootTab: popToRootTab, timeline: .federated)
|
TimelineTab(popToRootTab: popToRootTab, timeline: .federated)
|
||||||
case .notifications:
|
case .notifications:
|
||||||
NotificationsTab(popToRootTab: popToRootTab)
|
NotificationsTab(popToRootTab: popToRootTab, lockedType: nil)
|
||||||
|
case .mentions:
|
||||||
|
NotificationsTab(popToRootTab: popToRootTab, lockedType: .mention)
|
||||||
case .explore:
|
case .explore:
|
||||||
ExploreTab(popToRootTab: popToRootTab)
|
ExploreTab(popToRootTab: popToRootTab)
|
||||||
case .messages:
|
case .messages:
|
||||||
|
@ -62,6 +64,8 @@ enum Tab: Int, Identifiable, Hashable {
|
||||||
Label("Federated", systemImage: iconName)
|
Label("Federated", systemImage: iconName)
|
||||||
case .notifications:
|
case .notifications:
|
||||||
Label("Notifications", systemImage: iconName)
|
Label("Notifications", systemImage: iconName)
|
||||||
|
case .mentions:
|
||||||
|
Label("Notifications", systemImage: iconName)
|
||||||
case .explore:
|
case .explore:
|
||||||
Label("Explore", systemImage: iconName)
|
Label("Explore", systemImage: iconName)
|
||||||
case .messages:
|
case .messages:
|
||||||
|
@ -85,6 +89,8 @@ enum Tab: Int, Identifiable, Hashable {
|
||||||
return "globe.americas"
|
return "globe.americas"
|
||||||
case .notifications:
|
case .notifications:
|
||||||
return "bell"
|
return "bell"
|
||||||
|
case .mentions:
|
||||||
|
return "at"
|
||||||
case .explore:
|
case .explore:
|
||||||
return "magnifyingglass"
|
return "magnifyingglass"
|
||||||
case .messages:
|
case .messages:
|
||||||
|
|
|
@ -21,7 +21,7 @@ public enum Notifications: Endpoint {
|
||||||
var params = makePaginationParam(sinceId: sinceId, maxId: maxId, mindId: nil) ?? []
|
var params = makePaginationParam(sinceId: sinceId, maxId: maxId, mindId: nil) ?? []
|
||||||
if let types {
|
if let types {
|
||||||
for type in types {
|
for type in types {
|
||||||
params.append(.init(name: "types[]", value: type))
|
params.append(.init(name: "exclude_types[]", value: type))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return params
|
return params
|
||||||
|
|
|
@ -46,7 +46,7 @@ extension Models.Notification.NotificationType {
|
||||||
case .status:
|
case .status:
|
||||||
return "Post"
|
return "Post"
|
||||||
case .mention:
|
case .mention:
|
||||||
return "Mention"
|
return "Mentions"
|
||||||
case .reblog:
|
case .reblog:
|
||||||
return "Boost"
|
return "Boost"
|
||||||
case .follow:
|
case .follow:
|
||||||
|
|
|
@ -11,8 +11,12 @@ public struct NotificationsListView: View {
|
||||||
@EnvironmentObject private var watcher: StreamWatcher
|
@EnvironmentObject private var watcher: StreamWatcher
|
||||||
@EnvironmentObject private var client: Client
|
@EnvironmentObject private var client: Client
|
||||||
@StateObject private var viewModel = NotificationsViewModel()
|
@StateObject private var viewModel = NotificationsViewModel()
|
||||||
|
|
||||||
|
let lockedType: Models.Notification.NotificationType?
|
||||||
|
|
||||||
public init() {}
|
public init(lockedType: Models.Notification.NotificationType?) {
|
||||||
|
self.lockedType = lockedType
|
||||||
|
}
|
||||||
|
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
|
@ -23,21 +27,23 @@ public struct NotificationsListView: View {
|
||||||
.padding(.top, .layoutPadding + 16)
|
.padding(.top, .layoutPadding + 16)
|
||||||
.background(theme.primaryBackgroundColor)
|
.background(theme.primaryBackgroundColor)
|
||||||
}
|
}
|
||||||
.navigationTitle(viewModel.selectedType?.menuTitle() ?? "All Notifications")
|
.navigationTitle(lockedType?.menuTitle() ?? viewModel.selectedType?.menuTitle() ?? "All Notifications")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarTitleMenu {
|
if lockedType == nil {
|
||||||
Button {
|
ToolbarTitleMenu {
|
||||||
viewModel.selectedType = nil
|
|
||||||
} label: {
|
|
||||||
Label("All Notifications", systemImage: "bell.fill")
|
|
||||||
}
|
|
||||||
Divider()
|
|
||||||
ForEach(Notification.NotificationType.allCases, id: \.self) { type in
|
|
||||||
Button {
|
Button {
|
||||||
viewModel.selectedType = type
|
viewModel.selectedType = nil
|
||||||
} label: {
|
} 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)
|
.background(theme.primaryBackgroundColor)
|
||||||
.task {
|
.task {
|
||||||
viewModel.client = client
|
viewModel.client = client
|
||||||
|
if let lockedType {
|
||||||
|
viewModel.selectedType = lockedType
|
||||||
|
}
|
||||||
await viewModel.fetchNotifications()
|
await viewModel.fetchNotifications()
|
||||||
}
|
}
|
||||||
.refreshable {
|
.refreshable {
|
||||||
|
|
|
@ -39,7 +39,12 @@ class NotificationsViewModel: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
private var queryTypes: [String]? {
|
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] = []
|
private var notifications: [Models.Notification] = []
|
||||||
|
@ -98,7 +103,8 @@ class NotificationsViewModel: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleEvent(event: any StreamEvent) {
|
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.contains(where: { $0.id == event.notification.id })
|
||||||
{
|
{
|
||||||
notifications.insert(event.notification, at: 0)
|
notifications.insert(event.notification, at: 0)
|
||||||
|
|
Loading…
Reference in a new issue