mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-05 11:58:32 +00:00
Room mentioning in the composer (#3868)
* refactored the suggestion item structure to scale with the room pill * Implemented a way for the rooms to appear in the suggestions view for the RTE, however I need to add the pills to the composer and the compatibility with the plain text composer * small code correction * fix * fixed a bug where the suggestion wasn't returning the right suggestion type and the suggestion text properly * implementation done! also updated some tests, but we need more of them * updated toolbar view model tests * updated tests * updated preview tests * renamed the Avatars case for the suggestions
This commit is contained in:
+35
-17
@@ -378,22 +378,23 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
||||
shouldMakeAnotherPass = false
|
||||
attributedString.enumerateAttribute(.link, in: .init(location: 0, length: attributedString.length), options: []) { value, range, stop in
|
||||
guard let value else { return }
|
||||
|
||||
shouldMakeAnotherPass = true
|
||||
|
||||
// Remove the attribute so it doesn't get inherited by the new string
|
||||
attributedString.removeAttribute(.link, range: range)
|
||||
|
||||
guard let userID = attributedString.attribute(.MatrixUserID, at: range.location, effectiveRange: nil) as? String else {
|
||||
if let userID = attributedString.attribute(.MatrixUserID, at: range.location, effectiveRange: nil) as? String {
|
||||
let displayName = attributedString.attribute(.MatrixUserDisplayName, at: range.location, effectiveRange: nil)
|
||||
attributedString.replaceCharacters(in: range, with: "[\(displayName ?? userID)](\(value))")
|
||||
userIDs.insert(userID)
|
||||
stop.pointee = true
|
||||
} else if let roomAlias = attributedString.attribute(.MatrixRoomAlias, at: range.location, effectiveRange: nil) as? String {
|
||||
let displayName = attributedString.attribute(.MatrixRoomDisplayName, at: range.location, effectiveRange: nil)
|
||||
attributedString.replaceCharacters(in: range, with: "[\(displayName ?? roomAlias)](\(value))")
|
||||
stop.pointee = true
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
let displayName = attributedString.attribute(.MatrixUserDisplayName, at: range.location, effectiveRange: nil)
|
||||
|
||||
attributedString.replaceCharacters(in: range, with: "[\(displayName ?? userID)](\(value))")
|
||||
userIDs.insert(userID)
|
||||
|
||||
stop.pointee = true
|
||||
}
|
||||
} while shouldMakeAnotherPass
|
||||
|
||||
@@ -473,23 +474,24 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
||||
}
|
||||
|
||||
private func handleSuggestion(_ suggestion: SuggestionItem) {
|
||||
switch suggestion {
|
||||
case let .user(item):
|
||||
guard let url = try? URL(string: matrixToUserPermalink(userId: item.id)) else {
|
||||
switch suggestion.suggestionType {
|
||||
case let .user(user):
|
||||
guard let url = try? URL(string: matrixToUserPermalink(userId: user.id)) else {
|
||||
MXLog.error("Could not build user permalink")
|
||||
return
|
||||
}
|
||||
|
||||
if context.composerFormattingEnabled {
|
||||
wysiwygViewModel.setMention(url: url.absoluteString, name: item.id, mentionType: .user)
|
||||
wysiwygViewModel.setMention(url: url.absoluteString, name: user.id, mentionType: .user)
|
||||
} else {
|
||||
let attributedString = NSMutableAttributedString(attributedString: state.bindings.plainComposerText)
|
||||
mentionBuilder.handleUserMention(for: attributedString, in: suggestion.range, url: url, userID: item.id, userDisplayName: item.displayName)
|
||||
mentionBuilder.handleUserMention(for: attributedString, in: suggestion.range, url: url, userID: user.id, userDisplayName: user.displayName)
|
||||
state.bindings.plainComposerText = attributedString
|
||||
let newSelectedRange = NSRange(location: state.bindings.selectedRange.location - item.rawSuggestionText.count, length: 0)
|
||||
|
||||
let newSelectedRange = NSRange(location: state.bindings.selectedRange.location - suggestion.rawSuggestionText.count, length: 0)
|
||||
state.bindings.selectedRange = newSelectedRange
|
||||
}
|
||||
case let .allUsers(item):
|
||||
case .allUsers:
|
||||
if context.composerFormattingEnabled {
|
||||
wysiwygViewModel.setAtRoomMention()
|
||||
} else {
|
||||
@@ -497,7 +499,23 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
||||
mentionBuilder.handleAllUsersMention(for: attributedString, in: suggestion.range)
|
||||
state.bindings.plainComposerText = attributedString
|
||||
|
||||
let newSelectedRange = NSRange(location: state.bindings.selectedRange.location - item.rawSuggestionText.count, length: 0)
|
||||
let newSelectedRange = NSRange(location: state.bindings.selectedRange.location - suggestion.rawSuggestionText.count, length: 0)
|
||||
state.bindings.selectedRange = newSelectedRange
|
||||
}
|
||||
case let .room(room):
|
||||
guard let url = try? URL(string: matrixToRoomAliasPermalink(roomAlias: room.canonicalAlias)) else {
|
||||
MXLog.error("Could not build alias permalink")
|
||||
return
|
||||
}
|
||||
|
||||
if context.composerFormattingEnabled {
|
||||
wysiwygViewModel.setMention(url: url.absoluteString, name: room.name, mentionType: .room)
|
||||
} else {
|
||||
let attributedString = NSMutableAttributedString(attributedString: state.bindings.plainComposerText)
|
||||
mentionBuilder.handleRoomAliasMention(for: attributedString, in: suggestion.range, url: url, roomAlias: room.canonicalAlias, roomDisplayName: room.name)
|
||||
state.bindings.plainComposerText = attributedString
|
||||
|
||||
let newSelectedRange = NSRange(location: state.bindings.selectedRange.location - suggestion.rawSuggestionText.count, length: 0)
|
||||
state.bindings.selectedRange = newSelectedRange
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user