From 5e55ce75c2dbf7da47dae7657958216d522b2960 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 2 Jun 2024 10:33:25 -0700 Subject: [PATCH] Fix previous sidebar selection losing navigation stack in some circumstances --- .../Main/MainSidebarViewController.swift | 21 ++++--- .../Main/MainSplitViewController.swift | 59 ++++++++----------- 2 files changed, 37 insertions(+), 43 deletions(-) diff --git a/Tusker/Screens/Main/MainSidebarViewController.swift b/Tusker/Screens/Main/MainSidebarViewController.swift index 47817ffcca..b7d8981f7d 100644 --- a/Tusker/Screens/Main/MainSidebarViewController.swift +++ b/Tusker/Screens/Main/MainSidebarViewController.swift @@ -13,8 +13,8 @@ import Combine @MainActor protocol MainSidebarViewControllerDelegate: AnyObject { func sidebarRequestPresentCompose(_ sidebarViewController: MainSidebarViewController) - func sidebar(_ sidebarViewController: MainSidebarViewController, didSelectItem item: MainSidebarViewController.Item) - func sidebar(_ sidebarViewController: MainSidebarViewController, showViewController viewController: UIViewController) + func sidebar(_ sidebarViewController: MainSidebarViewController, didSelectItem item: MainSidebarViewController.Item, previousItem: MainSidebarViewController.Item?) + func sidebar(_ sidebarViewController: MainSidebarViewController, showViewController viewController: UIViewController, previousItem: MainSidebarViewController.Item?) func sidebar(_ sidebarViewController: MainSidebarViewController, scrollToTopFor item: MainSidebarViewController.Item) } @@ -57,7 +57,7 @@ class MainSidebarViewController: UIViewController { return items } - private(set) var previouslySelectedItem: Item? + private var previouslySelectedItem: Item? var selectedItem: Item? { guard let indexPath = collectionView?.indexPathsForSelectedItems?.first else { return nil @@ -261,19 +261,21 @@ class MainSidebarViewController: UIViewController { } private func returnToPreviousItem() { - let item = previouslySelectedItem ?? .tab(.timelines) + let oldItem = selectedItem + let newItem = previouslySelectedItem ?? .tab(.timelines) previouslySelectedItem = nil - select(item: item, animated: true) - sidebarDelegate?.sidebar(self, didSelectItem: item) + select(item: newItem, animated: true) + sidebarDelegate?.sidebar(self, didSelectItem: newItem, previousItem: oldItem) } private func showAddList() { let service = CreateListService(mastodonController: mastodonController, present: { self.present($0, animated: true ) }) { list in + let oldItem = self.selectedItem self.select(item: .list(list), animated: false) let list = ListTimelineViewController(for: list, mastodonController: self.mastodonController) list.presentEditOnAppear = true - self.sidebarDelegate?.sidebar(self, showViewController: list) + self.sidebarDelegate?.sidebar(self, showViewController: list, previousItem: oldItem) } service.run() } @@ -471,7 +473,7 @@ extension MainSidebarViewController: UICollectionViewDelegate { fatalError("unreachable") } } else { - sidebarDelegate?.sidebar(self, didSelectItem: item) + sidebarDelegate?.sidebar(self, didSelectItem: item, previousItem: previouslySelectedItem) } } @@ -540,8 +542,9 @@ extension MainSidebarViewController: UICollectionViewDragDelegate { extension MainSidebarViewController: InstanceTimelineViewControllerDelegate { func didSaveInstance(url: URL) { dismiss(animated: true) { + let oldItem = self.selectedItem self.select(item: .savedInstance(url), animated: true) - self.sidebarDelegate?.sidebar(self, didSelectItem: .savedInstance(url)) + self.sidebarDelegate?.sidebar(self, didSelectItem: .savedInstance(url), previousItem: oldItem) } } diff --git a/Tusker/Screens/Main/MainSplitViewController.swift b/Tusker/Screens/Main/MainSplitViewController.swift index f356cc93e0..3a73b63fe1 100644 --- a/Tusker/Screens/Main/MainSplitViewController.swift +++ b/Tusker/Screens/Main/MainSplitViewController.swift @@ -86,7 +86,7 @@ class MainSplitViewController: UISplitViewController { // don't unnecesarily construct a content VC unless the we're in actually split mode // when we change from compact -> split for the first time, the VC will be transferred anyways if traitCollection.horizontalSizeClass != .compact { - select(item: .tab(.timelines)) + doSelect(item: .tab(.timelines)) } if UIDevice.current.userInterfaceIdiom != .mac { @@ -149,7 +149,15 @@ class MainSplitViewController: UISplitViewController { self.setViewController(newNav, for: .secondary) } - func select(item: MainSidebarViewController.Item) { + private func select(newItem: MainSidebarViewController.Item, oldItem: MainSidebarViewController.Item?) { + if let oldItem, + newItem != oldItem { + navigationStacks[oldItem] = secondaryNavController.viewControllers + } + doSelect(item: newItem) + } + + private func doSelect(item: MainSidebarViewController.Item) { secondaryNavController.viewControllers = getOrCreateNavigationStack(item: item) } @@ -180,43 +188,28 @@ class MainSplitViewController: UISplitViewController { } @objc func handleSidebarCommandTimelines() { - if let previous = sidebar.selectedItem { - navigationStacks[previous] = secondaryNavController.viewControllers - } sidebar.select(item: .tab(.timelines), animated: false) - select(item: .tab(.timelines)) + select(newItem: .tab(.timelines), oldItem: sidebar.selectedItem) } @objc func handleSidebarCommandNotifications() { - if let previous = sidebar.selectedItem { - navigationStacks[previous] = secondaryNavController.viewControllers - } sidebar.select(item: .tab(.notifications), animated: false) - select(item: .tab(.notifications)) + select(newItem: .tab(.notifications), oldItem: sidebar.selectedItem) } @objc func handleSidebarCommandExplore() { - if let previous = sidebar.selectedItem { - navigationStacks[previous] = secondaryNavController.viewControllers - } sidebar.select(item: .tab(.explore), animated: false) - select(item: .tab(.explore)) + select(newItem: .tab(.explore), oldItem: sidebar.selectedItem) } @objc func handleSidebarCommandBookmarks() { - if let previous = sidebar.selectedItem { - navigationStacks[previous] = secondaryNavController.viewControllers - } sidebar.select(item: .bookmarks, animated: false) - select(item: .bookmarks) + select(newItem: .bookmarks, oldItem: sidebar.selectedItem) } @objc func handleSidebarCommandMyProfile() { - if let previous = sidebar.selectedItem { - navigationStacks[previous] = secondaryNavController.viewControllers - } sidebar.select(item: .tab(.myProfile), animated: false) - select(item: .tab(.myProfile)) + select(newItem: .tab(.myProfile), oldItem: sidebar.selectedItem) } @objc private func sidebarTapped() { @@ -459,12 +452,12 @@ extension MainSplitViewController: UISplitViewControllerDelegate { // These tabs map 1 <-> 1 with sidebar items let item = MainSidebarViewController.Item.tab(tabBarViewController.selectedTab) sidebar.select(item: item, animated: false) - select(item: item) + doSelect(item: item) case .explore: // If the explore tab is active, the sidebar item is determined above when transferring the explore VC's nav stack sidebar.select(item: exploreItem!, animated: false) - select(item: exploreItem!) + doSelect(item: exploreItem!) default: return @@ -489,16 +482,13 @@ extension MainSplitViewController: MainSidebarViewControllerDelegate { compose(editing: nil) } - func sidebar(_ sidebarViewController: MainSidebarViewController, didSelectItem item: MainSidebarViewController.Item) { - if let previous = sidebar.previouslySelectedItem { - navigationStacks[previous] = secondaryNavController.viewControllers - } - select(item: item) + func sidebar(_ sidebarViewController: MainSidebarViewController, didSelectItem item: MainSidebarViewController.Item, previousItem: MainSidebarViewController.Item?) { + select(newItem: item, oldItem: previousItem) } - func sidebar(_ sidebarViewController: MainSidebarViewController, showViewController viewController: UIViewController) { - if let previous = sidebar.previouslySelectedItem { - navigationStacks[previous] = secondaryNavController.viewControllers + func sidebar(_ sidebarViewController: MainSidebarViewController, showViewController viewController: UIViewController, previousItem: MainSidebarViewController.Item?) { + if let previousItem { + navigationStacks[previousItem] = secondaryNavController.viewControllers } secondaryNavController.viewControllers = [viewController] } @@ -582,8 +572,9 @@ extension MainSplitViewController: TuskerRootViewController { return } } + let oldItem = sidebar.selectedItem sidebar.select(item: item, animated: false) - select(item: item) + select(newItem: item, oldItem: oldItem) } func getTabController(tab: MainTabBarViewController.Tab) -> UIViewController? { @@ -625,7 +616,7 @@ extension MainSplitViewController: TuskerRootViewController { } if sidebar.selectedItem != .explore { - select(item: .explore) + select(newItem: .explore, oldItem: sidebar.selectedItem) } guard let searchViewController = secondaryNavController.viewControllers.first as? InlineTrendsViewController else {