Fix message completion trigger to work anywhere in the message (#3696)

* Fix message completion trigger to work anywhere in the message

* Add tests for display suggestion in difference message positions

* Fix suggestion trigger could support multiple mention symbol

* Remove optional parameter type and tweak argument name to hide

* Optimize the suggestions trigger using regex

* Fix the cursor at wrong position after selected suggestion

* Modify the rawSuggestionText pass data in right way

* Modify mention symbol to use regex type

* Update ElementX/Sources/Screens/RoomScreen/ComposerToolbar/CompletionSuggestionService.swift

Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>

* Update generated mock

---------

Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
This commit is contained in:
Vickcoo
2025-02-13 23:13:09 +08:00
committed by GitHub
parent 8ee1427809
commit 4b43d901f8
14 changed files with 151 additions and 59 deletions
@@ -197,7 +197,9 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
case .voiceMessage(let voiceMessageAction):
processVoiceMessageAction(voiceMessageAction)
case .plainComposerTextChanged:
completionSuggestionService.processTextMessage(state.bindings.plainComposerText.string)
completionSuggestionService.processTextMessage(state.bindings.plainComposerText.string, selectedRange: context.viewState.bindings.selectedRange)
case .selectedTextChanged:
completionSuggestionService.processTextMessage(state.bindings.plainComposerText.string, selectedRange: context.viewState.bindings.selectedRange)
case .didToggleFormattingOptions:
if context.composerFormattingEnabled {
guard !context.plainComposerText.string.isEmpty else {
@@ -483,14 +485,19 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
let attributedString = NSMutableAttributedString(attributedString: state.bindings.plainComposerText)
mentionBuilder.handleUserMention(for: attributedString, in: suggestion.range, url: url, userID: item.id, userDisplayName: item.displayName)
state.bindings.plainComposerText = attributedString
let newSelectedRange = NSRange(location: state.bindings.selectedRange.location - item.rawSuggestionText.count, length: 0)
state.bindings.selectedRange = newSelectedRange
}
case .allUsers:
case let .allUsers(item):
if context.composerFormattingEnabled {
wysiwygViewModel.setAtRoomMention()
} else {
let attributedString = NSMutableAttributedString(attributedString: state.bindings.plainComposerText)
mentionBuilder.handleAllUsersMention(for: attributedString, in: suggestion.range)
state.bindings.plainComposerText = attributedString
let newSelectedRange = NSRange(location: state.bindings.selectedRange.location - item.rawSuggestionText.count, length: 0)
state.bindings.selectedRange = newSelectedRange
}
}
}