mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-05 20:09:04 +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:
@@ -595,6 +595,7 @@
|
|||||||
899359A4D1147601F6C4E364 /* PillConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB8D34E94AB07128DB73D6C7 /* PillConstants.swift */; };
|
899359A4D1147601F6C4E364 /* PillConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB8D34E94AB07128DB73D6C7 /* PillConstants.swift */; };
|
||||||
899793EFC63DF93C3E0141E7 /* RoomMemberDetailsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FA60F848D1C14F873F9621A /* RoomMemberDetailsScreenCoordinator.swift */; };
|
899793EFC63DF93C3E0141E7 /* RoomMemberDetailsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FA60F848D1C14F873F9621A /* RoomMemberDetailsScreenCoordinator.swift */; };
|
||||||
8A0BD60CA4A6004DB06B5403 /* MediaUploadingPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669F35C505ACE1110589F875 /* MediaUploadingPreprocessor.swift */; };
|
8A0BD60CA4A6004DB06B5403 /* MediaUploadingPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669F35C505ACE1110589F875 /* MediaUploadingPreprocessor.swift */; };
|
||||||
|
8A83D715940378B9BA9F739E /* RoomInviterLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EB58E4E8D6D634C246AD5C2 /* RoomInviterLabel.swift */; };
|
||||||
8AA84EF202F2EFC8453A97BD /* SecureBackupRecoveryKeyScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 645E027C112740573D27765C /* SecureBackupRecoveryKeyScreenModels.swift */; };
|
8AA84EF202F2EFC8453A97BD /* SecureBackupRecoveryKeyScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 645E027C112740573D27765C /* SecureBackupRecoveryKeyScreenModels.swift */; };
|
||||||
8AB8ED1051216546CB35FA0E /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5E9C044BEB7C70B1378E91 /* UserSession.swift */; };
|
8AB8ED1051216546CB35FA0E /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5E9C044BEB7C70B1378E91 /* UserSession.swift */; };
|
||||||
8AC256AF0EC54658321C9241 /* LegalInformationScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5725BC6C63604CB769145B /* LegalInformationScreenViewModelTests.swift */; };
|
8AC256AF0EC54658321C9241 /* LegalInformationScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5725BC6C63604CB769145B /* LegalInformationScreenViewModelTests.swift */; };
|
||||||
@@ -1667,6 +1668,7 @@
|
|||||||
7DDBF99755A9008CF8C8499E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
7DDBF99755A9008CF8C8499E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||||
7DDF49CEBC0DFC59C308335F /* RoomMemberDetailsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
7DDF49CEBC0DFC59C308335F /* RoomMemberDetailsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
7E492690C8B27A892C194CC4 /* AdvancedSettingsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenCoordinator.swift; sourceTree = "<group>"; };
|
7E492690C8B27A892C194CC4 /* AdvancedSettingsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
|
7EB58E4E8D6D634C246AD5C2 /* RoomInviterLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomInviterLabel.swift; sourceTree = "<group>"; };
|
||||||
7EC2F1622C5BBABED6012E12 /* HeroImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeroImage.swift; sourceTree = "<group>"; };
|
7EC2F1622C5BBABED6012E12 /* HeroImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeroImage.swift; sourceTree = "<group>"; };
|
||||||
7EECE8B331CD169790EF284F /* BugReportScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenViewModelTests.swift; sourceTree = "<group>"; };
|
7EECE8B331CD169790EF284F /* BugReportScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
7F615A00DB223FF3280204D2 /* UserDiscoveryServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoveryServiceProtocol.swift; sourceTree = "<group>"; };
|
7F615A00DB223FF3280204D2 /* UserDiscoveryServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoveryServiceProtocol.swift; sourceTree = "<group>"; };
|
||||||
@@ -2792,6 +2794,7 @@
|
|||||||
648DD1C10E4957CB791FE0B8 /* OverridableAvatarImage.swift */,
|
648DD1C10E4957CB791FE0B8 /* OverridableAvatarImage.swift */,
|
||||||
C705E605EF57C19DBE86FFA1 /* PlaceholderAvatarImage.swift */,
|
C705E605EF57C19DBE86FFA1 /* PlaceholderAvatarImage.swift */,
|
||||||
BEF5FE93A06F563B477F024A /* RoomAvatarImage.swift */,
|
BEF5FE93A06F563B477F024A /* RoomAvatarImage.swift */,
|
||||||
|
7EB58E4E8D6D634C246AD5C2 /* RoomInviterLabel.swift */,
|
||||||
839E2C35DF3F9C7B54C3CE49 /* RoundedCornerShape.swift */,
|
839E2C35DF3F9C7B54C3CE49 /* RoundedCornerShape.swift */,
|
||||||
DE7C80EF77AD102053D3646E /* RoundedLabelItem.swift */,
|
DE7C80EF77AD102053D3646E /* RoundedLabelItem.swift */,
|
||||||
AEB5FF7A09B79B0C6B528F7C /* SFNumberedListView.swift */,
|
AEB5FF7A09B79B0C6B528F7C /* SFNumberedListView.swift */,
|
||||||
@@ -6445,6 +6448,7 @@
|
|||||||
42F1C8731166633E35A6D7E6 /* RoomEventStringBuilder.swift in Sources */,
|
42F1C8731166633E35A6D7E6 /* RoomEventStringBuilder.swift in Sources */,
|
||||||
D55AF9B5B55FEED04771A461 /* RoomFlowCoordinator.swift in Sources */,
|
D55AF9B5B55FEED04771A461 /* RoomFlowCoordinator.swift in Sources */,
|
||||||
04A16B45228F7678A027C079 /* RoomHeaderView.swift in Sources */,
|
04A16B45228F7678A027C079 /* RoomHeaderView.swift in Sources */,
|
||||||
|
8A83D715940378B9BA9F739E /* RoomInviterLabel.swift in Sources */,
|
||||||
F4996C82A4B3A5FF0C8EDD03 /* RoomListFilterModels.swift in Sources */,
|
F4996C82A4B3A5FF0C8EDD03 /* RoomListFilterModels.swift in Sources */,
|
||||||
4A9CEEE612D6D8B3DDBD28BA /* RoomListFilterView.swift in Sources */,
|
4A9CEEE612D6D8B3DDBD28BA /* RoomListFilterView.swift in Sources */,
|
||||||
BD0BE20DBCE31253AE4490A1 /* RoomListFiltersEmptyStateView.swift in Sources */,
|
BD0BE20DBCE31253AE4490A1 /* RoomListFiltersEmptyStateView.swift in Sources */,
|
||||||
|
|||||||
@@ -8273,6 +8273,23 @@ class RoomProxyMock: RoomProxyProtocol {
|
|||||||
set(value) { underlyingMembership = value }
|
set(value) { underlyingMembership = value }
|
||||||
}
|
}
|
||||||
var underlyingMembership: Membership!
|
var underlyingMembership: Membership!
|
||||||
|
var inviterCallsCount = 0
|
||||||
|
var inviterCalled: Bool {
|
||||||
|
return inviterCallsCount > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var inviter: RoomMemberProxyProtocol? {
|
||||||
|
get async {
|
||||||
|
inviterCallsCount += 1
|
||||||
|
if let inviterClosure = inviterClosure {
|
||||||
|
return await inviterClosure()
|
||||||
|
} else {
|
||||||
|
return underlyingInviter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var underlyingInviter: RoomMemberProxyProtocol?
|
||||||
|
var inviterClosure: (() async -> RoomMemberProxyProtocol?)?
|
||||||
var hasOngoingCall: Bool {
|
var hasOngoingCall: Bool {
|
||||||
get { return underlyingHasOngoingCall }
|
get { return underlyingHasOngoingCall }
|
||||||
set(value) { underlyingHasOngoingCall = value }
|
set(value) { underlyingHasOngoingCall = value }
|
||||||
|
|||||||
@@ -97,6 +97,11 @@ extension RoomMemberProxyMock {
|
|||||||
membership: .join))
|
membership: .join))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static var mockNoName: RoomMemberProxyMock {
|
||||||
|
RoomMemberProxyMock(with: .init(userID: "@anonymous:matrix.org",
|
||||||
|
membership: .join))
|
||||||
|
}
|
||||||
|
|
||||||
static var mockInvited: RoomMemberProxyMock {
|
static var mockInvited: RoomMemberProxyMock {
|
||||||
RoomMemberProxyMock(with: .init(userID: "@invited:matrix.org",
|
RoomMemberProxyMock(with: .init(userID: "@invited:matrix.org",
|
||||||
displayName: "Invited",
|
displayName: "Invited",
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ struct RoomProxyMockConfiguration {
|
|||||||
|
|
||||||
var members: [RoomMemberProxyMock] = .allMembers
|
var members: [RoomMemberProxyMock] = .allMembers
|
||||||
var ownUserID = RoomMemberProxyMock.mockMe.userID
|
var ownUserID = RoomMemberProxyMock.mockMe.userID
|
||||||
|
var inviter: RoomMemberProxyProtocol?
|
||||||
|
|
||||||
var canUserInvite = true
|
var canUserInvite = true
|
||||||
var canUserTriggerRoomNotification = false
|
var canUserTriggerRoomNotification = false
|
||||||
@@ -85,6 +86,7 @@ extension RoomProxyMock {
|
|||||||
|
|
||||||
ownUserID = configuration.ownUserID
|
ownUserID = configuration.ownUserID
|
||||||
membership = .joined
|
membership = .joined
|
||||||
|
inviterClosure = { configuration.inviter }
|
||||||
|
|
||||||
membersPublisher = CurrentValueSubject(configuration.members).asCurrentValuePublisher()
|
membersPublisher = CurrentValueSubject(configuration.members).asCurrentValuePublisher()
|
||||||
typingMembersPublisher = CurrentValueSubject([]).asCurrentValuePublisher()
|
typingMembersPublisher = CurrentValueSubject([]).asCurrentValuePublisher()
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2024 New Vector Ltd
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct RoomInviterDetails: Equatable {
|
||||||
|
let id: String
|
||||||
|
let displayName: String?
|
||||||
|
let avatarURL: URL?
|
||||||
|
|
||||||
|
let attributedInviteText: AttributedString
|
||||||
|
|
||||||
|
init(member: RoomMemberProxyProtocol) {
|
||||||
|
id = member.userID
|
||||||
|
displayName = member.displayName
|
||||||
|
avatarURL = member.avatarURL
|
||||||
|
|
||||||
|
let nameOrLocalPart = if let displayName = member.displayName {
|
||||||
|
displayName
|
||||||
|
} else {
|
||||||
|
String(member.userID.dropFirst().prefix { $0 != ":" })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre-compute the attributed string.
|
||||||
|
let placeholder = "{displayname}"
|
||||||
|
var string = AttributedString(L10n.screenInvitesInvitedYou(placeholder, id))
|
||||||
|
var displayNameString = AttributedString(nameOrLocalPart)
|
||||||
|
displayNameString.bold()
|
||||||
|
displayNameString.foregroundColor = .compound.textPrimary
|
||||||
|
string.replace(placeholder, with: displayNameString)
|
||||||
|
attributedInviteText = string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RoomInviterLabel: View {
|
||||||
|
let inviter: RoomInviterDetails
|
||||||
|
|
||||||
|
let imageProvider: ImageProviderProtocol?
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack(alignment: .firstTextBaseline, spacing: 8) {
|
||||||
|
LoadableAvatarImage(url: inviter.avatarURL,
|
||||||
|
name: inviter.displayName,
|
||||||
|
contentID: inviter.id,
|
||||||
|
avatarSize: .custom(16),
|
||||||
|
imageProvider: imageProvider)
|
||||||
|
.alignmentGuide(.firstTextBaseline) { $0[.bottom] * 0.8 }
|
||||||
|
|
||||||
|
Text(inviter.attributedInviteText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Previews
|
||||||
|
|
||||||
|
struct RoomInviterLabel_Previews: PreviewProvider, TestablePreview {
|
||||||
|
static var previews: some View {
|
||||||
|
VStack(spacing: 10) {
|
||||||
|
RoomInviterLabel(inviter: .init(member: RoomMemberProxyMock.mockAlice),
|
||||||
|
imageProvider: MockMediaProvider())
|
||||||
|
RoomInviterLabel(inviter: .init(member: RoomMemberProxyMock.mockDan),
|
||||||
|
imageProvider: MockMediaProvider())
|
||||||
|
RoomInviterLabel(inviter: .init(member: RoomMemberProxyMock.mockNoName),
|
||||||
|
imageProvider: MockMediaProvider())
|
||||||
|
RoomInviterLabel(inviter: .init(member: RoomMemberProxyMock.mockCharlie),
|
||||||
|
imageProvider: MockMediaProvider())
|
||||||
|
.foregroundStyle(.compound.textPrimary)
|
||||||
|
}
|
||||||
|
.font(.compound.bodyMD)
|
||||||
|
.foregroundStyle(.compound.textSecondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -144,12 +144,6 @@ struct HomeScreenRoom: Identifiable, Equatable {
|
|||||||
case invite
|
case invite
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InviterDetails: Equatable {
|
|
||||||
let userID: String
|
|
||||||
let displayName: String?
|
|
||||||
let avatarURL: URL?
|
|
||||||
}
|
|
||||||
|
|
||||||
static let placeholderLastMessage = AttributedString("Hidden last message")
|
static let placeholderLastMessage = AttributedString("Hidden last message")
|
||||||
|
|
||||||
/// The list item identifier is it's room identifier.
|
/// The list item identifier is it's room identifier.
|
||||||
@@ -182,7 +176,7 @@ struct HomeScreenRoom: Identifiable, Equatable {
|
|||||||
|
|
||||||
let avatar: RoomAvatar
|
let avatar: RoomAvatar
|
||||||
|
|
||||||
let inviter: InviterDetails?
|
let inviter: RoomInviterDetails?
|
||||||
|
|
||||||
let canonicalAlias: String?
|
let canonicalAlias: String?
|
||||||
|
|
||||||
@@ -215,12 +209,7 @@ extension HomeScreenRoom {
|
|||||||
let isCallShown = summary.hasOngoingCall
|
let isCallShown = summary.hasOngoingCall
|
||||||
let isHighlighted = summary.isMarkedUnread || (!summary.isMuted && (summary.hasUnreadNotifications || summary.hasUnreadMentions))
|
let isHighlighted = summary.isMarkedUnread || (!summary.isMuted && (summary.hasUnreadNotifications || summary.hasUnreadMentions))
|
||||||
|
|
||||||
var inviter: InviterDetails?
|
let inviter = summary.inviter.map(RoomInviterDetails.init)
|
||||||
if let roomMemberProxy = summary.inviter {
|
|
||||||
inviter = .init(userID: roomMemberProxy.userID,
|
|
||||||
displayName: roomMemberProxy.displayName,
|
|
||||||
avatarURL: roomMemberProxy.avatarURL)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.init(id: identifier,
|
self.init(id: identifier,
|
||||||
roomID: summary.id,
|
roomID: summary.id,
|
||||||
|
|||||||
@@ -74,17 +74,10 @@ struct HomeScreenInviteCell: View {
|
|||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var inviterView: some View {
|
private var inviterView: some View {
|
||||||
if let invitedText = attributedInviteText, let name = room.inviter?.displayName {
|
if let inviter = room.inviter, !room.isDirect {
|
||||||
HStack(alignment: .firstTextBaseline, spacing: 8) {
|
RoomInviterLabel(inviter: inviter, imageProvider: context.imageProvider)
|
||||||
LoadableAvatarImage(url: room.inviter?.avatarURL,
|
.font(.compound.bodyMD)
|
||||||
name: name,
|
.foregroundStyle(.compound.textPlaceholder)
|
||||||
contentID: name,
|
|
||||||
avatarSize: .custom(16),
|
|
||||||
imageProvider: context.imageProvider)
|
|
||||||
.alignmentGuide(.firstTextBaseline) { $0[.bottom] * 0.8 }
|
|
||||||
|
|
||||||
Text(invitedText)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,27 +123,7 @@ struct HomeScreenInviteCell: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var subtitle: String? {
|
private var subtitle: String? {
|
||||||
room.isDirect ? room.inviter?.userID : room.canonicalAlias
|
room.isDirect ? room.inviter?.id : 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var badge: some View {
|
private var badge: some View {
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ struct JoinRoomScreenRoomDetails {
|
|||||||
let canonicalAlias: String?
|
let canonicalAlias: String?
|
||||||
let avatar: RoomAvatar
|
let avatar: RoomAvatar
|
||||||
let memberCount: UInt
|
let memberCount: UInt
|
||||||
|
let inviter: RoomInviterDetails?
|
||||||
}
|
}
|
||||||
|
|
||||||
struct JoinRoomScreenViewState: BindableState {
|
struct JoinRoomScreenViewState: BindableState {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
|||||||
|
|
||||||
defer {
|
defer {
|
||||||
hideLoadingIndicator()
|
hideLoadingIndicator()
|
||||||
updateRoomDetails()
|
Task { await updateRoomDetails() }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using only the preview API isn't enough as it's not capable
|
// 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) {
|
if let roomProxy = await clientProxy.roomForIdentifier(roomID) {
|
||||||
self.roomProxy = roomProxy
|
self.roomProxy = roomProxy
|
||||||
updateRoomDetails()
|
await updateRoomDetails()
|
||||||
}
|
}
|
||||||
|
|
||||||
switch await clientProxy.roomPreviewForIdentifier(roomID, via: via) {
|
switch await clientProxy.roomPreviewForIdentifier(roomID, via: via) {
|
||||||
case .success(let roomPreviewDetails):
|
case .success(let roomPreviewDetails):
|
||||||
self.roomPreviewDetails = roomPreviewDetails
|
self.roomPreviewDetails = roomPreviewDetails
|
||||||
updateRoomDetails()
|
await updateRoomDetails()
|
||||||
case .failure(.roomPreviewIsPrivate):
|
case .failure(.roomPreviewIsPrivate):
|
||||||
break // Handled by the mode, we don't need an error indicator.
|
break // Handled by the mode, we don't need an error indicator.
|
||||||
case .failure:
|
case .failure:
|
||||||
@@ -105,22 +105,24 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateRoomDetails() {
|
private func updateRoomDetails() async {
|
||||||
let name = roomProxy?.name ?? roomPreviewDetails?.name
|
let name = roomProxy?.name ?? roomPreviewDetails?.name
|
||||||
|
let inviter = await roomProxy?.inviter.flatMap(RoomInviterDetails.init)
|
||||||
state.roomDetails = JoinRoomScreenRoomDetails(name: name,
|
state.roomDetails = JoinRoomScreenRoomDetails(name: name,
|
||||||
topic: roomProxy?.topic ?? roomPreviewDetails?.topic,
|
topic: roomProxy?.topic ?? roomPreviewDetails?.topic,
|
||||||
canonicalAlias: roomProxy?.canonicalAlias ?? roomPreviewDetails?.canonicalAlias,
|
canonicalAlias: roomProxy?.canonicalAlias ?? roomPreviewDetails?.canonicalAlias,
|
||||||
avatar: roomProxy?.avatar ?? .room(id: roomID, name: name ?? "", avatarURL: roomPreviewDetails?.avatarURL),
|
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()
|
updateMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateMode() {
|
private func updateMode() {
|
||||||
if roomProxy?.isPublic ?? false || roomPreviewDetails?.isPublic ?? false {
|
if roomProxy?.membership == .invited || roomPreviewDetails?.isInvited ?? false { // Check invites first to show Accept/Decline buttons on public rooms.
|
||||||
state.mode = .join
|
|
||||||
} else if roomProxy?.membership == .invited || roomPreviewDetails?.isInvited ?? false {
|
|
||||||
state.mode = .invited
|
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.
|
} else if roomPreviewDetails?.canKnock ?? false, allowKnocking { // Knocking is not supported yet, the flag is purely for preview tests.
|
||||||
state.mode = .knock
|
state.mode = .knock
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -62,6 +62,12 @@ struct JoinRoomScreen: View {
|
|||||||
BadgeLabel(title: "\(memberCount)", icon: \.userProfile, isHighlighted: false)
|
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 {
|
if let topic = context.viewState.roomDetails?.topic {
|
||||||
Text(topic)
|
Text(topic)
|
||||||
.font(.compound.bodyMD)
|
.font(.compound.bodyMD)
|
||||||
|
|||||||
@@ -64,6 +64,12 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
room.membership()
|
room.membership()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var inviter: RoomMemberProxyProtocol? {
|
||||||
|
get async {
|
||||||
|
await (try? roomListItem.roomInfo().inviter).map(RoomMemberProxy.init)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var isDirect: Bool {
|
var isDirect: Bool {
|
||||||
room.isDirect()
|
room.isDirect()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ protocol RoomProxyProtocol {
|
|||||||
var isFavourite: Bool { get async }
|
var isFavourite: Bool { get async }
|
||||||
var pinnedEventIDs: [String] { get async }
|
var pinnedEventIDs: [String] { get async }
|
||||||
var membership: Membership { get }
|
var membership: Membership { get }
|
||||||
|
var inviter: RoomMemberProxyProtocol? { get async }
|
||||||
var hasOngoingCall: Bool { get }
|
var hasOngoingCall: Bool { get }
|
||||||
var canonicalAlias: String? { get }
|
var canonicalAlias: String? { get }
|
||||||
var ownUserID: String { get }
|
var ownUserID: String { get }
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:bfca845384d5d0a44aa1a3e322c7aa059c4286750d2e0ff2a47632096b95c926
|
||||||
|
size 108298
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:cd1441564319b3f2a6028ac242063014964d601913ea1f8a7ccd86d1d7d4ef4f
|
||||||
|
size 121015
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:0aa045fa03babdf4b7eb051cc1befb486524ef0a904fb5f55d8f41633dd06f20
|
||||||
|
size 63819
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:56a4cb633080ff6f57162246d43e6dc2f8dbddd718c84181f348af1e1efeb47f
|
||||||
|
size 79274
|
||||||
Reference in New Issue
Block a user