mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 10:33:45 +00:00
Rename UserProfileProxy to UserProfile. It's a pure struct and proxies nothing.
Also remove the redundant `userID` property given `id` already exists (for Identifiable conformance).
This commit is contained in:
@@ -100,6 +100,7 @@
|
|||||||
0DC815CA24E1BD7F408F37D3 /* CollapsibleTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */; };
|
0DC815CA24E1BD7F408F37D3 /* CollapsibleTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */; };
|
||||||
0DFCEAB8C82B151718F71D49 /* FrequentlyUsedEmoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A2074C0449B83D5858BD2D7 /* FrequentlyUsedEmoji.swift */; };
|
0DFCEAB8C82B151718F71D49 /* FrequentlyUsedEmoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A2074C0449B83D5858BD2D7 /* FrequentlyUsedEmoji.swift */; };
|
||||||
0E08BB72B2258652CF501A8B /* Version in Frameworks */ = {isa = PBXBuildFile; productRef = 2B9ACE4FCACB5A8812154424 /* Version */; };
|
0E08BB72B2258652CF501A8B /* Version in Frameworks */ = {isa = PBXBuildFile; productRef = 2B9ACE4FCACB5A8812154424 /* Version */; };
|
||||||
|
0E6B97E4F4DAC3E5B64B215F /* UserProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66653C5417592A727B549533 /* UserProfile.swift */; };
|
||||||
0E8C480700870BB34A2A360F /* DeviceKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4003BC24B24C9E63D3304177 /* DeviceKit */; };
|
0E8C480700870BB34A2A360F /* DeviceKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4003BC24B24C9E63D3304177 /* DeviceKit */; };
|
||||||
0EA6537A07E2DC882AEA5962 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 187853A7E643995EE49FAD43 /* Localizable.stringsdict */; };
|
0EA6537A07E2DC882AEA5962 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 187853A7E643995EE49FAD43 /* Localizable.stringsdict */; };
|
||||||
0EBF0A411E1C46D4BFA2B087 /* ManageAuthorizedSpacesScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB9CD3A0A39BC063438E12D4 /* ManageAuthorizedSpacesScreenCoordinator.swift */; };
|
0EBF0A411E1C46D4BFA2B087 /* ManageAuthorizedSpacesScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB9CD3A0A39BC063438E12D4 /* ManageAuthorizedSpacesScreenCoordinator.swift */; };
|
||||||
@@ -1353,7 +1354,6 @@
|
|||||||
E1C67E5D9E22135A8FEBBD60 /* StackedAvatarsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8558D41DD4B553A752C868A /* StackedAvatarsView.swift */; };
|
E1C67E5D9E22135A8FEBBD60 /* StackedAvatarsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8558D41DD4B553A752C868A /* StackedAvatarsView.swift */; };
|
||||||
E1DE8A5422643F759385290F /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD5523BDEDB247E29228476 /* AppSettings.swift */; };
|
E1DE8A5422643F759385290F /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD5523BDEDB247E29228476 /* AppSettings.swift */; };
|
||||||
E1DF24D085572A55C9758A2D /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E89E530A8E92EC44301CA1 /* Bundle.swift */; };
|
E1DF24D085572A55C9758A2D /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E89E530A8E92EC44301CA1 /* Bundle.swift */; };
|
||||||
E21FE4C5B614F311C0955859 /* UserProfileProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C454AE59914B551A6D02C0 /* UserProfileProxy.swift */; };
|
|
||||||
E26E702F325F0AA49B8A5CFD /* RoomPowerLevelsProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = E944F717FC10A428D027074D /* RoomPowerLevelsProxyMock.swift */; };
|
E26E702F325F0AA49B8A5CFD /* RoomPowerLevelsProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = E944F717FC10A428D027074D /* RoomPowerLevelsProxyMock.swift */; };
|
||||||
E27C4D1A1F8BB77CA790B403 /* InviteUsersScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A861DA5932B128FE1DCB5CE2 /* InviteUsersScreenCoordinator.swift */; };
|
E27C4D1A1F8BB77CA790B403 /* InviteUsersScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A861DA5932B128FE1DCB5CE2 /* InviteUsersScreenCoordinator.swift */; };
|
||||||
E290C78E7F09F47FD2662986 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40C19719687984FD9478FBE /* Task.swift */; };
|
E290C78E7F09F47FD2662986 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40C19719687984FD9478FBE /* Task.swift */; };
|
||||||
@@ -2114,7 +2114,6 @@
|
|||||||
510E89B989477E5EE8E503C0 /* PinnedEventsTimelineScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinnedEventsTimelineScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
510E89B989477E5EE8E503C0 /* PinnedEventsTimelineScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinnedEventsTimelineScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenViewModelTests.swift; sourceTree = "<group>"; };
|
514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
51C2BCE0BC1FC69C1B36E688 /* BugReportScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenModels.swift; sourceTree = "<group>"; };
|
51C2BCE0BC1FC69C1B36E688 /* BugReportScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenModels.swift; sourceTree = "<group>"; };
|
||||||
51C454AE59914B551A6D02C0 /* UserProfileProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileProxy.swift; sourceTree = "<group>"; };
|
|
||||||
51F14C0F5FD4A1814D5527E6 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = fa.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
51F14C0F5FD4A1814D5527E6 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = fa.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
52135BD9E0E7A091688F627A /* MessageForwardingScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreenModels.swift; sourceTree = "<group>"; };
|
52135BD9E0E7A091688F627A /* MessageForwardingScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreenModels.swift; sourceTree = "<group>"; };
|
||||||
5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreen.swift; sourceTree = "<group>"; };
|
5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreen.swift; sourceTree = "<group>"; };
|
||||||
@@ -2222,6 +2221,7 @@
|
|||||||
664ABD745A746C45CB842158 /* CallInviteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallInviteRoomTimelineView.swift; sourceTree = "<group>"; };
|
664ABD745A746C45CB842158 /* CallInviteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallInviteRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||||
664D3C710B4A12CE4E623645 /* DeactivateAccountScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeactivateAccountScreenModels.swift; sourceTree = "<group>"; };
|
664D3C710B4A12CE4E623645 /* DeactivateAccountScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeactivateAccountScreenModels.swift; sourceTree = "<group>"; };
|
||||||
6654859746B0BE9611459391 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = cs; path = cs.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
6654859746B0BE9611459391 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = cs; path = cs.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
|
66653C5417592A727B549533 /* UserProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfile.swift; sourceTree = "<group>"; };
|
||||||
667DD3A9D932D7D9EB380CAA /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sk; path = sk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
667DD3A9D932D7D9EB380CAA /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sk; path = sk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
6695C64F066628411EAD21E9 /* RoomPreviewProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPreviewProxyMock.swift; sourceTree = "<group>"; };
|
6695C64F066628411EAD21E9 /* RoomPreviewProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPreviewProxyMock.swift; sourceTree = "<group>"; };
|
||||||
669F35C505ACE1110589F875 /* MediaUploadingPreprocessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadingPreprocessor.swift; sourceTree = "<group>"; };
|
669F35C505ACE1110589F875 /* MediaUploadingPreprocessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadingPreprocessor.swift; sourceTree = "<group>"; };
|
||||||
@@ -6740,7 +6740,7 @@
|
|||||||
7F615A00DB223FF3280204D2 /* UserDiscoveryServiceProtocol.swift */,
|
7F615A00DB223FF3280204D2 /* UserDiscoveryServiceProtocol.swift */,
|
||||||
964093C7CA8823CAB7FFD88E /* UserIdentityProxy.swift */,
|
964093C7CA8823CAB7FFD88E /* UserIdentityProxy.swift */,
|
||||||
0F793C422BDACE0C60C774F4 /* UserIdentityProxyProtocol.swift */,
|
0F793C422BDACE0C60C774F4 /* UserIdentityProxyProtocol.swift */,
|
||||||
51C454AE59914B551A6D02C0 /* UserProfileProxy.swift */,
|
66653C5417592A727B549533 /* UserProfile.swift */,
|
||||||
);
|
);
|
||||||
path = Users;
|
path = Users;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -9182,8 +9182,8 @@
|
|||||||
A8DB299C5C891EDAE74A22F4 /* UserLocationCell.swift in Sources */,
|
A8DB299C5C891EDAE74A22F4 /* UserLocationCell.swift in Sources */,
|
||||||
E3291AD16D7A5CB14781819C /* UserNotificationCenterProtocol.swift in Sources */,
|
E3291AD16D7A5CB14781819C /* UserNotificationCenterProtocol.swift in Sources */,
|
||||||
80DEA2A4B20F9E279EAE6B2B /* UserProfile+Mock.swift in Sources */,
|
80DEA2A4B20F9E279EAE6B2B /* UserProfile+Mock.swift in Sources */,
|
||||||
|
0E6B97E4F4DAC3E5B64B215F /* UserProfile.swift in Sources */,
|
||||||
ED90A59F068FD0CA27E602ED /* UserProfileListRow.swift in Sources */,
|
ED90A59F068FD0CA27E602ED /* UserProfileListRow.swift in Sources */,
|
||||||
E21FE4C5B614F311C0955859 /* UserProfileProxy.swift in Sources */,
|
|
||||||
1A3B073568D1DC8F76F1F3A0 /* UserProfileScreen.swift in Sources */,
|
1A3B073568D1DC8F76F1F3A0 /* UserProfileScreen.swift in Sources */,
|
||||||
6AEB650311F694A5702255C9 /* UserProfileScreenCoordinator.swift in Sources */,
|
6AEB650311F694A5702255C9 /* UserProfileScreenCoordinator.swift in Sources */,
|
||||||
D4CB979EB4FE26AAD9F9A72B /* UserProfileScreenModels.swift in Sources */,
|
D4CB979EB4FE26AAD9F9A72B /* UserProfileScreenModels.swift in Sources */,
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ enum InviteUsersFlow: Hashable {
|
|||||||
/// Invite people into the current room.
|
/// Invite people into the current room.
|
||||||
case existingRoom
|
case existingRoom
|
||||||
/// Start a new room with the given invitee pre-selected and mandatory.
|
/// Start a new room with the given invitee pre-selected and mandatory.
|
||||||
case newRoom(mandatoryInvitee: UserProfileProxy)
|
case newRoom(mandatoryInvitee: UserProfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// swiftlint:disable:next type_body_length
|
// swiftlint:disable:next type_body_length
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
MXLog.info("Received session verification request")
|
MXLog.info("Received session verification request")
|
||||||
|
|
||||||
if details.senderProfile.userID == userSession.clientProxy.userID {
|
if details.senderProfile.id == userSession.clientProxy.userID {
|
||||||
presentSessionVerificationScreen(flow: .deviceResponder(requestDetails: details))
|
presentSessionVerificationScreen(flow: .deviceResponder(requestDetails: details))
|
||||||
} else {
|
} else {
|
||||||
presentSessionVerificationScreen(flow: .userResponder(requestDetails: details))
|
presentSessionVerificationScreen(flow: .userResponder(requestDetails: details))
|
||||||
|
|||||||
@@ -3533,14 +3533,14 @@ nonisolated class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private let profileForReturnValueLock = NSLock()
|
private let profileForReturnValueLock = NSLock()
|
||||||
private nonisolated(unsafe) var profileForUnderlyingReturnValue: Result<UserProfileProxy, ClientProxyError>!
|
private nonisolated(unsafe) var profileForUnderlyingReturnValue: Result<UserProfile, ClientProxyError>!
|
||||||
var profileForReturnValue: Result<UserProfileProxy, ClientProxyError>! {
|
var profileForReturnValue: Result<UserProfile, ClientProxyError>! {
|
||||||
get { profileForReturnValueLock.withLock { profileForUnderlyingReturnValue } }
|
get { profileForReturnValueLock.withLock { profileForUnderlyingReturnValue } }
|
||||||
set { profileForReturnValueLock.withLock { profileForUnderlyingReturnValue = newValue } }
|
set { profileForReturnValueLock.withLock { profileForUnderlyingReturnValue = newValue } }
|
||||||
}
|
}
|
||||||
nonisolated(unsafe) var profileForClosure: ((String) async -> Result<UserProfileProxy, ClientProxyError>)?
|
nonisolated(unsafe) var profileForClosure: ((String) async -> Result<UserProfile, ClientProxyError>)?
|
||||||
|
|
||||||
@concurrent func profile(for userID: String) async -> Result<UserProfileProxy, ClientProxyError> {
|
@concurrent func profile(for userID: String) async -> Result<UserProfile, ClientProxyError> {
|
||||||
profileForCallsCountLock.withLock { profileForUnderlyingCallsCount += 1 }
|
profileForCallsCountLock.withLock { profileForUnderlyingCallsCount += 1 }
|
||||||
profileForReceivedUserID = userID
|
profileForReceivedUserID = userID
|
||||||
profileForReceivedInvocationsLock.withLock { profileForUnderlyingReceivedInvocations.append(userID) }
|
profileForReceivedInvocationsLock.withLock { profileForUnderlyingReceivedInvocations.append(userID) }
|
||||||
@@ -3972,14 +3972,14 @@ nonisolated class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private let recentConversationCounterpartsReturnValueLock = NSLock()
|
private let recentConversationCounterpartsReturnValueLock = NSLock()
|
||||||
private nonisolated(unsafe) var recentConversationCounterpartsUnderlyingReturnValue: [UserProfileProxy]!
|
private nonisolated(unsafe) var recentConversationCounterpartsUnderlyingReturnValue: [UserProfile]!
|
||||||
var recentConversationCounterpartsReturnValue: [UserProfileProxy]! {
|
var recentConversationCounterpartsReturnValue: [UserProfile]! {
|
||||||
get { recentConversationCounterpartsReturnValueLock.withLock { recentConversationCounterpartsUnderlyingReturnValue } }
|
get { recentConversationCounterpartsReturnValueLock.withLock { recentConversationCounterpartsUnderlyingReturnValue } }
|
||||||
set { recentConversationCounterpartsReturnValueLock.withLock { recentConversationCounterpartsUnderlyingReturnValue = newValue } }
|
set { recentConversationCounterpartsReturnValueLock.withLock { recentConversationCounterpartsUnderlyingReturnValue = newValue } }
|
||||||
}
|
}
|
||||||
nonisolated(unsafe) var recentConversationCounterpartsClosure: (() async -> [UserProfileProxy])?
|
nonisolated(unsafe) var recentConversationCounterpartsClosure: (() async -> [UserProfile])?
|
||||||
|
|
||||||
@concurrent func recentConversationCounterparts() async -> [UserProfileProxy] {
|
@concurrent func recentConversationCounterparts() async -> [UserProfile] {
|
||||||
recentConversationCounterpartsCallsCountLock.withLock { recentConversationCounterpartsUnderlyingCallsCount += 1 }
|
recentConversationCounterpartsCallsCountLock.withLock { recentConversationCounterpartsUnderlyingCallsCount += 1 }
|
||||||
if let recentConversationCounterpartsClosure = recentConversationCounterpartsClosure {
|
if let recentConversationCounterpartsClosure = recentConversationCounterpartsClosure {
|
||||||
return await recentConversationCounterpartsClosure()
|
return await recentConversationCounterpartsClosure()
|
||||||
@@ -14057,14 +14057,14 @@ nonisolated class UserDiscoveryServiceMock: UserDiscoveryServiceProtocol, @unche
|
|||||||
}
|
}
|
||||||
|
|
||||||
private let searchProfilesWithReturnValueLock = NSLock()
|
private let searchProfilesWithReturnValueLock = NSLock()
|
||||||
private nonisolated(unsafe) var searchProfilesWithUnderlyingReturnValue: Result<[UserProfileProxy], UserDiscoveryErrorType>!
|
private nonisolated(unsafe) var searchProfilesWithUnderlyingReturnValue: Result<[UserProfile], UserDiscoveryErrorType>!
|
||||||
var searchProfilesWithReturnValue: Result<[UserProfileProxy], UserDiscoveryErrorType>! {
|
var searchProfilesWithReturnValue: Result<[UserProfile], UserDiscoveryErrorType>! {
|
||||||
get { searchProfilesWithReturnValueLock.withLock { searchProfilesWithUnderlyingReturnValue } }
|
get { searchProfilesWithReturnValueLock.withLock { searchProfilesWithUnderlyingReturnValue } }
|
||||||
set { searchProfilesWithReturnValueLock.withLock { searchProfilesWithUnderlyingReturnValue = newValue } }
|
set { searchProfilesWithReturnValueLock.withLock { searchProfilesWithUnderlyingReturnValue = newValue } }
|
||||||
}
|
}
|
||||||
nonisolated(unsafe) var searchProfilesWithClosure: ((String) async -> Result<[UserProfileProxy], UserDiscoveryErrorType>)?
|
nonisolated(unsafe) var searchProfilesWithClosure: ((String) async -> Result<[UserProfile], UserDiscoveryErrorType>)?
|
||||||
|
|
||||||
@concurrent func searchProfiles(with searchQuery: String) async -> Result<[UserProfileProxy], UserDiscoveryErrorType> {
|
@concurrent func searchProfiles(with searchQuery: String) async -> Result<[UserProfile], UserDiscoveryErrorType> {
|
||||||
searchProfilesWithCallsCountLock.withLock { searchProfilesWithUnderlyingCallsCount += 1 }
|
searchProfilesWithCallsCountLock.withLock { searchProfilesWithUnderlyingCallsCount += 1 }
|
||||||
searchProfilesWithReceivedSearchQuery = searchQuery
|
searchProfilesWithReceivedSearchQuery = searchQuery
|
||||||
searchProfilesWithReceivedInvocationsLock.withLock { searchProfilesWithUnderlyingReceivedInvocations.append(searchQuery) }
|
searchProfilesWithReceivedInvocationsLock.withLock { searchProfilesWithUnderlyingReceivedInvocations.append(searchQuery) }
|
||||||
|
|||||||
@@ -8,29 +8,29 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension UserProfileProxy {
|
extension UserProfile {
|
||||||
/// Mocks
|
/// Mocks
|
||||||
static var mockAlice: UserProfileProxy {
|
static var mockAlice: UserProfile {
|
||||||
.init(userID: "@alice:matrix.org", displayName: "Alice", avatarURL: "mxc://matrix.org/UcCimidcvpFvWkPzvjXMQPHA")
|
.init(userID: "@alice:matrix.org", displayName: "Alice", avatarURL: "mxc://matrix.org/UcCimidcvpFvWkPzvjXMQPHA")
|
||||||
}
|
}
|
||||||
|
|
||||||
static var mockBob: UserProfileProxy {
|
static var mockBob: UserProfile {
|
||||||
.init(userID: "@bob:matrix.org", displayName: "Bob", avatarURL: nil)
|
.init(userID: "@bob:matrix.org", displayName: "Bob", avatarURL: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
static var mockBobby: UserProfileProxy {
|
static var mockBobby: UserProfile {
|
||||||
.init(userID: "@bobby:matrix.org", displayName: "Bobby", avatarURL: nil)
|
.init(userID: "@bobby:matrix.org", displayName: "Bobby", avatarURL: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
static var mockCharlie: UserProfileProxy {
|
static var mockCharlie: UserProfile {
|
||||||
.init(userID: "@charlie:matrix.org", displayName: "Charlie", avatarURL: nil)
|
.init(userID: "@charlie:matrix.org", displayName: "Charlie", avatarURL: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
static var mockDan: UserProfileProxy {
|
static var mockDan: UserProfile {
|
||||||
.init(userID: "@dan:matrix.org", displayName: "Dan", avatarURL: .mockMXCUserAvatar)
|
.init(userID: "@dan:matrix.org", displayName: "Dan", avatarURL: .mockMXCUserAvatar)
|
||||||
}
|
}
|
||||||
|
|
||||||
static var mockVerbose: UserProfileProxy {
|
static var mockVerbose: UserProfile {
|
||||||
.init(userID: "@charlie:matrix.org", displayName: "Charlie is the best display name", avatarURL: nil)
|
.init(userID: "@charlie:matrix.org", displayName: "Charlie is the best display name", avatarURL: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import SwiftUI
|
|||||||
struct AvatarHeaderView<Footer: View>: View {
|
struct AvatarHeaderView<Footer: View>: View {
|
||||||
private enum AvatarInfo {
|
private enum AvatarInfo {
|
||||||
case room(RoomAvatar)
|
case room(RoomAvatar)
|
||||||
case user(UserProfileProxy)
|
case user(UserProfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum Badge: Hashable {
|
private enum Badge: Hashable {
|
||||||
@@ -44,7 +44,7 @@ struct AvatarHeaderView<Footer: View>: View {
|
|||||||
if let roomAlias = room.canonicalAlias {
|
if let roomAlias = room.canonicalAlias {
|
||||||
subtitle = roomAlias
|
subtitle = roomAlias
|
||||||
} else if room.isDirect, case let .heroes(heroes) = room.avatar, heroes.count == 1 {
|
} else if room.isDirect, case let .heroes(heroes) = room.avatar, heroes.count == 1 {
|
||||||
subtitle = heroes[0].userID
|
subtitle = heroes[0].id
|
||||||
} else {
|
} else {
|
||||||
subtitle = nil
|
subtitle = nil
|
||||||
}
|
}
|
||||||
@@ -70,10 +70,10 @@ struct AvatarHeaderView<Footer: View>: View {
|
|||||||
mediaProvider: MediaProviderProtocol? = nil,
|
mediaProvider: MediaProviderProtocol? = nil,
|
||||||
onAvatarTap: ((URL) -> Void)? = nil,
|
onAvatarTap: ((URL) -> Void)? = nil,
|
||||||
@ViewBuilder footer: @escaping () -> Footer) {
|
@ViewBuilder footer: @escaping () -> Footer) {
|
||||||
let dmRecipientProfile = UserProfileProxy(member: dmRecipient)
|
let dmRecipientProfile = UserProfile(member: dmRecipient)
|
||||||
avatarInfo = .room(.heroes([dmRecipientProfile, UserProfileProxy(member: accountOwner)]))
|
avatarInfo = .room(.heroes([dmRecipientProfile, UserProfile(member: accountOwner)]))
|
||||||
title = dmRecipientProfile.displayName ?? dmRecipientProfile.userID
|
title = dmRecipientProfile.displayName ?? dmRecipientProfile.id
|
||||||
subtitle = dmRecipientProfile.displayName == nil ? nil : dmRecipientProfile.userID
|
subtitle = dmRecipientProfile.displayName == nil ? nil : dmRecipientProfile.id
|
||||||
|
|
||||||
avatarSize = .user(on: .dmDetails)
|
avatarSize = .user(on: .dmDetails)
|
||||||
self.mediaProvider = mediaProvider
|
self.mediaProvider = mediaProvider
|
||||||
@@ -89,7 +89,7 @@ struct AvatarHeaderView<Footer: View>: View {
|
|||||||
mediaProvider: MediaProviderProtocol? = nil,
|
mediaProvider: MediaProviderProtocol? = nil,
|
||||||
onAvatarTap: ((URL) -> Void)? = nil,
|
onAvatarTap: ((URL) -> Void)? = nil,
|
||||||
@ViewBuilder footer: @escaping () -> Footer) {
|
@ViewBuilder footer: @escaping () -> Footer) {
|
||||||
let profile = UserProfileProxy(member: member)
|
let profile = UserProfile(member: member)
|
||||||
|
|
||||||
self.init(user: profile,
|
self.init(user: profile,
|
||||||
isVerified: isVerified,
|
isVerified: isVerified,
|
||||||
@@ -99,15 +99,15 @@ struct AvatarHeaderView<Footer: View>: View {
|
|||||||
footer: footer)
|
footer: footer)
|
||||||
}
|
}
|
||||||
|
|
||||||
init(user: UserProfileProxy,
|
init(user: UserProfile,
|
||||||
isVerified: Bool,
|
isVerified: Bool,
|
||||||
avatarSize: Avatars.Size,
|
avatarSize: Avatars.Size,
|
||||||
mediaProvider: MediaProviderProtocol? = nil,
|
mediaProvider: MediaProviderProtocol? = nil,
|
||||||
onAvatarTap: ((URL) -> Void)? = nil,
|
onAvatarTap: ((URL) -> Void)? = nil,
|
||||||
@ViewBuilder footer: @escaping () -> Footer) {
|
@ViewBuilder footer: @escaping () -> Footer) {
|
||||||
avatarInfo = .user(user)
|
avatarInfo = .user(user)
|
||||||
title = user.displayName ?? user.userID
|
title = user.displayName ?? user.id
|
||||||
subtitle = user.displayName == nil ? nil : user.userID
|
subtitle = user.displayName == nil ? nil : user.id
|
||||||
|
|
||||||
self.avatarSize = avatarSize
|
self.avatarSize = avatarSize
|
||||||
self.mediaProvider = mediaProvider
|
self.mediaProvider = mediaProvider
|
||||||
@@ -123,7 +123,7 @@ struct AvatarHeaderView<Footer: View>: View {
|
|||||||
mediaProvider: MediaProviderProtocol? = nil,
|
mediaProvider: MediaProviderProtocol? = nil,
|
||||||
onAvatarTap: ((URL) -> Void)? = nil,
|
onAvatarTap: ((URL) -> Void)? = nil,
|
||||||
@ViewBuilder footer: @escaping () -> Footer) {
|
@ViewBuilder footer: @escaping () -> Footer) {
|
||||||
let profile = UserProfileProxy(sender: sender)
|
let profile = UserProfile(sender: sender)
|
||||||
|
|
||||||
self.init(user: profile,
|
self.init(user: profile,
|
||||||
isVerified: false,
|
isVerified: false,
|
||||||
@@ -180,8 +180,8 @@ struct AvatarHeaderView<Footer: View>: View {
|
|||||||
switch avatarInfo {
|
switch avatarInfo {
|
||||||
case .room(let roomAvatar):
|
case .room(let roomAvatar):
|
||||||
return roomAvatar.hasURL ? L10n.a11yViewAvatar : L10n.a11yAvatar
|
return roomAvatar.hasURL ? L10n.a11yViewAvatar : L10n.a11yAvatar
|
||||||
case .user(let userProfileProxy):
|
case .user(let userProfile):
|
||||||
return userProfileProxy.avatarURL != nil ? L10n.a11yViewAvatar : L10n.a11yAvatar
|
return userProfile.avatarURL != nil ? L10n.a11yViewAvatar : L10n.a11yAvatar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ struct AvatarHeaderView<Footer: View>: View {
|
|||||||
case .user(let userProfile):
|
case .user(let userProfile):
|
||||||
LoadableAvatarImage(url: userProfile.avatarURL,
|
LoadableAvatarImage(url: userProfile.avatarURL,
|
||||||
name: userProfile.displayName,
|
name: userProfile.displayName,
|
||||||
contentID: userProfile.userID,
|
contentID: userProfile.id,
|
||||||
avatarSize: avatarSize,
|
avatarSize: avatarSize,
|
||||||
mediaProvider: mediaProvider,
|
mediaProvider: mediaProvider,
|
||||||
onTap: onAvatarTap)
|
onTap: onAvatarTap)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import Compound
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct JoinedMembersBadgeView: View {
|
struct JoinedMembersBadgeView: View {
|
||||||
let heroes: [UserProfileProxy]
|
let heroes: [UserProfile]
|
||||||
var shouldHideAvatars = false
|
var shouldHideAvatars = false
|
||||||
let joinedCount: Int
|
let joinedCount: Int
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ struct JoinedMembersBadgeView: View {
|
|||||||
ForEach(heroes.prefix(3).reversed()) { hero in
|
ForEach(heroes.prefix(3).reversed()) { hero in
|
||||||
LoadableAvatarImage(url: shouldHideAvatars ? nil : hero.avatarURL,
|
LoadableAvatarImage(url: shouldHideAvatars ? nil : hero.avatarURL,
|
||||||
name: hero.displayName,
|
name: hero.displayName,
|
||||||
contentID: hero.userID,
|
contentID: hero.id,
|
||||||
avatarSize: .user(on: .spaceHeader),
|
avatarSize: .user(on: .spaceHeader),
|
||||||
mediaProvider: mediaProvider)
|
mediaProvider: mediaProvider)
|
||||||
.mask {
|
.mask {
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ struct LocationMarkerView: View {
|
|||||||
if let userProfile = kind.userProfile {
|
if let userProfile = kind.userProfile {
|
||||||
LoadableAvatarImage(url: userProfile.avatarURL,
|
LoadableAvatarImage(url: userProfile.avatarURL,
|
||||||
name: userProfile.displayName,
|
name: userProfile.displayName,
|
||||||
contentID: userProfile.userID,
|
contentID: userProfile.id,
|
||||||
avatarSize: .user(on: .map),
|
avatarSize: .user(on: .map),
|
||||||
mediaProvider: mediaProvider)
|
mediaProvider: mediaProvider)
|
||||||
.overlay {
|
.overlay {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ enum RoomAvatar: Equatable {
|
|||||||
/// An avatar generated from a Room's details.
|
/// An avatar generated from a Room's details.
|
||||||
case room(id: String, name: String?, avatarURL: URL?)
|
case room(id: String, name: String?, avatarURL: URL?)
|
||||||
/// An avatar generated from a collection of room heroes.
|
/// An avatar generated from a collection of room heroes.
|
||||||
case heroes([UserProfileProxy])
|
case heroes([UserProfile])
|
||||||
/// An avatar generated from a Space's details.
|
/// An avatar generated from a Space's details.
|
||||||
case space(id: String, name: String?, avatarURL: URL?)
|
case space(id: String, name: String?, avatarURL: URL?)
|
||||||
/// A static avatar for a tombstoned room.
|
/// A static avatar for a tombstoned room.
|
||||||
@@ -24,7 +24,7 @@ enum RoomAvatar: Equatable {
|
|||||||
case let .room(id, name, _):
|
case let .room(id, name, _):
|
||||||
.room(id: id, name: name, avatarURL: nil)
|
.room(id: id, name: name, avatarURL: nil)
|
||||||
case let .heroes(users):
|
case let .heroes(users):
|
||||||
.heroes(users.map { .init(userID: $0.userID, displayName: $0.displayName, avatarURL: nil) })
|
.heroes(users.map { .init(userID: $0.id, displayName: $0.displayName, avatarURL: nil) })
|
||||||
case .space(let id, let name, _):
|
case .space(let id, let name, _):
|
||||||
.space(id: id, name: name, avatarURL: nil)
|
.space(id: id, name: name, avatarURL: nil)
|
||||||
case .tombstoned:
|
case .tombstoned:
|
||||||
@@ -76,7 +76,7 @@ struct RoomAvatarImage: View {
|
|||||||
ZStack {
|
ZStack {
|
||||||
LoadableAvatarImage(url: users[0].avatarURL,
|
LoadableAvatarImage(url: users[0].avatarURL,
|
||||||
name: users[0].displayName,
|
name: users[0].displayName,
|
||||||
contentID: users[0].userID,
|
contentID: users[0].id,
|
||||||
avatarSize: avatarSize,
|
avatarSize: avatarSize,
|
||||||
mediaProvider: mediaProvider,
|
mediaProvider: mediaProvider,
|
||||||
onTap: onAvatarTap)
|
onTap: onAvatarTap)
|
||||||
@@ -84,7 +84,7 @@ struct RoomAvatarImage: View {
|
|||||||
|
|
||||||
LoadableAvatarImage(url: users[1].avatarURL,
|
LoadableAvatarImage(url: users[1].avatarURL,
|
||||||
name: users[1].displayName,
|
name: users[1].displayName,
|
||||||
contentID: users[1].userID,
|
contentID: users[1].id,
|
||||||
avatarSize: avatarSize,
|
avatarSize: avatarSize,
|
||||||
mediaProvider: mediaProvider,
|
mediaProvider: mediaProvider,
|
||||||
onTap: onAvatarTap)
|
onTap: onAvatarTap)
|
||||||
@@ -107,7 +107,7 @@ struct RoomAvatarImage: View {
|
|||||||
} else {
|
} else {
|
||||||
LoadableAvatarImage(url: users[0].avatarURL,
|
LoadableAvatarImage(url: users[0].avatarURL,
|
||||||
name: users[0].displayName,
|
name: users[0].displayName,
|
||||||
contentID: users[0].userID,
|
contentID: users[0].id,
|
||||||
avatarSize: avatarSize,
|
avatarSize: avatarSize,
|
||||||
mediaProvider: mediaProvider,
|
mediaProvider: mediaProvider,
|
||||||
onTap: onAvatarTap)
|
onTap: onAvatarTap)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import MatrixRustSDK
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct UserProfileListRow: View {
|
struct UserProfileListRow: View {
|
||||||
let user: UserProfileProxy
|
let user: UserProfile
|
||||||
let membership: MembershipState?
|
let membership: MembershipState?
|
||||||
let mediaProvider: MediaProviderProtocol?
|
let mediaProvider: MediaProviderProtocol?
|
||||||
|
|
||||||
@@ -27,14 +27,14 @@ struct UserProfileListRow: View {
|
|||||||
if let membershipText = membership?.localizedDescription {
|
if let membershipText = membership?.localizedDescription {
|
||||||
return membershipText
|
return membershipText
|
||||||
} else if user.displayName != nil {
|
} else if user.displayName != nil {
|
||||||
return user.userID
|
return user.id
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ListRow(label: .avatar(title: user.displayName ?? user.userID,
|
ListRow(label: .avatar(title: user.displayName ?? user.id,
|
||||||
description: subtitle,
|
description: subtitle,
|
||||||
icon: avatar,
|
icon: avatar,
|
||||||
role: isUnknownProfile ? .error : nil),
|
role: isUnknownProfile ? .error : nil),
|
||||||
@@ -44,7 +44,7 @@ struct UserProfileListRow: View {
|
|||||||
var avatar: LoadableAvatarImage {
|
var avatar: LoadableAvatarImage {
|
||||||
LoadableAvatarImage(url: user.avatarURL,
|
LoadableAvatarImage(url: user.avatarURL,
|
||||||
name: user.displayName,
|
name: user.displayName,
|
||||||
contentID: user.userID,
|
contentID: user.id,
|
||||||
avatarSize: .user(on: .startChat),
|
avatarSize: .user(on: .startChat),
|
||||||
mediaProvider: mediaProvider)
|
mediaProvider: mediaProvider)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct BlockedUsersScreenViewState: BindableState {
|
struct BlockedUsersScreenViewState: BindableState {
|
||||||
var blockedUsers: [UserProfileProxy]
|
var blockedUsers: [UserProfile]
|
||||||
var processingUserID: String?
|
var processingUserID: String?
|
||||||
|
|
||||||
var bindings = BlockedUsersScreenViewStateBindings()
|
var bindings = BlockedUsersScreenViewStateBindings()
|
||||||
@@ -20,7 +20,7 @@ struct BlockedUsersScreenViewStateBindings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum BlockedUsersScreenViewAction {
|
enum BlockedUsersScreenViewAction {
|
||||||
case unblockUser(UserProfileProxy)
|
case unblockUser(UserProfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BlockedUsersScreenViewStateAlertType: Hashable {
|
enum BlockedUsersScreenViewStateAlertType: Hashable {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class BlockedUsersScreenViewModel: BlockedUsersScreenViewModelType, BlockedUsers
|
|||||||
clientProxy = userSession.clientProxy
|
clientProxy = userSession.clientProxy
|
||||||
self.userIndicatorController = userIndicatorController
|
self.userIndicatorController = userIndicatorController
|
||||||
|
|
||||||
let ignoredUsers = clientProxy.ignoredUsersPublisher.value?.map { UserProfileProxy(userID: $0) }
|
let ignoredUsers = clientProxy.ignoredUsersPublisher.value?.map { UserProfile(userID: $0) }
|
||||||
|
|
||||||
super.init(initialViewState: BlockedUsersScreenViewState(blockedUsers: ignoredUsers ?? []),
|
super.init(initialViewState: BlockedUsersScreenViewState(blockedUsers: ignoredUsers ?? []),
|
||||||
mediaProvider: userSession.mediaProvider)
|
mediaProvider: userSession.mediaProvider)
|
||||||
@@ -64,16 +64,16 @@ class BlockedUsersScreenViewModel: BlockedUsersScreenViewModelType, BlockedUsers
|
|||||||
defer { hideLoadingIndicator() }
|
defer { hideLoadingIndicator() }
|
||||||
|
|
||||||
if hideProfiles {
|
if hideProfiles {
|
||||||
state.blockedUsers = blockedUsers.map { UserProfileProxy(userID: $0) }
|
state.blockedUsers = blockedUsers.map { UserProfile(userID: $0) }
|
||||||
} else {
|
} else {
|
||||||
state.blockedUsers = await withTaskGroup(of: UserProfileProxy.self) { group in
|
state.blockedUsers = await withTaskGroup(of: UserProfile.self) { group in
|
||||||
for userID in blockedUsers {
|
for userID in blockedUsers {
|
||||||
group.addTask {
|
group.addTask {
|
||||||
await self.profile(for: userID)
|
await self.profile(for: userID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var profiles = [UserProfileProxy]()
|
var profiles = [UserProfile]()
|
||||||
for await profile in group {
|
for await profile in group {
|
||||||
profiles.append(profile)
|
profiles.append(profile)
|
||||||
}
|
}
|
||||||
@@ -84,19 +84,19 @@ class BlockedUsersScreenViewModel: BlockedUsersScreenViewModelType, BlockedUsers
|
|||||||
|
|
||||||
/// The client proxy isn't Sendable, fetch through this helper so that it
|
/// The client proxy isn't Sendable, fetch through this helper so that it
|
||||||
/// never leaves the main actor when running calls in parallel.
|
/// never leaves the main actor when running calls in parallel.
|
||||||
private func profile(for userID: String) async -> UserProfileProxy {
|
private func profile(for userID: String) async -> UserProfile {
|
||||||
switch await clientProxy.profile(for: userID) {
|
switch await clientProxy.profile(for: userID) {
|
||||||
case .success(let profile): profile
|
case .success(let profile): profile
|
||||||
case .failure: UserProfileProxy(userID: userID)
|
case .failure: UserProfile(userID: userID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func unblockUser(_ user: UserProfileProxy) {
|
private func unblockUser(_ user: UserProfile) {
|
||||||
showLoadingIndicator()
|
showLoadingIndicator()
|
||||||
state.processingUserID = user.userID
|
state.processingUserID = user.id
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
if case .failure = await clientProxy.unignoreUser(user.userID) {
|
if case .failure = await clientProxy.unignoreUser(user.id) {
|
||||||
state.bindings.alertInfo = .init(id: .error)
|
state.bindings.alertInfo = .init(id: .error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,20 +33,20 @@ struct BlockedUsersScreen: View {
|
|||||||
} else {
|
} else {
|
||||||
Form {
|
Form {
|
||||||
ForEach(context.viewState.blockedUsers, id: \.self) { user in
|
ForEach(context.viewState.blockedUsers, id: \.self) { user in
|
||||||
ListRow(label: .avatar(title: user.displayName ?? user.userID,
|
ListRow(label: .avatar(title: user.displayName ?? user.id,
|
||||||
description: user.displayName != nil ? user.userID : nil,
|
description: user.displayName != nil ? user.id : nil,
|
||||||
icon: avatar(for: user)),
|
icon: avatar(for: user)),
|
||||||
details: .isWaiting(context.viewState.processingUserID == user.userID),
|
details: .isWaiting(context.viewState.processingUserID == user.id),
|
||||||
kind: .button { context.send(viewAction: .unblockUser(user)) })
|
kind: .button { context.send(viewAction: .unblockUser(user)) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func avatar(for user: UserProfileProxy) -> some View {
|
private func avatar(for user: UserProfile) -> some View {
|
||||||
LoadableAvatarImage(url: user.avatarURL,
|
LoadableAvatarImage(url: user.avatarURL,
|
||||||
name: user.displayName,
|
name: user.displayName,
|
||||||
contentID: user.userID,
|
contentID: user.id,
|
||||||
avatarSize: .user(on: .blockedUsers),
|
avatarSize: .user(on: .blockedUsers),
|
||||||
mediaProvider: context.mediaProvider)
|
mediaProvider: context.mediaProvider)
|
||||||
.accessibilityHidden(true)
|
.accessibilityHidden(true)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ enum InviteUsersScreenViewModelAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum InviteUsersScreenRoomType {
|
enum InviteUsersScreenRoomType {
|
||||||
case draft(mandatoryInvitees: [UserProfileProxy])
|
case draft(mandatoryInvitees: [UserProfile])
|
||||||
case existingRoom(roomProxy: JoinedRoomProxyProtocol)
|
case existingRoom(roomProxy: JoinedRoomProxyProtocol)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,10 +29,10 @@ struct InviteUsersScreenViewState: BindableState {
|
|||||||
|
|
||||||
var usersSection: UserDiscoverySection = .init(type: .suggestions, users: [])
|
var usersSection: UserDiscoverySection = .init(type: .suggestions, users: [])
|
||||||
|
|
||||||
var selectedUsers: [UserProfileProxy] = []
|
var selectedUsers: [UserProfile] = []
|
||||||
var mandatoryInvitees: [UserProfileProxy] = []
|
var mandatoryInvitees: [UserProfile] = []
|
||||||
var membershipState: [String: MembershipState] = .init()
|
var membershipState: [String: MembershipState] = .init()
|
||||||
var usersToConfirm: [UserProfileProxy] = []
|
var usersToConfirm: [UserProfile] = []
|
||||||
|
|
||||||
var isSearching = false
|
var isSearching = false
|
||||||
|
|
||||||
@@ -44,11 +44,11 @@ struct InviteUsersScreenViewState: BindableState {
|
|||||||
selectedUsers.contains { !isInviteeMandatory($0) }
|
selectedUsers.contains { !isInviteeMandatory($0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
func isUserSelected(_ user: UserProfileProxy) -> Bool {
|
func isUserSelected(_ user: UserProfile) -> Bool {
|
||||||
isUserDisabled(user) || selectedUsers.contains { $0.userID == user.userID }
|
isUserDisabled(user) || selectedUsers.contains { $0.id == user.id }
|
||||||
}
|
}
|
||||||
|
|
||||||
func isUserDisabled(_ user: UserProfileProxy) -> Bool {
|
func isUserDisabled(_ user: UserProfile) -> Bool {
|
||||||
if isInviteeMandatory(user) {
|
if isInviteeMandatory(user) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -56,12 +56,12 @@ struct InviteUsersScreenViewState: BindableState {
|
|||||||
return membershipState == .invite || membershipState == .join
|
return membershipState == .invite || membershipState == .join
|
||||||
}
|
}
|
||||||
|
|
||||||
func isInviteeMandatory(_ user: UserProfileProxy) -> Bool {
|
func isInviteeMandatory(_ user: UserProfile) -> Bool {
|
||||||
mandatoryInvitees.contains { $0.userID == user.userID }
|
mandatoryInvitees.contains { $0.id == user.id }
|
||||||
}
|
}
|
||||||
|
|
||||||
func membershipState(_ user: UserProfileProxy) -> MembershipState? {
|
func membershipState(_ user: UserProfile) -> MembershipState? {
|
||||||
membershipState[user.userID]
|
membershipState[user.id]
|
||||||
}
|
}
|
||||||
|
|
||||||
let isSkippable: Bool
|
let isSkippable: Bool
|
||||||
@@ -83,5 +83,5 @@ enum InviteUsersScreenViewAction {
|
|||||||
case proceed
|
case proceed
|
||||||
case removeUnknownUsers
|
case removeUnknownUsers
|
||||||
case confirmUnknownUsers
|
case confirmUnknownUsers
|
||||||
case toggleUser(UserProfileProxy)
|
case toggleUser(UserProfile)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class InviteUsersScreenViewModel: InviteUsersScreenViewModelType, InviteUsersScr
|
|||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
|
|
||||||
private var suggestedUsers = [UserProfileProxy]()
|
private var suggestedUsers = [UserProfile]()
|
||||||
|
|
||||||
private let actionsSubject: PassthroughSubject<InviteUsersScreenViewModelAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<InviteUsersScreenViewModelAction, Never> = .init()
|
||||||
var actions: AnyPublisher<InviteUsersScreenViewModelAction, Never> {
|
var actions: AnyPublisher<InviteUsersScreenViewModelAction, Never> {
|
||||||
@@ -38,7 +38,7 @@ class InviteUsersScreenViewModel: InviteUsersScreenViewModelType, InviteUsersScr
|
|||||||
self.userIndicatorController = userIndicatorController
|
self.userIndicatorController = userIndicatorController
|
||||||
self.appSettings = appSettings
|
self.appSettings = appSettings
|
||||||
|
|
||||||
let mandatoryInvitees: [UserProfileProxy] = if case .draft(let invitees) = roomType {
|
let mandatoryInvitees: [UserProfile] = if case .draft(let invitees) = roomType {
|
||||||
invitees
|
invitees
|
||||||
} else {
|
} else {
|
||||||
[]
|
[]
|
||||||
@@ -70,12 +70,12 @@ class InviteUsersScreenViewModel: InviteUsersScreenViewModelType, InviteUsersScr
|
|||||||
case .proceed:
|
case .proceed:
|
||||||
switch roomType {
|
switch roomType {
|
||||||
case .draft:
|
case .draft:
|
||||||
createDraftRoom(mandatoryUserIDs: state.selectedUsers.map(\.userID))
|
createDraftRoom(mandatoryUserIDs: state.selectedUsers.map(\.id))
|
||||||
case .existingRoom(let roomProxy):
|
case .existingRoom(let roomProxy):
|
||||||
guard roomProxy.details.historySharingState != RoomHistorySharingState.hidden,
|
guard roomProxy.details.historySharingState != RoomHistorySharingState.hidden,
|
||||||
!state.usersToConfirm.isEmpty,
|
!state.usersToConfirm.isEmpty,
|
||||||
!state.isSkippable else {
|
!state.isSkippable else {
|
||||||
inviteUsers(state.selectedUsers.map(\.userID), roomProxy: roomProxy)
|
inviteUsers(state.selectedUsers.map(\.id), roomProxy: roomProxy)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
state.bindings.presentConfirmationDialog = true
|
state.bindings.presentConfirmationDialog = true
|
||||||
@@ -83,14 +83,14 @@ class InviteUsersScreenViewModel: InviteUsersScreenViewModelType, InviteUsersScr
|
|||||||
case .removeUnknownUsers:
|
case .removeUnknownUsers:
|
||||||
state.bindings.presentConfirmationDialog = false
|
state.bindings.presentConfirmationDialog = false
|
||||||
state.selectedUsers.removeAll { user in
|
state.selectedUsers.removeAll { user in
|
||||||
state.usersToConfirm.contains { $0.userID == user.userID }
|
state.usersToConfirm.contains { $0.id == user.id }
|
||||||
}
|
}
|
||||||
state.usersToConfirm = []
|
state.usersToConfirm = []
|
||||||
case .confirmUnknownUsers:
|
case .confirmUnknownUsers:
|
||||||
state.bindings.presentConfirmationDialog = false
|
state.bindings.presentConfirmationDialog = false
|
||||||
state.usersToConfirm = []
|
state.usersToConfirm = []
|
||||||
if case .existingRoom(let roomProxy) = roomType {
|
if case .existingRoom(let roomProxy) = roomType {
|
||||||
inviteUsers(state.selectedUsers.map(\.userID), roomProxy: roomProxy)
|
inviteUsers(state.selectedUsers.map(\.id), roomProxy: roomProxy)
|
||||||
}
|
}
|
||||||
case .toggleUser(let user):
|
case .toggleUser(let user):
|
||||||
toggleUser(user)
|
toggleUser(user)
|
||||||
@@ -99,16 +99,16 @@ class InviteUsersScreenViewModel: InviteUsersScreenViewModelType, InviteUsersScr
|
|||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func toggleUser(_ user: UserProfileProxy) {
|
private func toggleUser(_ user: UserProfile) {
|
||||||
guard !state.isInviteeMandatory(user) else { return }
|
guard !state.isInviteeMandatory(user) else { return }
|
||||||
|
|
||||||
if state.selectedUsers.contains(user) {
|
if state.selectedUsers.contains(user) {
|
||||||
state.selectedUsers.removeAll { $0.userID == user.userID }
|
state.selectedUsers.removeAll { $0.id == user.id }
|
||||||
} else {
|
} else {
|
||||||
state.selectedUsers.append(user)
|
state.selectedUsers.append(user)
|
||||||
withElementAnimation(.easeInOut) { state.bindings.selectedUsersPosition = user.userID }
|
withElementAnimation(.easeInOut) { state.bindings.selectedUsersPosition = user.id }
|
||||||
Task {
|
Task {
|
||||||
let identityUnknown = if case .success(let identity) = await self.clientProxy.userIdentity(for: user.userID, fallBackToServer: false) {
|
let identityUnknown = if case .success(let identity) = await self.clientProxy.userIdentity(for: user.id, fallBackToServer: false) {
|
||||||
identity == nil
|
identity == nil
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
|||||||
+2
-2
@@ -12,7 +12,7 @@ struct InviteUsersConfirmationSheetView: View {
|
|||||||
@ObservedObject var context: InviteUsersScreenViewModel.Context
|
@ObservedObject var context: InviteUsersScreenViewModel.Context
|
||||||
|
|
||||||
/// The users whose identities we wish the user to confirm.
|
/// The users whose identities we wish the user to confirm.
|
||||||
var users: [UserProfileProxy]
|
var users: [UserProfile]
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
FullscreenDialog(topPadding: 24, horizontalPadding: 24) {
|
FullscreenDialog(topPadding: 24, horizontalPadding: 24) {
|
||||||
@@ -22,7 +22,7 @@ struct InviteUsersConfirmationSheetView: View {
|
|||||||
icon: \.userAddSolid,
|
icon: \.userAddSolid,
|
||||||
iconStyle: .defaultSolid)
|
iconStyle: .defaultSolid)
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
ForEach(users, id: \.userID) { user in
|
ForEach(users, id: \.id) { user in
|
||||||
UserProfileListRow(user: user,
|
UserProfileListRow(user: user,
|
||||||
membership: nil,
|
membership: nil,
|
||||||
mediaProvider: context.mediaProvider,
|
mediaProvider: context.mediaProvider,
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ struct InviteUsersScreen: View {
|
|||||||
private var usersSection: some View {
|
private var usersSection: some View {
|
||||||
if !context.viewState.usersSection.users.isEmpty {
|
if !context.viewState.usersSection.users.isEmpty {
|
||||||
Section {
|
Section {
|
||||||
ForEach(context.viewState.usersSection.users, id: \.userID) { user in
|
ForEach(context.viewState.usersSection.users, id: \.id) { user in
|
||||||
UserProfileListRow(user: user,
|
UserProfileListRow(user: user,
|
||||||
membership: context.viewState.membershipState(user),
|
membership: context.viewState.membershipState(user),
|
||||||
mediaProvider: context.mediaProvider,
|
mediaProvider: context.mediaProvider,
|
||||||
@@ -109,7 +109,7 @@ struct InviteUsersScreen: View {
|
|||||||
private var selectedUsersSection: some View {
|
private var selectedUsersSection: some View {
|
||||||
ScrollView(.horizontal, showsIndicators: false) {
|
ScrollView(.horizontal, showsIndicators: false) {
|
||||||
HStack(spacing: 8) {
|
HStack(spacing: 8) {
|
||||||
ForEach(context.viewState.selectedUsers, id: \.userID) { user in
|
ForEach(context.viewState.selectedUsers, id: \.id) { user in
|
||||||
InviteUsersScreenSelectedItem(user: user,
|
InviteUsersScreenSelectedItem(user: user,
|
||||||
mediaProvider: context.mediaProvider,
|
mediaProvider: context.mediaProvider,
|
||||||
isLocked: context.viewState.isInviteeMandatory(user)) {
|
isLocked: context.viewState.isInviteeMandatory(user)) {
|
||||||
@@ -150,7 +150,7 @@ struct InviteUsersScreen: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func deselect(_ user: UserProfileProxy) {
|
private func deselect(_ user: UserProfile) {
|
||||||
context.send(viewAction: .toggleUser(user))
|
context.send(viewAction: .toggleUser(user))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import Compound
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct InviteUsersScreenSelectedItem: View {
|
struct InviteUsersScreenSelectedItem: View {
|
||||||
let user: UserProfileProxy
|
let user: UserProfile
|
||||||
let mediaProvider: MediaProviderProtocol?
|
let mediaProvider: MediaProviderProtocol?
|
||||||
var isLocked = false
|
var isLocked = false
|
||||||
let dismissAction: () -> Void
|
let dismissAction: () -> Void
|
||||||
@@ -20,7 +20,7 @@ struct InviteUsersScreenSelectedItem: View {
|
|||||||
avatar
|
avatar
|
||||||
.accessibilityHidden(true)
|
.accessibilityHidden(true)
|
||||||
|
|
||||||
Text(user.displayName ?? user.userID)
|
Text(user.displayName ?? user.id)
|
||||||
.font(.compound.bodySM)
|
.font(.compound.bodySM)
|
||||||
.foregroundColor(.compound.textSecondary)
|
.foregroundColor(.compound.textSecondary)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
@@ -39,7 +39,7 @@ struct InviteUsersScreenSelectedItem: View {
|
|||||||
var avatar: some View {
|
var avatar: some View {
|
||||||
let avatarImage = LoadableAvatarImage(url: user.avatarURL,
|
let avatarImage = LoadableAvatarImage(url: user.avatarURL,
|
||||||
name: user.displayName,
|
name: user.displayName,
|
||||||
contentID: user.userID,
|
contentID: user.id,
|
||||||
avatarSize: .user(on: .inviteUsers),
|
avatarSize: .user(on: .inviteUsers),
|
||||||
mediaProvider: mediaProvider)
|
mediaProvider: mediaProvider)
|
||||||
if isLocked {
|
if isLocked {
|
||||||
@@ -58,12 +58,12 @@ struct InviteUsersScreenSelectedItem: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct InviteUsersScreenSelectedItem_Previews: PreviewProvider, TestablePreview {
|
struct InviteUsersScreenSelectedItem_Previews: PreviewProvider, TestablePreview {
|
||||||
static let people: [UserProfileProxy] = [.mockAlice, .mockVerbose]
|
static let people: [UserProfile] = [.mockAlice, .mockVerbose]
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
ScrollView(.horizontal) {
|
ScrollView(.horizontal) {
|
||||||
HStack(spacing: 8) {
|
HStack(spacing: 8) {
|
||||||
ForEach(people, id: \.userID) { user in
|
ForEach(people, id: \.id) { user in
|
||||||
InviteUsersScreenSelectedItem(user: user, mediaProvider: MediaProviderMock(.init())) { }
|
InviteUsersScreenSelectedItem(user: user, mediaProvider: MediaProviderMock(.init())) { }
|
||||||
.frame(width: 80)
|
.frame(width: 80)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ struct JoinRoomScreenRoomDetails {
|
|||||||
let canonicalAlias: String?
|
let canonicalAlias: String?
|
||||||
let avatar: RoomAvatar?
|
let avatar: RoomAvatar?
|
||||||
let memberCount: Int?
|
let memberCount: Int?
|
||||||
let heroes: [UserProfileProxy]
|
let heroes: [UserProfile]
|
||||||
let inviter: RoomInviterDetails?
|
let inviter: RoomInviterDetails?
|
||||||
let isDirect: Bool?
|
let isDirect: Bool?
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ struct LocationSharingScreenViewState: BindableState {
|
|||||||
self.mapURLBuilder = mapURLBuilder
|
self.mapURLBuilder = mapURLBuilder
|
||||||
self.ownUserID = ownUserID
|
self.ownUserID = ownUserID
|
||||||
|
|
||||||
let initialProfile: UserProfileProxy = switch interactionMode {
|
let initialProfile: UserProfile = switch interactionMode {
|
||||||
case .viewStatic(let locationData):
|
case .viewStatic(let locationData):
|
||||||
.init(sender: locationData.sender)
|
.init(sender: locationData.sender)
|
||||||
case .viewLive(let sender, _):
|
case .viewLive(let sender, _):
|
||||||
@@ -64,7 +64,7 @@ struct LocationSharingScreenViewState: BindableState {
|
|||||||
case .picker:
|
case .picker:
|
||||||
.init(userID: ownUserID)
|
.init(userID: ownUserID)
|
||||||
}
|
}
|
||||||
userProfiles = [initialProfile.userID: initialProfile]
|
userProfiles = [initialProfile.id: initialProfile]
|
||||||
|
|
||||||
if case .viewLive(_, let initialLiveLocationShare) = interactionMode, let initialLiveLocationShare {
|
if case .viewLive(_, let initialLiveLocationShare) = interactionMode, let initialLiveLocationShare {
|
||||||
liveLocationShares = [initialLiveLocationShare]
|
liveLocationShares = [initialLiveLocationShare]
|
||||||
@@ -79,7 +79,7 @@ struct LocationSharingScreenViewState: BindableState {
|
|||||||
let interactionMode: LocationSharingInteractionMode
|
let interactionMode: LocationSharingInteractionMode
|
||||||
let mapURLBuilder: MapTilerURLBuilderProtocol
|
let mapURLBuilder: MapTilerURLBuilderProtocol
|
||||||
let ownUserID: String
|
let ownUserID: String
|
||||||
var userProfiles: [String: UserProfileProxy]
|
var userProfiles: [String: UserProfile]
|
||||||
var liveLocationShares: [LiveLocationShare] = []
|
var liveLocationShares: [LiveLocationShare] = []
|
||||||
var isStoppingLiveLocation = false
|
var isStoppingLiveLocation = false
|
||||||
/// Whether this device has an active live location sharing session in the room.
|
/// Whether this device has an active live location sharing session in the room.
|
||||||
@@ -103,10 +103,10 @@ struct LocationSharingScreenViewState: BindableState {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
let profile = userProfiles[share.userID] ?? UserProfileProxy(userID: share.userID)
|
let profile = userProfiles[share.userID] ?? UserProfile(userID: share.userID)
|
||||||
let kind = LocationMarkerKind.liveUser(profile)
|
let kind = LocationMarkerKind.liveUser(profile)
|
||||||
let coordinate = CLLocationCoordinate2D(latitude: geoURI.latitude, longitude: geoURI.longitude)
|
let coordinate = CLLocationCoordinate2D(latitude: geoURI.latitude, longitude: geoURI.longitude)
|
||||||
return LocationAnnotation(id: profile.userID, coordinate: coordinate, kind: kind)
|
return LocationAnnotation(id: profile.id, coordinate: coordinate, kind: kind)
|
||||||
}
|
}
|
||||||
case .picker:
|
case .picker:
|
||||||
return []
|
return []
|
||||||
@@ -287,8 +287,8 @@ extension AlertInfo where T == LocationSharingViewAlert {
|
|||||||
|
|
||||||
enum LocationMarkerKind: Equatable {
|
enum LocationMarkerKind: Equatable {
|
||||||
case pin
|
case pin
|
||||||
case staticUser(UserProfileProxy)
|
case staticUser(UserProfile)
|
||||||
case liveUser(UserProfileProxy)
|
case liveUser(UserProfile)
|
||||||
case placeholder
|
case placeholder
|
||||||
|
|
||||||
var id: String {
|
var id: String {
|
||||||
@@ -296,7 +296,7 @@ enum LocationMarkerKind: Equatable {
|
|||||||
case .pin, .placeholder:
|
case .pin, .placeholder:
|
||||||
UUID().uuidString
|
UUID().uuidString
|
||||||
case .staticUser(let profile), .liveUser(let profile):
|
case .staticUser(let profile), .liveUser(let profile):
|
||||||
profile.userID
|
profile.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +309,7 @@ enum LocationMarkerKind: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var userProfile: UserProfileProxy? {
|
var userProfile: UserProfile? {
|
||||||
switch self {
|
switch self {
|
||||||
case .pin, .placeholder:
|
case .pin, .placeholder:
|
||||||
nil
|
nil
|
||||||
|
|||||||
@@ -194,11 +194,11 @@ class LocationSharingScreenViewModel: LocationSharingScreenViewModelType, Locati
|
|||||||
private func updateUserProfiles(members: [RoomMemberProxyProtocol]) {
|
private func updateUserProfiles(members: [RoomMemberProxyProtocol]) {
|
||||||
switch state.interactionMode {
|
switch state.interactionMode {
|
||||||
case .picker:
|
case .picker:
|
||||||
let ownUser = members.first { $0.userID == roomProxy.ownUserID }.map(UserProfileProxy.init) ?? .init(userID: roomProxy.ownUserID)
|
let ownUser = members.first { $0.userID == roomProxy.ownUserID }.map(UserProfile.init) ?? .init(userID: roomProxy.ownUserID)
|
||||||
state.userProfiles = [ownUser.userID: ownUser]
|
state.userProfiles = [ownUser.id: ownUser]
|
||||||
case .viewStatic(let location):
|
case .viewStatic(let location):
|
||||||
let sender = members.first { $0.userID == location.sender.id }.map(UserProfileProxy.init) ?? .init(sender: location.sender)
|
let sender = members.first { $0.userID == location.sender.id }.map(UserProfile.init) ?? .init(sender: location.sender)
|
||||||
state.userProfiles = [sender.userID: sender]
|
state.userProfiles = [sender.id: sender]
|
||||||
case .viewLive(let sender, _):
|
case .viewLive(let sender, _):
|
||||||
var userIDs = Set(state.liveLocationShares.map(\.userID))
|
var userIDs = Set(state.liveLocationShares.map(\.userID))
|
||||||
if let senderID = sender?.id {
|
if let senderID = sender?.id {
|
||||||
@@ -206,9 +206,9 @@ class LocationSharingScreenViewModel: LocationSharingScreenViewModelType, Locati
|
|||||||
}
|
}
|
||||||
state.userProfiles = userIDs.reduce(into: [:]) { dict, userID in
|
state.userProfiles = userIDs.reduce(into: [:]) { dict, userID in
|
||||||
if let member = members.first(where: { $0.userID == userID }) {
|
if let member = members.first(where: { $0.userID == userID }) {
|
||||||
dict[userID] = UserProfileProxy(member: member)
|
dict[userID] = UserProfile(member: member)
|
||||||
} else {
|
} else {
|
||||||
dict[userID] = UserProfileProxy(userID: userID)
|
dict[userID] = UserProfile(userID: userID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ struct LocationShareSheet: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var senderName: String? {
|
private var senderName: String? {
|
||||||
annotation.kind.displayName ?? annotation.kind.userProfile?.userID
|
annotation.kind.displayName ?? annotation.kind.userProfile?.id
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -40,8 +40,8 @@ struct LocationShareSheet: View {
|
|||||||
// MARK: - Previews
|
// MARK: - Previews
|
||||||
|
|
||||||
struct LocationShareSheet_Previews: PreviewProvider {
|
struct LocationShareSheet_Previews: PreviewProvider {
|
||||||
static let profile = UserProfileProxy(userID: "@alice:example.com", displayName: "Alice")
|
static let profile = UserProfile(userID: "@alice:example.com", displayName: "Alice")
|
||||||
static let annotation = LocationAnnotation(id: profile.userID,
|
static let annotation = LocationAnnotation(id: profile.id,
|
||||||
coordinate: .init(latitude: 51.509865, longitude: -0.118092),
|
coordinate: .init(latitude: 51.509865, longitude: -0.118092),
|
||||||
kind: .liveUser(profile))
|
kind: .liveUser(profile))
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ struct StaticLocationSheet: View {
|
|||||||
longitude: location.geoURI.longitude)))
|
longitude: location.geoURI.longitude)))
|
||||||
} label: {
|
} label: {
|
||||||
UserLocationCell(profile: profile,
|
UserLocationCell(profile: profile,
|
||||||
isOwnUser: context.viewState.isOwnUser(profile.userID),
|
isOwnUser: context.viewState.isOwnUser(profile.id),
|
||||||
kind: .static(isUserLocation: location.kind == .sender,
|
kind: .static(isUserLocation: location.kind == .sender,
|
||||||
timestamp: location.timestamp),
|
timestamp: location.timestamp),
|
||||||
mediaProvider: context.mediaProvider,
|
mediaProvider: context.mediaProvider,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import Compound
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct UserLocationCell: View {
|
struct UserLocationCell: View {
|
||||||
let profile: UserProfileProxy
|
let profile: UserProfile
|
||||||
let isOwnUser: Bool
|
let isOwnUser: Bool
|
||||||
let kind: Kind
|
let kind: Kind
|
||||||
var mediaProvider: MediaProviderProtocol?
|
var mediaProvider: MediaProviderProtocol?
|
||||||
@@ -23,7 +23,7 @@ struct UserLocationCell: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var name: String {
|
private var name: String {
|
||||||
isOwnUser ? L10n.commonYou : profile.displayName ?? profile.userID
|
isOwnUser ? L10n.commonYou : profile.displayName ?? profile.id
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
|||||||
+7
-7
@@ -30,18 +30,18 @@ struct SessionVerificationRequestDetailsView: View {
|
|||||||
HStack(spacing: 12) {
|
HStack(spacing: 12) {
|
||||||
LoadableAvatarImage(url: details.senderProfile.avatarURL,
|
LoadableAvatarImage(url: details.senderProfile.avatarURL,
|
||||||
name: details.senderProfile.displayName,
|
name: details.senderProfile.displayName,
|
||||||
contentID: details.senderProfile.userID,
|
contentID: details.senderProfile.id,
|
||||||
avatarSize: .user(on: .sessionVerification),
|
avatarSize: .user(on: .sessionVerification),
|
||||||
mediaProvider: mediaProvider)
|
mediaProvider: mediaProvider)
|
||||||
.accessibilityHidden(true)
|
.accessibilityHidden(true)
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
Text(details.senderProfile.displayName ?? details.senderProfile.userID)
|
Text(details.senderProfile.displayName ?? details.senderProfile.id)
|
||||||
.font(.compound.bodySM)
|
.font(.compound.bodySM)
|
||||||
.foregroundColor(.compound.textSecondary)
|
.foregroundColor(.compound.textSecondary)
|
||||||
|
|
||||||
if details.senderProfile.displayName != nil {
|
if details.senderProfile.displayName != nil {
|
||||||
Text(details.senderProfile.userID)
|
Text(details.senderProfile.id)
|
||||||
.font(.compound.bodyMD)
|
.font(.compound.bodyMD)
|
||||||
.foregroundColor(.compound.textPrimary)
|
.foregroundColor(.compound.textPrimary)
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ struct SessionVerificationRequestDetailsView: View {
|
|||||||
.clipShape(RoundedRectangle(cornerRadius: 8))
|
.clipShape(RoundedRectangle(cornerRadius: 8))
|
||||||
|
|
||||||
let displayName = isUserVerification ? details.senderProfile.displayName : details.deviceDisplayName
|
let displayName = isUserVerification ? details.senderProfile.displayName : details.deviceDisplayName
|
||||||
Text(displayName ?? details.senderProfile.userID)
|
Text(displayName ?? details.senderProfile.id)
|
||||||
.font(.compound.bodyMDSemibold)
|
.font(.compound.bodyMDSemibold)
|
||||||
.foregroundColor(.compound.textPrimary)
|
.foregroundColor(.compound.textPrimary)
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
@@ -110,9 +110,9 @@ struct SessionVerificationRequestDetailsView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct SessionVerificationRequestDetailsView_Previews: PreviewProvider, TestablePreview {
|
struct SessionVerificationRequestDetailsView_Previews: PreviewProvider, TestablePreview {
|
||||||
static let details = SessionVerificationRequestDetails(senderProfile: UserProfileProxy(userID: "@bob:matrix.org",
|
static let details = SessionVerificationRequestDetails(senderProfile: UserProfile(userID: "@bob:matrix.org",
|
||||||
displayName: "Billy bob",
|
displayName: "Billy bob",
|
||||||
avatarURL: .mockMXCUserAvatar),
|
avatarURL: .mockMXCUserAvatar),
|
||||||
flowID: "123",
|
flowID: "123",
|
||||||
deviceID: "CODEMISTAKE",
|
deviceID: "CODEMISTAKE",
|
||||||
deviceDisplayName: "Bob's Element X iOS",
|
deviceDisplayName: "Bob's Element X iOS",
|
||||||
|
|||||||
+3
-3
@@ -232,9 +232,9 @@ struct SessionVerification_Previews: PreviewProvider, TestablePreview {
|
|||||||
sessionVerificationScreen(state: .initial, flow: .userInitiator(userID: "@bob:matrix.org"))
|
sessionVerificationScreen(state: .initial, flow: .userInitiator(userID: "@bob:matrix.org"))
|
||||||
.previewDisplayName("Initial - User Initiator")
|
.previewDisplayName("Initial - User Initiator")
|
||||||
|
|
||||||
let details = SessionVerificationRequestDetails(senderProfile: UserProfileProxy(userID: "@bob:matrix.org",
|
let details = SessionVerificationRequestDetails(senderProfile: UserProfile(userID: "@bob:matrix.org",
|
||||||
displayName: "Billy Bob",
|
displayName: "Billy Bob",
|
||||||
avatarURL: .mockMXCUserAvatar),
|
avatarURL: .mockMXCUserAvatar),
|
||||||
flowID: "123",
|
flowID: "123",
|
||||||
deviceID: "CODEMISTAKE",
|
deviceID: "CODEMISTAKE",
|
||||||
deviceDisplayName: "Bob's Element X iOS",
|
deviceDisplayName: "Bob's Element X iOS",
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ enum RoomDetailsScreenCoordinatorAction {
|
|||||||
case presentRoomDetailsEditScreen
|
case presentRoomDetailsEditScreen
|
||||||
case presentNotificationSettingsScreen
|
case presentNotificationSettingsScreen
|
||||||
case presentInviteUsersScreen
|
case presentInviteUsersScreen
|
||||||
case presentInviteToNewRoom(invitee: UserProfileProxy)
|
case presentInviteToNewRoom(invitee: UserProfile)
|
||||||
case presentPollsHistory
|
case presentPollsHistory
|
||||||
case presentRolesAndPermissionsScreen
|
case presentRolesAndPermissionsScreen
|
||||||
case presentCall(isVoiceCall: Bool)
|
case presentCall(isVoiceCall: Bool)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ enum RoomDetailsScreenViewModelAction: Equatable {
|
|||||||
case requestMemberDetailsPresentation
|
case requestMemberDetailsPresentation
|
||||||
case requestRecipientDetailsPresentation(userID: String)
|
case requestRecipientDetailsPresentation(userID: String)
|
||||||
case requestInvitePeoplePresentation
|
case requestInvitePeoplePresentation
|
||||||
case requestInviteToNewRoomPresentation(selectedInvitee: UserProfileProxy)
|
case requestInviteToNewRoomPresentation(selectedInvitee: UserProfile)
|
||||||
case leftRoom
|
case leftRoom
|
||||||
case requestEditDetailsPresentation
|
case requestEditDetailsPresentation
|
||||||
case requestPollsHistoryPresentation
|
case requestPollsHistoryPresentation
|
||||||
|
|||||||
+1
-1
@@ -202,7 +202,7 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro
|
|||||||
} else if roomProxy.details.historySharingState != RoomHistorySharingState.hidden {
|
} else if roomProxy.details.historySharingState != RoomHistorySharingState.hidden {
|
||||||
Task {
|
Task {
|
||||||
let identity = await self.userSession.clientProxy.userIdentity(for: roomMemberProxy.userID, fallBackToServer: false)
|
let identity = await self.userSession.clientProxy.userIdentity(for: roomMemberProxy.userID, fallBackToServer: false)
|
||||||
let user: UserProfileProxy = .init(userID: roomMemberProxy.userID, displayName: roomMemberProxy.displayName, avatarURL: roomMemberProxy.avatarURL)
|
let user: UserProfile = .init(userID: roomMemberProxy.userID, displayName: roomMemberProxy.displayName, avatarURL: roomMemberProxy.avatarURL)
|
||||||
let isUnknown = if case .success(let identity) = identity {
|
let isUnknown = if case .success(let identity) = identity {
|
||||||
identity == nil
|
identity == nil
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ struct RoomMemberDetailsScreen: View {
|
|||||||
.padding(.top, 24)
|
.padding(.top, 24)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AvatarHeaderView(user: UserProfileProxy(userID: context.viewState.userID),
|
AvatarHeaderView(user: UserProfile(userID: context.viewState.userID),
|
||||||
isVerified: context.viewState.showVerifiedBadge,
|
isVerified: context.viewState.showVerifiedBadge,
|
||||||
avatarSize: .user(on: .memberDetails),
|
avatarSize: .user(on: .memberDetails),
|
||||||
mediaProvider: context.mediaProvider) { }
|
mediaProvider: context.mediaProvider) { }
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ class SearchScreenViewModel: SearchScreenViewModelType, SearchScreenViewModelPro
|
|||||||
// Show the matrix identifier as the subtitle: the other member's user ID for DMs,
|
// Show the matrix identifier as the subtitle: the other member's user ID for DMs,
|
||||||
// otherwise the room's canonical alias.
|
// otherwise the room's canonical alias.
|
||||||
let identifier = if summary.isDirect {
|
let identifier = if summary.isDirect {
|
||||||
summary.heroes.first?.userID ?? summary.canonicalAlias
|
summary.heroes.first?.id ?? summary.canonicalAlias
|
||||||
} else {
|
} else {
|
||||||
summary.canonicalAlias
|
summary.canonicalAlias
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ struct StartChatScreenViewStateBindings {
|
|||||||
enum StartChatScreenViewAction {
|
enum StartChatScreenViewAction {
|
||||||
case close
|
case close
|
||||||
case createRoom
|
case createRoom
|
||||||
case createDM(user: UserProfileProxy)
|
case createDM(user: UserProfile)
|
||||||
case selectUser(UserProfileProxy)
|
case selectUser(UserProfile)
|
||||||
case joinRoomByAddress
|
case joinRoomByAddress
|
||||||
case openRoomDirectorySearch
|
case openRoomDirectorySearch
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
|||||||
private let userDiscoveryService: UserDiscoveryServiceProtocol
|
private let userDiscoveryService: UserDiscoveryServiceProtocol
|
||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
|
|
||||||
private var suggestedUsers = [UserProfileProxy]()
|
private var suggestedUsers = [UserProfile]()
|
||||||
|
|
||||||
private let actionsSubject: PassthroughSubject<StartChatScreenViewModelAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<StartChatScreenViewModelAction, Never> = .init()
|
||||||
var actions: AnyPublisher<StartChatScreenViewModelAction, Never> {
|
var actions: AnyPublisher<StartChatScreenViewModelAction, Never> {
|
||||||
@@ -61,7 +61,7 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
|||||||
case .selectUser(let user):
|
case .selectUser(let user):
|
||||||
showLoadingIndicator(delay: .milliseconds(200))
|
showLoadingIndicator(delay: .milliseconds(200))
|
||||||
|
|
||||||
let currentDirectRoom = userSession.clientProxy.directRoomForUserID(user.userID)
|
let currentDirectRoom = userSession.clientProxy.directRoomForUserID(user.id)
|
||||||
switch currentDirectRoom {
|
switch currentDirectRoom {
|
||||||
case .success(.some(let roomId)):
|
case .success(.some(let roomId)):
|
||||||
hideLoadingIndicator()
|
hideLoadingIndicator()
|
||||||
@@ -69,7 +69,7 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
|||||||
case .success:
|
case .success:
|
||||||
Task {
|
Task {
|
||||||
// If an error occured while fetching the identity, assume they are unknown.
|
// If an error occured while fetching the identity, assume they are unknown.
|
||||||
let isUnknown = if case .success(let identity) = await self.userSession.clientProxy.userIdentity(for: user.userID, fallBackToServer: false) {
|
let isUnknown = if case .success(let identity) = await self.userSession.clientProxy.userIdentity(for: user.id, fallBackToServer: false) {
|
||||||
identity == nil
|
identity == nil
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
@@ -186,12 +186,12 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createDirectRoom(user: UserProfileProxy) async {
|
private func createDirectRoom(user: UserProfile) async {
|
||||||
defer {
|
defer {
|
||||||
hideLoadingIndicator()
|
hideLoadingIndicator()
|
||||||
}
|
}
|
||||||
showLoadingIndicator()
|
showLoadingIndicator()
|
||||||
switch await userSession.clientProxy.createDirectRoom(with: user.userID, expectedRoomName: user.displayName) {
|
switch await userSession.clientProxy.createDirectRoom(with: user.id, expectedRoomName: user.displayName) {
|
||||||
case .success(let roomId):
|
case .success(let roomId):
|
||||||
analytics.trackCreatedRoom(isDM: true)
|
analytics.trackCreatedRoom(isDM: true)
|
||||||
actionsSubject.send(.showRoom(roomID: roomId))
|
actionsSubject.send(.showRoom(roomID: roomId))
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ struct StartChatScreen: View {
|
|||||||
private var usersSection: some View {
|
private var usersSection: some View {
|
||||||
if !context.viewState.usersSection.users.isEmpty {
|
if !context.viewState.usersSection.users.isEmpty {
|
||||||
Section {
|
Section {
|
||||||
ForEach(context.viewState.usersSection.users, id: \.userID) { user in
|
ForEach(context.viewState.usersSection.users, id: \.id) { user in
|
||||||
UserProfileListRow(user: user,
|
UserProfileListRow(user: user,
|
||||||
membership: nil,
|
membership: nil,
|
||||||
mediaProvider: context.mediaProvider,
|
mediaProvider: context.mediaProvider,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ struct UserProfileScreenViewState: BindableState {
|
|||||||
let isOwnUser: Bool
|
let isOwnUser: Bool
|
||||||
let isPresentedModally: Bool
|
let isPresentedModally: Bool
|
||||||
|
|
||||||
var userProfile: UserProfileProxy?
|
var userProfile: UserProfile?
|
||||||
var isIdentityKnown = false
|
var isIdentityKnown = false
|
||||||
var isVerified: Bool?
|
var isVerified: Bool?
|
||||||
var permalink: URL?
|
var permalink: URL?
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr
|
|||||||
// The proxies aren't Sendable, fetch through these helpers so that
|
// The proxies aren't Sendable, fetch through these helpers so that
|
||||||
// they never leave the main actor when running calls in parallel.
|
// they never leave the main actor when running calls in parallel.
|
||||||
|
|
||||||
private func fetchProfile() async -> Result<UserProfileProxy, ClientProxyError> {
|
private func fetchProfile() async -> Result<UserProfile, ClientProxyError> {
|
||||||
await userSession.clientProxy.profile(for: state.userID)
|
await userSession.clientProxy.profile(for: state.userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr
|
|||||||
state.userProfile = userProfile
|
state.userProfile = userProfile
|
||||||
state.permalink = (try? matrixToUserPermalink(userId: state.userID)).flatMap(URL.init(string:))
|
state.permalink = (try? matrixToUserPermalink(userId: state.userID)).flatMap(URL.init(string:))
|
||||||
|
|
||||||
switch userSession.clientProxy.directRoomForUserID(userProfile.userID) {
|
switch userSession.clientProxy.directRoomForUserID(userProfile.id) {
|
||||||
case .success(let roomID):
|
case .success(let roomID):
|
||||||
state.dmRoomID = roomID
|
state.dmRoomID = roomID
|
||||||
case .failure:
|
case .failure:
|
||||||
@@ -133,13 +133,13 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr
|
|||||||
showLoadingIndicator(allowsInteraction: false)
|
showLoadingIndicator(allowsInteraction: false)
|
||||||
defer { hideLoadingIndicator() }
|
defer { hideLoadingIndicator() }
|
||||||
|
|
||||||
switch userSession.clientProxy.directRoomForUserID(userProfile.userID) {
|
switch userSession.clientProxy.directRoomForUserID(userProfile.id) {
|
||||||
case .success(let roomID):
|
case .success(let roomID):
|
||||||
if let roomID {
|
if let roomID {
|
||||||
actionsSubject.send(.openDirectChat(roomID: roomID))
|
actionsSubject.send(.openDirectChat(roomID: roomID))
|
||||||
} else {
|
} else {
|
||||||
Task {
|
Task {
|
||||||
let isUnknown = if case let .success(identity) = await userSession.clientProxy.userIdentity(for: userProfile.userID, fallBackToServer: false) {
|
let isUnknown = if case let .success(identity) = await userSession.clientProxy.userIdentity(for: userProfile.id, fallBackToServer: false) {
|
||||||
identity == nil
|
identity == nil
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
@@ -158,7 +158,7 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr
|
|||||||
showLoadingIndicator(allowsInteraction: false)
|
showLoadingIndicator(allowsInteraction: false)
|
||||||
defer { hideLoadingIndicator() }
|
defer { hideLoadingIndicator() }
|
||||||
|
|
||||||
switch await userSession.clientProxy.createDirectRoom(with: userProfile.userID, expectedRoomName: userProfile.displayName) {
|
switch await userSession.clientProxy.createDirectRoom(with: userProfile.id, expectedRoomName: userProfile.displayName) {
|
||||||
case .success(let roomID):
|
case .success(let roomID):
|
||||||
analytics.trackCreatedRoom(isDM: true)
|
analytics.trackCreatedRoom(isDM: true)
|
||||||
actionsSubject.send(.openDirectChat(roomID: roomID))
|
actionsSubject.send(.openDirectChat(roomID: roomID))
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ struct UserProfileScreen: View {
|
|||||||
otherUserFooter
|
otherUserFooter
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AvatarHeaderView(user: UserProfileProxy(userID: context.viewState.userID),
|
AvatarHeaderView(user: UserProfile(userID: context.viewState.userID),
|
||||||
isVerified: context.viewState.showVerifiedBadge,
|
isVerified: context.viewState.showVerifiedBadge,
|
||||||
avatarSize: .user(on: .memberDetails),
|
avatarSize: .user(on: .memberDetails),
|
||||||
mediaProvider: context.mediaProvider) { }
|
mediaProvider: context.mediaProvider) { }
|
||||||
|
|||||||
@@ -786,7 +786,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func profile(for userID: String) async -> Result<UserProfileProxy, ClientProxyError> {
|
func profile(for userID: String) async -> Result<UserProfile, ClientProxyError> {
|
||||||
do {
|
do {
|
||||||
return try await .success(.init(sdkUserProfile: client.getProfile(userId: userID)))
|
return try await .success(.init(sdkUserProfile: client.getProfile(userId: userID)))
|
||||||
} catch {
|
} catch {
|
||||||
@@ -933,14 +933,14 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
return rooms
|
return rooms
|
||||||
}
|
}
|
||||||
|
|
||||||
func recentConversationCounterparts() async -> [UserProfileProxy] {
|
func recentConversationCounterparts() async -> [UserProfile] {
|
||||||
let maxResultsToReturn = 5
|
let maxResultsToReturn = 5
|
||||||
|
|
||||||
guard case let .success(roomIdentifiers) = await recentlyVisitedRoomIDs() else {
|
guard case let .success(roomIdentifiers) = await recentlyVisitedRoomIDs() else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
var users: OrderedSet<UserProfileProxy> = []
|
var users: OrderedSet<UserProfile> = []
|
||||||
|
|
||||||
for roomID in roomIdentifiers {
|
for roomID in roomIdentifiers {
|
||||||
guard case let .joined(roomProxy) = await roomForIdentifier(roomID),
|
guard case let .joined(roomProxy) = await roomForIdentifier(roomID),
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ protocol ClientProxyProtocol: AnyObject {
|
|||||||
|
|
||||||
func searchUsers(searchTerm: String, limit: UInt) async -> Result<SearchUsersResultsProxy, ClientProxyError>
|
func searchUsers(searchTerm: String, limit: UInt) async -> Result<SearchUsersResultsProxy, ClientProxyError>
|
||||||
|
|
||||||
func profile(for userID: String) async -> Result<UserProfileProxy, ClientProxyError>
|
func profile(for userID: String) async -> Result<UserProfile, ClientProxyError>
|
||||||
|
|
||||||
func roomDirectorySearchProxy() -> RoomDirectorySearchProxyProtocol
|
func roomDirectorySearchProxy() -> RoomDirectorySearchProxyProtocol
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ protocol ClientProxyProtocol: AnyObject {
|
|||||||
func trackRecentlyVisitedRoom(_ roomID: String) async -> Result<Void, ClientProxyError>
|
func trackRecentlyVisitedRoom(_ roomID: String) async -> Result<Void, ClientProxyError>
|
||||||
|
|
||||||
func recentlyVisitedRooms(filter: @Sendable (JoinedRoomProxyProtocol) -> Bool) async -> [JoinedRoomProxyProtocol]
|
func recentlyVisitedRooms(filter: @Sendable (JoinedRoomProxyProtocol) -> Bool) async -> [JoinedRoomProxyProtocol]
|
||||||
func recentConversationCounterparts() async -> [UserProfileProxy]
|
func recentConversationCounterparts() async -> [UserProfile]
|
||||||
|
|
||||||
// MARK: - Crypto
|
// MARK: - Crypto
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ extension BaseRoomInfoProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isDirect, avatarURL == nil, heroes.count == 1 {
|
if isDirect, avatarURL == nil, heroes.count == 1 {
|
||||||
return .heroes(heroes.map(UserProfileProxy.init))
|
return .heroes(heroes.map(UserProfile.init))
|
||||||
}
|
}
|
||||||
|
|
||||||
return .room(id: id, name: displayName, avatarURL: avatarURL)
|
return .room(id: id, name: displayName, avatarURL: avatarURL)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ nonisolated struct RoomSummary {
|
|||||||
let isSpace: Bool
|
let isSpace: Bool
|
||||||
let avatarURL: URL?
|
let avatarURL: URL?
|
||||||
|
|
||||||
let heroes: [UserProfileProxy]
|
let heroes: [UserProfile]
|
||||||
let activeMembersCount: UInt
|
let activeMembersCount: UInt
|
||||||
|
|
||||||
let lastMessage: AttributedString?
|
let lastMessage: AttributedString?
|
||||||
|
|||||||
@@ -354,7 +354,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
isDirect: roomInfo.isDirect,
|
isDirect: roomInfo.isDirect,
|
||||||
isSpace: roomInfo.isSpace,
|
isSpace: roomInfo.isSpace,
|
||||||
avatarURL: roomInfo.avatarUrl.flatMap(URL.init(string:)),
|
avatarURL: roomInfo.avatarUrl.flatMap(URL.init(string:)),
|
||||||
heroes: roomInfo.heroes.map(UserProfileProxy.init),
|
heroes: roomInfo.heroes.map(UserProfile.init),
|
||||||
activeMembersCount: UInt(roomInfo.activeMembersCount),
|
activeMembersCount: UInt(roomInfo.activeMembersCount),
|
||||||
lastMessage: attributedLastMessage,
|
lastMessage: attributedLastMessage,
|
||||||
lastMessageDate: lastMessageDate,
|
lastMessageDate: lastMessageDate,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import Foundation
|
|||||||
|
|
||||||
struct UserToInvite: Identifiable {
|
struct UserToInvite: Identifiable {
|
||||||
/// The profile of the user being invited.
|
/// The profile of the user being invited.
|
||||||
var user: UserProfileProxy
|
var user: UserProfile
|
||||||
|
|
||||||
/// The ID of the user being invited.
|
/// The ID of the user being invited.
|
||||||
var id: String {
|
var id: String {
|
||||||
|
|||||||
+2
-2
@@ -89,7 +89,7 @@ class SessionVerificationControllerProxy: SessionVerificationControllerProxyProt
|
|||||||
MXLog.info("Acknowledging verification request")
|
MXLog.info("Acknowledging verification request")
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try await sessionVerificationController.acknowledgeVerificationRequest(senderId: details.senderProfile.userID, flowId: details.flowID)
|
try await sessionVerificationController.acknowledgeVerificationRequest(senderId: details.senderProfile.id, flowId: details.flowID)
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed requesting session verification with error: \(error)")
|
MXLog.error("Failed requesting session verification with error: \(error)")
|
||||||
@@ -190,7 +190,7 @@ class SessionVerificationControllerProxy: SessionVerificationControllerProxyProt
|
|||||||
fileprivate func didReceiveVerificationRequest(details: MatrixRustSDK.SessionVerificationRequestDetails) {
|
fileprivate func didReceiveVerificationRequest(details: MatrixRustSDK.SessionVerificationRequestDetails) {
|
||||||
MXLog.info("Received verification request \(details)")
|
MXLog.info("Received verification request \(details)")
|
||||||
|
|
||||||
let details = SessionVerificationRequestDetails(senderProfile: UserProfileProxy(sdkUserProfile: details.senderProfile),
|
let details = SessionVerificationRequestDetails(senderProfile: UserProfile(sdkUserProfile: details.senderProfile),
|
||||||
flowID: details.flowId,
|
flowID: details.flowId,
|
||||||
deviceID: details.deviceId,
|
deviceID: details.deviceId,
|
||||||
deviceDisplayName: details.deviceDisplayName,
|
deviceDisplayName: details.deviceDisplayName,
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ enum SessionVerificationControllerProxyAction: Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct SessionVerificationRequestDetails: Equatable {
|
struct SessionVerificationRequestDetails: Equatable {
|
||||||
let senderProfile: UserProfileProxy
|
let senderProfile: UserProfile
|
||||||
let flowID: String
|
let flowID: String
|
||||||
let deviceID: String
|
let deviceID: String
|
||||||
let deviceDisplayName: String?
|
let deviceDisplayName: String?
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ struct SpaceServiceRoom {
|
|||||||
var childrenCount: Int
|
var childrenCount: Int
|
||||||
|
|
||||||
var joinedMembersCount: Int
|
var joinedMembersCount: Int
|
||||||
var heroes: [UserProfileProxy]
|
var heroes: [UserProfile]
|
||||||
var topic: String?
|
var topic: String?
|
||||||
var canonicalAlias: String?
|
var canonicalAlias: String?
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ extension SpaceServiceRoom {
|
|||||||
childrenCount = Int(spaceRoom.childrenCount)
|
childrenCount = Int(spaceRoom.childrenCount)
|
||||||
|
|
||||||
joinedMembersCount = Int(spaceRoom.numJoinedMembers)
|
joinedMembersCount = Int(spaceRoom.numJoinedMembers)
|
||||||
heroes = (spaceRoom.heroes ?? []).map(UserProfileProxy.init)
|
heroes = (spaceRoom.heroes ?? []).map(UserProfile.init)
|
||||||
topic = spaceRoom.topic
|
topic = spaceRoom.topic
|
||||||
canonicalAlias = spaceRoom.canonicalAlias
|
canonicalAlias = spaceRoom.canonicalAlias
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ extension SpaceServiceRoom {
|
|||||||
isDM: Bool? = nil,
|
isDM: Bool? = nil,
|
||||||
childrenCount: Int = 0,
|
childrenCount: Int = 0,
|
||||||
joinedMembersCount: Int = 0,
|
joinedMembersCount: Int = 0,
|
||||||
heroes: [UserProfileProxy] = [],
|
heroes: [UserProfile] = [],
|
||||||
topic: String? = nil,
|
topic: String? = nil,
|
||||||
canonicalAlias: String? = nil,
|
canonicalAlias: String? = nil,
|
||||||
joinRule: JoinRule? = nil,
|
joinRule: JoinRule? = nil,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import Foundation
|
|||||||
|
|
||||||
struct UserDiscoverySection {
|
struct UserDiscoverySection {
|
||||||
let type: UserDiscoverySectionType
|
let type: UserDiscoverySectionType
|
||||||
let users: [UserProfileProxy]
|
let users: [UserProfile]
|
||||||
|
|
||||||
var title: String? {
|
var title: String? {
|
||||||
switch type {
|
switch type {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ final class UserDiscoveryService: UserDiscoveryServiceProtocol {
|
|||||||
self.clientProxy = clientProxy
|
self.clientProxy = clientProxy
|
||||||
}
|
}
|
||||||
|
|
||||||
func searchProfiles(with searchQuery: String) async -> Result<[UserProfileProxy], UserDiscoveryErrorType> {
|
func searchProfiles(with searchQuery: String) async -> Result<[UserProfile], UserDiscoveryErrorType> {
|
||||||
async let queriedProfile = profileIfPossible(with: searchQuery)
|
async let queriedProfile = profileIfPossible(with: searchQuery)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -32,7 +32,7 @@ final class UserDiscoveryService: UserDiscoveryServiceProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func merge(queriedProfile: UserProfileProxy?, searchResults: SearchUsersResultsProxy) -> [UserProfileProxy] {
|
private func merge(queriedProfile: UserProfile?, searchResults: SearchUsersResultsProxy) -> [UserProfile] {
|
||||||
let searchResults = searchResults.results
|
let searchResults = searchResults.results
|
||||||
|
|
||||||
guard let queriedProfile else {
|
guard let queriedProfile else {
|
||||||
@@ -40,13 +40,13 @@ final class UserDiscoveryService: UserDiscoveryServiceProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let filteredSearchResult = searchResults.filter {
|
let filteredSearchResult = searchResults.filter {
|
||||||
$0.userID != queriedProfile.userID
|
$0.id != queriedProfile.id
|
||||||
}
|
}
|
||||||
|
|
||||||
return [queriedProfile] + filteredSearchResult
|
return [queriedProfile] + filteredSearchResult
|
||||||
}
|
}
|
||||||
|
|
||||||
private func profileIfPossible(with searchQuery: String) async -> UserProfileProxy? {
|
private func profileIfPossible(with searchQuery: String) async -> UserProfile? {
|
||||||
guard searchQuery.isMatrixIdentifier, searchQuery != clientProxy.userID else {
|
guard searchQuery.isMatrixIdentifier, searchQuery != clientProxy.userID else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -57,9 +57,9 @@ final class UserDiscoveryService: UserDiscoveryServiceProtocol {
|
|||||||
return getProfileResult ?? .init(userID: searchQuery)
|
return getProfileResult ?? .init(userID: searchQuery)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func filterAccountOwner(_ profiles: [UserProfileProxy]) -> [UserProfileProxy] {
|
private func filterAccountOwner(_ profiles: [UserProfile]) -> [UserProfile] {
|
||||||
let accountOwnerID = clientProxy.userID
|
let accountOwnerID = clientProxy.userID
|
||||||
return profiles.filter { $0.userID != accountOwnerID }
|
return profiles.filter { $0.id != accountOwnerID }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,5 +14,5 @@ enum UserDiscoveryErrorType: Error {
|
|||||||
|
|
||||||
// sourcery: AutoMockable
|
// sourcery: AutoMockable
|
||||||
protocol UserDiscoveryServiceProtocol {
|
protocol UserDiscoveryServiceProtocol {
|
||||||
func searchProfiles(with searchQuery: String) async -> Result<[UserProfileProxy], UserDiscoveryErrorType>
|
func searchProfiles(with searchQuery: String) async -> Result<[UserProfile], UserDiscoveryErrorType>
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-15
@@ -9,37 +9,37 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import MatrixRustSDK
|
import MatrixRustSDK
|
||||||
|
|
||||||
nonisolated struct UserProfileProxy: Equatable, Hashable {
|
nonisolated struct UserProfile: Hashable, Identifiable {
|
||||||
let userID: String
|
let id: String
|
||||||
let displayName: String?
|
let displayName: String?
|
||||||
let avatarURL: URL?
|
let avatarURL: URL?
|
||||||
|
|
||||||
init(userID: String, displayName: String? = nil, avatarURL: URL? = nil) {
|
init(userID: String, displayName: String? = nil, avatarURL: URL? = nil) {
|
||||||
self.userID = userID
|
id = userID
|
||||||
self.displayName = displayName
|
self.displayName = displayName
|
||||||
self.avatarURL = avatarURL
|
self.avatarURL = avatarURL
|
||||||
}
|
}
|
||||||
|
|
||||||
init(member: RoomMemberDetails) {
|
init(member: RoomMemberDetails) {
|
||||||
userID = member.id
|
id = member.id
|
||||||
displayName = member.isBanned ? nil : member.name
|
displayName = member.isBanned ? nil : member.name
|
||||||
avatarURL = member.isBanned ? nil : member.avatarURL
|
avatarURL = member.isBanned ? nil : member.avatarURL
|
||||||
}
|
}
|
||||||
|
|
||||||
init(sender: TimelineItemSender) {
|
init(sender: TimelineItemSender) {
|
||||||
userID = sender.id
|
id = sender.id
|
||||||
displayName = sender.displayName
|
displayName = sender.displayName
|
||||||
avatarURL = sender.avatarURL
|
avatarURL = sender.avatarURL
|
||||||
}
|
}
|
||||||
|
|
||||||
init(sdkUserProfile: MatrixRustSDK.UserProfile) {
|
init(sdkUserProfile: MatrixRustSDK.UserProfile) {
|
||||||
userID = sdkUserProfile.userId
|
id = sdkUserProfile.userId
|
||||||
displayName = sdkUserProfile.displayName
|
displayName = sdkUserProfile.displayName
|
||||||
avatarURL = sdkUserProfile.avatarUrl.flatMap(URL.init(string:))
|
avatarURL = sdkUserProfile.avatarUrl.flatMap(URL.init(string:))
|
||||||
}
|
}
|
||||||
|
|
||||||
init(sdkRoomHero: MatrixRustSDK.RoomHero) {
|
init(sdkRoomHero: MatrixRustSDK.RoomHero) {
|
||||||
userID = sdkRoomHero.userId
|
id = sdkRoomHero.userId
|
||||||
displayName = sdkRoomHero.displayName
|
displayName = sdkRoomHero.displayName
|
||||||
avatarURL = sdkRoomHero.avatarUrl.flatMap(URL.init(string:))
|
avatarURL = sdkRoomHero.avatarUrl.flatMap(URL.init(string:))
|
||||||
}
|
}
|
||||||
@@ -56,19 +56,13 @@ nonisolated struct UserProfileProxy: Equatable, Hashable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct SearchUsersResultsProxy {
|
struct SearchUsersResultsProxy {
|
||||||
let results: [UserProfileProxy]
|
let results: [UserProfile]
|
||||||
let limited: Bool
|
let limited: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SearchUsersResultsProxy {
|
extension SearchUsersResultsProxy {
|
||||||
init(sdkResults: MatrixRustSDK.SearchUsersResults) {
|
init(sdkResults: MatrixRustSDK.SearchUsersResults) {
|
||||||
results = sdkResults.results.map(UserProfileProxy.init)
|
results = sdkResults.results.map(UserProfile.init)
|
||||||
limited = sdkResults.limited
|
limited = sdkResults.limited
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension UserProfileProxy: Identifiable {
|
|
||||||
var id: String {
|
|
||||||
userID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -19,7 +19,7 @@ final class CreateRoomScreenViewModelTests {
|
|||||||
|
|
||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
|
|
||||||
private let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
|
private let usersSubject = CurrentValueSubject<[UserProfile], Never>([])
|
||||||
|
|
||||||
var context: CreateRoomScreenViewModel.Context {
|
var context: CreateRoomScreenViewModel.Context {
|
||||||
viewModel.context
|
viewModel.context
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ final class InviteUsersScreenViewModelTests {
|
|||||||
#expect(context.viewState.selectedUsers.isEmpty)
|
#expect(context.viewState.selectedUsers.isEmpty)
|
||||||
context.send(viewAction: .toggleUser(.mockAlice))
|
context.send(viewAction: .toggleUser(.mockAlice))
|
||||||
#expect(context.viewState.selectedUsers.count == 1)
|
#expect(context.viewState.selectedUsers.count == 1)
|
||||||
#expect(context.viewState.selectedUsers.first?.userID == UserProfileProxy.mockAlice.userID)
|
#expect(context.viewState.selectedUsers.first?.id == UserProfile.mockAlice.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -41,7 +41,7 @@ final class InviteUsersScreenViewModelTests {
|
|||||||
#expect(context.viewState.selectedUsers.isEmpty)
|
#expect(context.viewState.selectedUsers.isEmpty)
|
||||||
context.send(viewAction: .toggleUser(.mockAlice))
|
context.send(viewAction: .toggleUser(.mockAlice))
|
||||||
#expect(context.viewState.selectedUsers.count == 1)
|
#expect(context.viewState.selectedUsers.count == 1)
|
||||||
#expect(context.viewState.selectedUsers.first?.userID == UserProfileProxy.mockAlice.userID)
|
#expect(context.viewState.selectedUsers.first?.id == UserProfile.mockAlice.id)
|
||||||
context.send(viewAction: .toggleUser(.mockAlice))
|
context.send(viewAction: .toggleUser(.mockAlice))
|
||||||
#expect(context.viewState.selectedUsers.isEmpty)
|
#expect(context.viewState.selectedUsers.isEmpty)
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ final class InviteUsersScreenViewModelTests {
|
|||||||
#expect(context.viewState.selectedUsers.isEmpty)
|
#expect(context.viewState.selectedUsers.isEmpty)
|
||||||
context.send(viewAction: .toggleUser(.mockAlice))
|
context.send(viewAction: .toggleUser(.mockAlice))
|
||||||
#expect(context.viewState.selectedUsers.count == 1)
|
#expect(context.viewState.selectedUsers.count == 1)
|
||||||
#expect(context.viewState.selectedUsers.first?.userID == UserProfileProxy.mockAlice.userID)
|
#expect(context.viewState.selectedUsers.first?.id == UserProfile.mockAlice.id)
|
||||||
context.send(viewAction: .toggleUser(.mockAlice))
|
context.send(viewAction: .toggleUser(.mockAlice))
|
||||||
#expect(context.viewState.selectedUsers.isEmpty)
|
#expect(context.viewState.selectedUsers.isEmpty)
|
||||||
}
|
}
|
||||||
@@ -174,7 +174,7 @@ final class InviteUsersScreenViewModelTests {
|
|||||||
appSettings: .volatile())
|
appSettings: .volatile())
|
||||||
|
|
||||||
// The locked invitee starts pre-selected and locked.
|
// The locked invitee starts pre-selected and locked.
|
||||||
#expect(context.viewState.selectedUsers.map(\.userID) == [UserProfileProxy.mockAlice.userID])
|
#expect(context.viewState.selectedUsers.map(\.id) == [UserProfile.mockAlice.id])
|
||||||
#expect(context.viewState.isInviteeMandatory(.mockAlice))
|
#expect(context.viewState.isInviteeMandatory(.mockAlice))
|
||||||
// The proceed button is disabled while the only selected user is the locked invitee.
|
// The proceed button is disabled while the only selected user is the locked invitee.
|
||||||
#expect(!context.viewState.hasInvitableSelectedUsers)
|
#expect(!context.viewState.hasInvitableSelectedUsers)
|
||||||
@@ -218,7 +218,7 @@ final class InviteUsersScreenViewModelTests {
|
|||||||
#expect(args.topic == nil)
|
#expect(args.topic == nil)
|
||||||
#expect(args.accessType == .private)
|
#expect(args.accessType == .private)
|
||||||
#expect(args.isSpace == false)
|
#expect(args.isSpace == false)
|
||||||
#expect(args.userIDs == [UserProfileProxy.mockAlice.userID, UserProfileProxy.mockBob.userID])
|
#expect(args.userIDs == [UserProfile.mockAlice.id, UserProfile.mockBob.id])
|
||||||
#expect(args.avatarURL == nil)
|
#expect(args.avatarURL == nil)
|
||||||
#expect(args.aliasLocalPart == nil)
|
#expect(args.aliasLocalPart == nil)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import Testing
|
|||||||
struct RoomSummaryTests {
|
struct RoomSummaryTests {
|
||||||
// swiftlint:disable:next large_tuple
|
// swiftlint:disable:next large_tuple
|
||||||
let roomDetails: (id: String, name: String, avatarURL: URL) = ("room_id", "Room Name", "mxc://hs.tld/room/avatar")
|
let roomDetails: (id: String, name: String, avatarURL: URL) = ("room_id", "Room Name", "mxc://hs.tld/room/avatar")
|
||||||
let heroes = [UserProfileProxy(userID: "hero_1", displayName: "Hero 1", avatarURL: "mxc://hs.tld/user/avatar")]
|
let heroes = [UserProfile(userID: "hero_1", displayName: "Hero 1", avatarURL: "mxc://hs.tld/user/avatar")]
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
func roomAvatar() {
|
func roomAvatar() {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ struct UserDiscoveryServiceTest {
|
|||||||
private var service: UserDiscoveryService
|
private var service: UserDiscoveryService
|
||||||
private var clientProxy: ClientProxyMock
|
private var clientProxy: ClientProxyMock
|
||||||
|
|
||||||
private var searchResults: [UserProfileProxy] {
|
private var searchResults: [UserProfile] {
|
||||||
[.mockAlice, .mockBob, .mockCharlie]
|
[.mockAlice, .mockBob, .mockCharlie]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ struct UserDiscoveryServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
func queryShowingResults() async {
|
func queryShowingResults() async {
|
||||||
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: [UserProfileProxy.mockAlice], limited: true))
|
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: [UserProfile.mockAlice], limited: true))
|
||||||
|
|
||||||
let results = await (try? search(query: "AAA").get()) ?? []
|
let results = await (try? search(query: "AAA").get()) ?? []
|
||||||
assertSearchResults(results, toBe: 1)
|
assertSearchResults(results, toBe: 1)
|
||||||
@@ -33,7 +33,7 @@ struct UserDiscoveryServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
func ownerIsFiltered() async {
|
func ownerIsFiltered() async {
|
||||||
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: [UserProfileProxy(userID: "@foo:matrix.org")], limited: true))
|
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: [UserProfile(userID: "@foo:matrix.org")], limited: true))
|
||||||
|
|
||||||
let results = await (try? search(query: "AAA").get()) ?? []
|
let results = await (try? search(query: "AAA").get()) ?? []
|
||||||
assertSearchResults(results, toBe: 0)
|
assertSearchResults(results, toBe: 0)
|
||||||
@@ -104,7 +104,7 @@ struct UserDiscoveryServiceTest {
|
|||||||
let results = await (try? search(query: "@a:b.com").get()) ?? []
|
let results = await (try? search(query: "@a:b.com").get()) ?? []
|
||||||
|
|
||||||
assertSearchResults(results, toBe: 3)
|
assertSearchResults(results, toBe: 3)
|
||||||
let firstUserID = results.first?.userID
|
let firstUserID = results.first?.id
|
||||||
#expect(firstUserID == "@bob:matrix.org")
|
#expect(firstUserID == "@bob:matrix.org")
|
||||||
#expect(clientProxy.profileForCalled)
|
#expect(clientProxy.profileForCalled)
|
||||||
}
|
}
|
||||||
@@ -116,20 +116,20 @@ struct UserDiscoveryServiceTest {
|
|||||||
|
|
||||||
let results = await (try? search(query: "@a:b.com").get()) ?? []
|
let results = await (try? search(query: "@a:b.com").get()) ?? []
|
||||||
|
|
||||||
let firstUserID = results.first?.userID
|
let firstUserID = results.first?.id
|
||||||
#expect(firstUserID == "@a:b.com")
|
#expect(firstUserID == "@a:b.com")
|
||||||
#expect(clientProxy.profileForCalled)
|
#expect(clientProxy.profileForCalled)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func assertSearchResults(_ results: [UserProfileProxy], toBe count: Int) {
|
private func assertSearchResults(_ results: [UserProfile], toBe count: Int) {
|
||||||
#expect(count >= 0)
|
#expect(count >= 0)
|
||||||
#expect(results.count == count)
|
#expect(results.count == count)
|
||||||
#expect(results.isEmpty == (count == 0))
|
#expect(results.isEmpty == (count == 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
private func search(query: String) async -> Result<[UserProfileProxy], UserDiscoveryErrorType> {
|
private func search(query: String) async -> Result<[UserProfile], UserDiscoveryErrorType> {
|
||||||
await service.searchProfiles(with: query)
|
await service.searchProfiles(with: query)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ struct UserProfileScreenViewModelTests {
|
|||||||
func initialState() async throws {
|
func initialState() async throws {
|
||||||
let userIndicatorController = UserIndicatorControllerMock()
|
let userIndicatorController = UserIndicatorControllerMock()
|
||||||
|
|
||||||
let profile = UserProfileProxy(userID: "@alice:matrix.org", displayName: "Alice", avatarURL: .mockMXCAvatar)
|
let profile = UserProfile(userID: "@alice:matrix.org", displayName: "Alice", avatarURL: .mockMXCAvatar)
|
||||||
let clientProxy = ClientProxyMock(.init())
|
let clientProxy = ClientProxyMock(.init())
|
||||||
clientProxy.profileForReturnValue = .success(profile)
|
clientProxy.profileForReturnValue = .success(profile)
|
||||||
|
|
||||||
let viewModel = UserProfileScreenViewModel(userID: profile.userID,
|
let viewModel = UserProfileScreenViewModel(userID: profile.id,
|
||||||
isPresentedModally: false,
|
isPresentedModally: false,
|
||||||
userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||||
userIndicatorController: userIndicatorController,
|
userIndicatorController: userIndicatorController,
|
||||||
@@ -39,11 +39,11 @@ struct UserProfileScreenViewModelTests {
|
|||||||
func initialStateAccountOwner() async throws {
|
func initialStateAccountOwner() async throws {
|
||||||
let userIndicatorController = UserIndicatorControllerMock()
|
let userIndicatorController = UserIndicatorControllerMock()
|
||||||
|
|
||||||
let profile = UserProfileProxy(userID: RoomMemberProxyMock.mockMe.userID, displayName: "Me", avatarURL: .mockMXCAvatar)
|
let profile = UserProfile(userID: RoomMemberProxyMock.mockMe.userID, displayName: "Me", avatarURL: .mockMXCAvatar)
|
||||||
let clientProxy = ClientProxyMock(.init())
|
let clientProxy = ClientProxyMock(.init())
|
||||||
clientProxy.profileForReturnValue = .success(profile)
|
clientProxy.profileForReturnValue = .success(profile)
|
||||||
|
|
||||||
let viewModel = UserProfileScreenViewModel(userID: profile.userID,
|
let viewModel = UserProfileScreenViewModel(userID: profile.id,
|
||||||
isPresentedModally: false,
|
isPresentedModally: false,
|
||||||
userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||||
userIndicatorController: userIndicatorController,
|
userIndicatorController: userIndicatorController,
|
||||||
@@ -63,13 +63,13 @@ struct UserProfileScreenViewModelTests {
|
|||||||
func startingDmWithUnknownUserFetchesIdentity() async throws {
|
func startingDmWithUnknownUserFetchesIdentity() async throws {
|
||||||
let userIndicatorController = UserIndicatorControllerMock()
|
let userIndicatorController = UserIndicatorControllerMock()
|
||||||
|
|
||||||
let profile = UserProfileProxy.mockAlice
|
let profile = UserProfile.mockAlice
|
||||||
|
|
||||||
let clientProxy = ClientProxyMock(.init())
|
let clientProxy = ClientProxyMock(.init())
|
||||||
clientProxy.directRoomForUserIDReturnValue = .success(nil)
|
clientProxy.directRoomForUserIDReturnValue = .success(nil)
|
||||||
clientProxy.userIdentityForFallBackToServerReturnValue = .success(nil)
|
clientProxy.userIdentityForFallBackToServerReturnValue = .success(nil)
|
||||||
|
|
||||||
let viewModel = UserProfileScreenViewModel(userID: profile.userID,
|
let viewModel = UserProfileScreenViewModel(userID: profile.id,
|
||||||
isPresentedModally: false,
|
isPresentedModally: false,
|
||||||
userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||||
userIndicatorController: userIndicatorController,
|
userIndicatorController: userIndicatorController,
|
||||||
|
|||||||
Reference in New Issue
Block a user