From a3af04759124544580423d4aa0a28d7199b3c74b Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 20 Dec 2020 14:03:38 -0500 Subject: [PATCH] Re-add back/forwards context menus --- Gemini-iOS/ToolbarView.swift | 74 +++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/Gemini-iOS/ToolbarView.swift b/Gemini-iOS/ToolbarView.swift index 53f920b..86aadeb 100644 --- a/Gemini-iOS/ToolbarView.swift +++ b/Gemini-iOS/ToolbarView.swift @@ -53,6 +53,11 @@ class ToolbarView: UIView { backButton.setImage(UIImage(systemName: "arrow.left", withConfiguration: symbolConfig), for: .normal) backButton.accessibilityLabel = "Back" backButton.isPointerInteractionEnabled = true + // fallback for when UIButton.menu isn't available + if #available(iOS 14.0, *) { + } else { + backButton.addInteraction(UIContextMenuInteraction(delegate: self)) + } forwardsButton = UIButton() forwardsButton.addTarget(navigator, action: #selector(NavigationManager.goForward), for: .touchUpInside) @@ -60,6 +65,10 @@ class ToolbarView: UIView { forwardsButton.setImage(UIImage(systemName: "arrow.right", withConfiguration: symbolConfig), for: .normal) forwardsButton.accessibilityLabel = "Forward" forwardsButton.isPointerInteractionEnabled = true + if #available(iOS 14.0, *) { + } else { + forwardsButton.addInteraction(UIContextMenuInteraction(delegate: self)) + } reloadButton = UIButton() reloadButton.addTarget(navigator, action: #selector(NavigationManager.reload), for: .touchUpInside) @@ -105,10 +114,11 @@ class ToolbarView: UIView { stack.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor), ]) + updateNavigationButtons() + navigator.navigationOperation .sink { (_) in - self.backButton.isEnabled = navigator.backStack.count > 0 - self.forwardsButton.isEnabled = navigator.forwardStack.count > 0 + self.updateNavigationButtons() } .store(in: &cancellables) } @@ -123,6 +133,39 @@ class ToolbarView: UIView { border.backgroundColor = UIColor(white: traitCollection.userInterfaceStyle == .dark ? 0.25 : 0.75, alpha: 1) } + private func urlForDisplay(_ url: URL) -> String { + var str = url.host! + if let port = url.port, + url.scheme != "gemini" || port != 1965 { + str += ":\(port)" + } + str += url.path + return str + } + + private func updateNavigationButtons() { + backButton.isEnabled = navigator.backStack.count > 0 + forwardsButton.isEnabled = navigator.forwardStack.count > 0 + + if #available(iOS 14.0, *) { + let back = navigator.backStack.suffix(5).enumerated().reversed().map { (index, url) -> UIAction in + let backCount = min(5, navigator.backStack.count) - index + return UIAction(title: urlForDisplay(url)) { (_) in + self.navigator.back(count: backCount) + } + } + backButton.menu = UIMenu(children: back) + + let forward = navigator.forwardStack.prefix(5).enumerated().map { (index, url) -> UIAction in + let forwardCount = index + 1 + return UIAction(title: urlForDisplay(url)) { (_) in + self.navigator.forward(count: forwardCount) + } + } + forwardsButton.menu = UIMenu(children: forward) + } + } + @objc private func tableOfContentsPressed() { showTableOfContents?() } @@ -136,3 +179,30 @@ class ToolbarView: UIView { } } + +extension ToolbarView: UIContextMenuInteractionDelegate { + func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? { + if interaction.view == backButton { + return UIContextMenuConfiguration(identifier: nil, previewProvider: { nil }) { (_) -> UIMenu? in + let children = self.navigator.backStack.suffix(5).enumerated().map { (index, url) in + UIAction(title: self.urlForDisplay(url)) { (_) in + self.navigator.back(count: min(5, self.navigator.backStack.count) - index) + } + } + return UIMenu(title: "", image: nil, identifier: nil, options: [], children: children) + } + } else if interaction.view == forwardsButton { + return UIContextMenuConfiguration(identifier: nil, previewProvider: { nil }) { (_) -> UIMenu? in + let children = self.navigator.forwardStack.prefix(5).enumerated().map { (index, url) -> UIAction in + let forwardCount = index + 1 + return UIAction(title: self.urlForDisplay(url)) { (_) in + self.navigator.forward(count: forwardCount) + } + } + return UIMenu(title: "", image: nil, identifier: nil, options: [], children: children) + } + } else { + return nil + } + } +}