Rename SpaceRoomProxy to SpaceServiceRoom and stop proxying the struct. (#4952)

* Rename SpaceRoomProxy to SpaceServiceRoom.

The underlying type is a struct, we don't need to proxy it.

* Actually stop proxying the SpaceRoom.
This commit is contained in:
Doug
2026-01-13 12:00:20 +00:00
committed by GitHub
parent de1753a766
commit 334df3f5cd
43 changed files with 620 additions and 604 deletions
+12 -12
View File
@@ -216,7 +216,6 @@
24B7CD41342C143117ADA768 /* Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2B1CC9AA154F4D5435BF60A /* Comparable.swift */; }; 24B7CD41342C143117ADA768 /* Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2B1CC9AA154F4D5435BF60A /* Comparable.swift */; };
24BDDD09A90B8BFE3793F3AA /* ClientProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6033779EB37259F27F938937 /* ClientProxyProtocol.swift */; }; 24BDDD09A90B8BFE3793F3AA /* ClientProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6033779EB37259F27F938937 /* ClientProxyProtocol.swift */; };
24C32D7EF94ECF9081638DF6 /* RemotePreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69A05E85E4872C3221C5C287 /* RemotePreference.swift */; }; 24C32D7EF94ECF9081638DF6 /* RemotePreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69A05E85E4872C3221C5C287 /* RemotePreference.swift */; };
24D4E0BBC2ECD2AAD84E7159 /* SpaceRoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 355C8C46DA9C0B45F1B7FC4F /* SpaceRoomProxy.swift */; };
250D2E8309C8CC48796D41D1 /* SpaceScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = C11397904D19CFF0E3689F0E /* SpaceScreenModels.swift */; }; 250D2E8309C8CC48796D41D1 /* SpaceScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = C11397904D19CFF0E3689F0E /* SpaceScreenModels.swift */; };
2538350683F421AB620AA950 /* AccessibleLongPress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307C3E5B9B189497D3250E23 /* AccessibleLongPress.swift */; }; 2538350683F421AB620AA950 /* AccessibleLongPress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307C3E5B9B189497D3250E23 /* AccessibleLongPress.swift */; };
25618589E0DE0F1E95FC7B5C /* EmojiProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 099F2D36C141D845A445B1E6 /* EmojiProviderTests.swift */; }; 25618589E0DE0F1E95FC7B5C /* EmojiProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 099F2D36C141D845A445B1E6 /* EmojiProviderTests.swift */; };
@@ -540,6 +539,7 @@
601AB75BD52B0B4276CEB84A /* SessionVerificationScreenStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 161CD412E75F4086F422AE39 /* SessionVerificationScreenStateMachine.swift */; }; 601AB75BD52B0B4276CEB84A /* SessionVerificationScreenStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 161CD412E75F4086F422AE39 /* SessionVerificationScreenStateMachine.swift */; };
60ED66E63A169E47489348A8 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = A20EA00CCB9DBE0FFB17DD09 /* Collections */; }; 60ED66E63A169E47489348A8 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = A20EA00CCB9DBE0FFB17DD09 /* Collections */; };
611BEE29B8B622204E1E6B04 /* SecurityAndPrivacyScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F2F6B6E56055EF173A2DD3 /* SecurityAndPrivacyScreenCoordinator.swift */; }; 611BEE29B8B622204E1E6B04 /* SecurityAndPrivacyScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F2F6B6E56055EF173A2DD3 /* SecurityAndPrivacyScreenCoordinator.swift */; };
612196AF7826846A50C07FA6 /* SpaceServiceRoom.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCAA1B97A17A750AC706B112 /* SpaceServiceRoom.swift */; };
617624A97BDBB75ED3DD8156 /* RoomScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */; }; 617624A97BDBB75ED3DD8156 /* RoomScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */; };
6183BD3916CAA7134B6070D2 /* MatrixEntityRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */; }; 6183BD3916CAA7134B6070D2 /* MatrixEntityRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */; };
6189B4ABD535CE526FA1107B /* StartChatViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DF438EAFC732D2D95D34BF6 /* StartChatViewModelTests.swift */; }; 6189B4ABD535CE526FA1107B /* StartChatViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DF438EAFC732D2D95D34BF6 /* StartChatViewModelTests.swift */; };
@@ -826,6 +826,7 @@
90733645AE76FB33DAD28C2B /* URLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE40D4A5DD857AC16EED945A /* URLSession.swift */; }; 90733645AE76FB33DAD28C2B /* URLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE40D4A5DD857AC16EED945A /* URLSession.swift */; };
90DF83A6A347F7EE7EDE89EE /* AttributedStringBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF25E364AE85090A70AE4644 /* AttributedStringBuilderTests.swift */; }; 90DF83A6A347F7EE7EDE89EE /* AttributedStringBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF25E364AE85090A70AE4644 /* AttributedStringBuilderTests.swift */; };
90EB25D13AE6EEF034BDE9D2 /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71D52BAA5BADB06E5E8C295D /* Assets.swift */; }; 90EB25D13AE6EEF034BDE9D2 /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71D52BAA5BADB06E5E8C295D /* Assets.swift */; };
913BCABB99796F82E3D8D93D /* SpaceRoomInfoMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5530D3541C8832D858EB755A /* SpaceRoomInfoMock.swift */; };
914BDF61447C723F104BCE33 /* SessionDirectories.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C2067FF58B4996323EB40C /* SessionDirectories.swift */; }; 914BDF61447C723F104BCE33 /* SessionDirectories.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C2067FF58B4996323EB40C /* SessionDirectories.swift */; };
915B4CDAF220D9AEB4047D45 /* PollInteractionHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 259E5B05BDE6E20C26CF11B4 /* PollInteractionHandlerProtocol.swift */; }; 915B4CDAF220D9AEB4047D45 /* PollInteractionHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 259E5B05BDE6E20C26CF11B4 /* PollInteractionHandlerProtocol.swift */; };
91ABC91758A6E4A5FAA2E9C4 /* ReadReceipt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314F1C79850BE46E8ABEAFCB /* ReadReceipt.swift */; }; 91ABC91758A6E4A5FAA2E9C4 /* ReadReceipt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314F1C79850BE46E8ABEAFCB /* ReadReceipt.swift */; };
@@ -1079,7 +1080,6 @@
BDED6DA7AD1E76018C424143 /* LegalInformationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C34667458773B02AB5FB0B2 /* LegalInformationScreenViewModel.swift */; }; BDED6DA7AD1E76018C424143 /* LegalInformationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C34667458773B02AB5FB0B2 /* LegalInformationScreenViewModel.swift */; };
BDFF0AEBF57B5B124062DAEF /* GeneratedAccessibilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4CEB4590CCF70F0E3C0B171 /* GeneratedAccessibilityTests.swift */; }; BDFF0AEBF57B5B124062DAEF /* GeneratedAccessibilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4CEB4590CCF70F0E3C0B171 /* GeneratedAccessibilityTests.swift */; };
BE011C4473B9A8F12CBFE92A /* UserDetailsEditScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F58D94C936A1B731D78DE1 /* UserDetailsEditScreenViewModelTests.swift */; }; BE011C4473B9A8F12CBFE92A /* UserDetailsEditScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F58D94C936A1B731D78DE1 /* UserDetailsEditScreenViewModelTests.swift */; };
BE8075CA131C5EA3665C9E0D /* SpaceRoomProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01F2E9FD8FF95AB89A345E6 /* SpaceRoomProxyProtocol.swift */; };
BE8E5985771DF9137C6CE89A /* ProcessInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077B01C13BBA2996272C5FB5 /* ProcessInfo.swift */; }; BE8E5985771DF9137C6CE89A /* ProcessInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077B01C13BBA2996272C5FB5 /* ProcessInfo.swift */; };
BEC6DFEA506085D3027E353C /* MediaEventsTimelineScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 002399C6CB875C4EBB01CBC0 /* MediaEventsTimelineScreen.swift */; }; BEC6DFEA506085D3027E353C /* MediaEventsTimelineScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 002399C6CB875C4EBB01CBC0 /* MediaEventsTimelineScreen.swift */; };
BED59052E5C5163D2B065CA6 /* EventTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A81FD0C60175FA081EB19AD /* EventTimelineItem.swift */; }; BED59052E5C5163D2B065CA6 /* EventTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A81FD0C60175FA081EB19AD /* EventTimelineItem.swift */; };
@@ -1127,7 +1127,6 @@
C67FCC854F3A6FC7A2EC04D0 /* MediaUploadPreviewScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70C86696AC9521F8ED88FBEB /* MediaUploadPreviewScreen.swift */; }; C67FCC854F3A6FC7A2EC04D0 /* MediaUploadPreviewScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70C86696AC9521F8ED88FBEB /* MediaUploadPreviewScreen.swift */; };
C6AC34B731F4F853E9D15146 /* AnalyticsConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA2397174D0DC3918A7A8A7B /* AnalyticsConfiguration.swift */; }; C6AC34B731F4F853E9D15146 /* AnalyticsConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA2397174D0DC3918A7A8A7B /* AnalyticsConfiguration.swift */; };
C6C06DDA8881260303FBA3A0 /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2141693488CE5446BB391964 /* Date.swift */; }; C6C06DDA8881260303FBA3A0 /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2141693488CE5446BB391964 /* Date.swift */; };
C73CF79A578133D3AB7FB83D /* SpaceRoomProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF771312D208C8002A2F05C4 /* SpaceRoomProxyMock.swift */; };
C76892321558E75101E68ED6 /* ReadableFrameModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */; }; C76892321558E75101E68ED6 /* ReadableFrameModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */; };
C7774720A4B2E34693E3227C /* RoomNotificationSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8896CDD20CA2D87EA3B848A1 /* RoomNotificationSettingsScreen.swift */; }; C7774720A4B2E34693E3227C /* RoomNotificationSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8896CDD20CA2D87EA3B848A1 /* RoomNotificationSettingsScreen.swift */; };
C797C0B4CF45C66CD1921252 /* SoftLogoutScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC43313F21511C853D34544E /* SoftLogoutScreenViewModelTests.swift */; }; C797C0B4CF45C66CD1921252 /* SoftLogoutScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC43313F21511C853D34544E /* SoftLogoutScreenViewModelTests.swift */; };
@@ -1386,6 +1385,7 @@
F4996C82A4B3A5FF0C8EDD03 /* RoomListFilterModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = E06AAD6D9D3F5833E7A5A2F9 /* RoomListFilterModels.swift */; }; F4996C82A4B3A5FF0C8EDD03 /* RoomListFilterModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = E06AAD6D9D3F5833E7A5A2F9 /* RoomListFilterModels.swift */; };
F4C005F006FC3657B9F0A31D /* BugReportHook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25586C0ADB814FEE9897DCAA /* BugReportHook.swift */; }; F4C005F006FC3657B9F0A31D /* BugReportHook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25586C0ADB814FEE9897DCAA /* BugReportHook.swift */; };
F4D5A2A8304ED61621BF02D4 /* test_audio.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 66B96842BF5F8ACA1AC84C55 /* test_audio.mp3 */; }; F4D5A2A8304ED61621BF02D4 /* test_audio.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 66B96842BF5F8ACA1AC84C55 /* test_audio.mp3 */; };
F4F29FF972C0C8B38757B2DD /* SpaceServiceRoomProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5416FE342A1E6A1B6D028999 /* SpaceServiceRoomProtocol.swift */; };
F519DE17A3A0F760307B2E6D /* InviteUsersScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02D155E09BF961BBA8F85263 /* InviteUsersScreenViewModel.swift */; }; F519DE17A3A0F760307B2E6D /* InviteUsersScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02D155E09BF961BBA8F85263 /* InviteUsersScreenViewModel.swift */; };
F54E2D6CAD96E1AC15BC526F /* MessageForwardingScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8E60332509665C00179ACF6 /* MessageForwardingScreenViewModel.swift */; }; F54E2D6CAD96E1AC15BC526F /* MessageForwardingScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8E60332509665C00179ACF6 /* MessageForwardingScreenViewModel.swift */; };
F5D2270B5021D521C0D22E11 /* FlowCoordinatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B9FCA1CFD07B8CF9BD21266 /* FlowCoordinatorProtocol.swift */; }; F5D2270B5021D521C0D22E11 /* FlowCoordinatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B9FCA1CFD07B8CF9BD21266 /* FlowCoordinatorProtocol.swift */; };
@@ -1834,7 +1834,6 @@
34ED3AB7E0287552A5648AB3 /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 34ED3AB7E0287552A5648AB3 /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/InfoPlist.strings; sourceTree = "<group>"; };
353024006CB726E9F9187B3A /* AnalyticsConsentState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsConsentState.swift; sourceTree = "<group>"; }; 353024006CB726E9F9187B3A /* AnalyticsConsentState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsConsentState.swift; sourceTree = "<group>"; };
3558A15CFB934F9229301527 /* RestorationToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorationToken.swift; sourceTree = "<group>"; }; 3558A15CFB934F9229301527 /* RestorationToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorationToken.swift; sourceTree = "<group>"; };
355C8C46DA9C0B45F1B7FC4F /* SpaceRoomProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceRoomProxy.swift; sourceTree = "<group>"; };
35A057BA9BE0F079784CD061 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; 35A057BA9BE0F079784CD061 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
35AFCF4C05DEED04E3DB1A16 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; }; 35AFCF4C05DEED04E3DB1A16 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
36DA824791172B9821EACBED /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; }; 36DA824791172B9821EACBED /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
@@ -1996,12 +1995,14 @@
536E72DCBEEC4A1FE66CFDCE /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; }; 536E72DCBEEC4A1FE66CFDCE /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
53F41CEAAE2BB4E74CDC2278 /* TimelineMediaPreviewViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMediaPreviewViewModel.swift; sourceTree = "<group>"; }; 53F41CEAAE2BB4E74CDC2278 /* TimelineMediaPreviewViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMediaPreviewViewModel.swift; sourceTree = "<group>"; };
53FD6D3D38F556CEAA280C58 /* test_animated_image.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = test_animated_image.gif; sourceTree = "<group>"; }; 53FD6D3D38F556CEAA280C58 /* test_animated_image.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = test_animated_image.gif; sourceTree = "<group>"; };
5416FE342A1E6A1B6D028999 /* SpaceServiceRoomProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceServiceRoomProtocol.swift; sourceTree = "<group>"; };
5445FCE0CE15E634FDC1A2E2 /* AnalyticsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsService.swift; sourceTree = "<group>"; }; 5445FCE0CE15E634FDC1A2E2 /* AnalyticsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsService.swift; sourceTree = "<group>"; };
5484457C81B325660901B161 /* AppLockSetupSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupSettingsScreen.swift; sourceTree = "<group>"; }; 5484457C81B325660901B161 /* AppLockSetupSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupSettingsScreen.swift; sourceTree = "<group>"; };
54A5E6F398C269AD52C9AE21 /* EncryptionResetPasswordScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreenModels.swift; sourceTree = "<group>"; }; 54A5E6F398C269AD52C9AE21 /* EncryptionResetPasswordScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreenModels.swift; sourceTree = "<group>"; };
54A7923F0115CF17ABC8047F /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/SAS.strings; sourceTree = "<group>"; }; 54A7923F0115CF17ABC8047F /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/SAS.strings; sourceTree = "<group>"; };
54AD70D6E03D2031AE1B5A52 /* TimelineReactionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReactionsView.swift; sourceTree = "<group>"; }; 54AD70D6E03D2031AE1B5A52 /* TimelineReactionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReactionsView.swift; sourceTree = "<group>"; };
54C4E7B46099462F12000C91 /* DeveloperOptionsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreenViewModelProtocol.swift; sourceTree = "<group>"; }; 54C4E7B46099462F12000C91 /* DeveloperOptionsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
5530D3541C8832D858EB755A /* SpaceRoomInfoMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceRoomInfoMock.swift; sourceTree = "<group>"; };
5557DDA438841AF5DC003D0B /* SpaceListScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceListScreenViewModelTests.swift; sourceTree = "<group>"; }; 5557DDA438841AF5DC003D0B /* SpaceListScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceListScreenViewModelTests.swift; sourceTree = "<group>"; };
55AEEF8142DF1B59DB40FB93 /* TimelineItemSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemSender.swift; sourceTree = "<group>"; }; 55AEEF8142DF1B59DB40FB93 /* TimelineItemSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemSender.swift; sourceTree = "<group>"; };
55B3BF242C93CD32C4C3E08D /* ChatsFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatsFlowCoordinator.swift; sourceTree = "<group>"; }; 55B3BF242C93CD32C4C3E08D /* ChatsFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatsFlowCoordinator.swift; sourceTree = "<group>"; };
@@ -2393,7 +2394,6 @@
A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelProtocol.swift; sourceTree = "<group>"; }; A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelProtocol.swift; sourceTree = "<group>"; };
A010B8EAD1A9F6B4686DF2F4 /* BlockedUsersScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersScreenViewModel.swift; sourceTree = "<group>"; }; A010B8EAD1A9F6B4686DF2F4 /* BlockedUsersScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersScreenViewModel.swift; sourceTree = "<group>"; };
A019A12C866D64CF072024B9 /* AppLockSetupPINScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreenViewModel.swift; sourceTree = "<group>"; }; A019A12C866D64CF072024B9 /* AppLockSetupPINScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreenViewModel.swift; sourceTree = "<group>"; };
A01F2E9FD8FF95AB89A345E6 /* SpaceRoomProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceRoomProxyProtocol.swift; sourceTree = "<group>"; };
A02D1A490944BF01A37586E1 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/SAS.strings; sourceTree = "<group>"; }; A02D1A490944BF01A37586E1 /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/SAS.strings; sourceTree = "<group>"; };
A057F2FDC14866C3026A89A4 /* NotificationManagerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManagerProtocol.swift; sourceTree = "<group>"; }; A057F2FDC14866C3026A89A4 /* NotificationManagerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManagerProtocol.swift; sourceTree = "<group>"; };
A07B011547B201A836C03052 /* EncryptionResetFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetFlowCoordinator.swift; sourceTree = "<group>"; }; A07B011547B201A836C03052 /* EncryptionResetFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetFlowCoordinator.swift; sourceTree = "<group>"; };
@@ -2480,7 +2480,6 @@
AEEAFB646E583655652C3D04 /* RoomStateEventStringBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomStateEventStringBuilderTests.swift; sourceTree = "<group>"; }; AEEAFB646E583655652C3D04 /* RoomStateEventStringBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomStateEventStringBuilderTests.swift; sourceTree = "<group>"; };
AF25E364AE85090A70AE4644 /* AttributedStringBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringBuilderTests.swift; sourceTree = "<group>"; }; AF25E364AE85090A70AE4644 /* AttributedStringBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringBuilderTests.swift; sourceTree = "<group>"; };
AF2E6ADAE685F4109B1FE795 /* TimelineThreadSummaryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineThreadSummaryView.swift; sourceTree = "<group>"; }; AF2E6ADAE685F4109B1FE795 /* TimelineThreadSummaryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineThreadSummaryView.swift; sourceTree = "<group>"; };
AF771312D208C8002A2F05C4 /* SpaceRoomProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceRoomProxyMock.swift; sourceTree = "<group>"; };
AF848B41DAF1066F3054D4A1 /* SessionVerificationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenModels.swift; sourceTree = "<group>"; }; AF848B41DAF1066F3054D4A1 /* SessionVerificationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenModels.swift; sourceTree = "<group>"; };
AF8548D48512127CCC17C520 /* PollRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollRoomTimelineView.swift; sourceTree = "<group>"; }; AF8548D48512127CCC17C520 /* PollRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollRoomTimelineView.swift; sourceTree = "<group>"; };
AFEF489B8E2450E2BA1A314E /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/SAS.strings; sourceTree = "<group>"; }; AFEF489B8E2450E2BA1A314E /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/SAS.strings; sourceTree = "<group>"; };
@@ -2643,6 +2642,7 @@
CC666DAE98245269775329B2 /* RoomMembersFlowCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersFlowCoordinatorTests.swift; sourceTree = "<group>"; }; CC666DAE98245269775329B2 /* RoomMembersFlowCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersFlowCoordinatorTests.swift; sourceTree = "<group>"; };
CC680E0E79D818706CB28CF8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; }; CC680E0E79D818706CB28CF8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
CC743C7A85E3171BCBF0A653 /* AvatarHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarHeaderView.swift; sourceTree = "<group>"; }; CC743C7A85E3171BCBF0A653 /* AvatarHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarHeaderView.swift; sourceTree = "<group>"; };
CCAA1B97A17A750AC706B112 /* SpaceServiceRoom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceServiceRoom.swift; sourceTree = "<group>"; };
CCF71646898A2F720C5BFDF5 /* RoomDirectorySearchScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchScreenViewModel.swift; sourceTree = "<group>"; }; CCF71646898A2F720C5BFDF5 /* RoomDirectorySearchScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchScreenViewModel.swift; sourceTree = "<group>"; };
CD469F7513574341181F7EAA /* ServerSelectionScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreen.swift; sourceTree = "<group>"; }; CD469F7513574341181F7EAA /* ServerSelectionScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreen.swift; sourceTree = "<group>"; };
CD6613DE16AD26B3A74DA1F5 /* LocationRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationRoomTimelineItemContent.swift; sourceTree = "<group>"; }; CD6613DE16AD26B3A74DA1F5 /* LocationRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationRoomTimelineItemContent.swift; sourceTree = "<group>"; };
@@ -3640,8 +3640,8 @@
FC83F47D2173B7538AA72E0E /* RoomSummaryProviderMock.swift */, FC83F47D2173B7538AA72E0E /* RoomSummaryProviderMock.swift */,
4AB29A2D95D3469B5F016655 /* SecureBackupControllerMock.swift */, 4AB29A2D95D3469B5F016655 /* SecureBackupControllerMock.swift */,
248649EBA5BC33DB93698734 /* SessionVerificationControllerProxyMock.swift */, 248649EBA5BC33DB93698734 /* SessionVerificationControllerProxyMock.swift */,
5530D3541C8832D858EB755A /* SpaceRoomInfoMock.swift */,
7DB2A5FF1E68BA580A20D405 /* SpaceRoomListProxyMock.swift */, 7DB2A5FF1E68BA580A20D405 /* SpaceRoomListProxyMock.swift */,
AF771312D208C8002A2F05C4 /* SpaceRoomProxyMock.swift */,
EF36FC3DE25B20B7FA91F1FD /* SpaceServiceProxyMock.swift */, EF36FC3DE25B20B7FA91F1FD /* SpaceServiceProxyMock.swift */,
B0F5CC38803B8382D2C63222 /* TimelineControllerFactoryMock.swift */, B0F5CC38803B8382D2C63222 /* TimelineControllerFactoryMock.swift */,
62EACAFB3F3E017060F9F1C5 /* TimelineProviderMock.swift */, 62EACAFB3F3E017060F9F1C5 /* TimelineProviderMock.swift */,
@@ -5703,10 +5703,10 @@
75B3CE05643C7791D46AC54B /* LeaveSpaceHandleProxy.swift */, 75B3CE05643C7791D46AC54B /* LeaveSpaceHandleProxy.swift */,
4B2B564CA6570E1487A7C7CC /* SpaceRoomListProxy.swift */, 4B2B564CA6570E1487A7C7CC /* SpaceRoomListProxy.swift */,
EACD4855BDAD0799FD86B7B5 /* SpaceRoomListProxyProtocol.swift */, EACD4855BDAD0799FD86B7B5 /* SpaceRoomListProxyProtocol.swift */,
355C8C46DA9C0B45F1B7FC4F /* SpaceRoomProxy.swift */,
A01F2E9FD8FF95AB89A345E6 /* SpaceRoomProxyProtocol.swift */,
226A56746AD99ABDA97189E1 /* SpaceServiceProxy.swift */, 226A56746AD99ABDA97189E1 /* SpaceServiceProxy.swift */,
C57DB49B8426AA721BF85D83 /* SpaceServiceProxyProtocol.swift */, C57DB49B8426AA721BF85D83 /* SpaceServiceProxyProtocol.swift */,
CCAA1B97A17A750AC706B112 /* SpaceServiceRoom.swift */,
5416FE342A1E6A1B6D028999 /* SpaceServiceRoomProtocol.swift */,
); );
path = Spaces; path = Spaces;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -8546,12 +8546,10 @@
F396470968764E2C3EDA92DA /* SpaceListScreenViewModel.swift in Sources */, F396470968764E2C3EDA92DA /* SpaceListScreenViewModel.swift in Sources */,
368EC173453FB805C677BFEF /* SpaceListScreenViewModelProtocol.swift in Sources */, 368EC173453FB805C677BFEF /* SpaceListScreenViewModelProtocol.swift in Sources */,
9B84F55288AB98783C11CC49 /* SpaceRoomCell.swift in Sources */, 9B84F55288AB98783C11CC49 /* SpaceRoomCell.swift in Sources */,
913BCABB99796F82E3D8D93D /* SpaceRoomInfoMock.swift in Sources */,
0DAB08C117E0391F3ADB2031 /* SpaceRoomListProxy.swift in Sources */, 0DAB08C117E0391F3ADB2031 /* SpaceRoomListProxy.swift in Sources */,
9FBF0078657CA4F2A9747E98 /* SpaceRoomListProxyMock.swift in Sources */, 9FBF0078657CA4F2A9747E98 /* SpaceRoomListProxyMock.swift in Sources */,
2EAA1B35D9CA24F090F48792 /* SpaceRoomListProxyProtocol.swift in Sources */, 2EAA1B35D9CA24F090F48792 /* SpaceRoomListProxyProtocol.swift in Sources */,
24D4E0BBC2ECD2AAD84E7159 /* SpaceRoomProxy.swift in Sources */,
C73CF79A578133D3AB7FB83D /* SpaceRoomProxyMock.swift in Sources */,
BE8075CA131C5EA3665C9E0D /* SpaceRoomProxyProtocol.swift in Sources */,
6CAADDC6318E41C7D7AA9526 /* SpaceScreen.swift in Sources */, 6CAADDC6318E41C7D7AA9526 /* SpaceScreen.swift in Sources */,
EF1C1A5D212B14FFCE0E7C83 /* SpaceScreenCoordinator.swift in Sources */, EF1C1A5D212B14FFCE0E7C83 /* SpaceScreenCoordinator.swift in Sources */,
250D2E8309C8CC48796D41D1 /* SpaceScreenModels.swift in Sources */, 250D2E8309C8CC48796D41D1 /* SpaceScreenModels.swift in Sources */,
@@ -8560,6 +8558,8 @@
94C2B531B96493B68B976E5F /* SpaceServiceProxy.swift in Sources */, 94C2B531B96493B68B976E5F /* SpaceServiceProxy.swift in Sources */,
A2091F4B1332D9BF273B09D5 /* SpaceServiceProxyMock.swift in Sources */, A2091F4B1332D9BF273B09D5 /* SpaceServiceProxyMock.swift in Sources */,
DB5200B87C4CE9DF0024AC4E /* SpaceServiceProxyProtocol.swift in Sources */, DB5200B87C4CE9DF0024AC4E /* SpaceServiceProxyProtocol.swift in Sources */,
612196AF7826846A50C07FA6 /* SpaceServiceRoom.swift in Sources */,
F4F29FF972C0C8B38757B2DD /* SpaceServiceRoomProtocol.swift in Sources */,
D0E257557DAC8A34C7B52A9F /* SpaceSettingsFlowCoordinator.swift in Sources */, D0E257557DAC8A34C7B52A9F /* SpaceSettingsFlowCoordinator.swift in Sources */,
383063A7924F06D54BA9B24C /* SpaceSettingsScreen.swift in Sources */, 383063A7924F06D54BA9B24C /* SpaceSettingsScreen.swift in Sources */,
9DB4B303ECC05F0F33582594 /* SpacesAnnouncementSheetView.swift in Sources */, 9DB4B303ECC05F0F33582594 /* SpacesAnnouncementSheetView.swift in Sources */,
@@ -18,12 +18,12 @@ enum SpaceFlowCoordinatorAction {
enum SpaceFlowCoordinatorEntryPoint { enum SpaceFlowCoordinatorEntryPoint {
case space(SpaceRoomListProxyProtocol) case space(SpaceRoomListProxyProtocol)
case joinSpace(SpaceRoomProxyProtocol) case joinSpace(SpaceServiceRoomProtocol)
var spaceID: String { var spaceID: String {
switch self { switch self {
case .space(let spaceRoomListProxy): spaceRoomListProxy.id case .space(let spaceRoomListProxy): spaceRoomListProxy.id
case .joinSpace(let spaceRoomProxy): spaceRoomProxy.id case .joinSpace(let spaceServiceRoom): spaceServiceRoom.id
} }
} }
} }
@@ -294,8 +294,8 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
switch action { switch action {
case .selectSpace(let spaceRoomListProxy): case .selectSpace(let spaceRoomListProxy):
stateMachine.tryEvent(.startChildFlow, userInfo: SpaceFlowCoordinatorEntryPoint.space(spaceRoomListProxy)) stateMachine.tryEvent(.startChildFlow, userInfo: SpaceFlowCoordinatorEntryPoint.space(spaceRoomListProxy))
case .selectUnjoinedSpace(let spaceRoomProxy): case .selectUnjoinedSpace(let spaceServiceRoom):
stateMachine.tryEvent(.startChildFlow, userInfo: SpaceFlowCoordinatorEntryPoint.joinSpace(spaceRoomProxy)) stateMachine.tryEvent(.startChildFlow, userInfo: SpaceFlowCoordinatorEntryPoint.joinSpace(spaceServiceRoom))
case .selectRoom(let roomID): case .selectRoom(let roomID):
stateMachine.tryEvent(.startRoomFlow(roomID: roomID)) stateMachine.tryEvent(.startRoomFlow(roomID: roomID))
case .leftSpace: case .leftSpace:
@@ -322,9 +322,9 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
} }
private func presentJoinSpaceScreen() { private func presentJoinSpaceScreen() {
guard case let .joinSpace(spaceRoomProxy) = entryPoint else { fatalError("Attempting to join a space with the wrong entry point.") } guard case let .joinSpace(spaceServiceRoom) = entryPoint else { fatalError("Attempting to join a space with the wrong entry point.") }
let parameters = JoinRoomScreenCoordinatorParameters(source: .space(spaceRoomProxy), let parameters = JoinRoomScreenCoordinatorParameters(source: .space(spaceServiceRoom),
userSession: flowParameters.userSession, userSession: flowParameters.userSession,
userIndicatorController: flowParameters.userIndicatorController, userIndicatorController: flowParameters.userIndicatorController,
appSettings: flowParameters.appSettings) appSettings: flowParameters.appSettings)
+2 -2
View File
@@ -123,8 +123,8 @@ extension ClientProxyMock {
roomProxy.loadOrFetchEventDetailsForReturnValue = .success(TimelineEventSDKMock()) roomProxy.loadOrFetchEventDetailsForReturnValue = .success(TimelineEventSDKMock())
return .joined(roomProxy) return .joined(roomProxy)
} }
} else if let spaceRoomProxy = configuration.spaceServiceConfiguration.topLevelSpaces.first(where: { $0.id == identifier }) { } else if let spaceServiceRoom = configuration.spaceServiceConfiguration.topLevelSpaces.first(where: { $0.id == identifier }) {
let roomProxy = await JoinedRoomProxyMock(.init(id: spaceRoomProxy.id, name: spaceRoomProxy.name, isSpace: spaceRoomProxy.isSpace)) let roomProxy = await JoinedRoomProxyMock(.init(id: spaceServiceRoom.id, name: spaceServiceRoom.name, isSpace: spaceServiceRoom.isSpace))
roomProxy.loadOrFetchEventDetailsForReturnValue = .success(TimelineEventSDKMock()) roomProxy.loadOrFetchEventDetailsForReturnValue = .success(TimelineEventSDKMock())
return .joined(roomProxy) return .joined(roomProxy)
} else { } else {
@@ -16721,16 +16721,16 @@ class SpaceRoomListProxyMock: SpaceRoomListProxyProtocol, @unchecked Sendable {
set(value) { underlyingId = value } set(value) { underlyingId = value }
} }
var underlyingId: String! var underlyingId: String!
var spaceRoomProxyPublisher: CurrentValuePublisher<SpaceRoomProxyProtocol, Never> { var spaceServiceRoomPublisher: CurrentValuePublisher<SpaceServiceRoomProtocol, Never> {
get { return underlyingSpaceRoomProxyPublisher } get { return underlyingSpaceServiceRoomPublisher }
set(value) { underlyingSpaceRoomProxyPublisher = value } set(value) { underlyingSpaceServiceRoomPublisher = value }
} }
var underlyingSpaceRoomProxyPublisher: CurrentValuePublisher<SpaceRoomProxyProtocol, Never>! var underlyingSpaceServiceRoomPublisher: CurrentValuePublisher<SpaceServiceRoomProtocol, Never>!
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> { var spaceRoomsPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> {
get { return underlyingSpaceRoomsPublisher } get { return underlyingSpaceRoomsPublisher }
set(value) { underlyingSpaceRoomsPublisher = value } set(value) { underlyingSpaceRoomsPublisher = value }
} }
var underlyingSpaceRoomsPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never>! var underlyingSpaceRoomsPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never>!
var paginationStatePublisher: CurrentValuePublisher<SpaceRoomListPaginationState, Never> { var paginationStatePublisher: CurrentValuePublisher<SpaceRoomListPaginationState, Never> {
get { return underlyingPaginationStatePublisher } get { return underlyingPaginationStatePublisher }
set(value) { underlyingPaginationStatePublisher = value } set(value) { underlyingPaginationStatePublisher = value }
@@ -16773,55 +16773,12 @@ class SpaceRoomListProxyMock: SpaceRoomListProxyProtocol, @unchecked Sendable {
await paginateClosure?() await paginateClosure?()
} }
} }
class SpaceRoomProxyMock: SpaceRoomProxyProtocol, @unchecked Sendable {
var id: String {
get { return underlyingId }
set(value) { underlyingId = value }
}
var underlyingId: String!
var name: String {
get { return underlyingName }
set(value) { underlyingName = value }
}
var underlyingName: String!
var rawName: String?
var avatarURL: URL?
var isSpace: Bool {
get { return underlyingIsSpace }
set(value) { underlyingIsSpace = value }
}
var underlyingIsSpace: Bool!
var isDirect: Bool?
var childrenCount: Int {
get { return underlyingChildrenCount }
set(value) { underlyingChildrenCount = value }
}
var underlyingChildrenCount: Int!
var joinedMembersCount: Int {
get { return underlyingJoinedMembersCount }
set(value) { underlyingJoinedMembersCount = value }
}
var underlyingJoinedMembersCount: Int!
var heroes: [UserProfileProxy] = []
var topic: String?
var canonicalAlias: String?
var joinRule: JoinRule?
var worldReadable: Bool?
var guestCanJoin: Bool {
get { return underlyingGuestCanJoin }
set(value) { underlyingGuestCanJoin = value }
}
var underlyingGuestCanJoin: Bool!
var state: Membership?
var via: [String] = []
}
class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable { class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> { var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> {
get { return underlyingTopLevelSpacesPublisher } get { return underlyingTopLevelSpacesPublisher }
set(value) { underlyingTopLevelSpacesPublisher = value } set(value) { underlyingTopLevelSpacesPublisher = value }
} }
var underlyingTopLevelSpacesPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never>! var underlyingTopLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never>!
//MARK: - spaceRoomList //MARK: - spaceRoomList
@@ -16925,13 +16882,13 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
var spaceForIdentifierSpaceIDReceivedSpaceID: String? var spaceForIdentifierSpaceIDReceivedSpaceID: String?
var spaceForIdentifierSpaceIDReceivedInvocations: [String] = [] var spaceForIdentifierSpaceIDReceivedInvocations: [String] = []
var spaceForIdentifierSpaceIDUnderlyingReturnValue: Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError>! var spaceForIdentifierSpaceIDUnderlyingReturnValue: Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError>!
var spaceForIdentifierSpaceIDReturnValue: Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError>! { var spaceForIdentifierSpaceIDReturnValue: Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError>! {
get { get {
if Thread.isMainThread { if Thread.isMainThread {
return spaceForIdentifierSpaceIDUnderlyingReturnValue return spaceForIdentifierSpaceIDUnderlyingReturnValue
} else { } else {
var returnValue: Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError>? = nil var returnValue: Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError>? = nil
DispatchQueue.main.sync { DispatchQueue.main.sync {
returnValue = spaceForIdentifierSpaceIDUnderlyingReturnValue returnValue = spaceForIdentifierSpaceIDUnderlyingReturnValue
} }
@@ -16949,9 +16906,9 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
} }
} }
} }
var spaceForIdentifierSpaceIDClosure: ((String) async -> Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError>)? var spaceForIdentifierSpaceIDClosure: ((String) async -> Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError>)?
func spaceForIdentifier(spaceID: String) async -> Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError> { func spaceForIdentifier(spaceID: String) async -> Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError> {
spaceForIdentifierSpaceIDCallsCount += 1 spaceForIdentifierSpaceIDCallsCount += 1
spaceForIdentifierSpaceIDReceivedSpaceID = spaceID spaceForIdentifierSpaceIDReceivedSpaceID = spaceID
DispatchQueue.main.async { DispatchQueue.main.async {
@@ -17065,13 +17022,13 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
var joinedParentsChildIDReceivedChildID: String? var joinedParentsChildIDReceivedChildID: String?
var joinedParentsChildIDReceivedInvocations: [String] = [] var joinedParentsChildIDReceivedInvocations: [String] = []
var joinedParentsChildIDUnderlyingReturnValue: Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>! var joinedParentsChildIDUnderlyingReturnValue: Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError>!
var joinedParentsChildIDReturnValue: Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>! { var joinedParentsChildIDReturnValue: Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError>! {
get { get {
if Thread.isMainThread { if Thread.isMainThread {
return joinedParentsChildIDUnderlyingReturnValue return joinedParentsChildIDUnderlyingReturnValue
} else { } else {
var returnValue: Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>? = nil var returnValue: Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError>? = nil
DispatchQueue.main.sync { DispatchQueue.main.sync {
returnValue = joinedParentsChildIDUnderlyingReturnValue returnValue = joinedParentsChildIDUnderlyingReturnValue
} }
@@ -17089,9 +17046,9 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
} }
} }
} }
var joinedParentsChildIDClosure: ((String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>)? var joinedParentsChildIDClosure: ((String) async -> Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError>)?
func joinedParents(childID: String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError> { func joinedParents(childID: String) async -> Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError> {
joinedParentsChildIDCallsCount += 1 joinedParentsChildIDCallsCount += 1
joinedParentsChildIDReceivedChildID = childID joinedParentsChildIDReceivedChildID = childID
DispatchQueue.main.async { DispatchQueue.main.async {
@@ -17104,6 +17061,49 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
} }
} }
} }
class SpaceServiceRoomMock: SpaceServiceRoomProtocol, @unchecked Sendable {
var id: String {
get { return underlyingId }
set(value) { underlyingId = value }
}
var underlyingId: String!
var name: String {
get { return underlyingName }
set(value) { underlyingName = value }
}
var underlyingName: String!
var rawName: String?
var avatarURL: URL?
var isSpace: Bool {
get { return underlyingIsSpace }
set(value) { underlyingIsSpace = value }
}
var underlyingIsSpace: Bool!
var isDirect: Bool?
var childrenCount: Int {
get { return underlyingChildrenCount }
set(value) { underlyingChildrenCount = value }
}
var underlyingChildrenCount: Int!
var joinedMembersCount: Int {
get { return underlyingJoinedMembersCount }
set(value) { underlyingJoinedMembersCount = value }
}
var underlyingJoinedMembersCount: Int!
var heroes: [UserProfileProxy] = []
var topic: String?
var canonicalAlias: String?
var joinRule: JoinRule?
var worldReadable: Bool?
var guestCanJoin: Bool {
get { return underlyingGuestCanJoin }
set(value) { underlyingGuestCanJoin = value }
}
var underlyingGuestCanJoin: Bool!
var state: Membership?
var via: [String] = []
}
class StaticRoomSummaryProviderMock: StaticRoomSummaryProviderProtocol, @unchecked Sendable { class StaticRoomSummaryProviderMock: StaticRoomSummaryProviderProtocol, @unchecked Sendable {
var statePublisher: CurrentValuePublisher<RoomSummaryProviderState, Never> { var statePublisher: CurrentValuePublisher<RoomSummaryProviderState, Never> {
get { return underlyingStatePublisher } get { return underlyingStatePublisher }
@@ -98,17 +98,17 @@ extension RoomPreviewProxyMock {
underlyingOwnMembershipDetails = roomMembershipDetails underlyingOwnMembershipDetails = roomMembershipDetails
} }
convenience init(spaceRoomProxy: SpaceRoomProxyProtocol) { convenience init(spaceServiceRoom: SpaceServiceRoomProtocol) {
self.init(Configuration(roomID: spaceRoomProxy.id, self.init(Configuration(roomID: spaceServiceRoom.id,
canonicalAlias: spaceRoomProxy.canonicalAlias ?? "", canonicalAlias: spaceServiceRoom.canonicalAlias ?? "",
name: spaceRoomProxy.name, name: spaceServiceRoom.name,
topic: spaceRoomProxy.topic ?? "", topic: spaceServiceRoom.topic ?? "",
avatarURL: spaceRoomProxy.avatarURL?.absoluteString ?? "", avatarURL: spaceServiceRoom.avatarURL?.absoluteString ?? "",
numJoinedMembers: UInt64(spaceRoomProxy.joinedMembersCount), numJoinedMembers: UInt64(spaceServiceRoom.joinedMembersCount),
numActiveMembers: UInt64(spaceRoomProxy.joinedMembersCount), numActiveMembers: UInt64(spaceServiceRoom.joinedMembersCount),
roomType: spaceRoomProxy.isSpace ? .space : .room, roomType: spaceServiceRoom.isSpace ? .space : .room,
membership: nil, membership: nil,
joinRule: spaceRoomProxy.joinRule ?? .restricted(rules: []), joinRule: spaceServiceRoom.joinRule ?? .restricted(rules: []),
isDirect: false)) isDirect: false))
} }
} }
@@ -23,17 +23,17 @@ extension LeaveSpaceHandleSDKMock {
} }
extension [LeaveSpaceRoom] { extension [LeaveSpaceRoom] {
static func mockRoomsWithSpace(spaceRoomProxy: SpaceRoomProxyProtocol, isLastAdmin: Bool) -> [LeaveSpaceRoom] { static func mockRoomsWithSpace(spaceServiceRoom: SpaceServiceRoomProtocol, isLastAdmin: Bool) -> [LeaveSpaceRoom] {
mockRooms + mockSingleSpace(spaceRoomProxy: spaceRoomProxy, isLastAdmin: isLastAdmin) mockRooms + mockSingleSpace(spaceServiceRoom: spaceServiceRoom, isLastAdmin: isLastAdmin)
} }
static func mockSingleSpace(spaceRoomProxy: SpaceRoomProxyProtocol, isLastAdmin: Bool) -> [LeaveSpaceRoom] { static func mockSingleSpace(spaceServiceRoom: SpaceServiceRoomProtocol, isLastAdmin: Bool) -> [LeaveSpaceRoom] {
[LeaveSpaceRoom(spaceRoom: SpaceRoom(id: spaceRoomProxy.id, [LeaveSpaceRoom(spaceRoom: SpaceRoom(id: spaceServiceRoom.id,
name: spaceRoomProxy.name, name: spaceServiceRoom.name,
avatarURL: spaceRoomProxy.avatarURL, avatarURL: spaceServiceRoom.avatarURL,
isSpace: true, isSpace: true,
memberCount: UInt64(spaceRoomProxy.joinedMembersCount), memberCount: UInt64(spaceServiceRoom.joinedMembersCount),
joinRule: spaceRoomProxy.joinRule), joinRule: spaceServiceRoom.joinRule),
isLastAdmin: isLastAdmin)] isLastAdmin: isLastAdmin)]
} }
@@ -0,0 +1,205 @@
//
// Copyright 2025 Element Creations Ltd.
// Copyright 2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import Foundation
import MatrixRustSDK
extension SpaceServiceRoomMock {
struct Configuration {
var id: String = UUID().uuidString
var name: String?
var rawName: String?
var avatarURL: URL?
var isSpace: Bool
var isDirect: Bool?
var childrenCount = 0
var joinedMembersCount = 0
var heroes: [UserProfileProxy] = []
var topic: String?
var canonicalAlias: String?
var joinRule: JoinRule?
var worldReadable: Bool?
var guestCanJoin = true
var state: Membership?
}
convenience init(_ configuration: Configuration) {
self.init()
id = configuration.id
name = configuration.name ?? configuration.id
rawName = configuration.rawName
avatarURL = configuration.avatarURL
isSpace = configuration.isSpace
isDirect = configuration.isDirect
childrenCount = configuration.childrenCount
joinedMembersCount = configuration.joinedMembersCount
heroes = configuration.heroes
topic = configuration.topic
canonicalAlias = configuration.canonicalAlias
joinRule = configuration.joinRule
worldReadable = configuration.worldReadable
guestCanJoin = configuration.guestCanJoin
state = configuration.state
}
}
extension [SpaceServiceRoomProtocol] {
static var mockJoinedSpaces: [SpaceServiceRoomMock] {
[
SpaceServiceRoomMock(.init(id: "space1",
name: "The Foundation",
isSpace: true,
childrenCount: 1,
joinedMembersCount: 500,
state: .joined)),
SpaceServiceRoomMock(.init(id: "space2",
name: "The Second Foundation",
isSpace: true,
childrenCount: 1,
joinedMembersCount: 100,
state: .joined)),
SpaceServiceRoomMock(.init(id: "space3",
name: "The Galactic Empire",
isSpace: true,
childrenCount: 25000,
joinedMembersCount: 1_000_000_000,
state: .joined)),
SpaceServiceRoomMock(.init(id: "space4",
name: "The Korellians",
isSpace: true,
childrenCount: 27,
joinedMembersCount: 2_000_000,
state: .joined)),
SpaceServiceRoomMock(.init(id: "space5",
name: "The Luminists",
isSpace: true,
childrenCount: 1,
joinedMembersCount: 100_000,
state: .joined)),
SpaceServiceRoomMock(.init(id: "space6",
name: "The Anacreons",
isSpace: true,
childrenCount: 25,
joinedMembersCount: 400_000,
state: .joined)),
SpaceServiceRoomMock(.init(id: "space7",
name: "The Thespians",
isSpace: true,
childrenCount: 15,
joinedMembersCount: 300_000,
state: .joined))
]
}
static var mockJoinedSpaces2: [SpaceServiceRoomMock] {
[
SpaceServiceRoomMock(.init(id: "space1",
name: "The Foundation",
avatarURL: .mockMXCAvatar,
isSpace: true,
childrenCount: 1,
joinedMembersCount: 500,
canonicalAlias: "#the-foundation:matrix.org",
state: .joined)),
SpaceServiceRoomMock(.init(id: "space2",
name: "The Second Foundation",
isSpace: true,
childrenCount: 1,
joinedMembersCount: 100,
state: .joined)),
SpaceServiceRoomMock(.init(id: "space3",
name: "The Galactic Empire",
isSpace: true,
childrenCount: 25000,
joinedMembersCount: 1_000_000_000,
canonicalAlias: "#the-galactic-empire:matrix.org",
state: .joined))
]
}
static var mockSpaceList: [SpaceServiceRoomProtocol] {
makeSpaceRooms(isSpace: true) + makeSpaceRooms(isSpace: false)
}
static var mockSingleRoom: [SpaceServiceRoomProtocol] {
[SpaceServiceRoomMock(.init(id: "!spaceroom:matrix.org",
name: "Management",
isSpace: false,
joinedMembersCount: 12,
topic: "This is where everything gets organised 📋.",
state: .joined))]
}
private static func makeSpaceRooms(isSpace: Bool) -> [SpaceServiceRoomMock] {
let typeName = isSpace ? "Space" : "Room"
return [
SpaceServiceRoomMock(.init(id: "!\(typeName.lowercased())1:matrix.org",
name: "Company \(typeName)",
isSpace: isSpace)),
SpaceServiceRoomMock(.init(id: "!\(typeName.lowercased())2:matrix.org",
name: "Public \(typeName)",
avatarURL: .mockMXCAvatar,
isSpace: isSpace,
joinedMembersCount: 78,
topic: "Discussion on specific topic goes here.",
joinRule: .public)),
SpaceServiceRoomMock(.init(id: "!\(typeName.lowercased())3:matrix.org",
name: "Joined \(typeName)",
isSpace: isSpace,
joinedMembersCount: 123,
topic: "Discussion on specific topic goes here.",
joinRule: .restricted(rules: []),
state: .joined))
]
}
}
extension SpaceServiceRoomMock {
convenience init(mode: JoinRoomScreenMode) {
var state: Membership?
var joinRule: JoinRule?
switch mode {
case .joinable:
joinRule = .public
case .restricted:
joinRule = .restricted(rules: [])
case .inviteRequired:
joinRule = .private
case .invited:
state = .invited
joinRule = .private
case .knockable:
joinRule = .knock
case .knocked:
state = .knocked
joinRule = .knock
case .banned:
state = .banned
case .loading, .unknown, .forbidden:
break
}
self.init(.init(id: "1",
name: "The Three-Body Problem",
avatarURL: .mockMXCAvatar,
isSpace: true,
childrenCount: 100,
joinedMembersCount: 123,
heroes: [.mockAlice, .mockBob, .mockCharlie],
topic: "“Science and technology were the only keys to opening the door to the future, and people approached science with the faith and sincerity of elementary school students.”",
canonicalAlias: "#3-body-problem:matrix.org",
joinRule: joinRule,
state: state))
}
}
@@ -12,16 +12,16 @@ import MatrixRustSDK
extension SpaceRoomListProxyMock { extension SpaceRoomListProxyMock {
class Configuration { class Configuration {
var spaceRoomProxy: SpaceRoomProxyProtocol var spaceServiceRoom: SpaceServiceRoomProtocol
var initialSpaceRooms: [SpaceRoomProxyProtocol] var initialSpaceRooms: [SpaceServiceRoomProtocol]
var paginationStateSubject: CurrentValueSubject<SpaceRoomListPaginationState, Never> var paginationStateSubject: CurrentValueSubject<SpaceRoomListPaginationState, Never>
var paginationResponses: [[SpaceRoomProxyProtocol]] var paginationResponses: [[SpaceServiceRoomProtocol]]
init(spaceRoomProxy: SpaceRoomProxyProtocol, init(spaceServiceRoom: SpaceServiceRoomProtocol,
initialSpaceRooms: [SpaceRoomProxyProtocol] = [], initialSpaceRooms: [SpaceServiceRoomProtocol] = [],
paginationStateSubject: CurrentValueSubject<SpaceRoomListPaginationState, Never> = .init(.idle(endReached: true)), paginationStateSubject: CurrentValueSubject<SpaceRoomListPaginationState, Never> = .init(.idle(endReached: true)),
paginationResponses: [[SpaceRoomProxyProtocol]] = []) { paginationResponses: [[SpaceServiceRoomProtocol]] = []) {
self.spaceRoomProxy = spaceRoomProxy self.spaceServiceRoom = spaceServiceRoom
self.initialSpaceRooms = initialSpaceRooms self.initialSpaceRooms = initialSpaceRooms
self.paginationStateSubject = paginationStateSubject self.paginationStateSubject = paginationStateSubject
self.paginationResponses = paginationResponses self.paginationResponses = paginationResponses
@@ -31,10 +31,10 @@ extension SpaceRoomListProxyMock {
convenience init(_ configuration: Configuration) { convenience init(_ configuration: Configuration) {
self.init() self.init()
let spaceRoomsSubject: CurrentValueSubject<[SpaceRoomProxyProtocol], Never> = .init(configuration.initialSpaceRooms) let spaceRoomsSubject: CurrentValueSubject<[SpaceServiceRoomProtocol], Never> = .init(configuration.initialSpaceRooms)
id = configuration.spaceRoomProxy.id id = configuration.spaceServiceRoom.id
spaceRoomProxyPublisher = .init(configuration.spaceRoomProxy) spaceServiceRoomPublisher = .init(configuration.spaceServiceRoom)
spaceRoomsPublisher = spaceRoomsSubject.asCurrentValuePublisher() spaceRoomsPublisher = spaceRoomsSubject.asCurrentValuePublisher()
paginationStatePublisher = configuration.paginationStateSubject.asCurrentValuePublisher() paginationStatePublisher = configuration.paginationStateSubject.asCurrentValuePublisher()
@@ -1,205 +0,0 @@
//
// Copyright 2025 Element Creations Ltd.
// Copyright 2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import Foundation
import MatrixRustSDK
extension SpaceRoomProxyMock {
struct Configuration {
var id: String = UUID().uuidString
var name: String?
var rawName: String?
var avatarURL: URL?
var isSpace: Bool
var isDirect: Bool?
var childrenCount = 0
var joinedMembersCount = 0
var heroes: [UserProfileProxy] = []
var topic: String?
var canonicalAlias: String?
var joinRule: JoinRule?
var worldReadable: Bool?
var guestCanJoin = true
var state: Membership?
}
convenience init(_ configuration: Configuration) {
self.init()
id = configuration.id
name = configuration.name ?? configuration.id
rawName = configuration.rawName
avatarURL = configuration.avatarURL
isSpace = configuration.isSpace
isDirect = configuration.isDirect
childrenCount = configuration.childrenCount
joinedMembersCount = configuration.joinedMembersCount
heroes = configuration.heroes
topic = configuration.topic
canonicalAlias = configuration.canonicalAlias
joinRule = configuration.joinRule
worldReadable = configuration.worldReadable
guestCanJoin = configuration.guestCanJoin
state = configuration.state
}
}
extension [SpaceRoomProxyProtocol] {
static var mockJoinedSpaces: [SpaceRoomProxyMock] {
[
SpaceRoomProxyMock(.init(id: "space1",
name: "The Foundation",
isSpace: true,
childrenCount: 1,
joinedMembersCount: 500,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space2",
name: "The Second Foundation",
isSpace: true,
childrenCount: 1,
joinedMembersCount: 100,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space3",
name: "The Galactic Empire",
isSpace: true,
childrenCount: 25000,
joinedMembersCount: 1_000_000_000,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space4",
name: "The Korellians",
isSpace: true,
childrenCount: 27,
joinedMembersCount: 2_000_000,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space5",
name: "The Luminists",
isSpace: true,
childrenCount: 1,
joinedMembersCount: 100_000,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space6",
name: "The Anacreons",
isSpace: true,
childrenCount: 25,
joinedMembersCount: 400_000,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space7",
name: "The Thespians",
isSpace: true,
childrenCount: 15,
joinedMembersCount: 300_000,
state: .joined))
]
}
static var mockJoinedSpaces2: [SpaceRoomProxyMock] {
[
SpaceRoomProxyMock(.init(id: "space1",
name: "The Foundation",
avatarURL: .mockMXCAvatar,
isSpace: true,
childrenCount: 1,
joinedMembersCount: 500,
canonicalAlias: "#the-foundation:matrix.org",
state: .joined)),
SpaceRoomProxyMock(.init(id: "space2",
name: "The Second Foundation",
isSpace: true,
childrenCount: 1,
joinedMembersCount: 100,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space3",
name: "The Galactic Empire",
isSpace: true,
childrenCount: 25000,
joinedMembersCount: 1_000_000_000,
canonicalAlias: "#the-galactic-empire:matrix.org",
state: .joined))
]
}
static var mockSpaceList: [SpaceRoomProxyProtocol] {
makeSpaceRooms(isSpace: true) + makeSpaceRooms(isSpace: false)
}
static var mockSingleRoom: [SpaceRoomProxyProtocol] {
[SpaceRoomProxyMock(.init(id: "!spaceroom:matrix.org",
name: "Management",
isSpace: false,
joinedMembersCount: 12,
topic: "This is where everything gets organised 📋.",
state: .joined))]
}
private static func makeSpaceRooms(isSpace: Bool) -> [SpaceRoomProxyMock] {
let typeName = isSpace ? "Space" : "Room"
return [
SpaceRoomProxyMock(.init(id: "!\(typeName.lowercased())1:matrix.org",
name: "Company \(typeName)",
isSpace: isSpace)),
SpaceRoomProxyMock(.init(id: "!\(typeName.lowercased())2:matrix.org",
name: "Public \(typeName)",
avatarURL: .mockMXCAvatar,
isSpace: isSpace,
joinedMembersCount: 78,
topic: "Discussion on specific topic goes here.",
joinRule: .public)),
SpaceRoomProxyMock(.init(id: "!\(typeName.lowercased())3:matrix.org",
name: "Joined \(typeName)",
isSpace: isSpace,
joinedMembersCount: 123,
topic: "Discussion on specific topic goes here.",
joinRule: .restricted(rules: []),
state: .joined))
]
}
}
extension SpaceRoomProxyMock {
convenience init(mode: JoinRoomScreenMode) {
var state: Membership?
var joinRule: JoinRule?
switch mode {
case .joinable:
joinRule = .public
case .restricted:
joinRule = .restricted(rules: [])
case .inviteRequired:
joinRule = .private
case .invited:
state = .invited
joinRule = .private
case .knockable:
joinRule = .knock
case .knocked:
state = .knocked
joinRule = .knock
case .banned:
state = .banned
case .loading, .unknown, .forbidden:
break
}
self.init(.init(id: "1",
name: "The Three-Body Problem",
avatarURL: .mockMXCAvatar,
isSpace: true,
childrenCount: 100,
joinedMembersCount: 123,
heroes: [.mockAlice, .mockBob, .mockCharlie],
topic: "“Science and technology were the only keys to opening the door to the future, and people approached science with the faith and sincerity of elementary school students.”",
canonicalAlias: "#3-body-problem:matrix.org",
joinRule: joinRule,
state: state))
}
}
@@ -13,8 +13,8 @@ import MatrixRustSDKMocks
extension SpaceServiceProxyMock { extension SpaceServiceProxyMock {
struct Configuration { struct Configuration {
var topLevelSpaces: [SpaceRoomProxyProtocol] = [] var topLevelSpaces: [SpaceServiceRoomProtocol] = []
var joinedParentSpaces: [SpaceRoomProxyProtocol] = [] var joinedParentSpaces: [SpaceServiceRoomProtocol] = []
var spaceRoomLists: [String: SpaceRoomListProxyMock] = [:] var spaceRoomLists: [String: SpaceRoomListProxyMock] = [:]
var leaveSpaceRooms: [LeaveSpaceRoom] = [] var leaveSpaceRooms: [LeaveSpaceRoom] = []
} }
@@ -43,11 +43,11 @@ extension SpaceServiceProxyMock {
extension SpaceServiceProxyMock.Configuration { extension SpaceServiceProxyMock.Configuration {
static var populated: SpaceServiceProxyMock.Configuration { static var populated: SpaceServiceProxyMock.Configuration {
let spaceRoomLists = [SpaceRoomProxyProtocol].mockJoinedSpaces.map { let spaceRoomLists = [SpaceServiceRoomProtocol].mockJoinedSpaces.map {
($0.id, SpaceRoomListProxyMock(.init(spaceRoomProxy: $0, initialSpaceRooms: .mockSpaceList))) ($0.id, SpaceRoomListProxyMock(.init(spaceServiceRoom: $0, initialSpaceRooms: .mockSpaceList)))
} }
let subSpaceRoomLists = [SpaceRoomProxyProtocol].mockSpaceList.map { let subSpaceRoomLists = [SpaceServiceRoomProtocol].mockSpaceList.map {
($0.id, SpaceRoomListProxyMock(.init(spaceRoomProxy: $0, initialSpaceRooms: .mockSingleRoom))) ($0.id, SpaceRoomListProxyMock(.init(spaceServiceRoom: $0, initialSpaceRooms: .mockSingleRoom)))
} }
return .init(topLevelSpaces: .mockJoinedSpaces, spaceRoomLists: .init(uniqueKeysWithValues: spaceRoomLists + subSpaceRoomLists)) return .init(topLevelSpaces: .mockJoinedSpaces, spaceRoomLists: .init(uniqueKeysWithValues: spaceRoomLists + subSpaceRoomLists))
@@ -18,14 +18,14 @@ struct JoinRoomScreenCoordinatorParameters {
enum JoinRoomScreenSource { enum JoinRoomScreenSource {
case generic(roomID: String, via: [String]) case generic(roomID: String, via: [String])
case space(SpaceRoomProxyProtocol) case space(SpaceServiceRoomProtocol)
func roomIDAndVia() -> (roomID: String, via: [String]) { func roomIDAndVia() -> (roomID: String, via: [String]) {
switch self { switch self {
case let .generic(roomID: roomID, via: via): case let .generic(roomID: roomID, via: via):
return (roomID: roomID, via: via) return (roomID: roomID, via: via)
case let .space(spaceRoomProxy): case let .space(spaceServiceRoom):
return (roomID: spaceRoomProxy.id, via: spaceRoomProxy.via) return (roomID: spaceServiceRoom.id, via: spaceServiceRoom.via)
} }
} }
} }
@@ -49,7 +49,7 @@ struct JoinRoomScreenRoomDetails {
let isSpace: Bool? let isSpace: Bool?
let childrenCount: Int? let childrenCount: Int?
let spaceVisibility: SpaceRoomProxyVisibility? let spaceVisibility: SpaceServiceRoomVisibility?
} }
struct JoinRoomScreenViewState: BindableState { struct JoinRoomScreenViewState: BindableState {
@@ -172,8 +172,8 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
switch source { switch source {
case .generic(let roomID, _): case .generic(let roomID, _):
await updateGenericRoomDetails(roomID: roomID, roomInfo: roomInfo, inviter: inviter) await updateGenericRoomDetails(roomID: roomID, roomInfo: roomInfo, inviter: inviter)
case .space(let spaceRoomProxy): case .space(let spaceServiceRoom):
await updateSpaceRoomDetails(spaceRoomProxy: spaceRoomProxy, inviter: inviter) await updateSpaceRoomDetails(spaceServiceRoom: spaceServiceRoom, inviter: inviter)
} }
await updateMode() await updateMode()
} }
@@ -200,18 +200,18 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
spaceVisibility: nil) spaceVisibility: nil)
} }
private func updateSpaceRoomDetails(spaceRoomProxy: SpaceRoomProxyProtocol, inviter: RoomInviterDetails?) async { private func updateSpaceRoomDetails(spaceServiceRoom: SpaceServiceRoomProtocol, inviter: RoomInviterDetails?) async {
state.roomDetails = JoinRoomScreenRoomDetails(name: spaceRoomProxy.name, state.roomDetails = JoinRoomScreenRoomDetails(name: spaceServiceRoom.name,
topic: spaceRoomProxy.topic, topic: spaceServiceRoom.topic,
canonicalAlias: spaceRoomProxy.canonicalAlias, canonicalAlias: spaceServiceRoom.canonicalAlias,
avatar: spaceRoomProxy.avatar, avatar: spaceServiceRoom.avatar,
memberCount: spaceRoomProxy.joinedMembersCount, memberCount: spaceServiceRoom.joinedMembersCount,
heroes: spaceRoomProxy.heroes, heroes: spaceServiceRoom.heroes,
inviter: inviter, inviter: inviter,
isDirect: spaceRoomProxy.isDirect, isDirect: spaceServiceRoom.isDirect,
isSpace: spaceRoomProxy.isSpace, isSpace: spaceServiceRoom.isSpace,
childrenCount: spaceRoomProxy.childrenCount, childrenCount: spaceServiceRoom.childrenCount,
spaceVisibility: spaceRoomProxy.visibility) spaceVisibility: spaceServiceRoom.visibility)
} }
private func updateMode() async { private func updateMode() async {
@@ -225,16 +225,16 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
return return
} }
if case .space(let spaceRoomProxy) = source { if case .space(let spaceServiceRoom) = source {
switch spaceRoomProxy.state { switch spaceServiceRoom.state {
case .invited: case .invited:
state.mode = .invited(isDM: spaceRoomProxy.isDirect == true && spaceRoomProxy.joinedMembersCount == 1) state.mode = .invited(isDM: spaceServiceRoom.isDirect == true && spaceServiceRoom.joinedMembersCount == 1)
case .knocked: case .knocked:
state.mode = .knocked state.mode = .knocked
case .banned: case .banned:
state.mode = .banned(sender: nil, reason: nil) state.mode = .banned(sender: nil, reason: nil)
default: default:
switch spaceRoomProxy.joinRule { switch spaceServiceRoom.joinRule {
case .private, .invite: case .private, .invite:
state.mode = .inviteRequired state.mode = .inviteRequired
case .knock, .knockRestricted: case .knock, .knockRestricted:
@@ -445,7 +445,7 @@ struct JoinRoomScreenPreviewWrapper: Identifiable {
} }
let source: JoinRoomScreenSource = if isSpace { let source: JoinRoomScreenSource = if isSpace {
.space(SpaceRoomProxyMock(mode: mode)) .space(SpaceServiceRoomMock(mode: mode))
} else { } else {
.generic(roomID: "1", via: []) .generic(roomID: "1", via: [])
} }
@@ -37,7 +37,7 @@ enum ManageAuthorizedSpacesScreenViewAction {
} }
struct AuthorizedSpacesSelection { struct AuthorizedSpacesSelection {
let joinedSpaces: [SpaceRoomProxyProtocol] let joinedSpaces: [SpaceServiceRoomProtocol]
let unknownSpacesIDs: [String] let unknownSpacesIDs: [String]
let initialSelectedIDs: Set<String> let initialSelectedIDs: Set<String>
let selectedIDs: PassthroughSubject<Set<String>, Never> = .init() let selectedIDs: PassthroughSubject<Set<String>, Never> = .init()
@@ -77,7 +77,7 @@ struct ManageAuthorizedSpacesScreen: View {
} }
} }
private func avatar(space: SpaceRoomProxyProtocol) -> some View { private func avatar(space: SpaceServiceRoomProtocol) -> some View {
RoomAvatarImage(avatar: space.avatar, RoomAvatarImage(avatar: space.avatar,
avatarSize: .room(on: .authorizedSpaces), avatarSize: .room(on: .authorizedSpaces),
mediaProvider: context.mediaProvider) mediaProvider: context.mediaProvider)
@@ -32,7 +32,7 @@ struct SecurityAndPrivacyScreenViewState: BindableState {
var canEditHistoryVisibility = false var canEditHistoryVisibility = false
/// The union of joined parent spaces and the joined spaces in the current access type /// The union of joined parent spaces and the joined spaces in the current access type
var selectableJoinedSpaces: [SpaceRoomProxyProtocol] = [] var selectableJoinedSpaces: [SpaceServiceRoomProtocol] = []
/// The count of the intersection between the set of joined parent spaces and the set of spaces in the current access type /// The count of the intersection between the set of joined parent spaces and the set of spaces in the current access type
var selectableSpacesCount: Int { var selectableSpacesCount: Int {
@@ -118,7 +118,7 @@ struct SecurityAndPrivacyScreenViewState: BindableState {
enum SpaceSelection { enum SpaceSelection {
/// There is only one available parent space for selection and is joined by the user /// There is only one available parent space for selection and is joined by the user
case singleJoined(SpaceRoomProxyProtocol) case singleJoined(SpaceServiceRoomProtocol)
/// There is only one available space for selection and is unknown to the user /// There is only one available space for selection and is unknown to the user
case singleUnknown(id: String) case singleUnknown(id: String)
/// Multiple spaces are available for selection /// Multiple spaces are available for selection
@@ -305,7 +305,7 @@ class SecurityAndPrivacyScreenViewModel: SecurityAndPrivacyScreenViewModelType,
} }
private func setupSelectableJoinedSpaces() async { private func setupSelectableJoinedSpaces() async {
var joinedParentSpaces: [SpaceRoomProxyProtocol] = [] var joinedParentSpaces: [SpaceServiceRoomProtocol] = []
switch await clientProxy.spaceService.joinedParents(childID: roomProxy.id) { switch await clientProxy.spaceService.joinedParents(childID: roomProxy.id) {
case .success(let value): case .success(let value):
joinedParentSpaces = value joinedParentSpaces = value
@@ -313,7 +313,7 @@ class SecurityAndPrivacyScreenViewModel: SecurityAndPrivacyScreenViewModelType,
break break
} }
var nonParentJoinedSpaces: [SpaceRoomProxyProtocol] = [] var nonParentJoinedSpaces: [SpaceServiceRoomProtocol] = []
for spaceID in state.currentSettings.accessType.spaceIDs where !joinedParentSpaces.contains(where: { $0.id == spaceID }) { for spaceID in state.currentSettings.accessType.spaceIDs where !joinedParentSpaces.contains(where: { $0.id == spaceID }) {
if case let .success(.some(space)) = await clientProxy.spaceService.spaceForIdentifier(spaceID: spaceID) { if case let .success(.some(space)) = await clientProxy.spaceService.spaceForIdentifier(spaceID: spaceID) {
nonParentJoinedSpaces.append(space) nonParentJoinedSpaces.append(space)
@@ -269,7 +269,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview {
AppSettings.resetAllSettings() AppSettings.resetAllSettings()
let appSettings = AppSettings() let appSettings = AppSettings()
appSettings.spaceSettingsEnabled = true appSettings.spaceSettingsEnabled = true
let space = [SpaceRoomProxyProtocol].mockSingleRoom[0] let space = [SpaceServiceRoomProtocol].mockSingleRoom[0]
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false, return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
canonicalAlias: "#room:matrix.org", canonicalAlias: "#room:matrix.org",
@@ -286,7 +286,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview {
AppSettings.resetAllSettings() AppSettings.resetAllSettings()
let appSettings = AppSettings() let appSettings = AppSettings()
appSettings.spaceSettingsEnabled = true appSettings.spaceSettingsEnabled = true
let spaces = [SpaceRoomProxyProtocol].mockJoinedSpaces let spaces = [SpaceServiceRoomProtocol].mockJoinedSpaces
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false, return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
canonicalAlias: "#room:matrix.org", canonicalAlias: "#room:matrix.org",
@@ -319,7 +319,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview {
let appSettings = AppSettings() let appSettings = AppSettings()
appSettings.spaceSettingsEnabled = true appSettings.spaceSettingsEnabled = true
appSettings.knockingEnabled = true appSettings.knockingEnabled = true
let space = [SpaceRoomProxyProtocol].mockSingleRoom[0] let space = [SpaceServiceRoomProtocol].mockSingleRoom[0]
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false, return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
canonicalAlias: "#room:matrix.org", canonicalAlias: "#room:matrix.org",
@@ -337,7 +337,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview {
let appSettings = AppSettings() let appSettings = AppSettings()
appSettings.spaceSettingsEnabled = true appSettings.spaceSettingsEnabled = true
appSettings.knockingEnabled = true appSettings.knockingEnabled = true
let spaces = [SpaceRoomProxyProtocol].mockJoinedSpaces let spaces = [SpaceServiceRoomProtocol].mockJoinedSpaces
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false, return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
canonicalAlias: "#room:matrix.org", canonicalAlias: "#room:matrix.org",
@@ -10,36 +10,36 @@ import Compound
import SwiftUI import SwiftUI
struct SpaceHeaderView: View { struct SpaceHeaderView: View {
let spaceRoomProxy: SpaceRoomProxyProtocol let spaceServiceRoom: SpaceServiceRoomProtocol
let mediaProvider: MediaProviderProtocol? let mediaProvider: MediaProviderProtocol?
@State private var isPresentingTopic = false @State private var isPresentingTopic = false
var body: some View { var body: some View {
VStack(spacing: 16) { VStack(spacing: 16) {
RoomAvatarImage(avatar: spaceRoomProxy.avatar, RoomAvatarImage(avatar: spaceServiceRoom.avatar,
avatarSize: .room(on: .spaceHeader), avatarSize: .room(on: .spaceHeader),
mediaProvider: mediaProvider) mediaProvider: mediaProvider)
.accessibilityHidden(true) .accessibilityHidden(true)
VStack(spacing: 8) { VStack(spacing: 8) {
Text(spaceRoomProxy.name) Text(spaceServiceRoom.name)
.font(.compound.headingLGBold) .font(.compound.headingLGBold)
.foregroundStyle(.compound.textPrimary) .foregroundStyle(.compound.textPrimary)
.multilineTextAlignment(.center) .multilineTextAlignment(.center)
if let alias = spaceRoomProxy.canonicalAlias { if let alias = spaceServiceRoom.canonicalAlias {
CopyTextButton(content: alias) CopyTextButton(content: alias)
} }
spaceDetails spaceDetails
JoinedMembersBadgeView(heroes: spaceRoomProxy.heroes, JoinedMembersBadgeView(heroes: spaceServiceRoom.heroes,
joinedCount: spaceRoomProxy.joinedMembersCount, joinedCount: spaceServiceRoom.joinedMembersCount,
mediaProvider: mediaProvider) mediaProvider: mediaProvider)
} }
if let topic = spaceRoomProxy.topic { if let topic = spaceServiceRoom.topic {
Button { isPresentingTopic = true } label: { Button { isPresentingTopic = true } label: {
Text(topic) Text(topic)
.font(.compound.bodyMD) .font(.compound.bodyMD)
@@ -60,7 +60,7 @@ struct SpaceHeaderView: View {
.frame(height: 1 / UIScreen.main.scale) .frame(height: 1 / UIScreen.main.scale)
} }
.sheet(isPresented: $isPresentingTopic) { .sheet(isPresented: $isPresentingTopic) {
if let topic = spaceRoomProxy.topic { if let topic = spaceServiceRoom.topic {
SpaceHeaderTopicSheetView(topic: topic) SpaceHeaderTopicSheetView(topic: topic)
} }
} }
@@ -79,7 +79,7 @@ struct SpaceHeaderView: View {
} }
private var spaceDetailsVisibilityTitle: String { private var spaceDetailsVisibilityTitle: String {
switch spaceRoomProxy.visibility { switch spaceServiceRoom.visibility {
case .public: L10n.commonPublicSpace case .public: L10n.commonPublicSpace
case .private: L10n.commonPrivateSpace case .private: L10n.commonPrivateSpace
case .restricted: L10n.commonSharedSpace case .restricted: L10n.commonSharedSpace
@@ -88,7 +88,7 @@ struct SpaceHeaderView: View {
} }
private var spaceDetailsVisibilityIcon: KeyPath<CompoundIcons, Image> { private var spaceDetailsVisibilityIcon: KeyPath<CompoundIcons, Image> {
switch spaceRoomProxy.visibility { switch spaceServiceRoom.visibility {
case .public: \.public case .public: \.public
case .private: \.lock case .private: \.lock
case .restricted: \.space case .restricted: \.space
@@ -107,19 +107,19 @@ struct SpaceHeaderView_Previews: PreviewProvider, TestablePreview {
static var previews: some View { static var previews: some View {
VStack(spacing: 0) { VStack(spacing: 0) {
ForEach(spaces, id: \.id) { space in ForEach(spaces, id: \.id) { space in
SpaceHeaderView(spaceRoomProxy: space, mediaProvider: mediaProvider) SpaceHeaderView(spaceServiceRoom: space, mediaProvider: mediaProvider)
} }
} }
} }
static func makeSpaceRooms() -> [SpaceRoomProxyMock] { static func makeSpaceRooms() -> [SpaceServiceRoomMock] {
[ [
SpaceRoomProxyMock(.init(id: "!space1:matrix.org", SpaceServiceRoomMock(.init(id: "!space1:matrix.org",
name: "Company Space", name: "Company Space",
isSpace: true, isSpace: true,
childrenCount: 10, childrenCount: 10,
joinedMembersCount: 50)), joinedMembersCount: 50)),
SpaceRoomProxyMock(.init(id: "!space2:matrix.org", SpaceServiceRoomMock(.init(id: "!space2:matrix.org",
name: "Community Space", name: "Community Space",
avatarURL: .mockMXCAvatar, avatarURL: .mockMXCAvatar,
isSpace: true, isSpace: true,
@@ -128,7 +128,7 @@ struct SpaceHeaderView_Previews: PreviewProvider, TestablePreview {
topic: "Description of the space goes right here.", topic: "Description of the space goes right here.",
canonicalAlias: "#space:matrix.org", canonicalAlias: "#space:matrix.org",
joinRule: .public)), joinRule: .public)),
SpaceRoomProxyMock(.init(id: "!space3:matrix.org", SpaceServiceRoomMock(.init(id: "!space3:matrix.org",
name: "Subspace", name: "Subspace",
isSpace: true, isSpace: true,
childrenCount: 30, childrenCount: 30,
@@ -13,32 +13,32 @@ import SwiftUI
struct SpaceRoomCell: View { struct SpaceRoomCell: View {
@Environment(\.dynamicTypeSize) var dynamicTypeSize @Environment(\.dynamicTypeSize) var dynamicTypeSize
let spaceRoomProxy: SpaceRoomProxyProtocol let spaceServiceRoom: SpaceServiceRoomProtocol
let isSelected: Bool let isSelected: Bool
var isJoining = false var isJoining = false
let mediaProvider: MediaProviderProtocol! let mediaProvider: MediaProviderProtocol!
enum Action { case select(SpaceRoomProxyProtocol), join(SpaceRoomProxyProtocol) } enum Action { case select(SpaceServiceRoomProtocol), join(SpaceServiceRoomProtocol) }
let action: (Action) -> Void let action: (Action) -> Void
private let verticalInsets = 12.0 private let verticalInsets = 12.0
private let horizontalInsets = 16.0 private let horizontalInsets = 16.0
private var subtitle: String { private var subtitle: String {
if spaceRoomProxy.isSpace { if spaceServiceRoom.isSpace {
switch spaceRoomProxy.visibility { switch spaceServiceRoom.visibility {
case .public: L10n.commonPublicSpace case .public: L10n.commonPublicSpace
case .private: L10n.commonPrivateSpace case .private: L10n.commonPrivateSpace
case .restricted: L10n.commonSharedSpace case .restricted: L10n.commonSharedSpace
case .none: L10n.commonPrivateSpace case .none: L10n.commonPrivateSpace
} }
} else { } else {
L10n.commonMemberCount(spaceRoomProxy.joinedMembersCount) L10n.commonMemberCount(spaceServiceRoom.joinedMembersCount)
} }
} }
var visibilityIcon: KeyPath<CompoundIcons, Image>? { var visibilityIcon: KeyPath<CompoundIcons, Image>? {
switch spaceRoomProxy.visibility { switch spaceServiceRoom.visibility {
case .public: \.public case .public: \.public
case .private: \.lockSolid case .private: \.lockSolid
case .restricted: nil case .restricted: nil
@@ -47,16 +47,16 @@ struct SpaceRoomCell: View {
} }
private var details: String { private var details: String {
if spaceRoomProxy.isSpace { if spaceServiceRoom.isSpace {
L10n.commonMemberCount(spaceRoomProxy.joinedMembersCount) L10n.commonMemberCount(spaceServiceRoom.joinedMembersCount)
} else { } else {
spaceRoomProxy.topic ?? " " // Use a single space to reserve a consistent amount of space. spaceServiceRoom.topic ?? " " // Use a single space to reserve a consistent amount of space.
} }
} }
var body: some View { var body: some View {
Button { Button {
action(.select(spaceRoomProxy)) action(.select(spaceServiceRoom))
} label: { } label: {
HStack(spacing: 16.0) { HStack(spacing: 16.0) {
avatar avatar
@@ -74,13 +74,13 @@ struct SpaceRoomCell: View {
.accessibilityElement(children: .combine) .accessibilityElement(children: .combine)
} }
.buttonStyle(SpaceRoomCellButtonStyle(isSelected: isSelected)) .buttonStyle(SpaceRoomCellButtonStyle(isSelected: isSelected))
.accessibilityIdentifier(A11yIdentifiers.spaceListScreen.spaceRoomName(spaceRoomProxy.name)) .accessibilityIdentifier(A11yIdentifiers.spaceListScreen.spaceRoomName(spaceServiceRoom.name))
} }
@ViewBuilder @MainActor @ViewBuilder @MainActor
private var avatar: some View { private var avatar: some View {
if dynamicTypeSize < .accessibility3 { if dynamicTypeSize < .accessibility3 {
RoomAvatarImage(avatar: spaceRoomProxy.avatar, RoomAvatarImage(avatar: spaceServiceRoom.avatar,
avatarSize: .room(on: .spaces), avatarSize: .room(on: .spaces),
mediaProvider: mediaProvider) mediaProvider: mediaProvider)
.dynamicTypeSize(dynamicTypeSize < .accessibility1 ? dynamicTypeSize : .accessibility1) .dynamicTypeSize(dynamicTypeSize < .accessibility1 ? dynamicTypeSize : .accessibility1)
@@ -91,7 +91,7 @@ struct SpaceRoomCell: View {
private var content: some View { private var content: some View {
HStack(spacing: 16) { HStack(spacing: 16) {
VStack(alignment: .leading, spacing: 2) { VStack(alignment: .leading, spacing: 2) {
Text(spaceRoomProxy.name) Text(spaceServiceRoom.name)
.font(.compound.bodyLGSemibold) .font(.compound.bodyLGSemibold)
.foregroundColor(.compound.textPrimary) .foregroundColor(.compound.textPrimary)
.lineLimit(1) .lineLimit(1)
@@ -128,9 +128,9 @@ struct SpaceRoomCell: View {
@ViewBuilder @ViewBuilder
private var accessory: some View { private var accessory: some View {
switch spaceRoomProxy.state { switch spaceServiceRoom.state {
case .none, .left, .invited: case .none, .left, .invited:
Button(L10n.actionJoin) { action(.join(spaceRoomProxy)) } Button(L10n.actionJoin) { action(.join(spaceServiceRoom)) }
.font(.compound.bodyLG) .font(.compound.bodyLG)
.foregroundStyle(.compound.textActionAccent) .foregroundStyle(.compound.textActionAccent)
.opacity(isJoining ? 0 : 1) .opacity(isJoining ? 0 : 1)
@@ -159,21 +159,21 @@ struct SpaceRoomCellButtonStyle: ButtonStyle {
struct SpaceRoomCell_Previews: PreviewProvider, TestablePreview { struct SpaceRoomCell_Previews: PreviewProvider, TestablePreview {
static let mediaProvider = MediaProviderMock(configuration: .init()) static let mediaProvider = MediaProviderMock(configuration: .init())
static let spaces = [SpaceRoomProxyProtocol].mockSpaceList static let spaces = [SpaceServiceRoomProtocol].mockSpaceList
static var previews: some View { static var previews: some View {
VStack(spacing: 0) { VStack(spacing: 0) {
ForEach(spaces, id: \.id) { space in ForEach(spaces, id: \.id) { space in
SpaceRoomCell(spaceRoomProxy: space, SpaceRoomCell(spaceServiceRoom: space,
isSelected: false, isSelected: false,
mediaProvider: mediaProvider) { _ in } mediaProvider: mediaProvider) { _ in }
} }
SpaceRoomCell(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "Space being joined", isSpace: true)), SpaceRoomCell(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "Space being joined", isSpace: true)),
isSelected: false, isSelected: false,
isJoining: true, isJoining: true,
mediaProvider: mediaProvider) { _ in } mediaProvider: mediaProvider) { _ in }
SpaceRoomCell(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "Room being joined", isSpace: false)), SpaceRoomCell(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "Room being joined", isSpace: false)),
isSelected: false, isSelected: false,
isJoining: true, isJoining: true,
mediaProvider: mediaProvider) { _ in } mediaProvider: mediaProvider) { _ in }
@@ -19,13 +19,13 @@ struct LeaveSpaceRoomDetailsCell: View {
let action: () -> Void let action: () -> Void
private var subtitle: String? { private var subtitle: String? {
guard !room.spaceRoomProxy.isSpace else { return nil } guard !room.spaceServiceRoom.isSpace else { return nil }
let memberCount = L10n.commonMemberCount(room.spaceRoomProxy.joinedMembersCount) let memberCount = L10n.commonMemberCount(room.spaceServiceRoom.joinedMembersCount)
return room.isLastAdmin ? L10n.screenLeaveSpaceLastAdminInfo(memberCount) : memberCount return room.isLastAdmin ? L10n.screenLeaveSpaceLastAdminInfo(memberCount) : memberCount
} }
var visibilityIcon: KeyPath<CompoundIcons, Image>? { var visibilityIcon: KeyPath<CompoundIcons, Image>? {
switch room.spaceRoomProxy.visibility { switch room.spaceServiceRoom.visibility {
case .public: \.public case .public: \.public
case .private: \.lockSolid case .private: \.lockSolid
case .restricted: nil case .restricted: nil
@@ -37,13 +37,13 @@ struct LeaveSpaceRoomDetailsCell: View {
Button(action: action) { Button(action: action) {
HStack(spacing: 16) { HStack(spacing: 16) {
if dynamicTypeSize < .accessibility3 { if dynamicTypeSize < .accessibility3 {
RoomAvatarImage(avatar: room.spaceRoomProxy.avatar, RoomAvatarImage(avatar: room.spaceServiceRoom.avatar,
avatarSize: .room(on: .leaveSpace), avatarSize: .room(on: .leaveSpace),
mediaProvider: mediaProvider) mediaProvider: mediaProvider)
} }
VStack(alignment: .leading, spacing: 0) { VStack(alignment: .leading, spacing: 0) {
Text(room.spaceRoomProxy.name) Text(room.spaceServiceRoom.name)
.font(.compound.bodyLGSemibold) .font(.compound.bodyLGSemibold)
.foregroundStyle(.compound.textPrimary) .foregroundStyle(.compound.textPrimary)
.lineLimit(1) .lineLimit(1)
@@ -91,38 +91,38 @@ struct LeaveSpaceRoomDetailsCell: View {
struct LeaveSpaceRoomDetailsCell_Previews: PreviewProvider, TestablePreview { struct LeaveSpaceRoomDetailsCell_Previews: PreviewProvider, TestablePreview {
static var previews: some View { static var previews: some View {
VStack(spacing: 0) { VStack(spacing: 0) {
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "1", LeaveSpaceRoomDetailsCell(room: .init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "1",
name: "Space", name: "Space",
isSpace: true)), isSpace: true)),
isLastAdmin: false, isLastAdmin: false,
isSelected: true), isSelected: true),
mediaProvider: MediaProviderMock(configuration: .init())) { } mediaProvider: MediaProviderMock(configuration: .init())) { }
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "2", LeaveSpaceRoomDetailsCell(room: .init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "2",
name: "My Space", name: "My Space",
isSpace: true)), isSpace: true)),
isLastAdmin: true, isLastAdmin: true,
isSelected: false), isSelected: false),
mediaProvider: MediaProviderMock(configuration: .init())) { } mediaProvider: MediaProviderMock(configuration: .init())) { }
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "2", LeaveSpaceRoomDetailsCell(room: .init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "2",
name: "My Space", name: "My Space",
isSpace: true)), isSpace: true)),
isLastAdmin: true, isLastAdmin: true,
isSelected: false), isSelected: false),
hideSelection: true, hideSelection: true,
mediaProvider: MediaProviderMock(configuration: .init())) { } mediaProvider: MediaProviderMock(configuration: .init())) { }
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "3", LeaveSpaceRoomDetailsCell(room: .init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "3",
name: "Room", name: "Room",
isSpace: false)), isSpace: false)),
isLastAdmin: false, isLastAdmin: false,
isSelected: true), isSelected: true),
mediaProvider: MediaProviderMock(configuration: .init())) { } mediaProvider: MediaProviderMock(configuration: .init())) { }
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "4", LeaveSpaceRoomDetailsCell(room: .init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "4",
name: "My Room", name: "My Room",
isSpace: false)), isSpace: false)),
isLastAdmin: true, isLastAdmin: true,
isSelected: false), isSelected: false),
mediaProvider: MediaProviderMock(configuration: .init())) { } mediaProvider: MediaProviderMock(configuration: .init())) { }
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "4", LeaveSpaceRoomDetailsCell(room: .init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "4",
name: "My Room", name: "My Room",
isSpace: false)), isSpace: false)),
isLastAdmin: true, isLastAdmin: true,
@@ -64,11 +64,11 @@ struct LeaveSpaceView: View {
context.viewState.leaveHandle.canLeave { context.viewState.leaveHandle.canLeave {
LazyVStack(spacing: 0, pinnedViews: .sectionHeaders) { LazyVStack(spacing: 0, pinnedViews: .sectionHeaders) {
Section { Section {
ForEach(context.viewState.leaveHandle.rooms, id: \.spaceRoomProxy.id) { room in ForEach(context.viewState.leaveHandle.rooms, id: \.spaceServiceRoom.id) { room in
LeaveSpaceRoomDetailsCell(room: room, LeaveSpaceRoomDetailsCell(room: room,
hideSelection: context.viewState.leaveHandle.mode == .onlyAdminRooms, hideSelection: context.viewState.leaveHandle.mode == .onlyAdminRooms,
mediaProvider: context.mediaProvider) { mediaProvider: context.mediaProvider) {
context.send(viewAction: .toggleRoom(roomID: room.spaceRoomProxy.id)) context.send(viewAction: .toggleRoom(roomID: room.spaceServiceRoom.id))
} }
.disabled(room.isLastAdmin) .disabled(room.isLastAdmin)
} }
@@ -136,7 +136,7 @@ struct LeaveSpaceView_Previews: PreviewProvider, TestablePreview {
.previewDisplayName("Last Space Admin") .previewDisplayName("Last Space Admin")
} }
static let spaceRoomProxy = SpaceRoomProxyMock(.init(id: "!eng-space:matrix.org", static let spaceServiceRoom = SpaceServiceRoomMock(.init(id: "!eng-space:matrix.org",
name: "Engineering Team", name: "Engineering Team",
isSpace: true, isSpace: true,
childrenCount: 30, childrenCount: 30,
@@ -149,14 +149,14 @@ struct LeaveSpaceView_Previews: PreviewProvider, TestablePreview {
let rooms: [LeaveSpaceRoom] = switch mode { let rooms: [LeaveSpaceRoom] = switch mode {
case .manyRooms: .mockRooms case .manyRooms: .mockRooms
case .onlyAdminRooms: .mockAdminRooms case .onlyAdminRooms: .mockAdminRooms
case .noRooms: .mockSingleSpace(spaceRoomProxy: spaceRoomProxy, isLastAdmin: false) case .noRooms: .mockSingleSpace(spaceServiceRoom: spaceServiceRoom, isLastAdmin: false)
case .lastSpaceAdmin: .mockRoomsWithSpace(spaceRoomProxy: spaceRoomProxy, isLastAdmin: true) case .lastSpaceAdmin: .mockRoomsWithSpace(spaceServiceRoom: spaceServiceRoom, isLastAdmin: true)
} }
let leaveHandle = LeaveSpaceHandleProxy(spaceID: spaceRoomProxy.id, let leaveHandle = LeaveSpaceHandleProxy(spaceID: spaceServiceRoom.id,
leaveHandle: LeaveSpaceHandleSDKMock(.init(rooms: rooms))) leaveHandle: LeaveSpaceHandleSDKMock(.init(rooms: rooms)))
return LeaveSpaceViewModel(spaceName: spaceRoomProxy.name, return LeaveSpaceViewModel(spaceName: spaceServiceRoom.name,
canEditRolesAndPermissions: true, canEditRolesAndPermissions: true,
leaveHandle: leaveHandle, leaveHandle: leaveHandle,
userIndicatorController: UserIndicatorControllerMock(), userIndicatorController: UserIndicatorControllerMock(),
@@ -18,7 +18,7 @@ struct SpaceListScreenViewState: BindableState {
var userDisplayName: String? var userDisplayName: String?
var userAvatarURL: URL? var userAvatarURL: URL?
var topLevelSpaces: [SpaceRoomProxyProtocol] var topLevelSpaces: [SpaceServiceRoomProtocol]
var selectedSpaceID: String? var selectedSpaceID: String?
var isCreateSpaceEnabled: Bool var isCreateSpaceEnabled: Bool
@@ -65,8 +65,8 @@ class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenVie
MXLog.info("View model: received view action: \(viewAction)") MXLog.info("View model: received view action: \(viewAction)")
switch viewAction { switch viewAction {
case .spaceAction(.select(let spaceRoomProxy)): case .spaceAction(.select(let spaceServiceRoom)):
Task { await selectSpace(spaceRoomProxy) } Task { await selectSpace(spaceServiceRoom) }
case .spaceAction(.join): case .spaceAction(.join):
fatalError("There shouldn't be any unjoined spaces in the joined spaces list.") fatalError("There shouldn't be any unjoined spaces in the joined spaces list.")
case .showSettings: case .showSettings:
@@ -86,8 +86,8 @@ class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenVie
// MARK: - Private // MARK: - Private
private func selectSpace(_ spaceRoomProxy: SpaceRoomProxyProtocol) async { private func selectSpace(_ spaceServiceRoom: SpaceServiceRoomProtocol) async {
switch await spaceServiceProxy.spaceRoomList(spaceID: spaceRoomProxy.id) { switch await spaceServiceProxy.spaceRoomList(spaceID: spaceServiceRoom.id) {
case .success(let spaceRoomListProxy): case .success(let spaceRoomListProxy):
actionsSubject.send(.selectSpace(spaceRoomListProxy)) actionsSubject.send(.selectSpace(spaceRoomListProxy))
case .failure(let error): case .failure(let error):
@@ -85,9 +85,9 @@ struct SpaceListScreen: View {
} }
private var spaces: some View { private var spaces: some View {
ForEach(context.viewState.topLevelSpaces, id: \.id) { spaceRoomProxy in ForEach(context.viewState.topLevelSpaces, id: \.id) { spaceServiceRoom in
SpaceRoomCell(spaceRoomProxy: spaceRoomProxy, SpaceRoomCell(spaceServiceRoom: spaceServiceRoom,
isSelected: spaceRoomProxy.id == context.viewState.selectedSpaceID, isSelected: spaceServiceRoom.id == context.viewState.selectedSpaceID,
mediaProvider: context.mediaProvider) { action in mediaProvider: context.mediaProvider) { action in
context.send(viewAction: .spaceAction(action)) context.send(viewAction: .spaceAction(action))
} }
@@ -22,7 +22,7 @@ struct SpaceScreenCoordinatorParameters {
enum SpaceScreenCoordinatorAction { enum SpaceScreenCoordinatorAction {
case selectSpace(SpaceRoomListProxyProtocol) case selectSpace(SpaceRoomListProxyProtocol)
case selectUnjoinedSpace(SpaceRoomProxyProtocol) case selectUnjoinedSpace(SpaceServiceRoomProtocol)
case selectRoom(roomID: String) case selectRoom(roomID: String)
case leftSpace case leftSpace
case displayMembers(roomProxy: JoinedRoomProxyProtocol) case displayMembers(roomProxy: JoinedRoomProxyProtocol)
@@ -60,8 +60,8 @@ final class SpaceScreenCoordinator: CoordinatorProtocol {
switch action { switch action {
case .selectSpace(let spaceRoomListProxy): case .selectSpace(let spaceRoomListProxy):
actionsSubject.send(.selectSpace(spaceRoomListProxy)) actionsSubject.send(.selectSpace(spaceRoomListProxy))
case .selectUnjoinedSpace(let spaceRoomProxy): case .selectUnjoinedSpace(let spaceServiceRoom):
actionsSubject.send(.selectUnjoinedSpace(spaceRoomProxy)) actionsSubject.send(.selectUnjoinedSpace(spaceServiceRoom))
case .selectRoom(let roomID): case .selectRoom(let roomID):
actionsSubject.send(.selectRoom(roomID: roomID)) actionsSubject.send(.selectRoom(roomID: roomID))
case .leftSpace: case .leftSpace:
@@ -10,7 +10,7 @@ import Foundation
enum SpaceScreenViewModelAction { enum SpaceScreenViewModelAction {
case selectSpace(SpaceRoomListProxyProtocol) case selectSpace(SpaceRoomListProxyProtocol)
case selectUnjoinedSpace(SpaceRoomProxyProtocol) case selectUnjoinedSpace(SpaceServiceRoomProtocol)
case selectRoom(roomID: String) case selectRoom(roomID: String)
case leftSpace case leftSpace
case presentRolesAndPermissions(roomProxy: JoinedRoomProxyProtocol) case presentRolesAndPermissions(roomProxy: JoinedRoomProxyProtocol)
@@ -19,13 +19,13 @@ enum SpaceScreenViewModelAction {
} }
struct SpaceScreenViewState: BindableState { struct SpaceScreenViewState: BindableState {
var space: SpaceRoomProxyProtocol var space: SpaceServiceRoomProtocol
var permalink: URL? var permalink: URL?
var roomProxy: JoinedRoomProxyProtocol? var roomProxy: JoinedRoomProxyProtocol?
var isPaginating = false var isPaginating = false
var rooms: [SpaceRoomProxyProtocol] var rooms: [SpaceServiceRoomProtocol]
var selectedSpaceRoomID: String? var selectedSpaceRoomID: String?
var joiningRoomIDs: Set<String> = [] var joiningRoomIDs: Set<String> = []
@@ -37,12 +37,12 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
self.userIndicatorController = userIndicatorController self.userIndicatorController = userIndicatorController
self.appSettings = appSettings self.appSettings = appSettings
super.init(initialViewState: SpaceScreenViewState(space: spaceRoomListProxy.spaceRoomProxyPublisher.value, super.init(initialViewState: SpaceScreenViewState(space: spaceRoomListProxy.spaceServiceRoomPublisher.value,
rooms: spaceRoomListProxy.spaceRoomsPublisher.value, rooms: spaceRoomListProxy.spaceRoomsPublisher.value,
selectedSpaceRoomID: selectedSpaceRoomPublisher.value), selectedSpaceRoomID: selectedSpaceRoomPublisher.value),
mediaProvider: userSession.mediaProvider) mediaProvider: userSession.mediaProvider)
spaceRoomListProxy.spaceRoomProxyPublisher spaceRoomListProxy.spaceServiceRoomPublisher
.receive(on: DispatchQueue.main) .receive(on: DispatchQueue.main)
.weakAssign(to: \.state.space, on: self) .weakAssign(to: \.state.space, on: self)
.store(in: &cancellables) .store(in: &cancellables)
@@ -107,19 +107,19 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
MXLog.info("View model: received view action: \(viewAction)") MXLog.info("View model: received view action: \(viewAction)")
switch viewAction { switch viewAction {
case .spaceAction(.select(let spaceRoomProxy)): case .spaceAction(.select(let spaceServiceRoom)):
if spaceRoomProxy.isSpace { if spaceServiceRoom.isSpace {
if spaceRoomProxy.state != .joined { if spaceServiceRoom.state != .joined {
actionsSubject.send(.selectUnjoinedSpace(spaceRoomProxy)) actionsSubject.send(.selectUnjoinedSpace(spaceServiceRoom))
} else { } else {
Task { await selectSpace(spaceRoomProxy) } Task { await selectSpace(spaceServiceRoom) }
} }
} else { } else {
// No need to check the join state, the room flow will show an appropriately configured join screen if needed. // No need to check the join state, the room flow will show an appropriately configured join screen if needed.
actionsSubject.send(.selectRoom(roomID: spaceRoomProxy.id)) actionsSubject.send(.selectRoom(roomID: spaceServiceRoom.id))
} }
case .spaceAction(.join(let spaceRoomProxy)): case .spaceAction(.join(let spaceServiceRoom)):
Task { await join(spaceRoomProxy) } Task { await join(spaceServiceRoom) }
case .leaveSpace: case .leaveSpace:
Task { await showLeaveSpaceConfirmation() } Task { await showLeaveSpaceConfirmation() }
case .displayMembers(let roomProxy): case .displayMembers(let roomProxy):
@@ -136,11 +136,11 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
// MARK: - Private // MARK: - Private
private func join(_ spaceRoomProxy: SpaceRoomProxyProtocol) async { private func join(_ spaceServiceRoom: SpaceServiceRoomProtocol) async {
state.joiningRoomIDs.insert(spaceRoomProxy.id) state.joiningRoomIDs.insert(spaceServiceRoom.id)
defer { state.joiningRoomIDs.remove(spaceRoomProxy.id) } defer { state.joiningRoomIDs.remove(spaceServiceRoom.id) }
guard case .success = await clientProxy.joinRoom(spaceRoomProxy.id, via: spaceRoomProxy.via) else { guard case .success = await clientProxy.joinRoom(spaceServiceRoom.id, via: spaceServiceRoom.via) else {
showFailureIndicator() showFailureIndicator()
return return
} }
@@ -148,8 +148,8 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
// We don't want to show the space room after joining it this way 🤷‍♂️ // We don't want to show the space room after joining it this way 🤷‍♂️
} }
private func selectSpace(_ spaceRoomProxy: SpaceRoomProxyProtocol) async { private func selectSpace(_ spaceServiceRoom: SpaceServiceRoomProtocol) async {
switch await spaceServiceProxy.spaceRoomList(spaceID: spaceRoomProxy.id) { switch await spaceServiceProxy.spaceRoomList(spaceID: spaceServiceRoom.id) {
case .success(let spaceRoomListProxy): case .success(let spaceRoomListProxy):
actionsSubject.send(.selectSpace(spaceRoomListProxy)) actionsSubject.send(.selectSpace(spaceRoomListProxy))
case .failure(let error): case .failure(let error):
@@ -15,7 +15,7 @@ struct SpaceScreen: View {
var body: some View { var body: some View {
ScrollView { ScrollView {
LazyVStack(spacing: 0) { LazyVStack(spacing: 0) {
SpaceHeaderView(spaceRoomProxy: context.viewState.space, SpaceHeaderView(spaceServiceRoom: context.viewState.space,
mediaProvider: context.mediaProvider) mediaProvider: context.mediaProvider)
rooms rooms
} }
@@ -32,10 +32,10 @@ struct SpaceScreen: View {
@ViewBuilder @ViewBuilder
var rooms: some View { var rooms: some View {
ForEach(context.viewState.rooms, id: \.id) { spaceRoomProxy in ForEach(context.viewState.rooms, id: \.id) { spaceServiceRoom in
SpaceRoomCell(spaceRoomProxy: spaceRoomProxy, SpaceRoomCell(spaceServiceRoom: spaceServiceRoom,
isSelected: spaceRoomProxy.id == context.viewState.selectedSpaceRoomID, isSelected: spaceServiceRoom.id == context.viewState.selectedSpaceRoomID,
isJoining: context.viewState.joiningRoomIDs.contains(spaceRoomProxy.id), isJoining: context.viewState.joiningRoomIDs.contains(spaceServiceRoom.id),
mediaProvider: context.mediaProvider) { action in mediaProvider: context.mediaProvider) { action in
context.send(viewAction: .spaceAction(action)) context.send(viewAction: .spaceAction(action))
} }
@@ -114,7 +114,7 @@ struct SpaceScreen_Previews: PreviewProvider, TestablePreview {
} }
static func makeViewModel() -> SpaceScreenViewModel { static func makeViewModel() -> SpaceScreenViewModel {
let spaceRoomProxy = SpaceRoomProxyMock(.init(id: "!eng-space:matrix.org", let spaceServiceRoom = SpaceServiceRoomMock(.init(id: "!eng-space:matrix.org",
name: "Engineering Team", name: "Engineering Team",
isSpace: true, isSpace: true,
childrenCount: 30, childrenCount: 30,
@@ -123,7 +123,7 @@ struct SpaceScreen_Previews: PreviewProvider, TestablePreview {
topic: "Description of the space goes right here. Lorem ipsum dolor sit amet consectetur. Leo viverra morbi habitant in.", topic: "Description of the space goes right here. Lorem ipsum dolor sit amet consectetur. Leo viverra morbi habitant in.",
canonicalAlias: "#engineering-team:element.io", canonicalAlias: "#engineering-team:element.io",
joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")]))) joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")])))
let spaceRoomListProxy = SpaceRoomListProxyMock(.init(spaceRoomProxy: spaceRoomProxy, let spaceRoomListProxy = SpaceRoomListProxyMock(.init(spaceServiceRoom: spaceServiceRoom,
initialSpaceRooms: .mockSpaceList)) initialSpaceRooms: .mockSpaceList))
let clientProxy = ClientProxyMock(.init()) let clientProxy = ClientProxyMock(.init())
@@ -35,7 +35,7 @@ final class LeaveSpaceHandleProxy {
room.spaceRoom.roomId != spaceID else { room.spaceRoom.roomId != spaceID else {
return nil return nil
} }
return .init(spaceRoomProxy: SpaceRoomProxy(spaceRoom: room.spaceRoom), return .init(spaceServiceRoom: SpaceServiceRoom(spaceRoom: room.spaceRoom),
isLastAdmin: room.isLastAdmin, isLastAdmin: room.isLastAdmin,
isSelected: !room.isLastAdmin) isSelected: !room.isLastAdmin)
} }
@@ -64,21 +64,21 @@ final class LeaveSpaceHandleProxy {
} }
func toggleRoom(roomID: String) { func toggleRoom(roomID: String) {
guard let room = rooms.first(where: { $0.spaceRoomProxy.id == roomID }) else { guard let room = rooms.first(where: { $0.spaceServiceRoom.id == roomID }) else {
return return
} }
room.isSelected.toggle() room.isSelected.toggle()
} }
func leave() async -> Result<Void, SpaceServiceProxyError> { func leave() async -> Result<Void, SpaceServiceProxyError> {
let selectedRoomIDs = rooms.filter(\.isSelected).map(\.spaceRoomProxy.id) let selectedRoomIDs = rooms.filter(\.isSelected).map(\.spaceServiceRoom.id)
do { do {
return try await .success(leaveHandle.leave(roomIds: selectedRoomIDs + [id])) return try await .success(leaveHandle.leave(roomIds: selectedRoomIDs + [id]))
} catch { } catch {
MXLog.error("Failed leaving space \(id): \(error)") MXLog.error("Failed leaving space \(id): \(error)")
rooms = rooms.filter { leaveRoom in rooms = rooms.filter { leaveRoom in
leaveHandle.rooms().contains { $0.spaceRoom.roomId == leaveRoom.spaceRoomProxy.id } leaveHandle.rooms().contains { $0.spaceRoom.roomId == leaveRoom.spaceServiceRoom.id }
} }
return .failure(.sdkError(error)) return .failure(.sdkError(error))
} }
@@ -86,12 +86,12 @@ final class LeaveSpaceHandleProxy {
} }
@Observable class LeaveSpaceRoomDetails { @Observable class LeaveSpaceRoomDetails {
let spaceRoomProxy: SpaceRoomProxyProtocol let spaceServiceRoom: SpaceServiceRoomProtocol
let isLastAdmin: Bool let isLastAdmin: Bool
var isSelected: Bool var isSelected: Bool
init(spaceRoomProxy: SpaceRoomProxyProtocol, isLastAdmin: Bool, isSelected: Bool) { init(spaceServiceRoom: SpaceServiceRoomProtocol, isLastAdmin: Bool, isSelected: Bool) {
self.spaceRoomProxy = spaceRoomProxy self.spaceServiceRoom = spaceServiceRoom
self.isLastAdmin = isLastAdmin self.isLastAdmin = isLastAdmin
self.isSelected = isSelected self.isSelected = isSelected
} }
@@ -10,19 +10,19 @@ import Combine
import MatrixRustSDK import MatrixRustSDK
class SpaceRoomListProxy: SpaceRoomListProxyProtocol { class SpaceRoomListProxy: SpaceRoomListProxyProtocol {
var id: String { spaceRoomProxyPublisher.value.id } var id: String { spaceServiceRoomPublisher.value.id }
private let spaceRoomList: SpaceRoomListProtocol private let spaceRoomList: SpaceRoomListProtocol
private var spaceRoomProxyHandle: TaskHandle? private var spaceServiceRoomHandle: TaskHandle?
private let spaceRoomProxySubject: CurrentValueSubject<SpaceRoomProxyProtocol, Never> private let spaceServiceRoomSubject: CurrentValueSubject<SpaceServiceRoomProtocol, Never>
var spaceRoomProxyPublisher: CurrentValuePublisher<SpaceRoomProxyProtocol, Never> { var spaceServiceRoomPublisher: CurrentValuePublisher<SpaceServiceRoomProtocol, Never> {
spaceRoomProxySubject.asCurrentValuePublisher() spaceServiceRoomSubject.asCurrentValuePublisher()
} }
private var spaceRoomsHandle: TaskHandle? private var spaceRoomsHandle: TaskHandle?
private let spaceRoomsSubject = CurrentValueSubject<[SpaceRoomProxyProtocol], Never>([]) private let spaceRoomsSubject = CurrentValueSubject<[SpaceServiceRoomProtocol], Never>([])
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> { var spaceRoomsPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> {
spaceRoomsSubject.asCurrentValuePublisher() spaceRoomsSubject.asCurrentValuePublisher()
} }
@@ -33,7 +33,7 @@ class SpaceRoomListProxy: SpaceRoomListProxyProtocol {
guard let spaceRoom = spaceRoomList.space() else { throw SpaceRoomListProxyError.missingSpace } guard let spaceRoom = spaceRoomList.space() else { throw SpaceRoomListProxyError.missingSpace }
self.spaceRoomList = spaceRoomList self.spaceRoomList = spaceRoomList
spaceRoomProxySubject = .init(SpaceRoomProxy(spaceRoom: spaceRoom)) spaceServiceRoomSubject = .init(SpaceServiceRoom(spaceRoom: spaceRoom))
let paginationStateSubject = CurrentValueSubject<SpaceRoomListPaginationState, Never>(spaceRoomList.paginationState()) let paginationStateSubject = CurrentValueSubject<SpaceRoomListPaginationState, Never>(spaceRoomList.paginationState())
paginationStatePublisher = paginationStateSubject.asCurrentValuePublisher() paginationStatePublisher = paginationStateSubject.asCurrentValuePublisher()
@@ -46,9 +46,9 @@ class SpaceRoomListProxy: SpaceRoomListProxyProtocol {
self?.handleUpdates(updates) self?.handleUpdates(updates)
}) })
spaceRoomProxyHandle = spaceRoomList.subscribeToSpaceUpdates(listener: SDKListener { [weak self] spaceRoom in spaceServiceRoomHandle = spaceRoomList.subscribeToSpaceUpdates(listener: SDKListener { [weak self] spaceRoom in
guard let spaceRoom else { return } guard let spaceRoom else { return }
self?.spaceRoomProxySubject.send(SpaceRoomProxy(spaceRoom: spaceRoom)) self?.spaceServiceRoomSubject.send(SpaceServiceRoom(spaceRoom: spaceRoom))
}) })
} }
@@ -68,27 +68,27 @@ class SpaceRoomListProxy: SpaceRoomListProxyProtocol {
for update in updates { for update in updates {
switch update { switch update {
case .append(let spaceRooms): case .append(let spaceRooms):
rooms.append(contentsOf: spaceRooms.map(SpaceRoomProxy.init)) rooms.append(contentsOf: spaceRooms.map(SpaceServiceRoom.init))
case .clear: case .clear:
rooms.removeAll() rooms.removeAll()
case .pushFront(let spaceRoom): case .pushFront(let spaceRoom):
rooms.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: 0) rooms.insert(SpaceServiceRoom(spaceRoom: spaceRoom), at: 0)
case .pushBack(let spaceRoom): case .pushBack(let spaceRoom):
rooms.append(SpaceRoomProxy(spaceRoom: spaceRoom)) rooms.append(SpaceServiceRoom(spaceRoom: spaceRoom))
case .popFront: case .popFront:
rooms.removeFirst() rooms.removeFirst()
case .popBack: case .popBack:
rooms.removeLast() rooms.removeLast()
case .insert(let index, let spaceRoom): case .insert(let index, let spaceRoom):
rooms.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: Int(index)) rooms.insert(SpaceServiceRoom(spaceRoom: spaceRoom), at: Int(index))
case .set(let index, let spaceRoom): case .set(let index, let spaceRoom):
rooms[Int(index)] = SpaceRoomProxy(spaceRoom: spaceRoom) rooms[Int(index)] = SpaceServiceRoom(spaceRoom: spaceRoom)
case .remove(let index): case .remove(let index):
rooms.remove(at: Int(index)) rooms.remove(at: Int(index))
case .truncate(let length): case .truncate(let length):
rooms.removeSubrange(Int(length)..<rooms.count) rooms.removeSubrange(Int(length)..<rooms.count)
case .reset(let spaceRooms): case .reset(let spaceRooms):
rooms = spaceRooms.map(SpaceRoomProxy.init) rooms = spaceRooms.map(SpaceServiceRoom.init)
} }
} }
@@ -17,8 +17,8 @@ enum SpaceRoomListProxyError: Error {
protocol SpaceRoomListProxyProtocol { protocol SpaceRoomListProxyProtocol {
var id: String { get } var id: String { get }
var spaceRoomProxyPublisher: CurrentValuePublisher<SpaceRoomProxyProtocol, Never> { get } var spaceServiceRoomPublisher: CurrentValuePublisher<SpaceServiceRoomProtocol, Never> { get }
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> { get } var spaceRoomsPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> { get }
var paginationStatePublisher: CurrentValuePublisher<SpaceRoomListPaginationState, Never> { get } var paginationStatePublisher: CurrentValuePublisher<SpaceRoomListPaginationState, Never> { get }
func paginate() async func paginate() async
@@ -1,38 +0,0 @@
//
// Copyright 2025 Element Creations Ltd.
// Copyright 2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import Foundation
import MatrixRustSDK
class SpaceRoomProxy: SpaceRoomProxyProtocol {
private let spaceRoom: SpaceRoom
init(spaceRoom: SpaceRoom) {
self.spaceRoom = spaceRoom
}
lazy var id = spaceRoom.roomId
var name: String { spaceRoom.displayName }
var rawName: String? { spaceRoom.rawName }
var avatarURL: URL? { spaceRoom.avatarUrl.flatMap(URL.init) }
var isSpace: Bool { spaceRoom.roomType == .space }
var isDirect: Bool? { spaceRoom.isDirect }
var childrenCount: Int { Int(spaceRoom.childrenCount) }
var joinedMembersCount: Int { Int(spaceRoom.numJoinedMembers) }
var heroes: [UserProfileProxy] { (spaceRoom.heroes ?? []).map(UserProfileProxy.init) }
var topic: String? { spaceRoom.topic }
var canonicalAlias: String? { spaceRoom.canonicalAlias }
var joinRule: JoinRule? { spaceRoom.joinRule }
var worldReadable: Bool? { spaceRoom.worldReadable }
var guestCanJoin: Bool { spaceRoom.guestCanJoin }
var state: Membership? { spaceRoom.state }
var via: [String] { spaceRoom.via }
}
@@ -14,8 +14,8 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
private let spaceService: SpaceServiceProtocol private let spaceService: SpaceServiceProtocol
private var topLevelSpacesHandle: TaskHandle? private var topLevelSpacesHandle: TaskHandle?
private let spacesSubject = CurrentValueSubject<[SpaceRoomProxyProtocol], Never>([]) private let spacesSubject = CurrentValueSubject<[SpaceServiceRoomProtocol], Never>([])
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> { var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> {
spacesSubject.asCurrentValuePublisher() spacesSubject.asCurrentValuePublisher()
} }
@@ -40,9 +40,9 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
} }
} }
func spaceForIdentifier(spaceID: String) async -> Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError> { func spaceForIdentifier(spaceID: String) async -> Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError> {
do { do {
return try await .success(spaceService.getSpaceRoom(roomId: spaceID).map(SpaceRoomProxy.init)) return try await .success(spaceService.getSpaceRoom(roomId: spaceID).map(SpaceServiceRoom.init))
} catch { } catch {
MXLog.error("Failed getting space room for \(spaceID): \(error)") MXLog.error("Failed getting space room for \(spaceID): \(error)")
return .failure(.sdkError(error)) return .failure(.sdkError(error))
@@ -58,9 +58,9 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
} }
} }
func joinedParents(childID: String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError> { func joinedParents(childID: String) async -> Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError> {
do { do {
return try await .success(spaceService.joinedParentsOfChild(childId: childID).map(SpaceRoomProxy.init)) return try await .success(spaceService.joinedParentsOfChild(childId: childID).map(SpaceServiceRoom.init))
} catch { } catch {
MXLog.error("Failed to get joined parents for \(childID): \(error)") MXLog.error("Failed to get joined parents for \(childID): \(error)")
return .failure(.sdkError(error)) return .failure(.sdkError(error))
@@ -75,27 +75,27 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
for update in updates { for update in updates {
switch update { switch update {
case .append(let spaceRooms): case .append(let spaceRooms):
spaces.append(contentsOf: spaceRooms.map(SpaceRoomProxy.init)) spaces.append(contentsOf: spaceRooms.map(SpaceServiceRoom.init))
case .clear: case .clear:
spaces.removeAll() spaces.removeAll()
case .pushFront(let spaceRoom): case .pushFront(let spaceRoom):
spaces.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: 0) spaces.insert(SpaceServiceRoom(spaceRoom: spaceRoom), at: 0)
case .pushBack(let spaceRoom): case .pushBack(let spaceRoom):
spaces.append(SpaceRoomProxy(spaceRoom: spaceRoom)) spaces.append(SpaceServiceRoom(spaceRoom: spaceRoom))
case .popFront: case .popFront:
spaces.removeFirst() spaces.removeFirst()
case .popBack: case .popBack:
spaces.removeLast() spaces.removeLast()
case .insert(let index, let spaceRoom): case .insert(let index, let spaceRoom):
spaces.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: Int(index)) spaces.insert(SpaceServiceRoom(spaceRoom: spaceRoom), at: Int(index))
case .set(let index, let spaceRoom): case .set(let index, let spaceRoom):
spaces[Int(index)] = SpaceRoomProxy(spaceRoom: spaceRoom) spaces[Int(index)] = SpaceServiceRoom(spaceRoom: spaceRoom)
case .remove(let index): case .remove(let index):
spaces.remove(at: Int(index)) spaces.remove(at: Int(index))
case .truncate(let length): case .truncate(let length):
spaces.removeSubrange(Int(length)..<spaces.count) spaces.removeSubrange(Int(length)..<spaces.count)
case .reset(let spaceRooms): case .reset(let spaceRooms):
spaces = spaceRooms.map(SpaceRoomProxy.init) spaces = spaceRooms.map(SpaceServiceRoom.init)
} }
} }
@@ -15,12 +15,12 @@ enum SpaceServiceProxyError: Error {
// sourcery: AutoMockable // sourcery: AutoMockable
protocol SpaceServiceProxyProtocol { protocol SpaceServiceProxyProtocol {
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> { get } var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> { get }
func spaceRoomList(spaceID: String) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError> func spaceRoomList(spaceID: String) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError>
/// Returns a joined space given its identifier /// Returns a joined space given its identifier
func spaceForIdentifier(spaceID: String) async -> Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError> func spaceForIdentifier(spaceID: String) async -> Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError>
func leaveSpace(spaceID: String) async -> Result<LeaveSpaceHandleProxy, SpaceServiceProxyError> func leaveSpace(spaceID: String) async -> Result<LeaveSpaceHandleProxy, SpaceServiceProxyError>
/// Returns all the parent spaces of a child that user has joined. /// Returns all the parent spaces of a child that user has joined.
func joinedParents(childID: String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError> func joinedParents(childID: String) async -> Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError>
} }
@@ -0,0 +1,54 @@
//
// Copyright 2025 Element Creations Ltd.
// Copyright 2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import Foundation
import MatrixRustSDK
struct SpaceServiceRoom: SpaceServiceRoomProtocol {
var id: String
var name: String
var rawName: String?
var avatarURL: URL?
var isSpace: Bool
var isDirect: Bool?
var childrenCount: Int
var joinedMembersCount: Int
var heroes: [UserProfileProxy]
var topic: String?
var canonicalAlias: String?
var joinRule: JoinRule?
var worldReadable: Bool?
var guestCanJoin: Bool
var state: Membership?
var via: [String]
init(spaceRoom: SpaceRoom) {
id = spaceRoom.roomId
name = spaceRoom.displayName
rawName = spaceRoom.rawName
avatarURL = spaceRoom.avatarUrl.flatMap(URL.init)
isSpace = spaceRoom.roomType == .space
isDirect = spaceRoom.isDirect
childrenCount = Int(spaceRoom.childrenCount)
joinedMembersCount = Int(spaceRoom.numJoinedMembers)
heroes = (spaceRoom.heroes ?? []).map(UserProfileProxy.init)
topic = spaceRoom.topic
canonicalAlias = spaceRoom.canonicalAlias
joinRule = spaceRoom.joinRule
worldReadable = spaceRoom.worldReadable
guestCanJoin = spaceRoom.guestCanJoin
state = spaceRoom.state
via = spaceRoom.via
}
}
@@ -9,7 +9,7 @@
import Foundation import Foundation
import MatrixRustSDK import MatrixRustSDK
enum SpaceRoomProxyVisibility: Equatable { enum SpaceServiceRoomVisibility: Equatable {
case `public` case `public`
case `private` case `private`
case restricted case restricted
@@ -17,7 +17,7 @@ enum SpaceRoomProxyVisibility: Equatable {
} }
// sourcery: AutoMockable // sourcery: AutoMockable
protocol SpaceRoomProxyProtocol { protocol SpaceServiceRoomProtocol {
var id: String { get } var id: String { get }
var name: String { get } var name: String { get }
var rawName: String? { get } var rawName: String? { get }
@@ -39,7 +39,7 @@ protocol SpaceRoomProxyProtocol {
var via: [String] { get } var via: [String] { get }
} }
extension SpaceRoomProxyProtocol { extension SpaceServiceRoomProtocol {
var avatar: RoomAvatar { var avatar: RoomAvatar {
if isSpace { if isSpace {
.space(id: id, name: name, avatarURL: avatarURL) .space(id: id, name: name, avatarURL: avatarURL)
@@ -50,7 +50,7 @@ extension SpaceRoomProxyProtocol {
} }
} }
var visibility: SpaceRoomProxyVisibility? { var visibility: SpaceServiceRoomVisibility? {
switch joinRule { switch joinRule {
case .public: case .public:
.public .public
@@ -597,7 +597,7 @@ class MockScreen: Identifiable {
deviceID: "MOCKCLIENT", deviceID: "MOCKCLIENT",
roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(roomSummaries))), roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(roomSummaries))),
spaceServiceConfiguration: .init(topLevelSpaces: .mockSingleRoom), spaceServiceConfiguration: .init(topLevelSpaces: .mockSingleRoom),
roomPreviews: [SpaceRoomProxyProtocol].mockSpaceList.map(RoomPreviewProxyMock.init))) roomPreviews: [SpaceServiceRoomProtocol].mockSpaceList.map(RoomPreviewProxyMock.init)))
// The tab bar remains hidden for the non-spaces tests as we don't supply any mock spaces. // The tab bar remains hidden for the non-spaces tests as we don't supply any mock spaces.
let spaceServiceProxy = SpaceServiceProxyMock(id == .userSessionSpacesFlow ? .populated : .init()) let spaceServiceProxy = SpaceServiceProxyMock(id == .userSessionSpacesFlow ? .populated : .init())
@@ -311,7 +311,7 @@ class HomeScreenViewModelTests: XCTestCase {
XCTAssertEqual(invitedRoomIDs.count, 2) XCTAssertEqual(invitedRoomIDs.count, 2)
let deferred = deferFulfillment(viewModel.actions) { let deferred = deferFulfillment(viewModel.actions) {
$0 == .presentSpace(SpaceRoomListProxyMock(.init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: invitedRoomIDs[0], isSpace: true))))) $0 == .presentSpace(SpaceRoomListProxyMock(.init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: invitedRoomIDs[0], isSpace: true)))))
} }
context.send(viewAction: .acceptInvite(roomIdentifier: invitedRoomIDs[0])) context.send(viewAction: .acceptInvite(roomIdentifier: invitedRoomIDs[0]))
try await deferred.fulfill() try await deferred.fulfill()
@@ -408,7 +408,7 @@ class HomeScreenViewModelTests: XCTestCase {
let spaceServiceProxy = SpaceServiceProxyMock(.init()) let spaceServiceProxy = SpaceServiceProxyMock(.init())
spaceServiceProxy.spaceRoomListSpaceIDClosure = { spaceID in spaceServiceProxy.spaceRoomListSpaceIDClosure = { spaceID in
.success(SpaceRoomListProxyMock(.init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: spaceID, isSpace: true))))) .success(SpaceRoomListProxyMock(.init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: spaceID, isSpace: true)))))
} }
clientProxy.underlyingSpaceService = spaceServiceProxy clientProxy.underlyingSpaceService = spaceServiceProxy
case nil: case nil:
@@ -29,7 +29,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
} }
func testSetSingleJoinedSpaceMembersAccess() async throws { func testSetSingleJoinedSpaceMembersAccess() async throws {
let singleRoom = [SpaceRoomProxyProtocol].mockSingleRoom let singleRoom = [SpaceServiceRoomProtocol].mockSingleRoom
let space = singleRoom[0] let space = singleRoom[0]
setupViewModel(joinedParentSpaces: singleRoom, joinRule: .public) setupViewModel(joinedParentSpaces: singleRoom, joinRule: .public)
@@ -60,7 +60,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
} }
func testSetSingleJoinedAskToJoinWithSpaceMembersAccess() async throws { func testSetSingleJoinedAskToJoinWithSpaceMembersAccess() async throws {
let singleRoom = [SpaceRoomProxyProtocol].mockSingleRoom let singleRoom = [SpaceServiceRoomProtocol].mockSingleRoom
let space = singleRoom[0] let space = singleRoom[0]
setupViewModel(joinedParentSpaces: singleRoom, joinRule: .public) setupViewModel(joinedParentSpaces: singleRoom, joinRule: .public)
@@ -91,7 +91,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
} }
func testSingleUnknownSpaceMembersAccessCanBeReselected() async throws { func testSingleUnknownSpaceMembersAccessCanBeReselected() async throws {
let singleRoom = [SpaceRoomProxyProtocol].mockSingleRoom let singleRoom = [SpaceServiceRoomProtocol].mockSingleRoom
let space = singleRoom[0] let space = singleRoom[0]
setupViewModel(joinedParentSpaces: [], joinRule: .restricted(rules: [.roomMembership(roomId: space.id)])) setupViewModel(joinedParentSpaces: [], joinRule: .restricted(rules: [.roomMembership(roomId: space.id)]))
@@ -122,7 +122,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
} }
func testMultipleKnownSpacesMembersSelection() async throws { func testMultipleKnownSpacesMembersSelection() async throws {
let spaces = [SpaceRoomProxyProtocol].mockJoinedSpaces2 let spaces = [SpaceServiceRoomProtocol].mockJoinedSpaces2
setupViewModel(joinedParentSpaces: spaces, joinRule: .public) setupViewModel(joinedParentSpaces: spaces, joinRule: .public)
let deferred = deferFulfillment(context.$viewState) { $0.selectableJoinedSpaces.count == 3 } let deferred = deferFulfillment(context.$viewState) { $0.selectableJoinedSpaces.count == 3 }
@@ -166,7 +166,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
} }
func testMultipleKnownAskToJoinSpacesMembersSelection() async throws { func testMultipleKnownAskToJoinSpacesMembersSelection() async throws {
let spaces = [SpaceRoomProxyProtocol].mockJoinedSpaces2 let spaces = [SpaceServiceRoomProtocol].mockJoinedSpaces2
setupViewModel(joinedParentSpaces: spaces, joinRule: .public) setupViewModel(joinedParentSpaces: spaces, joinRule: .public)
let deferred = deferFulfillment(context.$viewState) { $0.selectableJoinedSpaces.count == 3 } let deferred = deferFulfillment(context.$viewState) { $0.selectableJoinedSpaces.count == 3 }
@@ -210,7 +210,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
} }
func testMultipleSpacesMembersSelection() async throws { func testMultipleSpacesMembersSelection() async throws {
let spaces = [SpaceRoomProxyProtocol].mockJoinedSpaces2 let spaces = [SpaceServiceRoomProtocol].mockJoinedSpaces2
setupViewModel(joinedParentSpaces: spaces, setupViewModel(joinedParentSpaces: spaces,
joinRule: .restricted(rules: [.roomMembership(roomId: "unknownSpaceID")])) joinRule: .restricted(rules: [.roomMembership(roomId: "unknownSpaceID")]))
@@ -256,8 +256,8 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
} }
func testMultipleSpacesMembersSelectionWithAnExistingNonParentButJoinedSpace() async throws { func testMultipleSpacesMembersSelectionWithAnExistingNonParentButJoinedSpace() async throws {
let joinedParentSpaces = [SpaceRoomProxyProtocol].mockJoinedSpaces2 let joinedParentSpaces = [SpaceServiceRoomProtocol].mockJoinedSpaces2
let singleRoom = [SpaceRoomProxyProtocol].mockSingleRoom let singleRoom = [SpaceServiceRoomProtocol].mockSingleRoom
let space = singleRoom[0] let space = singleRoom[0]
let allSpaces = joinedParentSpaces + singleRoom let allSpaces = joinedParentSpaces + singleRoom
setupViewModel(joinedParentSpaces: joinedParentSpaces, setupViewModel(joinedParentSpaces: joinedParentSpaces,
@@ -319,7 +319,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
func testEmptySpaceMembersSelectionWithJoinedParentEdgeCase() async throws { func testEmptySpaceMembersSelectionWithJoinedParentEdgeCase() async throws {
// Edge case where there is one available joined parent but the room has a restricted join rule. // Edge case where there is one available joined parent but the room has a restricted join rule.
// With no space ids in it // With no space ids in it
let singleRoom = [SpaceRoomProxyProtocol].mockSingleRoom let singleRoom = [SpaceServiceRoomProtocol].mockSingleRoom
setupViewModel(joinedParentSpaces: singleRoom, setupViewModel(joinedParentSpaces: singleRoom,
joinRule: .restricted(rules: [])) joinRule: .restricted(rules: []))
@@ -424,8 +424,8 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
// MARK: - Helpers // MARK: - Helpers
private func setupViewModel(joinedParentSpaces: [SpaceRoomProxyProtocol], private func setupViewModel(joinedParentSpaces: [SpaceServiceRoomProtocol],
topLevelSpaces: [SpaceRoomProxyProtocol] = [], topLevelSpaces: [SpaceServiceRoomProtocol] = [],
joinRule: JoinRule) { joinRule: JoinRule) {
let appSettings = AppSettings() let appSettings = AppSettings()
appSettings.spaceSettingsEnabled = true appSettings.spaceSettingsEnabled = true
@@ -13,7 +13,7 @@ import XCTest
@MainActor @MainActor
class SpaceListScreenViewModelTests: XCTestCase { class SpaceListScreenViewModelTests: XCTestCase {
var topLevelSpacesSubject: CurrentValueSubject<[SpaceRoomProxyProtocol], Never>! var topLevelSpacesSubject: CurrentValueSubject<[SpaceServiceRoomProtocol], Never>!
var spaceServiceProxy: SpaceServiceProxyMock! var spaceServiceProxy: SpaceServiceProxyMock!
var appSettings: AppSettings! var appSettings: AppSettings!
@@ -47,7 +47,7 @@ class SpaceListScreenViewModelTests: XCTestCase {
deferred = deferFulfillment(context.observe(\.viewState.topLevelSpaces)) { $0.count == 1 } deferred = deferFulfillment(context.observe(\.viewState.topLevelSpaces)) { $0.count == 1 }
topLevelSpacesSubject.send([ topLevelSpacesSubject.send([
SpaceRoomProxyMock(.init(isSpace: true)) SpaceServiceRoomMock(.init(isSpace: true))
]) ])
try await deferred.fulfill() try await deferred.fulfill()
XCTAssertEqual(context.viewState.topLevelSpaces.count, 1) XCTAssertEqual(context.viewState.topLevelSpaces.count, 1)
@@ -97,15 +97,15 @@ class SpaceListScreenViewModelTests: XCTestCase {
let userSession = UserSessionMock(.init(clientProxy: clientProxy)) let userSession = UserSessionMock(.init(clientProxy: clientProxy))
topLevelSpacesSubject = .init([ topLevelSpacesSubject = .init([
SpaceRoomProxyMock(.init(id: "space1", isSpace: true)), SpaceServiceRoomMock(.init(id: "space1", isSpace: true)),
SpaceRoomProxyMock(.init(id: "space2", isSpace: true)), SpaceServiceRoomMock(.init(id: "space2", isSpace: true)),
SpaceRoomProxyMock(.init(id: "space3", isSpace: true)) SpaceServiceRoomMock(.init(id: "space3", isSpace: true))
]) ])
spaceServiceProxy = SpaceServiceProxyMock(.init()) spaceServiceProxy = SpaceServiceProxyMock(.init())
spaceServiceProxy.topLevelSpacesPublisher = topLevelSpacesSubject.asCurrentValuePublisher() spaceServiceProxy.topLevelSpacesPublisher = topLevelSpacesSubject.asCurrentValuePublisher()
spaceServiceProxy.spaceRoomListSpaceIDClosure = { [topLevelSpacesSubject] spaceID in spaceServiceProxy.spaceRoomListSpaceIDClosure = { [topLevelSpacesSubject] spaceID in
guard let spaceRoomProxy = topLevelSpacesSubject?.value.first(where: { $0.id == spaceID }) else { return .failure(.missingSpace) } guard let spaceServiceRoom = topLevelSpacesSubject?.value.first(where: { $0.id == spaceID }) else { return .failure(.missingSpace) }
return .success(SpaceRoomListProxyMock(.init(spaceRoomProxy: spaceRoomProxy))) return .success(SpaceRoomListProxyMock(.init(spaceServiceRoom: spaceServiceRoom)))
} }
clientProxy.spaceService = spaceServiceProxy clientProxy.spaceService = spaceServiceProxy
@@ -16,7 +16,7 @@ import MatrixRustSDKMocks
@MainActor @MainActor
class SpaceScreenViewModelTests: XCTestCase { class SpaceScreenViewModelTests: XCTestCase {
var spaceRoomListProxy: SpaceRoomListProxyMock! var spaceRoomListProxy: SpaceRoomListProxyMock!
let mockSpaceRooms = [SpaceRoomProxyProtocol].mockSpaceList let mockSpaceRooms = [SpaceServiceRoomProtocol].mockSpaceList
var clientProxy: ClientProxyMock! var clientProxy: ClientProxyMock!
var paginationStateSubject: CurrentValueSubject<SpaceRoomListPaginationState, Never> = .init(.idle(endReached: true)) var paginationStateSubject: CurrentValueSubject<SpaceRoomListPaginationState, Never> = .init(.idle(endReached: true))
var rustLeaveHandle: LeaveSpaceHandleSDKMock! var rustLeaveHandle: LeaveSpaceHandleSDKMock!
@@ -118,7 +118,7 @@ class SpaceScreenViewModelTests: XCTestCase {
let action = try await deferred.fulfill() let action = try await deferred.fulfill()
switch action { switch action {
case .selectUnjoinedSpace(let spaceRoomProxy) where spaceRoomProxy.id == selectedSpace.id: case .selectUnjoinedSpace(let spaceServiceRoom) where spaceServiceRoom.id == selectedSpace.id:
break break
default: default:
XCTFail("The action should select the space.") XCTFail("The action should select the space.")
@@ -195,7 +195,7 @@ class SpaceScreenViewModelTests: XCTestCase {
leaveSpaceViewModel.context.send(viewAction: .deselectAll) leaveSpaceViewModel.context.send(viewAction: .deselectAll)
XCTAssertEqual(handle.selectedCount, 0, "Deselecting all should result in no selected rooms.") XCTAssertEqual(handle.selectedCount, 0, "Deselecting all should result in no selected rooms.")
leaveSpaceViewModel.context.send(viewAction: .toggleRoom(roomID: firstSelectedRoom.spaceRoomProxy.id)) leaveSpaceViewModel.context.send(viewAction: .toggleRoom(roomID: firstSelectedRoom.spaceServiceRoom.id))
XCTAssertEqual(handle.selectedCount, 1, "Toggling a room should result in 1 selected room") XCTAssertEqual(handle.selectedCount, 1, "Toggling a room should result in 1 selected room")
// Confirming the leave should leave the selected room and then the space. // Confirming the leave should leave the selected room and then the space.
@@ -205,21 +205,21 @@ class SpaceScreenViewModelTests: XCTestCase {
XCTAssertNil(context.leaveSpaceViewModel) XCTAssertNil(context.leaveSpaceViewModel)
XCTAssertTrue(rustLeaveHandle.leaveRoomIdsCalled) XCTAssertTrue(rustLeaveHandle.leaveRoomIdsCalled)
XCTAssertEqual(rustLeaveHandle.leaveRoomIdsReceivedRoomIds, XCTAssertEqual(rustLeaveHandle.leaveRoomIdsReceivedRoomIds,
[firstSelectedRoom.spaceRoomProxy.id, spaceRoomListProxy.id], [firstSelectedRoom.spaceServiceRoom.id, spaceRoomListProxy.id],
"Confirming the leave should first leave the selected room and then the space.") "Confirming the leave should first leave the selected room and then the space.")
} }
// MARK: - Helpers // MARK: - Helpers
private func setupViewModel(paginationResponses: [[SpaceRoomProxyProtocol]] = []) { private func setupViewModel(paginationResponses: [[SpaceServiceRoomProtocol]] = []) {
spaceRoomListProxy = SpaceRoomListProxyMock(.init(spaceRoomProxy: SpaceRoomProxyMock(.init(isSpace: true)), spaceRoomListProxy = SpaceRoomListProxyMock(.init(spaceServiceRoom: SpaceServiceRoomMock(.init(isSpace: true)),
paginationStateSubject: paginationStateSubject, paginationStateSubject: paginationStateSubject,
paginationResponses: paginationResponses)) paginationResponses: paginationResponses))
let spaceServiceProxy = SpaceServiceProxyMock(.init()) let spaceServiceProxy = SpaceServiceProxyMock(.init())
spaceServiceProxy.spaceRoomListSpaceIDClosure = { [mockSpaceRooms] spaceID in spaceServiceProxy.spaceRoomListSpaceIDClosure = { [mockSpaceRooms] spaceID in
guard let spaceRoomProxy = mockSpaceRooms.first(where: { $0.id == spaceID }) else { return .failure(.missingSpace) } guard let spaceServiceRoom = mockSpaceRooms.first(where: { $0.id == spaceID }) else { return .failure(.missingSpace) }
return .success(SpaceRoomListProxyMock(.init(spaceRoomProxy: spaceRoomProxy))) return .success(SpaceRoomListProxyMock(.init(spaceServiceRoom: spaceServiceRoom)))
} }
let rustLeaveHandle = LeaveSpaceHandleSDKMock(.init()) let rustLeaveHandle = LeaveSpaceHandleSDKMock(.init())
spaceServiceProxy.leaveSpaceSpaceIDClosure = { spaceID in spaceServiceProxy.leaveSpaceSpaceIDClosure = { spaceID in