mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Switch callbacks to combine (#1710)
* #750 - Convert the SoftLogoutScreen to combine * #750 - Convert the UserSessionFlowCoordinator to Combine * #750 - Convert the AnalyticsPromptScreen to Combine * #750 - Convert the LoginScreen to Combine * #750 - Convert the ServerSelectionScreen to Combine * #750 - Convert the EmojiPickerScreen to Combine * #750 - Convert the HomeScreen to Combine * #750 - Convert the MediaUploadPreviewScreen to Combine * #750 - Convert the OnboardingScreen to Combine * Rename `Onboarding` to `OnboardingScreen` * #750 - Convert the ReportContentScreen to Combine * #750 - Convert the RoomDetailsSscreen to Combine * #750 - Convert the RoomMemberDetailsScreen to Combine * #750 - Convert the RoomMembersListScreen to Combine * #750 - Convert the SessionVerificationScreen to Combine * #750 - Convert the SettingsScreen to Combine * #750 - Convert the AdvancedSettingsScreen to Combine * #750 - Convert the DeveloperOptionsScreen to Combine * Fix the unit tests * Use .sink action and the same cancellables constructor everywhere * Cleanup cancellables when setting up tests
This commit is contained in:
parent
a0d40b6f0c
commit
a4e5e4f0ed
@ -39,6 +39,7 @@
|
|||||||
0BDA19079FD6E17C5AC62E22 /* RoomDetailsEditScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06F22CFA34885B40976061 /* RoomDetailsEditScreen.swift */; };
|
0BDA19079FD6E17C5AC62E22 /* RoomDetailsEditScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06F22CFA34885B40976061 /* RoomDetailsEditScreen.swift */; };
|
||||||
0BE4D5CBF86956410F071F91 /* CreateRoomViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15A657D96779D1DEB8EF1327 /* CreateRoomViewModel.swift */; };
|
0BE4D5CBF86956410F071F91 /* CreateRoomViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15A657D96779D1DEB8EF1327 /* CreateRoomViewModel.swift */; };
|
||||||
0BFA67AFD757EE2BA569836A /* ScrollViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */; };
|
0BFA67AFD757EE2BA569836A /* ScrollViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */; };
|
||||||
|
0C26A1588B17DCDE5F490FE3 /* OnboardingScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D53D6BB7E8E5EC031281872C /* OnboardingScreenViewModelTests.swift */; };
|
||||||
0C47AE2CA7929CB3B0E2D793 /* ServerSelectionScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0685156EB62D7E243F097CFC /* ServerSelectionScreenViewModelProtocol.swift */; };
|
0C47AE2CA7929CB3B0E2D793 /* ServerSelectionScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0685156EB62D7E243F097CFC /* ServerSelectionScreenViewModelProtocol.swift */; };
|
||||||
0C58A846F61949B1D545D661 /* NoticeRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421E716C521F96D24ECE69B3 /* NoticeRoomTimelineItem.swift */; };
|
0C58A846F61949B1D545D661 /* NoticeRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421E716C521F96D24ECE69B3 /* NoticeRoomTimelineItem.swift */; };
|
||||||
0C797CD650DFD2876BEC5173 /* CollapsibleReactionLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F7C6DDBB5D12F6EF6A3D6E1 /* CollapsibleReactionLayout.swift */; };
|
0C797CD650DFD2876BEC5173 /* CollapsibleReactionLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F7C6DDBB5D12F6EF6A3D6E1 /* CollapsibleReactionLayout.swift */; };
|
||||||
@ -138,7 +139,6 @@
|
|||||||
2C4C750D0039AFABDF24236C /* TemplateScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342BEBC3C5FC3F9943C41C4C /* TemplateScreenViewModelProtocol.swift */; };
|
2C4C750D0039AFABDF24236C /* TemplateScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 342BEBC3C5FC3F9943C41C4C /* TemplateScreenViewModelProtocol.swift */; };
|
||||||
2C5E832434EE94E21AB3B238 /* EmojiPickerScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3EAE3E9D5EF4A6D5D9C6CFD /* EmojiPickerScreenViewModel.swift */; };
|
2C5E832434EE94E21AB3B238 /* EmojiPickerScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3EAE3E9D5EF4A6D5D9C6CFD /* EmojiPickerScreenViewModel.swift */; };
|
||||||
2CA6ABBC9A88EB89EA52FCCB /* ConfettiScene.scn in Resources */ = {isa = PBXBuildFile; fileRef = B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */; };
|
2CA6ABBC9A88EB89EA52FCCB /* ConfettiScene.scn in Resources */ = {isa = PBXBuildFile; fileRef = B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */; };
|
||||||
2CB6787E25B11711518E9588 /* OnboardingCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6281B199D8A8F0892490C2E /* OnboardingCoordinator.swift */; };
|
|
||||||
2DA90E38FF4E696825810C1A /* WaitlistScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB08484CD5D77C9BF97AA78 /* WaitlistScreenUITests.swift */; };
|
2DA90E38FF4E696825810C1A /* WaitlistScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB08484CD5D77C9BF97AA78 /* WaitlistScreenUITests.swift */; };
|
||||||
2E43A3D221BE9587BC19C3F1 /* MatrixEntityRegexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F31F59030205A6F65B057E1A /* MatrixEntityRegexTests.swift */; };
|
2E43A3D221BE9587BC19C3F1 /* MatrixEntityRegexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F31F59030205A6F65B057E1A /* MatrixEntityRegexTests.swift */; };
|
||||||
2E8C6672D0EE7D5B1BEDB8E2 /* ServerConfirmationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7478623CECC9438014244BA /* ServerConfirmationScreen.swift */; };
|
2E8C6672D0EE7D5B1BEDB8E2 /* ServerConfirmationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7478623CECC9438014244BA /* ServerConfirmationScreen.swift */; };
|
||||||
@ -152,7 +152,6 @@
|
|||||||
30CC4F796B27BE8B1DFDBF5A /* NSEUserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAA2832D93EC7D2608703FB /* NSEUserSession.swift */; };
|
30CC4F796B27BE8B1DFDBF5A /* NSEUserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAA2832D93EC7D2608703FB /* NSEUserSession.swift */; };
|
||||||
3113065AABBC14CEAE6843FA /* UserSessionFlowCoordinatorStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8774CF614849664B5B3C2A1 /* UserSessionFlowCoordinatorStateMachine.swift */; };
|
3113065AABBC14CEAE6843FA /* UserSessionFlowCoordinatorStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8774CF614849664B5B3C2A1 /* UserSessionFlowCoordinatorStateMachine.swift */; };
|
||||||
3116693C5EB476E028990416 /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74611A4182DCF5F4D42696EC /* XCTestCase.swift */; };
|
3116693C5EB476E028990416 /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74611A4182DCF5F4D42696EC /* XCTestCase.swift */; };
|
||||||
329571083B132E4941131835 /* OnboardingBackgroundImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 686BCFA37AC6C67FF973CE67 /* OnboardingBackgroundImage.swift */; };
|
|
||||||
32B7891D937377A59606EDFC /* UserFlowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21DD8599815136EFF5B73F38 /* UserFlowTests.swift */; };
|
32B7891D937377A59606EDFC /* UserFlowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21DD8599815136EFF5B73F38 /* UserFlowTests.swift */; };
|
||||||
339BC18777912E1989F2F17D /* Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584A61D9C459FAFEF038A7C0 /* Section.swift */; };
|
339BC18777912E1989F2F17D /* Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584A61D9C459FAFEF038A7C0 /* Section.swift */; };
|
||||||
339D847497C51F2B36E3666B /* FixedIconSizeLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3518637393394901BF5BFAC3 /* FixedIconSizeLabelStyle.swift */; };
|
339D847497C51F2B36E3666B /* FixedIconSizeLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3518637393394901BF5BFAC3 /* FixedIconSizeLabelStyle.swift */; };
|
||||||
@ -178,6 +177,7 @@
|
|||||||
388D39ED9FE1122EA6D76BF2 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BC84BA0AF11C2128D58ABD /* Common.swift */; };
|
388D39ED9FE1122EA6D76BF2 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BC84BA0AF11C2128D58ABD /* Common.swift */; };
|
||||||
39929D29B265C3F6606047DE /* AlignedScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8872E9C5E91E9F2BFC4EBCCA /* AlignedScrollView.swift */; };
|
39929D29B265C3F6606047DE /* AlignedScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8872E9C5E91E9F2BFC4EBCCA /* AlignedScrollView.swift */; };
|
||||||
3A08584ECDD4A4541DBF21F8 /* EmojiLoaderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 201305507D7DFD16E544563A /* EmojiLoaderProtocol.swift */; };
|
3A08584ECDD4A4541DBF21F8 /* EmojiLoaderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 201305507D7DFD16E544563A /* EmojiLoaderProtocol.swift */; };
|
||||||
|
3A5BD701D1AC916AC534F52C /* OnboardingScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB26F24164E9461B2054D0B3 /* OnboardingScreenModels.swift */; };
|
||||||
3A64A93A651A3CB8774ADE8E /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = BA93CD75CCE486660C9040BD /* Collections */; };
|
3A64A93A651A3CB8774ADE8E /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = BA93CD75CCE486660C9040BD /* Collections */; };
|
||||||
3A7DD0D13B0FB8876D69D829 /* TextBasedRoomTimelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB2C848BB9A7A9B618B7B89 /* TextBasedRoomTimelineTests.swift */; };
|
3A7DD0D13B0FB8876D69D829 /* TextBasedRoomTimelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB2C848BB9A7A9B618B7B89 /* TextBasedRoomTimelineTests.swift */; };
|
||||||
3B0F9B57D25B07E66F15762A /* MediaUploadPreviewScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2E7C987AE5DC9087BB19F7D /* MediaUploadPreviewScreenModels.swift */; };
|
3B0F9B57D25B07E66F15762A /* MediaUploadPreviewScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2E7C987AE5DC9087BB19F7D /* MediaUploadPreviewScreenModels.swift */; };
|
||||||
@ -214,6 +214,7 @@
|
|||||||
46A261AA898344A1F3C406B1 /* ReportContentScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CCE3636E3D01477C8B2E9D0 /* ReportContentScreenModels.swift */; };
|
46A261AA898344A1F3C406B1 /* ReportContentScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CCE3636E3D01477C8B2E9D0 /* ReportContentScreenModels.swift */; };
|
||||||
46BA7F4B4D3A7164DED44B88 /* FullscreenDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 565F1B2B300597C616B37888 /* FullscreenDialog.swift */; };
|
46BA7F4B4D3A7164DED44B88 /* FullscreenDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 565F1B2B300597C616B37888 /* FullscreenDialog.swift */; };
|
||||||
46D1E2940ED8CCBF62FE8854 /* CreatePollScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27EA0F71A3A400A202E15318 /* CreatePollScreen.swift */; };
|
46D1E2940ED8CCBF62FE8854 /* CreatePollScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27EA0F71A3A400A202E15318 /* CreatePollScreen.swift */; };
|
||||||
|
4714991754A08B58B4D7ED85 /* OnboardingScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F27BAB69EB568369F1F6B3 /* OnboardingScreenViewModelProtocol.swift */; };
|
||||||
47305C0911C9E1AA774A4000 /* TemplateScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA90BD288E5AE6BC643AFDDF /* TemplateScreenCoordinator.swift */; };
|
47305C0911C9E1AA774A4000 /* TemplateScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA90BD288E5AE6BC643AFDDF /* TemplateScreenCoordinator.swift */; };
|
||||||
4799A852132F1744E2825994 /* CreateRoomViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340179A0FC1AD4AEDA7FC134 /* CreateRoomViewModelProtocol.swift */; };
|
4799A852132F1744E2825994 /* CreateRoomViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340179A0FC1AD4AEDA7FC134 /* CreateRoomViewModelProtocol.swift */; };
|
||||||
484202C5D50983442D24D061 /* AttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52BD6ED18E2EB61E28C340AD /* AttributedString.swift */; };
|
484202C5D50983442D24D061 /* AttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52BD6ED18E2EB61E28C340AD /* AttributedString.swift */; };
|
||||||
@ -278,7 +279,6 @@
|
|||||||
5D2AF8C0DF872E7985F8FE54 /* TimelineDeliveryStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5AC06FC11B6638F7BF1670E /* TimelineDeliveryStatusView.swift */; };
|
5D2AF8C0DF872E7985F8FE54 /* TimelineDeliveryStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5AC06FC11B6638F7BF1670E /* TimelineDeliveryStatusView.swift */; };
|
||||||
5D53AE9342A4C06B704247ED /* MediaLoaderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A02406480C351B8C6E0682C /* MediaLoaderProtocol.swift */; };
|
5D53AE9342A4C06B704247ED /* MediaLoaderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A02406480C351B8C6E0682C /* MediaLoaderProtocol.swift */; };
|
||||||
5D70FAE4D2BF4553AFFFFE41 /* NotificationItemProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F7FE40EF7490A7E09D7BE6 /* NotificationItemProxy.swift */; };
|
5D70FAE4D2BF4553AFFFFE41 /* NotificationItemProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F7FE40EF7490A7E09D7BE6 /* NotificationItemProxy.swift */; };
|
||||||
5D7960B32C350FA93F48D02B /* OnboardingModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB33A751BFDA223BDD106EC0 /* OnboardingModels.swift */; };
|
|
||||||
5DD85A0FE3D85AEC3C7EFE36 /* DeveloperOptionsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7C7CFA6B2A62A685FF6CE3 /* DeveloperOptionsScreenCoordinator.swift */; };
|
5DD85A0FE3D85AEC3C7EFE36 /* DeveloperOptionsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7C7CFA6B2A62A685FF6CE3 /* DeveloperOptionsScreenCoordinator.swift */; };
|
||||||
5E0F2E612718BB4397A6D40A /* TextRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9E785D5137510481733A3E8 /* TextRoomTimelineView.swift */; };
|
5E0F2E612718BB4397A6D40A /* TextRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9E785D5137510481733A3E8 /* TextRoomTimelineView.swift */; };
|
||||||
5E415EF9A5D31B1690CE27F5 /* CreatePollScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5DDF245FA51CF75F89E58A4 /* CreatePollScreenUITests.swift */; };
|
5E415EF9A5D31B1690CE27F5 /* CreatePollScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5DDF245FA51CF75F89E58A4 /* CreatePollScreenUITests.swift */; };
|
||||||
@ -321,7 +321,6 @@
|
|||||||
69C7B956B74BEC3DB88224EA /* NavigationSplitCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78913D6E120D46138E97C107 /* NavigationSplitCoordinatorTests.swift */; };
|
69C7B956B74BEC3DB88224EA /* NavigationSplitCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78913D6E120D46138E97C107 /* NavigationSplitCoordinatorTests.swift */; };
|
||||||
6A0E7551E0D1793245F34CDD /* ClientError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09A267106B9585D3D0CFC0D /* ClientError.swift */; };
|
6A0E7551E0D1793245F34CDD /* ClientError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09A267106B9585D3D0CFC0D /* ClientError.swift */; };
|
||||||
6AD722DD92E465E56D2885AB /* BugReportScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */; };
|
6AD722DD92E465E56D2885AB /* BugReportScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */; };
|
||||||
6B15FF984906AAFCF9DC4F58 /* OnboardingUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C88046D6A070D9827181C4D /* OnboardingUITests.swift */; };
|
|
||||||
6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */; };
|
6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */; };
|
||||||
6B4BF4A6450F55939B49FAEF /* PollOptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67779D9A1B797285A09B7720 /* PollOptionView.swift */; };
|
6B4BF4A6450F55939B49FAEF /* PollOptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67779D9A1B797285A09B7720 /* PollOptionView.swift */; };
|
||||||
6BB6944443C421C722ED1E7D /* portrait_test_video.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = F2D513D2477B57F90E98EEC0 /* portrait_test_video.mp4 */; };
|
6BB6944443C421C722ED1E7D /* portrait_test_video.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = F2D513D2477B57F90E98EEC0 /* portrait_test_video.mp4 */; };
|
||||||
@ -377,6 +376,7 @@
|
|||||||
7C384A8E54A4B60A14CDE8E5 /* WaitlistScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12F1E7F9C2BE8BB751037826 /* WaitlistScreenCoordinator.swift */; };
|
7C384A8E54A4B60A14CDE8E5 /* WaitlistScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12F1E7F9C2BE8BB751037826 /* WaitlistScreenCoordinator.swift */; };
|
||||||
7C6376192F578E0BA801BFEC /* AnalyticsSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C64A14EE89928207E3B42B /* AnalyticsSettingsScreenModels.swift */; };
|
7C6376192F578E0BA801BFEC /* AnalyticsSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C64A14EE89928207E3B42B /* AnalyticsSettingsScreenModels.swift */; };
|
||||||
7CD16990BA843BE9ED639129 /* ImageRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DFE4453AB0B34C203447162 /* ImageRoomTimelineItem.swift */; };
|
7CD16990BA843BE9ED639129 /* ImageRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DFE4453AB0B34C203447162 /* ImageRoomTimelineItem.swift */; };
|
||||||
|
7CFCC177F0ED083867FAD9C9 /* OnboardingScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E727F7E0BCE8A0BBFD33FF /* OnboardingScreenCoordinator.swift */; };
|
||||||
7E2BB42805C59DB57E95610F /* PillView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7773CBFDBD458E0B7E270507 /* PillView.swift */; };
|
7E2BB42805C59DB57E95610F /* PillView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7773CBFDBD458E0B7E270507 /* PillView.swift */; };
|
||||||
7E91BAC17963ED41208F489B /* UserSessionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8BDC092D817B68CD9040C5 /* UserSessionStore.swift */; };
|
7E91BAC17963ED41208F489B /* UserSessionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8BDC092D817B68CD9040C5 /* UserSessionStore.swift */; };
|
||||||
7ECF12D5DCD69F67BD3E3842 /* RoomTimelineControllerFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18FE0CDF1FFA92EA7EE17B0B /* RoomTimelineControllerFactoryProtocol.swift */; };
|
7ECF12D5DCD69F67BD3E3842 /* RoomTimelineControllerFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18FE0CDF1FFA92EA7EE17B0B /* RoomTimelineControllerFactoryProtocol.swift */; };
|
||||||
@ -445,6 +445,7 @@
|
|||||||
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 */; };
|
||||||
91ABC91758A6E4A5FAA2E9C4 /* ReadReceipt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314F1C79850BE46E8ABEAFCB /* ReadReceipt.swift */; };
|
91ABC91758A6E4A5FAA2E9C4 /* ReadReceipt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314F1C79850BE46E8ABEAFCB /* ReadReceipt.swift */; };
|
||||||
|
92133B170A1F917685E9FF78 /* OnboardingScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D168471461717AF5689F64B /* OnboardingScreenUITests.swift */; };
|
||||||
9219640F4D980CFC5FE855AD /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 536E72DCBEEC4A1FE66CFDCE /* target.yml */; };
|
9219640F4D980CFC5FE855AD /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 536E72DCBEEC4A1FE66CFDCE /* target.yml */; };
|
||||||
92D9088B901CEBB1A99ECA4E /* RoomMemberProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FD673E24FBFCFDF398716A /* RoomMemberProxyMock.swift */; };
|
92D9088B901CEBB1A99ECA4E /* RoomMemberProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FD673E24FBFCFDF398716A /* RoomMemberProxyMock.swift */; };
|
||||||
93875ADD456142D20823ED24 /* ServerSelectionViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */; };
|
93875ADD456142D20823ED24 /* ServerSelectionViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */; };
|
||||||
@ -466,7 +467,6 @@
|
|||||||
981853650217B6C8ECDD998C /* NavigationRootCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F875D71347DC81EAE7687446 /* NavigationRootCoordinatorTests.swift */; };
|
981853650217B6C8ECDD998C /* NavigationRootCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F875D71347DC81EAE7687446 /* NavigationRootCoordinatorTests.swift */; };
|
||||||
983896D611ABF52A5C37498D /* RoomSummaryProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB3227C7A74B734924942E9 /* RoomSummaryProvider.swift */; };
|
983896D611ABF52A5C37498D /* RoomSummaryProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB3227C7A74B734924942E9 /* RoomSummaryProvider.swift */; };
|
||||||
988BA75A182738150894A23F /* UserIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8AE4B3273BA189FDCD4055C /* UserIndicator.swift */; };
|
988BA75A182738150894A23F /* UserIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8AE4B3273BA189FDCD4055C /* UserIndicator.swift */; };
|
||||||
992477AB8E3F3C36D627D32E /* OnboardingViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BC4437C107D52ED19357DFC /* OnboardingViewModelProtocol.swift */; };
|
|
||||||
992F5E750F5030C4BA2D0D03 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 01C4C7DB37597D7D8379511A /* Assets.xcassets */; };
|
992F5E750F5030C4BA2D0D03 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 01C4C7DB37597D7D8379511A /* Assets.xcassets */; };
|
||||||
9965CB800CE6BC74ACA969FC /* EncryptedHistoryRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75697AB5E64A12F1F069F511 /* EncryptedHistoryRoomTimelineView.swift */; };
|
9965CB800CE6BC74ACA969FC /* EncryptedHistoryRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75697AB5E64A12F1F069F511 /* EncryptedHistoryRoomTimelineView.swift */; };
|
||||||
99ED42B8F8D6BFB1DBCF4C45 /* AnalyticsEvents in Frameworks */ = {isa = PBXBuildFile; productRef = D661CAB418C075A94306A792 /* AnalyticsEvents */; };
|
99ED42B8F8D6BFB1DBCF4C45 /* AnalyticsEvents in Frameworks */ = {isa = PBXBuildFile; productRef = D661CAB418C075A94306A792 /* AnalyticsEvents */; };
|
||||||
@ -518,6 +518,7 @@
|
|||||||
A494741843F087881299ACF0 /* RestorationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3558A15CFB934F9229301527 /* RestorationToken.swift */; };
|
A494741843F087881299ACF0 /* RestorationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3558A15CFB934F9229301527 /* RestorationToken.swift */; };
|
||||||
A4E885358D7DD5A072A06824 /* PostHog in Frameworks */ = {isa = PBXBuildFile; productRef = CCE5BF78B125320CBF3BB834 /* PostHog */; };
|
A4E885358D7DD5A072A06824 /* PostHog in Frameworks */ = {isa = PBXBuildFile; productRef = CCE5BF78B125320CBF3BB834 /* PostHog */; };
|
||||||
A5B9EF45C7B8ACEB4954AE36 /* LoginScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9780389F8A53E4D26E23DD03 /* LoginScreenViewModelProtocol.swift */; };
|
A5B9EF45C7B8ACEB4954AE36 /* LoginScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9780389F8A53E4D26E23DD03 /* LoginScreenViewModelProtocol.swift */; };
|
||||||
|
A5C5C18671EDD2747AC16D2D /* OnboardingScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49C1CEBA9BCF5D2AD1884FA /* OnboardingScreenViewModel.swift */; };
|
||||||
A5D551E5691749066E0E0C44 /* RoomDetailsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 837B440C4705E4B899BCB899 /* RoomDetailsScreenViewModel.swift */; };
|
A5D551E5691749066E0E0C44 /* RoomDetailsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 837B440C4705E4B899BCB899 /* RoomDetailsScreenViewModel.swift */; };
|
||||||
A680F54935A6ADEA4ED6C38F /* TimelineItemStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A4C9547BBFEEF30AA11329B /* TimelineItemStatusView.swift */; };
|
A680F54935A6ADEA4ED6C38F /* TimelineItemStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A4C9547BBFEEF30AA11329B /* TimelineItemStatusView.swift */; };
|
||||||
A6D4C5EEA85A6A0ABA1559D6 /* RoomDetailsEditScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16D09C79746BDCD9173EB3A7 /* RoomDetailsEditScreenModels.swift */; };
|
A6D4C5EEA85A6A0ABA1559D6 /* RoomDetailsEditScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16D09C79746BDCD9173EB3A7 /* RoomDetailsEditScreenModels.swift */; };
|
||||||
@ -612,6 +613,7 @@
|
|||||||
C0090506A52A1991BAF4BA68 /* NotificationSettingsChatType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07579F9C29001E40715F3014 /* NotificationSettingsChatType.swift */; };
|
C0090506A52A1991BAF4BA68 /* NotificationSettingsChatType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07579F9C29001E40715F3014 /* NotificationSettingsChatType.swift */; };
|
||||||
C051475DFF4C8EBDDF4DC8E4 /* StartChatScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B99E13633862847D8B7E2815 /* StartChatScreenModels.swift */; };
|
C051475DFF4C8EBDDF4DC8E4 /* StartChatScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B99E13633862847D8B7E2815 /* StartChatScreenModels.swift */; };
|
||||||
C08AAE7563E0722C9383F51C /* RoomMembersListScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B8E176484A89BAC389D4076 /* RoomMembersListScreen.swift */; };
|
C08AAE7563E0722C9383F51C /* RoomMembersListScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B8E176484A89BAC389D4076 /* RoomMembersListScreen.swift */; };
|
||||||
|
C0DC02E2B91DC76A4D1A0E7F /* OnboardingScreenBackgroundImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3450F4C32D73532DBBC1A2 /* OnboardingScreenBackgroundImage.swift */; };
|
||||||
C11939FDC40716C4387275A4 /* NotificationSettingsEditScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8544F7058D31DBEB8DBFF0F5 /* NotificationSettingsEditScreenViewModelTests.swift */; };
|
C11939FDC40716C4387275A4 /* NotificationSettingsEditScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8544F7058D31DBEB8DBFF0F5 /* NotificationSettingsEditScreenViewModelTests.swift */; };
|
||||||
C13128AAA787A4C2CBE4EE82 /* MessageForwardingScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC10CCC8D68B863E20660DBC /* MessageForwardingScreenViewModelProtocol.swift */; };
|
C13128AAA787A4C2CBE4EE82 /* MessageForwardingScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC10CCC8D68B863E20660DBC /* MessageForwardingScreenViewModelProtocol.swift */; };
|
||||||
C1910A16BDF131FECA77BE22 /* EmojiPickerScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA38B9851CFCC4D67F5587D /* EmojiPickerScreenCoordinator.swift */; };
|
C1910A16BDF131FECA77BE22 /* EmojiPickerScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA38B9851CFCC4D67F5587D /* EmojiPickerScreenCoordinator.swift */; };
|
||||||
@ -662,7 +664,6 @@
|
|||||||
CDCA8A559E098503DDE29477 /* AttributedStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5C6FBF97B6EED3D4FA5EFF /* AttributedStringBuilder.swift */; };
|
CDCA8A559E098503DDE29477 /* AttributedStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5C6FBF97B6EED3D4FA5EFF /* AttributedStringBuilder.swift */; };
|
||||||
CE1694C7BB93C3311524EF28 /* Untranslated.strings in Resources */ = {isa = PBXBuildFile; fileRef = D2F7194F440375338F8E2487 /* Untranslated.strings */; };
|
CE1694C7BB93C3311524EF28 /* Untranslated.strings in Resources */ = {isa = PBXBuildFile; fileRef = D2F7194F440375338F8E2487 /* Untranslated.strings */; };
|
||||||
CE6F237360875D3D573FD0B2 /* RoomNotificationSettingsProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD6B522BD637845AB9570B10 /* RoomNotificationSettingsProxy.swift */; };
|
CE6F237360875D3D573FD0B2 /* RoomNotificationSettingsProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD6B522BD637845AB9570B10 /* RoomNotificationSettingsProxy.swift */; };
|
||||||
CE7148E80F09B7305E026AC6 /* OnboardingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1198B925F4A88DA74083662 /* OnboardingViewModel.swift */; };
|
|
||||||
CE9530A4CA661E090635C2F2 /* NotificationItemProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F7FE40EF7490A7E09D7BE6 /* NotificationItemProxy.swift */; };
|
CE9530A4CA661E090635C2F2 /* NotificationItemProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F7FE40EF7490A7E09D7BE6 /* NotificationItemProxy.swift */; };
|
||||||
CEB8FB1269DE20536608B957 /* LoginMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41FABA2B0AEF4389986495 /* LoginMode.swift */; };
|
CEB8FB1269DE20536608B957 /* LoginMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41FABA2B0AEF4389986495 /* LoginMode.swift */; };
|
||||||
CF3827071B0BC9638BD44F5D /* WaitlistScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB58EF0176D4CFB1040DA22 /* WaitlistScreenViewModel.swift */; };
|
CF3827071B0BC9638BD44F5D /* WaitlistScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB58EF0176D4CFB1040DA22 /* WaitlistScreenViewModel.swift */; };
|
||||||
@ -797,7 +798,6 @@
|
|||||||
F94000E3D91B11C527DA8807 /* UserProfileCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923485F85E1D765EF9D20E88 /* UserProfileCell.swift */; };
|
F94000E3D91B11C527DA8807 /* UserProfileCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923485F85E1D765EF9D20E88 /* UserProfileCell.swift */; };
|
||||||
F9842667B68DC6FA1F9ECCBB /* NSItemProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72EFC8C634469F9262659C7 /* NSItemProvider.swift */; };
|
F9842667B68DC6FA1F9ECCBB /* NSItemProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72EFC8C634469F9262659C7 /* NSItemProvider.swift */; };
|
||||||
F99FB21EFC6D99D247FE7CBE /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = DE8DC9B3FBA402117DC4C49F /* Kingfisher */; };
|
F99FB21EFC6D99D247FE7CBE /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = DE8DC9B3FBA402117DC4C49F /* Kingfisher */; };
|
||||||
F9F6D2883BBEBB9A3789A137 /* OnboardingViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00A941F289F6AB876BA3361A /* OnboardingViewModelTests.swift */; };
|
|
||||||
FA2BBAE9FC5E2E9F960C0980 /* NavigationCoordinators.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8F28602AC7AC881AED37EBA /* NavigationCoordinators.swift */; };
|
FA2BBAE9FC5E2E9F960C0980 /* NavigationCoordinators.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8F28602AC7AC881AED37EBA /* NavigationCoordinators.swift */; };
|
||||||
FA4296218444C48BC890F46B /* RoomMemberDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B35311C7FED04B0E1B80C2 /* RoomMemberDetails.swift */; };
|
FA4296218444C48BC890F46B /* RoomMemberDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B35311C7FED04B0E1B80C2 /* RoomMemberDetails.swift */; };
|
||||||
FA5A7E32B1920FCB4EEDC1BA /* RoomDetailsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6493AC9979CEB1410302BFE3 /* RoomDetailsScreenCoordinator.swift */; };
|
FA5A7E32B1920FCB4EEDC1BA /* RoomDetailsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6493AC9979CEB1410302BFE3 /* RoomDetailsScreenCoordinator.swift */; };
|
||||||
@ -864,7 +864,6 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
00245D40CD90FD71D6A05239 /* EmojiPickerScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreen.swift; sourceTree = "<group>"; };
|
00245D40CD90FD71D6A05239 /* EmojiPickerScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreen.swift; sourceTree = "<group>"; };
|
||||||
00A941F289F6AB876BA3361A /* OnboardingViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewModelTests.swift; sourceTree = "<group>"; };
|
|
||||||
00E5B2CBEF8F96424F095508 /* RoomDetailsEditScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsEditScreenViewModelTests.swift; sourceTree = "<group>"; };
|
00E5B2CBEF8F96424F095508 /* RoomDetailsEditScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsEditScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
01C4C7DB37597D7D8379511A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
01C4C7DB37597D7D8379511A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
024F7398C5FC12586FB10E9D /* EffectsScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EffectsScene.swift; sourceTree = "<group>"; };
|
024F7398C5FC12586FB10E9D /* EffectsScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EffectsScene.swift; sourceTree = "<group>"; };
|
||||||
@ -900,7 +899,6 @@
|
|||||||
0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
0C34667458773B02AB5FB0B2 /* LegalInformationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenViewModel.swift; sourceTree = "<group>"; };
|
0C34667458773B02AB5FB0B2 /* LegalInformationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
0C671107BDFC6CD1778C0B4C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
0C671107BDFC6CD1778C0B4C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||||
0C88046D6A070D9827181C4D /* OnboardingUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingUITests.swift; sourceTree = "<group>"; };
|
|
||||||
0D0B159AFFBBD8ECFD0E37FA /* LoginScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenModels.swift; sourceTree = "<group>"; };
|
0D0B159AFFBBD8ECFD0E37FA /* LoginScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenModels.swift; sourceTree = "<group>"; };
|
||||||
0D8F620C8B314840D8602E3F /* NSE.appex */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "wrapper.app-extension"; path = NSE.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
0D8F620C8B314840D8602E3F /* NSE.appex */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "wrapper.app-extension"; path = NSE.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
0E8BDC092D817B68CD9040C5 /* UserSessionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStore.swift; sourceTree = "<group>"; };
|
0E8BDC092D817B68CD9040C5 /* UserSessionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStore.swift; sourceTree = "<group>"; };
|
||||||
@ -958,7 +956,6 @@
|
|||||||
1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenModels.swift; sourceTree = "<group>"; };
|
1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenModels.swift; sourceTree = "<group>"; };
|
||||||
1B8E176484A89BAC389D4076 /* RoomMembersListScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreen.swift; sourceTree = "<group>"; };
|
1B8E176484A89BAC389D4076 /* RoomMembersListScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreen.swift; sourceTree = "<group>"; };
|
||||||
1B927CF5EF7FCCDA5EDC474B /* NotificationItemProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationItemProxyProtocol.swift; sourceTree = "<group>"; };
|
1B927CF5EF7FCCDA5EDC474B /* NotificationItemProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationItemProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
1BC4437C107D52ED19357DFC /* OnboardingViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewModelProtocol.swift; sourceTree = "<group>"; };
|
|
||||||
1CC575D1895FA62591451A93 /* RoomMemberDetailsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreen.swift; sourceTree = "<group>"; };
|
1CC575D1895FA62591451A93 /* RoomMemberDetailsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreen.swift; sourceTree = "<group>"; };
|
||||||
1D56469A9EE0CFA2B7BA9760 /* SessionVerificationControllerProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxyProtocol.swift; sourceTree = "<group>"; };
|
1D56469A9EE0CFA2B7BA9760 /* SessionVerificationControllerProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
1DB34B0C74CD242FED9DD069 /* LoginScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenUITests.swift; sourceTree = "<group>"; };
|
1DB34B0C74CD242FED9DD069 /* LoginScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenUITests.swift; sourceTree = "<group>"; };
|
||||||
@ -1028,6 +1025,7 @@
|
|||||||
376D941BF8BB294389C0DE24 /* MapTilerURLBuildersTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerURLBuildersTests.swift; sourceTree = "<group>"; };
|
376D941BF8BB294389C0DE24 /* MapTilerURLBuildersTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerURLBuildersTests.swift; sourceTree = "<group>"; };
|
||||||
37A243E04B58DC6E41FDCD82 /* EmojiItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiItem.swift; sourceTree = "<group>"; };
|
37A243E04B58DC6E41FDCD82 /* EmojiItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiItem.swift; sourceTree = "<group>"; };
|
||||||
37CA26F55123E36B50DB0B3A /* AttributedStringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringTests.swift; sourceTree = "<group>"; };
|
37CA26F55123E36B50DB0B3A /* AttributedStringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringTests.swift; sourceTree = "<group>"; };
|
||||||
|
37E727F7E0BCE8A0BBFD33FF /* OnboardingScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
382B50F7E379B3DBBD174364 /* NotificationSettingsProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsProxyMock.swift; sourceTree = "<group>"; };
|
382B50F7E379B3DBBD174364 /* NotificationSettingsProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsProxyMock.swift; sourceTree = "<group>"; };
|
||||||
38E521D6C2BF8DF0DFB35146 /* DeveloperOptionsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreen.swift; sourceTree = "<group>"; };
|
38E521D6C2BF8DF0DFB35146 /* DeveloperOptionsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreen.swift; sourceTree = "<group>"; };
|
||||||
3948D16F021DFDB2CD26EAA8 /* MockBackgroundTaskService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBackgroundTaskService.swift; sourceTree = "<group>"; };
|
3948D16F021DFDB2CD26EAA8 /* MockBackgroundTaskService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBackgroundTaskService.swift; sourceTree = "<group>"; };
|
||||||
@ -1167,7 +1165,6 @@
|
|||||||
66F2402D738694F98729A441 /* RoomTimelineProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineProvider.swift; sourceTree = "<group>"; };
|
66F2402D738694F98729A441 /* RoomTimelineProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineProvider.swift; sourceTree = "<group>"; };
|
||||||
67779D9A1B797285A09B7720 /* PollOptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollOptionView.swift; sourceTree = "<group>"; };
|
67779D9A1B797285A09B7720 /* PollOptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollOptionView.swift; sourceTree = "<group>"; };
|
||||||
6861FE915C7B5466E6962BBA /* StartChatScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartChatScreen.swift; sourceTree = "<group>"; };
|
6861FE915C7B5466E6962BBA /* StartChatScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartChatScreen.swift; sourceTree = "<group>"; };
|
||||||
686BCFA37AC6C67FF973CE67 /* OnboardingBackgroundImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingBackgroundImage.swift; sourceTree = "<group>"; };
|
|
||||||
693E16574C6F7F9FA1015A8C /* Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Search.swift; sourceTree = "<group>"; };
|
693E16574C6F7F9FA1015A8C /* Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Search.swift; sourceTree = "<group>"; };
|
||||||
69B63F817FE305548DB4B512 /* RoomMembersListViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListViewModelTests.swift; sourceTree = "<group>"; };
|
69B63F817FE305548DB4B512 /* RoomMembersListViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
69CB8242D69B7E4D0B32E18D /* AggregatedReactionMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AggregatedReactionMock.swift; sourceTree = "<group>"; };
|
69CB8242D69B7E4D0B32E18D /* AggregatedReactionMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AggregatedReactionMock.swift; sourceTree = "<group>"; };
|
||||||
@ -1265,6 +1262,7 @@
|
|||||||
8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaLoader.swift; sourceTree = "<group>"; };
|
8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaLoader.swift; sourceTree = "<group>"; };
|
||||||
8BEBF0E59F25E842EDB6FD11 /* LocationSharingScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSharingScreenModels.swift; sourceTree = "<group>"; };
|
8BEBF0E59F25E842EDB6FD11 /* LocationSharingScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSharingScreenModels.swift; sourceTree = "<group>"; };
|
||||||
8C8616254EE40CA8BA5E9BC2 /* VideoRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRoomTimelineItemContent.swift; sourceTree = "<group>"; };
|
8C8616254EE40CA8BA5E9BC2 /* VideoRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRoomTimelineItemContent.swift; sourceTree = "<group>"; };
|
||||||
|
8D168471461717AF5689F64B /* OnboardingScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingScreenUITests.swift; sourceTree = "<group>"; };
|
||||||
8D55702474F279D910D2D162 /* RoomStateEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomStateEventStringBuilder.swift; sourceTree = "<group>"; };
|
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>"; };
|
8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyle.swift; sourceTree = "<group>"; };
|
8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyle.swift; sourceTree = "<group>"; };
|
||||||
@ -1312,6 +1310,7 @@
|
|||||||
9CE3C90E487B255B735D73C8 /* RoomScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModel.swift; sourceTree = "<group>"; };
|
9CE3C90E487B255B735D73C8 /* RoomScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
9CF1EE0AA78470C674554262 /* PillTextAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillTextAttachment.swift; sourceTree = "<group>"; };
|
9CF1EE0AA78470C674554262 /* PillTextAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillTextAttachment.swift; sourceTree = "<group>"; };
|
||||||
9E6D88E8AFFBF2C1D589C0FA /* UIConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIConstants.swift; sourceTree = "<group>"; };
|
9E6D88E8AFFBF2C1D589C0FA /* UIConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIConstants.swift; sourceTree = "<group>"; };
|
||||||
|
9F3450F4C32D73532DBBC1A2 /* OnboardingScreenBackgroundImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingScreenBackgroundImage.swift; sourceTree = "<group>"; };
|
||||||
9F85164F9475FF2867F71AAA /* RoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineController.swift; sourceTree = "<group>"; };
|
9F85164F9475FF2867F71AAA /* RoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineController.swift; sourceTree = "<group>"; };
|
||||||
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>"; };
|
||||||
A05707BF550D770168A406DB /* LoginViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModelTests.swift; sourceTree = "<group>"; };
|
A05707BF550D770168A406DB /* LoginViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
@ -1402,7 +1401,6 @@
|
|||||||
BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreen.swift; sourceTree = "<group>"; };
|
BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreen.swift; sourceTree = "<group>"; };
|
||||||
BB23BEAF8831DC6A57E39F52 /* CreatePollScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatePollScreenCoordinator.swift; sourceTree = "<group>"; };
|
BB23BEAF8831DC6A57E39F52 /* CreatePollScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatePollScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
BB3073CCD77D906B330BC1D6 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = "<group>"; };
|
BB3073CCD77D906B330BC1D6 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = "<group>"; };
|
||||||
BB33A751BFDA223BDD106EC0 /* OnboardingModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingModels.swift; sourceTree = "<group>"; };
|
|
||||||
BB8BC4C791D0E88CFCF4E5DF /* ServerSelectionScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreenCoordinator.swift; sourceTree = "<group>"; };
|
BB8BC4C791D0E88CFCF4E5DF /* ServerSelectionScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
BC8AA23D4F37CC26564F63C5 /* LayoutMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutMocks.swift; sourceTree = "<group>"; };
|
BC8AA23D4F37CC26564F63C5 /* LayoutMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutMocks.swift; sourceTree = "<group>"; };
|
||||||
BE148A4FFEE853C5A281500C /* UNNotificationContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNNotificationContent.swift; sourceTree = "<group>"; };
|
BE148A4FFEE853C5A281500C /* UNNotificationContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNNotificationContent.swift; sourceTree = "<group>"; };
|
||||||
@ -1417,7 +1415,6 @@
|
|||||||
C08E9043618AE5B0BF7B07E1 /* TemplateScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenViewModelTests.swift; sourceTree = "<group>"; };
|
C08E9043618AE5B0BF7B07E1 /* TemplateScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
C0900BBF0A5D5D775E917C70 /* EventBasedMessageTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBasedMessageTimelineItemProtocol.swift; sourceTree = "<group>"; };
|
C0900BBF0A5D5D775E917C70 /* EventBasedMessageTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBasedMessageTimelineItemProtocol.swift; sourceTree = "<group>"; };
|
||||||
C0FEA560929DD73FFEF8C3DF /* HomeScreenEmptyStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenEmptyStateView.swift; sourceTree = "<group>"; };
|
C0FEA560929DD73FFEF8C3DF /* HomeScreenEmptyStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenEmptyStateView.swift; sourceTree = "<group>"; };
|
||||||
C1198B925F4A88DA74083662 /* OnboardingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewModel.swift; sourceTree = "<group>"; };
|
|
||||||
C14D83B2B7CD5501A0089EFC /* LayoutDirection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutDirection.swift; sourceTree = "<group>"; };
|
C14D83B2B7CD5501A0089EFC /* LayoutDirection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutDirection.swift; sourceTree = "<group>"; };
|
||||||
C1511766C534367700C8DD75 /* RoomNotificationModeProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationModeProxy.swift; sourceTree = "<group>"; };
|
C1511766C534367700C8DD75 /* RoomNotificationModeProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationModeProxy.swift; sourceTree = "<group>"; };
|
||||||
C15E0017717EAE3A1D02D005 /* StaticLocationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLocationScreenCoordinator.swift; sourceTree = "<group>"; };
|
C15E0017717EAE3A1D02D005 /* StaticLocationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLocationScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
@ -1428,6 +1425,7 @@
|
|||||||
C2E9B841EE4878283ECDB554 /* InviteUsersScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreen.swift; sourceTree = "<group>"; };
|
C2E9B841EE4878283ECDB554 /* InviteUsersScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreen.swift; sourceTree = "<group>"; };
|
||||||
C2F079B5DBD0D85FEA687AAE /* SDKGeneratedMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDKGeneratedMocks.swift; sourceTree = "<group>"; };
|
C2F079B5DBD0D85FEA687AAE /* SDKGeneratedMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDKGeneratedMocks.swift; sourceTree = "<group>"; };
|
||||||
C352359663A0E52BA20761EE /* LoadableImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableImage.swift; sourceTree = "<group>"; };
|
C352359663A0E52BA20761EE /* LoadableImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableImage.swift; sourceTree = "<group>"; };
|
||||||
|
C49C1CEBA9BCF5D2AD1884FA /* OnboardingScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
C4C89820BB2B88D4EA28131C /* BugReportScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
C4C89820BB2B88D4EA28131C /* BugReportScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
C54464351F170D570110AFCA /* WelcomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreen.swift; sourceTree = "<group>"; };
|
C54464351F170D570110AFCA /* WelcomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreen.swift; sourceTree = "<group>"; };
|
||||||
C55D7E514F9DE4E3D72FDCAD /* SessionVerificationControllerProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxy.swift; sourceTree = "<group>"; };
|
C55D7E514F9DE4E3D72FDCAD /* SessionVerificationControllerProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxy.swift; sourceTree = "<group>"; };
|
||||||
@ -1456,6 +1454,7 @@
|
|||||||
CA89A2DD51B6BBE1DA55E263 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
CA89A2DD51B6BBE1DA55E263 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
||||||
CA90BD288E5AE6BC643AFDDF /* TemplateScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenCoordinator.swift; sourceTree = "<group>"; };
|
CA90BD288E5AE6BC643AFDDF /* TemplateScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
CACA846B3E3E9A521D98B178 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
CACA846B3E3E9A521D98B178 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
CB26F24164E9461B2054D0B3 /* OnboardingScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingScreenModels.swift; sourceTree = "<group>"; };
|
||||||
CBBCC6E74774E79B599625D0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
CBBCC6E74774E79B599625D0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
CBF9AEA706926DD0DA2B954C /* JoinedRoomSize+MemberCount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "JoinedRoomSize+MemberCount.swift"; sourceTree = "<group>"; };
|
CBF9AEA706926DD0DA2B954C /* JoinedRoomSize+MemberCount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "JoinedRoomSize+MemberCount.swift"; sourceTree = "<group>"; };
|
||||||
CC03209FDE8CE0810617BFFF /* RoomMembersListScreenMemberCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenMemberCell.swift; sourceTree = "<group>"; };
|
CC03209FDE8CE0810617BFFF /* RoomMembersListScreenMemberCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenMemberCell.swift; sourceTree = "<group>"; };
|
||||||
@ -1488,6 +1487,7 @@
|
|||||||
D3D455BC2423D911A62ACFB2 /* NSELogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSELogger.swift; sourceTree = "<group>"; };
|
D3D455BC2423D911A62ACFB2 /* NSELogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSELogger.swift; sourceTree = "<group>"; };
|
||||||
D49B9785E3AD7D1C15A29F2F /* MediaSourceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaSourceProxy.swift; sourceTree = "<group>"; };
|
D49B9785E3AD7D1C15A29F2F /* MediaSourceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaSourceProxy.swift; sourceTree = "<group>"; };
|
||||||
D4DA544B2520BFA65D6DB4BB /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
D4DA544B2520BFA65D6DB4BB /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
||||||
|
D53D6BB7E8E5EC031281872C /* OnboardingScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
D54E12B98252F6C527E31FEE /* MediaUploadPreviewScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
D54E12B98252F6C527E31FEE /* MediaUploadPreviewScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
D5685139D0B72BED3503EFCC /* MigrationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationScreen.swift; sourceTree = "<group>"; };
|
D5685139D0B72BED3503EFCC /* MigrationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationScreen.swift; sourceTree = "<group>"; };
|
||||||
D5AC06FC11B6638F7BF1670E /* TimelineDeliveryStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineDeliveryStatusView.swift; sourceTree = "<group>"; };
|
D5AC06FC11B6638F7BF1670E /* TimelineDeliveryStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineDeliveryStatusView.swift; sourceTree = "<group>"; };
|
||||||
@ -1520,6 +1520,7 @@
|
|||||||
E26747B3154A5DBC3A7E24A5 /* Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = "<group>"; };
|
E26747B3154A5DBC3A7E24A5 /* Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = "<group>"; };
|
||||||
E2B1CC9AA154F4D5435BF60A /* Comparable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Comparable.swift; sourceTree = "<group>"; };
|
E2B1CC9AA154F4D5435BF60A /* Comparable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Comparable.swift; sourceTree = "<group>"; };
|
||||||
E2DCA495ED42D2463DDAA94D /* TimelineBubbleLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineBubbleLayout.swift; sourceTree = "<group>"; };
|
E2DCA495ED42D2463DDAA94D /* TimelineBubbleLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineBubbleLayout.swift; sourceTree = "<group>"; };
|
||||||
|
E2F27BAB69EB568369F1F6B3 /* OnboardingScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
E3059CFA00C67D8787273B20 /* ServerSelectionScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreenViewModel.swift; sourceTree = "<group>"; };
|
E3059CFA00C67D8787273B20 /* ServerSelectionScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
E36CB905A2B9EC2C92A2DA7C /* KeychainController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainController.swift; sourceTree = "<group>"; };
|
E36CB905A2B9EC2C92A2DA7C /* KeychainController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainController.swift; sourceTree = "<group>"; };
|
||||||
E3B97591B2D3D4D67553506D /* AnalyticsClientProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsClientProtocol.swift; sourceTree = "<group>"; };
|
E3B97591B2D3D4D67553506D /* AnalyticsClientProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsClientProtocol.swift; sourceTree = "<group>"; };
|
||||||
@ -1532,7 +1533,6 @@
|
|||||||
E55B5EA766E89FF1F87C3ACB /* RoomNotificationSettingsProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsProxyProtocol.swift; sourceTree = "<group>"; };
|
E55B5EA766E89FF1F87C3ACB /* RoomNotificationSettingsProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerProtocol.swift; 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>"; };
|
E5F2B6443D1ED8602F328539 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
E6281B199D8A8F0892490C2E /* OnboardingCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingCoordinator.swift; sourceTree = "<group>"; };
|
|
||||||
E65DA46BD5CA83747AE144F3 /* secrets.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = secrets.xcconfig; sourceTree = "<group>"; };
|
E65DA46BD5CA83747AE144F3 /* secrets.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = secrets.xcconfig; sourceTree = "<group>"; };
|
||||||
E6E6BDF9D26DB05C88901416 /* RedactedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedactedRoomTimelineItem.swift; sourceTree = "<group>"; };
|
E6E6BDF9D26DB05C88901416 /* RedactedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedactedRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
E6F5D66F158A6662F953733E /* NotificationSettingsProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsProxy.swift; sourceTree = "<group>"; };
|
E6F5D66F158A6662F953733E /* NotificationSettingsProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsProxy.swift; sourceTree = "<group>"; };
|
||||||
@ -2161,10 +2161,10 @@
|
|||||||
3F38EAC92E2281990E65DAF2 /* OnboardingScreen */ = {
|
3F38EAC92E2281990E65DAF2 /* OnboardingScreen */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
E6281B199D8A8F0892490C2E /* OnboardingCoordinator.swift */,
|
37E727F7E0BCE8A0BBFD33FF /* OnboardingScreenCoordinator.swift */,
|
||||||
BB33A751BFDA223BDD106EC0 /* OnboardingModels.swift */,
|
CB26F24164E9461B2054D0B3 /* OnboardingScreenModels.swift */,
|
||||||
C1198B925F4A88DA74083662 /* OnboardingViewModel.swift */,
|
C49C1CEBA9BCF5D2AD1884FA /* OnboardingScreenViewModel.swift */,
|
||||||
1BC4437C107D52ED19357DFC /* OnboardingViewModelProtocol.swift */,
|
E2F27BAB69EB568369F1F6B3 /* OnboardingScreenViewModelProtocol.swift */,
|
||||||
7B14834450AE76EEFDDBCBB8 /* View */,
|
7B14834450AE76EEFDDBCBB8 /* View */,
|
||||||
);
|
);
|
||||||
path = OnboardingScreen;
|
path = OnboardingScreen;
|
||||||
@ -2646,7 +2646,7 @@
|
|||||||
9C698E30698EC59302A8EEBD /* NavigationStackCoordinatorTests.swift */,
|
9C698E30698EC59302A8EEBD /* NavigationStackCoordinatorTests.swift */,
|
||||||
8544F7058D31DBEB8DBFF0F5 /* NotificationSettingsEditScreenViewModelTests.swift */,
|
8544F7058D31DBEB8DBFF0F5 /* NotificationSettingsEditScreenViewModelTests.swift */,
|
||||||
514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */,
|
514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */,
|
||||||
00A941F289F6AB876BA3361A /* OnboardingViewModelTests.swift */,
|
D53D6BB7E8E5EC031281872C /* OnboardingScreenViewModelTests.swift */,
|
||||||
6FB31A32C93D94930B253FBF /* PermalinkBuilderTests.swift */,
|
6FB31A32C93D94930B253FBF /* PermalinkBuilderTests.swift */,
|
||||||
086C19086DD16E9B38E25954 /* ReportContentViewModelTests.swift */,
|
086C19086DD16E9B38E25954 /* ReportContentViewModelTests.swift */,
|
||||||
00E5B2CBEF8F96424F095508 /* RoomDetailsEditScreenViewModelTests.swift */,
|
00E5B2CBEF8F96424F095508 /* RoomDetailsEditScreenViewModelTests.swift */,
|
||||||
@ -2798,8 +2798,8 @@
|
|||||||
7B14834450AE76EEFDDBCBB8 /* View */ = {
|
7B14834450AE76EEFDDBCBB8 /* View */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
686BCFA37AC6C67FF973CE67 /* OnboardingBackgroundImage.swift */,
|
|
||||||
AB8E75B9CB6C78BE8D09B1AF /* OnboardingScreen.swift */,
|
AB8E75B9CB6C78BE8D09B1AF /* OnboardingScreen.swift */,
|
||||||
|
9F3450F4C32D73532DBBC1A2 /* OnboardingScreenBackgroundImage.swift */,
|
||||||
);
|
);
|
||||||
path = View;
|
path = View;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -3064,7 +3064,7 @@
|
|||||||
75910F5A36EA8FF9BAD08D18 /* MigrationScreenUITests.swift */,
|
75910F5A36EA8FF9BAD08D18 /* MigrationScreenUITests.swift */,
|
||||||
46F52419AEEDA2C006CB7181 /* NotificationSettingsEditScreenUITests.swift */,
|
46F52419AEEDA2C006CB7181 /* NotificationSettingsEditScreenUITests.swift */,
|
||||||
B83BC0DC9A2DF2DD60F9B6E9 /* NotificationSettingsScreenUITests.swift */,
|
B83BC0DC9A2DF2DD60F9B6E9 /* NotificationSettingsScreenUITests.swift */,
|
||||||
0C88046D6A070D9827181C4D /* OnboardingUITests.swift */,
|
8D168471461717AF5689F64B /* OnboardingScreenUITests.swift */,
|
||||||
4132F882A984ED971338EE9D /* ReportContentScreenUITests.swift */,
|
4132F882A984ED971338EE9D /* ReportContentScreenUITests.swift */,
|
||||||
122186B7CD1BC46A9C629DD9 /* RoomDetailsEditScreenUITests.swift */,
|
122186B7CD1BC46A9C629DD9 /* RoomDetailsEditScreenUITests.swift */,
|
||||||
3BFDAF6918BB096C44788FC9 /* RoomDetailsScreenUITests.swift */,
|
3BFDAF6918BB096C44788FC9 /* RoomDetailsScreenUITests.swift */,
|
||||||
@ -4399,7 +4399,7 @@
|
|||||||
1B2DADC008EE211AF1DA5292 /* NotificationManagerTests.swift in Sources */,
|
1B2DADC008EE211AF1DA5292 /* NotificationManagerTests.swift in Sources */,
|
||||||
C11939FDC40716C4387275A4 /* NotificationSettingsEditScreenViewModelTests.swift in Sources */,
|
C11939FDC40716C4387275A4 /* NotificationSettingsEditScreenViewModelTests.swift in Sources */,
|
||||||
E3AC72E3E58F364EF15C1CC7 /* NotificationSettingsScreenViewModelTests.swift in Sources */,
|
E3AC72E3E58F364EF15C1CC7 /* NotificationSettingsScreenViewModelTests.swift in Sources */,
|
||||||
F9F6D2883BBEBB9A3789A137 /* OnboardingViewModelTests.swift in Sources */,
|
0C26A1588B17DCDE5F490FE3 /* OnboardingScreenViewModelTests.swift in Sources */,
|
||||||
27E9263DA75E266690A37EB1 /* PermalinkBuilderTests.swift in Sources */,
|
27E9263DA75E266690A37EB1 /* PermalinkBuilderTests.swift in Sources */,
|
||||||
D415764645491F10344FC6AC /* Publisher.swift in Sources */,
|
D415764645491F10344FC6AC /* Publisher.swift in Sources */,
|
||||||
D53B80EF02C1062E68659EDD /* ReportContentViewModelTests.swift in Sources */,
|
D53B80EF02C1062E68659EDD /* ReportContentViewModelTests.swift in Sources */,
|
||||||
@ -4740,12 +4740,12 @@
|
|||||||
CBD2ABE4C1A47ECD99E1488E /* NotificationSettingsScreenViewModelProtocol.swift in Sources */,
|
CBD2ABE4C1A47ECD99E1488E /* NotificationSettingsScreenViewModelProtocol.swift in Sources */,
|
||||||
523C6800ED85D5810CF18C19 /* OIDCAccountSettingsPresenter.swift in Sources */,
|
523C6800ED85D5810CF18C19 /* OIDCAccountSettingsPresenter.swift in Sources */,
|
||||||
9A4E3D5AA44B041DAC3A0D81 /* OIDCAuthenticationPresenter.swift in Sources */,
|
9A4E3D5AA44B041DAC3A0D81 /* OIDCAuthenticationPresenter.swift in Sources */,
|
||||||
329571083B132E4941131835 /* OnboardingBackgroundImage.swift in Sources */,
|
|
||||||
2CB6787E25B11711518E9588 /* OnboardingCoordinator.swift in Sources */,
|
|
||||||
5D7960B32C350FA93F48D02B /* OnboardingModels.swift in Sources */,
|
|
||||||
7F64FA937B95924B3A44EC12 /* OnboardingScreen.swift in Sources */,
|
7F64FA937B95924B3A44EC12 /* OnboardingScreen.swift in Sources */,
|
||||||
CE7148E80F09B7305E026AC6 /* OnboardingViewModel.swift in Sources */,
|
C0DC02E2B91DC76A4D1A0E7F /* OnboardingScreenBackgroundImage.swift in Sources */,
|
||||||
992477AB8E3F3C36D627D32E /* OnboardingViewModelProtocol.swift in Sources */,
|
7CFCC177F0ED083867FAD9C9 /* OnboardingScreenCoordinator.swift in Sources */,
|
||||||
|
3A5BD701D1AC916AC534F52C /* OnboardingScreenModels.swift in Sources */,
|
||||||
|
A5C5C18671EDD2747AC16D2D /* OnboardingScreenViewModel.swift in Sources */,
|
||||||
|
4714991754A08B58B4D7ED85 /* OnboardingScreenViewModelProtocol.swift in Sources */,
|
||||||
804C15D8ADE0EA7A5268F58A /* OverridableAvatarImage.swift in Sources */,
|
804C15D8ADE0EA7A5268F58A /* OverridableAvatarImage.swift in Sources */,
|
||||||
CD6A72B65D3B6076F4045C30 /* PHGPostHogConfiguration.swift in Sources */,
|
CD6A72B65D3B6076F4045C30 /* PHGPostHogConfiguration.swift in Sources */,
|
||||||
7501442D52A65F73DF79FFD4 /* PaginationIndicatorRoomTimelineItem.swift in Sources */,
|
7501442D52A65F73DF79FFD4 /* PaginationIndicatorRoomTimelineItem.swift in Sources */,
|
||||||
@ -5019,7 +5019,7 @@
|
|||||||
51C240F4660F7269203A9B3A /* MigrationScreenUITests.swift in Sources */,
|
51C240F4660F7269203A9B3A /* MigrationScreenUITests.swift in Sources */,
|
||||||
1830E5431DB426E2F3660D58 /* NotificationSettingsEditScreenUITests.swift in Sources */,
|
1830E5431DB426E2F3660D58 /* NotificationSettingsEditScreenUITests.swift in Sources */,
|
||||||
AF4232E6F08C3DB86FFA9BBD /* NotificationSettingsScreenUITests.swift in Sources */,
|
AF4232E6F08C3DB86FFA9BBD /* NotificationSettingsScreenUITests.swift in Sources */,
|
||||||
6B15FF984906AAFCF9DC4F58 /* OnboardingUITests.swift in Sources */,
|
92133B170A1F917685E9FF78 /* OnboardingScreenUITests.swift in Sources */,
|
||||||
BA0D3DDCEDD97502DAC4B6E9 /* ReportContentScreenUITests.swift in Sources */,
|
BA0D3DDCEDD97502DAC4B6E9 /* ReportContentScreenUITests.swift in Sources */,
|
||||||
F16109A6F6DF03DA26D59233 /* RoomDetailsEditScreenUITests.swift in Sources */,
|
F16109A6F6DF03DA26D59233 /* RoomDetailsEditScreenUITests.swift in Sources */,
|
||||||
829062DD3C3F7016FE1A6476 /* RoomDetailsScreenUITests.swift in Sources */,
|
829062DD3C3F7016FE1A6476 /* RoomDetailsScreenUITests.swift in Sources */,
|
||||||
|
@ -217,7 +217,7 @@
|
|||||||
{
|
{
|
||||||
"identity" : "swiftui-introspect",
|
"identity" : "swiftui-introspect",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/siteline/SwiftUI-Introspect",
|
"location" : "https://github.com/siteline/SwiftUI-Introspect.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "b94da693e57eaf79d16464b8b7c90d09cba4e290",
|
"revision" : "b94da693e57eaf79d16464b8b7c90d09cba4e290",
|
||||||
"version" : "0.9.2"
|
"version" : "0.9.2"
|
||||||
|
@ -51,7 +51,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
|
|||||||
private var appDelegateObserver: AnyCancellable?
|
private var appDelegateObserver: AnyCancellable?
|
||||||
private var userSessionObserver: AnyCancellable?
|
private var userSessionObserver: AnyCancellable?
|
||||||
private var clientProxyObserver: AnyCancellable?
|
private var clientProxyObserver: AnyCancellable?
|
||||||
private var networkMonitorObserver: AnyCancellable?
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
let notificationManager: NotificationManagerProtocol
|
let notificationManager: NotificationManagerProtocol
|
||||||
|
|
||||||
@ -374,15 +374,20 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
|
|||||||
keyBackupNeeded: false,
|
keyBackupNeeded: false,
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||||
let coordinator = SoftLogoutScreenCoordinator(parameters: parameters)
|
let coordinator = SoftLogoutScreenCoordinator(parameters: parameters)
|
||||||
coordinator.callback = { result in
|
|
||||||
switch result {
|
coordinator.actions
|
||||||
case .signedIn(let session):
|
.sink { [weak self] action in
|
||||||
self.userSession = session
|
guard let self else { return }
|
||||||
self.stateMachine.processEvent(.createdUserSession)
|
|
||||||
case .clearAllData:
|
switch action {
|
||||||
self.stateMachine.processEvent(.signOut(isSoft: false))
|
case .signedIn(let session):
|
||||||
|
self.userSession = session
|
||||||
|
stateMachine.processEvent(.createdUserSession)
|
||||||
|
case .clearAllData:
|
||||||
|
stateMachine.processEvent(.signOut(isSoft: false))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
navigationRootCoordinator.setRootCoordinator(coordinator)
|
navigationRootCoordinator.setRootCoordinator(coordinator)
|
||||||
}
|
}
|
||||||
@ -401,14 +406,18 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
|
|||||||
appSettings: appSettings,
|
appSettings: appSettings,
|
||||||
analytics: ServiceLocator.shared.analytics)
|
analytics: ServiceLocator.shared.analytics)
|
||||||
|
|
||||||
userSessionFlowCoordinator.callback = { [weak self] action in
|
userSessionFlowCoordinator.actions
|
||||||
switch action {
|
.sink { [weak self] action in
|
||||||
case .signOut:
|
guard let self else { return }
|
||||||
self?.stateMachine.processEvent(.signOut(isSoft: false))
|
|
||||||
case .clearCache:
|
switch action {
|
||||||
self?.stateMachine.processEvent(.clearCache)
|
case .signOut:
|
||||||
|
stateMachine.processEvent(.signOut(isSoft: false))
|
||||||
|
case .clearCache:
|
||||||
|
stateMachine.processEvent(.clearCache)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
userSessionFlowCoordinator.start()
|
userSessionFlowCoordinator.start()
|
||||||
|
|
||||||
@ -528,7 +537,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
|
|||||||
|
|
||||||
private func observeNetworkState() {
|
private func observeNetworkState() {
|
||||||
let reachabilityNotificationIdentifier = "io.element.elementx.reachability.notification"
|
let reachabilityNotificationIdentifier = "io.element.elementx.reachability.notification"
|
||||||
networkMonitorObserver = ServiceLocator.shared.networkMonitor
|
ServiceLocator.shared.networkMonitor
|
||||||
.reachabilityPublisher
|
.reachabilityPublisher
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
.sink { reachability in
|
.sink { reachability in
|
||||||
@ -542,6 +551,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
|
|||||||
persistent: true))
|
persistent: true))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleAppRoute(_ appRoute: AppRoute) {
|
private func handleAppRoute(_ appRoute: AppRoute) {
|
||||||
|
@ -36,7 +36,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
private let stateMachine: StateMachine<State, Event> = .init(state: .initial)
|
private let stateMachine: StateMachine<State, Event> = .init(state: .initial)
|
||||||
|
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
private let actionsSubject: PassthroughSubject<RoomFlowCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<RoomFlowCoordinatorAction, Never> = .init()
|
||||||
var actions: AnyPublisher<RoomFlowCoordinatorAction, Never> {
|
var actions: AnyPublisher<RoomFlowCoordinatorAction, Never> {
|
||||||
@ -456,16 +456,22 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
roomProxy: roomProxy,
|
roomProxy: roomProxy,
|
||||||
userIndicatorController: userIndicatorController)
|
userIndicatorController: userIndicatorController)
|
||||||
let coordinator = ReportContentScreenCoordinator(parameters: parameters)
|
let coordinator = ReportContentScreenCoordinator(parameters: parameters)
|
||||||
coordinator.callback = { [weak self] completion in
|
|
||||||
self?.navigationStackCoordinator.setSheetCoordinator(nil)
|
coordinator.actions
|
||||||
|
.sink { [weak self] action in
|
||||||
switch completion {
|
guard let self else { return }
|
||||||
case .cancel:
|
|
||||||
break
|
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||||
case .finish:
|
|
||||||
userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonReportSubmitted, iconName: "checkmark"))
|
switch action {
|
||||||
|
case .cancel:
|
||||||
|
break
|
||||||
|
case .finish:
|
||||||
|
userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonReportSubmitted, iconName: "checkmark"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
navigationCoordinator.setRootCoordinator(coordinator)
|
navigationCoordinator.setRootCoordinator(coordinator)
|
||||||
navigationStackCoordinator.setSheetCoordinator(userIndicatorController) { [weak self] in
|
navigationStackCoordinator.setSheetCoordinator(userIndicatorController) { [weak self] in
|
||||||
self?.stateMachine.tryEvent(.dismissReportContent)
|
self?.stateMachine.tryEvent(.dismissReportContent)
|
||||||
@ -508,12 +514,18 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
title: url.lastPathComponent,
|
title: url.lastPathComponent,
|
||||||
url: url)
|
url: url)
|
||||||
|
|
||||||
let mediaUploadPreviewScreenCoordinator = MediaUploadPreviewScreenCoordinator(parameters: parameters) { [weak self] action in
|
let mediaUploadPreviewScreenCoordinator = MediaUploadPreviewScreenCoordinator(parameters: parameters)
|
||||||
switch action {
|
|
||||||
case .dismiss:
|
mediaUploadPreviewScreenCoordinator.actions
|
||||||
self?.navigationStackCoordinator.setSheetCoordinator(nil)
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
|
|
||||||
|
switch action {
|
||||||
|
case .dismiss:
|
||||||
|
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
stackCoordinator.setRootCoordinator(mediaUploadPreviewScreenCoordinator)
|
stackCoordinator.setRootCoordinator(mediaUploadPreviewScreenCoordinator)
|
||||||
|
|
||||||
@ -526,18 +538,22 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
let params = EmojiPickerScreenCoordinatorParameters(emojiProvider: emojiProvider,
|
let params = EmojiPickerScreenCoordinatorParameters(emojiProvider: emojiProvider,
|
||||||
itemID: itemID, selectedEmojis: selectedEmoji)
|
itemID: itemID, selectedEmojis: selectedEmoji)
|
||||||
let coordinator = EmojiPickerScreenCoordinator(parameters: params)
|
let coordinator = EmojiPickerScreenCoordinator(parameters: params)
|
||||||
coordinator.callback = { [weak self] action in
|
|
||||||
|
coordinator.actions.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case let .emojiSelected(emoji: emoji, itemID: itemID):
|
case let .emojiSelected(emoji: emoji, itemID: itemID):
|
||||||
MXLog.debug("Selected \(emoji) for \(itemID)")
|
MXLog.debug("Selected \(emoji) for \(itemID)")
|
||||||
self?.navigationStackCoordinator.setSheetCoordinator(nil)
|
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||||
Task {
|
Task {
|
||||||
await self?.timelineController?.toggleReaction(emoji, to: itemID)
|
await self.timelineController?.toggleReaction(emoji, to: itemID)
|
||||||
}
|
}
|
||||||
case .dismiss:
|
case .dismiss:
|
||||||
self?.navigationStackCoordinator.setSheetCoordinator(nil)
|
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
navigationStackCoordinator.setSheetCoordinator(coordinator) { [weak self] in
|
navigationStackCoordinator.setSheetCoordinator(coordinator) { [weak self] in
|
||||||
self?.stateMachine.tryEvent(.dismissEmojiPicker)
|
self?.stateMachine.tryEvent(.dismissEmojiPicker)
|
||||||
|
@ -29,11 +29,12 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
private let roomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol
|
private let roomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol
|
||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
private let analytics: AnalyticsService
|
private let analytics: AnalyticsService
|
||||||
|
private let actionsSubject: PassthroughSubject<UserSessionFlowCoordinatorAction, Never> = .init()
|
||||||
|
|
||||||
private let stateMachine: UserSessionFlowCoordinatorStateMachine
|
private let stateMachine: UserSessionFlowCoordinatorStateMachine
|
||||||
private let roomFlowCoordinator: RoomFlowCoordinator
|
private let roomFlowCoordinator: RoomFlowCoordinator
|
||||||
|
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
private var migrationCancellable: AnyCancellable?
|
private var migrationCancellable: AnyCancellable?
|
||||||
|
|
||||||
private let sidebarNavigationStackCoordinator: NavigationStackCoordinator
|
private let sidebarNavigationStackCoordinator: NavigationStackCoordinator
|
||||||
@ -41,7 +42,9 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
private let selectedRoomSubject = CurrentValueSubject<String?, Never>(nil)
|
private let selectedRoomSubject = CurrentValueSubject<String?, Never>(nil)
|
||||||
|
|
||||||
var callback: ((UserSessionFlowCoordinatorAction) -> Void)?
|
var actions: AnyPublisher<UserSessionFlowCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(userSession: UserSessionProtocol,
|
init(userSession: UserSessionProtocol,
|
||||||
navigationSplitCoordinator: NavigationSplitCoordinator,
|
navigationSplitCoordinator: NavigationSplitCoordinator,
|
||||||
@ -263,34 +266,36 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
navigationStackCoordinator: detailNavigationStackCoordinator,
|
navigationStackCoordinator: detailNavigationStackCoordinator,
|
||||||
selectedRoomPublisher: selectedRoomSubject.asCurrentValuePublisher())
|
selectedRoomPublisher: selectedRoomSubject.asCurrentValuePublisher())
|
||||||
let coordinator = HomeScreenCoordinator(parameters: parameters)
|
let coordinator = HomeScreenCoordinator(parameters: parameters)
|
||||||
|
|
||||||
coordinator.callback = { [weak self] action in
|
coordinator.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
switch action {
|
|
||||||
case .presentRoom(let roomID):
|
switch action {
|
||||||
self.roomFlowCoordinator.handleAppRoute(.room(roomID: roomID), animated: true)
|
case .presentRoom(let roomID):
|
||||||
case .presentRoomDetails(let roomID):
|
roomFlowCoordinator.handleAppRoute(.room(roomID: roomID), animated: true)
|
||||||
self.roomFlowCoordinator.handleAppRoute(.roomDetails(roomID: roomID), animated: true)
|
case .presentRoomDetails(let roomID):
|
||||||
case .roomLeft(let roomID):
|
roomFlowCoordinator.handleAppRoute(.roomDetails(roomID: roomID), animated: true)
|
||||||
if case .roomList(selectedRoomID: let selectedRoomID) = stateMachine.state,
|
case .roomLeft(let roomID):
|
||||||
selectedRoomID == roomID {
|
if case .roomList(selectedRoomID: let selectedRoomID) = stateMachine.state,
|
||||||
self.roomFlowCoordinator.handleAppRoute(.roomList, animated: true)
|
selectedRoomID == roomID {
|
||||||
|
roomFlowCoordinator.handleAppRoute(.roomList, animated: true)
|
||||||
|
}
|
||||||
|
case .presentSettingsScreen:
|
||||||
|
stateMachine.processEvent(.showSettingsScreen)
|
||||||
|
case .presentFeedbackScreen:
|
||||||
|
stateMachine.processEvent(.feedbackScreen)
|
||||||
|
case .presentSessionVerificationScreen:
|
||||||
|
stateMachine.processEvent(.showSessionVerificationScreen)
|
||||||
|
case .presentStartChatScreen:
|
||||||
|
stateMachine.processEvent(.showStartChatScreen)
|
||||||
|
case .signOut:
|
||||||
|
actionsSubject.send(.signOut)
|
||||||
|
case .presentInvitesScreen:
|
||||||
|
stateMachine.processEvent(.showInvitesScreen)
|
||||||
}
|
}
|
||||||
case .presentSettingsScreen:
|
|
||||||
self.stateMachine.processEvent(.showSettingsScreen)
|
|
||||||
case .presentFeedbackScreen:
|
|
||||||
self.stateMachine.processEvent(.feedbackScreen)
|
|
||||||
case .presentSessionVerificationScreen:
|
|
||||||
self.stateMachine.processEvent(.showSessionVerificationScreen)
|
|
||||||
case .presentStartChatScreen:
|
|
||||||
self.stateMachine.processEvent(.showStartChatScreen)
|
|
||||||
case .signOut:
|
|
||||||
self.callback?(.signOut)
|
|
||||||
case .presentInvitesScreen:
|
|
||||||
self.stateMachine.processEvent(.showInvitesScreen)
|
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
sidebarNavigationStackCoordinator.setRootCoordinator(coordinator)
|
sidebarNavigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
}
|
}
|
||||||
@ -324,18 +329,22 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
notificationSettings: userSession.clientProxy.notificationSettings,
|
notificationSettings: userSession.clientProxy.notificationSettings,
|
||||||
appSettings: appSettings)
|
appSettings: appSettings)
|
||||||
let settingsScreenCoordinator = SettingsScreenCoordinator(parameters: parameters)
|
let settingsScreenCoordinator = SettingsScreenCoordinator(parameters: parameters)
|
||||||
settingsScreenCoordinator.callback = { [weak self] action in
|
|
||||||
guard let self else { return }
|
settingsScreenCoordinator.actions
|
||||||
switch action {
|
.sink { [weak self] action in
|
||||||
case .dismiss:
|
guard let self else { return }
|
||||||
self.navigationSplitCoordinator.setSheetCoordinator(nil)
|
|
||||||
case .logout:
|
switch action {
|
||||||
self.navigationSplitCoordinator.setSheetCoordinator(nil)
|
case .dismiss:
|
||||||
self.callback?(.signOut)
|
navigationSplitCoordinator.setSheetCoordinator(nil)
|
||||||
case .clearCache:
|
case .logout:
|
||||||
self.callback?(.clearCache)
|
navigationSplitCoordinator.setSheetCoordinator(nil)
|
||||||
|
actionsSubject.send(.signOut)
|
||||||
|
case .clearCache:
|
||||||
|
actionsSubject.send(.clearCache)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
settingsNavigationStackCoordinator.setRootCoordinator(settingsScreenCoordinator, animated: animated)
|
settingsNavigationStackCoordinator.setRootCoordinator(settingsScreenCoordinator, animated: animated)
|
||||||
|
|
||||||
@ -355,9 +364,16 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
let coordinator = SessionVerificationScreenCoordinator(parameters: parameters)
|
let coordinator = SessionVerificationScreenCoordinator(parameters: parameters)
|
||||||
|
|
||||||
coordinator.callback = { [weak self] in
|
coordinator.actions
|
||||||
self?.navigationSplitCoordinator.setSheetCoordinator(nil)
|
.sink { [weak self] action in
|
||||||
}
|
guard let self else { return }
|
||||||
|
|
||||||
|
switch action {
|
||||||
|
case .done:
|
||||||
|
navigationSplitCoordinator.setSheetCoordinator(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
navigationSplitCoordinator.setSheetCoordinator(coordinator, animated: animated) { [weak self] in
|
navigationSplitCoordinator.setSheetCoordinator(coordinator, animated: animated) { [weak self] in
|
||||||
self?.stateMachine.processEvent(.dismissedSessionVerificationScreen)
|
self?.stateMachine.processEvent(.dismissedSessionVerificationScreen)
|
||||||
|
@ -14,13 +14,22 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
enum AnalyticsPromptScreenCoordinatorAction {
|
||||||
|
case done
|
||||||
|
}
|
||||||
|
|
||||||
final class AnalyticsPromptScreenCoordinator: CoordinatorProtocol {
|
final class AnalyticsPromptScreenCoordinator: CoordinatorProtocol {
|
||||||
private let analytics: AnalyticsService
|
private let analytics: AnalyticsService
|
||||||
private var viewModel: AnalyticsPromptScreenViewModel
|
private var viewModel: AnalyticsPromptScreenViewModelProtocol
|
||||||
|
private let actionsSubject: PassthroughSubject<AnalyticsPromptScreenCoordinatorAction, Never> = .init()
|
||||||
var callback: (@MainActor () -> Void)?
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<AnalyticsPromptScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(analytics: AnalyticsService, termsURL: URL) {
|
init(analytics: AnalyticsService, termsURL: URL) {
|
||||||
self.analytics = analytics
|
self.analytics = analytics
|
||||||
@ -30,20 +39,22 @@ final class AnalyticsPromptScreenCoordinator: CoordinatorProtocol {
|
|||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
viewModel.callback = { [weak self] result in
|
viewModel.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
switch result {
|
|
||||||
case .enable:
|
switch action {
|
||||||
MXLog.info("Enable Analytics")
|
case .enable:
|
||||||
analytics.optIn()
|
MXLog.info("Enable Analytics")
|
||||||
self.callback?()
|
analytics.optIn()
|
||||||
case .disable:
|
actionsSubject.send(.done)
|
||||||
MXLog.info("Disable Analytics")
|
case .disable:
|
||||||
analytics.optOut()
|
MXLog.info("Disable Analytics")
|
||||||
self.callback?()
|
analytics.optOut()
|
||||||
|
actionsSubject.send(.done)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toPresentable() -> AnyView {
|
func toPresentable() -> AnyView {
|
||||||
|
@ -20,7 +20,11 @@ import SwiftUI
|
|||||||
typealias AnalyticsPromptScreenViewModelType = StateStoreViewModel<AnalyticsPromptScreenViewState, AnalyticsPromptScreenViewAction>
|
typealias AnalyticsPromptScreenViewModelType = StateStoreViewModel<AnalyticsPromptScreenViewState, AnalyticsPromptScreenViewAction>
|
||||||
|
|
||||||
class AnalyticsPromptScreenViewModel: AnalyticsPromptScreenViewModelType, AnalyticsPromptScreenViewModelProtocol {
|
class AnalyticsPromptScreenViewModel: AnalyticsPromptScreenViewModelType, AnalyticsPromptScreenViewModelProtocol {
|
||||||
var callback: (@MainActor (AnalyticsPromptScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<AnalyticsPromptScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<AnalyticsPromptScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialize a view model with the specified prompt type and app display name.
|
/// Initialize a view model with the specified prompt type and app display name.
|
||||||
init(termsURL: URL) {
|
init(termsURL: URL) {
|
||||||
@ -33,9 +37,9 @@ class AnalyticsPromptScreenViewModel: AnalyticsPromptScreenViewModelType, Analyt
|
|||||||
override func process(viewAction: AnalyticsPromptScreenViewAction) {
|
override func process(viewAction: AnalyticsPromptScreenViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .enable:
|
case .enable:
|
||||||
callback?(.enable)
|
actionsSubject.send(.enable)
|
||||||
case .disable:
|
case .disable:
|
||||||
callback?(.disable)
|
actionsSubject.send(.disable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol AnalyticsPromptScreenViewModelProtocol {
|
protocol AnalyticsPromptScreenViewModelProtocol {
|
||||||
var callback: (@MainActor (AnalyticsPromptScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<AnalyticsPromptScreenViewModelAction, Never> { get }
|
||||||
var context: AnalyticsPromptScreenViewModelType.Context { get }
|
var context: AnalyticsPromptScreenViewModelType.Context { get }
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
|||||||
private let analytics: AnalyticsService
|
private let analytics: AnalyticsService
|
||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
|
|
||||||
private var cancellables: Set<AnyCancellable> = []
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
weak var delegate: AuthenticationCoordinatorDelegate?
|
weak var delegate: AuthenticationCoordinatorDelegate?
|
||||||
|
|
||||||
@ -57,15 +57,18 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
|||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func showOnboarding() {
|
private func showOnboarding() {
|
||||||
let coordinator = OnboardingCoordinator()
|
let coordinator = OnboardingScreenCoordinator()
|
||||||
|
|
||||||
coordinator.callback = { [weak self] action in
|
coordinator.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
switch action {
|
guard let self else { return }
|
||||||
case .login:
|
|
||||||
Task { await self.startAuthentication() }
|
switch action {
|
||||||
|
case .login:
|
||||||
|
Task { await self.startAuthentication() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
}
|
}
|
||||||
@ -92,29 +95,31 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
|||||||
isModallyPresented: isModallyPresented)
|
isModallyPresented: isModallyPresented)
|
||||||
let coordinator = ServerSelectionScreenCoordinator(parameters: parameters)
|
let coordinator = ServerSelectionScreenCoordinator(parameters: parameters)
|
||||||
|
|
||||||
coordinator.callback = { [weak self] action in
|
coordinator.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
switch action {
|
|
||||||
case .updated:
|
switch action {
|
||||||
if isModallyPresented {
|
case .updated:
|
||||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
if isModallyPresented {
|
||||||
} else {
|
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||||
// We are here because the default server failed to respond.
|
|
||||||
if authenticationService.homeserver.value.loginMode == .password {
|
|
||||||
// Add the password login screen directly to the flow, its fine.
|
|
||||||
showLoginScreen()
|
|
||||||
} else {
|
} else {
|
||||||
// OIDC is presented from the confirmation screen so replace the
|
// We are here because the default server failed to respond.
|
||||||
// server selection screen which was inserted to handle the failure.
|
if authenticationService.homeserver.value.loginMode == .password {
|
||||||
navigationStackCoordinator.pop()
|
// Add the password login screen directly to the flow, its fine.
|
||||||
showServerConfirmationScreen()
|
showLoginScreen()
|
||||||
|
} else {
|
||||||
|
// OIDC is presented from the confirmation screen so replace the
|
||||||
|
// server selection screen which was inserted to handle the failure.
|
||||||
|
navigationStackCoordinator.pop()
|
||||||
|
showServerConfirmationScreen()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
case .dismiss:
|
||||||
|
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||||
}
|
}
|
||||||
case .dismiss:
|
|
||||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
if isModallyPresented {
|
if isModallyPresented {
|
||||||
navigationCoordinator.setRootCoordinator(coordinator)
|
navigationCoordinator.setRootCoordinator(coordinator)
|
||||||
@ -178,20 +183,22 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
|||||||
userIndicatorController: userIndicatorController)
|
userIndicatorController: userIndicatorController)
|
||||||
let coordinator = LoginScreenCoordinator(parameters: parameters)
|
let coordinator = LoginScreenCoordinator(parameters: parameters)
|
||||||
|
|
||||||
coordinator.callback = { [weak self] action in
|
coordinator.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case .signedIn(let userSession):
|
case .signedIn(let userSession):
|
||||||
userHasSignedIn(userSession: userSession)
|
userHasSignedIn(userSession: userSession)
|
||||||
case .configuredForOIDC:
|
case .configuredForOIDC:
|
||||||
// Pop back to the confirmation screen for OIDC login to continue.
|
// Pop back to the confirmation screen for OIDC login to continue.
|
||||||
navigationStackCoordinator.pop(animated: false)
|
navigationStackCoordinator.pop(animated: false)
|
||||||
case .isOnWaitlist(let credentials):
|
case .isOnWaitlist(let credentials):
|
||||||
showWaitlistScreen(for: credentials)
|
showWaitlistScreen(for: credentials)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
navigationStackCoordinator.push(coordinator)
|
navigationStackCoordinator.push(coordinator)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,10 +235,18 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
|||||||
completion()
|
completion()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let coordinator = AnalyticsPromptScreenCoordinator(analytics: analytics, termsURL: appSettings.analyticsConfiguration.termsURL)
|
let coordinator = AnalyticsPromptScreenCoordinator(analytics: analytics, termsURL: appSettings.analyticsConfiguration.termsURL)
|
||||||
coordinator.callback = {
|
|
||||||
completion()
|
coordinator.actions
|
||||||
}
|
.sink { action in
|
||||||
|
switch action {
|
||||||
|
case .done:
|
||||||
|
completion()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
navigationStackCoordinator.push(coordinator)
|
navigationStackCoordinator.push(coordinator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,12 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
|
|||||||
|
|
||||||
private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService }
|
private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService }
|
||||||
|
|
||||||
var callback: (@MainActor (LoginScreenCoordinatorAction) -> Void)?
|
private let actionsSubject: PassthroughSubject<LoginScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<LoginScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Setup
|
// MARK: - Setup
|
||||||
|
|
||||||
@ -56,18 +61,20 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
|
|||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
viewModel.callback = { [weak self] action in
|
viewModel.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
switch action {
|
|
||||||
case .parseUsername(let username):
|
switch action {
|
||||||
parseUsername(username)
|
case .parseUsername(let username):
|
||||||
case .forgotPassword:
|
parseUsername(username)
|
||||||
showForgotPasswordScreen()
|
case .forgotPassword:
|
||||||
case .login(let username, let password):
|
showForgotPasswordScreen()
|
||||||
login(username: username, password: password)
|
case .login(let username, let password):
|
||||||
|
login(username: username, password: password)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func stop() {
|
func stop() {
|
||||||
@ -126,7 +133,7 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
|
|||||||
initialDeviceName: UIDevice.current.initialDeviceName,
|
initialDeviceName: UIDevice.current.initialDeviceName,
|
||||||
deviceID: nil) {
|
deviceID: nil) {
|
||||||
case .success(let userSession):
|
case .success(let userSession):
|
||||||
callback?(.signedIn(userSession))
|
actionsSubject.send(.signedIn(userSession))
|
||||||
parameters.analytics.signpost.endLogin()
|
parameters.analytics.signpost.endLogin()
|
||||||
stopLoading()
|
stopLoading()
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
@ -134,11 +141,11 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
|
|||||||
parameters.analytics.signpost.endLogin()
|
parameters.analytics.signpost.endLogin()
|
||||||
switch error {
|
switch error {
|
||||||
case .isOnWaitlist:
|
case .isOnWaitlist:
|
||||||
callback?(.isOnWaitlist(.init(username: username,
|
actionsSubject.send(.isOnWaitlist(.init(username: username,
|
||||||
password: password,
|
password: password,
|
||||||
initialDeviceName: UIDevice.current.initialDeviceName,
|
initialDeviceName: UIDevice.current.initialDeviceName,
|
||||||
deviceID: nil,
|
deviceID: nil,
|
||||||
homeserver: authenticationService.homeserver.value)))
|
homeserver: authenticationService.homeserver.value)))
|
||||||
default:
|
default:
|
||||||
handleError(error)
|
handleError(error)
|
||||||
}
|
}
|
||||||
@ -159,7 +166,7 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
|
|||||||
case .success:
|
case .success:
|
||||||
stopLoading()
|
stopLoading()
|
||||||
if authenticationService.homeserver.value.loginMode == .oidc {
|
if authenticationService.homeserver.value.loginMode == .oidc {
|
||||||
callback?(.configuredForOIDC)
|
actionsSubject.send(.configuredForOIDC)
|
||||||
} else {
|
} else {
|
||||||
updateViewModel()
|
updateViewModel()
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
typealias LoginScreenViewModelType = StateStoreViewModel<LoginScreenViewState, LoginScreenViewAction>
|
typealias LoginScreenViewModelType = StateStoreViewModel<LoginScreenViewState, LoginScreenViewAction>
|
||||||
@ -21,7 +22,11 @@ typealias LoginScreenViewModelType = StateStoreViewModel<LoginScreenViewState, L
|
|||||||
class LoginScreenViewModel: LoginScreenViewModelType, LoginScreenViewModelProtocol {
|
class LoginScreenViewModel: LoginScreenViewModelType, LoginScreenViewModelProtocol {
|
||||||
private let slidingSyncLearnMoreURL: URL
|
private let slidingSyncLearnMoreURL: URL
|
||||||
|
|
||||||
var callback: (@MainActor (LoginScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<LoginScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<LoginScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(homeserver: LoginHomeserver, slidingSyncLearnMoreURL: URL) {
|
init(homeserver: LoginHomeserver, slidingSyncLearnMoreURL: URL) {
|
||||||
self.slidingSyncLearnMoreURL = slidingSyncLearnMoreURL
|
self.slidingSyncLearnMoreURL = slidingSyncLearnMoreURL
|
||||||
@ -34,11 +39,11 @@ class LoginScreenViewModel: LoginScreenViewModelType, LoginScreenViewModelProtoc
|
|||||||
override func process(viewAction: LoginScreenViewAction) {
|
override func process(viewAction: LoginScreenViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .parseUsername:
|
case .parseUsername:
|
||||||
callback?(.parseUsername(state.bindings.username))
|
actionsSubject.send(.parseUsername(state.bindings.username))
|
||||||
case .forgotPassword:
|
case .forgotPassword:
|
||||||
callback?(.forgotPassword)
|
actionsSubject.send(.forgotPassword)
|
||||||
case .next:
|
case .next:
|
||||||
callback?(.login(username: state.bindings.username, password: state.bindings.password))
|
actionsSubject.send(.login(username: state.bindings.username, password: state.bindings.password))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol LoginScreenViewModelProtocol {
|
protocol LoginScreenViewModelProtocol {
|
||||||
var callback: (@MainActor (LoginScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<LoginScreenViewModelAction, Never> { get }
|
||||||
var context: LoginScreenViewModelType.Context { get }
|
var context: LoginScreenViewModelType.Context { get }
|
||||||
|
|
||||||
/// Update the view to reflect that a new homeserver is being loaded.
|
/// Update the view to reflect that a new homeserver is being loaded.
|
||||||
|
@ -31,7 +31,7 @@ final class ServerConfirmationScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: ServerConfirmationScreenCoordinatorParameters
|
private let parameters: ServerConfirmationScreenCoordinatorParameters
|
||||||
private var viewModel: ServerConfirmationScreenViewModelProtocol
|
private var viewModel: ServerConfirmationScreenViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<ServerConfirmationScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<ServerConfirmationScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<ServerConfirmationScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<ServerConfirmationScreenCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct ServerSelectionScreenCoordinatorParameters {
|
struct ServerSelectionScreenCoordinatorParameters {
|
||||||
@ -35,7 +36,12 @@ final class ServerSelectionScreenCoordinator: CoordinatorProtocol {
|
|||||||
private var viewModel: ServerSelectionScreenViewModelProtocol
|
private var viewModel: ServerSelectionScreenViewModelProtocol
|
||||||
private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService }
|
private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService }
|
||||||
|
|
||||||
var callback: (@MainActor (ServerSelectionScreenCoordinatorAction) -> Void)?
|
private let actionsSubject: PassthroughSubject<ServerSelectionScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<ServerSelectionScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(parameters: ServerSelectionScreenCoordinatorParameters) {
|
init(parameters: ServerSelectionScreenCoordinatorParameters) {
|
||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
@ -48,16 +54,18 @@ final class ServerSelectionScreenCoordinator: CoordinatorProtocol {
|
|||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
viewModel.callback = { [weak self] action in
|
viewModel.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
switch action {
|
|
||||||
case .confirm(let homeserverAddress):
|
switch action {
|
||||||
self.useHomeserver(homeserverAddress)
|
case .confirm(let homeserverAddress):
|
||||||
case .dismiss:
|
self.useHomeserver(homeserverAddress)
|
||||||
self.callback?(.dismiss)
|
case .dismiss:
|
||||||
|
actionsSubject.send(.dismiss)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func stop() {
|
func stop() {
|
||||||
@ -88,7 +96,7 @@ final class ServerSelectionScreenCoordinator: CoordinatorProtocol {
|
|||||||
switch await authenticationService.configure(for: homeserverAddress) {
|
switch await authenticationService.configure(for: homeserverAddress) {
|
||||||
case .success:
|
case .success:
|
||||||
MXLog.info("Selected homeserver: \(homeserverAddress)")
|
MXLog.info("Selected homeserver: \(homeserverAddress)")
|
||||||
callback?(.updated)
|
actionsSubject.send(.updated)
|
||||||
stopLoading()
|
stopLoading()
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
MXLog.info("Invalid homeserver: \(homeserverAddress)")
|
MXLog.info("Invalid homeserver: \(homeserverAddress)")
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
typealias ServerSelectionScreenViewModelType = StateStoreViewModel<ServerSelectionScreenViewState, ServerSelectionScreenViewAction>
|
typealias ServerSelectionScreenViewModelType = StateStoreViewModel<ServerSelectionScreenViewState, ServerSelectionScreenViewAction>
|
||||||
@ -21,7 +22,11 @@ typealias ServerSelectionScreenViewModelType = StateStoreViewModel<ServerSelecti
|
|||||||
class ServerSelectionScreenViewModel: ServerSelectionScreenViewModelType, ServerSelectionScreenViewModelProtocol {
|
class ServerSelectionScreenViewModel: ServerSelectionScreenViewModelType, ServerSelectionScreenViewModelProtocol {
|
||||||
private let slidingSyncLearnMoreURL: URL
|
private let slidingSyncLearnMoreURL: URL
|
||||||
|
|
||||||
var callback: (@MainActor (ServerSelectionScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<ServerSelectionScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<ServerSelectionScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(homeserverAddress: String, slidingSyncLearnMoreURL: URL, isModallyPresented: Bool) {
|
init(homeserverAddress: String, slidingSyncLearnMoreURL: URL, isModallyPresented: Bool) {
|
||||||
self.slidingSyncLearnMoreURL = slidingSyncLearnMoreURL
|
self.slidingSyncLearnMoreURL = slidingSyncLearnMoreURL
|
||||||
@ -35,9 +40,9 @@ class ServerSelectionScreenViewModel: ServerSelectionScreenViewModelType, Server
|
|||||||
override func process(viewAction: ServerSelectionScreenViewAction) {
|
override func process(viewAction: ServerSelectionScreenViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .confirm:
|
case .confirm:
|
||||||
callback?(.confirm(homeserverAddress: state.bindings.homeserverAddress))
|
actionsSubject.send(.confirm(homeserverAddress: state.bindings.homeserverAddress))
|
||||||
case .dismiss:
|
case .dismiss:
|
||||||
callback?(.dismiss)
|
actionsSubject.send(.dismiss)
|
||||||
case .clearFooterError:
|
case .clearFooterError:
|
||||||
clearFooterError()
|
clearFooterError()
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol ServerSelectionScreenViewModelProtocol {
|
protocol ServerSelectionScreenViewModelProtocol {
|
||||||
var callback: (@MainActor (ServerSelectionScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<ServerSelectionScreenViewModelAction, Never> { get }
|
||||||
var context: ServerSelectionScreenViewModelType.Context { get }
|
var context: ServerSelectionScreenViewModelType.Context { get }
|
||||||
|
|
||||||
/// Displays an error to the user.
|
/// Displays an error to the user.
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct SoftLogoutScreenCoordinatorParameters {
|
struct SoftLogoutScreenCoordinatorParameters {
|
||||||
@ -43,10 +44,14 @@ enum SoftLogoutScreenCoordinatorResult: CustomStringConvertible {
|
|||||||
final class SoftLogoutScreenCoordinator: CoordinatorProtocol {
|
final class SoftLogoutScreenCoordinator: CoordinatorProtocol {
|
||||||
private let parameters: SoftLogoutScreenCoordinatorParameters
|
private let parameters: SoftLogoutScreenCoordinatorParameters
|
||||||
private var viewModel: SoftLogoutScreenViewModelProtocol
|
private var viewModel: SoftLogoutScreenViewModelProtocol
|
||||||
|
private let actionsSubject: PassthroughSubject<SoftLogoutScreenCoordinatorResult, Never> = .init()
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService }
|
private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService }
|
||||||
|
|
||||||
var callback: (@MainActor (SoftLogoutScreenCoordinatorResult) -> Void)?
|
var actions: AnyPublisher<SoftLogoutScreenCoordinatorResult, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
@MainActor init(parameters: SoftLogoutScreenCoordinatorParameters) {
|
@MainActor init(parameters: SoftLogoutScreenCoordinatorParameters) {
|
||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
@ -60,21 +65,23 @@ final class SoftLogoutScreenCoordinator: CoordinatorProtocol {
|
|||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
viewModel.callback = { [weak self] result in
|
viewModel.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
MXLog.info("[SoftLogoutCoordinator] SoftLogoutViewModel did complete with result: \(result).")
|
guard let self else { return }
|
||||||
|
MXLog.info("[SoftLogoutCoordinator] SoftLogoutViewModel did complete with result: \(action).")
|
||||||
|
|
||||||
switch result {
|
switch action {
|
||||||
case .login(let password):
|
case .login(let password):
|
||||||
self.login(withPassword: password)
|
login(withPassword: password)
|
||||||
case .forgotPassword:
|
case .forgotPassword:
|
||||||
self.showForgotPasswordScreen()
|
showForgotPasswordScreen()
|
||||||
case .clearAllData:
|
case .clearAllData:
|
||||||
self.callback?(.clearAllData)
|
actionsSubject.send(.clearAllData)
|
||||||
case .continueWithOIDC:
|
case .continueWithOIDC:
|
||||||
self.continueWithOIDC(presentationAnchor: viewModel.context.viewState.window)
|
continueWithOIDC(presentationAnchor: viewModel.context.viewState.window)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func stop() {
|
func stop() {
|
||||||
@ -119,7 +126,7 @@ final class SoftLogoutScreenCoordinator: CoordinatorProtocol {
|
|||||||
initialDeviceName: UIDevice.current.initialDeviceName,
|
initialDeviceName: UIDevice.current.initialDeviceName,
|
||||||
deviceID: parameters.credentials.deviceID) {
|
deviceID: parameters.credentials.deviceID) {
|
||||||
case .success(let userSession):
|
case .success(let userSession):
|
||||||
callback?(.signedIn(userSession))
|
actionsSubject.send(.signedIn(userSession))
|
||||||
stopLoading()
|
stopLoading()
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
stopLoading()
|
stopLoading()
|
||||||
@ -146,7 +153,7 @@ final class SoftLogoutScreenCoordinator: CoordinatorProtocol {
|
|||||||
presentationAnchor: presentationAnchor)
|
presentationAnchor: presentationAnchor)
|
||||||
switch await presenter.authenticate(using: oidcData) {
|
switch await presenter.authenticate(using: oidcData) {
|
||||||
case .success(let userSession):
|
case .success(let userSession):
|
||||||
callback?(.signedIn(userSession))
|
actionsSubject.send(.signedIn(userSession))
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
handleError(error)
|
handleError(error)
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,17 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
typealias SoftLogoutScreenViewModelType = StateStoreViewModel<SoftLogoutScreenViewState, SoftLogoutScreenViewAction>
|
typealias SoftLogoutScreenViewModelType = StateStoreViewModel<SoftLogoutScreenViewState, SoftLogoutScreenViewAction>
|
||||||
|
|
||||||
class SoftLogoutScreenViewModel: SoftLogoutScreenViewModelType, SoftLogoutScreenViewModelProtocol {
|
class SoftLogoutScreenViewModel: SoftLogoutScreenViewModelType, SoftLogoutScreenViewModelProtocol {
|
||||||
var callback: (@MainActor (SoftLogoutScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<SoftLogoutScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<SoftLogoutScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(credentials: SoftLogoutScreenCredentials,
|
init(credentials: SoftLogoutScreenCredentials,
|
||||||
homeserver: LoginHomeserver,
|
homeserver: LoginHomeserver,
|
||||||
@ -36,13 +41,13 @@ class SoftLogoutScreenViewModel: SoftLogoutScreenViewModelType, SoftLogoutScreen
|
|||||||
override func process(viewAction: SoftLogoutScreenViewAction) {
|
override func process(viewAction: SoftLogoutScreenViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .login:
|
case .login:
|
||||||
callback?(.login(state.bindings.password))
|
actionsSubject.send(.login(state.bindings.password))
|
||||||
case .forgotPassword:
|
case .forgotPassword:
|
||||||
callback?(.forgotPassword)
|
actionsSubject.send(.forgotPassword)
|
||||||
case .clearAllData:
|
case .clearAllData:
|
||||||
callback?(.clearAllData)
|
actionsSubject.send(.clearAllData)
|
||||||
case .continueWithOIDC:
|
case .continueWithOIDC:
|
||||||
callback?(.continueWithOIDC)
|
actionsSubject.send(.continueWithOIDC)
|
||||||
case .updateWindow(let window):
|
case .updateWindow(let window):
|
||||||
guard state.window != window else { return }
|
guard state.window != window else { return }
|
||||||
Task { state.window = window }
|
Task { state.window = window }
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
protocol SoftLogoutScreenViewModelProtocol {
|
protocol SoftLogoutScreenViewModelProtocol {
|
||||||
var callback: (@MainActor (SoftLogoutScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<SoftLogoutScreenViewModelAction, Never> { get }
|
||||||
var context: SoftLogoutScreenViewModelType.Context { get }
|
var context: SoftLogoutScreenViewModelType.Context { get }
|
||||||
|
|
||||||
/// Display an error to the user.
|
/// Display an error to the user.
|
||||||
|
@ -37,7 +37,7 @@ final class WaitlistScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: WaitlistScreenCoordinatorParameters
|
private let parameters: WaitlistScreenCoordinatorParameters
|
||||||
private var viewModel: WaitlistScreenViewModelProtocol
|
private var viewModel: WaitlistScreenViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<WaitlistScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<WaitlistScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
private var refreshCancellable: AnyCancellable?
|
private var refreshCancellable: AnyCancellable?
|
||||||
|
|
||||||
var actions: AnyPublisher<WaitlistScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<WaitlistScreenCoordinatorAction, Never> {
|
||||||
|
@ -35,7 +35,7 @@ struct BugReportScreenCoordinatorParameters {
|
|||||||
final class BugReportScreenCoordinator: CoordinatorProtocol {
|
final class BugReportScreenCoordinator: CoordinatorProtocol {
|
||||||
private let parameters: BugReportScreenCoordinatorParameters
|
private let parameters: BugReportScreenCoordinatorParameters
|
||||||
private var viewModel: BugReportScreenViewModelProtocol
|
private var viewModel: BugReportScreenViewModelProtocol
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var completion: ((BugReportScreenCoordinatorResult) -> Void)?
|
var completion: ((BugReportScreenCoordinatorResult) -> Void)?
|
||||||
|
|
||||||
@ -54,10 +54,10 @@ final class BugReportScreenCoordinator: CoordinatorProtocol {
|
|||||||
func start() {
|
func start() {
|
||||||
viewModel
|
viewModel
|
||||||
.actions
|
.actions
|
||||||
.sink { [weak self] result in
|
.sink { [weak self] action in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
MXLog.info("BugReportViewModel did complete with result: \(result).")
|
MXLog.info("BugReportViewModel did complete with result: \(action).")
|
||||||
switch result {
|
switch action {
|
||||||
case .cancel:
|
case .cancel:
|
||||||
self.completion?(.cancel)
|
self.completion?(.cancel)
|
||||||
case let .submitStarted(progressPublisher):
|
case let .submitStarted(progressPublisher):
|
||||||
|
@ -28,7 +28,7 @@ final class CreatePollScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: CreatePollScreenCoordinatorParameters
|
private let parameters: CreatePollScreenCoordinatorParameters
|
||||||
private var viewModel: CreatePollScreenViewModelProtocol
|
private var viewModel: CreatePollScreenViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<CreatePollScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<CreatePollScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<CreatePollScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<CreatePollScreenCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
@ -36,7 +36,7 @@ final class CreateRoomCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: CreateRoomCoordinatorParameters
|
private let parameters: CreateRoomCoordinatorParameters
|
||||||
private var viewModel: CreateRoomViewModelProtocol
|
private var viewModel: CreateRoomViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<CreateRoomCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<CreateRoomCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<CreateRoomCoordinatorAction, Never> {
|
var actions: AnyPublisher<CreateRoomCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct EmojiPickerScreenCoordinatorParameters {
|
struct EmojiPickerScreenCoordinatorParameters {
|
||||||
@ -31,7 +32,12 @@ final class EmojiPickerScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: EmojiPickerScreenCoordinatorParameters
|
private let parameters: EmojiPickerScreenCoordinatorParameters
|
||||||
private var viewModel: EmojiPickerScreenViewModelProtocol
|
private var viewModel: EmojiPickerScreenViewModelProtocol
|
||||||
|
|
||||||
var callback: ((EmojiPickerScreenCoordinatorAction) -> Void)?
|
private let actionsSubject: PassthroughSubject<EmojiPickerScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<EmojiPickerScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(parameters: EmojiPickerScreenCoordinatorParameters) {
|
init(parameters: EmojiPickerScreenCoordinatorParameters) {
|
||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
@ -40,16 +46,18 @@ final class EmojiPickerScreenCoordinator: CoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
viewModel.callback = { [weak self] action in
|
viewModel.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
switch action {
|
|
||||||
case let .emojiSelected(emoji: emoji):
|
switch action {
|
||||||
self.callback?(.emojiSelected(emoji: emoji, itemID: self.parameters.itemID))
|
case let .emojiSelected(emoji: emoji):
|
||||||
case .dismiss:
|
actionsSubject.send(.emojiSelected(emoji: emoji, itemID: self.parameters.itemID))
|
||||||
self.callback?(.dismiss)
|
case .dismiss:
|
||||||
|
actionsSubject.send(.dismiss)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toPresentable() -> AnyView {
|
func toPresentable() -> AnyView {
|
||||||
|
@ -14,12 +14,17 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
typealias EmojiPickerScreenViewModelType = StateStoreViewModel<EmojiPickerScreenViewState, EmojiPickerScreenViewAction>
|
typealias EmojiPickerScreenViewModelType = StateStoreViewModel<EmojiPickerScreenViewState, EmojiPickerScreenViewAction>
|
||||||
|
|
||||||
class EmojiPickerScreenViewModel: EmojiPickerScreenViewModelType, EmojiPickerScreenViewModelProtocol {
|
class EmojiPickerScreenViewModel: EmojiPickerScreenViewModelType, EmojiPickerScreenViewModelProtocol {
|
||||||
var callback: ((EmojiPickerScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<EmojiPickerScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<EmojiPickerScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
private let emojiProvider: EmojiProviderProtocol
|
private let emojiProvider: EmojiProviderProtocol
|
||||||
|
|
||||||
@ -40,9 +45,9 @@ class EmojiPickerScreenViewModel: EmojiPickerScreenViewModelType, EmojiPickerScr
|
|||||||
state.categories = convert(emojiCategories: categories)
|
state.categories = convert(emojiCategories: categories)
|
||||||
}
|
}
|
||||||
case let .emojiTapped(emoji: emoji):
|
case let .emojiTapped(emoji: emoji):
|
||||||
callback?(.emojiSelected(emoji: emoji.value))
|
actionsSubject.send(.emojiSelected(emoji: emoji.value))
|
||||||
case .dismiss:
|
case .dismiss:
|
||||||
callback?(.dismiss)
|
actionsSubject.send(.dismiss)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol EmojiPickerScreenViewModelProtocol {
|
protocol EmojiPickerScreenViewModelProtocol {
|
||||||
var callback: ((EmojiPickerScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<EmojiPickerScreenViewModelAction, Never> { get }
|
||||||
var context: EmojiPickerScreenViewModelType.Context { get }
|
var context: EmojiPickerScreenViewModelType.Context { get }
|
||||||
}
|
}
|
||||||
|
@ -41,9 +41,12 @@ final class HomeScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: HomeScreenCoordinatorParameters
|
private let parameters: HomeScreenCoordinatorParameters
|
||||||
private var viewModel: HomeScreenViewModelProtocol
|
private var viewModel: HomeScreenViewModelProtocol
|
||||||
|
|
||||||
|
private let actionsSubject: PassthroughSubject<HomeScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables = Set<AnyCancellable>()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var callback: ((HomeScreenCoordinatorAction) -> Void)?
|
var actions: AnyPublisher<HomeScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(parameters: HomeScreenCoordinatorParameters) {
|
init(parameters: HomeScreenCoordinatorParameters) {
|
||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
@ -55,30 +58,32 @@ final class HomeScreenCoordinator: CoordinatorProtocol {
|
|||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||||
|
|
||||||
viewModel.callback = { [weak self] action in
|
viewModel.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
switch action {
|
|
||||||
case .presentRoom(let roomIdentifier):
|
switch action {
|
||||||
self.callback?(.presentRoom(roomIdentifier: roomIdentifier))
|
case .presentRoom(let roomIdentifier):
|
||||||
case .presentRoomDetails(roomIdentifier: let roomIdentifier):
|
actionsSubject.send(.presentRoom(roomIdentifier: roomIdentifier))
|
||||||
self.callback?(.presentRoomDetails(roomIdentifier: roomIdentifier))
|
case .presentRoomDetails(roomIdentifier: let roomIdentifier):
|
||||||
case .roomLeft(roomIdentifier: let roomIdentifier):
|
actionsSubject.send(.presentRoomDetails(roomIdentifier: roomIdentifier))
|
||||||
self.callback?(.roomLeft(roomIdentifier: roomIdentifier))
|
case .roomLeft(roomIdentifier: let roomIdentifier):
|
||||||
case .presentFeedbackScreen:
|
actionsSubject.send(.roomLeft(roomIdentifier: roomIdentifier))
|
||||||
self.callback?(.presentFeedbackScreen)
|
case .presentFeedbackScreen:
|
||||||
case .presentSettingsScreen:
|
actionsSubject.send(.presentFeedbackScreen)
|
||||||
self.callback?(.presentSettingsScreen)
|
case .presentSettingsScreen:
|
||||||
case .presentSessionVerificationScreen:
|
actionsSubject.send(.presentSettingsScreen)
|
||||||
self.callback?(.presentSessionVerificationScreen)
|
case .presentSessionVerificationScreen:
|
||||||
case .signOut:
|
actionsSubject.send(.presentSessionVerificationScreen)
|
||||||
self.callback?(.signOut)
|
case .signOut:
|
||||||
case .presentStartChatScreen:
|
actionsSubject.send(.signOut)
|
||||||
self.callback?(.presentStartChatScreen)
|
case .presentStartChatScreen:
|
||||||
case .presentInvitesScreen:
|
actionsSubject.send(.presentStartChatScreen)
|
||||||
self.callback?(.presentInvitesScreen)
|
case .presentInvitesScreen:
|
||||||
|
actionsSubject.send(.presentInvitesScreen)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
@ -32,7 +32,11 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
private var visibleItemRangeObservationToken: AnyCancellable?
|
private var visibleItemRangeObservationToken: AnyCancellable?
|
||||||
private let visibleItemRangePublisher = CurrentValueSubject<(range: Range<Int>, isScrolling: Bool), Never>((0..<0, false))
|
private let visibleItemRangePublisher = CurrentValueSubject<(range: Range<Int>, isScrolling: Bool), Never>((0..<0, false))
|
||||||
|
|
||||||
var callback: ((HomeScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<HomeScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<HomeScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(userSession: UserSessionProtocol,
|
init(userSession: UserSessionProtocol,
|
||||||
attributedStringBuilder: AttributedStringBuilderProtocol,
|
attributedStringBuilder: AttributedStringBuilderProtocol,
|
||||||
@ -92,9 +96,9 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
override func process(viewAction: HomeScreenViewAction) {
|
override func process(viewAction: HomeScreenViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .selectRoom(let roomIdentifier):
|
case .selectRoom(let roomIdentifier):
|
||||||
callback?(.presentRoom(roomIdentifier: roomIdentifier))
|
actionsSubject.send(.presentRoom(roomIdentifier: roomIdentifier))
|
||||||
case .showRoomDetails(roomIdentifier: let roomIdentifier):
|
case .showRoomDetails(roomIdentifier: let roomIdentifier):
|
||||||
callback?(.presentRoomDetails(roomIdentifier: roomIdentifier))
|
actionsSubject.send(.presentRoomDetails(roomIdentifier: roomIdentifier))
|
||||||
case .leaveRoom(roomIdentifier: let roomIdentifier):
|
case .leaveRoom(roomIdentifier: let roomIdentifier):
|
||||||
startLeaveRoomProcess(roomId: roomIdentifier)
|
startLeaveRoomProcess(roomId: roomIdentifier)
|
||||||
case .confirmLeaveRoom(roomIdentifier: let roomIdentifier):
|
case .confirmLeaveRoom(roomIdentifier: let roomIdentifier):
|
||||||
@ -102,22 +106,22 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
case .userMenu(let action):
|
case .userMenu(let action):
|
||||||
switch action {
|
switch action {
|
||||||
case .feedback:
|
case .feedback:
|
||||||
callback?(.presentFeedbackScreen)
|
actionsSubject.send(.presentFeedbackScreen)
|
||||||
case .settings:
|
case .settings:
|
||||||
callback?(.presentSettingsScreen)
|
actionsSubject.send(.presentSettingsScreen)
|
||||||
case .signOut:
|
case .signOut:
|
||||||
callback?(.signOut)
|
actionsSubject.send(.signOut)
|
||||||
}
|
}
|
||||||
case .verifySession:
|
case .verifySession:
|
||||||
callback?(.presentSessionVerificationScreen)
|
actionsSubject.send(.presentSessionVerificationScreen)
|
||||||
case .skipSessionVerification:
|
case .skipSessionVerification:
|
||||||
state.showSessionVerificationBanner = false
|
state.showSessionVerificationBanner = false
|
||||||
case .updateVisibleItemRange(let range, let isScrolling):
|
case .updateVisibleItemRange(let range, let isScrolling):
|
||||||
visibleItemRangePublisher.send((range, isScrolling))
|
visibleItemRangePublisher.send((range, isScrolling))
|
||||||
case .startChat:
|
case .startChat:
|
||||||
callback?(.presentStartChatScreen)
|
actionsSubject.send(.presentStartChatScreen)
|
||||||
case .selectInvites:
|
case .selectInvites:
|
||||||
callback?(.presentInvitesScreen)
|
actionsSubject.send(.presentInvitesScreen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +130,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
title: L10n.crashDetectionDialogContent(InfoPlistReader.main.bundleDisplayName),
|
title: L10n.crashDetectionDialogContent(InfoPlistReader.main.bundleDisplayName),
|
||||||
primaryButton: .init(title: L10n.actionNo, action: nil),
|
primaryButton: .init(title: L10n.actionNo, action: nil),
|
||||||
secondaryButton: .init(title: L10n.actionYes) { [weak self] in
|
secondaryButton: .init(title: L10n.actionYes) { [weak self] in
|
||||||
self?.callback?(.presentFeedbackScreen)
|
self?.actionsSubject.send(.presentFeedbackScreen)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +339,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
type: .modal(progress: .none, interactiveDismissDisabled: false, allowsInteraction: false),
|
type: .modal(progress: .none, interactiveDismissDisabled: false, allowsInteraction: false),
|
||||||
title: L10n.commonCurrentUserLeftRoom,
|
title: L10n.commonCurrentUserLeftRoom,
|
||||||
iconName: "checkmark"))
|
iconName: "checkmark"))
|
||||||
callback?(.roomLeft(roomIdentifier: roomId))
|
actionsSubject.send(.roomLeft(roomIdentifier: roomId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,11 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
import UIKit
|
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol HomeScreenViewModelProtocol {
|
protocol HomeScreenViewModelProtocol {
|
||||||
var callback: ((HomeScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<HomeScreenViewModelAction, Never> { get }
|
||||||
|
|
||||||
var context: HomeScreenViewModelType.Context { get }
|
var context: HomeScreenViewModelType.Context { get }
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ final class InviteUsersScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: InviteUsersScreenCoordinatorParameters
|
private let parameters: InviteUsersScreenCoordinatorParameters
|
||||||
private let viewModel: InviteUsersScreenViewModelProtocol
|
private let viewModel: InviteUsersScreenViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<InviteUsersScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<InviteUsersScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<InviteUsersScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<InviteUsersScreenCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
@ -29,7 +29,7 @@ final class InvitesScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: InvitesScreenCoordinatorParameters
|
private let parameters: InvitesScreenCoordinatorParameters
|
||||||
private var viewModel: InvitesScreenViewModelProtocol
|
private var viewModel: InvitesScreenViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<InvitesScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<InvitesScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<InvitesScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<InvitesScreenCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
@ -31,7 +31,7 @@ final class StaticLocationScreenCoordinator: CoordinatorProtocol {
|
|||||||
let viewModel: StaticLocationScreenViewModelProtocol
|
let viewModel: StaticLocationScreenViewModelProtocol
|
||||||
|
|
||||||
private let actionsSubject: PassthroughSubject<StaticLocationScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<StaticLocationScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<StaticLocationScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<StaticLocationScreenCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct MediaUploadPreviewScreenCoordinatorParameters {
|
struct MediaUploadPreviewScreenCoordinatorParameters {
|
||||||
@ -30,11 +31,14 @@ enum MediaUploadPreviewScreenCoordinatorAction {
|
|||||||
|
|
||||||
final class MediaUploadPreviewScreenCoordinator: CoordinatorProtocol {
|
final class MediaUploadPreviewScreenCoordinator: CoordinatorProtocol {
|
||||||
private var viewModel: MediaUploadPreviewScreenViewModelProtocol
|
private var viewModel: MediaUploadPreviewScreenViewModelProtocol
|
||||||
private let callback: (MediaUploadPreviewScreenCoordinatorAction) -> Void
|
private let actionsSubject: PassthroughSubject<MediaUploadPreviewScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
init(parameters: MediaUploadPreviewScreenCoordinatorParameters, callback: @escaping (MediaUploadPreviewScreenCoordinatorAction) -> Void) {
|
var actions: AnyPublisher<MediaUploadPreviewScreenCoordinatorAction, Never> {
|
||||||
self.callback = callback
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
init(parameters: MediaUploadPreviewScreenCoordinatorParameters) {
|
||||||
viewModel = MediaUploadPreviewScreenViewModel(userIndicatorController: parameters.userIndicatorController,
|
viewModel = MediaUploadPreviewScreenViewModel(userIndicatorController: parameters.userIndicatorController,
|
||||||
roomProxy: parameters.roomProxy,
|
roomProxy: parameters.roomProxy,
|
||||||
mediaUploadingPreprocessor: parameters.mediaUploadingPreprocessor,
|
mediaUploadingPreprocessor: parameters.mediaUploadingPreprocessor,
|
||||||
@ -43,14 +47,18 @@ final class MediaUploadPreviewScreenCoordinator: CoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
viewModel.callback = { [weak self] action in
|
viewModel.actions
|
||||||
switch action {
|
.sink { [weak self] action in
|
||||||
case .dismiss:
|
guard let self else { return }
|
||||||
self?.callback(.dismiss)
|
|
||||||
|
switch action {
|
||||||
|
case .dismiss:
|
||||||
|
actionsSubject.send(.dismiss)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toPresentable() -> AnyView {
|
func toPresentable() -> AnyView {
|
||||||
AnyView(MediaUploadPreviewScreen(context: viewModel.context))
|
AnyView(MediaUploadPreviewScreen(context: viewModel.context))
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,11 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var callback: ((MediaUploadPreviewScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<MediaUploadPreviewScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<MediaUploadPreviewScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(userIndicatorController: UserIndicatorControllerProtocol?,
|
init(userIndicatorController: UserIndicatorControllerProtocol?,
|
||||||
roomProxy: RoomProxyProtocol,
|
roomProxy: RoomProxyProtocol,
|
||||||
@ -58,7 +62,7 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
|
|||||||
case .success(let mediaInfo):
|
case .success(let mediaInfo):
|
||||||
switch await sendAttachment(mediaInfo: mediaInfo, progressSubject: progressSubject) {
|
switch await sendAttachment(mediaInfo: mediaInfo, progressSubject: progressSubject) {
|
||||||
case .success:
|
case .success:
|
||||||
callback?(.dismiss)
|
actionsSubject.send(.dismiss)
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
MXLog.error("Failed sending attachment with error: \(error)")
|
MXLog.error("Failed sending attachment with error: \(error)")
|
||||||
showError(label: L10n.screenMediaUploadPreviewErrorFailedSending)
|
showError(label: L10n.screenMediaUploadPreviewErrorFailedSending)
|
||||||
@ -74,7 +78,7 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
|
|||||||
|
|
||||||
case .cancel:
|
case .cancel:
|
||||||
requestHandle?.cancel()
|
requestHandle?.cancel()
|
||||||
callback?(.dismiss)
|
actionsSubject.send(.dismiss)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol MediaUploadPreviewScreenViewModelProtocol {
|
protocol MediaUploadPreviewScreenViewModelProtocol {
|
||||||
var callback: ((MediaUploadPreviewScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<MediaUploadPreviewScreenViewModelAction, Never> { get }
|
||||||
var context: MediaUploadPreviewScreenViewModelType.Context { get }
|
var context: MediaUploadPreviewScreenViewModelType.Context { get }
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ final class MessageForwardingScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: MessageForwardingScreenCoordinatorParameters
|
private let parameters: MessageForwardingScreenCoordinatorParameters
|
||||||
private var viewModel: MessageForwardingScreenViewModelProtocol
|
private var viewModel: MessageForwardingScreenViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<MessageForwardingScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<MessageForwardingScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<MessageForwardingScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<MessageForwardingScreenCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
@ -19,7 +19,7 @@ import SwiftUI
|
|||||||
|
|
||||||
final class MigrationScreenCoordinator: CoordinatorProtocol {
|
final class MigrationScreenCoordinator: CoordinatorProtocol {
|
||||||
private var viewModel: MigrationScreenViewModelProtocol
|
private var viewModel: MigrationScreenViewModelProtocol
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
viewModel = MigrationScreenViewModel()
|
viewModel = MigrationScreenViewModel()
|
||||||
|
@ -14,28 +14,35 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
final class OnboardingCoordinator: CoordinatorProtocol {
|
final class OnboardingScreenCoordinator: CoordinatorProtocol {
|
||||||
private var viewModel: OnboardingViewModelProtocol
|
private var viewModel: OnboardingScreenViewModelProtocol
|
||||||
|
private let actionsSubject: PassthroughSubject<OnboardingScreenCoordinatorAction, Never> = .init()
|
||||||
var callback: ((OnboardingCoordinatorAction) -> Void)?
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<OnboardingScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
viewModel = OnboardingViewModel()
|
viewModel = OnboardingScreenViewModel()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
viewModel.callback = { [weak self] action in
|
viewModel.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
switch action {
|
|
||||||
case .login:
|
switch action {
|
||||||
self.callback?(.login)
|
case .login:
|
||||||
|
actionsSubject.send(.login)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toPresentable() -> AnyView {
|
func toPresentable() -> AnyView {
|
@ -18,23 +18,23 @@ import SwiftUI
|
|||||||
|
|
||||||
// MARK: - Coordinator
|
// MARK: - Coordinator
|
||||||
|
|
||||||
enum OnboardingCoordinatorAction {
|
enum OnboardingScreenCoordinatorAction {
|
||||||
case login
|
case login
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The content displayed in a single screen page.
|
/// The content displayed in a single screen page.
|
||||||
struct OnboardingPageContent {
|
struct OnboardingScreenPageContent {
|
||||||
let title: AttributedString
|
let title: AttributedString
|
||||||
let message: String
|
let message: String
|
||||||
let image: ImageAsset
|
let image: ImageAsset
|
||||||
}
|
}
|
||||||
|
|
||||||
enum OnboardingViewModelAction {
|
enum OnboardingScreenViewModelAction {
|
||||||
case login
|
case login
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OnboardingViewState: BindableState { }
|
struct OnboardingScreenViewState: BindableState { }
|
||||||
|
|
||||||
enum OnboardingViewAction {
|
enum OnboardingScreenViewAction {
|
||||||
case login
|
case login
|
||||||
}
|
}
|
@ -17,19 +17,23 @@
|
|||||||
import Combine
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
typealias OnboardingViewModelType = StateStoreViewModel<OnboardingViewState, OnboardingViewAction>
|
typealias OnboardingScreenViewModelType = StateStoreViewModel<OnboardingScreenViewState, OnboardingScreenViewAction>
|
||||||
|
|
||||||
class OnboardingViewModel: OnboardingViewModelType, OnboardingViewModelProtocol {
|
class OnboardingScreenViewModel: OnboardingScreenViewModelType, OnboardingScreenViewModelProtocol {
|
||||||
var callback: ((OnboardingViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<OnboardingScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
init() {
|
var actions: AnyPublisher<OnboardingScreenViewModelAction, Never> {
|
||||||
super.init(initialViewState: OnboardingViewState())
|
actionsSubject.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func process(viewAction: OnboardingViewAction) {
|
init() {
|
||||||
|
super.init(initialViewState: OnboardingScreenViewState())
|
||||||
|
}
|
||||||
|
|
||||||
|
override func process(viewAction: OnboardingScreenViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .login:
|
case .login:
|
||||||
callback?(.login)
|
actionsSubject.send(.login)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,10 +14,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol OnboardingViewModelProtocol {
|
protocol OnboardingScreenViewModelProtocol {
|
||||||
var callback: ((OnboardingViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<OnboardingScreenViewModelAction, Never> { get }
|
||||||
var context: OnboardingViewModelType.Context { get }
|
var context: OnboardingScreenViewModelType.Context { get }
|
||||||
}
|
}
|
@ -21,7 +21,7 @@ import SwiftUI
|
|||||||
struct OnboardingScreen: View {
|
struct OnboardingScreen: View {
|
||||||
@Environment(\.verticalSizeClass) private var verticalSizeClass
|
@Environment(\.verticalSizeClass) private var verticalSizeClass
|
||||||
|
|
||||||
@ObservedObject var context: OnboardingViewModel.Context
|
@ObservedObject var context: OnboardingScreenViewModel.Context
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
GeometryReader { geometry in
|
GeometryReader { geometry in
|
||||||
@ -45,7 +45,7 @@ struct OnboardingScreen: View {
|
|||||||
}
|
}
|
||||||
.navigationBarHidden(true)
|
.navigationBarHidden(true)
|
||||||
.background {
|
.background {
|
||||||
OnboardingBackgroundImage()
|
OnboardingScreenBackgroundImage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ struct OnboardingScreen: View {
|
|||||||
// MARK: - Previews
|
// MARK: - Previews
|
||||||
|
|
||||||
struct OnboardingScreen_Previews: PreviewProvider {
|
struct OnboardingScreen_Previews: PreviewProvider {
|
||||||
static let viewModel = OnboardingViewModel()
|
static let viewModel = OnboardingScreenViewModel()
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
OnboardingScreen(context: viewModel.context)
|
OnboardingScreen(context: viewModel.context)
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
/// The background gradient shown on the launch, splash and onboarding screens.
|
/// The background gradient shown on the launch, splash and onboarding screens.
|
||||||
struct OnboardingBackgroundImage: View {
|
struct OnboardingScreenBackgroundImage: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Image(asset: Asset.Images.launchBackground)
|
Image(asset: Asset.Images.launchBackground)
|
||||||
.resizable()
|
.resizable()
|
@ -32,9 +32,12 @@ enum ReportContentScreenCoordinatorAction {
|
|||||||
final class ReportContentScreenCoordinator: CoordinatorProtocol {
|
final class ReportContentScreenCoordinator: CoordinatorProtocol {
|
||||||
private let parameters: ReportContentScreenCoordinatorParameters
|
private let parameters: ReportContentScreenCoordinatorParameters
|
||||||
private var viewModel: ReportContentScreenViewModelProtocol
|
private var viewModel: ReportContentScreenViewModelProtocol
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private let actionsSubject: PassthroughSubject<ReportContentScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var callback: ((ReportContentScreenCoordinatorAction) -> Void)?
|
var actions: AnyPublisher<ReportContentScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(parameters: ReportContentScreenCoordinatorParameters) {
|
init(parameters: ReportContentScreenCoordinatorParameters) {
|
||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
@ -48,17 +51,18 @@ final class ReportContentScreenCoordinator: CoordinatorProtocol {
|
|||||||
viewModel.actions
|
viewModel.actions
|
||||||
.sink { [weak self] action in
|
.sink { [weak self] action in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case .submitStarted:
|
case .submitStarted:
|
||||||
self.startLoading()
|
startLoading()
|
||||||
case let .submitFailed(error):
|
case let .submitFailed(error):
|
||||||
self.stopLoading()
|
stopLoading()
|
||||||
self.showError(description: error.localizedDescription)
|
showError(description: error.localizedDescription)
|
||||||
case .submitFinished:
|
case .submitFinished:
|
||||||
self.stopLoading()
|
stopLoading()
|
||||||
self.callback?(.finish)
|
actionsSubject.send(.finish)
|
||||||
case .cancel:
|
case .cancel:
|
||||||
self.callback?(.cancel)
|
actionsSubject.send(.cancel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
@ -33,7 +33,7 @@ final class RoomDetailsEditScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: RoomDetailsEditScreenCoordinatorParameters
|
private let parameters: RoomDetailsEditScreenCoordinatorParameters
|
||||||
private var viewModel: RoomDetailsEditScreenViewModelProtocol
|
private var viewModel: RoomDetailsEditScreenViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<RoomDetailsEditScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<RoomDetailsEditScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<RoomDetailsEditScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<RoomDetailsEditScreenCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
@ -41,7 +41,7 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private let actionsSubject: PassthroughSubject<RoomDetailsScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<RoomDetailsScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<RoomDetailsScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<RoomDetailsScreenCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
@ -60,22 +60,24 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
|||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
viewModel.callback = { [weak self] action in
|
viewModel.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
switch action {
|
|
||||||
case .requestMemberDetailsPresentation:
|
switch action {
|
||||||
self.presentRoomMembersList()
|
case .requestMemberDetailsPresentation:
|
||||||
case .requestInvitePeoplePresentation:
|
presentRoomMembersList()
|
||||||
self.presentInviteUsersScreen()
|
case .requestInvitePeoplePresentation:
|
||||||
case .leftRoom:
|
presentInviteUsersScreen()
|
||||||
self.actionsSubject.send(.leftRoom)
|
case .leftRoom:
|
||||||
case .requestEditDetailsPresentation(let accountOwner):
|
actionsSubject.send(.leftRoom)
|
||||||
self.presentRoomDetailsEditScreen(accountOwner: accountOwner)
|
case .requestEditDetailsPresentation(let accountOwner):
|
||||||
case .requestNotificationSettingsPresentation:
|
presentRoomDetailsEditScreen(accountOwner: accountOwner)
|
||||||
self.presentNotificationSettings()
|
case .requestNotificationSettingsPresentation:
|
||||||
|
presentNotificationSettings()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func stop() {
|
func stop() {
|
||||||
@ -94,12 +96,16 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
|||||||
roomProxy: parameters.roomProxy)
|
roomProxy: parameters.roomProxy)
|
||||||
let coordinator = RoomMembersListScreenCoordinator(parameters: params)
|
let coordinator = RoomMembersListScreenCoordinator(parameters: params)
|
||||||
|
|
||||||
coordinator.callback = { [weak self] action in
|
coordinator.actions
|
||||||
switch action {
|
.sink { [weak self] action in
|
||||||
case .invite:
|
guard let self else { return }
|
||||||
self?.presentInviteUsersScreen()
|
|
||||||
|
switch action {
|
||||||
|
case .invite:
|
||||||
|
presentInviteUsersScreen()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
navigationStackCoordinator?.push(coordinator)
|
navigationStackCoordinator?.push(coordinator)
|
||||||
}
|
}
|
||||||
@ -115,10 +121,10 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
|||||||
let coordinator = InviteUsersScreenCoordinator(parameters: inviteParameters)
|
let coordinator = InviteUsersScreenCoordinator(parameters: inviteParameters)
|
||||||
inviteUsersStackCoordinator.setRootCoordinator(coordinator)
|
inviteUsersStackCoordinator.setRootCoordinator(coordinator)
|
||||||
|
|
||||||
coordinator.actions.sink { [weak self] result in
|
coordinator.actions.sink { [weak self] action in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
switch result {
|
switch action {
|
||||||
case .cancel:
|
case .cancel:
|
||||||
navigationStackCoordinator?.setSheetCoordinator(nil)
|
navigationStackCoordinator?.setSheetCoordinator(nil)
|
||||||
case .proceed:
|
case .proceed:
|
||||||
|
@ -32,7 +32,11 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
|
|
||||||
private var dmRecipient: RoomMemberProxyProtocol?
|
private var dmRecipient: RoomMemberProxyProtocol?
|
||||||
|
|
||||||
var callback: ((RoomDetailsScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<RoomDetailsScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<RoomDetailsScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(accountUserID: String,
|
init(accountUserID: String,
|
||||||
roomProxy: RoomProxyProtocol,
|
roomProxy: RoomProxyProtocol,
|
||||||
@ -75,9 +79,9 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
override func process(viewAction: RoomDetailsScreenViewAction) {
|
override func process(viewAction: RoomDetailsScreenViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .processTapPeople:
|
case .processTapPeople:
|
||||||
callback?(.requestMemberDetailsPresentation)
|
actionsSubject.send(.requestMemberDetailsPresentation)
|
||||||
case .processTapInvite:
|
case .processTapInvite:
|
||||||
callback?(.requestInvitePeoplePresentation)
|
actionsSubject.send(.requestInvitePeoplePresentation)
|
||||||
case .processTapLeave:
|
case .processTapLeave:
|
||||||
guard state.joinedMembersCount > 1 else {
|
guard state.joinedMembersCount > 1 else {
|
||||||
state.bindings.leaveRoomAlertItem = LeaveRoomAlertItem(roomId: roomProxy.id, state: .empty)
|
state.bindings.leaveRoomAlertItem = LeaveRoomAlertItem(roomId: roomProxy.id, state: .empty)
|
||||||
@ -95,7 +99,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
MXLog.error("Missing account owner when presenting the room's edit details screen")
|
MXLog.error("Missing account owner when presenting the room's edit details screen")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
callback?(.requestEditDetailsPresentation(accountOwner))
|
actionsSubject.send(.requestEditDetailsPresentation(accountOwner))
|
||||||
case .ignoreConfirmed:
|
case .ignoreConfirmed:
|
||||||
Task { await ignore() }
|
Task { await ignore() }
|
||||||
case .unignoreConfirmed:
|
case .unignoreConfirmed:
|
||||||
@ -104,7 +108,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
if state.notificationSettingsState.isError {
|
if state.notificationSettingsState.isError {
|
||||||
fetchNotificationSettings()
|
fetchNotificationSettings()
|
||||||
} else {
|
} else {
|
||||||
callback?(.requestNotificationSettingsPresentation)
|
actionsSubject.send(.requestNotificationSettingsPresentation)
|
||||||
}
|
}
|
||||||
case .processToogleMuteNotifications:
|
case .processToogleMuteNotifications:
|
||||||
Task { await toggleMuteNotifications() }
|
Task { await toggleMuteNotifications() }
|
||||||
@ -239,7 +243,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
case .failure:
|
case .failure:
|
||||||
state.bindings.alertInfo = AlertInfo(id: .unknown)
|
state.bindings.alertInfo = AlertInfo(id: .unknown)
|
||||||
case .success:
|
case .success:
|
||||||
callback?(.leftRoom)
|
actionsSubject.send(.leftRoom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol RoomDetailsScreenViewModelProtocol {
|
protocol RoomDetailsScreenViewModelProtocol {
|
||||||
var callback: ((RoomDetailsScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<RoomDetailsScreenViewModelAction, Never> { get }
|
||||||
var context: RoomDetailsScreenViewModelType.Context { get }
|
var context: RoomDetailsScreenViewModelType.Context { get }
|
||||||
func stop()
|
func stop()
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct RoomMemberDetailsScreenCoordinatorParameters {
|
struct RoomMemberDetailsScreenCoordinatorParameters {
|
||||||
@ -29,7 +30,12 @@ final class RoomMemberDetailsScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: RoomMemberDetailsScreenCoordinatorParameters
|
private let parameters: RoomMemberDetailsScreenCoordinatorParameters
|
||||||
private var viewModel: RoomMemberDetailsScreenViewModelProtocol
|
private var viewModel: RoomMemberDetailsScreenViewModelProtocol
|
||||||
|
|
||||||
var callback: ((RoomMemberDetailsScreenCoordinatorAction) -> Void)?
|
private let actionsSubject: PassthroughSubject<RoomMemberDetailsScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<RoomMemberDetailsScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(parameters: RoomMemberDetailsScreenCoordinatorParameters) {
|
init(parameters: RoomMemberDetailsScreenCoordinatorParameters) {
|
||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
typealias RoomMemberDetailsScreenViewModelType = StateStoreViewModel<RoomMemberDetailsScreenViewState, RoomMemberDetailsScreenViewAction>
|
typealias RoomMemberDetailsScreenViewModelType = StateStoreViewModel<RoomMemberDetailsScreenViewState, RoomMemberDetailsScreenViewAction>
|
||||||
@ -24,7 +25,11 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro
|
|||||||
private let mediaProvider: MediaProviderProtocol
|
private let mediaProvider: MediaProviderProtocol
|
||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
|
|
||||||
var callback: ((RoomMemberDetailsScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<RoomMemberDetailsScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<RoomMemberDetailsScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(roomProxy: RoomProxyProtocol,
|
init(roomProxy: RoomProxyProtocol,
|
||||||
roomMemberProxy: RoomMemberProxyProtocol,
|
roomMemberProxy: RoomMemberProxyProtocol,
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol RoomMemberDetailsScreenViewModelProtocol {
|
protocol RoomMemberDetailsScreenViewModelProtocol {
|
||||||
var callback: ((RoomMemberDetailsScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<RoomMemberDetailsScreenViewModelAction, Never> { get }
|
||||||
var context: RoomMemberDetailsScreenViewModelType.Context { get }
|
var context: RoomMemberDetailsScreenViewModelType.Context { get }
|
||||||
func stop()
|
func stop()
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct RoomMembersListScreenCoordinatorParameters {
|
struct RoomMembersListScreenCoordinatorParameters {
|
||||||
@ -33,7 +34,12 @@ final class RoomMembersListScreenCoordinator: CoordinatorProtocol {
|
|||||||
parameters.navigationStackCoordinator
|
parameters.navigationStackCoordinator
|
||||||
}
|
}
|
||||||
|
|
||||||
var callback: ((RoomMembersListScreenCoordinatorAction) -> Void)?
|
private let actionsSubject: PassthroughSubject<RoomMembersListScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<RoomMembersListScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(parameters: RoomMembersListScreenCoordinatorParameters) {
|
init(parameters: RoomMembersListScreenCoordinatorParameters) {
|
||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
@ -44,16 +50,18 @@ final class RoomMembersListScreenCoordinator: CoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
viewModel.callback = { [weak self] action in
|
viewModel.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
switch action {
|
|
||||||
case let .selectMember(member):
|
switch action {
|
||||||
self.selectMember(member)
|
case let .selectMember(member):
|
||||||
case .invite:
|
selectMember(member)
|
||||||
callback?(.invite)
|
case .invite:
|
||||||
|
actionsSubject.send(.invite)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toPresentable() -> AnyView {
|
func toPresentable() -> AnyView {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
typealias RoomMembersListScreenViewModelType = StateStoreViewModel<RoomMembersListScreenViewState, RoomMembersListScreenViewAction>
|
typealias RoomMembersListScreenViewModelType = StateStoreViewModel<RoomMembersListScreenViewState, RoomMembersListScreenViewAction>
|
||||||
@ -24,7 +25,11 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe
|
|||||||
|
|
||||||
private var members: [RoomMemberProxyProtocol] = []
|
private var members: [RoomMemberProxyProtocol] = []
|
||||||
|
|
||||||
var callback: ((RoomMembersListScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<RoomMembersListScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<RoomMembersListScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(roomProxy: RoomProxyProtocol,
|
init(roomProxy: RoomProxyProtocol,
|
||||||
mediaProvider: MediaProviderProtocol,
|
mediaProvider: MediaProviderProtocol,
|
||||||
@ -47,9 +52,9 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe
|
|||||||
MXLog.error("Selected member \(id) not found")
|
MXLog.error("Selected member \(id) not found")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
callback?(.selectMember(member))
|
actionsSubject.send(.selectMember(member))
|
||||||
case .invite:
|
case .invite:
|
||||||
callback?(.invite)
|
actionsSubject.send(.invite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol RoomMembersListScreenViewModelProtocol {
|
protocol RoomMembersListScreenViewModelProtocol {
|
||||||
var callback: ((RoomMembersListScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<RoomMembersListScreenViewModelAction, Never> { get }
|
||||||
var context: RoomMembersListScreenViewModelType.Context { get }
|
var context: RoomMembersListScreenViewModelType.Context { get }
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ final class RoomNotificationSettingsScreenCoordinator: CoordinatorProtocol {
|
|||||||
private var viewModel: RoomNotificationSettingsScreenViewModelProtocol
|
private var viewModel: RoomNotificationSettingsScreenViewModelProtocol
|
||||||
|
|
||||||
private let actionsSubject: PassthroughSubject<RoomNotificationSettingsScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<RoomNotificationSettingsScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<RoomNotificationSettingsScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<RoomNotificationSettingsScreenCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
@ -106,10 +106,10 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
|||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
composerViewModel.actions
|
composerViewModel.actions
|
||||||
.sink { [weak self] composerAction in
|
.sink { [weak self] action in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
viewModel.process(composerAction: composerAction)
|
viewModel.process(composerAction: action)
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ class TimelineTableViewController: UIViewController {
|
|||||||
|
|
||||||
/// The table's diffable data source.
|
/// The table's diffable data source.
|
||||||
private var dataSource: UITableViewDiffableDataSource<TimelineSection, String>?
|
private var dataSource: UITableViewDiffableDataSource<TimelineSection, String>?
|
||||||
private var cancellables: Set<AnyCancellable> = []
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
/// A publisher used to throttle back pagination requests.
|
/// A publisher used to throttle back pagination requests.
|
||||||
///
|
///
|
||||||
|
@ -14,8 +14,13 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
enum SessionVerificationScreenCoordinatorAction {
|
||||||
|
case done
|
||||||
|
}
|
||||||
|
|
||||||
struct SessionVerificationScreenCoordinatorParameters {
|
struct SessionVerificationScreenCoordinatorParameters {
|
||||||
let sessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol
|
let sessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol
|
||||||
}
|
}
|
||||||
@ -24,7 +29,12 @@ final class SessionVerificationScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: SessionVerificationScreenCoordinatorParameters
|
private let parameters: SessionVerificationScreenCoordinatorParameters
|
||||||
private var viewModel: SessionVerificationScreenViewModelProtocol
|
private var viewModel: SessionVerificationScreenViewModelProtocol
|
||||||
|
|
||||||
var callback: (() -> Void)?
|
private let actionsSubject: PassthroughSubject<SessionVerificationScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<SessionVerificationScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(parameters: SessionVerificationScreenCoordinatorParameters) {
|
init(parameters: SessionVerificationScreenCoordinatorParameters) {
|
||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
@ -35,14 +45,16 @@ final class SessionVerificationScreenCoordinator: CoordinatorProtocol {
|
|||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
viewModel.callback = { [weak self] action in
|
viewModel.actions
|
||||||
guard let self else { return }
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
switch action {
|
|
||||||
case .finished:
|
switch action {
|
||||||
self.callback?()
|
case .finished:
|
||||||
|
actionsSubject.send(.done)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toPresentable() -> AnyView {
|
func toPresentable() -> AnyView {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
typealias SessionVerificationViewModelType = StateStoreViewModel<SessionVerificationScreenViewState, SessionVerificationScreenViewAction>
|
typealias SessionVerificationViewModelType = StateStoreViewModel<SessionVerificationScreenViewState, SessionVerificationScreenViewAction>
|
||||||
@ -23,7 +24,11 @@ class SessionVerificationScreenViewModel: SessionVerificationViewModelType, Sess
|
|||||||
|
|
||||||
private var stateMachine: SessionVerificationScreenStateMachine
|
private var stateMachine: SessionVerificationScreenStateMachine
|
||||||
|
|
||||||
var callback: ((SessionVerificationScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<SessionVerificationScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<SessionVerificationScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(sessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol,
|
init(sessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol,
|
||||||
initialState: SessionVerificationScreenViewState = SessionVerificationScreenViewState()) {
|
initialState: SessionVerificationScreenViewState = SessionVerificationScreenViewState()) {
|
||||||
@ -79,7 +84,7 @@ class SessionVerificationScreenViewModel: SessionVerificationViewModelType, Sess
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
callback?(.finished)
|
actionsSubject.send(.finished)
|
||||||
case .accept:
|
case .accept:
|
||||||
stateMachine.processEvent(.acceptChallenge)
|
stateMachine.processEvent(.acceptChallenge)
|
||||||
case .decline:
|
case .decline:
|
||||||
@ -93,24 +98,24 @@ class SessionVerificationScreenViewModel: SessionVerificationViewModelType, Sess
|
|||||||
stateMachine.addTransitionHandler { [weak self] context in
|
stateMachine.addTransitionHandler { [weak self] context in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
self.state.verificationState = context.toState
|
state.verificationState = context.toState
|
||||||
|
|
||||||
switch (context.fromState, context.event, context.toState) {
|
switch (context.fromState, context.event, context.toState) {
|
||||||
case (.initial, .requestVerification, .requestingVerification):
|
case (.initial, .requestVerification, .requestingVerification):
|
||||||
self.requestVerification()
|
requestVerification()
|
||||||
case (.verificationRequestAccepted, .startSasVerification, .startingSasVerification):
|
case (.verificationRequestAccepted, .startSasVerification, .startingSasVerification):
|
||||||
self.startSasVerification()
|
startSasVerification()
|
||||||
case (.showingChallenge, .acceptChallenge, .acceptingChallenge):
|
case (.showingChallenge, .acceptChallenge, .acceptingChallenge):
|
||||||
self.acceptChallenge()
|
acceptChallenge()
|
||||||
case (.showingChallenge, .declineChallenge, .decliningChallenge):
|
case (.showingChallenge, .declineChallenge, .decliningChallenge):
|
||||||
self.declineChallenge()
|
declineChallenge()
|
||||||
case (_, .cancel, .cancelling):
|
case (_, .cancel, .cancelling):
|
||||||
self.cancelVerification()
|
cancelVerification()
|
||||||
case (_, _, .verified):
|
case (_, _, .verified):
|
||||||
// Dismiss the success screen automatically.
|
// Dismiss the success screen automatically.
|
||||||
Task {
|
Task {
|
||||||
try? await Task.sleep(for: .seconds(2))
|
try? await Task.sleep(for: .seconds(2))
|
||||||
self.callback?(.finished)
|
self.actionsSubject.send(.finished)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol SessionVerificationScreenViewModelProtocol {
|
protocol SessionVerificationScreenViewModelProtocol {
|
||||||
var callback: ((SessionVerificationScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<SessionVerificationScreenViewModelAction, Never> { get }
|
||||||
var context: SessionVerificationViewModelType.Context { get }
|
var context: SessionVerificationViewModelType.Context { get }
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
enum AdvancedSettingsScreenCoordinatorAction {
|
enum AdvancedSettingsScreenCoordinatorAction {
|
||||||
@ -23,7 +24,12 @@ enum AdvancedSettingsScreenCoordinatorAction {
|
|||||||
final class AdvancedSettingsScreenCoordinator: CoordinatorProtocol {
|
final class AdvancedSettingsScreenCoordinator: CoordinatorProtocol {
|
||||||
private var viewModel: AdvancedSettingsScreenViewModelProtocol
|
private var viewModel: AdvancedSettingsScreenViewModelProtocol
|
||||||
|
|
||||||
var callback: ((AdvancedSettingsScreenCoordinatorAction) -> Void)?
|
private let actionsSubject: PassthroughSubject<AdvancedSettingsScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<AdvancedSettingsScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
viewModel = AdvancedSettingsScreenViewModel(advancedSettings: ServiceLocator.shared.settings)
|
viewModel = AdvancedSettingsScreenViewModel(advancedSettings: ServiceLocator.shared.settings)
|
||||||
|
@ -14,12 +14,17 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
typealias AdvancedSettingsScreenViewModelType = StateStoreViewModel<AdvancedSettingsScreenViewState, AdvancedSettingsScreenViewAction>
|
typealias AdvancedSettingsScreenViewModelType = StateStoreViewModel<AdvancedSettingsScreenViewState, AdvancedSettingsScreenViewAction>
|
||||||
|
|
||||||
class AdvancedSettingsScreenViewModel: AdvancedSettingsScreenViewModelType, AdvancedSettingsScreenViewModelProtocol {
|
class AdvancedSettingsScreenViewModel: AdvancedSettingsScreenViewModelType, AdvancedSettingsScreenViewModelProtocol {
|
||||||
var callback: ((AdvancedSettingsScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<AdvancedSettingsScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<AdvancedSettingsScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(advancedSettings: AdvancedSettingsProtocol) {
|
init(advancedSettings: AdvancedSettingsProtocol) {
|
||||||
let bindings = AdvancedSettingsScreenViewStateBindings(advancedSettings: advancedSettings)
|
let bindings = AdvancedSettingsScreenViewStateBindings(advancedSettings: advancedSettings)
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol AdvancedSettingsScreenViewModelProtocol {
|
protocol AdvancedSettingsScreenViewModelProtocol {
|
||||||
var callback: ((AdvancedSettingsScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<AdvancedSettingsScreenViewModelAction, Never> { get }
|
||||||
var context: AdvancedSettingsScreenViewModelType.Context { get }
|
var context: AdvancedSettingsScreenViewModelType.Context { get }
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
enum DeveloperOptionsScreenCoordinatorAction {
|
enum DeveloperOptionsScreenCoordinatorAction {
|
||||||
@ -23,18 +24,28 @@ enum DeveloperOptionsScreenCoordinatorAction {
|
|||||||
final class DeveloperOptionsScreenCoordinator: CoordinatorProtocol {
|
final class DeveloperOptionsScreenCoordinator: CoordinatorProtocol {
|
||||||
private var viewModel: DeveloperOptionsScreenViewModelProtocol
|
private var viewModel: DeveloperOptionsScreenViewModelProtocol
|
||||||
|
|
||||||
var callback: ((DeveloperOptionsScreenCoordinatorAction) -> Void)?
|
private let actionsSubject: PassthroughSubject<DeveloperOptionsScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<DeveloperOptionsScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings)
|
viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings)
|
||||||
viewModel.callback = { [weak self] action in
|
|
||||||
switch action {
|
viewModel.actions
|
||||||
case .clearCache:
|
.sink { [weak self] action in
|
||||||
self?.callback?(.clearCache)
|
guard let self else { return }
|
||||||
|
|
||||||
|
switch action {
|
||||||
|
case .clearCache:
|
||||||
|
actionsSubject.send(.clearCache)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toPresentable() -> AnyView {
|
func toPresentable() -> AnyView {
|
||||||
AnyView(DeveloperOptionsScreen(context: viewModel.context))
|
AnyView(DeveloperOptionsScreen(context: viewModel.context))
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,17 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
typealias DeveloperOptionsScreenViewModelType = StateStoreViewModel<DeveloperOptionsScreenViewState, DeveloperOptionsScreenViewAction>
|
typealias DeveloperOptionsScreenViewModelType = StateStoreViewModel<DeveloperOptionsScreenViewState, DeveloperOptionsScreenViewAction>
|
||||||
|
|
||||||
class DeveloperOptionsScreenViewModel: DeveloperOptionsScreenViewModelType, DeveloperOptionsScreenViewModelProtocol {
|
class DeveloperOptionsScreenViewModel: DeveloperOptionsScreenViewModelType, DeveloperOptionsScreenViewModelProtocol {
|
||||||
var callback: ((DeveloperOptionsScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<DeveloperOptionsScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<DeveloperOptionsScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(developerOptions: DeveloperOptionsProtocol) {
|
init(developerOptions: DeveloperOptionsProtocol) {
|
||||||
let bindings = DeveloperOptionsScreenViewStateBindings(developerOptions: developerOptions)
|
let bindings = DeveloperOptionsScreenViewStateBindings(developerOptions: developerOptions)
|
||||||
@ -31,7 +36,7 @@ class DeveloperOptionsScreenViewModel: DeveloperOptionsScreenViewModelType, Deve
|
|||||||
override func process(viewAction: DeveloperOptionsScreenViewAction) {
|
override func process(viewAction: DeveloperOptionsScreenViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .clearCache:
|
case .clearCache:
|
||||||
callback?(.clearCache)
|
actionsSubject.send(.clearCache)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol DeveloperOptionsScreenViewModelProtocol {
|
protocol DeveloperOptionsScreenViewModelProtocol {
|
||||||
var callback: ((DeveloperOptionsScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<DeveloperOptionsScreenViewModelAction, Never> { get }
|
||||||
var context: DeveloperOptionsScreenViewModelType.Context { get }
|
var context: DeveloperOptionsScreenViewModelType.Context { get }
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ final class NotificationSettingsEditScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: NotificationSettingsEditScreenCoordinatorParameters
|
private let parameters: NotificationSettingsEditScreenCoordinatorParameters
|
||||||
private var viewModel: NotificationSettingsEditScreenViewModelProtocol
|
private var viewModel: NotificationSettingsEditScreenViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<NotificationSettingsEditScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<NotificationSettingsEditScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<NotificationSettingsEditScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<NotificationSettingsEditScreenCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
@ -33,7 +33,7 @@ final class NotificationSettingsScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: NotificationSettingsScreenCoordinatorParameters
|
private let parameters: NotificationSettingsScreenCoordinatorParameters
|
||||||
private var viewModel: NotificationSettingsScreenViewModelProtocol
|
private var viewModel: NotificationSettingsScreenViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<NotificationSettingsScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<NotificationSettingsScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
private var navigationStackCoordinator: NavigationStackCoordinator? {
|
private var navigationStackCoordinator: NavigationStackCoordinator? {
|
||||||
parameters.navigationStackCoordinator
|
parameters.navigationStackCoordinator
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct SettingsScreenCoordinatorParameters {
|
struct SettingsScreenCoordinatorParameters {
|
||||||
@ -34,8 +35,13 @@ enum SettingsScreenCoordinatorAction {
|
|||||||
final class SettingsScreenCoordinator: CoordinatorProtocol {
|
final class SettingsScreenCoordinator: CoordinatorProtocol {
|
||||||
private let parameters: SettingsScreenCoordinatorParameters
|
private let parameters: SettingsScreenCoordinatorParameters
|
||||||
private var viewModel: SettingsScreenViewModelProtocol
|
private var viewModel: SettingsScreenViewModelProtocol
|
||||||
|
|
||||||
var callback: ((SettingsScreenCoordinatorAction) -> Void)?
|
private let actionsSubject: PassthroughSubject<SettingsScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<SettingsScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Setup
|
// MARK: - Setup
|
||||||
|
|
||||||
@ -43,34 +49,37 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
|||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
|
|
||||||
viewModel = SettingsScreenViewModel(userSession: parameters.userSession, appSettings: ServiceLocator.shared.settings)
|
viewModel = SettingsScreenViewModel(userSession: parameters.userSession, appSettings: ServiceLocator.shared.settings)
|
||||||
viewModel.callback = { [weak self] action in
|
|
||||||
guard let self else { return }
|
viewModel.actions
|
||||||
|
.sink { [weak self] action in
|
||||||
switch action {
|
guard let self else { return }
|
||||||
case .close:
|
|
||||||
callback?(.dismiss)
|
switch action {
|
||||||
case .accountProfile:
|
case .close:
|
||||||
presentAccountProfileURL()
|
actionsSubject.send(.dismiss)
|
||||||
case .analytics:
|
case .accountProfile:
|
||||||
presentAnalyticsScreen()
|
presentAccountProfileURL()
|
||||||
case .reportBug:
|
case .analytics:
|
||||||
presentBugReportScreen()
|
presentAnalyticsScreen()
|
||||||
case .about:
|
case .reportBug:
|
||||||
presentLegalInformationScreen()
|
presentBugReportScreen()
|
||||||
case .sessionVerification:
|
case .about:
|
||||||
verifySession()
|
presentLegalInformationScreen()
|
||||||
case .accountSessionsList:
|
case .sessionVerification:
|
||||||
presentAccountSessionsListURL()
|
verifySession()
|
||||||
case .notifications:
|
case .accountSessionsList:
|
||||||
presentNotificationSettings()
|
presentAccountSessionsListURL()
|
||||||
case .advancedSettings:
|
case .notifications:
|
||||||
self.presentAdvancedSettings()
|
presentNotificationSettings()
|
||||||
case .developerOptions:
|
case .advancedSettings:
|
||||||
presentDeveloperOptions()
|
self.presentAdvancedSettings()
|
||||||
case .logout:
|
case .developerOptions:
|
||||||
callback?(.logout)
|
presentDeveloperOptions()
|
||||||
|
case .logout:
|
||||||
|
actionsSubject.send(.logout)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
@ -152,10 +161,17 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
|||||||
let verificationParameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController)
|
let verificationParameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController)
|
||||||
let coordinator = SessionVerificationScreenCoordinator(parameters: verificationParameters)
|
let coordinator = SessionVerificationScreenCoordinator(parameters: verificationParameters)
|
||||||
|
|
||||||
coordinator.callback = { [weak self] in
|
coordinator.actions
|
||||||
self?.parameters.navigationStackCoordinator?.setSheetCoordinator(nil)
|
.sink { [weak self] action in
|
||||||
}
|
guard let self else { return }
|
||||||
|
|
||||||
|
switch action {
|
||||||
|
case .done:
|
||||||
|
parameters.navigationStackCoordinator?.setSheetCoordinator(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
parameters.navigationStackCoordinator?.setSheetCoordinator(coordinator) { [weak self] in
|
parameters.navigationStackCoordinator?.setSheetCoordinator(coordinator) { [weak self] in
|
||||||
self?.parameters.navigationStackCoordinator?.setSheetCoordinator(nil)
|
self?.parameters.navigationStackCoordinator?.setSheetCoordinator(nil)
|
||||||
}
|
}
|
||||||
@ -179,12 +195,16 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
|||||||
private func presentDeveloperOptions() {
|
private func presentDeveloperOptions() {
|
||||||
let coordinator = DeveloperOptionsScreenCoordinator()
|
let coordinator = DeveloperOptionsScreenCoordinator()
|
||||||
|
|
||||||
coordinator.callback = { [weak self] action in
|
coordinator.actions
|
||||||
switch action {
|
.sink { [weak self] action in
|
||||||
case .clearCache:
|
guard let self else { return }
|
||||||
self?.callback?(.clearCache)
|
|
||||||
|
switch action {
|
||||||
|
case .clearCache:
|
||||||
|
actionsSubject.send(.clearCache)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
parameters.navigationStackCoordinator?.push(coordinator)
|
parameters.navigationStackCoordinator?.push(coordinator)
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,11 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
|
|||||||
private let userSession: UserSessionProtocol
|
private let userSession: UserSessionProtocol
|
||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
|
|
||||||
var callback: ((SettingsScreenViewModelAction) -> Void)?
|
private var actionsSubject: PassthroughSubject<SettingsScreenViewModelAction, Never> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<SettingsScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(userSession: UserSessionProtocol, appSettings: AppSettings) {
|
init(userSession: UserSessionProtocol, appSettings: AppSettings) {
|
||||||
self.userSession = userSession
|
self.userSession = userSession
|
||||||
@ -74,27 +78,27 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
|
|||||||
override func process(viewAction: SettingsScreenViewAction) {
|
override func process(viewAction: SettingsScreenViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .close:
|
case .close:
|
||||||
callback?(.close)
|
actionsSubject.send(.close)
|
||||||
case .accountProfile:
|
case .accountProfile:
|
||||||
callback?(.accountProfile)
|
actionsSubject.send(.accountProfile)
|
||||||
case .analytics:
|
case .analytics:
|
||||||
callback?(.analytics)
|
actionsSubject.send(.analytics)
|
||||||
case .reportBug:
|
case .reportBug:
|
||||||
callback?(.reportBug)
|
actionsSubject.send(.reportBug)
|
||||||
case .about:
|
case .about:
|
||||||
callback?(.about)
|
actionsSubject.send(.about)
|
||||||
case .logout:
|
case .logout:
|
||||||
callback?(.logout)
|
actionsSubject.send(.logout)
|
||||||
case .sessionVerification:
|
case .sessionVerification:
|
||||||
callback?(.sessionVerification)
|
actionsSubject.send(.sessionVerification)
|
||||||
case .notifications:
|
case .notifications:
|
||||||
callback?(.notifications)
|
actionsSubject.send(.notifications)
|
||||||
case .accountSessionsList:
|
case .accountSessionsList:
|
||||||
callback?(.accountSessionsList)
|
actionsSubject.send(.accountSessionsList)
|
||||||
case .advancedSettings:
|
case .advancedSettings:
|
||||||
callback?(.advancedSettings)
|
actionsSubject.send(.advancedSettings)
|
||||||
case .developerOptions:
|
case .developerOptions:
|
||||||
callback?(.developerOptions)
|
actionsSubject.send(.developerOptions)
|
||||||
|
|
||||||
case .updateWindow(let window):
|
case .updateWindow(let window):
|
||||||
Task {
|
Task {
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Combine
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
protocol SettingsScreenViewModelProtocol {
|
protocol SettingsScreenViewModelProtocol {
|
||||||
var callback: ((SettingsScreenViewModelAction) -> Void)? { get set }
|
var actions: AnyPublisher<SettingsScreenViewModelAction, Never> { get }
|
||||||
var context: SettingsScreenViewModelType.Context { get }
|
var context: SettingsScreenViewModelType.Context { get }
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ final class StartChatScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: StartChatScreenCoordinatorParameters
|
private let parameters: StartChatScreenCoordinatorParameters
|
||||||
private var viewModel: StartChatScreenViewModelProtocol
|
private var viewModel: StartChatScreenViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<StartChatScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<StartChatScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
private var createRoomParameters = CurrentValueSubject<CreateRoomFlowParameters, Never>(.init())
|
private var createRoomParameters = CurrentValueSubject<CreateRoomFlowParameters, Never>(.init())
|
||||||
private var createRoomParametersPublisher: CurrentValuePublisher<CreateRoomFlowParameters, Never> {
|
private var createRoomParametersPublisher: CurrentValuePublisher<CreateRoomFlowParameters, Never> {
|
||||||
@ -97,10 +97,10 @@ final class StartChatScreenCoordinator: CoordinatorProtocol {
|
|||||||
mediaProvider: parameters.userSession.mediaProvider,
|
mediaProvider: parameters.userSession.mediaProvider,
|
||||||
userDiscoveryService: parameters.userDiscoveryService)
|
userDiscoveryService: parameters.userDiscoveryService)
|
||||||
let coordinator = InviteUsersScreenCoordinator(parameters: inviteParameters)
|
let coordinator = InviteUsersScreenCoordinator(parameters: inviteParameters)
|
||||||
coordinator.actions.sink { [weak self] result in
|
coordinator.actions.sink { [weak self] action in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
switch result {
|
switch action {
|
||||||
case .cancel:
|
case .cancel:
|
||||||
break // Not shown in this flow.
|
break // Not shown in this flow.
|
||||||
case .proceed:
|
case .proceed:
|
||||||
@ -125,9 +125,9 @@ final class StartChatScreenCoordinator: CoordinatorProtocol {
|
|||||||
createRoomParameters: createRoomParametersPublisher,
|
createRoomParameters: createRoomParametersPublisher,
|
||||||
selectedUsers: selectedUsersPublisher)
|
selectedUsers: selectedUsersPublisher)
|
||||||
let coordinator = CreateRoomCoordinator(parameters: createParameters)
|
let coordinator = CreateRoomCoordinator(parameters: createParameters)
|
||||||
coordinator.actions.sink { [weak self] result in
|
coordinator.actions.sink { [weak self] action in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
switch result {
|
switch action {
|
||||||
case .deselectUser(let user):
|
case .deselectUser(let user):
|
||||||
self.toggleUser(user)
|
self.toggleUser(user)
|
||||||
case .updateDetails(let details):
|
case .updateDetails(let details):
|
||||||
|
@ -26,7 +26,7 @@ struct WelcomeScreen: View {
|
|||||||
} bottomContent: {
|
} bottomContent: {
|
||||||
button
|
button
|
||||||
}
|
}
|
||||||
.background(OnboardingBackgroundImage())
|
.background(OnboardingScreenBackgroundImage())
|
||||||
.environment(\.backgroundStyle, AnyShapeStyle(Color.clear))
|
.environment(\.backgroundStyle, AnyShapeStyle(Color.clear))
|
||||||
.onAppear {
|
.onAppear {
|
||||||
context.send(viewAction: .appeared)
|
context.send(viewAction: .appeared)
|
||||||
|
@ -24,7 +24,7 @@ enum WelcomeScreenScreenCoordinatorAction {
|
|||||||
final class WelcomeScreenScreenCoordinator: CoordinatorProtocol {
|
final class WelcomeScreenScreenCoordinator: CoordinatorProtocol {
|
||||||
private var viewModel: WelcomeScreenScreenViewModelProtocol
|
private var viewModel: WelcomeScreenScreenViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<WelcomeScreenScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<WelcomeScreenScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<WelcomeScreenScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<WelcomeScreenScreenCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
@ -71,7 +71,7 @@ class MockScreen: Identifiable {
|
|||||||
let id: UITestsScreenIdentifier
|
let id: UITestsScreenIdentifier
|
||||||
|
|
||||||
private var retainedState = [Any]()
|
private var retainedState = [Any]()
|
||||||
private var cancellables: Set<AnyCancellable> = []
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
init(id: UITestsScreenIdentifier) {
|
init(id: UITestsScreenIdentifier) {
|
||||||
self.id = id
|
self.id = id
|
||||||
@ -229,7 +229,7 @@ class MockScreen: Identifiable {
|
|||||||
isModallyPresented: false)
|
isModallyPresented: false)
|
||||||
return NotificationSettingsScreenCoordinator(parameters: parameters)
|
return NotificationSettingsScreenCoordinator(parameters: parameters)
|
||||||
case .onboarding:
|
case .onboarding:
|
||||||
return OnboardingCoordinator()
|
return OnboardingScreenCoordinator()
|
||||||
case .roomPlainNoAvatar:
|
case .roomPlainNoAvatar:
|
||||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
let parameters = RoomScreenCoordinatorParameters(roomProxy: RoomProxyMock(with: .init(displayName: "Some room name", avatarURL: nil)),
|
let parameters = RoomScreenCoordinatorParameters(roomProxy: RoomProxyMock(with: .init(displayName: "Some room name", avatarURL: nil)),
|
||||||
|
@ -29,7 +29,7 @@ final class TemplateScreenCoordinator: CoordinatorProtocol {
|
|||||||
private let parameters: TemplateScreenCoordinatorParameters
|
private let parameters: TemplateScreenCoordinatorParameters
|
||||||
private var viewModel: TemplateScreenViewModelProtocol
|
private var viewModel: TemplateScreenViewModelProtocol
|
||||||
private let actionsSubject: PassthroughSubject<TemplateScreenCoordinatorAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<TemplateScreenCoordinatorAction, Never> = .init()
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var actions: AnyPublisher<TemplateScreenCoordinatorAction, Never> {
|
var actions: AnyPublisher<TemplateScreenCoordinatorAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
class OnboardingUITests: XCTestCase {
|
class OnboardingScreenUITests: XCTestCase {
|
||||||
func testInitialStateComponents() async throws {
|
func testInitialStateComponents() async throws {
|
||||||
let app = Application.launch(.onboarding)
|
let app = Application.launch(.onboarding)
|
||||||
try await app.assertScreenshot(.onboarding)
|
try await app.assertScreenshot(.onboarding)
|
@ -26,13 +26,14 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
var userSession: MockUserSession!
|
var userSession: MockUserSession!
|
||||||
|
|
||||||
private let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
|
private let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
|
||||||
private var cancellables: Set<AnyCancellable> = []
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var context: CreateRoomViewModel.Context {
|
var context: CreateRoomViewModel.Context {
|
||||||
viewModel.context
|
viewModel.context
|
||||||
}
|
}
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
cancellables.removeAll()
|
||||||
clientProxy = MockClientProxy(userID: "@a:b.com")
|
clientProxy = MockClientProxy(userID: "@a:b.com")
|
||||||
userSession = MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider())
|
userSession = MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider())
|
||||||
let parameters = CreateRoomFlowParameters()
|
let parameters = CreateRoomFlowParameters()
|
||||||
|
@ -23,12 +23,11 @@ import XCTest
|
|||||||
class HomeScreenViewModelTests: XCTestCase {
|
class HomeScreenViewModelTests: XCTestCase {
|
||||||
var viewModel: HomeScreenViewModelProtocol!
|
var viewModel: HomeScreenViewModelProtocol!
|
||||||
var clientProxy: MockClientProxy!
|
var clientProxy: MockClientProxy!
|
||||||
|
var context: HomeScreenViewModelType.Context! { viewModel.context }
|
||||||
var context: HomeScreenViewModelType.Context! {
|
var cancellables = Set<AnyCancellable>()
|
||||||
viewModel.context
|
|
||||||
}
|
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
cancellables.removeAll()
|
||||||
clientProxy = MockClientProxy(userID: "@mock:client.com")
|
clientProxy = MockClientProxy(userID: "@mock:client.com")
|
||||||
viewModel = HomeScreenViewModel(userSession: MockUserSession(clientProxy: clientProxy,
|
viewModel = HomeScreenViewModel(userSession: MockUserSession(clientProxy: clientProxy,
|
||||||
mediaProvider: MockMediaProvider()),
|
mediaProvider: MockMediaProvider()),
|
||||||
@ -43,16 +42,19 @@ class HomeScreenViewModelTests: XCTestCase {
|
|||||||
let mockRoomId = "mock_room_id"
|
let mockRoomId = "mock_room_id"
|
||||||
var correctResult = false
|
var correctResult = false
|
||||||
var selectedRoomId = ""
|
var selectedRoomId = ""
|
||||||
viewModel.callback = { result in
|
|
||||||
switch result {
|
viewModel.actions
|
||||||
case .presentRoom(let roomId):
|
.sink { action in
|
||||||
correctResult = true
|
switch action {
|
||||||
selectedRoomId = roomId
|
case .presentRoom(let roomId):
|
||||||
default:
|
correctResult = true
|
||||||
break
|
selectedRoomId = roomId
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
context.send(viewAction: .selectRoom(roomIdentifier: mockRoomId))
|
context.send(viewAction: .selectRoom(roomIdentifier: mockRoomId))
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
XCTAssert(correctResult)
|
XCTAssert(correctResult)
|
||||||
@ -61,15 +63,18 @@ class HomeScreenViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
func testTapUserAvatar() async throws {
|
func testTapUserAvatar() async throws {
|
||||||
var correctResult = false
|
var correctResult = false
|
||||||
viewModel.callback = { result in
|
|
||||||
switch result {
|
viewModel.actions
|
||||||
case .presentSettingsScreen:
|
.sink { action in
|
||||||
correctResult = true
|
switch action {
|
||||||
default:
|
case .presentSettingsScreen:
|
||||||
break
|
correctResult = true
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
context.send(viewAction: .userMenu(action: .settings))
|
context.send(viewAction: .userMenu(action: .settings))
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
XCTAssert(correctResult)
|
XCTAssert(correctResult)
|
||||||
@ -97,15 +102,17 @@ class HomeScreenViewModelTests: XCTestCase {
|
|||||||
let mockRoomId = "1"
|
let mockRoomId = "1"
|
||||||
var correctResult = false
|
var correctResult = false
|
||||||
let expectation = expectation(description: #function)
|
let expectation = expectation(description: #function)
|
||||||
viewModel.callback = { result in
|
viewModel.actions
|
||||||
switch result {
|
.sink { action in
|
||||||
case .roomLeft(let roomIdentifier):
|
switch action {
|
||||||
correctResult = roomIdentifier == mockRoomId
|
case .roomLeft(let roomIdentifier):
|
||||||
default:
|
correctResult = roomIdentifier == mockRoomId
|
||||||
break
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
expectation.fulfill()
|
||||||
}
|
}
|
||||||
expectation.fulfill()
|
.store(in: &cancellables)
|
||||||
}
|
|
||||||
let room: RoomProxyMock = .init(with: .init(id: mockRoomId, displayName: "Some room"))
|
let room: RoomProxyMock = .init(with: .init(id: mockRoomId, displayName: "Some room"))
|
||||||
room.leaveRoomClosure = { .success(()) }
|
room.leaveRoomClosure = { .success(()) }
|
||||||
clientProxy.roomForIdentifierMocks[mockRoomId] = room
|
clientProxy.roomForIdentifierMocks[mockRoomId] = room
|
||||||
@ -118,14 +125,16 @@ class HomeScreenViewModelTests: XCTestCase {
|
|||||||
func testShowRoomDetails() async throws {
|
func testShowRoomDetails() async throws {
|
||||||
let mockRoomId = "1"
|
let mockRoomId = "1"
|
||||||
var correctResult = false
|
var correctResult = false
|
||||||
viewModel.callback = { result in
|
viewModel.actions
|
||||||
switch result {
|
.sink { action in
|
||||||
case .presentRoomDetails(let roomIdentifier):
|
switch action {
|
||||||
correctResult = roomIdentifier == mockRoomId
|
case .presentRoomDetails(let roomIdentifier):
|
||||||
default:
|
correctResult = roomIdentifier == mockRoomId
|
||||||
break
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
context.send(viewAction: .showRoomDetails(roomIdentifier: mockRoomId))
|
context.send(viewAction: .showRoomDetails(roomIdentifier: mockRoomId))
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
XCTAssertNil(context.alertInfo)
|
XCTAssertNil(context.alertInfo)
|
||||||
|
@ -25,12 +25,16 @@ class InviteUsersScreenViewModelTests: XCTestCase {
|
|||||||
var clientProxy: MockClientProxy!
|
var clientProxy: MockClientProxy!
|
||||||
var userDiscoveryService: UserDiscoveryServiceMock!
|
var userDiscoveryService: UserDiscoveryServiceMock!
|
||||||
|
|
||||||
private var cancellables: Set<AnyCancellable> = []
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var context: InviteUsersScreenViewModel.Context {
|
var context: InviteUsersScreenViewModel.Context {
|
||||||
viewModel.context
|
viewModel.context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func setUp() {
|
||||||
|
cancellables.removeAll()
|
||||||
|
}
|
||||||
|
|
||||||
func testSelectUser() {
|
func testSelectUser() {
|
||||||
setupWithRoomType(roomType: .draft)
|
setupWithRoomType(roomType: .draft)
|
||||||
XCTAssertTrue(context.viewState.selectedUsers.isEmpty)
|
XCTAssertTrue(context.viewState.selectedUsers.isEmpty)
|
||||||
|
@ -26,6 +26,7 @@ class MessageForwardingScreenViewModelTests: XCTestCase {
|
|||||||
var cancellables = Set<AnyCancellable>()
|
var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
cancellables.removeAll()
|
||||||
viewModel = MessageForwardingScreenViewModel(roomSummaryProvider: MockRoomSummaryProvider(state: .loaded(.mockRooms)), sourceRoomID: "1")
|
viewModel = MessageForwardingScreenViewModel(roomSummaryProvider: MockRoomSummaryProvider(state: .loaded(.mockRooms)), sourceRoomID: "1")
|
||||||
context = viewModel.context
|
context = viewModel.context
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,6 @@ import XCTest
|
|||||||
|
|
||||||
@testable import ElementX
|
@testable import ElementX
|
||||||
|
|
||||||
class OnboardingViewModelTests: XCTestCase {
|
class OnboardingScreenViewModelTests: XCTestCase {
|
||||||
// Nothing to test, the view model has no mutable state.
|
// Nothing to test, the view model has no mutable state.
|
||||||
}
|
}
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import MatrixRustSDK
|
import MatrixRustSDK
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import XCTest
|
import XCTest
|
||||||
@ -26,8 +27,10 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
var roomProxyMock: RoomProxyMock!
|
var roomProxyMock: RoomProxyMock!
|
||||||
var notificationSettingsProxyMock: NotificationSettingsProxyMock!
|
var notificationSettingsProxyMock: NotificationSettingsProxyMock!
|
||||||
var context: RoomDetailsScreenViewModelType.Context { viewModel.context }
|
var context: RoomDetailsScreenViewModelType.Context { viewModel.context }
|
||||||
|
var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
|
cancellables.removeAll()
|
||||||
roomProxyMock = RoomProxyMock(with: .init(displayName: "Test", joinedMembersCount: 0))
|
roomProxyMock = RoomProxyMock(with: .init(displayName: "Test", joinedMembersCount: 0))
|
||||||
notificationSettingsProxyMock = NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())
|
notificationSettingsProxyMock = NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())
|
||||||
viewModel = RoomDetailsScreenViewModel(accountUserID: "@owner:somewhere.com",
|
viewModel = RoomDetailsScreenViewModel(accountUserID: "@owner:somewhere.com",
|
||||||
@ -84,15 +87,17 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxyMock.leaveRoomClosure = {
|
roomProxyMock.leaveRoomClosure = {
|
||||||
.success(())
|
.success(())
|
||||||
}
|
}
|
||||||
viewModel.callback = { action in
|
viewModel.actions
|
||||||
switch action {
|
.sink { action in
|
||||||
case .leftRoom:
|
switch action {
|
||||||
break
|
case .leftRoom:
|
||||||
default:
|
break
|
||||||
XCTFail("leftRoom expected")
|
default:
|
||||||
|
XCTFail("leftRoom expected")
|
||||||
|
}
|
||||||
|
expectation.fulfill()
|
||||||
}
|
}
|
||||||
expectation.fulfill()
|
.store(in: &cancellables)
|
||||||
}
|
|
||||||
context.send(viewAction: .confirmLeave)
|
context.send(viewAction: .confirmLeave)
|
||||||
await fulfillment(of: [expectation])
|
await fulfillment(of: [expectation])
|
||||||
XCTAssertEqual(roomProxyMock.leaveRoomCallsCount, 1)
|
XCTAssertEqual(roomProxyMock.leaveRoomCallsCount, 1)
|
||||||
@ -263,14 +268,16 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
XCTAssertTrue(context.viewState.canInviteUsers)
|
XCTAssertTrue(context.viewState.canInviteUsers)
|
||||||
|
|
||||||
var callbackCorrectlyCalled = false
|
var callbackCorrectlyCalled = false
|
||||||
viewModel.callback = { action in
|
viewModel.actions
|
||||||
switch action {
|
.sink { action in
|
||||||
case .requestInvitePeoplePresentation:
|
switch action {
|
||||||
callbackCorrectlyCalled = true
|
case .requestInvitePeoplePresentation:
|
||||||
default:
|
callbackCorrectlyCalled = true
|
||||||
callbackCorrectlyCalled = false
|
default:
|
||||||
|
callbackCorrectlyCalled = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
context.send(viewAction: .processTapInvite)
|
context.send(viewAction: .processTapInvite)
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
|
@ -23,9 +23,10 @@ import Combine
|
|||||||
class RoomFlowCoordinatorTests: XCTestCase {
|
class RoomFlowCoordinatorTests: XCTestCase {
|
||||||
var roomFlowCoordinator: RoomFlowCoordinator!
|
var roomFlowCoordinator: RoomFlowCoordinator!
|
||||||
var navigationStackCoordinator: NavigationStackCoordinator!
|
var navigationStackCoordinator: NavigationStackCoordinator!
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
override func setUp() async throws {
|
override func setUp() async throws {
|
||||||
|
cancellables.removeAll()
|
||||||
let clientProxy = MockClientProxy(userID: "hi@bob", roomSummaryProvider: MockRoomSummaryProvider(state: .loaded(.mockRooms)))
|
let clientProxy = MockClientProxy(userID: "hi@bob", roomSummaryProvider: MockRoomSummaryProvider(state: .loaded(.mockRooms)))
|
||||||
let mediaProvider = MockMediaProvider()
|
let mediaProvider = MockMediaProvider()
|
||||||
let userSession = MockUserSession(clientProxy: clientProxy, mediaProvider: mediaProvider)
|
let userSession = MockUserSession(clientProxy: clientProxy, mediaProvider: mediaProvider)
|
||||||
|
@ -26,9 +26,10 @@ class RoomNotificationSettingsScreenViewModelTests: XCTestCase {
|
|||||||
var roomProxyMock: RoomProxyMock!
|
var roomProxyMock: RoomProxyMock!
|
||||||
var notificationSettingsProxyMock: NotificationSettingsProxyMock!
|
var notificationSettingsProxyMock: NotificationSettingsProxyMock!
|
||||||
var context: RoomNotificationSettingsScreenViewModelType.Context { viewModel.context }
|
var context: RoomNotificationSettingsScreenViewModelType.Context { viewModel.context }
|
||||||
var cancellables: Set<AnyCancellable> = []
|
var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
cancellables.removeAll()
|
||||||
roomProxyMock = RoomProxyMock(with: .init(displayName: "Test", joinedMembersCount: 0))
|
roomProxyMock = RoomProxyMock(with: .init(displayName: "Test", joinedMembersCount: 0))
|
||||||
notificationSettingsProxyMock = NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())
|
notificationSettingsProxyMock = NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())
|
||||||
viewModel = RoomNotificationSettingsScreenViewModel(notificationSettingsProxy: notificationSettingsProxyMock,
|
viewModel = RoomNotificationSettingsScreenViewModel(notificationSettingsProxy: notificationSettingsProxyMock,
|
||||||
@ -172,8 +173,8 @@ class RoomNotificationSettingsScreenViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
var actionSent: RoomNotificationSettingsScreenViewModelAction?
|
var actionSent: RoomNotificationSettingsScreenViewModelAction?
|
||||||
viewModel.actions
|
viewModel.actions
|
||||||
.sink { value in
|
.sink { action in
|
||||||
actionSent = value
|
actionSent = action
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
@ -207,8 +208,8 @@ class RoomNotificationSettingsScreenViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
var actionSent: RoomNotificationSettingsScreenViewModelAction?
|
var actionSent: RoomNotificationSettingsScreenViewModelAction?
|
||||||
viewModel.actions
|
viewModel.actions
|
||||||
.sink { value in
|
.sink { action in
|
||||||
actionSent = value
|
actionSent = action
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ class RoomScreenViewModelTests: XCTestCase {
|
|||||||
var cancellables = Set<AnyCancellable>()
|
var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
override func setUp() async throws {
|
override func setUp() async throws {
|
||||||
|
cancellables.removeAll()
|
||||||
userIndicatorControllerMock = UserIndicatorControllerMock.default
|
userIndicatorControllerMock = UserIndicatorControllerMock.default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@testable import ElementX
|
@testable import ElementX
|
||||||
@ -22,8 +23,10 @@ import XCTest
|
|||||||
class SettingsScreenViewModelTests: XCTestCase {
|
class SettingsScreenViewModelTests: XCTestCase {
|
||||||
var viewModel: SettingsScreenViewModelProtocol!
|
var viewModel: SettingsScreenViewModelProtocol!
|
||||||
var context: SettingsScreenViewModelType.Context!
|
var context: SettingsScreenViewModelType.Context!
|
||||||
|
var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
@MainActor override func setUpWithError() throws {
|
@MainActor override func setUpWithError() throws {
|
||||||
|
cancellables.removeAll()
|
||||||
let userSession = MockUserSession(clientProxy: MockClientProxy(userID: ""),
|
let userSession = MockUserSession(clientProxy: MockClientProxy(userID: ""),
|
||||||
mediaProvider: MockMediaProvider())
|
mediaProvider: MockMediaProvider())
|
||||||
viewModel = SettingsScreenViewModel(userSession: userSession, appSettings: ServiceLocator.shared.settings)
|
viewModel = SettingsScreenViewModel(userSession: userSession, appSettings: ServiceLocator.shared.settings)
|
||||||
@ -32,14 +35,17 @@ class SettingsScreenViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
@MainActor func testLogout() async throws {
|
@MainActor func testLogout() async throws {
|
||||||
var correctResult = false
|
var correctResult = false
|
||||||
viewModel.callback = { result in
|
|
||||||
switch result {
|
viewModel.actions
|
||||||
case .logout:
|
.sink { action in
|
||||||
correctResult = true
|
switch action {
|
||||||
default:
|
case .logout:
|
||||||
break
|
correctResult = true
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.store(in: &cancellables)
|
||||||
|
|
||||||
context.send(viewAction: .logout)
|
context.send(viewAction: .logout)
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
@ -48,10 +54,12 @@ class SettingsScreenViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
func testReportBug() async throws {
|
func testReportBug() async throws {
|
||||||
var correctResult = false
|
var correctResult = false
|
||||||
viewModel.callback = { result in
|
viewModel.actions
|
||||||
correctResult = result == .reportBug
|
.sink { action in
|
||||||
}
|
correctResult = action == .reportBug
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
context.send(viewAction: .reportBug)
|
context.send(viewAction: .reportBug)
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
XCTAssert(correctResult)
|
XCTAssert(correctResult)
|
||||||
@ -59,10 +67,12 @@ class SettingsScreenViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
func testAnalytics() async throws {
|
func testAnalytics() async throws {
|
||||||
var correctResult = false
|
var correctResult = false
|
||||||
viewModel.callback = { result in
|
viewModel.actions
|
||||||
correctResult = result == .analytics
|
.sink { action in
|
||||||
}
|
correctResult = action == .analytics
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
context.send(viewAction: .analytics)
|
context.send(viewAction: .analytics)
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
XCTAssert(correctResult)
|
XCTAssert(correctResult)
|
||||||
|
@ -24,13 +24,14 @@ class StaticLocationScreenViewModelTests: XCTestCase {
|
|||||||
var viewModel: StaticLocationScreenViewModelProtocol!
|
var viewModel: StaticLocationScreenViewModelProtocol!
|
||||||
|
|
||||||
private let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
|
private let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
|
||||||
private var cancellables: Set<AnyCancellable> = []
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
var context: StaticLocationScreenViewModel.Context {
|
var context: StaticLocationScreenViewModel.Context {
|
||||||
viewModel.context
|
viewModel.context
|
||||||
}
|
}
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
cancellables.removeAll()
|
||||||
let viewModel = StaticLocationScreenViewModel(interactionMode: .picker)
|
let viewModel = StaticLocationScreenViewModel(interactionMode: .picker)
|
||||||
viewModel.state.bindings.isLocationAuthorized = true
|
viewModel.state.bindings.isLocationAuthorized = true
|
||||||
self.viewModel = viewModel
|
self.viewModel = viewModel
|
||||||
|
@ -21,10 +21,10 @@ final class UserSessionTests: XCTestCase {
|
|||||||
var userSession: UserSession!
|
var userSession: UserSession!
|
||||||
let clientProxy = MockClientProxy(userID: "@test:user.net")
|
let clientProxy = MockClientProxy(userID: "@test:user.net")
|
||||||
|
|
||||||
private var cancellables: Set<AnyCancellable> = []
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
cancellables = []
|
cancellables.removeAll()
|
||||||
userSession = UserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider())
|
userSession = UserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user