mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-05 11:58:32 +00:00
@room in user suggestions (#1880)
* for now I am using a local RTE solution, need to fix one test * fixed a test * new rte version * pr suggestions * @room added to the suggestions * removed empty space * revert * code improvement * project updated * package
This commit is contained in:
@@ -20,11 +20,23 @@ import WysiwygComposer
|
||||
|
||||
enum SuggestionItem: Identifiable, Equatable {
|
||||
case user(item: MentionSuggestionItem)
|
||||
case allUsers(item: MentionSuggestionItem)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
case .user(let user):
|
||||
return user.id
|
||||
case .allUsers:
|
||||
return PillConstants.atRoom
|
||||
}
|
||||
}
|
||||
|
||||
var name: String? {
|
||||
switch self {
|
||||
case .user(let user):
|
||||
return user.displayName
|
||||
case .allUsers:
|
||||
return PillConstants.everyone
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +45,10 @@ struct MentionSuggestionItem: Identifiable, Equatable {
|
||||
let id: String
|
||||
let displayName: String?
|
||||
let avatarURL: URL?
|
||||
|
||||
static func allUsersMention(roomAvatar: URL?) -> Self {
|
||||
MentionSuggestionItem(id: PillConstants.atRoom, displayName: PillConstants.everyone, avatarURL: roomAvatar)
|
||||
}
|
||||
}
|
||||
|
||||
extension WysiwygComposer.SuggestionPattern {
|
||||
|
||||
@@ -18,50 +18,70 @@ import Combine
|
||||
import Foundation
|
||||
|
||||
final class CompletionSuggestionService: CompletionSuggestionServiceProtocol {
|
||||
private var canMentionAllUsers = false
|
||||
let areSuggestionsEnabled: Bool
|
||||
let suggestionsPublisher: AnyPublisher<[SuggestionItem], Never>
|
||||
private(set) var suggestionsPublisher: AnyPublisher<[SuggestionItem], Never> = Empty().eraseToAnyPublisher()
|
||||
|
||||
private let suggestionTriggerSubject = CurrentValueSubject<SuggestionPattern?, Never>(nil)
|
||||
|
||||
init(roomProxy: RoomProxyProtocol, areSuggestionsEnabled: Bool) {
|
||||
self.areSuggestionsEnabled = areSuggestionsEnabled
|
||||
guard areSuggestionsEnabled else {
|
||||
suggestionsPublisher = Empty().eraseToAnyPublisher()
|
||||
return
|
||||
}
|
||||
suggestionsPublisher = suggestionTriggerSubject
|
||||
.combineLatest(roomProxy.members)
|
||||
.map { suggestionTrigger, members -> [SuggestionItem] in
|
||||
guard let suggestionTrigger else {
|
||||
.map { [weak self] suggestionPattern, members -> [SuggestionItem] in
|
||||
guard let suggestionPattern else {
|
||||
return []
|
||||
}
|
||||
|
||||
switch suggestionTrigger.type {
|
||||
switch suggestionPattern.type {
|
||||
case .user:
|
||||
return members.filter { member in
|
||||
guard !member.isAccountOwner && member.membership == .join else {
|
||||
return false
|
||||
var membersSuggestion = members
|
||||
.compactMap { member -> SuggestionItem? in
|
||||
guard !member.isAccountOwner,
|
||||
member.membership == .join,
|
||||
Self.isIncluded(searchText: suggestionPattern.text, userID: member.userID, displayName: member.displayName) else {
|
||||
return nil
|
||||
}
|
||||
return SuggestionItem.user(item: .init(id: member.userID, displayName: member.displayName, avatarURL: member.avatarURL))
|
||||
}
|
||||
|
||||
let containedInUserID = member.userID.localizedStandardContains(suggestionTrigger.text.lowercased())
|
||||
|
||||
let containedInDisplayName: Bool
|
||||
if let displayName = member.displayName {
|
||||
containedInDisplayName = displayName.localizedStandardContains(suggestionTrigger.text.lowercased())
|
||||
} else {
|
||||
containedInDisplayName = false
|
||||
}
|
||||
|
||||
return containedInUserID || containedInDisplayName
|
||||
if self?.canMentionAllUsers == true,
|
||||
Self.isIncluded(searchText: suggestionPattern.text, userID: PillConstants.atRoom, displayName: PillConstants.everyone) {
|
||||
membersSuggestion
|
||||
.append(SuggestionItem.allUsers(item: .allUsersMention(roomAvatar: roomProxy.avatarURL)))
|
||||
}
|
||||
.map { SuggestionItem.user(item: .init(id: $0.userID, displayName: $0.displayName, avatarURL: $0.avatarURL)) }
|
||||
return membersSuggestion
|
||||
}
|
||||
}
|
||||
.debounce(for: 0.5, scheduler: DispatchQueue.main)
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
Task {
|
||||
switch await roomProxy.canUserTriggerRoomNotification(userID: roomProxy.ownUserID) {
|
||||
case .success(let value):
|
||||
canMentionAllUsers = value
|
||||
case .failure:
|
||||
canMentionAllUsers = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setSuggestionTrigger(_ suggestionTrigger: SuggestionPattern?) {
|
||||
suggestionTriggerSubject.value = suggestionTrigger
|
||||
}
|
||||
|
||||
private static func isIncluded(searchText: String, userID: String, displayName: String?) -> Bool {
|
||||
let containedInUserID = userID.localizedStandardContains(searchText.lowercased())
|
||||
|
||||
let containedInDisplayName: Bool
|
||||
if let displayName {
|
||||
containedInDisplayName = displayName.localizedStandardContains(searchText.lowercased())
|
||||
} else {
|
||||
containedInDisplayName = false
|
||||
}
|
||||
|
||||
return containedInUserID || containedInDisplayName
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,8 +166,8 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
||||
|
||||
wysiwygViewModel.mentionReplacer = ComposerMentionReplacer { urlString, string in
|
||||
let attributedString: NSMutableAttributedString
|
||||
// This is the all room mention case
|
||||
if urlString == "#" {
|
||||
// This is the all room mention special case
|
||||
if urlString == PillConstants.composerAtRoomURLString {
|
||||
attributedString = NSMutableAttributedString(string: string, attributes: [.MatrixAllUsersMention: true])
|
||||
} else {
|
||||
attributedString = NSMutableAttributedString(string: string, attributes: [.link: URL(string: urlString) as Any])
|
||||
@@ -188,6 +188,8 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
||||
return
|
||||
}
|
||||
wysiwygViewModel.setMention(url: url.absoluteString, name: item.displayName ?? item.id, mentionType: .user)
|
||||
case .allUsers:
|
||||
wysiwygViewModel.setAtRoomMention()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ struct CompletionSuggestionView: View {
|
||||
onTap(item)
|
||||
} label: {
|
||||
switch item {
|
||||
case .user(let mention):
|
||||
case .user(let mention), .allUsers(let mention):
|
||||
MentionSuggestionItemView(imageProvider: imageProvider, item: mention)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user