Route to push notifications on selection
This commit is contained in:
parent
6fbe56ce15
commit
90199fc88b
|
@ -19,6 +19,7 @@ struct IceCubesApp: App {
|
|||
@StateObject private var currentInstance = CurrentInstance.shared
|
||||
@StateObject private var currentAccount = CurrentAccount.shared
|
||||
@StateObject private var userPreferences = UserPreferences.shared
|
||||
@StateObject private var pushNotificationsService = PushNotificationsService.shared
|
||||
@StateObject private var watcher = StreamWatcher()
|
||||
@StateObject private var quickLook = QuickLook()
|
||||
@StateObject private var theme = Theme.shared
|
||||
|
@ -50,12 +51,18 @@ struct IceCubesApp: App {
|
|||
.environmentObject(userPreferences)
|
||||
.environmentObject(theme)
|
||||
.environmentObject(watcher)
|
||||
.environmentObject(PushNotificationsService.shared)
|
||||
.environmentObject(pushNotificationsService)
|
||||
.fullScreenCover(item: $quickLook.url, content: { url in
|
||||
QuickLookPreview(selectedURL: url, urls: quickLook.urls)
|
||||
.edgesIgnoringSafeArea(.bottom)
|
||||
.background(TransparentBackground())
|
||||
})
|
||||
.onChange(of: pushNotificationsService.routedNotification) { notification in
|
||||
if notification != nil {
|
||||
pushNotificationsService.routedNotification = nil
|
||||
selectedTab = .notifications
|
||||
}
|
||||
}
|
||||
}
|
||||
.commands {
|
||||
appMenu
|
||||
|
|
|
@ -17,6 +17,7 @@ struct NotificationsTab: View {
|
|||
@EnvironmentObject private var appAccount: AppAccountsManager
|
||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||
@EnvironmentObject private var userPreferences: UserPreferences
|
||||
@EnvironmentObject private var pushNotificationsService: PushNotificationsService
|
||||
@StateObject private var routerPath = RouterPath()
|
||||
@Binding var popToRootTab: Tab
|
||||
|
||||
|
@ -53,6 +54,17 @@ struct NotificationsTab: View {
|
|||
routerPath.path = []
|
||||
}
|
||||
}
|
||||
.onChange(of: pushNotificationsService.routedNotification) { notification in
|
||||
if let notification {
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: scenePhase, perform: { scenePhase in
|
||||
switch scenePhase {
|
||||
case .active:
|
||||
|
|
|
@ -19,19 +19,32 @@ public struct PushAccount {
|
|||
}
|
||||
|
||||
@MainActor
|
||||
public class PushNotificationsService: ObservableObject {
|
||||
public class PushNotificationsService: NSObject, ObservableObject {
|
||||
enum Constants {
|
||||
static let endpoint = "https://icecubesrelay.fly.dev"
|
||||
static let keychainAuthKey = "notifications_auth_key"
|
||||
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?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
UNUserNotificationCenter.current().delegate = self
|
||||
}
|
||||
|
||||
private var keychain: KeychainSwift {
|
||||
let keychain = KeychainSwift()
|
||||
#if !DEBUG && !targetEnvironment(simulator)
|
||||
|
@ -121,6 +134,27 @@ public class PushNotificationsService: 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 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Data {
|
||||
var hexString: String {
|
||||
return map { String(format: "%02.2hhx", arguments: [$0]) }.joined()
|
||||
|
|
Loading…
Reference in New Issue