diff --git a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewController.swift b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewController.swift index f82a8f9b..6e6d9692 100644 --- a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewController.swift +++ b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewController.swift @@ -150,7 +150,7 @@ extension DiscoveryHashtagsViewController: TableViewControllerNavigateable { navigateToTag(direction: direction, indexPath: indexPathForSelectedRow) } else { // set first visible item selected - navigateToFirstVisibleStatus() + navigateToFirstVisibleTag() } } @@ -185,7 +185,7 @@ extension DiscoveryHashtagsViewController: TableViewControllerNavigateable { tableView.selectRow(at: indexPath, animated: true, scrollPosition: scrollPosition) } - private func navigateToFirstVisibleStatus() { + private func navigateToFirstVisibleTag() { guard let indexPathsForVisibleRows = tableView.indexPathsForVisibleRows else { return } guard let diffableDataSource = viewModel.diffableDataSource else { return } diff --git a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewController.swift b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewController.swift index 4042e2cd..f73602ae 100644 --- a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewController.swift +++ b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewController.swift @@ -131,3 +131,99 @@ extension DiscoveryNewsViewController: ScrollViewContainer { tableView } } + +extension DiscoveryNewsViewController { + override var keyCommands: [UIKeyCommand]? { + return navigationKeyCommands + } +} + +extension DiscoveryNewsViewController: TableViewControllerNavigateable { + + func navigate(direction: TableViewNavigationDirection) { + if let indexPathForSelectedRow = tableView.indexPathForSelectedRow { + // navigate up/down on the current selected item + navigateToLink(direction: direction, indexPath: indexPathForSelectedRow) + } else { + // set first visible item selected + navigateToFirstVisibleLink() + } + } + + private func navigateToLink(direction: TableViewNavigationDirection, indexPath: IndexPath) { + guard let diffableDataSource = viewModel.diffableDataSource else { return } + let items = diffableDataSource.snapshot().itemIdentifiers + guard let selectedItem = diffableDataSource.itemIdentifier(for: indexPath), + let selectedItemIndex = items.firstIndex(of: selectedItem) else { + return + } + + let _navigateToItem: DiscoveryItem? = { + var index = selectedItemIndex + while 0.. 1 { + // drop first when visible not the first cell of table + visibleItems.removeFirst() + } + guard let item = visibleItems.first, let indexPath = diffableDataSource.indexPath(for: item) else { return } + let scrollPosition: UITableView.ScrollPosition = overrideNavigationScrollPosition ?? Self.navigateScrollPosition(tableView: tableView, indexPath: indexPath) + tableView.selectRow(at: indexPath, animated: true, scrollPosition: scrollPosition) + } + + static func validNavigateableItem(_ item: DiscoveryItem) -> Bool { + switch item { + case .link: + return true + default: + return false + } + } + + func open() { + guard let indexPathForSelectedRow = tableView.indexPathForSelectedRow else { return } + guard let diffableDataSource = viewModel.diffableDataSource else { return } + guard let item = diffableDataSource.itemIdentifier(for: indexPathForSelectedRow) else { return } + + guard case let .link(link) = item else { return } + guard let url = URL(string: link.url) else { return } + coordinator.present( + scene: .safari(url: url), + from: self, + transition: .safariPresent(animated: true, completion: nil) + ) + } + + func navigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) { + navigateKeyCommandHandler(sender) + } + +}