Show user statuses in mention pills.

This commit is contained in:
Doug
2026-07-10 13:13:50 +01:00
committed by Doug
parent 01b946926f
commit 6199ab596f
7 changed files with 73 additions and 31 deletions
@@ -228,6 +228,7 @@ enum TimelineAlertInfoType: Hashable {
struct RoomMemberState {
let displayName: String?
let avatarURL: URL?
let status: UserStatus
}
/// Used as the state for the TimelineView, to avoid having the context continuously refresh the list of items on each small change.
@@ -425,7 +425,9 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
private func updateMembers(_ members: [RoomMemberProxyProtocol]) {
state.members = members.reduce(into: [String: RoomMemberState]()) { dictionary, member in
dictionary[member.userID] = RoomMemberState(displayName: member.displayName, avatarURL: member.avatarURL)
dictionary[member.userID] = RoomMemberState(displayName: member.displayName,
avatarURL: member.avatarURL,
status: member.status)
if member.userID == roomProxy.ownUserID {
currentUserProxy = member
}
@@ -1010,21 +1012,25 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
case let .user(id):
let isOwnMention = id == state.ownUserID
if let profile = state.members[id] {
pillContext.viewState = .mention(isOwnMention: isOwnMention, displayText: PillUtilities.userPillDisplayText(username: profile.displayName, userID: id))
pillContext.viewState = .mention(isOwnMention: isOwnMention,
displayText: PillUtilities.userPillDisplayText(username: profile.displayName, userID: id),
statusEmoji: profile.status.displayed?.emoji)
} else {
pillContext.viewState = .mention(isOwnMention: isOwnMention, displayText: id)
pillContext.viewState = .mention(isOwnMention: isOwnMention, displayText: id, statusEmoji: nil)
pillContext.cancellable = context.$viewState
.compactMap { $0.members[id] }
.sink { [weak pillContext] profile in
guard let pillContext else {
return
}
pillContext.viewState = .mention(isOwnMention: isOwnMention, displayText: PillUtilities.userPillDisplayText(username: profile.displayName, userID: id))
pillContext.viewState = .mention(isOwnMention: isOwnMention,
displayText: PillUtilities.userPillDisplayText(username: profile.displayName, userID: id),
statusEmoji: profile.status.displayed?.emoji)
pillContext.cancellable = nil
}
}
case .allUsers:
pillContext.viewState = .mention(isOwnMention: true, displayText: PillUtilities.atRoom)
pillContext.viewState = .mention(isOwnMention: true, displayText: PillUtilities.atRoom, statusEmoji: nil)
case .event(let room):
let pillViewState: PillViewState
switch room {
@@ -63,13 +63,15 @@ struct ReadReceiptCell_Previews: PreviewProvider, TestablePreview {
ReadReceiptCell(readReceipt: .init(userID: "@test:matrix.org",
formattedTimestamp: "10:00"),
memberState: .init(displayName: "Test",
avatarURL: nil),
avatarURL: nil,
status: .init()),
mediaProvider: MediaProviderMock(.init()))
.previewDisplayName("No Image")
ReadReceiptCell(readReceipt: .init(userID: "@test:matrix.org",
formattedTimestamp: "10:00"),
memberState: .init(displayName: "Test",
avatarURL: .mockMXCUserAvatar),
avatarURL: .mockMXCUserAvatar,
status: .init()),
mediaProvider: MediaProviderMock(.init()))
.previewDisplayName("With Image")
ReadReceiptCell(readReceipt: .init(userID: "@test:matrix.org",