From 61773b97dbd8d7376fccc95d279d4cc5deebf1f5 Mon Sep 17 00:00:00 2001 From: James Magahern Date: Fri, 5 Aug 2022 15:56:30 -0700 Subject: [PATCH] TabPickerViewController: Remote tab UI --- App/Browser View/BrowserViewController.swift | 32 ++++++++-- App/Tabs/TabPickerViewController.swift | 67 ++++++++++++++++---- 2 files changed, 81 insertions(+), 18 deletions(-) diff --git a/App/Browser View/BrowserViewController.swift b/App/Browser View/BrowserViewController.swift index 58f447d..c1c624d 100644 --- a/App/Browser View/BrowserViewController.swift +++ b/App/Browser View/BrowserViewController.swift @@ -139,20 +139,38 @@ class BrowserViewController: UIViewController toolbarController.windowButton.addAction(UIAction(handler: { [unowned self] _ in let tabPickerController = TabPickerViewController() tabPickerController.delegate = self + tabPickerController.title = "Tabs" + tabPickerController.tabBarItem.image = UIImage(systemName: "rectangle.on.rectangle") tabPickerController.selectedTabIdentifier = self.tab.identifier - tabPickerController.tabIdentifiers = tabController.tabs.map { $0.identifier } tabPickerController.tabObserver = tabController.$tabs .receive(on: RunLoop.main) .sink(receiveValue: { (newTabs: [Tab]) in - tabPickerController.tabIdentifiers = newTabs.map { $0.identifier } + tabPickerController.setTabIdentifiers(newTabs.map { $0.identifier }, forHost: TabPickerViewController.localHostIdentifier) }) - let navController = UINavigationController(rootViewController: tabPickerController) - navController.modalPresentationStyle = .popover - navController.popoverPresentationController?.sourceView = self.toolbarController.windowButton - navController.popoverPresentationController?.delegate = self + // Set localhost tabs + let tabIdentifiers = tabController.tabs.map { $0.identifier } + tabPickerController.setTabIdentifiers(tabIdentifiers, forHost: TabPickerViewController.localHostIdentifier) + tabPickerController.selectedTabHost = TabPickerViewController.localHostIdentifier + + let remoteTabPickerController = TabPickerViewController() + remoteTabPickerController.delegate = self + remoteTabPickerController.title = "Remote Tabs" + remoteTabPickerController.tabBarItem.image = UIImage(systemName: "icloud") + remoteTabPickerController.newTabButton.isEnabled = false + remoteTabPickerController.editButtonItem.isEnabled = false + + let tabBarController = UITabBarController(nibName: nil, bundle: nil) + tabBarController.viewControllers = [ + UINavigationController(rootViewController: tabPickerController), + UINavigationController(rootViewController: remoteTabPickerController) + ] + + tabBarController.modalPresentationStyle = .popover + tabBarController.popoverPresentationController?.sourceView = self.toolbarController.windowButton + tabBarController.popoverPresentationController?.delegate = self - self.present(navController, animated: true, completion: nil) + self.present(tabBarController, animated: true, completion: nil) }), for: .touchUpInside) let newTabAction = UIAction { [unowned self] action in diff --git a/App/Tabs/TabPickerViewController.swift b/App/Tabs/TabPickerViewController.swift index 8f537ad..23f812d 100644 --- a/App/Tabs/TabPickerViewController.swift +++ b/App/Tabs/TabPickerViewController.swift @@ -20,20 +20,15 @@ class TabPickerViewController: UIViewController, UICollectionViewDelegate { typealias TabID = UUID + public static var localHostIdentifier = "__localhost__"; + public var selectedTabIdentifier: UUID? - public var tabIdentifiers: [ UUID ] = [] { - didSet { - var snapshot = dataSource.snapshot() - snapshot.deleteAllItems() - snapshot.appendSections([ 0 ]) - snapshot.appendItems(tabIdentifiers) - dataSource.apply(snapshot) - } - } + public var selectedTabHost: String? { didSet { didChangeSelectedTabHost(selectedTabHost!) } } weak var delegate: TabPickerViewControllerDelegate? public var tabObserver: AnyCancellable? private var selectedTabIdentifiersForEditing: Set = [] + private var tabIdentifiersByHost: [String: [UUID]] = [:] private var listConfiguration = UICollectionLayoutListConfiguration(appearance: .insetGrouped) private lazy var listLayout = UICollectionViewCompositionalLayout.list(using: listConfiguration) @@ -88,18 +83,29 @@ class TabPickerViewController: UIViewController, UICollectionViewDelegate get { return super.traitCollection.alwaysPadLike() } } - private lazy var newTabButton: UIBarButtonItem = { + public lazy var newTabButton: UIBarButtonItem = { UIBarButtonItem(systemItem: .add, primaryAction: UIAction(handler: { [unowned self] _ in self.delegate?.tabPicker(self, createNewTabWithURL: nil) }), menu: nil) }() - lazy var deleteTabButton: UIBarButtonItem = { + private lazy var deleteTabButton: UIBarButtonItem = { UIBarButtonItem(systemItem: .trash, primaryAction: UIAction(handler: { [unowned self] _ in deleteSelectedTabs() }), menu: nil) }() + private lazy var hostPickerButton: UIButton = { + var buttonConfiguration = UIButton.Configuration.filled() + buttonConfiguration.title = "Host" + + let button = UIButton(configuration: buttonConfiguration) + button.changesSelectionAsPrimaryAction = true + button.showsMenuAsPrimaryAction = true + + return button + }() + init() { super.init(nibName: nil, bundle: nil) self.title = "Tabs" @@ -130,6 +136,35 @@ class TabPickerViewController: UIViewController, UICollectionViewDelegate configureNavigationButtons(forEditing: isEditing) } + public func setTabIdentifiers(_ identifiers: [UUID], forHost host: String) { + tabIdentifiersByHost[host] = identifiers + if host == selectedTabHost { + var snapshot = dataSource.snapshot() + snapshot.deleteAllItems() + snapshot.appendSections([ 0 ]) + snapshot.appendItems(identifiers) + dataSource.apply(snapshot) + } + + reloadHostPickerButtonMenu() + } + + private func reloadHostPickerButtonMenu() { + var menuChildren: [UIAction] = [] + for host in tabIdentifiersByHost.keys { + menuChildren.append(UIAction(title: host, handler: { [unowned self] _ in + selectedTabHost = host + })) + } + + hostPickerButton.menu = UIMenu(children: menuChildren) + if tabIdentifiersByHost.keys.count > 0 && tabIdentifiersByHost.keys.first != Self.localHostIdentifier { + navigationItem.titleView = hostPickerButton + } else { + navigationItem.titleView = nil + } + } + private func configureNavigationButtons(forEditing: Bool) { if !forEditing { navigationItem.rightBarButtonItem = newTabButton @@ -158,6 +193,16 @@ class TabPickerViewController: UIViewController, UICollectionViewDelegate dataSource.apply(snapshot, animatingDifferences: true) } + private func didChangeSelectedTabHost(_ tabHost: String) { + guard let tabIdentifiers = tabIdentifiersByHost[tabHost] else { return } + + var snapshot = dataSource.snapshot() + snapshot.deleteAllItems() + snapshot.appendSections([ 0 ]) + snapshot.appendItems(tabIdentifiers) + dataSource.applySnapshotUsingReloadData(snapshot) + } + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { guard let tab = dataSource.itemIdentifier(for: indexPath) else { return }