Fix previous sidebar selection losing navigation stack in some circumstances

This commit is contained in:
Shadowfacts 2024-06-02 10:33:25 -07:00
parent eec2adbfd9
commit 5e55ce75c2
2 changed files with 37 additions and 43 deletions

View File

@ -13,8 +13,8 @@ import Combine
@MainActor @MainActor
protocol MainSidebarViewControllerDelegate: AnyObject { protocol MainSidebarViewControllerDelegate: AnyObject {
func sidebarRequestPresentCompose(_ sidebarViewController: MainSidebarViewController) func sidebarRequestPresentCompose(_ sidebarViewController: MainSidebarViewController)
func sidebar(_ sidebarViewController: MainSidebarViewController, didSelectItem item: MainSidebarViewController.Item) func sidebar(_ sidebarViewController: MainSidebarViewController, didSelectItem item: MainSidebarViewController.Item, previousItem: MainSidebarViewController.Item?)
func sidebar(_ sidebarViewController: MainSidebarViewController, showViewController viewController: UIViewController) func sidebar(_ sidebarViewController: MainSidebarViewController, showViewController viewController: UIViewController, previousItem: MainSidebarViewController.Item?)
func sidebar(_ sidebarViewController: MainSidebarViewController, scrollToTopFor item: MainSidebarViewController.Item) func sidebar(_ sidebarViewController: MainSidebarViewController, scrollToTopFor item: MainSidebarViewController.Item)
} }
@ -57,7 +57,7 @@ class MainSidebarViewController: UIViewController {
return items return items
} }
private(set) var previouslySelectedItem: Item? private var previouslySelectedItem: Item?
var selectedItem: Item? { var selectedItem: Item? {
guard let indexPath = collectionView?.indexPathsForSelectedItems?.first else { guard let indexPath = collectionView?.indexPathsForSelectedItems?.first else {
return nil return nil
@ -261,19 +261,21 @@ class MainSidebarViewController: UIViewController {
} }
private func returnToPreviousItem() { private func returnToPreviousItem() {
let item = previouslySelectedItem ?? .tab(.timelines) let oldItem = selectedItem
let newItem = previouslySelectedItem ?? .tab(.timelines)
previouslySelectedItem = nil previouslySelectedItem = nil
select(item: item, animated: true) select(item: newItem, animated: true)
sidebarDelegate?.sidebar(self, didSelectItem: item) sidebarDelegate?.sidebar(self, didSelectItem: newItem, previousItem: oldItem)
} }
private func showAddList() { private func showAddList() {
let service = CreateListService(mastodonController: mastodonController, present: { self.present($0, animated: true let service = CreateListService(mastodonController: mastodonController, present: { self.present($0, animated: true
) }) { list in ) }) { list in
let oldItem = self.selectedItem
self.select(item: .list(list), animated: false) self.select(item: .list(list), animated: false)
let list = ListTimelineViewController(for: list, mastodonController: self.mastodonController) let list = ListTimelineViewController(for: list, mastodonController: self.mastodonController)
list.presentEditOnAppear = true list.presentEditOnAppear = true
self.sidebarDelegate?.sidebar(self, showViewController: list) self.sidebarDelegate?.sidebar(self, showViewController: list, previousItem: oldItem)
} }
service.run() service.run()
} }
@ -471,7 +473,7 @@ extension MainSidebarViewController: UICollectionViewDelegate {
fatalError("unreachable") fatalError("unreachable")
} }
} else { } else {
sidebarDelegate?.sidebar(self, didSelectItem: item) sidebarDelegate?.sidebar(self, didSelectItem: item, previousItem: previouslySelectedItem)
} }
} }
@ -540,8 +542,9 @@ extension MainSidebarViewController: UICollectionViewDragDelegate {
extension MainSidebarViewController: InstanceTimelineViewControllerDelegate { extension MainSidebarViewController: InstanceTimelineViewControllerDelegate {
func didSaveInstance(url: URL) { func didSaveInstance(url: URL) {
dismiss(animated: true) { dismiss(animated: true) {
let oldItem = self.selectedItem
self.select(item: .savedInstance(url), animated: true) self.select(item: .savedInstance(url), animated: true)
self.sidebarDelegate?.sidebar(self, didSelectItem: .savedInstance(url)) self.sidebarDelegate?.sidebar(self, didSelectItem: .savedInstance(url), previousItem: oldItem)
} }
} }

View File

@ -86,7 +86,7 @@ class MainSplitViewController: UISplitViewController {
// don't unnecesarily construct a content VC unless the we're in actually split mode // 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 // when we change from compact -> split for the first time, the VC will be transferred anyways
if traitCollection.horizontalSizeClass != .compact { if traitCollection.horizontalSizeClass != .compact {
select(item: .tab(.timelines)) doSelect(item: .tab(.timelines))
} }
if UIDevice.current.userInterfaceIdiom != .mac { if UIDevice.current.userInterfaceIdiom != .mac {
@ -149,7 +149,15 @@ class MainSplitViewController: UISplitViewController {
self.setViewController(newNav, for: .secondary) 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) secondaryNavController.viewControllers = getOrCreateNavigationStack(item: item)
} }
@ -180,43 +188,28 @@ class MainSplitViewController: UISplitViewController {
} }
@objc func handleSidebarCommandTimelines() { @objc func handleSidebarCommandTimelines() {
if let previous = sidebar.selectedItem {
navigationStacks[previous] = secondaryNavController.viewControllers
}
sidebar.select(item: .tab(.timelines), animated: false) sidebar.select(item: .tab(.timelines), animated: false)
select(item: .tab(.timelines)) select(newItem: .tab(.timelines), oldItem: sidebar.selectedItem)
} }
@objc func handleSidebarCommandNotifications() { @objc func handleSidebarCommandNotifications() {
if let previous = sidebar.selectedItem {
navigationStacks[previous] = secondaryNavController.viewControllers
}
sidebar.select(item: .tab(.notifications), animated: false) sidebar.select(item: .tab(.notifications), animated: false)
select(item: .tab(.notifications)) select(newItem: .tab(.notifications), oldItem: sidebar.selectedItem)
} }
@objc func handleSidebarCommandExplore() { @objc func handleSidebarCommandExplore() {
if let previous = sidebar.selectedItem {
navigationStacks[previous] = secondaryNavController.viewControllers
}
sidebar.select(item: .tab(.explore), animated: false) sidebar.select(item: .tab(.explore), animated: false)
select(item: .tab(.explore)) select(newItem: .tab(.explore), oldItem: sidebar.selectedItem)
} }
@objc func handleSidebarCommandBookmarks() { @objc func handleSidebarCommandBookmarks() {
if let previous = sidebar.selectedItem {
navigationStacks[previous] = secondaryNavController.viewControllers
}
sidebar.select(item: .bookmarks, animated: false) sidebar.select(item: .bookmarks, animated: false)
select(item: .bookmarks) select(newItem: .bookmarks, oldItem: sidebar.selectedItem)
} }
@objc func handleSidebarCommandMyProfile() { @objc func handleSidebarCommandMyProfile() {
if let previous = sidebar.selectedItem {
navigationStacks[previous] = secondaryNavController.viewControllers
}
sidebar.select(item: .tab(.myProfile), animated: false) sidebar.select(item: .tab(.myProfile), animated: false)
select(item: .tab(.myProfile)) select(newItem: .tab(.myProfile), oldItem: sidebar.selectedItem)
} }
@objc private func sidebarTapped() { @objc private func sidebarTapped() {
@ -459,12 +452,12 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
// These tabs map 1 <-> 1 with sidebar items // These tabs map 1 <-> 1 with sidebar items
let item = MainSidebarViewController.Item.tab(tabBarViewController.selectedTab) let item = MainSidebarViewController.Item.tab(tabBarViewController.selectedTab)
sidebar.select(item: item, animated: false) sidebar.select(item: item, animated: false)
select(item: item) doSelect(item: item)
case .explore: case .explore:
// If the explore tab is active, the sidebar item is determined above when transferring the explore VC's nav stack // 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) sidebar.select(item: exploreItem!, animated: false)
select(item: exploreItem!) doSelect(item: exploreItem!)
default: default:
return return
@ -489,16 +482,13 @@ extension MainSplitViewController: MainSidebarViewControllerDelegate {
compose(editing: nil) compose(editing: nil)
} }
func sidebar(_ sidebarViewController: MainSidebarViewController, didSelectItem item: MainSidebarViewController.Item) { func sidebar(_ sidebarViewController: MainSidebarViewController, didSelectItem item: MainSidebarViewController.Item, previousItem: MainSidebarViewController.Item?) {
if let previous = sidebar.previouslySelectedItem { select(newItem: item, oldItem: previousItem)
navigationStacks[previous] = secondaryNavController.viewControllers
}
select(item: item)
} }
func sidebar(_ sidebarViewController: MainSidebarViewController, showViewController viewController: UIViewController) { func sidebar(_ sidebarViewController: MainSidebarViewController, showViewController viewController: UIViewController, previousItem: MainSidebarViewController.Item?) {
if let previous = sidebar.previouslySelectedItem { if let previousItem {
navigationStacks[previous] = secondaryNavController.viewControllers navigationStacks[previousItem] = secondaryNavController.viewControllers
} }
secondaryNavController.viewControllers = [viewController] secondaryNavController.viewControllers = [viewController]
} }
@ -582,8 +572,9 @@ extension MainSplitViewController: TuskerRootViewController {
return return
} }
} }
let oldItem = sidebar.selectedItem
sidebar.select(item: item, animated: false) sidebar.select(item: item, animated: false)
select(item: item) select(newItem: item, oldItem: oldItem)
} }
func getTabController(tab: MainTabBarViewController.Tab) -> UIViewController? { func getTabController(tab: MainTabBarViewController.Tab) -> UIViewController? {
@ -625,7 +616,7 @@ extension MainSplitViewController: TuskerRootViewController {
} }
if sidebar.selectedItem != .explore { if sidebar.selectedItem != .explore {
select(item: .explore) select(newItem: .explore, oldItem: sidebar.selectedItem)
} }
guard let searchViewController = secondaryNavController.viewControllers.first as? InlineTrendsViewController else { guard let searchViewController = secondaryNavController.viewControllers.first as? InlineTrendsViewController else {