diff --git a/iOS/KeyboardManager.swift b/iOS/KeyboardManager.swift index d9729dfb3..4163c5a74 100644 --- a/iOS/KeyboardManager.swift +++ b/iOS/KeyboardManager.swift @@ -34,8 +34,13 @@ private extension KeyboardManager { let entries = NSArray(contentsOfFile: file)! as! [[String: Any]] keyCommands = entries.compactMap { createKeyCommand(keyEntry: $0) } - if type == .sidebar { + switch type { + case .global: + keyCommands?.append(contentsOf: globalAuxilaryKeyCommands()) + case .sidebar: keyCommands?.append(contentsOf: sidebarAuxilaryKeyCommands()) + default: + break } } @@ -108,6 +113,33 @@ private extension KeyboardManager { return flags } + func globalAuxilaryKeyCommands() -> [UIKeyCommand] { + var keys = [UIKeyCommand]() + + let addNewFeedTitle = NSLocalizedString("New Feed", comment: "New Feed") + keys.append(createKeyCommand(title: addNewFeedTitle, action: "addNewFeed:", input: "n", modifiers: [.command])) + + let addNewFolderTitle = NSLocalizedString("New Folder", comment: "New Folder") + keys.append(createKeyCommand(title: addNewFolderTitle, action: "addNewFolder:", input: "n", modifiers: [.command, .shift])) + + let refreshTitle = NSLocalizedString("Refresh", comment: "Refresh") + keys.append(createKeyCommand(title: refreshTitle, action: "refresh:", input: "r", modifiers: [.command])) + + let nextUnreadTitle = NSLocalizedString("Next Unread", comment: "Next Unread") + keys.append(createKeyCommand(title: nextUnreadTitle, action: "nextUnread:", input: "/", modifiers: [.command])) + + let goToTodayTitle = NSLocalizedString("Go To Today", comment: "Go To Today") + keys.append(createKeyCommand(title: goToTodayTitle, action: "goToToday:", input: "1", modifiers: [.command])) + + let goToAllUnreadTitle = NSLocalizedString("Go To All Unread", comment: "Go To All Unread") + keys.append(createKeyCommand(title: goToAllUnreadTitle, action: "goToAllUnread:", input: "2", modifiers: [.command])) + + let goToStarredTitle = NSLocalizedString("Go To Starred", comment: "Go To Starred") + keys.append(createKeyCommand(title: goToStarredTitle, action: "goToStarred:", input: "3", modifiers: [.command])) + + return keys + } + func sidebarAuxilaryKeyCommands() -> [UIKeyCommand] { var keys = [UIKeyCommand]() diff --git a/iOS/MasterFeed/MasterFeedViewController.swift b/iOS/MasterFeed/MasterFeedViewController.swift index 301401607..81c34af79 100644 --- a/iOS/MasterFeed/MasterFeedViewController.swift +++ b/iOS/MasterFeed/MasterFeedViewController.swift @@ -421,6 +421,21 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner { } } + func ensureSectionIsExpanded(_ sectionIndex: Int, completion: (() -> Void)? = nil) { + guard let sectionNode = coordinator.rootNode.childAtIndex(sectionIndex) else { + return + } + + if !coordinator.isExpanded(sectionNode) { + coordinator.expand(section: sectionIndex) + self.applyChanges(animate: true) { + completion?() + } + } else { + completion?() + } + } + func discloseFeed(_ feed: Feed, completion: (() -> Void)? = nil) { guard let node = coordinator.rootNode.descendantNodeRepresentingObject(feed as AnyObject) else { @@ -481,12 +496,10 @@ private extension MasterFeedViewController { } func reloadNode(_ node: Node) { - let savedNode = selectedNode() - var snapshot = dataSource.snapshot() snapshot.reloadItems([node]) dataSource.apply(snapshot, animatingDifferences: false) { [weak self] in - self?.selectRow(node: savedNode) + self?.restoreSelectionIfNecessary() } } @@ -504,21 +517,6 @@ private extension MasterFeedViewController { completion?() } } - - func selectedNode() -> Node? { - if let selectedIndexPath = tableView.indexPathForSelectedRow { - return coordinator.nodeFor(selectedIndexPath) - } else { - return nil - } - } - - func selectRow(node: Node?) { - if let nodeToSelect = node, let selectingIndexPath = coordinator.indexPathFor(nodeToSelect) { - tableView.selectRow(at: selectingIndexPath, animated: false, scrollPosition: .none) - } - - } func makeDataSource() -> UITableViewDiffableDataSource { return MasterFeedDataSource(coordinator: coordinator, errorHandler: ErrorHandler.present(self), tableView: tableView, cellProvider: { [weak self] tableView, indexPath, node in diff --git a/iOS/RootSplitViewController.swift b/iOS/RootSplitViewController.swift index 6e4750c29..5653c267c 100644 --- a/iOS/RootSplitViewController.swift +++ b/iOS/RootSplitViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import Account class RootSplitViewController: UISplitViewController { @@ -54,4 +55,26 @@ class RootSplitViewController: UISplitViewController { coordinator.showBrowserForCurrentArticle() } + @objc func addNewFeed(_ sender: Any?) { + } + + @objc func addNewFolder(_ sender: Any?) { + } + + @objc func refresh(_ sender: Any?) { + AccountManager.shared.refreshAll(errorHandler: ErrorHandler.present(self)) + } + + @objc func goToToday(_ sender: Any?) { + coordinator.selectTodayFeed() + } + + @objc func goToAllUnread(_ sender: Any?) { + coordinator.selectAllUnreadFeed() + } + + @objc func goToStarred(_ sender: Any?) { + coordinator.selectStarredFeed() + } + } diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift index ac7133745..40cca25c8 100644 --- a/iOS/SceneCoordinator.swift +++ b/iOS/SceneCoordinator.swift @@ -571,6 +571,24 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider { selectFeed(indexPath) } } + + func selectTodayFeed() { + masterFeedViewController?.ensureSectionIsExpanded(0) { + self.selectFeed(IndexPath(row: 0, section: 0)) + } + } + + func selectAllUnreadFeed() { + masterFeedViewController?.ensureSectionIsExpanded(0) { + self.selectFeed(IndexPath(row: 1, section: 0)) + } + } + + func selectStarredFeed() { + masterFeedViewController?.ensureSectionIsExpanded(0) { + self.selectFeed(IndexPath(row: 2, section: 0)) + } + } func selectArticle(_ indexPath: IndexPath?, automated: Bool = true) { currentArticleIndexPath = indexPath