From 19176f955cdad29cc864d5a194be43bb112a7c89 Mon Sep 17 00:00:00 2001 From: Justin Mazzocchi <2831158+jzzocc@users.noreply.github.com> Date: Thu, 4 Feb 2021 13:33:29 -0800 Subject: [PATCH] Refactoring --- ...areExtensionNavigationViewController.swift | 2 +- .../MainNavigationViewController.swift | 45 ++++++++++++++----- .../NewStatusViewController.swift | 6 ++- View Controllers/TableViewController.swift | 12 +---- .../View Models/NavigationViewModel.swift | 5 +++ .../View Models/RootViewModel.swift | 6 +++ 6 files changed, 51 insertions(+), 25 deletions(-) diff --git a/Share Extension/ShareExtensionNavigationViewController.swift b/Share Extension/ShareExtensionNavigationViewController.swift index 265d0b0..67528a4 100644 --- a/Share Extension/ShareExtensionNavigationViewController.swift +++ b/Share Extension/ShareExtensionNavigationViewController.swift @@ -30,7 +30,7 @@ class ShareExtensionNavigationViewController: UINavigationController { } setViewControllers( - [NewStatusViewController(viewModel: newStatusViewModel)], + [NewStatusViewController(viewModel: newStatusViewModel, rootViewModel: nil)], animated: false) } } diff --git a/View Controllers/MainNavigationViewController.swift b/View Controllers/MainNavigationViewController.swift index 239c5d0..9081581 100644 --- a/View Controllers/MainNavigationViewController.swift +++ b/View Controllers/MainNavigationViewController.swift @@ -24,6 +24,15 @@ final class MainNavigationViewController: UITabBarController { override func viewDidLoad() { super.viewDidLoad() + viewModel.$presentedNewStatusViewModel.sink { [weak self] in + if let newStatusViewModel = $0 { + self?.presentNewStatus(newStatusViewModel: newStatusViewModel) + } else { + self?.dismissNewStatus() + } + } + .store(in: &cancellables) + viewModel.$presentingSecondaryNavigation.sink { [weak self] in if $0 { self?.presentSecondaryNavigation() @@ -56,6 +65,7 @@ final class MainNavigationViewController: UITabBarController { private extension MainNavigationViewController { static let secondaryNavigationViewTag = UUID().hashValue + static let newStatusViewTag = UUID().hashValue func setupViewControllers(pending: Bool) { var controllers: [UIViewController] = [ @@ -96,18 +106,9 @@ private extension MainNavigationViewController { func setupNewStatusButton() { let newStatusButtonView = NewStatusButtonView(primaryAction: UIAction { [weak self] _ in guard let self = self else { return } - let newStatusViewModel = self.rootViewModel.newStatusViewModel( - identityContext: self.viewModel.identityContext) - let newStatusViewController = NewStatusViewController(viewModel: newStatusViewModel) - let newStatusNavigationController = UINavigationController(rootViewController: newStatusViewController) - if UIDevice.current.userInterfaceIdiom == .phone { - newStatusNavigationController.modalPresentationStyle = .fullScreen - } else { - newStatusNavigationController.isModalInPresentation = true - } - - self.present(newStatusNavigationController, animated: true) + self.viewModel.presentedNewStatusViewModel = + self.rootViewModel.newStatusViewModel(identityContext: self.viewModel.identityContext) }) view.addSubview(newStatusButtonView) @@ -158,6 +159,28 @@ private extension MainNavigationViewController { } } + func presentNewStatus(newStatusViewModel: NewStatusViewModel) { + let newStatusViewController = NewStatusViewController(viewModel: newStatusViewModel, + rootViewModel: rootViewModel) + let navigationController = UINavigationController(rootViewController: newStatusViewController) + + if UIDevice.current.userInterfaceIdiom == .phone { + navigationController.modalPresentationStyle = .overFullScreen + } else { + navigationController.isModalInPresentation = true + } + + navigationController.view.tag = Self.newStatusViewTag + + present(navigationController, animated: true) + } + + func dismissNewStatus() { + if presentedViewController?.view.tag == Self.newStatusViewTag { + dismiss(animated: true) + } + } + func handle(navigation: Navigation) { let vc: UIViewController diff --git a/View Controllers/NewStatusViewController.swift b/View Controllers/NewStatusViewController.swift index 2dfcf7a..87db8d4 100644 --- a/View Controllers/NewStatusViewController.swift +++ b/View Controllers/NewStatusViewController.swift @@ -11,6 +11,7 @@ import ViewModels // swiftlint:disable file_length final class NewStatusViewController: UIViewController { private let viewModel: NewStatusViewModel + private let rootViewModel: RootViewModel? private let scrollView = UIScrollView() private let stackView = UIStackView() private let activityIndicatorView = UIActivityIndicatorView(style: .large) @@ -24,8 +25,9 @@ final class NewStatusViewController: UIViewController { private let documentPickerResuls = PassthroughSubject<[URL]?, Never>() private var cancellables = Set() - init(viewModel: NewStatusViewModel) { + init(viewModel: NewStatusViewModel, rootViewModel: RootViewModel?) { self.viewModel = viewModel + self.rootViewModel = rootViewModel super.init(nibName: nil, bundle: nil) @@ -241,7 +243,7 @@ private extension NewStatusViewController { if let extensionContext = extensionContext { extensionContext.completeRequest(returningItems: nil) } else { - presentingViewController?.dismiss(animated: true) + rootViewModel?.navigationViewModel?.presentedNewStatusViewModel = nil } } diff --git a/View Controllers/TableViewController.swift b/View Controllers/TableViewController.swift index 1d03783..28ceb9a 100644 --- a/View Controllers/TableViewController.swift +++ b/View Controllers/TableViewController.swift @@ -452,20 +452,10 @@ private extension TableViewController { } func compose(inReplyToViewModel: StatusViewModel?, redraft: Status?) { - let newStatusViewModel = rootViewModel.newStatusViewModel( + rootViewModel.navigationViewModel?.presentedNewStatusViewModel = rootViewModel.newStatusViewModel( identityContext: viewModel.identityContext, inReplyTo: inReplyToViewModel, redraft: redraft) - let newStatusViewController = NewStatusViewController(viewModel: newStatusViewModel) - let navigationController = UINavigationController(rootViewController: newStatusViewController) - - if UIDevice.current.userInterfaceIdiom == .phone { - navigationController.modalPresentationStyle = .overFullScreen - } else { - navigationController.isModalInPresentation = true - } - - present(navigationController, animated: true) } func confirmDelete(statusViewModel: StatusViewModel, redraft: Bool) { diff --git a/ViewModels/Sources/ViewModels/View Models/NavigationViewModel.swift b/ViewModels/Sources/ViewModels/View Models/NavigationViewModel.swift index 45b15dc..35bf9ac 100644 --- a/ViewModels/Sources/ViewModels/View Models/NavigationViewModel.swift +++ b/ViewModels/Sources/ViewModels/View Models/NavigationViewModel.swift @@ -10,6 +10,7 @@ public final class NavigationViewModel: ObservableObject { public let navigations: AnyPublisher @Published public private(set) var recentIdentities = [Identity]() + @Published public var presentedNewStatusViewModel: NewStatusViewModel? @Published public var presentingSecondaryNavigation = false @Published public var alertItem: AlertItem? @@ -110,6 +111,10 @@ public extension NavigationViewModel { titleComponents: ["follow-requests"]))) } + func navigate(pushNotification: PushNotification) { + // TODO + } + func viewModel(timeline: Timeline) -> CollectionItemsViewModel { CollectionItemsViewModel( collectionService: identityContext.service.navigationService.timelineService(timeline: timeline), diff --git a/ViewModels/Sources/ViewModels/View Models/RootViewModel.swift b/ViewModels/Sources/ViewModels/View Models/RootViewModel.swift index 0e4704c..a1f9d37 100644 --- a/ViewModels/Sources/ViewModels/View Models/RootViewModel.swift +++ b/ViewModels/Sources/ViewModels/View Models/RootViewModel.swift @@ -178,6 +178,12 @@ private extension RootViewModel { if identityId != navigationViewModel?.identityContext.identity.id { identitySelected(id: identityId, immediate: false, notify: true) } + + $navigationViewModel.first { $0?.identityContext.identity.id == identityId } + // Ensure views are set up if switching accounts + .delay(for: .milliseconds(1), scheduler: DispatchQueue.main) + .sink { $0?.navigate(pushNotification: pushNotification) } + .store(in: &cancellables) } func notifyIdentityChange(identityContext: IdentityContext) {