Better handling of notifications

This commit is contained in:
Thomas Ricouard 2023-02-13 22:30:06 +01:00
parent 90199fc88b
commit 3d96d6997d
5 changed files with 24 additions and 29 deletions

View File

@ -57,9 +57,9 @@ struct IceCubesApp: App {
.edgesIgnoringSafeArea(.bottom)
.background(TransparentBackground())
})
.onChange(of: pushNotificationsService.routedNotification) { notification in
.onChange(of: pushNotificationsService.handleNotification) { notification in
if notification != nil {
pushNotificationsService.routedNotification = nil
pushNotificationsService.handleNotification = nil
selectedTab = .notifications
}
}

View File

@ -54,13 +54,16 @@ struct NotificationsTab: View {
routerPath.path = []
}
}
.onChange(of: pushNotificationsService.routedNotification) { notification in
if let notification {
.onChange(of: pushNotificationsService.handleNotification) { notification in
if let notification, let type = notification.supportedType {
DispatchQueue.main.async {
if let account = notification.accountId {
routerPath.navigate(to: .accountDetail(id: account))
} else if let status = notification.statusId {
routerPath.navigate(to: .statusDetail(id: status))
switch type {
case .follow, .follow_request:
routerPath.navigate(to: .accountDetailWithAccount(account: notification.account))
default:
if let status = notification.status {
routerPath.navigate(to: .statusDetailWithStatus(status: status))
}
}
}
}

View File

@ -26,18 +26,12 @@ public class PushNotificationsService: NSObject, ObservableObject {
static let keychainPrivateKey = "notifications_private_key"
}
public struct RoutedNotification: Equatable {
public let accessToken: String
public let statusId: String?
public let accountId: String?
}
public static let shared = PushNotificationsService()
public private(set) var subscriptions: [PushNotificationSubscriptionSettings] = []
@Published public var pushToken: Data?
@Published public var routedNotification: RoutedNotification?
@Published public var handleNotification: Models.Notification?
override init() {
super.init()
@ -137,21 +131,16 @@ public class PushNotificationsService: NSObject, ObservableObject {
extension PushNotificationsService: UNUserNotificationCenterDelegate {
public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
guard let plaintext = response.notification.request.content.userInfo["plaintext"] as? Data,
let mastodonPushNotification = try? JSONDecoder().decode(MastodonPushNotification.self, from: plaintext) else {
let mastodonPushNotification = try? JSONDecoder().decode(MastodonPushNotification.self, from: plaintext),
let account = subscriptions.first(where: { $0.account.token.accessToken == mastodonPushNotification.accessToken }) else {
return
}
if let type = Models.Notification.NotificationType(rawValue: mastodonPushNotification.notificationType) {
switch type {
case .follow, .follow_request:
self.routedNotification = .init(accessToken: mastodonPushNotification.accessToken,
statusId: nil,
accountId: String(mastodonPushNotification.notificationID))
default:
self.routedNotification = .init(accessToken: mastodonPushNotification.accessToken,
statusId: String(mastodonPushNotification.notificationID),
accountId: nil)
}
}
do {
let client = Client(server: account.account.server, oauthToken: account.account.token)
let notification: Models.Notification =
try await client.get(endpoint: Notifications.notification(id:String(mastodonPushNotification.notificationID)))
self.handleNotification = notification
} catch { }
}
}

View File

@ -1,6 +1,6 @@
import Foundation
public struct Notification: Decodable, Identifiable {
public struct Notification: Decodable, Identifiable, Equatable {
public enum NotificationType: String, CaseIterable {
case follow, follow_request, mention, reblog, status, favourite, poll, update
}

View File

@ -5,12 +5,15 @@ public enum Notifications: Endpoint {
maxId: String?,
types: [String]?,
limit: Int)
case notification(id: String)
case clear
public func path() -> String {
switch self {
case .notifications:
return "notifications"
case let .notification(id):
return "notifications/\(id)"
case .clear:
return "notifications/clear"
}