metatext-app-ios-iphone-ipad/Shared/View Models/MainNavigationViewModel.swift

106 lines
3.3 KiB
Swift
Raw Normal View History

2020-08-03 17:20:51 +02:00
// Copyright © 2020 Metabolist. All rights reserved.
import Foundation
import Combine
class MainNavigationViewModel: ObservableObject {
2020-08-04 22:26:09 +02:00
@Published private(set) var identity: Identity
2020-08-03 17:20:51 +02:00
@Published var presentingSettings = false
2020-08-04 22:26:09 +02:00
@Published var alertItem: AlertItem?
var selectedTab: Tab? = .timelines
2020-08-03 17:20:51 +02:00
private let environment: AppEnvironment
private let networkClient: MastodonClient
private var cancellables = Set<AnyCancellable>()
2020-08-04 22:26:09 +02:00
init(identityID: String, environment: AppEnvironment) throws {
2020-08-03 17:20:51 +02:00
self.environment = environment
networkClient = MastodonClient(configuration: environment.URLSessionConfiguration)
2020-08-04 22:26:09 +02:00
let observation = environment.identityDatabase.identityObservation(id: identityID).share()
var initialIdentity: Identity?
observation.first().sink(
receiveCompletion: { _ in },
receiveValue: { initialIdentity = $0 })
.store(in: &cancellables)
guard let identity = initialIdentity else { throw IdentityDatabaseError.identityNotFound }
self.identity = identity
networkClient.instanceURL = identity.url
2020-08-03 17:20:51 +02:00
do {
2020-08-04 22:26:09 +02:00
networkClient.accessToken = try environment.secrets.item(.accessToken, forIdentityID: identity.id)
2020-08-03 17:20:51 +02:00
} catch {
alertItem = AlertItem(error: error)
}
2020-08-04 22:26:09 +02:00
observation.assignErrorsToAlertItem(to: \.alertItem, on: self).assign(to: &$identity)
2020-08-03 17:20:51 +02:00
2020-08-04 22:26:09 +02:00
environment.identityDatabase.updateLastUsedAt(identityID: identityID)
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink(receiveValue: {})
.store(in: &cancellables)
2020-08-03 17:20:51 +02:00
}
}
extension MainNavigationViewModel {
func refreshIdentity() {
2020-08-04 22:26:09 +02:00
let id = identity.id
2020-08-03 17:20:51 +02:00
if networkClient.accessToken != nil {
networkClient.request(AccountEndpoint.verifyCredentials)
.map { ($0, id) }
.flatMap(environment.identityDatabase.updateAccount)
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink(receiveValue: {})
.store(in: &cancellables)
}
networkClient.request(InstanceEndpoint.instance)
.map { ($0, id) }
.flatMap(environment.identityDatabase.updateInstance)
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink(receiveValue: {})
.store(in: &cancellables)
}
func settingsViewModel() -> SettingsViewModel {
2020-08-04 22:26:09 +02:00
SettingsViewModel(identity: _identity, environment: environment)
2020-08-03 17:20:51 +02:00
}
}
extension MainNavigationViewModel {
enum Tab: CaseIterable {
case timelines
case search
case notifications
case messages
}
}
extension MainNavigationViewModel.Tab {
var title: String {
switch self {
case .timelines: return "Timelines"
case .search: return "Search"
case .notifications: return "Notifications"
case .messages: return "Messages"
}
}
var systemImageName: String {
switch self {
case .timelines: return "house"
case .search: return "magnifyingglass"
case .notifications: return "bell"
case .messages: return "envelope"
}
}
}
extension MainNavigationViewModel.Tab: Identifiable {
var id: Self { self }
}