From 401e1fe07938267eb051c95d241f4c5df3086897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Sun, 2 Mar 2025 21:27:55 +0100 Subject: [PATCH] feat(autocompletion): Add keyboard support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcel Müller --- NextcloudTalk/InputbarViewController.swift | 54 ++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/NextcloudTalk/InputbarViewController.swift b/NextcloudTalk/InputbarViewController.swift index 088087d2a..3317a2b54 100644 --- a/NextcloudTalk/InputbarViewController.swift +++ b/NextcloudTalk/InputbarViewController.swift @@ -19,6 +19,7 @@ import UIKit internal var autocompletionUsers: [MentionSuggestion] = [] internal var mentionsDict: [String: NCMessageParameter] = [:] internal var contentView: UIView? + internal var selectedAutocompletionRow: IndexPath? public init?(forRoom room: NCRoom, withAccount account: TalkAccount, tableViewStyle style: UITableView.Style) { self.room = room @@ -230,6 +231,8 @@ import UIKit // Check if "@" is still there self.textView.look(forPrefixes: self.registeredPrefixes) { prefix, word, _ in + self.selectedAutocompletionRow = nil + if prefix?.count ?? 0 > 0 && word?.count ?? 0 > 0 { self.showAutoCompletionView(showAutocomplete) } else { @@ -254,6 +257,39 @@ import UIKit return resultMessage } + override public func pressesBegan(_ presses: Set, with event: UIPressesEvent?) { + guard self.isAutoCompleting, + !self.autocompletionUsers.isEmpty, + let firstVisibleRow = self.autoCompletionView.indexPathsForVisibleRows?.first + else { + super.pressesBegan(presses, with: event) + return + } + + var oldIndexPath: IndexPath? + var newIndexPath: IndexPath? + + // Support selecting the auto complete with return/enter key + if presses.contains(where: { $0.key?.keyCode == .keyboardReturnOrEnter }) { + let indexPath = self.selectedAutocompletionRow ?? firstVisibleRow + self.acceptAutoCompletion(withIndexPath: indexPath) + + return + } else if presses.contains(where: { $0.key?.keyCode == .keyboardUpArrow }) { + oldIndexPath = self.selectedAutocompletionRow ?? firstVisibleRow + newIndexPath = IndexPath(row: oldIndexPath!.row - 1, section: 0) + } else if presses.contains(where: { $0.key?.keyCode == .keyboardDownArrow }) { + oldIndexPath = self.selectedAutocompletionRow ?? firstVisibleRow + newIndexPath = IndexPath(row: oldIndexPath!.row + 1, section: 0) + } + + if let oldIndexPath, let newIndexPath, self.autoCompletionView.isValid(indexPath: newIndexPath) { + self.selectedAutocompletionRow = newIndexPath + self.autoCompletionView.reloadRows(at: [oldIndexPath, newIndexPath], with: .none) + self.autoCompletionView.scrollToRow(at: newIndexPath, at: .none, animated: true) + } + } + // MARK: - UITableViewDataSource methods public override func numberOfSections(in tableView: UITableView) -> Int { @@ -316,14 +352,25 @@ import UIKit cell.avatarButton.setActorAvatar(forId: suggestion.mention.id, withType: suggestion.source, withDisplayName: suggestion.mention.label, withRoomToken: self.room.token, using: self.account) } + if let selectedAutocompletionRow, selectedAutocompletionRow == indexPath { + cell.layer.borderColor = UIColor.systemGray.cgColor + cell.layer.borderWidth = 2.0 + } else { + cell.layer.borderWidth = 0.0 + } + cell.accessibilityIdentifier = AutoCompletionCellIdentifier return cell } public override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - guard tableView == self.autoCompletionView, - indexPath.row < self.autocompletionUsers.count - else { return } + guard tableView == self.autoCompletionView else { return } + + self.acceptAutoCompletion(withIndexPath: indexPath) + } + + private func acceptAutoCompletion(withIndexPath indexPath: IndexPath) { + guard indexPath.row < self.autocompletionUsers.count else { return } let suggestion = self.autocompletionUsers[indexPath.row] @@ -332,6 +379,7 @@ import UIKit let mentionWithWhitespace = suggestion.mention.label + " " self.acceptAutoCompletion(with: mentionWithWhitespace, keepPrefix: true) + self.selectedAutocompletionRow = nil } public override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {