mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Space Settings: Leave Room (#4700)
* Implementation for all navigations inside the space settings aside the left space action # Conflicts: # ElementX/Sources/FlowCoordinators/SpaceSettingsFlowCoordinator.swift * refactored the leave space view to use its own view model # Conflicts: # ElementX.xcodeproj/project.pbxproj * implemented the leave space view model also in the settings screen, and corrected some tests * reusing the details coordinator for the space settings screen * leave space from settings implemented * fix project * minor pr fixes * code improvements
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 77;
|
||||
objectVersion = 63;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXAggregateTarget section */
|
||||
@@ -583,6 +583,7 @@
|
||||
68B2DD307C57ECFABBB05323 /* DeclineAndBlockScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127D1947BA9C6CA62E3D03EC /* DeclineAndBlockScreen.swift */; };
|
||||
68C3AF257678F6E7BB238C3F /* AppAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FD22AEFFA20065494ED2333 /* AppAppearance.swift */; };
|
||||
695825D20A761C678809345D /* MessageForwardingScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52135BD9E0E7A091688F627A /* MessageForwardingScreenModels.swift */; };
|
||||
695BE6A2337A634F48B5DBC8 /* RoomMembersFlowCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC666DAE98245269775329B2 /* RoomMembersFlowCoordinatorTests.swift */; };
|
||||
69A9B430397C15075D86193F /* UserPropertiesExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66AFD800AF033D8B0D11191A /* UserPropertiesExt.swift */; };
|
||||
69B3C6010B42010F591FC3CB /* RoomRolesAndPermissionsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C1AF829F12FDC99717082D9 /* RoomRolesAndPermissionsScreenViewModel.swift */; };
|
||||
69C7B956B74BEC3DB88224EA /* NavigationSplitCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78913D6E120D46138E97C107 /* NavigationSplitCoordinatorTests.swift */; };
|
||||
@@ -944,10 +945,10 @@
|
||||
A6F345328CCC5C9B0DAE2257 /* LogViewerScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BB05221D7D941CC82DC8480 /* LogViewerScreenViewModel.swift */; };
|
||||
A6FFC4C5154C446BAD6B40D8 /* TimelineItemProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8520AFD6680CBAD388F6D927 /* TimelineItemProvider.swift */; };
|
||||
A722F426FD81FC67706BB1E0 /* CustomLayoutLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42236480CF0431535EBE8387 /* CustomLayoutLabelStyle.swift */; };
|
||||
A7385BAC2EBDFF80000B0961 /* LeaveSpaceModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7385BAB2EBDFF7B000B0961 /* LeaveSpaceModels.swift */; };
|
||||
A74438ED16F8683A4B793E6A /* AnalyticsSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */; };
|
||||
A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; };
|
||||
A7DB75E090542331F6668A23 /* CreateRoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF19027E7FFA5E63D148873A /* CreateRoomScreenViewModel.swift */; };
|
||||
A7F6CE532EBB76A500450B70 /* RoomMembersFlowCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7F6CE522EBB769D00450B70 /* RoomMembersFlowCoordinatorTests.swift */; };
|
||||
A808DC3F72D15C6C5A52317E /* TimelineItemDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCDA016D05107DED3B9495CB /* TimelineItemDebugView.swift */; };
|
||||
A816F7087C495D85048AC50E /* RoomMemberDetailsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */; };
|
||||
A851635B3255C6DC07034A12 /* RoomScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8108C8F0ACF6A7EB72D0117 /* RoomScreenCoordinator.swift */; };
|
||||
@@ -1337,6 +1338,7 @@
|
||||
F255083E18CDBFDF7E640FB1 /* Avatars.swift in Sources */ = {isa = PBXBuildFile; fileRef = C142248014E08E885E323E56 /* Avatars.swift */; };
|
||||
F2D5C0E1351DA7BD16867629 /* TimelineStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD4823EAB4B4E8BAB4F6B8C /* TimelineStyle.swift */; };
|
||||
F2E580C0FBFBEFFE9D69893B /* RoomPreviewProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 739077686814E4EA339B1C83 /* RoomPreviewProxyProtocol.swift */; };
|
||||
F3382570701BB87DA816AC82 /* LeaveSpaceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8C59748CC34606FF4FE95F0 /* LeaveSpaceViewModel.swift */; };
|
||||
F34D06F86C29E219E7132E87 /* AuthenticationStartScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F71A54CB96DAA1E72C6541D /* AuthenticationStartScreenViewModel.swift */; };
|
||||
F35FAD1B1B289E221A07D719 /* ManageRoomMemberSheetViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB7B588A06911B455AC0B4C9 /* ManageRoomMemberSheetViewModelProtocol.swift */; };
|
||||
F37629BAA5E8F50AAF2A131D /* SoftLogoutScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB7BAD55A4E2B8E5828CD64C /* SoftLogoutScreenViewModel.swift */; };
|
||||
@@ -1399,7 +1401,6 @@
|
||||
FCD3F2B82CAB29A07887A127 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = DE8DC9B3FBA402117DC4C49F /* Kingfisher */; };
|
||||
FCF95603F1D056B1B106A415 /* AdvancedSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E2B20431F890ED64255CA1 /* AdvancedSettingsScreenViewModelProtocol.swift */; };
|
||||
FD29471C72872F8B7580E3E1 /* KeychainControllerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39C0D861FC397AC34BCF089E /* KeychainControllerMock.swift */; };
|
||||
FD3C94F01ACAF2D4948CF9BE /* SpaceSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEA9DA018160CF76AFFBFBA7 /* SpaceSettingsScreenCoordinator.swift */; };
|
||||
FD439E183A48BE871AEEFAEA /* TimelineScrollToBottomButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E10765FBC83B34A3BC4ADB23 /* TimelineScrollToBottomButton.swift */; };
|
||||
FD4C21F8DA1E273DE94FCD1A /* NotificationItemProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B927CF5EF7FCCDA5EDC474B /* NotificationItemProxyProtocol.swift */; };
|
||||
FD573B5D665824EB79EABF06 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5327E3B3C58BEB0E65F4CF98 /* Observable.swift */; };
|
||||
@@ -1523,7 +1524,7 @@
|
||||
044E501B8331B339874D1B96 /* CompoundIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompoundIcon.swift; sourceTree = "<group>"; };
|
||||
045253F9967A535EE5B16691 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = "<group>"; };
|
||||
046C0D3F53B0B5EF0A1F5BEA /* RoomSummaryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryTests.swift; sourceTree = "<group>"; };
|
||||
048A21188AB19349D026BECD /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||
048A21188AB19349D026BECD /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||
04BB8DDE245ED86C489BA983 /* AccessibilityIdentifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityIdentifiers.swift; sourceTree = "<group>"; };
|
||||
04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManager.swift; sourceTree = "<group>"; };
|
||||
0516C69708D5CBDE1A8E77EC /* RoomDirectorySearchProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchProxyProtocol.swift; sourceTree = "<group>"; };
|
||||
@@ -1603,7 +1604,7 @@
|
||||
128501375217576AF0FE3E92 /* RoomAttachmentPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomAttachmentPicker.swift; sourceTree = "<group>"; };
|
||||
12B09A94C519227264A41208 /* RoomMembershipDetailsProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembershipDetailsProxy.swift; sourceTree = "<group>"; };
|
||||
12FD5280AF55AB7F50F8E47D /* preview_avatar_room.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = preview_avatar_room.jpg; sourceTree = "<group>"; };
|
||||
1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; path = IntegrationTests.xctestplan; sourceTree = "<group>"; };
|
||||
1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = IntegrationTests.xctestplan; sourceTree = "<group>"; };
|
||||
130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNTextInputNotificationResponse+Creator.swift"; sourceTree = "<group>"; };
|
||||
136F80A613B55BDD071DCEA5 /* JoinRoomScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinRoomScreenModels.swift; sourceTree = "<group>"; };
|
||||
13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||
@@ -1623,7 +1624,7 @@
|
||||
16D09C79746BDCD9173EB3A7 /* RoomDetailsEditScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsEditScreenModels.swift; sourceTree = "<group>"; };
|
||||
16D353E10A64172D863769BF /* TombstonedAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TombstonedAvatarImage.swift; sourceTree = "<group>"; };
|
||||
1715E3D7F53C0748AA50C91C /* PostHogAnalyticsClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostHogAnalyticsClient.swift; sourceTree = "<group>"; };
|
||||
174E4AEF3DED300AA81046EC /* compound-ios */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "compound-ios"; path = "compound-ios"; sourceTree = SOURCE_ROOT; };
|
||||
174E4AEF3DED300AA81046EC /* compound-ios */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "compound-ios"; sourceTree = SOURCE_ROOT; };
|
||||
17A8AA0DFA06012A9DAB951E /* TimelineProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineProxyMock.swift; sourceTree = "<group>"; };
|
||||
17BAE25A0E9E9F2F1BBA8930 /* DeactivateAccountScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeactivateAccountScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
181CF280BC8E3F335AFCB4B8 /* RemotePreferenceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemotePreferenceTests.swift; sourceTree = "<group>"; };
|
||||
@@ -1713,7 +1714,7 @@
|
||||
25F7FE40EF7490A7E09D7BE6 /* NotificationItemProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationItemProxy.swift; sourceTree = "<group>"; };
|
||||
25F8664F1FB95AF3C4202478 /* PollFormScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
260004737C573A56FA01E86E /* Encodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Encodable.swift; sourceTree = "<group>"; };
|
||||
267BB1D5B08A9511F894CB57 /* PreviewTests.xctestplan */ = {isa = PBXFileReference; path = PreviewTests.xctestplan; sourceTree = "<group>"; };
|
||||
267BB1D5B08A9511F894CB57 /* PreviewTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = PreviewTests.xctestplan; sourceTree = "<group>"; };
|
||||
26B0A96B8FE4849227945067 /* VoiceMessageRecorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRecorder.swift; sourceTree = "<group>"; };
|
||||
26EAAB54C6CE91D64B69A9F8 /* AppLockServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockServiceProtocol.swift; sourceTree = "<group>"; };
|
||||
2711E5996016ABD6EAAEB58A /* LogLevel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogLevel.swift; sourceTree = "<group>"; };
|
||||
@@ -1796,7 +1797,7 @@
|
||||
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>"; };
|
||||
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; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||
36FD673E24FBFCFDF398716A /* RoomMemberProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberProxyMock.swift; sourceTree = "<group>"; };
|
||||
3747C96188856006F784BF49 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ko; path = ko.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||
37A63A59BFDDC494B1C20119 /* CallScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
@@ -1909,7 +1910,7 @@
|
||||
4A2B5274C1D3D2999D643786 /* EncryptionResetPasswordScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
4A5B4CD611DE7E94F5BA87B2 /* AppLockTimerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockTimerTests.swift; sourceTree = "<group>"; };
|
||||
4AB29A2D95D3469B5F016655 /* SecureBackupControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupControllerMock.swift; sourceTree = "<group>"; };
|
||||
4B1F71AC585827E6C416C15A /* AppIcon.icon */ = {isa = PBXFileReference; path = AppIcon.icon; sourceTree = "<group>"; };
|
||||
4B1F71AC585827E6C416C15A /* AppIcon.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = AppIcon.icon; sourceTree = "<group>"; };
|
||||
4B2B564CA6570E1487A7C7CC /* SpaceRoomListProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceRoomListProxy.swift; sourceTree = "<group>"; };
|
||||
4B2D4EEBE8C098BBADD10939 /* SecureBackupKeyBackupScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupKeyBackupScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
4B41FABA2B0AEF4389986495 /* LoginMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginMode.swift; sourceTree = "<group>"; };
|
||||
@@ -1923,7 +1924,7 @@
|
||||
4E2245243369B99216C7D84E /* ImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCache.swift; sourceTree = "<group>"; };
|
||||
4E600B315B920B9687F8EE1B /* ComposerDraftServiceMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerDraftServiceMock.swift; sourceTree = "<group>"; };
|
||||
4E625B0EB2F86B37C14EF7E6 /* SettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
4E6690212271866C899AD2BA /* new-message.caf */ = {isa = PBXFileReference; path = "new-message.caf"; sourceTree = "<group>"; };
|
||||
4E6690212271866C899AD2BA /* new-message.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "new-message.caf"; sourceTree = "<group>"; };
|
||||
4E7F7A975514E850A834B29F /* PaginationIndicatorRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationIndicatorRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
4F5F0662483ED69791D63B16 /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = et; path = et.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||
4F75EF13F49DD2204E760910 /* FileRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
@@ -2240,7 +2241,7 @@
|
||||
8D55702474F279D910D2D162 /* RoomStateEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomStateEventStringBuilder.swift; sourceTree = "<group>"; };
|
||||
8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
8DA1E8F287680C8ED25EDBAC /* NetworkMonitorMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkMonitorMock.swift; sourceTree = "<group>"; };
|
||||
8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; path = UITests.xctestplan; sourceTree = "<group>"; };
|
||||
8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UITests.xctestplan; sourceTree = "<group>"; };
|
||||
8E1584F8BCF407BB94F48F04 /* EncryptionResetPasswordScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreen.swift; sourceTree = "<group>"; };
|
||||
8EAF4A49F3ACD8BB8B0D2371 /* ClientSDKMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientSDKMock.swift; sourceTree = "<group>"; };
|
||||
8F062DD2CCD95DC33528A16F /* KnockRequestProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KnockRequestProxy.swift; sourceTree = "<group>"; };
|
||||
@@ -2362,6 +2363,7 @@
|
||||
A6B891A6DA826E2461DBB40F /* PHGPostHogConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PHGPostHogConfiguration.swift; sourceTree = "<group>"; };
|
||||
A6C11AD9813045E44F950410 /* ElementCallWidgetDriverProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementCallWidgetDriverProtocol.swift; sourceTree = "<group>"; };
|
||||
A6EA0D8B0BBD8805F7D5A133 /* TextBasedRoomTimelineViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineViewProtocol.swift; sourceTree = "<group>"; };
|
||||
A7385BAB2EBDFF7B000B0961 /* LeaveSpaceModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeaveSpaceModels.swift; sourceTree = "<group>"; };
|
||||
A73A07BAEDD74C48795A996A /* AsyncSequence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncSequence.swift; sourceTree = "<group>"; };
|
||||
A768CA51A59B8A5D8C8FD599 /* AuthenticationStartScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationStartScreen.swift; sourceTree = "<group>"; };
|
||||
A7978C9EFBDD7DE39BD86726 /* RestorationTokenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorationTokenTests.swift; sourceTree = "<group>"; };
|
||||
@@ -2369,7 +2371,6 @@
|
||||
A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleTimelineItem.swift; sourceTree = "<group>"; };
|
||||
A7D452AF7B5F7E3A0A7DB54C /* SessionVerificationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
A7E37072597F67C4DD8CC2DB /* ComposerDraftServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerDraftServiceProtocol.swift; sourceTree = "<group>"; };
|
||||
A7F6CE522EBB769D00450B70 /* RoomMembersFlowCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersFlowCoordinatorTests.swift; sourceTree = "<group>"; };
|
||||
A84D413BF49F0E980F010A6B /* LogViewerScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewerScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
A8558D41DD4B553A752C868A /* StackedAvatarsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackedAvatarsView.swift; sourceTree = "<group>"; };
|
||||
A861DA5932B128FE1DCB5CE2 /* InviteUsersScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
@@ -2387,7 +2388,7 @@
|
||||
AAD8234D0E9C9B12BF9F240B /* LocationAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationAnnotation.swift; sourceTree = "<group>"; };
|
||||
AB07F03461023BC39C730922 /* PhishingDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhishingDetector.swift; sourceTree = "<group>"; };
|
||||
AB26D5444A4A7E095222DE8B /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
||||
AB389C38BD41EB3E47092CFB /* AccessibilityTests.xctestplan */ = {isa = PBXFileReference; path = AccessibilityTests.xctestplan; sourceTree = "<group>"; };
|
||||
AB389C38BD41EB3E47092CFB /* AccessibilityTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = AccessibilityTests.xctestplan; sourceTree = "<group>"; };
|
||||
ABA4CF2F5B4F68D02E412004 /* ServerConfirmationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
AC0275CEE9CA078B34028BDF /* AppLockScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
AC1DA29A5A041CC0BACA7CB0 /* MockImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockImageCache.swift; sourceTree = "<group>"; };
|
||||
@@ -2455,7 +2456,7 @@
|
||||
B53AC78E49A297AC1D72A7CF /* AppMediator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMediator.swift; sourceTree = "<group>"; };
|
||||
B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableAvatarImage.swift; sourceTree = "<group>"; };
|
||||
B5D829FD8958376614504B18 /* TargetConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TargetConfiguration.swift; sourceTree = "<group>"; };
|
||||
B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; path = ConfettiScene.scn; sourceTree = "<group>"; };
|
||||
B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = ConfettiScene.scn; sourceTree = "<group>"; };
|
||||
B6404166CBF5CC88673FF9E2 /* RoomDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetails.swift; sourceTree = "<group>"; };
|
||||
B65DDCF8E41759890355ACBC /* AuthenticationStartScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationStartScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
B682FE2C44C5E163E7023B05 /* CopyTextButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyTextButton.swift; sourceTree = "<group>"; };
|
||||
@@ -2478,6 +2479,7 @@
|
||||
B858A61F2A570DFB8DE570A7 /* AggregratedReaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AggregratedReaction.swift; sourceTree = "<group>"; };
|
||||
B88CE0A058727BC68EEEC6B6 /* ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ShareExtension.entitlements; sourceTree = "<group>"; };
|
||||
B8A3B7637DDBD6AA97AC2545 /* CameraPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraPicker.swift; sourceTree = "<group>"; };
|
||||
B8C59748CC34606FF4FE95F0 /* LeaveSpaceViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeaveSpaceViewModel.swift; sourceTree = "<group>"; };
|
||||
B8F28602AC7AC881AED37EBA /* NavigationCoordinators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationCoordinators.swift; sourceTree = "<group>"; };
|
||||
B902EA6CD3296B0E10EE432B /* HomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = "<group>"; };
|
||||
B99E13633862847D8B7E2815 /* StartChatScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartChatScreenModels.swift; sourceTree = "<group>"; };
|
||||
@@ -2485,7 +2487,7 @@
|
||||
BA40B98B098B6F0371B750B3 /* TemplateScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenModels.swift; sourceTree = "<group>"; };
|
||||
BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreen.swift; sourceTree = "<group>"; };
|
||||
BB284643AF7AB131E307DCE0 /* AudioSessionProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioSessionProtocol.swift; sourceTree = "<group>"; };
|
||||
BB576F4118C35E6B5124FA22 /* test_apple_image.heic */ = {isa = PBXFileReference; path = test_apple_image.heic; sourceTree = "<group>"; };
|
||||
BB576F4118C35E6B5124FA22 /* test_apple_image.heic */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_apple_image.heic; sourceTree = "<group>"; };
|
||||
BB5B00A014307CE37B2812CD /* TimelineViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
BB6ED50FE104992419310EEB /* NotificationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationHandler.swift; sourceTree = "<group>"; };
|
||||
BB8BC4C791D0E88CFCF4E5DF /* ServerSelectionScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
@@ -2579,6 +2581,7 @@
|
||||
CC03209FDE8CE0810617BFFF /* RoomMembersListScreenMemberCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenMemberCell.swift; sourceTree = "<group>"; };
|
||||
CC1DDB2293A51EA4C2739351 /* RoomListFiltersEmptyStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomListFiltersEmptyStateView.swift; sourceTree = "<group>"; };
|
||||
CC437C491EA6996513B1CEAB /* ElementCallConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementCallConfiguration.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>"; };
|
||||
CC743C7A85E3171BCBF0A653 /* AvatarHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarHeaderView.swift; sourceTree = "<group>"; };
|
||||
CCF71646898A2F720C5BFDF5 /* RoomDirectorySearchScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
@@ -2589,7 +2592,7 @@
|
||||
CDB3227C7A74B734924942E9 /* RoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProvider.swift; sourceTree = "<group>"; };
|
||||
CDE3F3911FF7CC639BDE5844 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
CEE20623EB4A9B88FB29F2BA /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/SAS.strings; sourceTree = "<group>"; };
|
||||
CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; path = UnitTests.xctestplan; sourceTree = "<group>"; };
|
||||
CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UnitTests.xctestplan; sourceTree = "<group>"; };
|
||||
CF19027E7FFA5E63D148873A /* CreateRoomScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
CF847A34FC4C8C937CD39E08 /* LabsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
CFFA5E881D281810AB428EA3 /* RoomPowerLevelsProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPowerLevelsProxy.swift; sourceTree = "<group>"; };
|
||||
@@ -2658,7 +2661,7 @@
|
||||
DC0AEA686E425F86F6BA0404 /* UNNotification+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNNotification+Creator.swift"; sourceTree = "<group>"; };
|
||||
DC10CCC8D68B863E20660DBC /* MessageForwardingScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
DC528B3764E3CF7FCFEF40E7 /* PollInteractionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollInteractionHandler.swift; sourceTree = "<group>"; };
|
||||
DCA2D836BD10303F37FAAEED /* test_voice_message.m4a */ = {isa = PBXFileReference; path = test_voice_message.m4a; sourceTree = "<group>"; };
|
||||
DCA2D836BD10303F37FAAEED /* test_voice_message.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_voice_message.m4a; sourceTree = "<group>"; };
|
||||
DCAC01A97A43BE07B9E94E43 /* ShareExtensionModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareExtensionModels.swift; sourceTree = "<group>"; };
|
||||
DCDAB580109C09A6AA97AF7E /* PollFormScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenTests.swift; sourceTree = "<group>"; };
|
||||
DCF239C619971FDE48132550 /* SecureBackupLogoutConfirmationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupLogoutConfirmationScreenModels.swift; sourceTree = "<group>"; };
|
||||
@@ -2705,7 +2708,7 @@
|
||||
E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = "<group>"; };
|
||||
E53BFB7E4F329621C844E8C3 /* AnalyticsPromptScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPromptScreen.swift; sourceTree = "<group>"; };
|
||||
E55B5EA766E89FF1F87C3ACB /* RoomNotificationSettingsProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsProxyProtocol.swift; sourceTree = "<group>"; };
|
||||
E5E7D4EE7CA295E5039FDA21 /* portrait_test_video.mp4 */ = {isa = PBXFileReference; path = portrait_test_video.mp4; sourceTree = "<group>"; };
|
||||
E5E7D4EE7CA295E5039FDA21 /* portrait_test_video.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = portrait_test_video.mp4; sourceTree = "<group>"; };
|
||||
E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerProtocol.swift; sourceTree = "<group>"; };
|
||||
E5F2B6443D1ED8602F328539 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||
E5FDFAA04174CC99FB66391C /* EditRoomAddressScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditRoomAddressScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
@@ -2752,13 +2755,12 @@
|
||||
ED0CBEAB5F796BEFBAF7BB6A /* VideoRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = "<group>"; };
|
||||
ED33988DA4FD4FC666800106 /* SessionVerificationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; path = message.caf; sourceTree = "<group>"; };
|
||||
ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = message.caf; sourceTree = "<group>"; };
|
||||
ED49073BB1C1FC649DAC2CCD /* LocationRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
ED60E4D2CD678E1EBF16F77A /* BlockedUsersScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersScreen.swift; sourceTree = "<group>"; };
|
||||
EDDE826EAB1BAB80C1104980 /* SpaceFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceFlowCoordinator.swift; sourceTree = "<group>"; };
|
||||
EE378083653EF0C9B5E9D580 /* EmoteRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItemContent.swift; sourceTree = "<group>"; };
|
||||
EE6BFF453838CF6C3982C5A3 /* RoomDirectorySearchScreenScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchScreenScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
EEA9DA018160CF76AFFBFBA7 /* SpaceSettingsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceSettingsScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
EEAB5662310AE73D93815134 /* JoinRoomScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinRoomScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
EF13BFD415CA84B1272E94F8 /* PINTextFieldTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PINTextFieldTests.swift; sourceTree = "<group>"; };
|
||||
EF1593DD87F974F8509BB619 /* ElementAnimations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementAnimations.swift; sourceTree = "<group>"; };
|
||||
@@ -4253,7 +4255,6 @@
|
||||
55312ACF4155CC5B2054AD75 /* SpaceSettingsScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EEA9DA018160CF76AFFBFBA7 /* SpaceSettingsScreenCoordinator.swift */,
|
||||
7C19E3A92E016D6E126DB06D /* View */,
|
||||
);
|
||||
path = SpaceSettingsScreen;
|
||||
@@ -4579,7 +4580,6 @@
|
||||
73CD9796729EB702B4DFA88C /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A7F6CE522EBB769D00450B70 /* RoomMembersFlowCoordinatorTests.swift */,
|
||||
58C2527813FDAE23E72A9063 /* AnalyticsSettingsScreenViewModelTests.swift */,
|
||||
C687844F60BFF532D49A994C /* AnalyticsTests.swift */,
|
||||
E461B3C8BBBFCA400B268D14 /* AppRouteURLParserTests.swift */,
|
||||
@@ -4653,6 +4653,7 @@
|
||||
4FCB2126C091EEF2454B4D56 /* RoomFlowCoordinatorTests.swift */,
|
||||
8AE0C9653870803E4F91F474 /* RoomListFiltersStateTests.swift */,
|
||||
EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */,
|
||||
CC666DAE98245269775329B2 /* RoomMembersFlowCoordinatorTests.swift */,
|
||||
3E9E0929CEFA356090BE5FB8 /* RoomMembersListScreenViewModelTests.swift */,
|
||||
58D295F0081084F38DB20893 /* RoomNotificationSettingsScreenViewModelTests.swift */,
|
||||
F0096BC5DA86AF6B6E5742AC /* RoomPermissionsTests.swift */,
|
||||
@@ -5323,7 +5324,9 @@
|
||||
985411D514A5913EB1B60B54 /* Spaces */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A7385BA92EBDFF31000B0961 /* LeaveSpace */,
|
||||
BDDD421CD80AD0BCBA035076 /* Common */,
|
||||
ADA672F2647D05F087305B21 /* LeaveSpaceSheet */,
|
||||
FCF165F4DDB83F3DECFEB57A /* SpaceListScreen */,
|
||||
C360FCF7418FE3593D5A0CBF /* SpaceScreen */,
|
||||
55312ACF4155CC5B2054AD75 /* SpaceSettingsScreen */,
|
||||
@@ -5523,6 +5526,25 @@
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A7385BA92EBDFF31000B0961 /* LeaveSpace */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A7385BAB2EBDFF7B000B0961 /* LeaveSpaceModels.swift */,
|
||||
B8C59748CC34606FF4FE95F0 /* LeaveSpaceViewModel.swift */,
|
||||
A7385BAA2EBDFF42000B0961 /* View */,
|
||||
);
|
||||
path = LeaveSpace;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A7385BAA2EBDFF42000B0961 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D7813824C547ED121F6F8E0F /* LeaveSpaceView.swift */,
|
||||
B329F7962435DB1B5F49F2AC /* LeaveSpaceRoomDetailsCell.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A7694BCE812C4D7B2B1B42DF /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -5619,6 +5641,13 @@
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
ADA672F2647D05F087305B21 /* LeaveSpaceSheet */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
path = LeaveSpaceSheet;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B04B538A859CD012755DC19C /* NSE */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -5848,6 +5877,13 @@
|
||||
path = MapLibre;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C18958141C8ED6D778F779A4 /* CreateRoom */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
path = CreateRoom;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C1CD278862878F9545608040 /* SessionVerificationScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -6230,6 +6266,7 @@
|
||||
53FB148CD26AFB6A5B9E20B3 /* BugReportScreen */,
|
||||
1185EECDD07495D65AC84AFC /* CallScreen */,
|
||||
90DC2E28718955ED87AD1456 /* CreatePollScreen */,
|
||||
C18958141C8ED6D778F779A4 /* CreateRoom */,
|
||||
821EB0D1C0019E3C7BBAEDBB /* CreateRoomScreen */,
|
||||
3E1CCC4B607946CE90B4A827 /* DeclineAndBlockScreen */,
|
||||
45F2BCFD6E9A6F040CC20582 /* EditRoomAddressScreen */,
|
||||
@@ -6486,8 +6523,6 @@
|
||||
FA1D480A302295CFC3582543 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B329F7962435DB1B5F49F2AC /* LeaveSpaceRoomDetailsCell.swift */,
|
||||
D7813824C547ED121F6F8E0F /* LeaveSpaceView.swift */,
|
||||
646B50583A2CE6DA67F7739A /* SpaceScreen.swift */,
|
||||
);
|
||||
path = View;
|
||||
@@ -6964,7 +6999,6 @@
|
||||
EE40B0E16A55BD23ECBFFD22 /* XCRemoteSwiftPackageReference "matrix-rich-text-editor-swift" */,
|
||||
C89CF7729E028671C5DC461E /* XCLocalSwiftPackageReference "compound-ios" */,
|
||||
);
|
||||
preferredProjectObjectVersion = 77;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
@@ -7376,7 +7410,6 @@
|
||||
3582056513A384F110EC8274 /* MediaPlayerProviderTests.swift in Sources */,
|
||||
167D00CAA13FAFB822298021 /* MediaProviderTests.swift in Sources */,
|
||||
B9A8C34A00D03094C0CF56F3 /* MediaUploadPreviewScreenViewModelTests.swift in Sources */,
|
||||
A7F6CE532EBB76A500450B70 /* RoomMembersFlowCoordinatorTests.swift in Sources */,
|
||||
23701DE32ACD6FD40AA992C3 /* MediaUploadingPreprocessorTests.swift in Sources */,
|
||||
F777C6FEE7D106136E2ED2B2 /* MessageForwardingScreenViewModelTests.swift in Sources */,
|
||||
1146E9EDCF8344F7D6E0D553 /* MockCoder.swift in Sources */,
|
||||
@@ -7409,6 +7442,7 @@
|
||||
095D3906CF2F940C2D2D17CC /* RoomFlowCoordinatorTests.swift in Sources */,
|
||||
4C8C0C9FC10BA73AB7780534 /* RoomListFiltersStateTests.swift in Sources */,
|
||||
6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */,
|
||||
695BE6A2337A634F48B5DBC8 /* RoomMembersFlowCoordinatorTests.swift in Sources */,
|
||||
5D56CE09743C6B90C21B04C2 /* RoomMembersListScreenViewModelTests.swift in Sources */,
|
||||
E49F74BD93230BDEFFE5EA51 /* RoomNotificationSettingsScreenViewModelTests.swift in Sources */,
|
||||
2335D1AB954C151FD8779F45 /* RoomPermissionsTests.swift in Sources */,
|
||||
@@ -7591,6 +7625,7 @@
|
||||
0F6C8033FA60CFD36F7CA205 /* AppLockSetupPINScreenViewModel.swift in Sources */,
|
||||
4C356F5CCB4CDC99BFA45185 /* AppLockSetupPINScreenViewModelProtocol.swift in Sources */,
|
||||
4E8A2A2CFEB212F14E49E1A1 /* AppLockSetupSettingsScreen.swift in Sources */,
|
||||
A7385BAC2EBDFF80000B0961 /* LeaveSpaceModels.swift in Sources */,
|
||||
8DCD9CC5361FF22A5B2C20F1 /* AppLockSetupSettingsScreenCoordinator.swift in Sources */,
|
||||
6E4E401BE97AC241DA7C7716 /* AppLockSetupSettingsScreenModels.swift in Sources */,
|
||||
4807E8F51DB54F56B25E1C7E /* AppLockSetupSettingsScreenViewModel.swift in Sources */,
|
||||
@@ -7895,6 +7930,7 @@
|
||||
DD21CE51DF9BD04FC8155972 /* LeaveSpaceHandleSDKMock.swift in Sources */,
|
||||
37EE1FB8400BBDC7A7338E57 /* LeaveSpaceRoomDetailsCell.swift in Sources */,
|
||||
B6CA5D18D702D0919BEF0263 /* LeaveSpaceView.swift in Sources */,
|
||||
F3382570701BB87DA816AC82 /* LeaveSpaceViewModel.swift in Sources */,
|
||||
42B084FDE621FBEE433AF444 /* LegalInformationScreen.swift in Sources */,
|
||||
9EBDC79CAC9B63A0D626E333 /* LegalInformationScreenCoordinator.swift in Sources */,
|
||||
F40B097470D3110DFDB1FAAA /* LegalInformationScreenModels.swift in Sources */,
|
||||
@@ -8329,7 +8365,6 @@
|
||||
DB5200B87C4CE9DF0024AC4E /* SpaceServiceProxyProtocol.swift in Sources */,
|
||||
D0E257557DAC8A34C7B52A9F /* SpaceSettingsFlowCoordinator.swift in Sources */,
|
||||
383063A7924F06D54BA9B24C /* SpaceSettingsScreen.swift in Sources */,
|
||||
FD3C94F01ACAF2D4948CF9BE /* SpaceSettingsScreenCoordinator.swift in Sources */,
|
||||
9DB4B303ECC05F0F33582594 /* SpacesAnnouncementSheetView.swift in Sources */,
|
||||
DF004A5B2EABBD0574D06A04 /* SplashScreenCoordinator.swift in Sources */,
|
||||
E1C67E5D9E22135A8FEBBD60 /* StackedAvatarsView.swift in Sources */,
|
||||
@@ -8784,9 +8819,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = (
|
||||
"-DRELEASE",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "-DRELEASE";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.accessibility.tests";
|
||||
PRODUCT_NAME = AccessibilityTests;
|
||||
SDKROOT = iphoneos;
|
||||
@@ -8805,9 +8838,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = (
|
||||
"-DDEBUG",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "-DDEBUG";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.accessibility.tests";
|
||||
PRODUCT_NAME = AccessibilityTests;
|
||||
SDKROOT = iphoneos;
|
||||
@@ -8829,9 +8860,7 @@
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = "$(MARKETING_VERSION)";
|
||||
OTHER_SWIFT_FLAGS = (
|
||||
"-DIS_NSE",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "-DIS_NSE";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.nse";
|
||||
PRODUCT_DISPLAY_NAME = "$(APP_DISPLAY_NAME)";
|
||||
PRODUCT_NAME = NSE;
|
||||
@@ -8880,9 +8909,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = "$(MARKETING_VERSION)";
|
||||
OTHER_SWIFT_FLAGS = (
|
||||
"-DIS_MAIN_APP",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "-DIS_MAIN_APP";
|
||||
PILLS_UT_TYPE_IDENTIFIER = "$(BASE_BUNDLE_IDENTIFIER).pills";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BASE_BUNDLE_IDENTIFIER)";
|
||||
PRODUCT_NAME = "$(APP_NAME)";
|
||||
@@ -8908,9 +8935,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = "$(MARKETING_VERSION)";
|
||||
OTHER_SWIFT_FLAGS = (
|
||||
"-DIS_MAIN_APP",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "-DIS_MAIN_APP";
|
||||
PILLS_UT_TYPE_IDENTIFIER = "$(BASE_BUNDLE_IDENTIFIER).pills";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BASE_BUNDLE_IDENTIFIER)";
|
||||
PRODUCT_NAME = "$(APP_NAME)";
|
||||
@@ -9135,9 +9160,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = (
|
||||
"-DDEBUG",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "-DDEBUG";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.ui.tests";
|
||||
PRODUCT_NAME = UITests;
|
||||
SDKROOT = iphoneos;
|
||||
@@ -9156,9 +9179,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = (
|
||||
"-DRELEASE",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "-DRELEASE";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.ui.tests";
|
||||
PRODUCT_NAME = UITests;
|
||||
SDKROOT = iphoneos;
|
||||
@@ -9180,9 +9201,7 @@
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = "$(MARKETING_VERSION)";
|
||||
OTHER_SWIFT_FLAGS = (
|
||||
"-DIS_NSE",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "-DIS_NSE";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.nse";
|
||||
PRODUCT_DISPLAY_NAME = "$(APP_DISPLAY_NAME)";
|
||||
PRODUCT_NAME = NSE;
|
||||
|
||||
@@ -43,6 +43,7 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private var roomFlowCoordinator: RoomFlowCoordinator?
|
||||
private var membersFlowCoordinator: RoomMembersFlowCoordinator?
|
||||
private var settingsFlowCoordinator: SpaceSettingsFlowCoordinator?
|
||||
private var rolesAndPermissionsFlowCoordinator: RoomRolesAndPermissionsFlowCoordinator?
|
||||
|
||||
indirect enum State: StateType {
|
||||
/// The state machine hasn't started.
|
||||
@@ -60,6 +61,8 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
/// A space settings flow is in progress
|
||||
case settingsFlow
|
||||
|
||||
case rolesAndPermissionsFlow
|
||||
|
||||
case leftSpace
|
||||
}
|
||||
|
||||
@@ -89,6 +92,9 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
case startSettingsFlow
|
||||
case stopSettingsFlow
|
||||
|
||||
case startRolesAndPermissionsFlow
|
||||
case stopRolesAndPermissionsFlow
|
||||
}
|
||||
|
||||
private let stateMachine: StateMachine<State, Event>
|
||||
@@ -151,6 +157,9 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case .settingsFlow:
|
||||
settingsFlowCoordinator?.clearRoute(animated: animated)
|
||||
clearRoute(animated: animated) // Re-run with the state machine back in the .space state.
|
||||
case .rolesAndPermissionsFlow:
|
||||
rolesAndPermissionsFlowCoordinator?.clearRoute(animated: animated)
|
||||
clearRoute(animated: animated) // Re-run with the state machine back in the .space state.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +257,22 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
settingsFlowCoordinator = nil
|
||||
}
|
||||
|
||||
stateMachine.addRouteMapping { event, fromState, _ in
|
||||
guard event == .startRolesAndPermissionsFlow, case .space = fromState else { return nil }
|
||||
return .rolesAndPermissionsFlow
|
||||
} handler: { [weak self] context in
|
||||
guard let self, let roomProxy = context.userInfo as? JoinedRoomProxyProtocol else { return }
|
||||
startRolesAndPermissionsFlow(roomProxy: roomProxy)
|
||||
}
|
||||
|
||||
stateMachine.addRouteMapping { event, fromState, _ in
|
||||
guard event == .stopRolesAndPermissionsFlow, case .rolesAndPermissionsFlow = fromState else { return nil }
|
||||
return .space
|
||||
} handler: { [weak self] _ in
|
||||
guard let self else { return }
|
||||
rolesAndPermissionsFlowCoordinator = nil
|
||||
}
|
||||
|
||||
stateMachine.addErrorHandler { context in
|
||||
fatalError("Unexpected transition: \(context)")
|
||||
}
|
||||
@@ -279,6 +304,8 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
stateMachine.tryEvent(.startMembersFlow, userInfo: roomProxy)
|
||||
case .displaySpaceSettings(let roomProxy):
|
||||
stateMachine.tryEvent(.startSettingsFlow, userInfo: roomProxy)
|
||||
case .displayRolesAndPermissions(let roomProxy):
|
||||
stateMachine.tryEvent(.startRolesAndPermissionsFlow, userInfo: roomProxy)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
@@ -430,8 +457,11 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
flowCoordinator.actions.sink { [weak self] actions in
|
||||
guard let self else { return }
|
||||
switch actions {
|
||||
case .finished:
|
||||
case .finished(let leftRoom):
|
||||
stateMachine.tryEvent(.stopSettingsFlow)
|
||||
if leftRoom {
|
||||
stateMachine.tryEvent(.leftSpace)
|
||||
}
|
||||
case .presentCallScreen(let roomProxy):
|
||||
actionsSubject.send(.presentCallScreen(roomProxy: roomProxy))
|
||||
case .verifyUser(userID: let userID):
|
||||
@@ -443,4 +473,23 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
settingsFlowCoordinator = flowCoordinator
|
||||
flowCoordinator.start()
|
||||
}
|
||||
|
||||
private func startRolesAndPermissionsFlow(roomProxy: JoinedRoomProxyProtocol) {
|
||||
let flowCoordinator = RoomRolesAndPermissionsFlowCoordinator(parameters: .init(roomProxy: roomProxy,
|
||||
mediaProvider: flowParameters.userSession.mediaProvider,
|
||||
navigationStackCoordinator: navigationStackCoordinator,
|
||||
userIndicatorController: flowParameters.userIndicatorController,
|
||||
analytics: flowParameters.analytics))
|
||||
flowCoordinator.actionsPublisher.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .complete:
|
||||
stateMachine.tryEvent(.stopRolesAndPermissionsFlow)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
rolesAndPermissionsFlowCoordinator = flowCoordinator
|
||||
flowCoordinator.start()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import Foundation
|
||||
import SwiftState
|
||||
|
||||
enum SpaceSettingsFlowCoordinatorAction {
|
||||
case finished
|
||||
case finished(leftRoom: Bool)
|
||||
case presentCallScreen(roomProxy: JoinedRoomProxyProtocol)
|
||||
case verifyUser(userID: String)
|
||||
}
|
||||
@@ -65,6 +65,9 @@ final class SpaceSettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private let stateMachine: StateMachine<State, Event>
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private var membersFlowCoordinator: RoomMembersFlowCoordinator?
|
||||
private var rolesAndPermissionsFlowCoordinator: RoomRolesAndPermissionsFlowCoordinator?
|
||||
|
||||
private var childFlowCoordinator: FlowCoordinatorProtocol?
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SpaceSettingsFlowCoordinatorAction, Never> = .init()
|
||||
@@ -178,31 +181,40 @@ final class SpaceSettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
|
||||
private func presentSpaceSettings(animated: Bool) {
|
||||
let coordinator = SpaceSettingsScreenCoordinator(parameters: .init(roomProxy: roomProxy,
|
||||
userSession: flowParameters.userSession,
|
||||
analyticsService: flowParameters.analytics,
|
||||
userIndicator: flowParameters.userIndicatorController,
|
||||
notificationSettingsProxy: flowParameters.userSession.clientProxy.notificationSettings,
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appSettings: flowParameters.appSettings))
|
||||
let coordinator = RoomDetailsScreenCoordinator(parameters: .init(roomProxy: roomProxy,
|
||||
userSession: flowParameters.userSession,
|
||||
analyticsService: flowParameters.analytics,
|
||||
userIndicatorController: flowParameters.userIndicatorController,
|
||||
notificationSettings: flowParameters.userSession.clientProxy.notificationSettings,
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appSettings: flowParameters.appSettings))
|
||||
|
||||
coordinator.actionsPublisher.sink { [weak self] action in
|
||||
var leftRoom = false
|
||||
coordinator.actions.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .presentEditDetailsScreen:
|
||||
case .presentRoomDetailsEditScreen:
|
||||
stateMachine.tryEvent(.presentEditDetailsScreen)
|
||||
case .presentSecurityAndPrivacyScreen:
|
||||
stateMachine.tryEvent(.presentSecurityAndPrivacyScreen)
|
||||
case .presentMembersListScreen:
|
||||
case .presentRoomMembersList:
|
||||
stateMachine.tryEvent(.startMembersListFlow)
|
||||
case .presentRolesAndPermissionsScreen:
|
||||
stateMachine.tryEvent(.startRolesAndPermissionsFlow)
|
||||
case .leftRoom:
|
||||
leftRoom = true
|
||||
navigationStackCoordinator.pop()
|
||||
case .presentRecipientDetails, .presentNotificationSettingsScreen, .transferOwnership,
|
||||
.presentInviteUsersScreen, .presentPollsHistory, .presentCall,
|
||||
.presentPinnedEventsTimeline, .presentMediaEventsTimeline, .presentKnockingRequestsListScreen,
|
||||
.presentReportRoomScreen:
|
||||
fatalError("Not handled in the space context")
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
navigationStackCoordinator.push(coordinator, animated: animated) { [weak self] in
|
||||
self?.actionsSubject.send(.finished)
|
||||
self?.actionsSubject.send(.finished(leftRoom: leftRoom))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ enum RoomDetailsScreenCoordinatorAction {
|
||||
|
||||
final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
||||
private var viewModel: RoomDetailsScreenViewModelProtocol
|
||||
private let isSpace: Bool
|
||||
|
||||
private let actionsSubject: PassthroughSubject<RoomDetailsScreenCoordinatorAction, Never> = .init()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
@@ -48,6 +49,7 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
||||
}
|
||||
|
||||
init(parameters: RoomDetailsScreenCoordinatorParameters) {
|
||||
isSpace = parameters.roomProxy.infoPublisher.value.isSpace
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: parameters.roomProxy,
|
||||
userSession: parameters.userSession,
|
||||
analyticsService: parameters.analyticsService,
|
||||
@@ -105,6 +107,10 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
||||
}
|
||||
|
||||
func toPresentable() -> AnyView {
|
||||
AnyView(RoomDetailsScreen(context: viewModel.context))
|
||||
if isSpace {
|
||||
AnyView(SpaceSettingsScreen(context: viewModel.context))
|
||||
} else {
|
||||
AnyView(RoomDetailsScreen(context: viewModel.context))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +172,9 @@ struct RoomDetailsScreenViewStateBindings {
|
||||
|
||||
/// A media item that will be previewed with QuickLook.
|
||||
var mediaPreviewItem: MediaPreviewItem?
|
||||
|
||||
/// The view model used to display the leave space sheet, will only be used if the room is a space.
|
||||
var leaveSpaceViewModel: LeaveSpaceViewModel?
|
||||
}
|
||||
|
||||
struct LeaveRoomAlertItem: AlertProtocol {
|
||||
|
||||
@@ -209,10 +209,29 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
||||
|
||||
private func processLeaveSpace() async {
|
||||
switch await userSession.clientProxy.spaceService.leaveSpace(spaceID: roomProxy.id) {
|
||||
case .success:
|
||||
// TODO: Handle leave space
|
||||
break
|
||||
case .failure(let failure):
|
||||
case .success(let leaveHandle):
|
||||
let leaveSpaceViewModel = LeaveSpaceViewModel(spaceName: state.details.name ?? state.details.id,
|
||||
canEditRolesAndPermissions: state.canEditRolesOrPermissions,
|
||||
leaveHandle: leaveHandle,
|
||||
userIndicatorController: userIndicatorController,
|
||||
mediaProvider: userSession.mediaProvider)
|
||||
leaveSpaceViewModel.actions.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .didCancel:
|
||||
state.bindings.leaveSpaceViewModel = nil
|
||||
case .presentRolesAndPermissions:
|
||||
state.bindings.leaveSpaceViewModel = nil
|
||||
actionsSubject.send(.requestRolesAndPermissionsPresentation)
|
||||
case .didLeaveSpace:
|
||||
state.bindings.leaveSpaceViewModel = nil
|
||||
actionsSubject.send(.leftRoom)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
state.bindings.leaveSpaceViewModel = leaveSpaceViewModel
|
||||
case .failure:
|
||||
userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Copyright 2025 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
enum LeaveSpaceViewAction {
|
||||
case confirmLeaveSpace
|
||||
case deselectAll
|
||||
case selectAll
|
||||
case toggleRoom(roomID: String)
|
||||
case rolesAndPermissions
|
||||
case cancel
|
||||
}
|
||||
|
||||
struct LeaveSpaceViewState: BindableState {
|
||||
let spaceName: String
|
||||
let canEditRolesAndPermissions: Bool
|
||||
let leaveHandle: LeaveSpaceHandleProxy
|
||||
|
||||
var title: String {
|
||||
switch leaveHandle.mode {
|
||||
case .lastSpaceAdmin: L10n.screenLeaveSpaceTitleLastAdmin(spaceName)
|
||||
default: L10n.screenLeaveSpaceTitle(spaceName)
|
||||
}
|
||||
}
|
||||
|
||||
var subtitle: String? {
|
||||
switch leaveHandle.mode {
|
||||
case .manyRooms: L10n.screenLeaveSpaceSubtitle
|
||||
case .onlyAdminRooms: L10n.screenLeaveSpaceSubtitleOnlyLastAdmin
|
||||
case .noRooms: nil
|
||||
case .lastSpaceAdmin: L10n.screenLeaveSpaceSubtitleLastAdmin
|
||||
}
|
||||
}
|
||||
|
||||
var confirmationTitle: String {
|
||||
let selectedCount = leaveHandle.selectedCount
|
||||
return selectedCount > 0 ? L10n.screenLeaveSpaceSubmit(selectedCount) : L10n.actionLeaveSpace
|
||||
}
|
||||
}
|
||||
|
||||
enum LeaveSpaceViewModelAction {
|
||||
case didLeaveSpace
|
||||
case presentRolesAndPermissions
|
||||
case didCancel
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// Copyright 2025 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias LeaveSpaceViewModelType = StateStoreViewModelV2<LeaveSpaceViewState, LeaveSpaceViewAction>
|
||||
|
||||
class LeaveSpaceViewModel: LeaveSpaceViewModelType {
|
||||
let actionsSubject = PassthroughSubject<LeaveSpaceViewModelAction, Never>()
|
||||
var actions: AnyPublisher<LeaveSpaceViewModelAction, Never> { actionsSubject.eraseToAnyPublisher() }
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let mediaProvider: MediaProviderProtocol
|
||||
|
||||
init(spaceName: String, canEditRolesAndPermissions: Bool, leaveHandle: LeaveSpaceHandleProxy, userIndicatorController: UserIndicatorControllerProtocol, mediaProvider: MediaProviderProtocol) {
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.mediaProvider = mediaProvider
|
||||
super.init(initialViewState: LeaveSpaceViewState(spaceName: spaceName, canEditRolesAndPermissions: canEditRolesAndPermissions, leaveHandle: leaveHandle), mediaProvider: mediaProvider)
|
||||
}
|
||||
|
||||
override func process(viewAction: LeaveSpaceViewAction) {
|
||||
switch viewAction {
|
||||
case .confirmLeaveSpace:
|
||||
Task { await confirmLeaveSpace() }
|
||||
case .rolesAndPermissions:
|
||||
actionsSubject.send(.presentRolesAndPermissions)
|
||||
case .cancel:
|
||||
actionsSubject.send(.didCancel)
|
||||
case .deselectAll:
|
||||
state.leaveHandle.deselectAll()
|
||||
case .selectAll:
|
||||
state.leaveHandle.selectAll()
|
||||
case .toggleRoom(let roomID):
|
||||
withTransaction(\.disablesAnimations, true) { // The button is adding an unwanted animation.
|
||||
state.leaveHandle.toggleRoom(roomID: roomID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func confirmLeaveSpace() async {
|
||||
showLeavingIndicator()
|
||||
defer { hideLeavingIndicator() }
|
||||
|
||||
switch await state.leaveHandle.leave() {
|
||||
case .success:
|
||||
actionsSubject.send(.didLeaveSpace)
|
||||
case .failure:
|
||||
showFailureIndicator()
|
||||
}
|
||||
}
|
||||
|
||||
private static var leavingIndicatorID: String { "\(Self.self)-Leaving" }
|
||||
private static var failureIndicatorID: String { "\(Self.self)-Failure" }
|
||||
|
||||
private func showLeavingIndicator() {
|
||||
userIndicatorController.submitIndicator(UserIndicator(id: Self.leavingIndicatorID,
|
||||
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true, allowsInteraction: false),
|
||||
title: L10n.commonLeavingSpace))
|
||||
}
|
||||
|
||||
private func hideLeavingIndicator() {
|
||||
userIndicatorController.retractIndicatorWithId(Self.leavingIndicatorID)
|
||||
}
|
||||
|
||||
private func showFailureIndicator() {
|
||||
userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorID,
|
||||
type: .toast,
|
||||
title: L10n.errorUnknown,
|
||||
iconName: "xmark"))
|
||||
}
|
||||
}
|
||||
|
||||
extension LeaveSpaceViewModel: Identifiable {
|
||||
var id: String { state.leaveHandle.id }
|
||||
}
|
||||
+30
-58
@@ -12,8 +12,7 @@ import SwiftUI
|
||||
struct LeaveSpaceView: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
let context: SpaceScreenViewModel.Context
|
||||
let leaveHandle: LeaveSpaceHandleProxy
|
||||
let context: LeaveSpaceViewModel.Context
|
||||
|
||||
@State private var scrollViewHeight: CGFloat = .zero
|
||||
@State private var buttonsHeight: CGFloat = .zero
|
||||
@@ -43,12 +42,12 @@ struct LeaveSpaceView: View {
|
||||
BigIcon(icon: \.errorSolid, style: .alertSolid)
|
||||
|
||||
VStack(spacing: 8) {
|
||||
Text(leaveHandle.title(spaceName: context.viewState.space.name))
|
||||
Text(context.viewState.title)
|
||||
.font(.compound.headingMDBold)
|
||||
.foregroundStyle(.compound.textPrimary)
|
||||
.multilineTextAlignment(.center)
|
||||
|
||||
if let subtitle = leaveHandle.subtitle {
|
||||
if let subtitle = context.viewState.subtitle {
|
||||
Text(subtitle)
|
||||
.font(.compound.bodyMD)
|
||||
.foregroundStyle(.compound.textSecondary)
|
||||
@@ -61,21 +60,22 @@ struct LeaveSpaceView: View {
|
||||
|
||||
@ViewBuilder
|
||||
var rooms: some View {
|
||||
if !leaveHandle.rooms.isEmpty, leaveHandle.canLeave {
|
||||
if !context.viewState.leaveHandle.rooms.isEmpty,
|
||||
context.viewState.leaveHandle.canLeave {
|
||||
LazyVStack(spacing: 0, pinnedViews: .sectionHeaders) {
|
||||
Section {
|
||||
ForEach(leaveHandle.rooms, id: \.spaceRoomProxy.id) { room in
|
||||
ForEach(context.viewState.leaveHandle.rooms, id: \.spaceRoomProxy.id) { room in
|
||||
LeaveSpaceRoomDetailsCell(room: room,
|
||||
hideSelection: leaveHandle.mode == .onlyAdminRooms,
|
||||
hideSelection: context.viewState.leaveHandle.mode == .onlyAdminRooms,
|
||||
mediaProvider: context.mediaProvider) {
|
||||
context.send(viewAction: .toggleLeaveSpaceRoomDetails(id: room.spaceRoomProxy.id))
|
||||
context.send(viewAction: .toggleRoom(roomID: room.spaceRoomProxy.id))
|
||||
}
|
||||
.disabled(room.isLastAdmin)
|
||||
}
|
||||
} header: {
|
||||
if leaveHandle.mode == .manyRooms {
|
||||
Button(leaveHandle.selectedCount > 0 ? L10n.actionDeselectAll : L10n.actionSelectAll) {
|
||||
context.send(viewAction: leaveHandle.selectedCount > 0 ? .deselectAllLeaveRoomDetails : .selectAllLeaveRoomDetails)
|
||||
if context.viewState.leaveHandle.mode == .manyRooms {
|
||||
Button(context.viewState.leaveHandle.selectedCount > 0 ? L10n.actionDeselectAll : L10n.actionSelectAll) {
|
||||
context.send(viewAction: context.viewState.leaveHandle.selectedCount > 0 ? .deselectAll : .selectAll)
|
||||
}
|
||||
.buttonStyle(.compound(.textLink, size: .small))
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
@@ -90,11 +90,11 @@ struct LeaveSpaceView: View {
|
||||
|
||||
var buttons: some View {
|
||||
VStack(spacing: 16) {
|
||||
if leaveHandle.canLeave {
|
||||
if context.viewState.leaveHandle.canLeave {
|
||||
Button(role: .destructive) {
|
||||
context.send(viewAction: .confirmLeaveSpace)
|
||||
} label: {
|
||||
Label(leaveHandle.confirmationTitle, icon: \.leave)
|
||||
Label(context.viewState.confirmationTitle, icon: \.leave)
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
} else if context.viewState.canEditRolesAndPermissions {
|
||||
@@ -114,44 +114,24 @@ struct LeaveSpaceView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private extension LeaveSpaceHandleProxy {
|
||||
func title(spaceName: String) -> String {
|
||||
switch mode {
|
||||
case .lastSpaceAdmin: L10n.screenLeaveSpaceTitleLastAdmin(spaceName)
|
||||
default: L10n.screenLeaveSpaceTitle(spaceName)
|
||||
}
|
||||
}
|
||||
|
||||
var subtitle: String? {
|
||||
switch mode {
|
||||
case .manyRooms: L10n.screenLeaveSpaceSubtitle
|
||||
case .onlyAdminRooms: L10n.screenLeaveSpaceSubtitleOnlyLastAdmin
|
||||
case .noRooms: nil
|
||||
case .lastSpaceAdmin: L10n.screenLeaveSpaceSubtitleLastAdmin
|
||||
}
|
||||
}
|
||||
|
||||
var confirmationTitle: String {
|
||||
let selectedCount = selectedCount
|
||||
return selectedCount > 0 ? L10n.screenLeaveSpaceSubmit(selectedCount) : L10n.actionLeaveSpace
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
import MatrixRustSDK
|
||||
|
||||
struct LeaveSpaceView_Previews: PreviewProvider, TestablePreview {
|
||||
static let viewModel = makeViewModel()
|
||||
static let manyViewModel = makeViewModel(mode: .manyRooms)
|
||||
static let onlyAdminViewModel = makeViewModel(mode: .onlyAdminRooms)
|
||||
static let noRoomsViewModel = makeViewModel(mode: .noRooms)
|
||||
static let lastAdminViewModel = makeViewModel(mode: .lastSpaceAdmin)
|
||||
|
||||
static var previews: some View {
|
||||
LeaveSpaceView(context: viewModel.context, leaveHandle: makeLeaveHandle(mode: .manyRooms))
|
||||
LeaveSpaceView(context: manyViewModel.context)
|
||||
.previewDisplayName("Many Rooms")
|
||||
LeaveSpaceView(context: viewModel.context, leaveHandle: makeLeaveHandle(mode: .onlyAdminRooms))
|
||||
LeaveSpaceView(context: onlyAdminViewModel.context)
|
||||
.previewDisplayName("Only Admin Rooms")
|
||||
LeaveSpaceView(context: viewModel.context, leaveHandle: makeLeaveHandle(mode: .noRooms))
|
||||
LeaveSpaceView(context: noRoomsViewModel.context)
|
||||
.previewDisplayName("No Rooms")
|
||||
LeaveSpaceView(context: viewModel.context, leaveHandle: makeLeaveHandle(mode: .lastSpaceAdmin))
|
||||
LeaveSpaceView(context: lastAdminViewModel.context)
|
||||
.previewDisplayName("Last Space Admin")
|
||||
}
|
||||
|
||||
@@ -164,21 +144,7 @@ struct LeaveSpaceView_Previews: PreviewProvider, TestablePreview {
|
||||
topic: "Description of the space goes right here. Lorem ipsum dolor sit amet consectetur. Leo viverra morbi habitant in.",
|
||||
joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")])))
|
||||
|
||||
static func makeViewModel() -> SpaceScreenViewModel {
|
||||
let spaceRoomListProxy = SpaceRoomListProxyMock(.init(spaceRoomProxy: spaceRoomProxy,
|
||||
initialSpaceRooms: .mockSpaceList))
|
||||
let spaceServiceProxy = SpaceServiceProxyMock(.init())
|
||||
|
||||
let viewModel = SpaceScreenViewModel(spaceRoomListProxy: spaceRoomListProxy,
|
||||
spaceServiceProxy: spaceServiceProxy,
|
||||
selectedSpaceRoomPublisher: .init(nil),
|
||||
userSession: UserSessionMock(.init()),
|
||||
appSettings: AppSettings(),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
return viewModel
|
||||
}
|
||||
|
||||
static func makeLeaveHandle(mode: LeaveSpaceHandleProxy.Mode) -> LeaveSpaceHandleProxy {
|
||||
static func makeViewModel(mode: LeaveSpaceHandleProxy.Mode) -> LeaveSpaceViewModel {
|
||||
let rooms: [LeaveSpaceRoom] = switch mode {
|
||||
case .manyRooms: .mockRooms
|
||||
case .onlyAdminRooms: .mockAdminRooms
|
||||
@@ -186,7 +152,13 @@ struct LeaveSpaceView_Previews: PreviewProvider, TestablePreview {
|
||||
case .lastSpaceAdmin: .mockLastSpaceAdmin(spaceRoomProxy: spaceRoomProxy)
|
||||
}
|
||||
|
||||
return LeaveSpaceHandleProxy(spaceID: spaceRoomProxy.id,
|
||||
leaveHandle: LeaveSpaceHandleSDKMock(.init(rooms: rooms)))
|
||||
let leaveHandle = LeaveSpaceHandleProxy(spaceID: spaceRoomProxy.id,
|
||||
leaveHandle: LeaveSpaceHandleSDKMock(.init(rooms: rooms)))
|
||||
|
||||
return LeaveSpaceViewModel(spaceName: spaceRoomProxy.name,
|
||||
canEditRolesAndPermissions: true,
|
||||
leaveHandle: leaveHandle,
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()))
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ enum SpaceScreenCoordinatorAction {
|
||||
case leftSpace
|
||||
case displayMembers(roomProxy: JoinedRoomProxyProtocol)
|
||||
case displaySpaceSettings(roomProxy: JoinedRoomProxyProtocol)
|
||||
case displayRolesAndPermissions(roomProxy: JoinedRoomProxyProtocol)
|
||||
}
|
||||
|
||||
final class SpaceScreenCoordinator: CoordinatorProtocol {
|
||||
@@ -69,6 +70,8 @@ final class SpaceScreenCoordinator: CoordinatorProtocol {
|
||||
actionsSubject.send(.displayMembers(roomProxy: roomProxy))
|
||||
case .displaySpaceSettings(let roomProxy):
|
||||
actionsSubject.send(.displaySpaceSettings(roomProxy: roomProxy))
|
||||
case .presentRolesAndPermissions(let roomProxy):
|
||||
actionsSubject.send(.displayRolesAndPermissions(roomProxy: roomProxy))
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
@@ -13,6 +13,7 @@ enum SpaceScreenViewModelAction {
|
||||
case selectUnjoinedSpace(SpaceRoomProxyProtocol)
|
||||
case selectRoom(roomID: String)
|
||||
case leftSpace
|
||||
case presentRolesAndPermissions(roomProxy: JoinedRoomProxyProtocol)
|
||||
case displayMembers(roomProxy: JoinedRoomProxyProtocol)
|
||||
case displaySpaceSettings(roomProxy: JoinedRoomProxyProtocol)
|
||||
}
|
||||
@@ -39,17 +40,12 @@ struct SpaceScreenViewState: BindableState {
|
||||
}
|
||||
|
||||
struct SpaceScreenViewStateBindings {
|
||||
var leaveHandle: LeaveSpaceHandleProxy?
|
||||
var leaveSpaceViewModel: LeaveSpaceViewModel?
|
||||
}
|
||||
|
||||
enum SpaceScreenViewAction {
|
||||
case spaceAction(SpaceRoomCell.Action)
|
||||
case leaveSpace
|
||||
case deselectAllLeaveRoomDetails
|
||||
case selectAllLeaveRoomDetails
|
||||
case toggleLeaveSpaceRoomDetails(id: String)
|
||||
case confirmLeaveSpace
|
||||
case spaceSettings(roomProxy: JoinedRoomProxyProtocol)
|
||||
case rolesAndPermissions
|
||||
case displayMembers(roomProxy: JoinedRoomProxyProtocol)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
|
||||
private let spaceRoomListProxy: SpaceRoomListProxyProtocol
|
||||
private let spaceServiceProxy: SpaceServiceProxyProtocol
|
||||
private let clientProxy: ClientProxyProtocol
|
||||
private let mediaProvider: MediaProviderProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
@@ -32,6 +33,7 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
|
||||
self.spaceRoomListProxy = spaceRoomListProxy
|
||||
self.spaceServiceProxy = spaceServiceProxy
|
||||
clientProxy = userSession.clientProxy
|
||||
mediaProvider = userSession.mediaProvider
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.appSettings = appSettings
|
||||
|
||||
@@ -117,31 +119,10 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
|
||||
Task { await join(spaceRoomProxy) }
|
||||
case .leaveSpace:
|
||||
Task { await showLeaveSpaceConfirmation() }
|
||||
case .deselectAllLeaveRoomDetails:
|
||||
guard let leaveHandle = state.bindings.leaveHandle else { fatalError("The leave handle should be available.") }
|
||||
for room in leaveHandle.rooms {
|
||||
room.isSelected = false
|
||||
}
|
||||
case .selectAllLeaveRoomDetails:
|
||||
guard let leaveHandle = state.bindings.leaveHandle else { fatalError("The leave handle should be available.") }
|
||||
for room in leaveHandle.rooms where !room.isLastAdmin {
|
||||
room.isSelected = true
|
||||
}
|
||||
case .toggleLeaveSpaceRoomDetails(let spaceRoomID):
|
||||
guard let room = state.bindings.leaveHandle?.rooms.first(where: { $0.spaceRoomProxy.id == spaceRoomID }) else {
|
||||
fatalError("The space room to toggle is not in the list of rooms to leave.")
|
||||
}
|
||||
withTransaction(\.disablesAnimations, true) { // The button is adding an unwanted animation.
|
||||
room.isSelected.toggle()
|
||||
}
|
||||
case .confirmLeaveSpace:
|
||||
Task { await confirmLeaveSpace() }
|
||||
case .displayMembers(let roomProxy):
|
||||
actionsSubject.send(.displayMembers(roomProxy: roomProxy))
|
||||
case .spaceSettings(let roomProxy):
|
||||
actionsSubject.send(.displaySpaceSettings(roomProxy: roomProxy))
|
||||
case .rolesAndPermissions:
|
||||
break // Not implemented yet
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,41 +161,37 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
|
||||
return
|
||||
}
|
||||
|
||||
state.bindings.leaveHandle = leaveHandle
|
||||
}
|
||||
|
||||
private func confirmLeaveSpace() async {
|
||||
guard let leaveHandle = state.bindings.leaveHandle else { fatalError("Leaving without a handle is impossible.") }
|
||||
|
||||
showLeavingIndicator()
|
||||
defer { hideLeavingIndicator() }
|
||||
|
||||
switch await leaveHandle.leave() {
|
||||
case .success:
|
||||
state.bindings.leaveHandle = nil
|
||||
actionsSubject.send(.leftSpace)
|
||||
case .failure:
|
||||
showFailureIndicator()
|
||||
let leaveSpaceViewModel = LeaveSpaceViewModel(spaceName: state.space.name,
|
||||
canEditRolesAndPermissions: appSettings.spaceSettingsEnabled && state.canEditRolesAndPermissions,
|
||||
leaveHandle: leaveHandle,
|
||||
userIndicatorController: userIndicatorController,
|
||||
mediaProvider: mediaProvider)
|
||||
leaveSpaceViewModel.actions.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .didCancel:
|
||||
state.bindings.leaveSpaceViewModel = nil
|
||||
case .presentRolesAndPermissions:
|
||||
guard let roomProxy = state.roomProxy else {
|
||||
fatalError("The space screen should always have a room proxy")
|
||||
}
|
||||
state.bindings.leaveSpaceViewModel = nil
|
||||
actionsSubject.send(.presentRolesAndPermissions(roomProxy: roomProxy))
|
||||
case .didLeaveSpace:
|
||||
state.bindings.leaveSpaceViewModel = nil
|
||||
actionsSubject.send(.leftSpace)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
state.bindings.leaveSpaceViewModel = leaveSpaceViewModel
|
||||
}
|
||||
|
||||
private func updatePermissions() { }
|
||||
|
||||
|
||||
// MARK: - Indicators
|
||||
|
||||
private static var leavingIndicatorID: String { "\(Self.self)-Leaving" }
|
||||
private static var failureIndicatorID: String { "\(Self.self)-Failure" }
|
||||
|
||||
private func showLeavingIndicator() {
|
||||
userIndicatorController.submitIndicator(UserIndicator(id: Self.leavingIndicatorID,
|
||||
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true, allowsInteraction: false),
|
||||
title: L10n.commonLeavingSpace))
|
||||
}
|
||||
|
||||
private func hideLeavingIndicator() {
|
||||
userIndicatorController.retractIndicatorWithId(Self.leavingIndicatorID)
|
||||
}
|
||||
|
||||
private func showFailureIndicator() {
|
||||
userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorID,
|
||||
type: .toast,
|
||||
|
||||
@@ -25,8 +25,8 @@ struct SpaceScreen: View {
|
||||
.navigationTitle(context.viewState.space.name)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar { toolbar }
|
||||
.sheet(item: $context.leaveHandle) { leaveHandle in
|
||||
LeaveSpaceView(context: context, leaveHandle: leaveHandle)
|
||||
.sheet(item: $context.leaveSpaceViewModel) { leaveSpaceViewModel in
|
||||
LeaveSpaceView(context: leaveSpaceViewModel.context)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-76
@@ -1,76 +0,0 @@
|
||||
//
|
||||
// Copyright 2025 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
struct SpaceSettingsScreenCoordinatorParameters {
|
||||
let roomProxy: JoinedRoomProxyProtocol
|
||||
let userSession: UserSessionProtocol
|
||||
let analyticsService: AnalyticsService
|
||||
let userIndicator: UserIndicatorControllerProtocol
|
||||
let notificationSettingsProxy: NotificationSettingsProxyProtocol
|
||||
let attributedStringBuilder: AttributedStringBuilderProtocol
|
||||
let appSettings: AppSettings
|
||||
}
|
||||
|
||||
enum SpaceSettingsScreenCoordinatorAction {
|
||||
case presentEditDetailsScreen
|
||||
case presentSecurityAndPrivacyScreen
|
||||
case presentMembersListScreen
|
||||
case presentRolesAndPermissionsScreen
|
||||
}
|
||||
|
||||
final class SpaceSettingsScreenCoordinator: CoordinatorProtocol {
|
||||
private let viewModel: RoomDetailsScreenViewModelProtocol
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SpaceSettingsScreenCoordinatorAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<SpaceSettingsScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(parameters: SpaceSettingsScreenCoordinatorParameters) {
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: parameters.roomProxy,
|
||||
userSession: parameters.userSession,
|
||||
analyticsService: parameters.analyticsService,
|
||||
userIndicatorController: parameters.userIndicator,
|
||||
notificationSettingsProxy: parameters.notificationSettingsProxy,
|
||||
attributedStringBuilder: parameters.attributedStringBuilder,
|
||||
appSettings: parameters.appSettings)
|
||||
}
|
||||
|
||||
func start() {
|
||||
viewModel.actions.sink { [weak self] action in
|
||||
MXLog.info("Coordinator: received view model action: \(action)")
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .requestNotificationSettingsPresentation, .requestRecipientDetailsPresentation, .requestInvitePeoplePresentation, .requestPollsHistoryPresentation,
|
||||
.startCall, .displayPinnedEventsTimeline, .displayMediaEventsTimeline, .displayKnockingRequests,
|
||||
.displayReportRoom, .transferOwnership:
|
||||
break // Not handled in this context
|
||||
case .requestEditDetailsPresentation:
|
||||
actionsSubject.send(.presentEditDetailsScreen)
|
||||
case .displaySecurityAndPrivacy:
|
||||
actionsSubject.send(.presentSecurityAndPrivacyScreen)
|
||||
case .requestMemberDetailsPresentation:
|
||||
actionsSubject.send(.presentMembersListScreen)
|
||||
case .requestRolesAndPermissionsPresentation:
|
||||
actionsSubject.send(.presentRolesAndPermissionsScreen)
|
||||
case .leftRoom:
|
||||
break // TODO:
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func toPresentable() -> AnyView {
|
||||
AnyView(SpaceSettingsScreen(context: viewModel.context))
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,9 @@ struct SpaceSettingsScreen: View {
|
||||
}
|
||||
.compoundList()
|
||||
.navigationTitle(L10n.commonSettings)
|
||||
.sheet(item: $context.leaveSpaceViewModel) { viewModel in
|
||||
LeaveSpaceView(context: viewModel.context)
|
||||
}
|
||||
}
|
||||
|
||||
private var editSection: some View {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
class LeaveSpaceHandleProxy: Identifiable {
|
||||
final class LeaveSpaceHandleProxy {
|
||||
let id: String
|
||||
var rooms: [LeaveSpaceRoomDetails]
|
||||
|
||||
@@ -51,6 +51,25 @@ class LeaveSpaceHandleProxy: Identifiable {
|
||||
}
|
||||
}
|
||||
|
||||
func deselectAll() {
|
||||
for room in rooms {
|
||||
room.isSelected = false
|
||||
}
|
||||
}
|
||||
|
||||
func selectAll() {
|
||||
for room in rooms where !room.isLastAdmin {
|
||||
room.isSelected = true
|
||||
}
|
||||
}
|
||||
|
||||
func toggleRoom(roomID: String) {
|
||||
guard let room = rooms.first(where: { $0.spaceRoomProxy.id == roomID }) else {
|
||||
return
|
||||
}
|
||||
room.isSelected.toggle()
|
||||
}
|
||||
|
||||
func leave() async -> Result<Void, SpaceServiceProxyError> {
|
||||
let selectedRoomIDs = rooms.filter(\.isSelected).map(\.spaceRoomProxy.id)
|
||||
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c396362920b57958f7e0586fe9161ad7808e91c62e9457c6dbb0379c04b1b488
|
||||
size 92482
|
||||
oid sha256:b2fe3c4f6354f94523ee75f69ed37b702aac943a095bcee679a6743be420a2a2
|
||||
size 103431
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3316fbd3a5c7b5310f940bef50381a3a947bfe82c836fe212f3a12d301ccf439
|
||||
size 100701
|
||||
oid sha256:b6087fcb56a01cebe9cbe17ce6e87764a3b586fdb4443b8a5a6c7be9fb5bbc7d
|
||||
size 113376
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4626895535cc88986dc35a8ddb0fac304ca3cc1bf21db3a58daa6efb66912132
|
||||
size 52109
|
||||
oid sha256:f8d1d8999c2df94cc24c7b11a3727878ce3dd7bfde23910da358fe5293fd58f7
|
||||
size 62111
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ef1fa43dc064fc2426bfa091eafcf4234f3a85ba2631dd95d5b0dca2648ddac5
|
||||
size 70188
|
||||
oid sha256:7d3418e7499a070280e0305e06b4b3a318d9acb73befe72cd9c42efa88451828
|
||||
size 86087
|
||||
|
||||
@@ -178,29 +178,30 @@ class SpaceScreenViewModelTests: XCTestCase {
|
||||
|
||||
func testLeavingSpace() async throws {
|
||||
setupViewModel()
|
||||
XCTAssertNil(context.leaveHandle)
|
||||
XCTAssertNil(context.leaveSpaceViewModel)
|
||||
|
||||
let deferredHandle = deferFulfillment(context.observe(\.leaveHandle)) { $0 != nil }
|
||||
let deferredHandle = deferFulfillment(context.observe(\.leaveSpaceViewModel)) { $0 != nil }
|
||||
context.send(viewAction: .leaveSpace)
|
||||
try await deferredHandle.fulfill()
|
||||
XCTAssertNotNil(context.leaveHandle, "The leave action should show the leave view.")
|
||||
XCTAssertNotNil(context.leaveSpaceViewModel, "The leave action should show the leave view.")
|
||||
|
||||
let handle = try XCTUnwrap(context.leaveHandle)
|
||||
let leaveSpaceViewModel = try XCTUnwrap(context.leaveSpaceViewModel)
|
||||
let handle = try XCTUnwrap(context.leaveSpaceViewModel?.state.leaveHandle)
|
||||
let selectedCount = handle.selectedCount
|
||||
let firstSelectedRoom = try XCTUnwrap(handle.rooms.first { $0.isSelected })
|
||||
XCTAssertGreaterThan(selectedCount, 0, "The leave view should have selected rooms to begin with")
|
||||
|
||||
context.send(viewAction: .deselectAllLeaveRoomDetails)
|
||||
leaveSpaceViewModel.context.send(viewAction: .deselectAll)
|
||||
XCTAssertEqual(handle.selectedCount, 0, "Deselecting all should result in no selected rooms.")
|
||||
|
||||
context.send(viewAction: .toggleLeaveSpaceRoomDetails(id: firstSelectedRoom.spaceRoomProxy.id))
|
||||
leaveSpaceViewModel.context.send(viewAction: .toggleRoom(roomID: firstSelectedRoom.spaceRoomProxy.id))
|
||||
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.
|
||||
let deferredAction = deferFulfillment(viewModel.actionsPublisher) { $0.isLeftSpace }
|
||||
context.send(viewAction: .confirmLeaveSpace)
|
||||
leaveSpaceViewModel.context.send(viewAction: .confirmLeaveSpace)
|
||||
try await deferredAction.fulfill()
|
||||
XCTAssertNil(context.leaveHandle)
|
||||
XCTAssertNil(context.leaveSpaceViewModel)
|
||||
XCTAssertTrue(rustLeaveHandle.leaveRoomIdsCalled)
|
||||
XCTAssertEqual(rustLeaveHandle.leaveRoomIdsReceivedRoomIds,
|
||||
[firstSelectedRoom.spaceRoomProxy.id, spaceRoomListProxy.id],
|
||||
|
||||
Reference in New Issue
Block a user