mirror of
https://github.com/metabolist/metatext.git
synced 2024-12-22 05:26:30 +00:00
Refactoring
This commit is contained in:
parent
4c1f0e2452
commit
182ecb5b91
8 changed files with 58 additions and 55 deletions
|
@ -47,7 +47,7 @@ public extension RootViewModel {
|
|||
}
|
||||
|
||||
public extension Identification {
|
||||
static let preview = RootViewModel.preview.identification!
|
||||
static let preview = RootViewModel.preview.navigationViewModel!.identification
|
||||
}
|
||||
|
||||
// swiftlint:enable force_try
|
||||
|
|
|
@ -5,7 +5,7 @@ import Foundation
|
|||
import ServiceLayer
|
||||
|
||||
public final class Identification: ObservableObject {
|
||||
@Published private(set) var identity: Identity
|
||||
@Published private(set) public var identity: Identity
|
||||
let service: IdentityService
|
||||
|
||||
init(identity: Identity, observation: AnyPublisher<Identity, Never>, service: IdentityService) {
|
||||
|
|
|
@ -5,24 +5,7 @@ import Foundation
|
|||
import ServiceLayer
|
||||
|
||||
public final class RootViewModel: ObservableObject {
|
||||
@Published public private(set) var identification: Identification? {
|
||||
didSet {
|
||||
guard let identification = identification else { return }
|
||||
|
||||
identification.service.updateLastUse()
|
||||
.sink { _ in } receiveValue: { _ in }
|
||||
.store(in: &cancellables)
|
||||
|
||||
userNotificationService.isAuthorized()
|
||||
.filter { $0 }
|
||||
.zip(registerForRemoteNotifications())
|
||||
.filter { identification.identity.lastRegisteredDeviceToken != $1 }
|
||||
.map { ($1, identification.identity.pushSubscriptionAlerts) }
|
||||
.flatMap(identification.service.createPushSubscription(deviceToken:alerts:))
|
||||
.sink { _ in } receiveValue: { _ in }
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
}
|
||||
@Published public private(set) var navigationViewModel: TabNavigationViewModel?
|
||||
|
||||
@Published private var mostRecentlyUsedIdentityID: UUID?
|
||||
private let environment: AppEnvironment
|
||||
|
@ -74,10 +57,12 @@ public extension RootViewModel {
|
|||
|
||||
private extension RootViewModel {
|
||||
func identitySelected(id: UUID?, immediate: Bool) {
|
||||
navigationViewModel?.presentingSecondaryNavigation = false
|
||||
|
||||
guard
|
||||
let id = id,
|
||||
let identityService = try? allIdentitiesService.identityService(id: id) else {
|
||||
identification = nil
|
||||
navigationViewModel = nil
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -93,13 +78,30 @@ private extension RootViewModel {
|
|||
.share()
|
||||
|
||||
observation
|
||||
.filter { [weak self] in $0.id != self?.identification?.identity.id }
|
||||
.map {
|
||||
Identification(
|
||||
.filter { [weak self] in $0.id != self?.navigationViewModel?.identification.identity.id }
|
||||
.map { [weak self] in
|
||||
let identification = Identification(
|
||||
identity: $0,
|
||||
observation: observation.eraseToAnyPublisher(),
|
||||
service: identityService)
|
||||
|
||||
if let self = self {
|
||||
identification.service.updateLastUse()
|
||||
.sink { _ in } receiveValue: { _ in }
|
||||
.store(in: &self.cancellables)
|
||||
|
||||
self.userNotificationService.isAuthorized()
|
||||
.filter { $0 }
|
||||
.zip(self.registerForRemoteNotifications())
|
||||
.filter { identification.identity.lastRegisteredDeviceToken != $1 }
|
||||
.map { ($1, identification.identity.pushSubscriptionAlerts) }
|
||||
.flatMap(identification.service.createPushSubscription(deviceToken:alerts:))
|
||||
.sink { _ in } receiveValue: { _ in }
|
||||
.store(in: &self.cancellables)
|
||||
}
|
||||
|
||||
return TabNavigationViewModel(identification: identification)
|
||||
}
|
||||
.assign(to: &$identification)
|
||||
.assign(to: &$navigationViewModel)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import Mastodon
|
|||
import ServiceLayer
|
||||
|
||||
public final class TabNavigationViewModel: ObservableObject {
|
||||
@Published public private(set) var identity: Identity
|
||||
public let identification: Identification
|
||||
@Published public private(set) var recentIdentities = [Identity]()
|
||||
@Published public var timeline: Timeline
|
||||
@Published public private(set) var timelinesAndLists: [Timeline]
|
||||
|
@ -14,18 +14,19 @@ public final class TabNavigationViewModel: ObservableObject {
|
|||
@Published public var alertItem: AlertItem?
|
||||
public var selectedTab: Tab? = .timelines
|
||||
|
||||
private let identification: Identification
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
public init(identification: Identification) {
|
||||
self.identification = identification
|
||||
identity = identification.identity
|
||||
timeline = identification.service.isAuthorized ? .home : .local
|
||||
timelinesAndLists = identification.service.isAuthorized
|
||||
? Timeline.authenticatedDefaults
|
||||
: Timeline.unauthenticatedDefaults
|
||||
|
||||
identification.$identity.dropFirst().assign(to: &$identity)
|
||||
identification.$identity
|
||||
.sink { [weak self] _ in self?.objectWillChange.send() }
|
||||
.store(in: &cancellables)
|
||||
|
||||
identification.service.recentIdentitiesObservation()
|
||||
.assignErrorsToAlertItem(to: \.alertItem, on: self)
|
||||
.assign(to: &$recentIdentities)
|
||||
|
@ -51,9 +52,9 @@ public extension TabNavigationViewModel {
|
|||
var timelineSubtitle: String {
|
||||
switch timeline {
|
||||
case .home, .list:
|
||||
return identity.handle
|
||||
return identification.identity.handle
|
||||
case .local, .federated, .tag:
|
||||
return identity.instance?.uri ?? ""
|
||||
return identification.identity.instance?.uri ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,7 +73,7 @@ public extension TabNavigationViewModel {
|
|||
.sink { _ in }
|
||||
.store(in: &cancellables)
|
||||
|
||||
if identity.preferences.useServerPostingReadingPreferences {
|
||||
if identification.identity.preferences.useServerPostingReadingPreferences {
|
||||
identification.service.refreshServerPreferences()
|
||||
.assignErrorsToAlertItem(to: \.alertItem, on: self)
|
||||
.sink { _ in }
|
||||
|
|
|
@ -5,7 +5,7 @@ import ViewModels
|
|||
|
||||
struct ListsView: View {
|
||||
@StateObject var viewModel: ListsViewModel
|
||||
@EnvironmentObject var tabNavigationViewModel: TabNavigationViewModel
|
||||
@EnvironmentObject var rootViewModel: RootViewModel
|
||||
@State private var newListTitle = ""
|
||||
|
||||
var body: some View {
|
||||
|
@ -28,8 +28,8 @@ struct ListsView: View {
|
|||
Section {
|
||||
ForEach(viewModel.lists) { list in
|
||||
Button(list.title) {
|
||||
tabNavigationViewModel.timeline = .list(list)
|
||||
tabNavigationViewModel.presentingSecondaryNavigation = false
|
||||
rootViewModel.navigationViewModel?.timeline = .list(list)
|
||||
rootViewModel.navigationViewModel?.presentingSecondaryNavigation = false
|
||||
}
|
||||
}
|
||||
.onDelete {
|
||||
|
|
|
@ -7,11 +7,9 @@ struct RootView: View {
|
|||
@StateObject var viewModel: RootViewModel
|
||||
|
||||
var body: some View {
|
||||
if let identification = viewModel.identification {
|
||||
TabNavigationView()
|
||||
.id(UUID())
|
||||
.environmentObject(identification)
|
||||
.environmentObject(TabNavigationViewModel(identification: identification))
|
||||
if let navigationViewModel = viewModel.navigationViewModel {
|
||||
TabNavigationView(viewModel: navigationViewModel)
|
||||
.id(navigationViewModel.identification.identity.id)
|
||||
.environmentObject(viewModel)
|
||||
.transition(.opacity)
|
||||
} else {
|
||||
|
|
|
@ -5,8 +5,9 @@ import SwiftUI
|
|||
import ViewModels
|
||||
|
||||
struct SecondaryNavigationView: View {
|
||||
@ObservedObject var viewModel: TabNavigationViewModel
|
||||
@EnvironmentObject var identification: Identification
|
||||
@EnvironmentObject var tabNavigationViewModel: TabNavigationViewModel
|
||||
@EnvironmentObject var rootViewModel: RootViewModel
|
||||
@Environment(\.displayScale) var displayScale: CGFloat
|
||||
|
||||
var body: some View {
|
||||
|
@ -17,25 +18,25 @@ struct SecondaryNavigationView: View {
|
|||
destination: IdentitiesView(viewModel: .init(identification: identification)),
|
||||
label: {
|
||||
HStack {
|
||||
KFImage(tabNavigationViewModel.identity.image,
|
||||
KFImage(identification.identity.image,
|
||||
options: .downsampled(dimension: 50, scaleFactor: displayScale))
|
||||
VStack(alignment: .leading) {
|
||||
if tabNavigationViewModel.identity.authenticated {
|
||||
if let account = tabNavigationViewModel.identity.account {
|
||||
if identification.identity.authenticated {
|
||||
if let account = identification.identity.account {
|
||||
CustomEmojiText(
|
||||
text: account.displayName,
|
||||
emoji: account.emojis,
|
||||
textStyle: .headline)
|
||||
}
|
||||
Text(tabNavigationViewModel.identity.handle)
|
||||
Text(identification.identity.handle)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(0.5)
|
||||
} else {
|
||||
Text(tabNavigationViewModel.identity.handle)
|
||||
Text(identification.identity.handle)
|
||||
.font(.headline)
|
||||
if let instance = tabNavigationViewModel.identity.instance {
|
||||
if let instance = identification.identity.instance {
|
||||
Text(instance.uri)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
|
@ -68,7 +69,7 @@ struct SecondaryNavigationView: View {
|
|||
.toolbar {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button {
|
||||
tabNavigationViewModel.presentingSecondaryNavigation = false
|
||||
viewModel.presentingSecondaryNavigation = false
|
||||
} label: {
|
||||
Image(systemName: "xmark.circle.fill")
|
||||
}
|
||||
|
@ -84,9 +85,9 @@ import PreviewViewModels
|
|||
|
||||
struct SecondaryNavigationView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
SecondaryNavigationView()
|
||||
SecondaryNavigationView(viewModel: TabNavigationViewModel(identification: .preview))
|
||||
.environmentObject(Identification.preview)
|
||||
.environmentObject(TabNavigationViewModel(identification: .preview))
|
||||
.environmentObject(RootViewModel.preview)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@ import SwiftUI
|
|||
import ViewModels
|
||||
|
||||
struct TabNavigationView: View {
|
||||
@EnvironmentObject var viewModel: TabNavigationViewModel
|
||||
@ObservedObject var viewModel: TabNavigationViewModel
|
||||
@EnvironmentObject var rootViewModel: RootViewModel
|
||||
@Environment(\.displayScale) var displayScale: CGFloat
|
||||
|
||||
|
@ -24,8 +24,10 @@ struct TabNavigationView: View {
|
|||
.tag(tab)
|
||||
}
|
||||
}
|
||||
.environmentObject(viewModel.identification)
|
||||
.sheet(isPresented: $viewModel.presentingSecondaryNavigation) {
|
||||
SecondaryNavigationView()
|
||||
SecondaryNavigationView(viewModel: viewModel)
|
||||
.environmentObject(viewModel.identification)
|
||||
.environmentObject(viewModel)
|
||||
.environmentObject(rootViewModel)
|
||||
}
|
||||
|
@ -81,7 +83,7 @@ private extension TabNavigationView {
|
|||
Button {
|
||||
viewModel.presentingSecondaryNavigation.toggle()
|
||||
} label: {
|
||||
KFImage(viewModel.identity.image,
|
||||
KFImage(viewModel.identification.identity.image,
|
||||
options: .downsampled(dimension: 28, scaleFactor: displayScale))
|
||||
.placeholder { Image(systemName: "gear") }
|
||||
.renderingMode(.original)
|
||||
|
@ -156,9 +158,8 @@ import PreviewViewModels
|
|||
|
||||
struct TabNavigation_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
TabNavigationView()
|
||||
TabNavigationView(viewModel: TabNavigationViewModel(identification: .preview))
|
||||
.environmentObject(Identification.preview)
|
||||
.environmentObject(TabNavigationViewModel(identification: .preview))
|
||||
.environmentObject(RootViewModel.preview)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue