Notificatio navigation wip
This commit is contained in:
parent
aea6030d43
commit
03b17d21ee
|
@ -39,6 +39,7 @@ final class NotificationService: UNNotificationServiceExtension {
|
|||
return
|
||||
}
|
||||
|
||||
bestAttemptContent.userInfo[PushNotificationParsingService.pushNotificationUserInfoKey] = decryptedJSON
|
||||
bestAttemptContent.title = pushNotification.title
|
||||
bestAttemptContent.body = XMLUnescaper(string: pushNotification.body).unescape()
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@ public struct PushNotificationParsingService {
|
|||
}
|
||||
|
||||
public extension PushNotificationParsingService {
|
||||
static let identityIdUserInfoKey = "i"
|
||||
static let pushNotificationUserInfoKey = "com.metabolist.metatext.push-notification-user-info-key"
|
||||
|
||||
func extractAndDecrypt(userInfo: [AnyHashable: Any]) throws -> (Data, Identity.Id) {
|
||||
guard let identityIdString = userInfo[Self.identityIdUserInfoKey] as? String,
|
||||
let identityId = Identity.Id(uuidString: identityIdString),
|
||||
|
@ -48,7 +51,6 @@ public extension PushNotificationParsingService {
|
|||
}
|
||||
|
||||
private extension PushNotificationParsingService {
|
||||
static let identityIdUserInfoKey = "i"
|
||||
static let encryptedMessageUserInfoKey = "m"
|
||||
static let saltUserInfoKey = "s"
|
||||
static let serverPublicKeyUserInfoKey = "k"
|
||||
|
|
|
@ -9,28 +9,27 @@ import ViewModels
|
|||
@main
|
||||
struct MetatextApp: App {
|
||||
@UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
|
||||
private let environment = AppEnvironment.live(
|
||||
userNotificationCenter: .current(),
|
||||
reduceMotion: { UIAccessibility.isReduceMotionEnabled })
|
||||
// swiftlint:disable:next force_try
|
||||
private let viewModel = try! RootViewModel(environment: Self.environment)
|
||||
|
||||
init() {
|
||||
try? AVAudioSession.sharedInstance().setCategory(.ambient, mode: .default)
|
||||
try? ImageCacheConfiguration(environment: environment).configure()
|
||||
try? ImageCacheConfiguration(environment: Self.environment).configure()
|
||||
}
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
RootView(
|
||||
// swiftlint:disable force_try
|
||||
viewModel: try! RootViewModel(
|
||||
environment: environment,
|
||||
registerForRemoteNotifications: appDelegate.registerForRemoteNotifications))
|
||||
// swiftlint:enable force_try
|
||||
viewModel.registerForRemoteNotifications = appDelegate.registerForRemoteNotifications
|
||||
|
||||
return WindowGroup {
|
||||
RootView(viewModel: viewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension MetatextApp {
|
||||
static let environment = AppEnvironment.live(
|
||||
userNotificationCenter: .current(),
|
||||
reduceMotion: { UIAccessibility.isReduceMotionEnabled })
|
||||
static let imageCacheName = "Images"
|
||||
static let imageCacheDirectoryURL = FileManager.default.containerURL(
|
||||
forSecurityApplicationGroupIdentifier: AppEnvironment.appGroup)?
|
||||
|
|
|
@ -70,7 +70,7 @@ public extension Instance {
|
|||
}
|
||||
|
||||
public extension RootViewModel {
|
||||
static let preview = try! RootViewModel(environment: environment) { Empty().eraseToAnyPublisher() }
|
||||
static let preview = try! RootViewModel(environment: environment)
|
||||
}
|
||||
|
||||
public extension IdentityContext {
|
||||
|
|
|
@ -7,20 +7,30 @@ import ServiceLayer
|
|||
|
||||
public final class RootViewModel: ObservableObject {
|
||||
@Published public private(set) var navigationViewModel: NavigationViewModel?
|
||||
public var registerForRemoteNotifications: (() -> AnyPublisher<Data, Error>)? {
|
||||
didSet {
|
||||
guard let registerForRemoteNotifications = registerForRemoteNotifications else { return }
|
||||
|
||||
userNotificationService.isAuthorized(request: false)
|
||||
.filter { $0 }
|
||||
.zip(registerForRemoteNotifications())
|
||||
.map { $1 }
|
||||
.flatMap(allIdentitiesService.updatePushSubscriptions(deviceToken:))
|
||||
.sink { _ in } receiveValue: { _ in }
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
}
|
||||
|
||||
@Published private var mostRecentlyUsedIdentityId: Identity.Id?
|
||||
private let environment: AppEnvironment
|
||||
private let allIdentitiesService: AllIdentitiesService
|
||||
private let userNotificationService: UserNotificationService
|
||||
private let registerForRemoteNotifications: () -> AnyPublisher<Data, Error>
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
public init(environment: AppEnvironment,
|
||||
registerForRemoteNotifications: @escaping () -> AnyPublisher<Data, Error>) throws {
|
||||
public init(environment: AppEnvironment) throws {
|
||||
self.environment = environment
|
||||
allIdentitiesService = try AllIdentitiesService(environment: environment)
|
||||
userNotificationService = UserNotificationService(environment: environment)
|
||||
self.registerForRemoteNotifications = registerForRemoteNotifications
|
||||
|
||||
allIdentitiesService.immediateMostRecentlyUsedIdentityIdPublisher()
|
||||
.replaceError(with: nil)
|
||||
|
@ -32,14 +42,6 @@ public final class RootViewModel: ObservableObject {
|
|||
.sink { [weak self] in self?.identitySelected(id: $0) }
|
||||
.store(in: &cancellables)
|
||||
|
||||
userNotificationService.isAuthorized(request: false)
|
||||
.filter { $0 }
|
||||
.zip(registerForRemoteNotifications())
|
||||
.map { $1 }
|
||||
.flatMap(allIdentitiesService.updatePushSubscriptions(deviceToken:))
|
||||
.sink { _ in } receiveValue: { _ in }
|
||||
.store(in: &cancellables)
|
||||
|
||||
userNotificationService.events
|
||||
.sink { [weak self] in self?.handle(event: $0) }
|
||||
.store(in: &cancellables)
|
||||
|
@ -116,10 +118,12 @@ private extension RootViewModel {
|
|||
.sink { _ in } receiveValue: { _ in }
|
||||
.store(in: &self.cancellables)
|
||||
|
||||
if identityContext.identity.authenticated && !identityContext.identity.pending {
|
||||
if identityContext.identity.authenticated,
|
||||
!identityContext.identity.pending,
|
||||
let registerForRemoteNotifications = self.registerForRemoteNotifications {
|
||||
self.userNotificationService.isAuthorized(request: true)
|
||||
.filter { $0 }
|
||||
.zip(self.registerForRemoteNotifications())
|
||||
.zip(registerForRemoteNotifications())
|
||||
.filter { identityContext.identity.lastRegisteredDeviceToken != $1 }
|
||||
.map { ($1, identityContext.identity.pushSubscriptionAlerts) }
|
||||
.flatMap(identityContext.service.createPushSubscription(deviceToken:alerts:))
|
||||
|
@ -136,8 +140,23 @@ private extension RootViewModel {
|
|||
switch event {
|
||||
case let .willPresentNotification(_, completionHandler):
|
||||
completionHandler(.banner)
|
||||
case let .didReceiveResponse(response, completionHandler):
|
||||
let userInfo = response.notification.request.content.userInfo
|
||||
|
||||
if let identityIdString = userInfo[PushNotificationParsingService.identityIdUserInfoKey] as? String,
|
||||
let identityId = Identity.Id(uuidString: identityIdString),
|
||||
let pushNotificationJSON = userInfo[PushNotificationParsingService.pushNotificationUserInfoKey] as? Data,
|
||||
let pushNotification = try? MastodonDecoder().decode(PushNotification.self, from: pushNotificationJSON) {
|
||||
handle(pushNotification: pushNotification, identityId: identityId)
|
||||
}
|
||||
|
||||
completionHandler()
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func handle(pushNotification: PushNotification, identityId: Identity.Id) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue