mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
Show user statuses in mention suggestions.
This commit is contained in:
+2
-1
@@ -87,7 +87,8 @@ final class CompletionSuggestionService: CompletionSuggestionServiceProtocol {
|
||||
Self.shouldIncludeMember(userID: member.userID, displayName: member.displayName, searchText: suggestionTrigger.text) else {
|
||||
return nil
|
||||
}
|
||||
return .init(suggestionType: .user(.init(id: member.userID, displayName: member.displayName, avatarURL: member.avatarURL)), range: suggestionTrigger.range, rawSuggestionText: suggestionTrigger.text)
|
||||
return .init(suggestionType: .user(.init(id: member.userID, displayName: member.displayName, avatarURL: member.avatarURL, status: member.status)),
|
||||
range: suggestionTrigger.range, rawSuggestionText: suggestionTrigger.text)
|
||||
}
|
||||
|
||||
if canMentionAllUsers,
|
||||
|
||||
+16
-6
@@ -32,6 +32,7 @@ struct SuggestionItem: Identifiable, Equatable {
|
||||
let id: String
|
||||
let displayName: String?
|
||||
let avatarURL: URL?
|
||||
var status = UserStatus()
|
||||
}
|
||||
|
||||
struct Room: Equatable {
|
||||
@@ -59,22 +60,31 @@ struct SuggestionItem: Identifiable, Equatable {
|
||||
var displayName: String {
|
||||
switch suggestionType {
|
||||
case .allUsers:
|
||||
return PillUtilities.everyone
|
||||
PillUtilities.everyone
|
||||
case .user(let user):
|
||||
return user.displayName ?? user.id
|
||||
user.displayName ?? user.id
|
||||
case .room(let room):
|
||||
return room.name
|
||||
room.name
|
||||
}
|
||||
}
|
||||
|
||||
var statusEmoji: Character? {
|
||||
switch suggestionType {
|
||||
case .user(let user):
|
||||
user.status.displayed?.emoji
|
||||
case .allUsers, .room:
|
||||
nil
|
||||
}
|
||||
}
|
||||
|
||||
var subtitle: String? {
|
||||
switch suggestionType {
|
||||
case .allUsers:
|
||||
return PillUtilities.atRoom
|
||||
PillUtilities.atRoom
|
||||
case .user(let user):
|
||||
return user.displayName == nil ? nil : user.id
|
||||
user.displayName == nil ? nil : user.id
|
||||
case .room(let room):
|
||||
return room.canonicalAlias
|
||||
room.canonicalAlias
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-2
@@ -110,8 +110,19 @@ struct CompletionSuggestion_Previews: PreviewProvider, TestablePreview {
|
||||
// Putting them is VStack allows the preview to work properly in tests
|
||||
VStack(spacing: 8) {
|
||||
CompletionSuggestionView(mediaProvider: MediaProviderMock(.init()),
|
||||
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 }
|
||||
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,
|
||||
status: .mockCall)),
|
||||
range: .init(),
|
||||
rawSuggestionText: "")
|
||||
]) { _ in }
|
||||
}
|
||||
|
||||
VStack(spacing: 8) {
|
||||
|
||||
+60
-9
@@ -6,6 +6,7 @@
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct MentionSuggestionItemView: View {
|
||||
@@ -13,19 +14,29 @@ struct MentionSuggestionItemView: View {
|
||||
let item: SuggestionItem
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: .center, spacing: 16) {
|
||||
HStack(alignment: .center, spacing: 12) {
|
||||
avatar
|
||||
.accessibilityHidden(true)
|
||||
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text(item.displayName)
|
||||
.font(.compound.bodyLG)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
.lineLimit(1)
|
||||
HStack(spacing: 2) {
|
||||
Text(item.displayName)
|
||||
.lineLimit(1)
|
||||
.padding(.vertical, 1) // Compensation for Figma line height.
|
||||
|
||||
if let statusEmoji = item.statusEmoji {
|
||||
Text(String(statusEmoji))
|
||||
}
|
||||
}
|
||||
.font(.compound.bodyLG)
|
||||
.foregroundStyle(.compound.textPrimary)
|
||||
|
||||
if let subtitle = item.subtitle {
|
||||
Text(subtitle)
|
||||
.font(.compound.bodySM)
|
||||
.foregroundColor(.compound.textSecondary)
|
||||
.foregroundStyle(.compound.textSecondary)
|
||||
.lineLimit(1)
|
||||
.padding(.vertical, 1) // Compensation for Figma line height.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,12 +60,52 @@ struct MentionSuggestionItemView_Previews: PreviewProvider, TestablePreview {
|
||||
static let mockMediaProvider = MediaProviderMock(.init())
|
||||
|
||||
static var previews: some View {
|
||||
MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(suggestionType: .user(.init(id: "test", displayName: "Test", avatarURL: .mockMXCUserAvatar)), 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: ""))
|
||||
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
MentionSuggestionItemView(mediaProvider: mockMediaProvider,
|
||||
item: .init(suggestionType: .user(.init(id: "@john.smith:example.com",
|
||||
displayName: "John Smith",
|
||||
avatarURL: nil,
|
||||
status: .mockHoliday)),
|
||||
range: .init(),
|
||||
rawSuggestionText: ""))
|
||||
|
||||
MentionSuggestionItemView(mediaProvider: mockMediaProvider,
|
||||
item: .init(suggestionType: .user(.init(id: "@alice.liddel:example.com",
|
||||
displayName: "Alice Liddell",
|
||||
avatarURL: nil,
|
||||
status: .mockCall)),
|
||||
range: .init(),
|
||||
rawSuggestionText: ""))
|
||||
|
||||
MentionSuggestionItemView(mediaProvider: mockMediaProvider,
|
||||
item: .init(suggestionType: .user(.init(id: "@long.name:example.com",
|
||||
displayName: "I have a long name that doesn't fit on one line",
|
||||
avatarURL: nil,
|
||||
status: .mock(text: "Travelling", emoji: "🚆"))),
|
||||
range: .init(),
|
||||
rawSuggestionText: ""))
|
||||
}
|
||||
.padding(16)
|
||||
.previewDisplayName("User with status")
|
||||
|
||||
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: ""))
|
||||
|
||||
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",
|
||||
|
||||
Reference in New Issue
Block a user