Root view model per-scene

This commit is contained in:
Justin Mazzocchi 2021-03-04 18:13:30 -08:00
parent 02fd3a0a07
commit 92e515e2b4
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
3 changed files with 21 additions and 24 deletions

View file

@ -8,8 +8,6 @@ import ViewModels
@main @main
struct MetatextApp: App { struct MetatextApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate @UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
// swiftlint:disable:next force_try
private let viewModel = try! RootViewModel(environment: Self.environment)
init() { init() {
try? AVAudioSession.sharedInstance().setCategory(.ambient, mode: .default) try? AVAudioSession.sharedInstance().setCategory(.ambient, mode: .default)
@ -17,10 +15,11 @@ struct MetatextApp: App {
} }
var body: some Scene { var body: some Scene {
viewModel.registerForRemoteNotifications = appDelegate.registerForRemoteNotifications WindowGroup {
// swiftlint:disable:next force_try
return WindowGroup { RootView(viewModel: try! RootViewModel(
RootView(viewModel: viewModel) environment: Self.environment,
registerForRemoteNotifications: appDelegate.registerForRemoteNotifications))
} }
} }
} }

View file

@ -69,7 +69,8 @@ public extension Instance {
} }
public extension RootViewModel { public extension RootViewModel {
static let preview = try! RootViewModel(environment: environment) static let preview = try! RootViewModel(environment: environment,
registerForRemoteNotifications: { Empty().eraseToAnyPublisher() })
} }
public extension IdentityContext { public extension IdentityContext {

View file

@ -7,28 +7,18 @@ import ServiceLayer
public final class RootViewModel: ObservableObject { public final class RootViewModel: ObservableObject {
@Published public private(set) var navigationViewModel: NavigationViewModel? @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? @Published private var mostRecentlyUsedIdentityId: Identity.Id?
private let environment: AppEnvironment private let environment: AppEnvironment
private let registerForRemoteNotifications: () -> AnyPublisher<Data, Error>
private let allIdentitiesService: AllIdentitiesService private let allIdentitiesService: AllIdentitiesService
private let userNotificationService: UserNotificationService private let userNotificationService: UserNotificationService
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
public init(environment: AppEnvironment) throws { public init(environment: AppEnvironment,
registerForRemoteNotifications: @escaping () -> AnyPublisher<Data, Error>) throws {
self.environment = environment self.environment = environment
self.registerForRemoteNotifications = registerForRemoteNotifications
allIdentitiesService = try AllIdentitiesService(environment: environment) allIdentitiesService = try AllIdentitiesService(environment: environment)
userNotificationService = UserNotificationService(environment: environment) userNotificationService = UserNotificationService(environment: environment)
@ -42,6 +32,14 @@ public final class RootViewModel: ObservableObject {
.sink { [weak self] in self?.identitySelected(id: $0) } .sink { [weak self] in self?.identitySelected(id: $0) }
.store(in: &cancellables) .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 userNotificationService.events
.sink { [weak self] in self?.handle(event: $0) } .sink { [weak self] in self?.handle(event: $0) }
.store(in: &cancellables) .store(in: &cancellables)
@ -128,11 +126,10 @@ private extension RootViewModel {
.store(in: &self.cancellables) .store(in: &self.cancellables)
if identityContext.identity.authenticated, if identityContext.identity.authenticated,
!identityContext.identity.pending, !identityContext.identity.pending {
let registerForRemoteNotifications = self.registerForRemoteNotifications {
self.userNotificationService.isAuthorized(request: true) self.userNotificationService.isAuthorized(request: true)
.filter { $0 } .filter { $0 }
.zip(registerForRemoteNotifications()) .zip(self.registerForRemoteNotifications())
.filter { identityContext.identity.lastRegisteredDeviceToken != $1 } .filter { identityContext.identity.lastRegisteredDeviceToken != $1 }
.map { ($1, identityContext.identity.pushSubscriptionAlerts) } .map { ($1, identityContext.identity.pushSubscriptionAlerts) }
.flatMap(identityContext.service.createPushSubscription(deviceToken:alerts:)) .flatMap(identityContext.service.createPushSubscription(deviceToken:alerts:))