mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-06 12:28:29 +00:00
Add a service and flow coordinator for the LinkNewDevice feature. (#4859)
* Add a LinkNewDeviceService that exposes the SDK's grant QR code login methods. * Add a flow coordinator for linking a new device. Changes the presentation too.
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
0033481EE363E4914295F188 /* LocalizationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C070FD43DC6BF4E50217965A /* LocalizationTests.swift */; };
|
0033481EE363E4914295F188 /* LocalizationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C070FD43DC6BF4E50217965A /* LocalizationTests.swift */; };
|
||||||
00C3023B6DF55024D8876B76 /* ShareExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 3D8BEEFCA07BEA43F4F4BF77 /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
00C3023B6DF55024D8876B76 /* ShareExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 3D8BEEFCA07BEA43F4F4BF77 /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
|
012D9DDCDE6278E4E0CDCC0F /* LinkNewDeviceFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94EE2C5F0A06F146BBE3A1B1 /* LinkNewDeviceFlowCoordinator.swift */; };
|
||||||
01373C1AC4839604C4FDA404 /* test_apple_image.heic in Resources */ = {isa = PBXBuildFile; fileRef = BB576F4118C35E6B5124FA22 /* test_apple_image.heic */; };
|
01373C1AC4839604C4FDA404 /* test_apple_image.heic in Resources */ = {isa = PBXBuildFile; fileRef = BB576F4118C35E6B5124FA22 /* test_apple_image.heic */; };
|
||||||
01681E8B20AD6F0D237F2DC1 /* IdentityConfirmedScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C6624240FFD32B7F0834229 /* IdentityConfirmedScreenViewModel.swift */; };
|
01681E8B20AD6F0D237F2DC1 /* IdentityConfirmedScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C6624240FFD32B7F0834229 /* IdentityConfirmedScreenViewModel.swift */; };
|
||||||
0180C44B997EDA8D21F883AC /* RoomNotificationSettingsCustomSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B746EFA112532A7B701FB914 /* RoomNotificationSettingsCustomSectionView.swift */; };
|
0180C44B997EDA8D21F883AC /* RoomNotificationSettingsCustomSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B746EFA112532A7B701FB914 /* RoomNotificationSettingsCustomSectionView.swift */; };
|
||||||
@@ -783,6 +784,7 @@
|
|||||||
88F348E2CB14FF71CBBB665D /* AudioRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7475C5AE20BA896930907EA8 /* AudioRoomTimelineItemContent.swift */; };
|
88F348E2CB14FF71CBBB665D /* AudioRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7475C5AE20BA896930907EA8 /* AudioRoomTimelineItemContent.swift */; };
|
||||||
890F0D453FE388756479AC97 /* AnalyticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C687844F60BFF532D49A994C /* AnalyticsTests.swift */; };
|
890F0D453FE388756479AC97 /* AnalyticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C687844F60BFF532D49A994C /* AnalyticsTests.swift */; };
|
||||||
89198AE2649DD77673D5793B /* ExtensionLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41A8571A8A071FB41778C016 /* ExtensionLogger.swift */; };
|
89198AE2649DD77673D5793B /* ExtensionLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41A8571A8A071FB41778C016 /* ExtensionLogger.swift */; };
|
||||||
|
89261D215E4A432E887CD156 /* GrantLoginWithQrCodeHandlerSDKMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBD288168C48D3F76177FCBF /* GrantLoginWithQrCodeHandlerSDKMock.swift */; };
|
||||||
8944548A684F1C837CEC47F4 /* RoomMembersListScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0946F77B696176E062D037 /* RoomMembersListScreenModels.swift */; };
|
8944548A684F1C837CEC47F4 /* RoomMembersListScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0946F77B696176E062D037 /* RoomMembersListScreenModels.swift */; };
|
||||||
89658A44C9FC19B58FD1C226 /* ServerConfirmationScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F08776C48FFB47CACF64ED10 /* ServerConfirmationScreenViewModelTests.swift */; };
|
89658A44C9FC19B58FD1C226 /* ServerConfirmationScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F08776C48FFB47CACF64ED10 /* ServerConfirmationScreenViewModelTests.swift */; };
|
||||||
899793EFC63DF93C3E0141E7 /* RoomMemberDetailsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FA60F848D1C14F873F9621A /* RoomMemberDetailsScreenCoordinator.swift */; };
|
899793EFC63DF93C3E0141E7 /* RoomMemberDetailsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FA60F848D1C14F873F9621A /* RoomMemberDetailsScreenCoordinator.swift */; };
|
||||||
@@ -936,6 +938,7 @@
|
|||||||
A32384E3D85CA65342D3A908 /* TimelineMediaPreviewRedactConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C75FE3F524B575D53787868C /* TimelineMediaPreviewRedactConfirmationView.swift */; };
|
A32384E3D85CA65342D3A908 /* TimelineMediaPreviewRedactConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C75FE3F524B575D53787868C /* TimelineMediaPreviewRedactConfirmationView.swift */; };
|
||||||
A33784831AD880A670CAA9F9 /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */; };
|
A33784831AD880A670CAA9F9 /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */; };
|
||||||
A36AD251013402EDBD666C75 /* AppMediatorMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BAC027034248429A438886B /* AppMediatorMock.swift */; };
|
A36AD251013402EDBD666C75 /* AppMediatorMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BAC027034248429A438886B /* AppMediatorMock.swift */; };
|
||||||
|
A37BFB32EAB8AEF6DD5BA0DC /* LinkNewDeviceService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 007C16779FDCF10DA4F1A510 /* LinkNewDeviceService.swift */; };
|
||||||
A37EED79941AD3B7140B3822 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287FC98AF2664EAD79C0D902 /* UIDevice.swift */; };
|
A37EED79941AD3B7140B3822 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287FC98AF2664EAD79C0D902 /* UIDevice.swift */; };
|
||||||
A3A7A05E8F9B7EB0E1A09A2A /* SoftLogoutScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05596E4A11A8C9346E9E54AE /* SoftLogoutScreenCoordinator.swift */; };
|
A3A7A05E8F9B7EB0E1A09A2A /* SoftLogoutScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05596E4A11A8C9346E9E54AE /* SoftLogoutScreenCoordinator.swift */; };
|
||||||
A3D7110C1E75E7B4A73BE71C /* VoiceMessageRecorderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93C94C30E3135BC9290DE13 /* VoiceMessageRecorderTests.swift */; };
|
A3D7110C1E75E7B4A73BE71C /* VoiceMessageRecorderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93C94C30E3135BC9290DE13 /* VoiceMessageRecorderTests.swift */; };
|
||||||
@@ -1253,6 +1256,7 @@
|
|||||||
DFD5AA8688A34C72D48AF3B1 /* StaticLocationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5311C989EC15B4C2D699025 /* StaticLocationScreenViewModel.swift */; };
|
DFD5AA8688A34C72D48AF3B1 /* StaticLocationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5311C989EC15B4C2D699025 /* StaticLocationScreenViewModel.swift */; };
|
||||||
DFF7D6A6C26DDD40D00AE579 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = F012CB5EE3F2B67359F6CC52 /* target.yml */; };
|
DFF7D6A6C26DDD40D00AE579 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = F012CB5EE3F2B67359F6CC52 /* target.yml */; };
|
||||||
E010DDE938032D3B8E84CC35 /* TracingHook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A95C9B8299A36A6495DECA6 /* TracingHook.swift */; };
|
E010DDE938032D3B8E84CC35 /* TracingHook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A95C9B8299A36A6495DECA6 /* TracingHook.swift */; };
|
||||||
|
E02DAD9FD8D62587049FFFEC /* LinkNewDeviceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80F04B12FA231E797B7151A8 /* LinkNewDeviceTests.swift */; };
|
||||||
E0B6A569AC3E81D233B43D60 /* SettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E625B0EB2F86B37C14EF7E6 /* SettingsScreenViewModel.swift */; };
|
E0B6A569AC3E81D233B43D60 /* SettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E625B0EB2F86B37C14EF7E6 /* SettingsScreenViewModel.swift */; };
|
||||||
E0C167D41A48EDB30B447DE3 /* VoiceMessageRecordingComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73A5C3F7C9C1DA10CAEC6A98 /* VoiceMessageRecordingComposer.swift */; };
|
E0C167D41A48EDB30B447DE3 /* VoiceMessageRecordingComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73A5C3F7C9C1DA10CAEC6A98 /* VoiceMessageRecordingComposer.swift */; };
|
||||||
E14E469CD97550D0FC58F3CA /* CancellableTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE52983FAFB4E0998C00EE8A /* CancellableTask.swift */; };
|
E14E469CD97550D0FC58F3CA /* CancellableTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE52983FAFB4E0998C00EE8A /* CancellableTask.swift */; };
|
||||||
@@ -1526,6 +1530,7 @@
|
|||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
002399C6CB875C4EBB01CBC0 /* MediaEventsTimelineScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaEventsTimelineScreen.swift; sourceTree = "<group>"; };
|
002399C6CB875C4EBB01CBC0 /* MediaEventsTimelineScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaEventsTimelineScreen.swift; sourceTree = "<group>"; };
|
||||||
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>"; };
|
||||||
|
007C16779FDCF10DA4F1A510 /* LinkNewDeviceService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkNewDeviceService.swift; sourceTree = "<group>"; };
|
||||||
00AFC5F08734C2EA4EE79C59 /* IdentityConfirmationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreen.swift; sourceTree = "<group>"; };
|
00AFC5F08734C2EA4EE79C59 /* IdentityConfirmationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreen.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>"; };
|
||||||
011AFA4990C585D157829679 /* DeclineAndBlockScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeclineAndBlockScreenViewModel.swift; sourceTree = "<group>"; };
|
011AFA4990C585D157829679 /* DeclineAndBlockScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeclineAndBlockScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
@@ -1719,6 +1724,7 @@
|
|||||||
22730A30C50AC2E3D5BA8642 /* InviteUsersScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
22730A30C50AC2E3D5BA8642 /* InviteUsersScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
227AC5D71A4CE43512062243 /* URL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URL.swift; sourceTree = "<group>"; };
|
227AC5D71A4CE43512062243 /* URL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URL.swift; sourceTree = "<group>"; };
|
||||||
22DB19219E6CC4D002E15D48 /* GlobalSearchScreenCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalSearchScreenCell.swift; sourceTree = "<group>"; };
|
22DB19219E6CC4D002E15D48 /* GlobalSearchScreenCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalSearchScreenCell.swift; sourceTree = "<group>"; };
|
||||||
|
233D5F7E5E9F49ABF3413291 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = hr; path = hr.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
2355398E4A55DA5A89128AD1 /* EncryptionKeyProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionKeyProvider.swift; sourceTree = "<group>"; };
|
2355398E4A55DA5A89128AD1 /* EncryptionKeyProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionKeyProvider.swift; sourceTree = "<group>"; };
|
||||||
2363DB6162BBCC511B67B527 /* AccessibilityTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = AccessibilityTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
2363DB6162BBCC511B67B527 /* AccessibilityTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = AccessibilityTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
23674BF78CE814366EBD8762 /* cy */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cy; path = cy.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
23674BF78CE814366EBD8762 /* cy */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cy; path = cy.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
@@ -1985,6 +1991,7 @@
|
|||||||
5445FCE0CE15E634FDC1A2E2 /* AnalyticsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsService.swift; sourceTree = "<group>"; };
|
5445FCE0CE15E634FDC1A2E2 /* AnalyticsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsService.swift; sourceTree = "<group>"; };
|
||||||
5484457C81B325660901B161 /* AppLockSetupSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupSettingsScreen.swift; sourceTree = "<group>"; };
|
5484457C81B325660901B161 /* AppLockSetupSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupSettingsScreen.swift; sourceTree = "<group>"; };
|
||||||
54A5E6F398C269AD52C9AE21 /* EncryptionResetPasswordScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreenModels.swift; sourceTree = "<group>"; };
|
54A5E6F398C269AD52C9AE21 /* EncryptionResetPasswordScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreenModels.swift; sourceTree = "<group>"; };
|
||||||
|
54A7923F0115CF17ABC8047F /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/SAS.strings; sourceTree = "<group>"; };
|
||||||
54AD70D6E03D2031AE1B5A52 /* TimelineReactionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReactionsView.swift; sourceTree = "<group>"; };
|
54AD70D6E03D2031AE1B5A52 /* TimelineReactionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReactionsView.swift; sourceTree = "<group>"; };
|
||||||
54C4E7B46099462F12000C91 /* DeveloperOptionsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
54C4E7B46099462F12000C91 /* DeveloperOptionsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
5557DDA438841AF5DC003D0B /* SpaceListScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceListScreenViewModelTests.swift; sourceTree = "<group>"; };
|
5557DDA438841AF5DC003D0B /* SpaceListScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceListScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
@@ -2198,6 +2205,7 @@
|
|||||||
7FDF541AE914059942B575B4 /* IdentityConfirmationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenModels.swift; sourceTree = "<group>"; };
|
7FDF541AE914059942B575B4 /* IdentityConfirmationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenModels.swift; sourceTree = "<group>"; };
|
||||||
8063E65441E771200108C558 /* ReadReceiptsSummaryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadReceiptsSummaryView.swift; sourceTree = "<group>"; };
|
8063E65441E771200108C558 /* ReadReceiptsSummaryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadReceiptsSummaryView.swift; sourceTree = "<group>"; };
|
||||||
80E815FF3CC5E5A355E3A25E /* RoomMessageEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageEventStringBuilder.swift; sourceTree = "<group>"; };
|
80E815FF3CC5E5A355E3A25E /* RoomMessageEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageEventStringBuilder.swift; sourceTree = "<group>"; };
|
||||||
|
80F04B12FA231E797B7151A8 /* LinkNewDeviceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkNewDeviceTests.swift; sourceTree = "<group>"; };
|
||||||
810133CF215075C285FC6F3A /* test_image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = test_image.png; sourceTree = "<group>"; };
|
810133CF215075C285FC6F3A /* test_image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = test_image.png; sourceTree = "<group>"; };
|
||||||
8112846C9D9D3817689CBAF8 /* TimelineTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineTableViewController.swift; sourceTree = "<group>"; };
|
8112846C9D9D3817689CBAF8 /* TimelineTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineTableViewController.swift; sourceTree = "<group>"; };
|
||||||
811E8BF34E931D51552C9C13 /* EncryptionResetScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetScreen.swift; sourceTree = "<group>"; };
|
811E8BF34E931D51552C9C13 /* EncryptionResetScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetScreen.swift; sourceTree = "<group>"; };
|
||||||
@@ -2317,6 +2325,7 @@
|
|||||||
94028A227645FA880B966211 /* WaveformSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaveformSource.swift; sourceTree = "<group>"; };
|
94028A227645FA880B966211 /* WaveformSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaveformSource.swift; sourceTree = "<group>"; };
|
||||||
9475FD81B13D50103E5290EB /* SpaceSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceSettingsScreen.swift; sourceTree = "<group>"; };
|
9475FD81B13D50103E5290EB /* SpaceSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceSettingsScreen.swift; sourceTree = "<group>"; };
|
||||||
94D670124FC3E84F23A62CCF /* APNSPayload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APNSPayload.swift; sourceTree = "<group>"; };
|
94D670124FC3E84F23A62CCF /* APNSPayload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APNSPayload.swift; sourceTree = "<group>"; };
|
||||||
|
94EE2C5F0A06F146BBE3A1B1 /* LinkNewDeviceFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkNewDeviceFlowCoordinator.swift; sourceTree = "<group>"; };
|
||||||
9501D11B4258DFA33BA3B40F /* ServerSelectionScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreenModels.swift; sourceTree = "<group>"; };
|
9501D11B4258DFA33BA3B40F /* ServerSelectionScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreenModels.swift; sourceTree = "<group>"; };
|
||||||
951F277E0585E50AC91987C8 /* DeclineAndBlockScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeclineAndBlockScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
951F277E0585E50AC91987C8 /* DeclineAndBlockScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeclineAndBlockScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
955336CBD5ED73C792D1F580 /* EncryptionAuthenticity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionAuthenticity.swift; sourceTree = "<group>"; };
|
955336CBD5ED73C792D1F580 /* EncryptionAuthenticity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionAuthenticity.swift; sourceTree = "<group>"; };
|
||||||
@@ -2389,6 +2398,7 @@
|
|||||||
A1C22B1B5FA3A765EADB2CC9 /* SessionVerificationStateMachineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationStateMachineTests.swift; sourceTree = "<group>"; };
|
A1C22B1B5FA3A765EADB2CC9 /* SessionVerificationStateMachineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationStateMachineTests.swift; sourceTree = "<group>"; };
|
||||||
A232D9156D225BD9FD1D0C43 /* PhotoLibraryPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryPicker.swift; sourceTree = "<group>"; };
|
A232D9156D225BD9FD1D0C43 /* PhotoLibraryPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryPicker.swift; sourceTree = "<group>"; };
|
||||||
A243A6E6207297123E60DE48 /* TimelineItemMacContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemMacContextMenu.swift; sourceTree = "<group>"; };
|
A243A6E6207297123E60DE48 /* TimelineItemMacContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemMacContextMenu.swift; sourceTree = "<group>"; };
|
||||||
|
A2723A4AF3AB9F5E18D26E49 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
A3B4B58B79A6FA250B24A1EC /* HomeScreenContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenContent.swift; sourceTree = "<group>"; };
|
A3B4B58B79A6FA250B24A1EC /* HomeScreenContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenContent.swift; sourceTree = "<group>"; };
|
||||||
A3FBD9C2B9A5479526920399 /* BugReportScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenCoordinator.swift; sourceTree = "<group>"; };
|
A3FBD9C2B9A5479526920399 /* BugReportScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
A40C19719687984FD9478FBE /* Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = "<group>"; };
|
A40C19719687984FD9478FBE /* Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = "<group>"; };
|
||||||
@@ -2668,6 +2678,7 @@
|
|||||||
D653265D006E708E4E51AD64 /* HomeScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenCoordinator.swift; sourceTree = "<group>"; };
|
D653265D006E708E4E51AD64 /* HomeScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
D66B5D86A9AB95E0E01BED82 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
D66B5D86A9AB95E0E01BED82 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
D67CBAFA48ED0B6FCE74F88F /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = lt.lproj/Localizable.strings; sourceTree = "<group>"; };
|
D67CBAFA48ED0B6FCE74F88F /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = lt.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
D6D094C15E8DB424F1C6FC94 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
D6DC38E64A5ED3FDB201029A /* BugReportService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportService.swift; sourceTree = "<group>"; };
|
D6DC38E64A5ED3FDB201029A /* BugReportService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportService.swift; sourceTree = "<group>"; };
|
||||||
D7149BDDE47F8AD104E644E2 /* TraceLogPack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TraceLogPack.swift; sourceTree = "<group>"; };
|
D7149BDDE47F8AD104E644E2 /* TraceLogPack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TraceLogPack.swift; sourceTree = "<group>"; };
|
||||||
D751AA05AD2182BFC4608DE6 /* ur */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ur; path = ur.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
D751AA05AD2182BFC4608DE6 /* ur */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ur; path = ur.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
@@ -2864,6 +2875,7 @@
|
|||||||
FB9EABCA9348DFA27439A809 /* WaveformCursorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaveformCursorView.swift; sourceTree = "<group>"; };
|
FB9EABCA9348DFA27439A809 /* WaveformCursorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaveformCursorView.swift; sourceTree = "<group>"; };
|
||||||
FBB0328F2887BF0A65BC5D49 /* NotificationSettingsEditScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsEditScreen.swift; sourceTree = "<group>"; };
|
FBB0328F2887BF0A65BC5D49 /* NotificationSettingsEditScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsEditScreen.swift; sourceTree = "<group>"; };
|
||||||
FBC776F301D374A3298C69DA /* AppCoordinatorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinatorProtocol.swift; sourceTree = "<group>"; };
|
FBC776F301D374A3298C69DA /* AppCoordinatorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinatorProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
FBD288168C48D3F76177FCBF /* GrantLoginWithQrCodeHandlerSDKMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GrantLoginWithQrCodeHandlerSDKMock.swift; sourceTree = "<group>"; };
|
||||||
FC3797A2325BE44FFB478BE9 /* LeaveSpaceRoomDetailsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeaveSpaceRoomDetailsCell.swift; sourceTree = "<group>"; };
|
FC3797A2325BE44FFB478BE9 /* LeaveSpaceRoomDetailsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeaveSpaceRoomDetailsCell.swift; sourceTree = "<group>"; };
|
||||||
FC83F47D2173B7538AA72E0E /* RoomSummaryProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProviderMock.swift; sourceTree = "<group>"; };
|
FC83F47D2173B7538AA72E0E /* RoomSummaryProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProviderMock.swift; sourceTree = "<group>"; };
|
||||||
FC9044BE0E4A66F5B963E834 /* AudioFileEventsTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioFileEventsTimelineView.swift; sourceTree = "<group>"; };
|
FC9044BE0E4A66F5B963E834 /* AudioFileEventsTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioFileEventsTimelineView.swift; sourceTree = "<group>"; };
|
||||||
@@ -4360,6 +4372,7 @@
|
|||||||
566FB9DA81607C2739D8C6A0 /* ChatsFlowCoordinatorStateMachine.swift */,
|
566FB9DA81607C2739D8C6A0 /* ChatsFlowCoordinatorStateMachine.swift */,
|
||||||
A07B011547B201A836C03052 /* EncryptionResetFlowCoordinator.swift */,
|
A07B011547B201A836C03052 /* EncryptionResetFlowCoordinator.swift */,
|
||||||
ECB836DD8BE31931F51B8AC9 /* EncryptionSettingsFlowCoordinator.swift */,
|
ECB836DD8BE31931F51B8AC9 /* EncryptionSettingsFlowCoordinator.swift */,
|
||||||
|
94EE2C5F0A06F146BBE3A1B1 /* LinkNewDeviceFlowCoordinator.swift */,
|
||||||
2178B951602AA921A5FD9DC8 /* MediaEventsTimelineFlowCoordinator.swift */,
|
2178B951602AA921A5FD9DC8 /* MediaEventsTimelineFlowCoordinator.swift */,
|
||||||
C3285BD95B564CA2A948E511 /* OnboardingFlowCoordinator.swift */,
|
C3285BD95B564CA2A948E511 /* OnboardingFlowCoordinator.swift */,
|
||||||
A54AAF72E821B4084B7E4298 /* PinnedEventsTimelineFlowCoordinator.swift */,
|
A54AAF72E821B4084B7E4298 /* PinnedEventsTimelineFlowCoordinator.swift */,
|
||||||
@@ -5340,6 +5353,7 @@
|
|||||||
27DF257F5D968E5DD719583C /* BugReportTests.swift */,
|
27DF257F5D968E5DD719583C /* BugReportTests.swift */,
|
||||||
89BB11A792EF6F70B95B467E /* EncryptionResetTests.swift */,
|
89BB11A792EF6F70B95B467E /* EncryptionResetTests.swift */,
|
||||||
57AD14D3ADADE8F6A10F9E88 /* EncryptionSettingsTests.swift */,
|
57AD14D3ADADE8F6A10F9E88 /* EncryptionSettingsTests.swift */,
|
||||||
|
80F04B12FA231E797B7151A8 /* LinkNewDeviceTests.swift */,
|
||||||
DCDAB580109C09A6AA97AF7E /* PollFormScreenTests.swift */,
|
DCDAB580109C09A6AA97AF7E /* PollFormScreenTests.swift */,
|
||||||
E2520C4F33AA0C061D209C28 /* RoomMembersListScreenTests.swift */,
|
E2520C4F33AA0C061D209C28 /* RoomMembersListScreenTests.swift */,
|
||||||
44DDC82DB6A84E700CD5DEC0 /* RoomRolesAndPermissionsTests.swift */,
|
44DDC82DB6A84E700CD5DEC0 /* RoomRolesAndPermissionsTests.swift */,
|
||||||
@@ -5683,6 +5697,7 @@
|
|||||||
EBD19057FDB154A44335CE62 /* AuthenticationClientFactory.swift */,
|
EBD19057FDB154A44335CE62 /* AuthenticationClientFactory.swift */,
|
||||||
F3A1AB5A84D843B6AC8D5F1E /* AuthenticationService.swift */,
|
F3A1AB5A84D843B6AC8D5F1E /* AuthenticationService.swift */,
|
||||||
5E75948AA1FE1D1A7809931F /* AuthenticationServiceProtocol.swift */,
|
5E75948AA1FE1D1A7809931F /* AuthenticationServiceProtocol.swift */,
|
||||||
|
007C16779FDCF10DA4F1A510 /* LinkNewDeviceService.swift */,
|
||||||
);
|
);
|
||||||
path = Authentication;
|
path = Authentication;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -6380,6 +6395,7 @@
|
|||||||
children = (
|
children = (
|
||||||
8EAF4A49F3ACD8BB8B0D2371 /* ClientSDKMock.swift */,
|
8EAF4A49F3ACD8BB8B0D2371 /* ClientSDKMock.swift */,
|
||||||
0A81FD0C60175FA081EB19AD /* EventTimelineItem.swift */,
|
0A81FD0C60175FA081EB19AD /* EventTimelineItem.swift */,
|
||||||
|
FBD288168C48D3F76177FCBF /* GrantLoginWithQrCodeHandlerSDKMock.swift */,
|
||||||
5EFB1D29B0870AFB6A56E9B8 /* IdentityResetHandleSDKMock.swift */,
|
5EFB1D29B0870AFB6A56E9B8 /* IdentityResetHandleSDKMock.swift */,
|
||||||
580BDCD23DD02481AB5FFB47 /* LeaveSpaceHandleSDKMock.swift */,
|
580BDCD23DD02481AB5FFB47 /* LeaveSpaceHandleSDKMock.swift */,
|
||||||
);
|
);
|
||||||
@@ -7025,6 +7041,7 @@
|
|||||||
fa,
|
fa,
|
||||||
fi,
|
fi,
|
||||||
fr,
|
fr,
|
||||||
|
hr,
|
||||||
hu,
|
hu,
|
||||||
id,
|
id,
|
||||||
it,
|
it,
|
||||||
@@ -7932,6 +7949,7 @@
|
|||||||
D34E328E9E65904358248FDD /* GlobalSearchScreenModels.swift in Sources */,
|
D34E328E9E65904358248FDD /* GlobalSearchScreenModels.swift in Sources */,
|
||||||
55D18AA4F4A2257642EBDB94 /* GlobalSearchScreenViewModel.swift in Sources */,
|
55D18AA4F4A2257642EBDB94 /* GlobalSearchScreenViewModel.swift in Sources */,
|
||||||
E32A18802EB37EEE3EF7B965 /* GlobalSearchScreenViewModelProtocol.swift in Sources */,
|
E32A18802EB37EEE3EF7B965 /* GlobalSearchScreenViewModelProtocol.swift in Sources */,
|
||||||
|
89261D215E4A432E887CD156 /* GrantLoginWithQrCodeHandlerSDKMock.swift in Sources */,
|
||||||
F3C9CAD26FD4D7D6EBACF501 /* HTMLFixtures.swift in Sources */,
|
F3C9CAD26FD4D7D6EBACF501 /* HTMLFixtures.swift in Sources */,
|
||||||
E8C4D9F93F0DCED211D5F187 /* HTMLParserStyle.swift in Sources */,
|
E8C4D9F93F0DCED211D5F187 /* HTMLParserStyle.swift in Sources */,
|
||||||
0C1E537A49ABB386F7554D4A /* HighlightedTimelineItemModifier.swift in Sources */,
|
0C1E537A49ABB386F7554D4A /* HighlightedTimelineItemModifier.swift in Sources */,
|
||||||
@@ -8024,11 +8042,13 @@
|
|||||||
A9D349478F7D4A2B1E40CEF9 /* LegalInformationScreenViewModelProtocol.swift in Sources */,
|
A9D349478F7D4A2B1E40CEF9 /* LegalInformationScreenViewModelProtocol.swift in Sources */,
|
||||||
5E597B9959BDAE7A67DBD5B2 /* LinkMetadataProvider.swift in Sources */,
|
5E597B9959BDAE7A67DBD5B2 /* LinkMetadataProvider.swift in Sources */,
|
||||||
112C6F1C493B3F26AB22716A /* LinkMetadataProviderProtocol.swift in Sources */,
|
112C6F1C493B3F26AB22716A /* LinkMetadataProviderProtocol.swift in Sources */,
|
||||||
|
012D9DDCDE6278E4E0CDCC0F /* LinkNewDeviceFlowCoordinator.swift in Sources */,
|
||||||
DE3BF0ED68E56BF625591D49 /* LinkNewDeviceScreen.swift in Sources */,
|
DE3BF0ED68E56BF625591D49 /* LinkNewDeviceScreen.swift in Sources */,
|
||||||
B466827F3766FF8E0CD0D34F /* LinkNewDeviceScreenCoordinator.swift in Sources */,
|
B466827F3766FF8E0CD0D34F /* LinkNewDeviceScreenCoordinator.swift in Sources */,
|
||||||
69B9CC733A880E1BB097C113 /* LinkNewDeviceScreenModels.swift in Sources */,
|
69B9CC733A880E1BB097C113 /* LinkNewDeviceScreenModels.swift in Sources */,
|
||||||
C16E25C41B858BF27E0C4FC6 /* LinkNewDeviceScreenViewModel.swift in Sources */,
|
C16E25C41B858BF27E0C4FC6 /* LinkNewDeviceScreenViewModel.swift in Sources */,
|
||||||
92FE657CDFAFE3031576EB43 /* LinkNewDeviceScreenViewModelProtocol.swift in Sources */,
|
92FE657CDFAFE3031576EB43 /* LinkNewDeviceScreenViewModelProtocol.swift in Sources */,
|
||||||
|
A37BFB32EAB8AEF6DD5BA0DC /* LinkNewDeviceService.swift in Sources */,
|
||||||
866FA35E7A2339EF8B6D91CA /* LinkPreviewView.swift in Sources */,
|
866FA35E7A2339EF8B6D91CA /* LinkPreviewView.swift in Sources */,
|
||||||
6E47D126DD7585E8F8237CE7 /* LoadableAvatarImage.swift in Sources */,
|
6E47D126DD7585E8F8237CE7 /* LoadableAvatarImage.swift in Sources */,
|
||||||
D9F80CE61BF8FF627FDB0543 /* LoadableImage.swift in Sources */,
|
D9F80CE61BF8FF627FDB0543 /* LoadableImage.swift in Sources */,
|
||||||
@@ -8670,6 +8690,7 @@
|
|||||||
94D0F36A87E596A93C0C178A /* Bundle.swift in Sources */,
|
94D0F36A87E596A93C0C178A /* Bundle.swift in Sources */,
|
||||||
8D24671992A1C1753B211221 /* EncryptionResetTests.swift in Sources */,
|
8D24671992A1C1753B211221 /* EncryptionResetTests.swift in Sources */,
|
||||||
E5E43A0CA99AF5BA11B194A2 /* EncryptionSettingsTests.swift in Sources */,
|
E5E43A0CA99AF5BA11B194A2 /* EncryptionSettingsTests.swift in Sources */,
|
||||||
|
E02DAD9FD8D62587049FFFEC /* LinkNewDeviceTests.swift in Sources */,
|
||||||
A950C95855C474F75B30CA7B /* PollFormScreenTests.swift in Sources */,
|
A950C95855C474F75B30CA7B /* PollFormScreenTests.swift in Sources */,
|
||||||
B5BCE012F9E7C45D1C76108E /* RoomMembersListScreenTests.swift in Sources */,
|
B5BCE012F9E7C45D1C76108E /* RoomMembersListScreenTests.swift in Sources */,
|
||||||
DBC3FDE1540B39702A117D8E /* RoomRolesAndPermissionsTests.swift in Sources */,
|
DBC3FDE1540B39702A117D8E /* RoomRolesAndPermissionsTests.swift in Sources */,
|
||||||
@@ -8751,6 +8772,7 @@
|
|||||||
C715CFE00686DACA59D836EA /* fa */,
|
C715CFE00686DACA59D836EA /* fa */,
|
||||||
A9E88667D393612FD5D84718 /* fi */,
|
A9E88667D393612FD5D84718 /* fi */,
|
||||||
CEE20623EB4A9B88FB29F2BA /* fr */,
|
CEE20623EB4A9B88FB29F2BA /* fr */,
|
||||||
|
54A7923F0115CF17ABC8047F /* hr */,
|
||||||
D196116D2DD3F2757D45FCB7 /* hu */,
|
D196116D2DD3F2757D45FCB7 /* hu */,
|
||||||
330AF4D121C3396F7A14B21D /* id */,
|
330AF4D121C3396F7A14B21D /* id */,
|
||||||
61B33F23681660E940BA57F4 /* it */,
|
61B33F23681660E940BA57F4 /* it */,
|
||||||
@@ -8783,6 +8805,7 @@
|
|||||||
48CE6BF18E542B32FA52CE06 /* fa */,
|
48CE6BF18E542B32FA52CE06 /* fa */,
|
||||||
057B747CF045D3C6C30EAB2C /* fi */,
|
057B747CF045D3C6C30EAB2C /* fi */,
|
||||||
653610CB5F9776EAAAB98155 /* fr */,
|
653610CB5F9776EAAAB98155 /* fr */,
|
||||||
|
233D5F7E5E9F49ABF3413291 /* hr */,
|
||||||
C95ADE8D9527523572532219 /* hu */,
|
C95ADE8D9527523572532219 /* hu */,
|
||||||
475D47D0BFE961B02BAC5D49 /* id */,
|
475D47D0BFE961B02BAC5D49 /* id */,
|
||||||
6FC5015B9634698BDB8701AF /* it */,
|
6FC5015B9634698BDB8701AF /* it */,
|
||||||
@@ -8826,6 +8849,7 @@
|
|||||||
A9873374E72AA53260AE90A2 /* fa */,
|
A9873374E72AA53260AE90A2 /* fa */,
|
||||||
434522ED2BDED08759048077 /* fi */,
|
434522ED2BDED08759048077 /* fi */,
|
||||||
CC680E0E79D818706CB28CF8 /* fr */,
|
CC680E0E79D818706CB28CF8 /* fr */,
|
||||||
|
D6D094C15E8DB424F1C6FC94 /* hr */,
|
||||||
624244C398804ADC885239AA /* hu */,
|
624244C398804ADC885239AA /* hu */,
|
||||||
EF98A02DED04075F7CF0C721 /* id */,
|
EF98A02DED04075F7CF0C721 /* id */,
|
||||||
7B04BD3874D736127A8156B8 /* it */,
|
7B04BD3874D736127A8156B8 /* it */,
|
||||||
@@ -8867,6 +8891,7 @@
|
|||||||
70F8DAEF1A8131BDFD4CDE83 /* eu */,
|
70F8DAEF1A8131BDFD4CDE83 /* eu */,
|
||||||
24E637CF570711FB5FD63DEA /* fi */,
|
24E637CF570711FB5FD63DEA /* fi */,
|
||||||
ACD7BD6BEE21264F6677904A /* fr */,
|
ACD7BD6BEE21264F6677904A /* fr */,
|
||||||
|
A2723A4AF3AB9F5E18D26E49 /* hr */,
|
||||||
1D652E78832289CD9EB64488 /* hu */,
|
1D652E78832289CD9EB64488 /* hu */,
|
||||||
7199693797B66245EF97BCF5 /* id */,
|
7199693797B66245EF97BCF5 /* id */,
|
||||||
44C314C00533E2C297796B60 /* it */,
|
44C314C00533E2C297796B60 /* it */,
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2025 Element Creations Ltd.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
// Please see LICENSE files in the repository root for full details.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum LinkNewDeviceFlowCoordinatorAction {
|
||||||
|
case requestOIDCAuthorisation(URL)
|
||||||
|
case dismiss
|
||||||
|
}
|
||||||
|
|
||||||
|
class LinkNewDeviceFlowCoordinator: FlowCoordinatorProtocol {
|
||||||
|
private let navigationStackCoordinator: NavigationStackCoordinator
|
||||||
|
private let flowParameters: CommonFlowParameters
|
||||||
|
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
private let actionsSubject: PassthroughSubject<LinkNewDeviceFlowCoordinatorAction, Never> = .init()
|
||||||
|
var actionsPublisher: AnyPublisher<LinkNewDeviceFlowCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
init(navigationStackCoordinator: NavigationStackCoordinator,
|
||||||
|
flowParameters: CommonFlowParameters) {
|
||||||
|
self.navigationStackCoordinator = navigationStackCoordinator
|
||||||
|
self.flowParameters = flowParameters
|
||||||
|
}
|
||||||
|
|
||||||
|
func start(animated: Bool) {
|
||||||
|
presentLinkNewDeviceScreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleAppRoute(_ appRoute: AppRoute, animated: Bool) {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
|
||||||
|
func clearRoute(animated: Bool) {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func presentLinkNewDeviceScreen() {
|
||||||
|
let coordinator = LinkNewDeviceScreenCoordinator(parameters: .init(clientProxy: flowParameters.userSession.clientProxy))
|
||||||
|
coordinator.actionsPublisher
|
||||||
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
|
|
||||||
|
switch action {
|
||||||
|
case .linkMobileDevice(let progressPublisher):
|
||||||
|
break
|
||||||
|
case .linkDesktopComputer:
|
||||||
|
break
|
||||||
|
case .dismiss:
|
||||||
|
actionsSubject.send(.dismiss)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,8 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
private var bugReportFlowCoordinator: BugReportFlowCoordinator?
|
private var bugReportFlowCoordinator: BugReportFlowCoordinator?
|
||||||
// periphery:ignore - retaining purpose
|
// periphery:ignore - retaining purpose
|
||||||
private var encryptionSettingsFlowCoordinator: EncryptionSettingsFlowCoordinator?
|
private var encryptionSettingsFlowCoordinator: EncryptionSettingsFlowCoordinator?
|
||||||
|
// periphery:ignore - retaining purpose
|
||||||
|
private var linkNewDeviceFlowCoordinator: LinkNewDeviceFlowCoordinator?
|
||||||
|
|
||||||
private var cancellables = Set<AnyCancellable>()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
@@ -84,7 +86,7 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
case .userDetails:
|
case .userDetails:
|
||||||
presentUserDetailsEditScreen()
|
presentUserDetailsEditScreen()
|
||||||
case .linkNewDevice:
|
case .linkNewDevice:
|
||||||
presentLinkNewDeviceScreen()
|
startLinkNewDeviceFlow()
|
||||||
case let .manageAccount(url):
|
case let .manageAccount(url):
|
||||||
presentAccountManagementURL(url)
|
presentAccountManagementURL(url)
|
||||||
case .analytics:
|
case .analytics:
|
||||||
@@ -169,6 +171,31 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
navigationStackCoordinator.push(coordinator)
|
navigationStackCoordinator.push(coordinator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func startLinkNewDeviceFlow() {
|
||||||
|
let stackCoordinator = NavigationStackCoordinator()
|
||||||
|
let flowCoordinator = LinkNewDeviceFlowCoordinator(navigationStackCoordinator: stackCoordinator,
|
||||||
|
flowParameters: flowParameters)
|
||||||
|
flowCoordinator.actionsPublisher
|
||||||
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
|
|
||||||
|
switch action {
|
||||||
|
case .dismiss:
|
||||||
|
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||||
|
case .requestOIDCAuthorisation(let url):
|
||||||
|
presentAccountManagementURL(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
linkNewDeviceFlowCoordinator = flowCoordinator
|
||||||
|
flowCoordinator.start()
|
||||||
|
|
||||||
|
navigationStackCoordinator.setSheetCoordinator(stackCoordinator) { [weak self] in
|
||||||
|
self?.linkNewDeviceFlowCoordinator = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func presentAnalyticsScreen() {
|
private func presentAnalyticsScreen() {
|
||||||
let coordinator = AnalyticsSettingsScreenCoordinator(parameters: .init(appSettings: flowParameters.appSettings,
|
let coordinator = AnalyticsSettingsScreenCoordinator(parameters: .init(appSettings: flowParameters.appSettings,
|
||||||
analytics: flowParameters.analytics))
|
analytics: flowParameters.analytics))
|
||||||
@@ -271,27 +298,4 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
appSettings: flowParameters.appSettings)
|
appSettings: flowParameters.appSettings)
|
||||||
accountSettingsPresenter?.start()
|
accountSettingsPresenter?.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Link New Device
|
|
||||||
|
|
||||||
private func presentLinkNewDeviceScreen() {
|
|
||||||
let parameters = LinkNewDeviceScreenCoordinatorParameters(clientProxy: flowParameters.userSession.clientProxy)
|
|
||||||
let coordinator = LinkNewDeviceScreenCoordinator(parameters: parameters)
|
|
||||||
coordinator.actionsPublisher
|
|
||||||
.sink { [weak self] action in
|
|
||||||
guard let self else { return }
|
|
||||||
|
|
||||||
switch action {
|
|
||||||
case .linkMobileDevice:
|
|
||||||
break
|
|
||||||
case .linkDesktopComputer:
|
|
||||||
break
|
|
||||||
case .dismiss:
|
|
||||||
navigationStackCoordinator.pop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
navigationStackCoordinator.push(coordinator)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4019,6 +4019,70 @@ class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable {
|
|||||||
return removeUserAvatarReturnValue
|
return removeUserAvatarReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//MARK: - linkNewDeviceService
|
||||||
|
|
||||||
|
var linkNewDeviceServiceUnderlyingCallsCount = 0
|
||||||
|
var linkNewDeviceServiceCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return linkNewDeviceServiceUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = linkNewDeviceServiceUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
linkNewDeviceServiceUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
linkNewDeviceServiceUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var linkNewDeviceServiceCalled: Bool {
|
||||||
|
return linkNewDeviceServiceCallsCount > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var linkNewDeviceServiceUnderlyingReturnValue: LinkNewDeviceService!
|
||||||
|
var linkNewDeviceServiceReturnValue: LinkNewDeviceService! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return linkNewDeviceServiceUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: LinkNewDeviceService? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = linkNewDeviceServiceUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
linkNewDeviceServiceUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
linkNewDeviceServiceUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var linkNewDeviceServiceClosure: (() -> LinkNewDeviceService)?
|
||||||
|
|
||||||
|
func linkNewDeviceService() -> LinkNewDeviceService {
|
||||||
|
linkNewDeviceServiceCallsCount += 1
|
||||||
|
if let linkNewDeviceServiceClosure = linkNewDeviceServiceClosure {
|
||||||
|
return linkNewDeviceServiceClosure()
|
||||||
|
} else {
|
||||||
|
return linkNewDeviceServiceReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
//MARK: - deactivateAccount
|
//MARK: - deactivateAccount
|
||||||
|
|
||||||
var deactivateAccountPasswordEraseDataUnderlyingCallsCount = 0
|
var deactivateAccountPasswordEraseDataUnderlyingCallsCount = 0
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2025 Element Creations Ltd.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
// Please see LICENSE files in the repository root for full details.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import MatrixRustSDK
|
||||||
|
|
||||||
|
extension GrantLoginWithQrCodeHandlerSDKMock {
|
||||||
|
struct Configuration {
|
||||||
|
var generateDelay: Duration = .seconds(0)
|
||||||
|
var generatedBase64QRCode = """
|
||||||
|
TUFUUklYAgS0yzZ1QVpQ1jlnoxWX3d5jrWRFfELxjS2gN7pz9y+3PABaaHR0
|
||||||
|
cHM6Ly9zeW5hcHNlLW9pZGMubGFiLmVsZW1lbnQuZGV2L19zeW5hcHNlL2Ns
|
||||||
|
aWVudC9yZW5kZXp2b3VzLzAxSFg5SzAwUTFINktQRDQ3RUc0RzFUM1hHACVo
|
||||||
|
dHRwczovL3N5bmFwc2Utb2lkYy5sYWIuZWxlbWVudC5kZXYv
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
|
||||||
|
convenience init(_ configuration: Configuration) {
|
||||||
|
self.init()
|
||||||
|
|
||||||
|
generateProgressListenerClosure = { listener in
|
||||||
|
Task {
|
||||||
|
try await Task.sleep(for: configuration.generateDelay)
|
||||||
|
let bytes = Data(base64Encoded: configuration.generatedBase64QRCode) ?? Data()
|
||||||
|
try listener.onUpdate(state: .qrReady(qrCode: .fromBytes(bytes: bytes)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,6 +45,7 @@ enum A11yIdentifiers {
|
|||||||
static let roomPollsHistoryScreen = RoomPollsHistoryScreen()
|
static let roomPollsHistoryScreen = RoomPollsHistoryScreen()
|
||||||
static let manageRoomMemberSheet = ManageRoomMemberSheet()
|
static let manageRoomMemberSheet = ManageRoomMemberSheet()
|
||||||
static let spaceListScreen = SpaceListScreen()
|
static let spaceListScreen = SpaceListScreen()
|
||||||
|
static let linkNewDeviceScreen = LinkNewDeviceScreen()
|
||||||
|
|
||||||
struct AlertInfo {
|
struct AlertInfo {
|
||||||
let primaryButton = "alert_info-primary_button"
|
let primaryButton = "alert_info-primary_button"
|
||||||
@@ -314,4 +315,10 @@ enum A11yIdentifiers {
|
|||||||
"\(roomNamePrefix):\(name)"
|
"\(roomNamePrefix):\(name)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct LinkNewDeviceScreen {
|
||||||
|
let cancel = "link_new_device_screen-cancel"
|
||||||
|
let mobileDevice = "link_new_device_screen-mobile_device"
|
||||||
|
let desktopComputer = "link_new_device_screen-desktop_computer"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,14 @@ extension SDKListener: QrLoginProgressListener where T == QrLoginProgress {
|
|||||||
func onUpdate(state: QrLoginProgress) { onUpdateClosure(state) }
|
func onUpdate(state: QrLoginProgress) { onUpdateClosure(state) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension SDKListener: GrantQrLoginProgressListener where T == GrantQrLoginProgress {
|
||||||
|
func onUpdate(state: GrantQrLoginProgress) { onUpdateClosure(state) }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SDKListener: GrantGeneratedQrLoginProgressListener where T == GrantGeneratedQrLoginProgress {
|
||||||
|
func onUpdate(state: GrantGeneratedQrLoginProgress) { onUpdateClosure(state) }
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: ClientProxy
|
// MARK: ClientProxy
|
||||||
|
|
||||||
extension SDKListener: MediaPreviewConfigListener where T == MediaPreviewConfig? {
|
extension SDKListener: MediaPreviewConfigListener where T == MediaPreviewConfig? {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import Combine
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
enum LinkNewDeviceScreenCoordinatorAction {
|
enum LinkNewDeviceScreenCoordinatorAction {
|
||||||
case linkMobileDevice
|
case linkMobileDevice(LinkNewDeviceService.GenerateProgressPublisher)
|
||||||
case linkDesktopComputer
|
case linkDesktopComputer
|
||||||
case dismiss
|
case dismiss
|
||||||
}
|
}
|
||||||
@@ -38,8 +38,8 @@ final class LinkNewDeviceScreenCoordinator: CoordinatorProtocol {
|
|||||||
|
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
switch action {
|
switch action {
|
||||||
case .linkMobileDevice:
|
case .linkMobileDevice(let progressPublisher):
|
||||||
actionsSubject.send(.linkMobileDevice)
|
actionsSubject.send(.linkMobileDevice(progressPublisher))
|
||||||
case .linkDesktopComputer:
|
case .linkDesktopComputer:
|
||||||
actionsSubject.send(.linkDesktopComputer)
|
actionsSubject.send(.linkDesktopComputer)
|
||||||
case .dismiss:
|
case .dismiss:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum LinkNewDeviceScreenViewModelAction {
|
enum LinkNewDeviceScreenViewModelAction {
|
||||||
case linkMobileDevice
|
case linkMobileDevice(LinkNewDeviceService.GenerateProgressPublisher)
|
||||||
case linkDesktopComputer
|
case linkDesktopComputer
|
||||||
case dismiss
|
case dismiss
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Combine
|
import Combine
|
||||||
|
import MatrixRustSDK
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
typealias LinkNewDeviceScreenViewModelType = StateStoreViewModelV2<LinkNewDeviceScreenViewState, LinkNewDeviceScreenViewAction>
|
typealias LinkNewDeviceScreenViewModelType = StateStoreViewModelV2<LinkNewDeviceScreenViewState, LinkNewDeviceScreenViewAction>
|
||||||
@@ -33,7 +34,7 @@ class LinkNewDeviceScreenViewModel: LinkNewDeviceScreenViewModelType, LinkNewDev
|
|||||||
|
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .linkMobileDevice:
|
case .linkMobileDevice:
|
||||||
linkMobileDevice()
|
Task { await linkMobileDevice() }
|
||||||
case .linkDesktopComputer:
|
case .linkDesktopComputer:
|
||||||
actionsSubject.send(.linkDesktopComputer)
|
actionsSubject.send(.linkDesktopComputer)
|
||||||
case .dismiss:
|
case .dismiss:
|
||||||
@@ -51,11 +52,27 @@ class LinkNewDeviceScreenViewModel: LinkNewDeviceScreenViewModelType, LinkNewDev
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func linkMobileDevice() {
|
private func linkMobileDevice() async {
|
||||||
state.mode = .readyToLink(isGeneratingCode: true)
|
state.mode = .readyToLink(isGeneratingCode: true)
|
||||||
|
|
||||||
// TODO: Generate a QR code.
|
let linkNewDeviceService = clientProxy.linkNewDeviceService()
|
||||||
|
|
||||||
actionsSubject.send(.linkMobileDevice)
|
let progressPublisher = linkNewDeviceService.generateQRCode()
|
||||||
|
|
||||||
|
do {
|
||||||
|
_ = try await progressPublisher.values
|
||||||
|
.first { progress in
|
||||||
|
switch progress {
|
||||||
|
case .qrReady: true
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actionsSubject.send(.linkMobileDevice(progressPublisher))
|
||||||
|
state.mode = .readyToLink(isGeneratingCode: false)
|
||||||
|
} catch {
|
||||||
|
#warning("Needs some form of re-usable error handling, will handle with the next screen.")
|
||||||
|
state.mode = .notSupported
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ struct LinkNewDeviceScreen: View {
|
|||||||
.backgroundStyle(.compound.bgSubtleSecondary)
|
.backgroundStyle(.compound.bgSubtleSecondary)
|
||||||
.navigationTitle(L10n.commonLinkNewDevice)
|
.navigationTitle(L10n.commonLinkNewDevice)
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
.toolbar { toolbar }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
@@ -86,11 +87,13 @@ struct LinkNewDeviceScreen: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.buttonStyle(.compound(.primary))
|
.buttonStyle(.compound(.primary))
|
||||||
|
.accessibilityIdentifier(A11yIdentifiers.linkNewDeviceScreen.mobileDevice)
|
||||||
|
|
||||||
Button { context.send(viewAction: .linkDesktopComputer) } label: {
|
Button { context.send(viewAction: .linkDesktopComputer) } label: {
|
||||||
Label(L10n.screenLinkNewDeviceRootDesktopComputer, icon: \.computer)
|
Label(L10n.screenLinkNewDeviceRootDesktopComputer, icon: \.computer)
|
||||||
}
|
}
|
||||||
.buttonStyle(.compound(.primary))
|
.buttonStyle(.compound(.primary))
|
||||||
|
.accessibilityIdentifier(A11yIdentifiers.linkNewDeviceScreen.desktopComputer)
|
||||||
}
|
}
|
||||||
.disabled(isGeneratingCode)
|
.disabled(isGeneratingCode)
|
||||||
case .notSupported:
|
case .notSupported:
|
||||||
@@ -100,6 +103,15 @@ struct LinkNewDeviceScreen: View {
|
|||||||
.buttonStyle(.compound(.primary))
|
.buttonStyle(.compound(.primary))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var toolbar: some ToolbarContent {
|
||||||
|
ToolbarItem(placement: .cancellationAction) {
|
||||||
|
Button(L10n.actionCancel) {
|
||||||
|
context.send(viewAction: .dismiss)
|
||||||
|
}
|
||||||
|
.accessibilityIdentifier(A11yIdentifiers.linkNewDeviceScreen.cancel)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Previews
|
// MARK: - Previews
|
||||||
@@ -148,6 +160,7 @@ struct LinkNewDeviceScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
clientProxy.linkNewDeviceServiceReturnValue = .init(handler: GrantLoginWithQrCodeHandlerSDKMock(.init(generateDelay: .seconds(20))))
|
||||||
|
|
||||||
let viewModel = LinkNewDeviceScreenViewModel(clientProxy: clientProxy)
|
let viewModel = LinkNewDeviceScreenViewModel(clientProxy: clientProxy)
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScr
|
|||||||
state.state = .error(.expired)
|
state.state = .error(.expired)
|
||||||
case .deviceNotSupported:
|
case .deviceNotSupported:
|
||||||
state.state = .error(.deviceNotSupported)
|
state.state = .error(.deviceNotSupported)
|
||||||
case .unknown:
|
case .deviceAlreadySignedIn, .unknown:
|
||||||
state.state = .error(.unknown)
|
state.state = .error(.unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ enum QRCodeLoginError: Error, Equatable {
|
|||||||
case expired
|
case expired
|
||||||
case deviceNotSupported
|
case deviceNotSupported
|
||||||
case deviceNotSignedIn
|
case deviceNotSignedIn
|
||||||
|
case deviceAlreadySignedIn
|
||||||
case unknown
|
case unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2025 Element Creations Ltd.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
// Please see LICENSE files in the repository root for full details.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
import MatrixRustSDK
|
||||||
|
|
||||||
|
class LinkNewDeviceService {
|
||||||
|
typealias GenerateProgressPublisher = CurrentValuePublisher<GenerateProgress, QRCodeLoginError>
|
||||||
|
typealias ScanProgressPublisher = CurrentValuePublisher<ScanProgress, QRCodeLoginError>
|
||||||
|
|
||||||
|
enum GenerateProgress {
|
||||||
|
case starting
|
||||||
|
case qrReady(QrCodeData)
|
||||||
|
case qrScanned(CheckCodeSenderProtocol)
|
||||||
|
case waitingForAuthorisation(verificationURI: String)
|
||||||
|
case syncingSecrets
|
||||||
|
case done
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ScanProgress {
|
||||||
|
case starting
|
||||||
|
case establishingSecureChannel(checkCode: UInt8, checkCodeString: String)
|
||||||
|
case waitingForAuth(verificationURI: String)
|
||||||
|
case syncingSecrets
|
||||||
|
case done
|
||||||
|
}
|
||||||
|
|
||||||
|
private let grantLoginHandler: GrantLoginWithQrCodeHandlerProtocol
|
||||||
|
|
||||||
|
init(handler: GrantLoginWithQrCodeHandlerProtocol) {
|
||||||
|
grantLoginHandler = handler
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateQRCode() -> GenerateProgressPublisher {
|
||||||
|
let progressSubject = CurrentValueSubject<GenerateProgress, QRCodeLoginError>(.starting)
|
||||||
|
let listener = SDKListener { progressSubject.send(.init(rustProgress: $0)) }
|
||||||
|
|
||||||
|
Task {
|
||||||
|
do {
|
||||||
|
// TODO: we need a way to cancel the in progress grant if the user hit the cancel button
|
||||||
|
try await grantLoginHandler.generate(progressListener: listener) // The success state is handled by the listener.
|
||||||
|
} catch let error as HumanQrGrantLoginError {
|
||||||
|
MXLog.error("QR code reciprocate error: \(error)")
|
||||||
|
progressSubject.send(completion: .failure(.init(rustError: error)))
|
||||||
|
} catch {
|
||||||
|
MXLog.error("QR code reciprocate unknown error: \(error)")
|
||||||
|
progressSubject.send(completion: .failure(.unknown))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return progressSubject.asCurrentValuePublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func scanQRCode(_ scannedQRData: Data) -> ScanProgressPublisher {
|
||||||
|
let progressSubject = CurrentValueSubject<ScanProgress, QRCodeLoginError>(.starting)
|
||||||
|
let listener = SDKListener { progressSubject.send(.init(rustProgress: $0)) }
|
||||||
|
|
||||||
|
let qrCodeData: QrCodeData
|
||||||
|
do {
|
||||||
|
qrCodeData = try QrCodeData.fromBytes(bytes: scannedQRData)
|
||||||
|
} catch {
|
||||||
|
MXLog.error("QR code decode error: \(error)")
|
||||||
|
progressSubject.send(completion: .failure(.invalidQRCode))
|
||||||
|
return progressSubject.asCurrentValuePublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
#warning("Check intent/server name here…")
|
||||||
|
|
||||||
|
Task {
|
||||||
|
do {
|
||||||
|
// TODO: it would be nice to be able to cancel the grant at the SDK level if the user hits the cancel button
|
||||||
|
try await grantLoginHandler.scan(qrCodeData: qrCodeData, progressListener: listener) // The success state is handled by the listener.
|
||||||
|
} catch let error as HumanQrGrantLoginError {
|
||||||
|
MXLog.error("QR code reciprocate error: \(error)")
|
||||||
|
progressSubject.send(completion: .failure(.init(rustError: error)))
|
||||||
|
} catch {
|
||||||
|
MXLog.error("QR code reciprocate unknown error: \(error)")
|
||||||
|
progressSubject.send(completion: .failure(.unknown))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return progressSubject.asCurrentValuePublisher()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LinkNewDeviceService.GenerateProgress: CustomStringConvertible {
|
||||||
|
init(rustProgress: GrantGeneratedQrLoginProgress) {
|
||||||
|
self = switch rustProgress {
|
||||||
|
case .starting: .starting
|
||||||
|
case .qrReady(let qrCode): .qrReady(qrCode)
|
||||||
|
case .qrScanned(let checkCodeSender): .qrScanned(checkCodeSender)
|
||||||
|
case .waitingForAuth(let verificationUri): .waitingForAuthorisation(verificationURI: verificationUri)
|
||||||
|
case .syncingSecrets: .syncingSecrets
|
||||||
|
case .done: .done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
switch self {
|
||||||
|
case .starting: "starting"
|
||||||
|
case .qrReady: "qrReady"
|
||||||
|
case .qrScanned: "qrScanned"
|
||||||
|
case .waitingForAuthorisation: "waitingForAuthorisation"
|
||||||
|
case .syncingSecrets: "syncingSecrets"
|
||||||
|
case .done: "done"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LinkNewDeviceService.ScanProgress: CustomStringConvertible {
|
||||||
|
init(rustProgress: GrantQrLoginProgress) {
|
||||||
|
self = switch rustProgress {
|
||||||
|
case .starting: .starting
|
||||||
|
case .establishingSecureChannel(let checkCode, let checkCodeString): .establishingSecureChannel(checkCode: checkCode, checkCodeString: checkCodeString)
|
||||||
|
case .waitingForAuth(let verificationUri): .waitingForAuth(verificationURI: verificationUri)
|
||||||
|
case .syncingSecrets: .syncingSecrets
|
||||||
|
case .done: .done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
switch self {
|
||||||
|
case .starting: "starting"
|
||||||
|
case .establishingSecureChannel: "establishingSecureChannel"
|
||||||
|
case .waitingForAuth: "waitingForAuth"
|
||||||
|
case .syncingSecrets: "syncingSecrets"
|
||||||
|
case .done: "done"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension QRCodeLoginError {
|
||||||
|
init(rustError: HumanQrGrantLoginError) {
|
||||||
|
self = switch rustError {
|
||||||
|
case .InvalidCheckCode:
|
||||||
|
.connectionInsecure
|
||||||
|
case .UnsupportedProtocol:
|
||||||
|
.linkingNotSupported
|
||||||
|
case .Unknown, .NotFound, .MissingSecretsBackup, .DeviceIdAlreadyInUse, .UnableToCreateDevice:
|
||||||
|
.unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -716,12 +716,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func logout() async {
|
func linkNewDeviceService() -> LinkNewDeviceService {
|
||||||
do {
|
LinkNewDeviceService(handler: client.newGrantLoginWithQrCodeHandler())
|
||||||
try await client.logout()
|
|
||||||
} catch {
|
|
||||||
MXLog.error("Failed logging out with error: \(error)")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func deactivateAccount(password: String?, eraseData: Bool) async -> Result<Void, ClientProxyError> {
|
func deactivateAccount(password: String?, eraseData: Bool) async -> Result<Void, ClientProxyError> {
|
||||||
@@ -734,6 +730,14 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func logout() async {
|
||||||
|
do {
|
||||||
|
try await client.logout()
|
||||||
|
} catch {
|
||||||
|
MXLog.error("Failed logging out with error: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func setPusher(with configuration: PusherConfiguration) async throws {
|
func setPusher(with configuration: PusherConfiguration) async throws {
|
||||||
try await client.setPusher(identifiers: configuration.identifiers,
|
try await client.setPusher(identifiers: configuration.identifiers,
|
||||||
kind: configuration.kind,
|
kind: configuration.kind,
|
||||||
|
|||||||
@@ -195,6 +195,8 @@ protocol ClientProxyProtocol: AnyObject {
|
|||||||
|
|
||||||
func removeUserAvatar() async -> Result<Void, ClientProxyError>
|
func removeUserAvatar() async -> Result<Void, ClientProxyError>
|
||||||
|
|
||||||
|
func linkNewDeviceService() -> LinkNewDeviceService
|
||||||
|
|
||||||
func deactivateAccount(password: String?, eraseData: Bool) async -> Result<Void, ClientProxyError>
|
func deactivateAccount(password: String?, eraseData: Bool) async -> Result<Void, ClientProxyError>
|
||||||
|
|
||||||
func logout() async
|
func logout() async
|
||||||
|
|||||||
@@ -734,6 +734,40 @@ class MockScreen: Identifiable {
|
|||||||
coordinator.start()
|
coordinator.start()
|
||||||
|
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
|
case .linkNewDevice:
|
||||||
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
|
let flowCoordinator = LinkNewDeviceFlowCoordinator(navigationStackCoordinator: navigationStackCoordinator,
|
||||||
|
flowParameters: CommonFlowParameters(userSession: UserSessionMock(.init()),
|
||||||
|
bugReportService: BugReportServiceMock(.init()),
|
||||||
|
elementCallService: ElementCallServiceMock(.init()),
|
||||||
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
||||||
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
||||||
|
linkMetadataProvider: LinkMetadataProvider(),
|
||||||
|
appMediator: AppMediatorMock.default,
|
||||||
|
appSettings: ServiceLocator.shared.settings,
|
||||||
|
appHooks: AppHooks(),
|
||||||
|
analytics: ServiceLocator.shared.analytics,
|
||||||
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
|
notificationManager: NotificationManagerMock(),
|
||||||
|
stateMachineFactory: StateMachineFactory()))
|
||||||
|
flowCoordinator.actionsPublisher
|
||||||
|
.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
|
switch action {
|
||||||
|
case .dismiss:
|
||||||
|
navigationRootCoordinator.setSheetCoordinator(nil)
|
||||||
|
case .requestOIDCAuthorisation:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
retainedState.append(flowCoordinator)
|
||||||
|
flowCoordinator.start()
|
||||||
|
|
||||||
|
// Use a sheet on top the the placeholder so we can test the dismissal.
|
||||||
|
navigationRootCoordinator.setSheetCoordinator(navigationStackCoordinator)
|
||||||
|
return PlaceholderScreenCoordinator(hideBrandChrome: false)
|
||||||
case .autoUpdatingTimeline:
|
case .autoUpdatingTimeline:
|
||||||
let appSettings: AppSettings = ServiceLocator.shared.settings
|
let appSettings: AppSettings = ServiceLocator.shared.settings
|
||||||
appSettings.hasRunIdentityConfirmationOnboarding = true
|
appSettings.hasRunIdentityConfirmationOnboarding = true
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ enum UITestsScreenIdentifier: String {
|
|||||||
case encryptionSettings
|
case encryptionSettings
|
||||||
case encryptionSettingsOutOfSync
|
case encryptionSettingsOutOfSync
|
||||||
case encryptionReset
|
case encryptionReset
|
||||||
|
case linkNewDevice
|
||||||
case roomLayoutBottom
|
case roomLayoutBottom
|
||||||
case roomLayoutMiddle
|
case roomLayoutMiddle
|
||||||
case roomLayoutTop
|
case roomLayoutTop
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:ad18b20c43c8f8127c485c8b434064de0b237d25ee177c98a989eb65113248e4
|
oid sha256:46aea5299c049f35dae8f1600616c6223a596fd2f8679f92989c16664cf4dbc1
|
||||||
size 109374
|
size 111944
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5645b5827fdf244280e80f6fc16b421a7dc0635b16b6f80b2b50a1907844b4cf
|
oid sha256:6a186ec9227165649b719f4dd798e3ac890369b308e1dd96bd21fa433d2af9b2
|
||||||
size 123395
|
size 126198
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:cc447ed7e8194814387d698437d3adaeb4b7b6f687842598fb84240d58d4e0fe
|
oid sha256:6a4f19b2fe16544a545520570eb2015aab26546ec8050a3b282715e2ec38826e
|
||||||
size 61504
|
size 63808
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:8510dfa5fe61fc0fe236ccf4bf69d3fec03a3cd5fb14182c93da27fb93b94356
|
oid sha256:61b9690e8d8521fcf9d64303caab7d6daf08bafb6d4b175cfdb3ec000d151ffb
|
||||||
size 82818
|
size 85214
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:e5a9223f99dfb8209fc21042a2656ca4a050a4f8f1a1d7723ef613bcf54706b5
|
oid sha256:8dfcf396e71ca8a417e88b2c27d452030b1ba092f7e91b2b20737394ca74e7db
|
||||||
size 98823
|
size 101393
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:79aba2f30b36dc42149b05844746297c3959cce54108fb6e9043d22a1e441b55
|
oid sha256:f95f8fe398860d1fad8b18babed1e1806c524af15cb9d9685c221cf1a0fb00a0
|
||||||
size 109776
|
size 112579
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:c49ca4038efc3d6059b8f8cd715b67741c4c45e4b817ff61aa5569ea3d76ed38
|
oid sha256:ed16c902c68752356fa5ee71aa684988a4b4bdcf4e505f75d970cb1f750aba96
|
||||||
size 65128
|
size 64763
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:7f94dff4155601b73d57df0294c051463ff330fe431a2c46a5a5b198cdc372ea
|
oid sha256:cc4f1056724de24ad5aaf7181a831e8b8c16e42b5e8771915dde72b957c98fbb
|
||||||
size 109664
|
size 112234
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:a049866c334facc710309e02999e4869a46839cf0448b68660d21e0cb6842a43
|
oid sha256:a152660e6fa14a8ae66af91ce8e43020fc4718dd300a8049e4375b697e705264
|
||||||
size 123411
|
size 126214
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:c0d7ce68e28cf45d36e04d4f6b9e62722ed67e7fc5be42287b43e1bc68924a67
|
oid sha256:844e98b0b406dafa543d47f773b5aef1367fa6e7bca1ed0b0735f26c55ffec6f
|
||||||
size 61909
|
size 64213
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:c637c11e208a467b4e4d77a2fb9f1ea0fe6602dcc0788934659328074ed4f3bc
|
oid sha256:37a8a52edf87070a3c325822dac1c0a29be41ed46f9d803ad5bbe6e2d4bd3015
|
||||||
size 81263
|
size 83659
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:d1959686b35a78a6c49ab16e9eb96f5ca879151ecf95969e13acf31d8c61f461
|
oid sha256:5ee9d2b8142ec642ea6f8d606769aaf2b4c1742855e5d67370f8d1b270a6e15a
|
||||||
size 106107
|
size 108670
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f15c62942085467d9e450c48bd5233ba51a3ae3b2c7f7c4cce2428ef66675b87
|
oid sha256:67621aa88efeeb7c589bc91087970211de6fa1ff35794c26245af3e483712f31
|
||||||
size 120137
|
size 123533
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:d85de510b52b116591c0e24b0ba647e3aa404a77b5e645f512a3cbf47d5291dd
|
oid sha256:a958c859edf66c6e11503fd590c04dc6937e8c322ade159bdaa4c1158f237cb2
|
||||||
size 60430
|
size 63031
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:a504b62f6c259b91a9a0a6d8a7b1cf18b513e86a69f5f5f9399aedf69053f65d
|
oid sha256:ddb567a2b6e080169771b6dece8ad4b47d80f83b207d6c0147531a8882fac7cb
|
||||||
size 80204
|
size 82338
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2025 Element Creations Ltd.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
// Please see LICENSE files in the repository root for full details.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
class LinkNewDeviceTests: XCTestCase {
|
||||||
|
enum Step {
|
||||||
|
static let selectDevice = 1
|
||||||
|
static let dismissed = 99
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFlow() async throws {
|
||||||
|
let app = Application.launch(.linkNewDevice)
|
||||||
|
try await app.assertScreenshot(step: Step.selectDevice)
|
||||||
|
|
||||||
|
let cancelButton = app.buttons[A11yIdentifiers.linkNewDeviceScreen.cancel]
|
||||||
|
cancelButton.tap()
|
||||||
|
|
||||||
|
try await app.assertScreenshot(step: Step.dismissed)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:9dbfadaaf361b79c626e35ab3cf5f42149e18de2538175e796a704cc21dc8411
|
||||||
|
size 158261
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:048a07df37bc493d91f67b5e1379ef571db047ab35780b28c23ee1990429846f
|
||||||
|
size 222243
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:da689e9ce1dc5b5fb809eda3e1886a9cec9d4b7c04271b9c8652a9893f910674
|
||||||
|
size 115287
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:47d79566040b9e990cd222dc056d22de86723171364d60a0fdc3592dff9bb48e
|
||||||
|
size 374177
|
||||||
Reference in New Issue
Block a user