mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Add the inviter to JoinRoomScreen when it's an invite. (#3093)
* Add inviter property to RoomProxyProtocol. * Extract the room cell inviter label into it's own view. * Use the new RoomInviterLabel in the JoinRoomScreen. * Fix bug with invite to a public room.
This commit is contained in:
@@ -144,12 +144,6 @@ struct HomeScreenRoom: Identifiable, Equatable {
|
||||
case invite
|
||||
}
|
||||
|
||||
struct InviterDetails: Equatable {
|
||||
let userID: String
|
||||
let displayName: String?
|
||||
let avatarURL: URL?
|
||||
}
|
||||
|
||||
static let placeholderLastMessage = AttributedString("Hidden last message")
|
||||
|
||||
/// The list item identifier is it's room identifier.
|
||||
@@ -182,7 +176,7 @@ struct HomeScreenRoom: Identifiable, Equatable {
|
||||
|
||||
let avatar: RoomAvatar
|
||||
|
||||
let inviter: InviterDetails?
|
||||
let inviter: RoomInviterDetails?
|
||||
|
||||
let canonicalAlias: String?
|
||||
|
||||
@@ -215,12 +209,7 @@ extension HomeScreenRoom {
|
||||
let isCallShown = summary.hasOngoingCall
|
||||
let isHighlighted = summary.isMarkedUnread || (!summary.isMuted && (summary.hasUnreadNotifications || summary.hasUnreadMentions))
|
||||
|
||||
var inviter: InviterDetails?
|
||||
if let roomMemberProxy = summary.inviter {
|
||||
inviter = .init(userID: roomMemberProxy.userID,
|
||||
displayName: roomMemberProxy.displayName,
|
||||
avatarURL: roomMemberProxy.avatarURL)
|
||||
}
|
||||
let inviter = summary.inviter.map(RoomInviterDetails.init)
|
||||
|
||||
self.init(id: identifier,
|
||||
roomID: summary.id,
|
||||
|
||||
@@ -74,17 +74,10 @@ struct HomeScreenInviteCell: View {
|
||||
|
||||
@ViewBuilder
|
||||
private var inviterView: some View {
|
||||
if let invitedText = attributedInviteText, let name = room.inviter?.displayName {
|
||||
HStack(alignment: .firstTextBaseline, spacing: 8) {
|
||||
LoadableAvatarImage(url: room.inviter?.avatarURL,
|
||||
name: name,
|
||||
contentID: name,
|
||||
avatarSize: .custom(16),
|
||||
imageProvider: context.imageProvider)
|
||||
.alignmentGuide(.firstTextBaseline) { $0[.bottom] * 0.8 }
|
||||
|
||||
Text(invitedText)
|
||||
}
|
||||
if let inviter = room.inviter, !room.isDirect {
|
||||
RoomInviterLabel(inviter: inviter, imageProvider: context.imageProvider)
|
||||
.font(.compound.bodyMD)
|
||||
.foregroundStyle(.compound.textPlaceholder)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,27 +123,7 @@ struct HomeScreenInviteCell: View {
|
||||
}
|
||||
|
||||
private var subtitle: String? {
|
||||
room.isDirect ? room.inviter?.userID : room.canonicalAlias
|
||||
}
|
||||
|
||||
private var attributedInviteText: AttributedString? {
|
||||
guard
|
||||
room.isDirect == false,
|
||||
let inviterName = room.inviter?.displayName,
|
||||
let inviterID = room.inviter?.userID
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let text = L10n.screenInvitesInvitedYou(inviterName, inviterID)
|
||||
var attributedString = AttributedString(text)
|
||||
attributedString.font = .compound.bodyMD
|
||||
attributedString.foregroundColor = .compound.textPlaceholder
|
||||
if let range = attributedString.range(of: inviterName) {
|
||||
attributedString[range].foregroundColor = .compound.textPrimary
|
||||
attributedString[range].font = .compound.bodyMDSemibold
|
||||
}
|
||||
return attributedString
|
||||
room.isDirect ? room.inviter?.id : room.canonicalAlias
|
||||
}
|
||||
|
||||
private var badge: some View {
|
||||
|
||||
@@ -35,6 +35,7 @@ struct JoinRoomScreenRoomDetails {
|
||||
let canonicalAlias: String?
|
||||
let avatar: RoomAvatar
|
||||
let memberCount: UInt
|
||||
let inviter: RoomInviterDetails?
|
||||
}
|
||||
|
||||
struct JoinRoomScreenViewState: BindableState {
|
||||
|
||||
@@ -81,7 +81,7 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
||||
|
||||
defer {
|
||||
hideLoadingIndicator()
|
||||
updateRoomDetails()
|
||||
Task { await updateRoomDetails() }
|
||||
}
|
||||
|
||||
// Using only the preview API isn't enough as it's not capable
|
||||
@@ -91,13 +91,13 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
||||
|
||||
if let roomProxy = await clientProxy.roomForIdentifier(roomID) {
|
||||
self.roomProxy = roomProxy
|
||||
updateRoomDetails()
|
||||
await updateRoomDetails()
|
||||
}
|
||||
|
||||
switch await clientProxy.roomPreviewForIdentifier(roomID, via: via) {
|
||||
case .success(let roomPreviewDetails):
|
||||
self.roomPreviewDetails = roomPreviewDetails
|
||||
updateRoomDetails()
|
||||
await updateRoomDetails()
|
||||
case .failure(.roomPreviewIsPrivate):
|
||||
break // Handled by the mode, we don't need an error indicator.
|
||||
case .failure:
|
||||
@@ -105,22 +105,24 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
||||
}
|
||||
}
|
||||
|
||||
private func updateRoomDetails() {
|
||||
private func updateRoomDetails() async {
|
||||
let name = roomProxy?.name ?? roomPreviewDetails?.name
|
||||
let inviter = await roomProxy?.inviter.flatMap(RoomInviterDetails.init)
|
||||
state.roomDetails = JoinRoomScreenRoomDetails(name: name,
|
||||
topic: roomProxy?.topic ?? roomPreviewDetails?.topic,
|
||||
canonicalAlias: roomProxy?.canonicalAlias ?? roomPreviewDetails?.canonicalAlias,
|
||||
avatar: roomProxy?.avatar ?? .room(id: roomID, name: name ?? "", avatarURL: roomPreviewDetails?.avatarURL),
|
||||
memberCount: UInt(roomProxy?.activeMembersCount ?? Int(roomPreviewDetails?.memberCount ?? 0)))
|
||||
memberCount: UInt(roomProxy?.activeMembersCount ?? Int(roomPreviewDetails?.memberCount ?? 0)),
|
||||
inviter: inviter)
|
||||
|
||||
updateMode()
|
||||
}
|
||||
|
||||
private func updateMode() {
|
||||
if roomProxy?.isPublic ?? false || roomPreviewDetails?.isPublic ?? false {
|
||||
state.mode = .join
|
||||
} else if roomProxy?.membership == .invited || roomPreviewDetails?.isInvited ?? false {
|
||||
if roomProxy?.membership == .invited || roomPreviewDetails?.isInvited ?? false { // Check invites first to show Accept/Decline buttons on public rooms.
|
||||
state.mode = .invited
|
||||
} else if roomProxy?.isPublic ?? false || roomPreviewDetails?.isPublic ?? false {
|
||||
state.mode = .join
|
||||
} else if roomPreviewDetails?.canKnock ?? false, allowKnocking { // Knocking is not supported yet, the flag is purely for preview tests.
|
||||
state.mode = .knock
|
||||
} else {
|
||||
|
||||
@@ -62,6 +62,12 @@ struct JoinRoomScreen: View {
|
||||
BadgeLabel(title: "\(memberCount)", icon: \.userProfile, isHighlighted: false)
|
||||
}
|
||||
|
||||
if let inviter = context.viewState.roomDetails?.inviter {
|
||||
RoomInviterLabel(inviter: inviter, imageProvider: context.imageProvider)
|
||||
.font(.compound.bodyMD)
|
||||
.foregroundStyle(.compound.textSecondary)
|
||||
}
|
||||
|
||||
if let topic = context.viewState.roomDetails?.topic {
|
||||
Text(topic)
|
||||
.font(.compound.bodyMD)
|
||||
|
||||
Reference in New Issue
Block a user