Refactoring

This commit is contained in:
Justin Mazzocchi 2020-09-07 09:33:36 -07:00
parent df5ca6ddb2
commit 367d79ed2c
No known key found for this signature in database
GPG Key ID: E223E6937AAFB01C
15 changed files with 176 additions and 146 deletions

View File

@ -102,19 +102,28 @@ public extension IdentityDatabase {
.eraseToAnyPublisher()
}
func updatePreferences(_ preferences: Identity.Preferences,
func updatePreferences(_ preferences: Mastodon.Preferences,
forIdentityID identityID: UUID) -> AnyPublisher<Never, Error> {
databaseQueue.writePublisher {
let data = try IdentityRecord.databaseJSONEncoder(for: "preferences").encode(preferences)
guard let storedPreferences = try IdentityRecord.filter(Column("id") == identityID)
.fetchOne($0)?
.preferences else {
throw IdentityDatabaseError.identityNotFound
}
try IdentityRecord
.filter(Column("id") == identityID)
.updateAll($0, Column("preferences").set(to: data))
try Self.writePreferences(storedPreferences.updated(from: preferences), id: identityID)($0)
}
.ignoreOutput()
.eraseToAnyPublisher()
}
func updatePreferences(_ preferences: Identity.Preferences,
forIdentityID identityID: UUID) -> AnyPublisher<Never, Error> {
databaseQueue.writePublisher(updates: Self.writePreferences(preferences, id: identityID))
.ignoreOutput()
.eraseToAnyPublisher()
}
func updatePushSubscription(alerts: PushSubscription.Alerts,
deviceToken: Data? = nil,
forIdentityID identityID: UUID) -> AnyPublisher<Never, Error> {
@ -201,6 +210,16 @@ private extension IdentityDatabase {
.asRequest(of: IdentityResult.self)
}
private static func writePreferences(_ preferences: Identity.Preferences, id: UUID) -> (Database) throws -> Void {
{
let data = try IdentityRecord.databaseJSONEncoder(for: "preferences").encode(preferences)
try IdentityRecord
.filter(Column("id") == id)
.updateAll($0, Column("preferences").set(to: data))
}
}
private static func migrate(_ writer: DatabaseWriter) throws {
var migrator = DatabaseMigrator()

View File

@ -0,0 +1,43 @@
// Copyright © 2020 Metabolist. All rights reserved.
import Combine
import DB
import Foundation
public class IdentifiedEnvironment {
@Published public private(set) var identity: Identity
public let appEnvironment: AppEnvironment
public let identityService: IdentityService
public let observationErrors: AnyPublisher<Error, Never>
init(id: UUID, database: IdentityDatabase, environment: AppEnvironment) throws {
appEnvironment = environment
// The scheduling on the observation is immediate so an initial value can be extracted
let sharedObservation = database.identityObservation(id: id).share()
var initialIdentity: Identity?
_ = sharedObservation.first().sink(
receiveCompletion: { _ in },
receiveValue: { initialIdentity = $0 })
guard let identity = initialIdentity else { throw IdentityDatabaseError.identityNotFound }
self.identity = identity
identityService = try IdentityService(id: identity.id,
instanceURL: identity.url,
database: database,
environment: environment)
let observationErrorsSubject = PassthroughSubject<Error, Never>()
self.observationErrors = observationErrorsSubject.eraseToAnyPublisher()
sharedObservation.catch { error -> Empty<Identity, Never> in
observationErrorsSubject.send(error)
return Empty()
}
.assign(to: &$identity)
}
}

View File

@ -11,16 +11,16 @@ public struct AllIdentitiesService {
public let mostRecentlyUsedIdentityID: AnyPublisher<UUID?, Never>
public let instanceFilterService: InstanceFilterService
private let identityDatabase: IdentityDatabase
private let database: IdentityDatabase
private let environment: AppEnvironment
public init(environment: AppEnvironment) throws {
self.identityDatabase = try IdentityDatabase(inMemory: environment.inMemoryContent,
self.database = try IdentityDatabase(inMemory: environment.inMemoryContent,
fixture: environment.identityFixture,
keychain: environment.keychain)
self.environment = environment
mostRecentlyUsedIdentityID = identityDatabase.mostRecentlyUsedIdentityIDObservation()
mostRecentlyUsedIdentityID = database.mostRecentlyUsedIdentityIDObservation()
.replaceError(with: nil)
.eraseToAnyPublisher()
instanceFilterService = InstanceFilterService(environment: environment)
@ -28,14 +28,12 @@ public struct AllIdentitiesService {
}
public extension AllIdentitiesService {
func identityService(id: UUID) throws -> IdentityService {
try IdentityService(identityID: id,
identityDatabase: identityDatabase,
environment: environment)
func identifiedEnvironment(id: UUID) throws -> IdentifiedEnvironment {
try IdentifiedEnvironment(id: id, database: database, environment: environment)
}
func createIdentity(id: UUID, instanceURL: URL) -> AnyPublisher<Never, Error> {
identityDatabase.createIdentity(id: id, url: instanceURL)
database.createIdentity(id: id, url: instanceURL)
}
func authorizeIdentity(id: UUID, instanceURL: URL) -> AnyPublisher<Never, Error> {
@ -61,7 +59,7 @@ public extension AllIdentitiesService {
mastodonAPIClient.instanceURL = identity.url
return identityDatabase.deleteIdentity(id: identity.id)
return database.deleteIdentity(id: identity.id)
.collect()
.tryMap { _ in
DeletionEndpoint.oauthRevoke(
@ -80,10 +78,10 @@ public extension AllIdentitiesService {
}
func updatePushSubscriptions(deviceToken: Data) -> AnyPublisher<Never, Error> {
identityDatabase.identitiesWithOutdatedDeviceTokens(deviceToken: deviceToken)
database.identitiesWithOutdatedDeviceTokens(deviceToken: deviceToken)
.tryMap { identities -> [AnyPublisher<Never, Never>] in
try identities.map {
try identityService(id: $0.id)
try IdentityService(id: $0.id, instanceURL: $0.url, database: database, environment: environment)
.createPushSubscription(deviceToken: deviceToken, alerts: $0.pushSubscriptionAlerts)
.catch { _ in Empty() } // don't want to disrupt pipeline
.eraseToAnyPublisher()

View File

@ -8,10 +8,8 @@ import Mastodon
import MastodonAPI
import Secrets
public class IdentityService {
@Published public private(set) var identity: Identity
public let observationErrors: AnyPublisher<Error, Never>
public struct IdentityService {
private let identityID: UUID
private let identityDatabase: IdentityDatabase
private let contentDatabase: ContentDatabase
private let environment: AppEnvironment
@ -19,40 +17,20 @@ public class IdentityService {
private let secrets: Secrets
private let observationErrorsInput = PassthroughSubject<Error, Never>()
init(identityID: UUID,
identityDatabase: IdentityDatabase,
environment: AppEnvironment) throws {
self.identityDatabase = identityDatabase
init(id: UUID, instanceURL: URL, database: IdentityDatabase, environment: AppEnvironment) throws {
identityID = id
identityDatabase = database
self.environment = environment
observationErrors = observationErrorsInput.eraseToAnyPublisher()
let observation = identityDatabase.identityObservation(id: identityID).share()
var initialIdentity: Identity?
_ = observation.first().sink(
receiveCompletion: { _ in },
receiveValue: { initialIdentity = $0 })
guard let identity = initialIdentity else { throw IdentityDatabaseError.identityNotFound }
self.identity = identity
secrets = Secrets(
identityID: identityID,
identityID: id,
keychain: environment.keychain)
mastodonAPIClient = MastodonAPIClient(session: environment.session)
mastodonAPIClient.instanceURL = identity.url
mastodonAPIClient.instanceURL = instanceURL
mastodonAPIClient.accessToken = try? secrets.getAccessToken()
contentDatabase = try ContentDatabase(identityID: identityID,
contentDatabase = try ContentDatabase(identityID: id,
inMemory: environment.inMemoryContent,
keychain: environment.keychain)
observation.catch { [weak self] error -> Empty<Identity, Never> in
self?.observationErrorsInput.send(error)
return Empty()
}
.assign(to: &$identity)
}
}
@ -60,28 +38,24 @@ public extension IdentityService {
var isAuthorized: Bool { mastodonAPIClient.accessToken != nil }
func updateLastUse() -> AnyPublisher<Never, Error> {
identityDatabase.updateLastUsedAt(identityID: identity.id)
identityDatabase.updateLastUsedAt(identityID: identityID)
}
func verifyCredentials() -> AnyPublisher<Never, Error> {
mastodonAPIClient.request(AccountEndpoint.verifyCredentials)
.zip(Just(identity.id).first().setFailureType(to: Error.self))
.flatMap(identityDatabase.updateAccount)
.flatMap { identityDatabase.updateAccount($0, forIdentityID: identityID) }
.eraseToAnyPublisher()
}
func refreshServerPreferences() -> AnyPublisher<Never, Error> {
mastodonAPIClient.request(PreferencesEndpoint.preferences)
.zip(Just(self).first().setFailureType(to: Error.self))
.map { ($1.identity.preferences.updated(from: $0), $1.identity.id) }
.flatMap(identityDatabase.updatePreferences)
.flatMap { identityDatabase.updatePreferences($0, forIdentityID: identityID) }
.eraseToAnyPublisher()
}
func refreshInstance() -> AnyPublisher<Never, Error> {
mastodonAPIClient.request(InstanceEndpoint.instance)
.zip(Just(identity.id).first().setFailureType(to: Error.self))
.flatMap(identityDatabase.updateInstance)
.flatMap { identityDatabase.updateInstance($0, forIdentityID: identityID) }
.eraseToAnyPublisher()
}
@ -90,7 +64,7 @@ public extension IdentityService {
}
func recentIdentitiesObservation() -> AnyPublisher<[Identity], Error> {
identityDatabase.recentIdentitiesObservation(excluding: identity.id)
identityDatabase.recentIdentitiesObservation(excluding: identityID)
}
func refreshLists() -> AnyPublisher<Never, Error> {
@ -145,8 +119,7 @@ public extension IdentityService {
func deleteFilter(id: String) -> AnyPublisher<Never, Error> {
mastodonAPIClient.request(DeletionEndpoint.filter(id: id))
.map { _ in id }
.flatMap(contentDatabase.deleteFilter(id:))
.flatMap { _ in contentDatabase.deleteFilter(id: id) }
.eraseToAnyPublisher()
}
@ -159,12 +132,10 @@ public extension IdentityService {
}
func updatePreferences(_ preferences: Identity.Preferences) -> AnyPublisher<Never, Error> {
identityDatabase.updatePreferences(preferences, forIdentityID: identity.id)
identityDatabase.updatePreferences(preferences, forIdentityID: identityID)
.collect()
.zip(Just(self).first().setFailureType(to: Error.self))
.filter { $1.identity.preferences.useServerPostingReadingPreferences }
.map { _ in () }
.flatMap(refreshServerPreferences)
.filter { _ in preferences.useServerPostingReadingPreferences }
.flatMap { _ in refreshServerPreferences() }
.eraseToAnyPublisher()
}
@ -179,7 +150,6 @@ public extension IdentityService {
return Fail(error: error).eraseToAnyPublisher()
}
let identityID = identity.id
let endpoint = Self.pushSubscriptionEndpointURL
.appendingPathComponent(deviceToken.base16EncodedString())
.appendingPathComponent(identityID.uuidString)
@ -196,9 +166,7 @@ public extension IdentityService {
}
func updatePushSubscription(alerts: PushSubscription.Alerts) -> AnyPublisher<Never, Error> {
let identityID = identity.id
return mastodonAPIClient.request(PushSubscriptionEndpoint.update(alerts: alerts))
mastodonAPIClient.request(PushSubscriptionEndpoint.update(alerts: alerts))
.map { ($0.alerts, nil, identityID) }
.flatMap(identityDatabase.updatePushSubscription(alerts:deviceToken:forIdentityID:))
.eraseToAnyPublisher()

View File

@ -15,13 +15,13 @@ public class EditFilterViewModel: ObservableObject {
didSet { filter.expiresAt = date }
}
private let identityService: IdentityService
private let environment: IdentifiedEnvironment
private let saveCompletedInput = PassthroughSubject<Void, Never>()
private var cancellables = Set<AnyCancellable>()
init(filter: Filter, identityService: IdentityService) {
init(filter: Filter, environment: IdentifiedEnvironment) {
self.filter = filter
self.identityService = identityService
self.environment = environment
date = filter.expiresAt ?? Date()
saveCompleted = saveCompletedInput.eraseToAnyPublisher()
}
@ -41,7 +41,7 @@ public extension EditFilterViewModel {
}
func save() {
(isNew ? identityService.createFilter(filter) : identityService.updateFilter(filter))
(isNew ? environment.identityService.createFilter(filter) : environment.identityService.updateFilter(filter))
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.handleEvents(
receiveSubscription: { [weak self] _ in self?.saving = true },

View File

@ -10,19 +10,19 @@ public class FiltersViewModel: ObservableObject {
@Published public var expiredFilters = [Filter]()
@Published public var alertItem: AlertItem?
private let identityService: IdentityService
private let environment: IdentifiedEnvironment
private var cancellables = Set<AnyCancellable>()
init(identityService: IdentityService) {
self.identityService = identityService
init(environment: IdentifiedEnvironment) {
self.environment = environment
let now = Date()
identityService.activeFiltersObservation(date: now)
environment.identityService.activeFiltersObservation(date: now)
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.assign(to: &$activeFilters)
identityService.expiredFiltersObservation(date: now)
environment.identityService.expiredFiltersObservation(date: now)
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.assign(to: &$expiredFilters)
}
@ -30,20 +30,20 @@ public class FiltersViewModel: ObservableObject {
public extension FiltersViewModel {
func refreshFilters() {
identityService.refreshFilters()
environment.identityService.refreshFilters()
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink { _ in }
.store(in: &cancellables)
}
func delete(filter: Filter) {
identityService.deleteFilter(id: filter.id)
environment.identityService.deleteFilter(id: filter.id)
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink { _ in }
.store(in: &cancellables)
}
func editFilterViewModel(filter: Filter) -> EditFilterViewModel {
EditFilterViewModel(filter: filter, identityService: identityService)
EditFilterViewModel(filter: filter, environment: environment)
}
}

View File

@ -5,18 +5,18 @@ import Foundation
import ServiceLayer
public class IdentitiesViewModel: ObservableObject {
@Published public private(set) var identity: Identity
public let currentIdentityID: UUID
@Published public var identities = [Identity]()
@Published public var alertItem: AlertItem?
private let identityService: IdentityService
private let environment: IdentifiedEnvironment
private var cancellables = Set<AnyCancellable>()
init(identityService: IdentityService) {
self.identityService = identityService
identity = identityService.identity
init(environment: IdentifiedEnvironment) {
self.environment = environment
currentIdentityID = environment.identity.id
identityService.identitiesObservation()
environment.identityService.identitiesObservation()
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.assign(to: &$identities)
}

View File

@ -10,13 +10,13 @@ public class ListsViewModel: ObservableObject {
@Published public private(set) var creatingList = false
@Published public var alertItem: AlertItem?
private let identityService: IdentityService
private let environment: IdentifiedEnvironment
private var cancellables = Set<AnyCancellable>()
init(identityService: IdentityService) {
self.identityService = identityService
init(environment: IdentifiedEnvironment) {
self.environment = environment
identityService.listsObservation()
environment.identityService.listsObservation()
.map {
$0.compactMap {
guard case let .list(list) = $0 else { return nil }
@ -31,14 +31,14 @@ public class ListsViewModel: ObservableObject {
public extension ListsViewModel {
func refreshLists() {
identityService.refreshLists()
environment.identityService.refreshLists()
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink { _ in }
.store(in: &cancellables)
}
func createList(title: String) {
identityService.createList(title: title)
environment.identityService.createList(title: title)
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.handleEvents(
receiveSubscription: { [weak self] _ in self?.creatingList = true },
@ -48,7 +48,7 @@ public extension ListsViewModel {
}
func delete(list: MastodonList) {
identityService.deleteList(id: list.id)
environment.identityService.deleteList(id: list.id)
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink { _ in }
.store(in: &cancellables)

View File

@ -9,14 +9,14 @@ public class NotificationTypesPreferencesViewModel: ObservableObject {
@Published public var pushSubscriptionAlerts: PushSubscription.Alerts
@Published public var alertItem: AlertItem?
private let identityService: IdentityService
private let environment: IdentifiedEnvironment
private var cancellables = Set<AnyCancellable>()
init(identityService: IdentityService) {
self.identityService = identityService
pushSubscriptionAlerts = identityService.identity.pushSubscriptionAlerts
init(environment: IdentifiedEnvironment) {
self.environment = environment
pushSubscriptionAlerts = environment.identity.pushSubscriptionAlerts
identityService.$identity
environment.$identity
.map(\.pushSubscriptionAlerts)
.dropFirst()
.removeDuplicates()
@ -32,14 +32,14 @@ public class NotificationTypesPreferencesViewModel: ObservableObject {
private extension NotificationTypesPreferencesViewModel {
func update(alerts: PushSubscription.Alerts) {
guard alerts != identityService.identity.pushSubscriptionAlerts else { return }
guard alerts != environment.identity.pushSubscriptionAlerts else { return }
identityService.updatePushSubscription(alerts: alerts)
environment.identityService.updatePushSubscription(alerts: alerts)
.sink { [weak self] in
guard let self = self, case let .failure(error) = $0 else { return }
self.alertItem = AlertItem(error: error)
self.pushSubscriptionAlerts = self.identityService.identity.pushSubscriptionAlerts
self.pushSubscriptionAlerts = self.environment.identity.pushSubscriptionAlerts
} receiveValue: { _ in }
.store(in: &cancellables)
}

View File

@ -8,14 +8,14 @@ public class PostingReadingPreferencesViewModel: ObservableObject {
@Published public var preferences: Identity.Preferences
@Published public var alertItem: AlertItem?
private let identityService: IdentityService
private let environment: IdentifiedEnvironment
private var cancellables = Set<AnyCancellable>()
init(identityService: IdentityService) {
self.identityService = identityService
preferences = identityService.identity.preferences
init(environment: IdentifiedEnvironment) {
self.environment = environment
preferences = environment.identity.preferences
identityService.$identity
environment.$identity
.map(\.preferences)
.dropFirst()
.removeDuplicates()
@ -23,7 +23,7 @@ public class PostingReadingPreferencesViewModel: ObservableObject {
$preferences
.dropFirst()
.flatMap(identityService.updatePreferences)
.flatMap(environment.identityService.updatePreferences)
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink { _ in }
.store(in: &cancellables)

View File

@ -7,26 +7,26 @@ public class PreferencesViewModel: ObservableObject {
public let handle: String
public let shouldShowNotificationTypePreferences: Bool
private let identityService: IdentityService
private let environment: IdentifiedEnvironment
init(identityService: IdentityService) {
self.identityService = identityService
handle = identityService.identity.handle
init(environment: IdentifiedEnvironment) {
self.environment = environment
handle = environment.identity.handle
shouldShowNotificationTypePreferences = identityService.identity.lastRegisteredDeviceToken != nil
shouldShowNotificationTypePreferences = environment.identity.lastRegisteredDeviceToken != nil
}
}
public extension PreferencesViewModel {
func postingReadingPreferencesViewModel() -> PostingReadingPreferencesViewModel {
PostingReadingPreferencesViewModel(identityService: identityService)
PostingReadingPreferencesViewModel(environment: environment)
}
func notificationTypesPreferencesViewModel() -> NotificationTypesPreferencesViewModel {
NotificationTypesPreferencesViewModel(identityService: identityService)
NotificationTypesPreferencesViewModel(environment: environment)
}
func filtersViewModel() -> FiltersViewModel {
FiltersViewModel(identityService: identityService)
FiltersViewModel(environment: environment)
}
}

View File

@ -8,6 +8,7 @@ public final class RootViewModel: ObservableObject {
@Published public private(set) var tabNavigationViewModel: TabNavigationViewModel?
@Published private var mostRecentlyUsedIdentityID: UUID?
private let environment: AppEnvironment
private let allIdentitiesService: AllIdentitiesService
private let userNotificationService: UserNotificationService
private let registerForRemoteNotifications: () -> AnyPublisher<Data, Error>
@ -15,6 +16,7 @@ public final class RootViewModel: ObservableObject {
public init(environment: AppEnvironment,
registerForRemoteNotifications: @escaping () -> AnyPublisher<Data, Error>) throws {
self.environment = environment
allIdentitiesService = try AllIdentitiesService(environment: environment)
userNotificationService = UserNotificationService(environment: environment)
self.registerForRemoteNotifications = registerForRemoteNotifications
@ -41,34 +43,34 @@ public extension RootViewModel {
return
}
let identityService: IdentityService
let identifiedEnvironment: IdentifiedEnvironment
do {
identityService = try allIdentitiesService.identityService(id: id)
identifiedEnvironment = try allIdentitiesService.identifiedEnvironment(id: id)
} catch {
return
}
identityService.observationErrors
identifiedEnvironment.observationErrors
.receive(on: RunLoop.main)
.map { [weak self] _ in self?.mostRecentlyUsedIdentityID }
.sink { [weak self] in self?.newIdentitySelected(id: $0) }
.store(in: &cancellables)
identityService.updateLastUse()
identifiedEnvironment.identityService.updateLastUse()
.sink { _ in } receiveValue: { _ in }
.store(in: &cancellables)
userNotificationService.isAuthorized()
.filter { $0 }
.zip(registerForRemoteNotifications())
.filter { identityService.identity.lastRegisteredDeviceToken != $1 }
.map { ($1, identityService.identity.pushSubscriptionAlerts) }
.flatMap(identityService.createPushSubscription(deviceToken:alerts:))
.filter { identifiedEnvironment.identity.lastRegisteredDeviceToken != $1 }
.map { ($1, identifiedEnvironment.identity.pushSubscriptionAlerts) }
.flatMap(identifiedEnvironment.identityService.createPushSubscription(deviceToken:alerts:))
.sink { _ in } receiveValue: { _ in }
.store(in: &cancellables)
tabNavigationViewModel = TabNavigationViewModel(identityService: identityService)
tabNavigationViewModel = TabNavigationViewModel(environment: identifiedEnvironment)
}
func deleteIdentity(_ identity: Identity) {

View File

@ -6,25 +6,25 @@ import ServiceLayer
public class SecondaryNavigationViewModel: ObservableObject {
@Published public private(set) var identity: Identity
private let identityService: IdentityService
private let environment: IdentifiedEnvironment
init(identityService: IdentityService) {
self.identityService = identityService
identity = identityService.identity
identityService.$identity.dropFirst().assign(to: &$identity)
init(environment: IdentifiedEnvironment) {
self.environment = environment
identity = environment.identity
environment.$identity.dropFirst().assign(to: &$identity)
}
}
public extension SecondaryNavigationViewModel {
func identitiesViewModel() -> IdentitiesViewModel {
IdentitiesViewModel(identityService: identityService)
IdentitiesViewModel(environment: environment)
}
func listsViewModel() -> ListsViewModel {
ListsViewModel(identityService: identityService)
ListsViewModel(environment: environment)
}
func preferencesViewModel() -> PreferencesViewModel {
PreferencesViewModel(identityService: identityService)
PreferencesViewModel(environment: environment)
}
}

View File

@ -14,19 +14,19 @@ public class TabNavigationViewModel: ObservableObject {
@Published public var alertItem: AlertItem?
public var selectedTab: Tab? = .timelines
private let identityService: IdentityService
private let environment: IdentifiedEnvironment
private var cancellables = Set<AnyCancellable>()
init(identityService: IdentityService) {
self.identityService = identityService
identity = identityService.identity
identityService.$identity.dropFirst().assign(to: &$identity)
init(environment: IdentifiedEnvironment) {
self.environment = environment
identity = environment.identity
environment.$identity.dropFirst().assign(to: &$identity)
identityService.recentIdentitiesObservation()
environment.identityService.recentIdentitiesObservation()
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.assign(to: &$recentIdentities)
identityService.listsObservation()
environment.identityService.listsObservation()
.map { Timeline.nonLists + $0 }
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.assign(to: &$timelinesAndLists)
@ -54,42 +54,42 @@ public extension TabNavigationViewModel {
}
func refreshIdentity() {
if identityService.isAuthorized {
identityService.verifyCredentials()
if environment.identityService.isAuthorized {
environment.identityService.verifyCredentials()
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink { _ in }
.store(in: &cancellables)
identityService.refreshLists()
environment.identityService.refreshLists()
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink { _ in }
.store(in: &cancellables)
identityService.refreshFilters()
environment.identityService.refreshFilters()
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink { _ in }
.store(in: &cancellables)
if identity.preferences.useServerPostingReadingPreferences {
identityService.refreshServerPreferences()
environment.identityService.refreshServerPreferences()
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink { _ in }
.store(in: &cancellables)
}
}
identityService.refreshInstance()
environment.identityService.refreshInstance()
.assignErrorsToAlertItem(to: \.alertItem, on: self)
.sink { _ in }
.store(in: &cancellables)
}
func secondaryNavigationViewModel() -> SecondaryNavigationViewModel {
SecondaryNavigationViewModel(identityService: identityService)
SecondaryNavigationViewModel(environment: environment)
}
func viewModel(timeline: Timeline) -> StatusListViewModel {
StatusListViewModel(statusListService: identityService.service(timeline: timeline))
StatusListViewModel(statusListService: environment.identityService.service(timeline: timeline))
}
}

View File

@ -43,12 +43,12 @@ struct IdentitiesView: View {
Spacer()
}
Spacer()
if identity.id == viewModel.identity.id {
if identity.id == viewModel.currentIdentityID {
Image(systemName: "checkmark.circle")
}
}
}
.disabled(identity.id == viewModel.identity.id)
.disabled(identity.id == viewModel.currentIdentityID)
.buttonStyle(PlainButtonStyle())
}
.onDelete {