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