mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +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:
+6
-8
@@ -32,7 +32,7 @@ struct CompletionSuggestionView: View {
|
||||
EmptyView()
|
||||
} else {
|
||||
ZStack {
|
||||
MentionSuggestionItemView(mediaProvider: nil, item: .init(id: "", displayName: nil, avatarURL: nil, range: .init(), rawSuggestionText: ""))
|
||||
MentionSuggestionItemView(mediaProvider: nil, item: .init(suggestionType: .user(.init(id: "", displayName: nil, avatarURL: nil)), range: .init(), rawSuggestionText: ""))
|
||||
.readFrame($prototypeListItemFrame)
|
||||
.hidden()
|
||||
if showBackgroundShadow {
|
||||
@@ -52,10 +52,7 @@ struct CompletionSuggestionView: View {
|
||||
Button {
|
||||
onTap(item)
|
||||
} label: {
|
||||
switch item {
|
||||
case .user(let mention), .allUsers(let mention):
|
||||
MentionSuggestionItemView(mediaProvider: mediaProvider, item: mention)
|
||||
}
|
||||
MentionSuggestionItemView(mediaProvider: mediaProvider, item: item)
|
||||
}
|
||||
.modifier(ListItemPaddingModifier(isFirst: items.first?.id == item.id))
|
||||
.listRowInsets(.init(top: 0, leading: Constants.leadingPadding, bottom: 0, trailing: 0))
|
||||
@@ -110,16 +107,17 @@ private struct BackgroundView<Content: View>: View {
|
||||
|
||||
struct CompletionSuggestion_Previews: PreviewProvider, TestablePreview {
|
||||
static let multipleItems: [SuggestionItem] = (0...10).map { index in
|
||||
SuggestionItem.user(item: MentionSuggestionItem(id: "\(index)", displayName: "\(index)", avatarURL: nil, range: .init(), rawSuggestionText: ""))
|
||||
.init(suggestionType: .user(.init(id: "\(index)", displayName: "\(index)", avatarURL: nil)), range: .init(), rawSuggestionText: "")
|
||||
}
|
||||
|
||||
static var previews: some View {
|
||||
// Putting them is VStack allows the preview to work properly in tests
|
||||
VStack(spacing: 8) {
|
||||
CompletionSuggestionView(mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
items: [.user(item: MentionSuggestionItem(id: "@user_mention_1:matrix.org", displayName: "User 1", avatarURL: nil, range: .init(), rawSuggestionText: "")),
|
||||
.user(item: MentionSuggestionItem(id: "@user_mention_2:matrix.org", displayName: "User 2", avatarURL: .mockMXCUserAvatar, range: .init(), rawSuggestionText: ""))]) { _ in }
|
||||
items: [.init(suggestionType: .user(.init(id: "@user_mention_1:matrix.org", displayName: "User 1", avatarURL: nil)), range: .init(), rawSuggestionText: ""),
|
||||
.init(suggestionType: .user(.init(id: "@user_mention_2:matrix.org", displayName: "User 2", avatarURL: .mockMXCUserAvatar)), range: .init(), rawSuggestionText: "")]) { _ in }
|
||||
}
|
||||
|
||||
VStack(spacing: 8) {
|
||||
CompletionSuggestionView(mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
items: multipleItems) { _ in }
|
||||
|
||||
@@ -321,8 +321,11 @@ struct ComposerToolbar_Previews: PreviewProvider, TestablePreview {
|
||||
mentionDisplayHelper: ComposerMentionDisplayHelper.mock,
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
composerDraftService: ComposerDraftServiceMock())
|
||||
static let suggestions: [SuggestionItem] = [.user(item: MentionSuggestionItem(id: "@user_mention_1:matrix.org", displayName: "User 1", avatarURL: nil, range: .init(), rawSuggestionText: "")),
|
||||
.user(item: MentionSuggestionItem(id: "@user_mention_2:matrix.org", displayName: "User 2", avatarURL: .mockMXCUserAvatar, range: .init(), rawSuggestionText: ""))]
|
||||
|
||||
static let suggestions: [SuggestionItem] = [
|
||||
.init(suggestionType: .user(.init(id: "@user_mention_1:matrix.org", displayName: "User 1", avatarURL: nil)), range: .init(), rawSuggestionText: ""),
|
||||
.init(suggestionType: .user(.init(id: "@user_mention_2:matrix.org", displayName: "User 2", avatarURL: .mockMXCUserAvatar)), range: .init(), rawSuggestionText: "")
|
||||
]
|
||||
|
||||
static var previews: some View {
|
||||
ComposerToolbar.mock(focused: true)
|
||||
|
||||
+27
-11
@@ -9,22 +9,25 @@ import SwiftUI
|
||||
|
||||
struct MentionSuggestionItemView: View {
|
||||
let mediaProvider: MediaProviderProtocol?
|
||||
let item: MentionSuggestionItem
|
||||
let item: SuggestionItem
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: .center, spacing: 16) {
|
||||
LoadableAvatarImage(url: item.avatarURL,
|
||||
name: item.displayName,
|
||||
contentID: item.id,
|
||||
avatarSize: .user(on: .suggestions),
|
||||
mediaProvider: mediaProvider)
|
||||
switch item.suggestionType {
|
||||
case .user(let user):
|
||||
LoadableAvatarImage(url: user.avatarURL, name: user.displayName, contentID: user.id, avatarSize: .user(on: .completionSuggestions), mediaProvider: mediaProvider)
|
||||
case .allUsers(let avatar):
|
||||
RoomAvatarImage(avatar: avatar, avatarSize: .room(on: .completionSuggestions), mediaProvider: mediaProvider)
|
||||
case .room(let room):
|
||||
RoomAvatarImage(avatar: room.avatar, avatarSize: .room(on: .completionSuggestions), mediaProvider: mediaProvider)
|
||||
}
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text(item.displayName ?? item.id)
|
||||
Text(item.displayName)
|
||||
.font(.compound.bodyLG)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
.lineLimit(1)
|
||||
if item.displayName != nil {
|
||||
Text(item.id)
|
||||
if let subtitle = item.subtitle {
|
||||
Text(subtitle)
|
||||
.font(.compound.bodySM)
|
||||
.foregroundColor(.compound.textSecondary)
|
||||
.lineLimit(1)
|
||||
@@ -38,7 +41,20 @@ struct MentionSuggestionItemView_Previews: PreviewProvider, TestablePreview {
|
||||
static let mockMediaProvider = MediaProviderMock(configuration: .init())
|
||||
|
||||
static var previews: some View {
|
||||
MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(id: "test", displayName: "Test", avatarURL: .mockMXCUserAvatar, range: .init(), rawSuggestionText: ""))
|
||||
MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(id: "test2", displayName: nil, avatarURL: nil, range: .init(), rawSuggestionText: ""))
|
||||
MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(suggestionType: .user(.init(id: "test", displayName: "Test", avatarURL: .mockMXCUserAvatar)), range: .init(), rawSuggestionText: ""))
|
||||
.previewDisplayName("User")
|
||||
MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(suggestionType: .user(.init(id: "test2", displayName: nil, avatarURL: nil)), range: .init(), rawSuggestionText: ""))
|
||||
.previewDisplayName("User no display name")
|
||||
MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(suggestionType: .allUsers(.room(id: "room", name: "Room", avatarURL: .mockMXCAvatar)), range: .init(), rawSuggestionText: ""))
|
||||
.previewDisplayName("All users")
|
||||
MentionSuggestionItemView(mediaProvider: mockMediaProvider,
|
||||
item: .init(suggestionType: .room(.init(id: "room",
|
||||
canonicalAlias: "#room:matrix.org",
|
||||
name: "Room",
|
||||
avatar: .room(id: "room",
|
||||
name: "Room", avatarURL: .mockMXCAvatar))),
|
||||
range: .init(),
|
||||
rawSuggestionText: ""))
|
||||
.previewDisplayName("Room")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user