mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 13:37:11 +00:00
Crypto identity reset (#3107)
* Add EncryptionReset password entry screen * Expose client proxy identity reset method * Update the IdentityConfirmationScreen to the latest designs * Replace the old recovery key reset screen with a new EncryptionReset one * Fixes #3102 - Add support for resetting the user's whole crypto identity * Address review comments * Bump the SDK to v1.0.30
This commit is contained in:
parent
276bbb09f2
commit
63e0b94764
@ -65,6 +65,7 @@
|
||||
0C346A4AD174F441EDB1414E /* IdentityConfirmationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB76A9AFC6CCAD4998D9B045 /* IdentityConfirmationScreenViewModel.swift */; };
|
||||
0C47AE2CA7929CB3B0E2D793 /* ServerSelectionScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0685156EB62D7E243F097CFC /* ServerSelectionScreenViewModelProtocol.swift */; };
|
||||
0C58A846F61949B1D545D661 /* NoticeRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421E716C521F96D24ECE69B3 /* NoticeRoomTimelineItem.swift */; };
|
||||
0C6DF318E9C8F6461E6ABDE7 /* EncryptionResetPasswordScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E1584F8BCF407BB94F48F04 /* EncryptionResetPasswordScreen.swift */; };
|
||||
0C797CD650DFD2876BEC5173 /* CollapsibleReactionLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F7C6DDBB5D12F6EF6A3D6E1 /* CollapsibleReactionLayout.swift */; };
|
||||
0C88044649BAEE6C49BFC43A /* SecureBackupControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C21A715237F2B6D6E80998C /* SecureBackupControllerProtocol.swift */; };
|
||||
0C932A5158C1D0604DFC5750 /* ComposerToolbarViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA29952595B804DA221A0C1D /* ComposerToolbarViewModelTests.swift */; };
|
||||
@ -203,6 +204,7 @@
|
||||
2F66701B15657A87B4AC3A0A /* WaitlistScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09CE2B7AD979BDEE09FEDB08 /* WaitlistScreenModels.swift */; };
|
||||
2F94054F50E312AF30BE07F3 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B21E611DADDEF00307E7AC /* String.swift */; };
|
||||
2FEC6652055984389CE1BBEC /* TimelineProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50F03079F6B5EF9CA005F14 /* TimelineProxyProtocol.swift */; };
|
||||
3041EBA2660F28FFB7BDA339 /* EncryptionResetScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0FF9CB3EFA753277291F609 /* EncryptionResetScreenCoordinator.swift */; };
|
||||
3042527CB344A9EF1157FC26 /* AudioRecorderStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55CC239AE12339C565F6C9A /* AudioRecorderStateTests.swift */; };
|
||||
308BD9343B95657FAA583FB7 /* SwiftState in Frameworks */ = {isa = PBXBuildFile; productRef = 19CD5B074D7DD44AF4C58BB6 /* SwiftState */; };
|
||||
30CC1DB7CE357659C82AA115 /* MediaProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85EB16E7FE59A947CA441531 /* MediaProviderProtocol.swift */; };
|
||||
@ -227,6 +229,7 @@
|
||||
35E975CFDA60E05362A7CF79 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 1222DB76B917EB8A55365BA5 /* target.yml */; };
|
||||
366D5BFE52CB79E804C7D095 /* CallScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD9547E47C58930E2CE8306 /* CallScreenViewModelTests.swift */; };
|
||||
368C8758FCD079E6AAA18C2C /* NoticeRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */; };
|
||||
36926D795D6D19177C7812F8 /* EncryptionResetPasswordScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6935A55AB3B0C94BC566DD6 /* EncryptionResetPasswordScreenCoordinator.swift */; };
|
||||
369BF960E52BBEE61F8A5BD1 /* BlockedUsersScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED60E4D2CD678E1EBF16F77A /* BlockedUsersScreen.swift */; };
|
||||
36AC963F2F04069B7FF1AA0C /* UIConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6D88E8AFFBF2C1D589C0FA /* UIConstants.swift */; };
|
||||
36AD4DD4C798E22584ED3200 /* SentrySwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 75361A9D8A3C5501EADB225D /* SentrySwiftUI */; };
|
||||
@ -257,7 +260,6 @@
|
||||
3C549A0BF39F8A854D45D9FD /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 0DD568A494247444A4B56031 /* Kingfisher */; };
|
||||
3C73442084BF8A6939F0F80B /* AnalyticsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5445FCE0CE15E634FDC1A2E2 /* AnalyticsService.swift */; };
|
||||
3CE4C5071B6D2576E2473989 /* OrderedSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62B07B296D7A9D2F09120853 /* OrderedSet.swift */; };
|
||||
3D2E3E1B01D4389DCBE8F0E8 /* ResetRecoveryKeyScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E995E3F726488F8938F0BCD1 /* ResetRecoveryKeyScreenCoordinator.swift */; };
|
||||
3DA57CA0D609A6B37CA1DC2F /* BugReportService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DC38E64A5ED3FDB201029A /* BugReportService.swift */; };
|
||||
3DAD62988F072607441CB7A5 /* PollFormScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F8664F1FB95AF3C4202478 /* PollFormScreenCoordinator.swift */; };
|
||||
3DAF325D8AE461F7CDB282BD /* StartChatScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6861FE915C7B5466E6962BBA /* StartChatScreen.swift */; };
|
||||
@ -439,7 +441,6 @@
|
||||
67C05C50AD734283374605E3 /* MatrixEntityRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */; };
|
||||
67D6E0700A9C1E676F6231F8 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = AD544C0FA48DFFB080920061 /* Collections */; };
|
||||
67E9926C4572C54F59FCA91A /* AuthenticationFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9B069D7772DDF6513E0F1B8 /* AuthenticationFlowCoordinator.swift */; };
|
||||
680062C402ECB8FCAAE85A5C /* ResetRecoveryKeyScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99637028A8BD2843A35A92D4 /* ResetRecoveryKeyScreenViewModelProtocol.swift */; };
|
||||
6817EAD73DC1FFD8B943B5B9 /* HomeScreenRoomTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73587C2E3CF5998361AE516 /* HomeScreenRoomTests.swift */; };
|
||||
68184EF36396424FE19A727D /* MediaLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */; };
|
||||
6832733838C57A7D3FE8FEB5 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 78A5A8DE1E2B09C978C7F3B0 /* KeychainAccess */; };
|
||||
@ -654,6 +655,7 @@
|
||||
97189E495F0E47805D1868DB /* DTCoreText in Frameworks */ = {isa = PBXBuildFile; productRef = 527578916BD388A09F5A8036 /* DTCoreText */; };
|
||||
978BB24F2A5D31EE59EEC249 /* UserSessionProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F4134FEFE4EB55759017408 /* UserSessionProtocol.swift */; };
|
||||
97969EF0B9C412CD38E5CA93 /* AppLockScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4005D82E9D27BAF006A8FE1 /* AppLockScreenViewModel.swift */; };
|
||||
97BAEDD9054FB5F233EE928B /* EncryptionResetScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306AB507E1027D6C5C147EB6 /* EncryptionResetScreenModels.swift */; };
|
||||
981853650217B6C8ECDD998C /* NavigationRootCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F875D71347DC81EAE7687446 /* NavigationRootCoordinatorTests.swift */; };
|
||||
983896D611ABF52A5C37498D /* RoomSummaryProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB3227C7A74B734924942E9 /* RoomSummaryProvider.swift */; };
|
||||
9847B056C1A216C314D21E68 /* AuthenticationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3A1AB5A84D843B6AC8D5F1E /* AuthenticationService.swift */; };
|
||||
@ -674,7 +676,6 @@
|
||||
9BD3A773186291560DF92B62 /* RoomTimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F2402D738694F98729A441 /* RoomTimelineProvider.swift */; };
|
||||
9C4EC28A921486B1775D7F8C /* IdentityConfirmedScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307702DD66E7DDCDD9214784 /* IdentityConfirmedScreen.swift */; };
|
||||
9C55746D8F6A3E35CFCF4A7A /* AuthenticationStartLogo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 598F01EBD0C4CC550C644418 /* AuthenticationStartLogo.swift */; };
|
||||
9C9838B68C00C980A498050C /* ResetRecoveryKeyScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC30DEC0097B9D217493007 /* ResetRecoveryKeyScreen.swift */; };
|
||||
9D2E03DB175A6AB14589076D /* AnalyticsEvents in Frameworks */ = {isa = PBXBuildFile; productRef = 2A3F7BCCB18C15B30CCA39A9 /* AnalyticsEvents */; };
|
||||
9D79B94493FB32249F7E472F /* PlaceholderAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C705E605EF57C19DBE86FFA1 /* PlaceholderAvatarImage.swift */; };
|
||||
9D9690D2FD4CD26FF670620F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C75EF87651B00A176AB08E97 /* AppDelegate.swift */; };
|
||||
@ -690,6 +691,8 @@
|
||||
9FB41B0E8B2AA9B404E52C8B /* AppLockSetupBiometricsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CCC6C31102E1D8B9106DEDE /* AppLockSetupBiometricsScreenViewModelProtocol.swift */; };
|
||||
A009BDFB0A6816D4C392ADCB /* SettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF715D4FD4710EBB637D661 /* SettingsScreenViewModelProtocol.swift */; };
|
||||
A021827B528F1EDC9101CA58 /* AppCoordinatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBC776F301D374A3298C69DA /* AppCoordinatorProtocol.swift */; };
|
||||
A0601810597769B81C2358AF /* EncryptionResetPasswordScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A2B5274C1D3D2999D643786 /* EncryptionResetPasswordScreenViewModelProtocol.swift */; };
|
||||
A0868BDE84D2140A885BE3C9 /* EncryptionResetScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E8562F4D7DE073BC32902AB /* EncryptionResetScreenViewModelProtocol.swift */; };
|
||||
A0A0D2A9564BDA3FDE2E360F /* FormattedBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */; };
|
||||
A0D7E5BD0298A97DCBDCE40B /* Emojibase in Frameworks */ = {isa = PBXBuildFile; productRef = C05729B1684C331F5FFE9232 /* Emojibase */; };
|
||||
A10D6CCDE2010C09EEA1A593 /* HomeScreenRoomList.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7661EFFCAA307A97D71132A /* HomeScreenRoomList.swift */; };
|
||||
@ -765,6 +768,7 @@
|
||||
B1387648C6F71F1B98244803 /* SecureBackupRecoveryKeyScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 596AA8843AC1A234F3387767 /* SecureBackupRecoveryKeyScreenCoordinator.swift */; };
|
||||
B14BC354E56616B6B7D9A3D7 /* NotificationServiceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27A1AD6389A4659AF0CEAE62 /* NotificationServiceExtension.swift */; };
|
||||
B188D0907A4D38AAAF6FEFA8 /* AppLockSetupFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DBB08A95EFA668F2CF27211 /* AppLockSetupFlowCoordinator.swift */; };
|
||||
B1B255CE0E4306DD6E09D936 /* EncryptionResetPasswordScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54A5E6F398C269AD52C9AE21 /* EncryptionResetPasswordScreenModels.swift */; };
|
||||
B22D857D1E8FCA6DD74A58E3 /* UserSessionScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F899D02CF26EA7675EEBE74C /* UserSessionScreenTests.swift */; };
|
||||
B245583C63F8F90357B87FAE /* KZFileWatchers in Frameworks */ = {isa = PBXBuildFile; productRef = A2AE110B053B55E38F8D10C7 /* KZFileWatchers */; };
|
||||
B272E5D1DE8BDA87A6B7A696 /* RoomTimelineProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = F74532E01B317C56C1BE8FA8 /* RoomTimelineProviderMock.swift */; };
|
||||
@ -926,6 +930,7 @@
|
||||
D5E771132BB36240DE38102F /* RoomMessageEventStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80E815FF3CC5E5A355E3A25E /* RoomMessageEventStringBuilder.swift */; };
|
||||
D5EA4C6C80579279770D5804 /* ImageRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */; };
|
||||
D5FE90A6AF5FD5AE91BD37C7 /* NotificationSettingsEditScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780258F1B9D15E30549FF4BE /* NotificationSettingsEditScreenViewModel.swift */; };
|
||||
D6152E21036B88C44ECB22E7 /* EncryptionResetPasswordScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 303D9438EFB481F57A366E82 /* EncryptionResetPasswordScreenViewModel.swift */; };
|
||||
D63974A88CF2BC721F109C77 /* Compound in Frameworks */ = {isa = PBXBuildFile; productRef = DCA3C4A997AD28E6918D4CE5 /* Compound */; };
|
||||
D6661A94DBD97658B2ADBD6A /* MapTilerStaticMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A4D29F2683F5772AC72406F /* MapTilerStaticMap.swift */; };
|
||||
D6DE764B17FB4A9A12C33BF4 /* MessageComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F1DF3FFFE5ED2B8133F43A7 /* MessageComposer.swift */; };
|
||||
@ -954,7 +959,6 @@
|
||||
DFCA89C4EC2A5332ED6B441F /* DataProtectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4959CECEC984B3995616F427 /* DataProtectionManager.swift */; };
|
||||
DFD5AA8688A34C72D48AF3B1 /* StaticLocationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5311C989EC15B4C2D699025 /* StaticLocationScreenViewModel.swift */; };
|
||||
DFF7D6A6C26DDD40D00AE579 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = F012CB5EE3F2B67359F6CC52 /* target.yml */; };
|
||||
E07ABB9FD1C87EBBDDE81DC5 /* ResetRecoveryKeyScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C63616A8920EC6948B31EA1B /* ResetRecoveryKeyScreenViewModel.swift */; };
|
||||
E0B6A569AC3E81D233B43D60 /* SettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E625B0EB2F86B37C14EF7E6 /* SettingsScreenViewModel.swift */; };
|
||||
E0C167D41A48EDB30B447DE3 /* VoiceMessageRecordingComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73A5C3F7C9C1DA10CAEC6A98 /* VoiceMessageRecordingComposer.swift */; };
|
||||
E0FB26262689F04D66A949D7 /* TestablePreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1E227F34BE43B08E098796E /* TestablePreview.swift */; };
|
||||
@ -1011,7 +1015,7 @@
|
||||
EB9F4688006B52E69DF5358F /* BlankFormCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7F63EB1525E697CAEB002B /* BlankFormCoordinator.swift */; };
|
||||
EBE13FAB4E29738AC41BD3E5 /* InfoPlistReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A580295A56B55A856CC4084 /* InfoPlistReader.swift */; };
|
||||
EC280623A42904341363EAAF /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = A20EA00CCB9DBE0FFB17DD09 /* Collections */; };
|
||||
EC65AF0D9240A248DC9917BB /* ResetRecoveryKeyScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76911C322BC4CD117A8A0AF1 /* ResetRecoveryKeyScreenModels.swift */; };
|
||||
EC3320639828BED8B3E5F2C6 /* EncryptionResetScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5875F7C0A2398E9F134B1284 /* EncryptionResetScreenViewModel.swift */; };
|
||||
ECA636DAF071C611FDC2BB57 /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; };
|
||||
ED564C8C7C43CF5F67000368 /* PlatformViewVersionPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D26813CCE39221FE30BF22CD /* PlatformViewVersionPredicate.swift */; };
|
||||
ED90A59F068FD0CA27E602ED /* UserProfileListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = E10DA51DBC8C7E1460DBCCBD /* UserProfileListRow.swift */; };
|
||||
@ -1043,6 +1047,7 @@
|
||||
F37629BAA5E8F50AAF2A131D /* SoftLogoutScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB7BAD55A4E2B8E5828CD64C /* SoftLogoutScreenViewModel.swift */; };
|
||||
F3E2D3F7ACDED65A4E5CD8DE /* RoomMembersListScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF79FB25E2D4BD6F50CE7C9 /* RoomMembersListScreenViewModel.swift */; };
|
||||
F3F38062C6CA21CF403C5C90 /* AudioConverterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2757B1BE23DF8AA239937243 /* AudioConverterProtocol.swift */; };
|
||||
F3F9D61C53C348043D3D6F51 /* EncryptionResetScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 811E8BF34E931D51552C9C13 /* EncryptionResetScreen.swift */; };
|
||||
F40B097470D3110DFDB1FAAA /* LegalInformationScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47873756E45B46683D97DC32 /* LegalInformationScreenModels.swift */; };
|
||||
F4971845B5C4F270F6BC5745 /* ScaledFrameModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D82F234B3576BD6268C7950 /* ScaledFrameModifier.swift */; };
|
||||
F4996C82A4B3A5FF0C8EDD03 /* RoomListFilterModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = E06AAD6D9D3F5833E7A5A2F9 /* RoomListFilterModels.swift */; };
|
||||
@ -1360,7 +1365,9 @@
|
||||
2E88534A39781D76487D59DF /* SecureBackupKeyBackupScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupKeyBackupScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
2EFE1922F39398ABFB36DF3F /* RoomDetailsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsViewModelTests.swift; sourceTree = "<group>"; };
|
||||
2F36C5D9B37E50915ECBD3EE /* RoomMemberProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberProxy.swift; sourceTree = "<group>"; };
|
||||
303D9438EFB481F57A366E82 /* EncryptionResetPasswordScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
303FCADE77DF1F3670C086ED /* BugReportScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
306AB507E1027D6C5C147EB6 /* EncryptionResetScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetScreenModels.swift; sourceTree = "<group>"; };
|
||||
307702DD66E7DDCDD9214784 /* IdentityConfirmedScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmedScreen.swift; sourceTree = "<group>"; };
|
||||
309AD8BAE6437C31BA7157BF /* ElementCallWidgetDriver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementCallWidgetDriver.swift; sourceTree = "<group>"; };
|
||||
30ED584467DB380E3CEFB1DB /* NotificationManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManagerTests.swift; sourceTree = "<group>"; };
|
||||
@ -1477,6 +1484,7 @@
|
||||
49E45C3DC740D3AB9A47FD32 /* SwipeToReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeToReplyView.swift; sourceTree = "<group>"; };
|
||||
49E6066092ED45E36BB306F7 /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
||||
49E751D7EDB6043238111D90 /* UNNotificationRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNNotificationRequest.swift; sourceTree = "<group>"; };
|
||||
4A2B5274C1D3D2999D643786 /* EncryptionResetPasswordScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
4A5B4CD611DE7E94F5BA87B2 /* AppLockTimerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockTimerTests.swift; sourceTree = "<group>"; };
|
||||
4AB7D7DAAAF662DED9D02379 /* MockMediaLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaLoader.swift; sourceTree = "<group>"; };
|
||||
4B2D4EEBE8C098BBADD10939 /* SecureBackupKeyBackupScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupKeyBackupScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
@ -1518,6 +1526,7 @@
|
||||
542D4F49FABA056DEEEB3400 /* RustTracing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RustTracing.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>"; };
|
||||
54A5E6F398C269AD52C9AE21 /* EncryptionResetPasswordScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreenModels.swift; sourceTree = "<group>"; };
|
||||
54C4E7B46099462F12000C91 /* DeveloperOptionsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
55AEEF8142DF1B59DB40FB93 /* TimelineItemSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemSender.swift; sourceTree = "<group>"; };
|
||||
5644919DB2022397D9D5825A /* MockSoftLogoutScreenState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSoftLogoutScreenState.swift; sourceTree = "<group>"; };
|
||||
@ -1530,6 +1539,7 @@
|
||||
57F95CADD0A5DBD76B990FCB /* ServiceLocator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceLocator.swift; sourceTree = "<group>"; };
|
||||
584509A363ADF6244DFDB96A /* CallNotificationRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallNotificationRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
584A61D9C459FAFEF038A7C0 /* Section.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Section.swift; sourceTree = "<group>"; };
|
||||
5875F7C0A2398E9F134B1284 /* EncryptionResetScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
58C2527813FDAE23E72A9063 /* AnalyticsSettingsScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
58D295F0081084F38DB20893 /* RoomNotificationSettingsScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
592A35163B0749C66BFD6186 /* MapLibreStaticMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLibreStaticMapView.swift; sourceTree = "<group>"; };
|
||||
@ -1599,7 +1609,6 @@
|
||||
6CEBE5EA91E8691EDF364EC2 /* UITestsScreenIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsScreenIdentifier.swift; sourceTree = "<group>"; };
|
||||
6D0A27607AB09784C8501B5C /* DeveloperOptionsScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
6D4777F0142E330A75C46FE4 /* SessionVerificationUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationUITests.swift; sourceTree = "<group>"; };
|
||||
6DC30DEC0097B9D217493007 /* ResetRecoveryKeyScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetRecoveryKeyScreen.swift; sourceTree = "<group>"; };
|
||||
6DF438EAFC732D2D95D34BF6 /* StartChatViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartChatViewModelTests.swift; sourceTree = "<group>"; };
|
||||
6E2656184491C505700D2405 /* CollapsibleRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
6E5725BC6C63604CB769145B /* LegalInformationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
@ -1636,7 +1645,6 @@
|
||||
7509AB72755DCC4B4E721B36 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/SAS.strings; sourceTree = "<group>"; };
|
||||
752A0EB49BF5BCEA37EDF7A3 /* Signposter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Signposter.swift; sourceTree = "<group>"; };
|
||||
76310030C831D4610A705603 /* URLComponentsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLComponentsTests.swift; sourceTree = "<group>"; };
|
||||
76911C322BC4CD117A8A0AF1 /* ResetRecoveryKeyScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetRecoveryKeyScreenModels.swift; sourceTree = "<group>"; };
|
||||
772334731A8BF8E6D90B194D /* LocationRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
7773CBFDBD458E0B7E270507 /* PillView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillView.swift; sourceTree = "<group>"; };
|
||||
780258F1B9D15E30549FF4BE /* NotificationSettingsEditScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsEditScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
@ -1669,6 +1677,7 @@
|
||||
7DDBF99755A9008CF8C8499E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||
7DDF49CEBC0DFC59C308335F /* RoomMemberDetailsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
7E492690C8B27A892C194CC4 /* AdvancedSettingsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
7E8562F4D7DE073BC32902AB /* EncryptionResetScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
7EB58E4E8D6D634C246AD5C2 /* RoomInviterLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomInviterLabel.swift; sourceTree = "<group>"; };
|
||||
7EC2F1622C5BBABED6012E12 /* HeroImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeroImage.swift; sourceTree = "<group>"; };
|
||||
7EECE8B331CD169790EF284F /* BugReportScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
@ -1677,6 +1686,7 @@
|
||||
7FDF541AE914059942B575B4 /* IdentityConfirmationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenModels.swift; sourceTree = "<group>"; };
|
||||
80C4927D09099497233E9980 /* WaitlistScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreen.swift; sourceTree = "<group>"; };
|
||||
80E815FF3CC5E5A355E3A25E /* RoomMessageEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageEventStringBuilder.swift; sourceTree = "<group>"; };
|
||||
811E8BF34E931D51552C9C13 /* EncryptionResetScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetScreen.swift; sourceTree = "<group>"; };
|
||||
8140010A796DB2C7977B6643 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
8166F121C79C7B62BF01D508 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = pt; path = pt.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||
818695BED971753243FEF897 /* StickerRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
@ -1734,6 +1744,7 @@
|
||||
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>"; };
|
||||
8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; path = UITests.xctestplan; sourceTree = "<group>"; };
|
||||
8E1584F8BCF407BB94F48F04 /* EncryptionResetPasswordScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreen.swift; sourceTree = "<group>"; };
|
||||
8F21ED7205048668BEB44A38 /* AppActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppActivityView.swift; sourceTree = "<group>"; };
|
||||
8F6210134203BE1F2DD5C679 /* RoomDirectoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectoryCell.swift; sourceTree = "<group>"; };
|
||||
8F841F219ACDFC1D3F42FEFB /* RoomChangeRolesScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomChangeRolesScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
@ -1772,7 +1783,6 @@
|
||||
989D7380D9C86B3A10D30B13 /* AppLockSetupPINScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
989FC684408B31A677F5538B /* CompletionSuggestionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletionSuggestionView.swift; sourceTree = "<group>"; };
|
||||
98A2932515EA11D3DD8A3506 /* TimelineItemBubbledStylerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemBubbledStylerView.swift; sourceTree = "<group>"; };
|
||||
99637028A8BD2843A35A92D4 /* ResetRecoveryKeyScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetRecoveryKeyScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
997BF045585AF6DB2EBC5755 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
9A008E57D52B07B78DFAD1BB /* RoomFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomFlowCoordinator.swift; sourceTree = "<group>"; };
|
||||
9A028783CFFF861C5E44FFB1 /* BadgeLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeLabel.swift; sourceTree = "<group>"; };
|
||||
@ -1967,7 +1977,6 @@
|
||||
C5F06F2F09B2EDD067DC2174 /* NotificationSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreen.swift; sourceTree = "<group>"; };
|
||||
C616D90B1E2F033CAA325439 /* StaticLocationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLocationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
C618CA2B6C8758B06C88013C /* CreateRoomCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomCoordinator.swift; sourceTree = "<group>"; };
|
||||
C63616A8920EC6948B31EA1B /* ResetRecoveryKeyScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetRecoveryKeyScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
C687844F60BFF532D49A994C /* AnalyticsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsTests.swift; sourceTree = "<group>"; };
|
||||
C6A9F49B3EE59147AF2F70BB /* SeparatorRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
C6FEA87EA3752203065ECE27 /* BugReportUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportUITests.swift; sourceTree = "<group>"; };
|
||||
@ -2075,6 +2084,7 @@
|
||||
E06AAD6D9D3F5833E7A5A2F9 /* RoomListFilterModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomListFilterModels.swift; sourceTree = "<group>"; };
|
||||
E0F7CCC4A9D1927223F559D5 /* AuthenticationStartScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationStartScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
E0FCA0957FAA0E15A9F5579D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Untranslated.stringsdict; sourceTree = "<group>"; };
|
||||
E0FF9CB3EFA753277291F609 /* EncryptionResetScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
E10DA51DBC8C7E1460DBCCBD /* UserProfileListRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileListRow.swift; sourceTree = "<group>"; };
|
||||
E1573D28C8A9FB6399D0EEFB /* SecureBackupLogoutConfirmationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupLogoutConfirmationScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
E1A5FEF17ED7E6176D922D4F /* RoomDetailsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreen.swift; sourceTree = "<group>"; };
|
||||
@ -2103,6 +2113,7 @@
|
||||
E6372DD10DED30E7AD7BCE21 /* RoomListFiltersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomListFiltersView.swift; sourceTree = "<group>"; };
|
||||
E65DA46BD5CA83747AE144F3 /* secrets.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = secrets.xcconfig; sourceTree = "<group>"; };
|
||||
E66763BD54A3A1D9C6E6F2F1 /* PinnedItemsIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinnedItemsIndicatorView.swift; sourceTree = "<group>"; };
|
||||
E6935A55AB3B0C94BC566DD6 /* EncryptionResetPasswordScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreenCoordinator.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>"; };
|
||||
E6FCC416A3BFE73DF7B3E6BF /* RoomTimelineControllerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineControllerFactory.swift; sourceTree = "<group>"; };
|
||||
@ -2116,7 +2127,6 @@
|
||||
E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIFont+AttributedStringBuilder.m"; sourceTree = "<group>"; };
|
||||
E96ED747FF90332EA1333C22 /* RoomTimelineItemFixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemFixtures.swift; sourceTree = "<group>"; };
|
||||
E992D7B8BE54B2AB454613AF /* XCUIElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCUIElement.swift; sourceTree = "<group>"; };
|
||||
E995E3F726488F8938F0BCD1 /* ResetRecoveryKeyScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetRecoveryKeyScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
E9A3D3CFA199FA7897364547 /* CallInviteRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallInviteRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
E9D059BFE329BE09B6D96A9F /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ro; path = ro.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||
EA4D639E27D5882A6A71AECF /* GlobalSearchScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalSearchScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
@ -2322,14 +2332,6 @@
|
||||
path = VoiceMessage;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
01DF58ADE41080A419AD424A /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6DC30DEC0097B9D217493007 /* ResetRecoveryKeyScreen.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0210F4932B59277E2EEEF7BC /* RoomNotificationSettingsScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -2601,7 +2603,6 @@
|
||||
2565414373E6F68005966B8E /* SecureBackup */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EE703B39AC7A2862CFDCA12C /* ResetKeyScreen */,
|
||||
B1FD4FD6CEB987AE274AEEE5 /* SecureBackupKeyBackupScreen */,
|
||||
63E514D74481A3D9556DFFC3 /* SecureBackupLogoutConfirmationScreen */,
|
||||
6E8F16377AD462BBD4951271 /* SecureBackupRecoveryKeyScreen */,
|
||||
@ -3143,6 +3144,14 @@
|
||||
path = Polls;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
459B661EA3598F9E709E81A7 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8E1584F8BCF407BB94F48F04 /* EncryptionResetPasswordScreen.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
464C6BFAA853DC755B9C1F60 /* PinnedItemsBanner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -4030,6 +4039,15 @@
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8656AFF06650360A5D0695FF /* EncryptionReset */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
934A2E4A36A7FB6E301758EB /* EncryptionResetPasswordScreen */,
|
||||
A3CF1DEFB89992E0B9187004 /* EncryptionResetScreen */,
|
||||
);
|
||||
path = EncryptionReset;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
87E2774157D9C4894BCFF3F8 /* MediaPickerScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -4168,6 +4186,18 @@
|
||||
path = ElementCall;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
934A2E4A36A7FB6E301758EB /* EncryptionResetPasswordScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E6935A55AB3B0C94BC566DD6 /* EncryptionResetPasswordScreenCoordinator.swift */,
|
||||
54A5E6F398C269AD52C9AE21 /* EncryptionResetPasswordScreenModels.swift */,
|
||||
303D9438EFB481F57A366E82 /* EncryptionResetPasswordScreenViewModel.swift */,
|
||||
4A2B5274C1D3D2999D643786 /* EncryptionResetPasswordScreenViewModelProtocol.swift */,
|
||||
459B661EA3598F9E709E81A7 /* View */,
|
||||
);
|
||||
path = EncryptionResetPasswordScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
93C7520ED23C9598BB144DBB /* UserProfileScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -4389,6 +4419,18 @@
|
||||
path = VoiceMessage;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A3CF1DEFB89992E0B9187004 /* EncryptionResetScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E0FF9CB3EFA753277291F609 /* EncryptionResetScreenCoordinator.swift */,
|
||||
306AB507E1027D6C5C147EB6 /* EncryptionResetScreenModels.swift */,
|
||||
5875F7C0A2398E9F134B1284 /* EncryptionResetScreenViewModel.swift */,
|
||||
7E8562F4D7DE073BC32902AB /* EncryptionResetScreenViewModelProtocol.swift */,
|
||||
D382E465AF067C1BF888BF8E /* View */,
|
||||
);
|
||||
path = EncryptionResetScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A448A3A8F764174C60CD0CA1 /* Other */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -4861,6 +4903,14 @@
|
||||
path = Layout;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D382E465AF067C1BF888BF8E /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
811E8BF34E931D51552C9C13 /* EncryptionResetScreen.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D4B487C81A239A9C71807601 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -5002,6 +5052,7 @@
|
||||
90DC2E28718955ED87AD1456 /* CreatePollScreen */,
|
||||
C18958141C8ED6D778F779A4 /* CreateRoom */,
|
||||
F5A65D1D3B83593598DC278D /* EmojiPickerScreen */,
|
||||
8656AFF06650360A5D0695FF /* EncryptionReset */,
|
||||
448435400B561C40E514BE1C /* FilePreviewScreen */,
|
||||
8A4738BBA7C7A299BAD70372 /* GlobalSearchScreen */,
|
||||
B53CA9BECD3F97805E1432D0 /* HomeScreen */,
|
||||
@ -5135,18 +5186,6 @@
|
||||
path = StartChatScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EE703B39AC7A2862CFDCA12C /* ResetKeyScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E995E3F726488F8938F0BCD1 /* ResetRecoveryKeyScreenCoordinator.swift */,
|
||||
76911C322BC4CD117A8A0AF1 /* ResetRecoveryKeyScreenModels.swift */,
|
||||
C63616A8920EC6948B31EA1B /* ResetRecoveryKeyScreenViewModel.swift */,
|
||||
99637028A8BD2843A35A92D4 /* ResetRecoveryKeyScreenViewModelProtocol.swift */,
|
||||
01DF58ADE41080A419AD424A /* View */,
|
||||
);
|
||||
path = ResetKeyScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EFD4F7FCAAAB3EF45EE7A067 /* BlockedUsersScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -6161,6 +6200,16 @@
|
||||
B5903E48CF43259836BF2DBF /* EncryptedRoomTimelineView.swift in Sources */,
|
||||
FBD402E3170EB1ED0D1AA672 /* EncryptionKeyProvider.swift in Sources */,
|
||||
46A6DB0F78FB399BD59E2D41 /* EncryptionKeyProviderProtocol.swift in Sources */,
|
||||
0C6DF318E9C8F6461E6ABDE7 /* EncryptionResetPasswordScreen.swift in Sources */,
|
||||
36926D795D6D19177C7812F8 /* EncryptionResetPasswordScreenCoordinator.swift in Sources */,
|
||||
B1B255CE0E4306DD6E09D936 /* EncryptionResetPasswordScreenModels.swift in Sources */,
|
||||
D6152E21036B88C44ECB22E7 /* EncryptionResetPasswordScreenViewModel.swift in Sources */,
|
||||
A0601810597769B81C2358AF /* EncryptionResetPasswordScreenViewModelProtocol.swift in Sources */,
|
||||
F3F9D61C53C348043D3D6F51 /* EncryptionResetScreen.swift in Sources */,
|
||||
3041EBA2660F28FFB7BDA339 /* EncryptionResetScreenCoordinator.swift in Sources */,
|
||||
97BAEDD9054FB5F233EE928B /* EncryptionResetScreenModels.swift in Sources */,
|
||||
EC3320639828BED8B3E5F2C6 /* EncryptionResetScreenViewModel.swift in Sources */,
|
||||
A0868BDE84D2140A885BE3C9 /* EncryptionResetScreenViewModelProtocol.swift in Sources */,
|
||||
50539366B408780B232C1910 /* EstimatedWaveformView.swift in Sources */,
|
||||
F78BAD28482A467287A9A5A3 /* EventBasedMessageTimelineItemProtocol.swift in Sources */,
|
||||
02D8DF8EB7537EB4E9019DDB /* EventBasedTimelineItemProtocol.swift in Sources */,
|
||||
@ -6406,11 +6455,6 @@
|
||||
46A261AA898344A1F3C406B1 /* ReportContentScreenModels.swift in Sources */,
|
||||
42A5A42ACF063EEE6B1980D2 /* ReportContentScreenViewModel.swift in Sources */,
|
||||
8285FF4B2C2331758C437FF7 /* ReportContentScreenViewModelProtocol.swift in Sources */,
|
||||
9C9838B68C00C980A498050C /* ResetRecoveryKeyScreen.swift in Sources */,
|
||||
3D2E3E1B01D4389DCBE8F0E8 /* ResetRecoveryKeyScreenCoordinator.swift in Sources */,
|
||||
EC65AF0D9240A248DC9917BB /* ResetRecoveryKeyScreenModels.swift in Sources */,
|
||||
E07ABB9FD1C87EBBDDE81DC5 /* ResetRecoveryKeyScreenViewModel.swift in Sources */,
|
||||
680062C402ECB8FCAAE85A5C /* ResetRecoveryKeyScreenViewModelProtocol.swift in Sources */,
|
||||
A494741843F087881299ACF0 /* RestorationToken.swift in Sources */,
|
||||
6E391F7F628D984AF44385D9 /* RoomAttachmentPicker.swift in Sources */,
|
||||
8587A53DE8EF94FD796DC375 /* RoomAvatarImage.swift in Sources */,
|
||||
@ -7509,7 +7553,7 @@
|
||||
repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift";
|
||||
requirement = {
|
||||
kind = exactVersion;
|
||||
version = 1.0.29;
|
||||
version = 1.0.30;
|
||||
};
|
||||
};
|
||||
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
|
||||
|
@ -149,8 +149,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/element-hq/matrix-rust-components-swift",
|
||||
"state" : {
|
||||
"revision" : "d0226f669526e908d45bf9b5682f372d84cf9ffe",
|
||||
"version" : "1.0.29"
|
||||
"revision" : "bc534e15fa0749d668b201b923ee57204afb868a",
|
||||
"version" : "1.0.30"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -81,6 +81,7 @@
|
||||
"action_report_bug" = "Report bug";
|
||||
"action_report_content" = "Report content";
|
||||
"action_reset" = "Reset";
|
||||
"action_reset_identity" = "Reset identity";
|
||||
"action_retry" = "Retry";
|
||||
"action_retry_decryption" = "Retry decryption";
|
||||
"action_save" = "Save";
|
||||
@ -429,12 +430,20 @@
|
||||
"screen_edit_profile_error_title" = "Unable to update profile";
|
||||
"screen_edit_profile_title" = "Edit profile";
|
||||
"screen_edit_profile_updating_details" = "Updating profile…";
|
||||
"screen_encryption_reset_bullet_1" = "Your account details, contacts, preferences, and chat list will be kept";
|
||||
"screen_encryption_reset_bullet_2" = "You will lose your existing message history";
|
||||
"screen_encryption_reset_bullet_3" = "You will need to verify all your existing devices and contacts again";
|
||||
"screen_encryption_reset_footer" = "Only reset your identity if you don’t have access to another signed-in device and you’ve lost your recovery key.";
|
||||
"screen_encryption_reset_subtitle" = "If you’re not signed in to any other devices and you’ve lost your recovery key, then you’ll need to reset your identity to continue using the app. ";
|
||||
"screen_encryption_reset_title" = "Reset your identity in case you can’t confirm another way";
|
||||
"screen_identity_confirmation_cannot_confirm" = "Can't confirm?";
|
||||
"screen_identity_confirmation_create_new_recovery_key" = "Create a new recovery key";
|
||||
"screen_identity_confirmation_subtitle" = "Verify this device to set up secure messaging.";
|
||||
"screen_identity_confirmation_title" = "Confirm that it's you";
|
||||
"screen_identity_confirmation_use_another_device" = "Use another device";
|
||||
"screen_identity_confirmation_use_recovery_key" = "Use recovery key";
|
||||
"screen_identity_confirmed_subtitle" = "Now you can read or send messages securely, and anyone you chat with can also trust this device.";
|
||||
"screen_identity_confirmed_title" = "Device verified";
|
||||
"screen_identity_use_another_device" = "Use another device";
|
||||
"screen_identity_waiting_on_other_device" = "Waiting on other device…";
|
||||
"screen_invites_decline_chat_message" = "Are you sure you want to decline the invitation to join %1$@?";
|
||||
"screen_invites_decline_chat_title" = "Decline invite";
|
||||
@ -578,6 +587,12 @@
|
||||
"screen_report_content_block_user_hint" = "Check if you want to hide all current and future messages from this user";
|
||||
"screen_report_content_explanation" = "This message will be reported to your homeserver’s administrator. They will not be able to read any encrypted messages.";
|
||||
"screen_report_content_hint" = "Reason for reporting this content";
|
||||
"screen_reset_encryption_confirmation_alert_action" = "Yes, reset now";
|
||||
"screen_reset_encryption_confirmation_alert_subtitle" = "This process is irreversible.";
|
||||
"screen_reset_encryption_confirmation_alert_title" = "Are you sure you want to reset your encryption?";
|
||||
"screen_reset_encryption_password_placeholder" = "Enter…";
|
||||
"screen_reset_encryption_password_subtitle" = "Confirm that you want to reset your encryption.";
|
||||
"screen_reset_encryption_password_title" = "Enter your account password to continue";
|
||||
"screen_room_alias_resolver_resolve_alias_failure" = "Failed to resolve room alias.";
|
||||
"screen_room_attachment_source_camera" = "Camera";
|
||||
"screen_room_attachment_source_camera_video" = "Record video";
|
||||
@ -922,6 +937,7 @@
|
||||
"screen_dm_details_unblock_user" = "Unblock user";
|
||||
"screen_edit_poll_delete_confirmation_title" = "Delete Poll";
|
||||
"screen_edit_poll_title" = "Edit poll";
|
||||
"screen_identity_use_another_device" = "Use another device";
|
||||
"screen_login_subtitle" = "Matrix is an open network for secure, decentralised communication.";
|
||||
"screen_qr_code_login_invalid_scan_state_retry_button" = "Try again";
|
||||
"screen_report_content_block_user" = "Block user";
|
||||
|
@ -26,6 +26,7 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private let notificationManager: NotificationManagerProtocol
|
||||
private let rootNavigationStackCoordinator: NavigationStackCoordinator
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let windowManager: WindowManagerProtocol
|
||||
private let isNewLogin: Bool
|
||||
|
||||
private var navigationStackCoordinator: NavigationStackCoordinator!
|
||||
@ -57,6 +58,7 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
|
||||
notificationManager: NotificationManagerProtocol,
|
||||
navigationStackCoordinator: NavigationStackCoordinator,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
windowManager: WindowManagerProtocol,
|
||||
isNewLogin: Bool) {
|
||||
self.userSession = userSession
|
||||
self.appLockService = appLockService
|
||||
@ -64,6 +66,7 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
|
||||
self.appSettings = appSettings
|
||||
self.notificationManager = notificationManager
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.windowManager = windowManager
|
||||
self.isNewLogin = isNewLogin
|
||||
|
||||
rootNavigationStackCoordinator = navigationStackCoordinator
|
||||
@ -215,7 +218,7 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
|
||||
appSettings.hasRunIdentityConfirmationOnboarding = true
|
||||
stateMachine.tryEvent(.next)
|
||||
case .reset:
|
||||
presentResetRecoveryKeyScreen()
|
||||
presentEncryptionResetScreen()
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
@ -262,8 +265,8 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case .recoveryFixed:
|
||||
appSettings.hasRunIdentityConfirmationOnboarding = true
|
||||
stateMachine.tryEvent(.next)
|
||||
case .showResetKeyInfo:
|
||||
presentResetRecoveryKeyScreen()
|
||||
case .resetEncryption:
|
||||
presentEncryptionResetScreen()
|
||||
default:
|
||||
MXLog.error("Unexpected recovery action: \(action)")
|
||||
}
|
||||
@ -273,16 +276,32 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
|
||||
presentCoordinator(coordinator)
|
||||
}
|
||||
|
||||
private func presentResetRecoveryKeyScreen() {
|
||||
let coordinator = ResetRecoveryKeyScreenCoordinator()
|
||||
private func presentEncryptionResetScreen() {
|
||||
let resetNavigationStackCoordinator = NavigationStackCoordinator()
|
||||
|
||||
let coordinator = EncryptionResetScreenCoordinator(parameters: .init(clientProxy: userSession.clientProxy,
|
||||
navigationStackCoordinator: resetNavigationStackCoordinator,
|
||||
userIndicatorController: userIndicatorController))
|
||||
|
||||
coordinator.actionsPublisher.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .cancel:
|
||||
self?.navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
case .requestOIDCAuthorisation(let url):
|
||||
presentOIDCAuthorisationScreen(url: url)
|
||||
case .resetFinished:
|
||||
appSettings.hasRunIdentityConfirmationOnboarding = true
|
||||
stateMachine.tryEvent(.next)
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
navigationStackCoordinator.setSheetCoordinator(coordinator)
|
||||
|
||||
resetNavigationStackCoordinator.setRootCoordinator(coordinator)
|
||||
|
||||
navigationStackCoordinator.setSheetCoordinator(resetNavigationStackCoordinator)
|
||||
}
|
||||
|
||||
private func presentIdentityConfirmedScreen() {
|
||||
@ -361,4 +380,12 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
|
||||
navigationStackCoordinator.push(coordinator)
|
||||
}
|
||||
}
|
||||
|
||||
private var accountSettingsPresenter: OIDCAccountSettingsPresenter?
|
||||
private func presentOIDCAuthorisationScreen(url: URL) {
|
||||
// Note to anyone in the future if you come back here to make this open in Safari instead of a WAS.
|
||||
// As of iOS 16, there is an issue on the simulator with accessing the cookie but it works on a device. 🤷♂️
|
||||
accountSettingsPresenter = OIDCAccountSettingsPresenter(accountURL: url, presentationAnchor: windowManager.mainWindow)
|
||||
accountSettingsPresenter?.start()
|
||||
}
|
||||
}
|
||||
|
@ -153,10 +153,18 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
private func presentSecureBackupScreen(animated: Bool) {
|
||||
let coordinator = SecureBackupScreenCoordinator(parameters: .init(appSettings: parameters.appSettings,
|
||||
secureBackupController: parameters.userSession.clientProxy.secureBackupController,
|
||||
clientProxy: parameters.userSession.clientProxy,
|
||||
navigationStackCoordinator: navigationStackCoordinator,
|
||||
userIndicatorController: parameters.userIndicatorController))
|
||||
|
||||
coordinator.actions.sink { [weak self] action in
|
||||
switch action {
|
||||
case .requestOIDCAuthorisation(let url):
|
||||
self?.presentAccountManagementURL(url)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
navigationStackCoordinator.push(coordinator, animated: animated)
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
notificationManager: notificationManager,
|
||||
navigationStackCoordinator: detailNavigationStackCoordinator,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
windowManager: appMediator.windowManager,
|
||||
isNewLogin: isNewLogin)
|
||||
|
||||
setupStateMachine()
|
||||
|
@ -196,6 +196,8 @@ internal enum L10n {
|
||||
internal static var actionReportContent: String { return L10n.tr("Localizable", "action_report_content") }
|
||||
/// Reset
|
||||
internal static var actionReset: String { return L10n.tr("Localizable", "action_reset") }
|
||||
/// Reset identity
|
||||
internal static var actionResetIdentity: String { return L10n.tr("Localizable", "action_reset_identity") }
|
||||
/// Retry
|
||||
internal static var actionRetry: String { return L10n.tr("Localizable", "action_retry") }
|
||||
/// Retry decryption
|
||||
@ -1045,12 +1047,30 @@ internal enum L10n {
|
||||
internal static var screenEditProfileTitle: String { return L10n.tr("Localizable", "screen_edit_profile_title") }
|
||||
/// Updating profile…
|
||||
internal static var screenEditProfileUpdatingDetails: String { return L10n.tr("Localizable", "screen_edit_profile_updating_details") }
|
||||
/// Your account details, contacts, preferences, and chat list will be kept
|
||||
internal static var screenEncryptionResetBullet1: String { return L10n.tr("Localizable", "screen_encryption_reset_bullet_1") }
|
||||
/// You will lose your existing message history
|
||||
internal static var screenEncryptionResetBullet2: String { return L10n.tr("Localizable", "screen_encryption_reset_bullet_2") }
|
||||
/// You will need to verify all your existing devices and contacts again
|
||||
internal static var screenEncryptionResetBullet3: String { return L10n.tr("Localizable", "screen_encryption_reset_bullet_3") }
|
||||
/// Only reset your identity if you don’t have access to another signed-in device and you’ve lost your recovery key.
|
||||
internal static var screenEncryptionResetFooter: String { return L10n.tr("Localizable", "screen_encryption_reset_footer") }
|
||||
/// If you’re not signed in to any other devices and you’ve lost your recovery key, then you’ll need to reset your identity to continue using the app.
|
||||
internal static var screenEncryptionResetSubtitle: String { return L10n.tr("Localizable", "screen_encryption_reset_subtitle") }
|
||||
/// Reset your identity in case you can’t confirm another way
|
||||
internal static var screenEncryptionResetTitle: String { return L10n.tr("Localizable", "screen_encryption_reset_title") }
|
||||
/// Can't confirm?
|
||||
internal static var screenIdentityConfirmationCannotConfirm: String { return L10n.tr("Localizable", "screen_identity_confirmation_cannot_confirm") }
|
||||
/// Create a new recovery key
|
||||
internal static var screenIdentityConfirmationCreateNewRecoveryKey: String { return L10n.tr("Localizable", "screen_identity_confirmation_create_new_recovery_key") }
|
||||
/// Verify this device to set up secure messaging.
|
||||
internal static var screenIdentityConfirmationSubtitle: String { return L10n.tr("Localizable", "screen_identity_confirmation_subtitle") }
|
||||
/// Confirm that it's you
|
||||
internal static var screenIdentityConfirmationTitle: String { return L10n.tr("Localizable", "screen_identity_confirmation_title") }
|
||||
/// Use another device
|
||||
internal static var screenIdentityConfirmationUseAnotherDevice: String { return L10n.tr("Localizable", "screen_identity_confirmation_use_another_device") }
|
||||
/// Use recovery key
|
||||
internal static var screenIdentityConfirmationUseRecoveryKey: String { return L10n.tr("Localizable", "screen_identity_confirmation_use_recovery_key") }
|
||||
/// Now you can read or send messages securely, and anyone you chat with can also trust this device.
|
||||
internal static var screenIdentityConfirmedSubtitle: String { return L10n.tr("Localizable", "screen_identity_confirmed_subtitle") }
|
||||
/// Device verified
|
||||
@ -1385,6 +1405,18 @@ internal enum L10n {
|
||||
internal static var screenReportContentExplanation: String { return L10n.tr("Localizable", "screen_report_content_explanation") }
|
||||
/// Reason for reporting this content
|
||||
internal static var screenReportContentHint: String { return L10n.tr("Localizable", "screen_report_content_hint") }
|
||||
/// Yes, reset now
|
||||
internal static var screenResetEncryptionConfirmationAlertAction: String { return L10n.tr("Localizable", "screen_reset_encryption_confirmation_alert_action") }
|
||||
/// This process is irreversible.
|
||||
internal static var screenResetEncryptionConfirmationAlertSubtitle: String { return L10n.tr("Localizable", "screen_reset_encryption_confirmation_alert_subtitle") }
|
||||
/// Are you sure you want to reset your encryption?
|
||||
internal static var screenResetEncryptionConfirmationAlertTitle: String { return L10n.tr("Localizable", "screen_reset_encryption_confirmation_alert_title") }
|
||||
/// Enter…
|
||||
internal static var screenResetEncryptionPasswordPlaceholder: String { return L10n.tr("Localizable", "screen_reset_encryption_password_placeholder") }
|
||||
/// Confirm that you want to reset your encryption.
|
||||
internal static var screenResetEncryptionPasswordSubtitle: String { return L10n.tr("Localizable", "screen_reset_encryption_password_subtitle") }
|
||||
/// Enter your account password to continue
|
||||
internal static var screenResetEncryptionPasswordTitle: String { return L10n.tr("Localizable", "screen_reset_encryption_password_title") }
|
||||
/// Failed to resolve room alias.
|
||||
internal static var screenRoomAliasResolverResolveAliasFailure: String { return L10n.tr("Localizable", "screen_room_alias_resolver_resolve_alias_failure") }
|
||||
/// Camera
|
||||
|
@ -4095,6 +4095,70 @@ class ClientProxyMock: ClientProxyProtocol {
|
||||
return curve25519Base64ReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - resetIdentity
|
||||
|
||||
var resetIdentityUnderlyingCallsCount = 0
|
||||
var resetIdentityCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return resetIdentityUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = resetIdentityUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
resetIdentityUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
resetIdentityUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var resetIdentityCalled: Bool {
|
||||
return resetIdentityCallsCount > 0
|
||||
}
|
||||
|
||||
var resetIdentityUnderlyingReturnValue: Result<IdentityResetHandle?, ClientProxyError>!
|
||||
var resetIdentityReturnValue: Result<IdentityResetHandle?, ClientProxyError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return resetIdentityUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<IdentityResetHandle?, ClientProxyError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = resetIdentityUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
resetIdentityUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
resetIdentityUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var resetIdentityClosure: (() async -> Result<IdentityResetHandle?, ClientProxyError>)?
|
||||
|
||||
func resetIdentity() async -> Result<IdentityResetHandle?, ClientProxyError> {
|
||||
resetIdentityCallsCount += 1
|
||||
if let resetIdentityClosure = resetIdentityClosure {
|
||||
return await resetIdentityClosure()
|
||||
} else {
|
||||
return resetIdentityReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - loadMediaContentForSource
|
||||
|
||||
var loadMediaContentForSourceThrowableError: Error?
|
||||
|
@ -5915,6 +5915,75 @@ open class EncryptionSDKMock: MatrixRustSDK.Encryption {
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - resetIdentity
|
||||
|
||||
open var resetIdentityThrowableError: Error?
|
||||
var resetIdentityUnderlyingCallsCount = 0
|
||||
open var resetIdentityCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return resetIdentityUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = resetIdentityUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
resetIdentityUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
resetIdentityUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
open var resetIdentityCalled: Bool {
|
||||
return resetIdentityCallsCount > 0
|
||||
}
|
||||
|
||||
var resetIdentityUnderlyingReturnValue: IdentityResetHandle?
|
||||
open var resetIdentityReturnValue: IdentityResetHandle? {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return resetIdentityUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: IdentityResetHandle?? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = resetIdentityUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
resetIdentityUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
resetIdentityUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
open var resetIdentityClosure: (() async throws -> IdentityResetHandle?)?
|
||||
|
||||
open override func resetIdentity() async throws -> IdentityResetHandle? {
|
||||
if let error = resetIdentityThrowableError {
|
||||
throw error
|
||||
}
|
||||
resetIdentityCallsCount += 1
|
||||
if let resetIdentityClosure = resetIdentityClosure {
|
||||
return try await resetIdentityClosure()
|
||||
} else {
|
||||
return resetIdentityReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - resetRecoveryKey
|
||||
|
||||
open var resetRecoveryKeyThrowableError: Error?
|
||||
@ -7595,6 +7664,128 @@ open class HomeserverLoginDetailsSDKMock: MatrixRustSDK.HomeserverLoginDetails {
|
||||
}
|
||||
}
|
||||
}
|
||||
open class IdentityResetHandleSDKMock: MatrixRustSDK.IdentityResetHandle {
|
||||
init() {
|
||||
super.init(noPointer: .init())
|
||||
}
|
||||
|
||||
public required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
|
||||
fatalError("init(unsafeFromRawPointer:) has not been implemented")
|
||||
}
|
||||
|
||||
fileprivate var pointer: UnsafeMutableRawPointer!
|
||||
|
||||
//MARK: - authType
|
||||
|
||||
var authTypeUnderlyingCallsCount = 0
|
||||
open var authTypeCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return authTypeUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = authTypeUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
authTypeUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
authTypeUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
open var authTypeCalled: Bool {
|
||||
return authTypeCallsCount > 0
|
||||
}
|
||||
|
||||
var authTypeUnderlyingReturnValue: CrossSigningResetAuthType!
|
||||
open var authTypeReturnValue: CrossSigningResetAuthType! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return authTypeUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: CrossSigningResetAuthType? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = authTypeUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
authTypeUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
authTypeUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
open var authTypeClosure: (() -> CrossSigningResetAuthType)?
|
||||
|
||||
open override func authType() -> CrossSigningResetAuthType {
|
||||
authTypeCallsCount += 1
|
||||
if let authTypeClosure = authTypeClosure {
|
||||
return authTypeClosure()
|
||||
} else {
|
||||
return authTypeReturnValue
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - reset
|
||||
|
||||
open var resetAuthThrowableError: Error?
|
||||
var resetAuthUnderlyingCallsCount = 0
|
||||
open var resetAuthCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return resetAuthUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = resetAuthUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
resetAuthUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
resetAuthUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
open var resetAuthCalled: Bool {
|
||||
return resetAuthCallsCount > 0
|
||||
}
|
||||
open var resetAuthReceivedAuth: AuthData?
|
||||
open var resetAuthReceivedInvocations: [AuthData?] = []
|
||||
open var resetAuthClosure: ((AuthData?) async throws -> Void)?
|
||||
|
||||
open override func reset(auth: AuthData?) async throws {
|
||||
if let error = resetAuthThrowableError {
|
||||
throw error
|
||||
}
|
||||
resetAuthCallsCount += 1
|
||||
resetAuthReceivedAuth = auth
|
||||
DispatchQueue.main.async {
|
||||
self.resetAuthReceivedInvocations.append(auth)
|
||||
}
|
||||
try await resetAuthClosure?(auth)
|
||||
}
|
||||
}
|
||||
open class MediaFileHandleSDKMock: MatrixRustSDK.MediaFileHandle {
|
||||
init() {
|
||||
super.init(noPointer: .init())
|
||||
|
@ -58,12 +58,11 @@ struct RoundedLabelItem<Icon: View>: View {
|
||||
|
||||
private struct CheckmarkLabelStyle: LabelStyle {
|
||||
func makeBody(configuration: Configuration) -> some View {
|
||||
HStack(alignment: .firstTextBaseline, spacing: 16) {
|
||||
HStack(alignment: .top, spacing: 16) {
|
||||
configuration.icon
|
||||
.font(.compound.bodyLGSemibold)
|
||||
configuration.title
|
||||
.font(.compound.bodyMDSemibold)
|
||||
}
|
||||
.font(.compound.bodyMD)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,68 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// periphery:ignore:all - this is just a encryptionResetPassword remove this comment once generating the final file
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
struct EncryptionResetPasswordScreenCoordinatorParameters { }
|
||||
|
||||
enum EncryptionResetPasswordScreenCoordinatorAction: CustomStringConvertible {
|
||||
case resetIdentity(String)
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .resetIdentity:
|
||||
"resetIdentity"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class EncryptionResetPasswordScreenCoordinator: CoordinatorProtocol {
|
||||
private let parameters: EncryptionResetPasswordScreenCoordinatorParameters
|
||||
private let viewModel: EncryptionResetPasswordScreenViewModelProtocol
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private let actionsSubject: PassthroughSubject<EncryptionResetPasswordScreenCoordinatorAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<EncryptionResetPasswordScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(parameters: EncryptionResetPasswordScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
|
||||
viewModel = EncryptionResetPasswordScreenViewModel()
|
||||
}
|
||||
|
||||
func start() {
|
||||
viewModel.actionsPublisher.sink { [weak self] action in
|
||||
MXLog.info("Coordinator: received view model action: \(action)")
|
||||
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .resetIdentity(let password):
|
||||
self.actionsSubject.send(.resetIdentity(password))
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func toPresentable() -> AnyView {
|
||||
AnyView(EncryptionResetPasswordScreen(context: viewModel.context))
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum EncryptionResetPasswordScreenViewModelAction: CustomStringConvertible {
|
||||
case resetIdentity(String)
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .resetIdentity:
|
||||
"resetIdentity"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct EncryptionResetPasswordScreenViewState: BindableState {
|
||||
var bindings: EncryptionResetPasswordScreenViewStateBindings
|
||||
}
|
||||
|
||||
struct EncryptionResetPasswordScreenViewStateBindings {
|
||||
var password: String
|
||||
var alertInfo: AlertInfo<UUID>?
|
||||
}
|
||||
|
||||
enum EncryptionResetPasswordScreenViewAction {
|
||||
case resetIdentity
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias EncryptionResetPasswordScreenViewModelType = StateStoreViewModel<EncryptionResetPasswordScreenViewState, EncryptionResetPasswordScreenViewAction>
|
||||
|
||||
class EncryptionResetPasswordScreenViewModel: EncryptionResetPasswordScreenViewModelType, EncryptionResetPasswordScreenViewModelProtocol {
|
||||
private let actionsSubject: PassthroughSubject<EncryptionResetPasswordScreenViewModelAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<EncryptionResetPasswordScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init() {
|
||||
super.init(initialViewState: .init(bindings: .init(password: "")))
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
override func process(viewAction: EncryptionResetPasswordScreenViewAction) {
|
||||
MXLog.info("View model: received view action: \(viewAction)")
|
||||
|
||||
switch viewAction {
|
||||
case .resetIdentity:
|
||||
actionsSubject.send(.resetIdentity(state.bindings.password))
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
import Combine
|
||||
|
||||
@MainActor
|
||||
protocol ResetRecoveryKeyScreenViewModelProtocol {
|
||||
var actionsPublisher: AnyPublisher<ResetRecoveryKeyScreenViewModelAction, Never> { get }
|
||||
var context: ResetRecoveryKeyScreenViewModelType.Context { get }
|
||||
protocol EncryptionResetPasswordScreenViewModelProtocol {
|
||||
var actionsPublisher: AnyPublisher<EncryptionResetPasswordScreenViewModelAction, Never> { get }
|
||||
var context: EncryptionResetPasswordScreenViewModelType.Context { get }
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct EncryptionResetPasswordScreen: View {
|
||||
@ObservedObject var context: EncryptionResetPasswordScreenViewModel.Context
|
||||
@FocusState private var textFieldFocus
|
||||
|
||||
var body: some View {
|
||||
FullscreenDialog {
|
||||
VStack(spacing: 16) {
|
||||
HeroImage(icon: \.lockSolid)
|
||||
|
||||
Text(L10n.screenResetEncryptionPasswordTitle)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
.font(.compound.headingMDBold)
|
||||
.multilineTextAlignment(.center)
|
||||
|
||||
Text(L10n.screenResetEncryptionPasswordSubtitle)
|
||||
.foregroundColor(.compound.textSecondary)
|
||||
.font(.compound.bodyMD)
|
||||
.multilineTextAlignment(.center)
|
||||
|
||||
passwordSection
|
||||
}
|
||||
.padding(16)
|
||||
} bottomContent: {
|
||||
Button(L10n.actionResetIdentity, role: .destructive) {
|
||||
context.send(viewAction: .resetIdentity)
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
}
|
||||
.backgroundStyle(.compound.bgCanvasDefault)
|
||||
.interactiveDismissDisabled()
|
||||
.onAppear { textFieldFocus = true }
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var passwordSection: some View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text(L10n.commonPassword)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
.font(.compound.bodySMSemibold)
|
||||
|
||||
SecureField(L10n.screenResetEncryptionPasswordPlaceholder, text: $context.password)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
.background(Color.compound.bgSubtleSecondaryLevel0)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 8))
|
||||
.focused($textFieldFocus)
|
||||
.submitLabel(.done)
|
||||
.onSubmit {
|
||||
context.send(viewAction: .resetIdentity)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct EncryptionResetPasswordScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static let viewModel = EncryptionResetPasswordScreenViewModel()
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
EncryptionResetPasswordScreen(context: viewModel.context)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
enum EncryptionResetScreenCoordinatorAction {
|
||||
case cancel
|
||||
case requestOIDCAuthorisation(URL)
|
||||
case resetFinished
|
||||
}
|
||||
|
||||
struct EncryptionResetScreenCoordinatorParameters {
|
||||
let clientProxy: ClientProxyProtocol
|
||||
let navigationStackCoordinator: NavigationStackCoordinator
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
}
|
||||
|
||||
final class EncryptionResetScreenCoordinator: CoordinatorProtocol {
|
||||
private let parameters: EncryptionResetScreenCoordinatorParameters
|
||||
private let viewModel: EncryptionResetScreenViewModelProtocol
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private let actionsSubject: PassthroughSubject<EncryptionResetScreenCoordinatorAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<EncryptionResetScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(parameters: EncryptionResetScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
viewModel = EncryptionResetScreenViewModel(clientProxy: parameters.clientProxy,
|
||||
userIndicatorController: parameters.userIndicatorController)
|
||||
}
|
||||
|
||||
func start() {
|
||||
viewModel.actionsPublisher.sink { [weak self] action in
|
||||
MXLog.info("Coordinator: received view model action: \(action)")
|
||||
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .requestPassword:
|
||||
presentPasswordScreen()
|
||||
case .requestOIDCAuthorisation(let url):
|
||||
self.actionsSubject.send(.requestOIDCAuthorisation(url))
|
||||
case .resetFinished:
|
||||
self.actionsSubject.send(.resetFinished)
|
||||
case .cancel:
|
||||
self.actionsSubject.send(.cancel)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func toPresentable() -> AnyView {
|
||||
AnyView(EncryptionResetScreen(context: viewModel.context))
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func presentPasswordScreen() {
|
||||
let coordinator = EncryptionResetPasswordScreenCoordinator(parameters: .init())
|
||||
|
||||
coordinator.actionsPublisher.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .resetIdentity(let password):
|
||||
viewModel.continueResetFlowWith(password: password)
|
||||
parameters.navigationStackCoordinator.pop()
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
parameters.navigationStackCoordinator.push(coordinator)
|
||||
}
|
||||
}
|
@ -16,11 +16,14 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
enum ResetRecoveryKeyScreenViewModelAction {
|
||||
enum EncryptionResetScreenViewModelAction {
|
||||
case requestPassword
|
||||
case requestOIDCAuthorisation(url: URL)
|
||||
case resetFinished
|
||||
case cancel
|
||||
}
|
||||
|
||||
struct ResetRecoveryKeyScreenViewState: BindableState {
|
||||
struct EncryptionResetScreenViewState: BindableState {
|
||||
private let listItem3AttributedText = {
|
||||
let boldPlaceholder = "{bold}"
|
||||
var finalString = AttributedString(L10n.screenCreateNewRecoveryKeyListItem3(boldPlaceholder))
|
||||
@ -39,8 +42,15 @@ struct ResetRecoveryKeyScreenViewState: BindableState {
|
||||
AttributedString(L10n.screenCreateNewRecoveryKeyListItem5)
|
||||
]
|
||||
}
|
||||
|
||||
var bindings: EncryptionResetScreenViewStateBindings
|
||||
}
|
||||
|
||||
enum ResetRecoveryKeyScreenViewAction {
|
||||
struct EncryptionResetScreenViewStateBindings {
|
||||
var alertInfo: AlertInfo<UUID>?
|
||||
}
|
||||
|
||||
enum EncryptionResetScreenViewAction {
|
||||
case reset
|
||||
case cancel
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import MatrixRustSDK
|
||||
import SwiftUI
|
||||
|
||||
typealias EncryptionResetScreenViewModelType = StateStoreViewModel<EncryptionResetScreenViewState, EncryptionResetScreenViewAction>
|
||||
|
||||
class EncryptionResetScreenViewModel: EncryptionResetScreenViewModelType, EncryptionResetScreenViewModelProtocol {
|
||||
private let clientProxy: ClientProxyProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
private let actionsSubject: PassthroughSubject<EncryptionResetScreenViewModelAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<EncryptionResetScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
private var identityResetHandle: IdentityResetHandle?
|
||||
|
||||
init(clientProxy: ClientProxyProtocol, userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
self.clientProxy = clientProxy
|
||||
self.userIndicatorController = userIndicatorController
|
||||
|
||||
super.init(initialViewState: EncryptionResetScreenViewState(bindings: .init()))
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
override func process(viewAction: EncryptionResetScreenViewAction) {
|
||||
switch viewAction {
|
||||
case .reset:
|
||||
state.bindings.alertInfo = .init(id: UUID(),
|
||||
title: L10n.screenResetEncryptionConfirmationAlertTitle,
|
||||
message: L10n.screenResetEncryptionConfirmationAlertSubtitle,
|
||||
primaryButton: .init(title: L10n.screenResetEncryptionConfirmationAlertAction, role: .destructive, action: { [weak self] in
|
||||
guard let self else { return }
|
||||
Task { await self.startResetFlow() }
|
||||
}))
|
||||
case .cancel:
|
||||
actionsSubject.send(.cancel)
|
||||
}
|
||||
}
|
||||
|
||||
func continueResetFlowWith(password: String) {
|
||||
Task {
|
||||
await resetWith(password: password)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func startResetFlow() async {
|
||||
showLoadingIndicator()
|
||||
|
||||
defer {
|
||||
hideLoadingIndicator()
|
||||
}
|
||||
|
||||
switch await clientProxy.resetIdentity() {
|
||||
case .success(let handle):
|
||||
// If the handle is missing then interactive authentication wasn't
|
||||
// necessary and the reset proceeded as normal
|
||||
guard let handle else {
|
||||
actionsSubject.send(.resetFinished)
|
||||
return
|
||||
}
|
||||
|
||||
identityResetHandle = handle
|
||||
|
||||
switch handle.authType() {
|
||||
case .uiaa:
|
||||
actionsSubject.send(.requestPassword)
|
||||
case .oidc(let oidcInfo):
|
||||
guard let url = URL(string: oidcInfo.approvalUrl) else {
|
||||
fatalError("Invalid URL received through identity reset handle: \(oidcInfo.approvalUrl)")
|
||||
}
|
||||
|
||||
hideLoadingIndicator()
|
||||
|
||||
actionsSubject.send(.requestOIDCAuthorisation(url: url))
|
||||
|
||||
await resetWithOIDCAuthorisation()
|
||||
}
|
||||
case .failure(let error):
|
||||
MXLog.error("Failed resetting encryption with error \(error)")
|
||||
showErrorToast()
|
||||
}
|
||||
}
|
||||
|
||||
func resetWith(password: String) async {
|
||||
guard let identityResetHandle else {
|
||||
fatalError("Requested reset flow continuation without a stored handle")
|
||||
}
|
||||
|
||||
showLoadingIndicator()
|
||||
|
||||
defer {
|
||||
hideLoadingIndicator()
|
||||
}
|
||||
|
||||
do {
|
||||
try await identityResetHandle.reset(auth: .password(passwordDetails: .init(identifier: clientProxy.userID, password: password)))
|
||||
actionsSubject.send(.resetFinished)
|
||||
} catch {
|
||||
MXLog.error("Failed resetting encryption with error \(error)")
|
||||
showErrorToast()
|
||||
}
|
||||
}
|
||||
|
||||
private func resetWithOIDCAuthorisation() async {
|
||||
guard let identityResetHandle else {
|
||||
fatalError("Requested reset flow continuation without a stored handle")
|
||||
}
|
||||
|
||||
do {
|
||||
try await identityResetHandle.reset(auth: nil)
|
||||
actionsSubject.send(.resetFinished)
|
||||
} catch {
|
||||
MXLog.error("Failed resetting encryption with error \(error)")
|
||||
showErrorToast()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Toasts and loading indicators
|
||||
|
||||
private static let loadingIndicatorIdentifier = "\(EncryptionResetScreenViewModel.self)-Loading"
|
||||
|
||||
private func showLoadingIndicator() {
|
||||
userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal,
|
||||
title: L10n.commonLoading,
|
||||
persistent: true))
|
||||
}
|
||||
|
||||
private func hideLoadingIndicator() {
|
||||
userIndicatorController.retractIndicatorWithId(Self.loadingIndicatorIdentifier)
|
||||
}
|
||||
|
||||
private func showErrorToast() {
|
||||
userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
|
||||
@MainActor
|
||||
protocol EncryptionResetScreenViewModelProtocol {
|
||||
var actionsPublisher: AnyPublisher<EncryptionResetScreenViewModelAction, Never> { get }
|
||||
var context: EncryptionResetScreenViewModelType.Context { get }
|
||||
|
||||
func continueResetFlowWith(password: String)
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct EncryptionResetScreen: View {
|
||||
@ObservedObject var context: EncryptionResetScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
FullscreenDialog {
|
||||
mainContent
|
||||
} bottomContent: {
|
||||
Button(L10n.actionContinue, role: .destructive) {
|
||||
context.send(viewAction: .reset)
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
}
|
||||
.background()
|
||||
.backgroundStyle(.compound.bgSubtleSecondary)
|
||||
.interactiveDismissDisabled()
|
||||
.toolbar { toolbar }
|
||||
.toolbar(.visible, for: .navigationBar)
|
||||
.alert(item: $context.alertInfo)
|
||||
}
|
||||
|
||||
/// The main content of the screen that is shown inside the scroll view.
|
||||
private var mainContent: some View {
|
||||
VStack(spacing: 24) {
|
||||
header
|
||||
checkmarkList
|
||||
footer
|
||||
}
|
||||
}
|
||||
|
||||
private var header: some View {
|
||||
VStack(spacing: 8) {
|
||||
HeroImage(icon: \.error, style: .critical)
|
||||
.padding(.bottom, 8)
|
||||
|
||||
Text(L10n.screenEncryptionResetTitle)
|
||||
.font(.compound.headingMDBold)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
|
||||
Text(L10n.screenEncryptionResetSubtitle)
|
||||
.font(.compound.bodyMD)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.compound.textSecondary)
|
||||
}
|
||||
}
|
||||
|
||||
private var footer: some View {
|
||||
Text(L10n.screenEncryptionResetFooter)
|
||||
.font(.compound.bodyMDSemibold)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
}
|
||||
|
||||
/// The list of re-assurances about analytics.
|
||||
private var checkmarkList: some View {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
checkMarkItem(title: L10n.screenEncryptionResetBullet1, position: .top, positive: true)
|
||||
checkMarkItem(title: L10n.screenEncryptionResetBullet2, position: .middle, positive: false)
|
||||
checkMarkItem(title: L10n.screenEncryptionResetBullet3, position: .bottom, positive: false)
|
||||
}
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.frame(maxWidth: .infinity)
|
||||
.environment(\.backgroundStyle, AnyShapeStyle(.compound.bgSubtleSecondary))
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func checkMarkItem(title: String, position: ListPosition, positive: Bool) -> some View {
|
||||
RoundedLabelItem(title: title, listPosition: position) {
|
||||
if positive {
|
||||
CompoundIcon(\.check)
|
||||
.foregroundColor(.compound.iconAccentPrimary)
|
||||
} else {
|
||||
CompoundIcon(\.close)
|
||||
.foregroundColor(.compound.iconCriticalPrimary)
|
||||
}
|
||||
}
|
||||
.backgroundStyle(.compound.bgCanvasDefault)
|
||||
}
|
||||
|
||||
@ToolbarContentBuilder
|
||||
private var toolbar: some ToolbarContent {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button(L10n.actionCancel) {
|
||||
context.send(viewAction: .cancel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct EncryptionResetScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static let viewModel = EncryptionResetScreenViewModel(clientProxy: ClientProxyMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
EncryptionResetScreen(context: viewModel.context)
|
||||
}
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Compound
|
||||
import SwiftUI
|
||||
|
||||
/// A prompt that asks the user whether they would like to enable Analytics or not.
|
||||
@ -58,14 +59,6 @@ struct AnalyticsPromptScreen: View {
|
||||
.foregroundColor(.compound.textSecondary)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var checkMark: some View {
|
||||
Image(systemName: "checkmark.circle")
|
||||
.symbolVariant(.fill)
|
||||
.symbolRenderingMode(.palette)
|
||||
.foregroundStyle(Color.compound.iconAccentTertiary, Color.compound.textOnSolidPrimary)
|
||||
}
|
||||
|
||||
/// The list of re-assurances about analytics.
|
||||
private var checkmarkList: some View {
|
||||
@ -82,7 +75,8 @@ struct AnalyticsPromptScreen: View {
|
||||
@ViewBuilder
|
||||
private func checkMarkItem(title: String, position: ListPosition) -> some View {
|
||||
RoundedLabelItem(title: title, listPosition: position) {
|
||||
checkMark
|
||||
CompoundIcon(\.checkCircle, size: .small, relativeTo: .body)
|
||||
.foregroundColor(.compound.iconAccentPrimary)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,21 +70,21 @@ struct IdentityConfirmationScreen: View {
|
||||
|
||||
@ViewBuilder
|
||||
private var actionButtons: some View {
|
||||
VStack(spacing: 32) {
|
||||
VStack(spacing: 16) {
|
||||
if context.viewState.availableActions.contains(.interactiveVerification) {
|
||||
Button(L10n.actionStartVerification) {
|
||||
Button(L10n.screenIdentityConfirmationUseAnotherDevice) {
|
||||
context.send(viewAction: .otherDevice)
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
|
||||
if context.viewState.availableActions.contains(.recovery) {
|
||||
Button(L10n.screenSessionVerificationEnterRecoveryKey) {
|
||||
Button(L10n.screenIdentityConfirmationUseRecoveryKey) {
|
||||
context.send(viewAction: .recoveryKey)
|
||||
}
|
||||
.buttonStyle(.compound(.plain))
|
||||
.buttonStyle(.compound(.secondary))
|
||||
}
|
||||
} else if context.viewState.availableActions.contains(.recovery) {
|
||||
Button(L10n.screenSessionVerificationEnterRecoveryKey) {
|
||||
Button(L10n.screenIdentityConfirmationUseRecoveryKey) {
|
||||
context.send(viewAction: .recoveryKey)
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
@ -97,10 +97,11 @@ struct IdentityConfirmationScreen: View {
|
||||
.buttonStyle(.compound(.plain))
|
||||
}
|
||||
|
||||
Button(L10n.screenRecoveryKeyConfirmLostRecoveryKey, role: .destructive) {
|
||||
Button(L10n.screenIdentityConfirmationCannotConfirm) {
|
||||
context.send(viewAction: .reset)
|
||||
}
|
||||
.buttonStyle(.compound(.plain))
|
||||
.padding(.vertical, 14)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -112,11 +113,13 @@ struct IdentityConfirmationScreen_Previews: PreviewProvider, TestablePreview {
|
||||
NavigationStack {
|
||||
IdentityConfirmationScreen(context: viewModel.context)
|
||||
}
|
||||
.snapshot(delay: 0.25)
|
||||
}
|
||||
|
||||
private static var viewModel: IdentityConfirmationScreenViewModel {
|
||||
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@user:example.com",
|
||||
roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded([])))))))
|
||||
let clientProxy = ClientProxyMock(.init())
|
||||
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||
userSession.sessionSecurityStatePublisher = CurrentValuePublisher<SessionSecurityState, Never>(.init(verificationState: .unverified, recoveryState: .enabled))
|
||||
|
||||
return IdentityConfirmationScreenViewModel(userSession: userSession,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
|
@ -1,56 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// periphery:ignore:all - this is just a resetKey remove this comment once generating the final file
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
enum ResetRecoveryKeyScreenCoordinatorAction {
|
||||
case cancel
|
||||
}
|
||||
|
||||
final class ResetRecoveryKeyScreenCoordinator: CoordinatorProtocol {
|
||||
private let viewModel: ResetRecoveryKeyScreenViewModelProtocol
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private let actionsSubject: PassthroughSubject<ResetRecoveryKeyScreenCoordinatorAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<ResetRecoveryKeyScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init() {
|
||||
viewModel = ResetRecoveryKeyScreenViewModel()
|
||||
}
|
||||
|
||||
func start() {
|
||||
viewModel.actionsPublisher.sink { [weak self] action in
|
||||
MXLog.info("Coordinator: received view model action: \(action)")
|
||||
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .cancel:
|
||||
self.actionsSubject.send(.cancel)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func toPresentable() -> AnyView {
|
||||
AnyView(ResetRecoveryKeyScreen(context: viewModel.context))
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias ResetRecoveryKeyScreenViewModelType = StateStoreViewModel<ResetRecoveryKeyScreenViewState, ResetRecoveryKeyScreenViewAction>
|
||||
|
||||
class ResetRecoveryKeyScreenViewModel: ResetRecoveryKeyScreenViewModelType, ResetRecoveryKeyScreenViewModelProtocol {
|
||||
private let actionsSubject: PassthroughSubject<ResetRecoveryKeyScreenViewModelAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<ResetRecoveryKeyScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init() {
|
||||
super.init(initialViewState: ResetRecoveryKeyScreenViewState())
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
override func process(viewAction: ResetRecoveryKeyScreenViewAction) {
|
||||
switch viewAction {
|
||||
case .cancel:
|
||||
// We might also need to display first an alert and do a logOut API call in some cases
|
||||
actionsSubject.send(.cancel)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct ResetRecoveryKeyScreen: View {
|
||||
@ObservedObject var context: ResetRecoveryKeyScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
FullscreenDialog {
|
||||
mainContent
|
||||
} bottomContent: {
|
||||
EmptyView()
|
||||
}
|
||||
.toolbar { toolbar }
|
||||
.toolbar(.visible, for: .navigationBar)
|
||||
.background()
|
||||
.backgroundStyle(.compound.bgSubtleSecondary)
|
||||
.interactiveDismissDisabled()
|
||||
}
|
||||
}
|
||||
|
||||
private var mainContent: some View {
|
||||
VStack(spacing: 40) {
|
||||
header
|
||||
SFNumberedListView(items: context.viewState.listItems)
|
||||
}
|
||||
}
|
||||
|
||||
private var header: some View {
|
||||
VStack(spacing: 16) {
|
||||
HeroImage(icon: \.computer, style: .subtle)
|
||||
|
||||
Text(L10n.screenCreateNewRecoveryKeyTitle)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
.font(.compound.headingMDBold)
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
}
|
||||
|
||||
@ToolbarContentBuilder
|
||||
private var toolbar: some ToolbarContent {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button(L10n.actionCancel) {
|
||||
context.send(viewAction: .cancel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct ResetRecoveryKeyScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static let viewModel = ResetRecoveryKeyScreenViewModel()
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
ResetRecoveryKeyScreen(context: viewModel.context)
|
||||
}
|
||||
}
|
||||
}
|
@ -28,7 +28,7 @@ enum SecureBackupRecoveryKeyScreenCoordinatorAction {
|
||||
case recoverySetUp
|
||||
case recoveryChanged
|
||||
case recoveryFixed
|
||||
case showResetKeyInfo
|
||||
case resetEncryption
|
||||
}
|
||||
|
||||
final class SecureBackupRecoveryKeyScreenCoordinator: CoordinatorProtocol {
|
||||
@ -65,8 +65,8 @@ final class SecureBackupRecoveryKeyScreenCoordinator: CoordinatorProtocol {
|
||||
case .unknown:
|
||||
fatalError()
|
||||
}
|
||||
case .showResetKeyInfo:
|
||||
self.actionsSubject.send(.showResetKeyInfo)
|
||||
case .resetEncryption:
|
||||
self.actionsSubject.send(.resetEncryption)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
@ -19,7 +19,7 @@ import Foundation
|
||||
enum SecureBackupRecoveryKeyScreenViewModelAction {
|
||||
case done(mode: SecureBackupRecoveryKeyScreenViewMode)
|
||||
case cancel
|
||||
case showResetKeyInfo
|
||||
case resetEncryption
|
||||
}
|
||||
|
||||
enum SecureBackupRecoveryKeyScreenViewMode {
|
||||
@ -90,7 +90,7 @@ enum SecureBackupRecoveryKeyScreenViewAction {
|
||||
case copyKey
|
||||
case keySaved
|
||||
case confirmKey
|
||||
case resetKey
|
||||
case resetEncryption
|
||||
case done
|
||||
case cancel
|
||||
}
|
||||
|
@ -40,13 +40,12 @@ class SecureBackupRecoveryKeyScreenViewModel: SecureBackupRecoveryKeyScreenViewM
|
||||
|
||||
secureBackupController.recoveryState
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(receiveValue: { [weak userIndicatorController] state in
|
||||
let loadingIndicatorIdentifier = "SecureBackupRecoveryKeyScreenLoading"
|
||||
.sink(receiveValue: { [weak self] state in
|
||||
switch state {
|
||||
case .settingUp:
|
||||
userIndicatorController?.submitIndicator(.init(id: loadingIndicatorIdentifier, type: .modal, title: L10n.commonLoading, persistent: true))
|
||||
self?.showLoadingIndicator()
|
||||
default:
|
||||
userIndicatorController?.retractIndicatorWithId(loadingIndicatorIdentifier)
|
||||
self?.hideLoadingIndicator()
|
||||
}
|
||||
})
|
||||
.store(in: &cancellables)
|
||||
@ -67,6 +66,8 @@ class SecureBackupRecoveryKeyScreenViewModel: SecureBackupRecoveryKeyScreenViewM
|
||||
MXLog.error("Failed generating recovery key with error: \(error)")
|
||||
state.bindings.alertInfo = .init(id: .init())
|
||||
}
|
||||
|
||||
hideLoadingIndicator()
|
||||
}
|
||||
case .copyKey:
|
||||
UIPasteboard.general.string = state.recoveryKey
|
||||
@ -76,8 +77,7 @@ class SecureBackupRecoveryKeyScreenViewModel: SecureBackupRecoveryKeyScreenViewM
|
||||
state.doneButtonEnabled = true
|
||||
case .confirmKey:
|
||||
Task {
|
||||
let loadingIndicatorIdentifier = "SecureBackupRecoveryKeyScreen"
|
||||
userIndicatorController.submitIndicator(.init(id: loadingIndicatorIdentifier, type: .modal, title: L10n.commonLoading, persistent: true))
|
||||
showLoadingIndicator()
|
||||
|
||||
switch await secureBackupController.confirmRecoveryKey(state.bindings.confirmationRecoveryKey) {
|
||||
case .success:
|
||||
@ -87,7 +87,7 @@ class SecureBackupRecoveryKeyScreenViewModel: SecureBackupRecoveryKeyScreenViewM
|
||||
state.bindings.alertInfo = .init(id: .init())
|
||||
}
|
||||
|
||||
userIndicatorController.retractIndicatorWithId(loadingIndicatorIdentifier)
|
||||
hideLoadingIndicator()
|
||||
}
|
||||
case .cancel:
|
||||
actionsSubject.send(.cancel)
|
||||
@ -100,10 +100,23 @@ class SecureBackupRecoveryKeyScreenViewModel: SecureBackupRecoveryKeyScreenViewM
|
||||
guard let self else { return }
|
||||
actionsSubject.send(.done(mode: context.viewState.mode))
|
||||
}))
|
||||
case .resetKey:
|
||||
actionsSubject.send(.showResetKeyInfo)
|
||||
case .resetEncryption:
|
||||
actionsSubject.send(.resetEncryption)
|
||||
}
|
||||
}
|
||||
|
||||
private static let loadingIndicatorIdentifier = "\(SecureBackupRecoveryKeyScreenViewModel.self)-Loading"
|
||||
|
||||
private func showLoadingIndicator() {
|
||||
userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal,
|
||||
title: L10n.commonLoading,
|
||||
persistent: true))
|
||||
}
|
||||
|
||||
private func hideLoadingIndicator() {
|
||||
userIndicatorController.retractIndicatorWithId(Self.loadingIndicatorIdentifier)
|
||||
}
|
||||
}
|
||||
|
||||
extension SecureBackupRecoveryState {
|
||||
|
@ -101,7 +101,7 @@ struct SecureBackupRecoveryKeyScreen: View {
|
||||
.disabled(context.confirmationRecoveryKey.isEmpty)
|
||||
|
||||
Button {
|
||||
context.send(viewAction: .resetKey)
|
||||
context.send(viewAction: .resetEncryption)
|
||||
} label: {
|
||||
Text(L10n.screenIdentityConfirmationCreateNewRecoveryKey)
|
||||
.padding(.vertical, 14)
|
||||
@ -205,9 +205,6 @@ struct SecureBackupRecoveryKeyScreen: View {
|
||||
.font(.compound.bodySMSemibold)
|
||||
|
||||
SecureField(L10n.screenRecoveryKeyConfirmKeyPlaceholder, text: $context.confirmationRecoveryKey)
|
||||
.textContentType(.password) // Not ideal but stops random suggestions
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
.background(Color.compound.bgSubtleSecondaryLevel0)
|
||||
|
@ -19,20 +19,30 @@ import SwiftUI
|
||||
|
||||
struct SecureBackupScreenCoordinatorParameters {
|
||||
let appSettings: AppSettings
|
||||
let secureBackupController: SecureBackupControllerProtocol
|
||||
let clientProxy: ClientProxyProtocol
|
||||
weak var navigationStackCoordinator: NavigationStackCoordinator?
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
}
|
||||
|
||||
enum SecureBackupScreenCoordinatorAction {
|
||||
case requestOIDCAuthorisation(URL)
|
||||
}
|
||||
|
||||
final class SecureBackupScreenCoordinator: CoordinatorProtocol {
|
||||
private let parameters: SecureBackupScreenCoordinatorParameters
|
||||
private var viewModel: SecureBackupScreenViewModelProtocol
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SecureBackupScreenCoordinatorAction, Never> = .init()
|
||||
var actions: AnyPublisher<SecureBackupScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(parameters: SecureBackupScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
|
||||
viewModel = SecureBackupScreenViewModel(secureBackupController: parameters.secureBackupController,
|
||||
viewModel = SecureBackupScreenViewModel(secureBackupController: parameters.clientProxy.secureBackupController,
|
||||
userIndicatorController: parameters.userIndicatorController,
|
||||
chatBackupDetailsURL: parameters.appSettings.chatBackupDetailsURL)
|
||||
}
|
||||
@ -43,9 +53,9 @@ final class SecureBackupScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
switch action {
|
||||
case .recoveryKey:
|
||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||
let recoveryNavigationStackCoordinator = NavigationStackCoordinator()
|
||||
|
||||
let recoveryKeyCoordinator = SecureBackupRecoveryKeyScreenCoordinator(parameters: .init(secureBackupController: parameters.secureBackupController,
|
||||
let recoveryKeyCoordinator = SecureBackupRecoveryKeyScreenCoordinator(parameters: .init(secureBackupController: parameters.clientProxy.secureBackupController,
|
||||
userIndicatorController: parameters.userIndicatorController,
|
||||
isModallyPresented: true))
|
||||
|
||||
@ -63,19 +73,19 @@ final class SecureBackupScreenCoordinator: CoordinatorProtocol {
|
||||
case .recoveryFixed:
|
||||
showSuccessIndicator(title: L10n.screenRecoveryKeyConfirmSuccess)
|
||||
parameters.navigationStackCoordinator?.setSheetCoordinator(nil)
|
||||
case .showResetKeyInfo:
|
||||
showResetRecoveryKeyScreen(navigationStackCoordinator: navigationStackCoordinator)
|
||||
case .resetEncryption:
|
||||
showEncryptionReset(recoveryNavigationStackCoordinator: recoveryNavigationStackCoordinator)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
navigationStackCoordinator.setRootCoordinator(recoveryKeyCoordinator, animated: true)
|
||||
recoveryNavigationStackCoordinator.setRootCoordinator(recoveryKeyCoordinator, animated: true)
|
||||
|
||||
parameters.navigationStackCoordinator?.setSheetCoordinator(navigationStackCoordinator)
|
||||
parameters.navigationStackCoordinator?.setSheetCoordinator(recoveryNavigationStackCoordinator)
|
||||
case .keyBackup:
|
||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||
|
||||
let keyBackupCoordinator = SecureBackupKeyBackupScreenCoordinator(parameters: .init(secureBackupController: parameters.secureBackupController,
|
||||
let keyBackupCoordinator = SecureBackupKeyBackupScreenCoordinator(parameters: .init(secureBackupController: parameters.clientProxy.secureBackupController,
|
||||
userIndicatorController: parameters.userIndicatorController))
|
||||
|
||||
keyBackupCoordinator.actions.sink { [weak self] action in
|
||||
@ -108,15 +118,30 @@ final class SecureBackupScreenCoordinator: CoordinatorProtocol {
|
||||
persistent: false))
|
||||
}
|
||||
|
||||
private func showResetRecoveryKeyScreen(navigationStackCoordinator: NavigationStackCoordinator) {
|
||||
let coordinator = ResetRecoveryKeyScreenCoordinator()
|
||||
coordinator.actionsPublisher.sink { action in
|
||||
private func showEncryptionReset(recoveryNavigationStackCoordinator: NavigationStackCoordinator) {
|
||||
let resetNavigationStackCoordinator = NavigationStackCoordinator()
|
||||
|
||||
let coordinator = EncryptionResetScreenCoordinator(parameters: .init(clientProxy: parameters.clientProxy,
|
||||
navigationStackCoordinator: resetNavigationStackCoordinator,
|
||||
userIndicatorController: parameters.userIndicatorController))
|
||||
|
||||
coordinator.actionsPublisher.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .cancel:
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
recoveryNavigationStackCoordinator.setSheetCoordinator(nil)
|
||||
case .requestOIDCAuthorisation(let url):
|
||||
actionsSubject.send(.requestOIDCAuthorisation(url))
|
||||
case .resetFinished:
|
||||
parameters.navigationStackCoordinator?.setSheetCoordinator(nil) // Dismiss the recovery screen
|
||||
recoveryNavigationStackCoordinator.setSheetCoordinator(nil)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
navigationStackCoordinator.setSheetCoordinator(coordinator)
|
||||
|
||||
resetNavigationStackCoordinator.setRootCoordinator(coordinator)
|
||||
|
||||
recoveryNavigationStackCoordinator.setSheetCoordinator(resetNavigationStackCoordinator)
|
||||
}
|
||||
}
|
||||
|
@ -42,12 +42,12 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
||||
private var viewModel: SettingsScreenViewModelProtocol
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SettingsScreenCoordinatorAction, Never> = .init()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
var actions: AnyPublisher<SettingsScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(parameters: SettingsScreenCoordinatorParameters) {
|
||||
|
@ -883,7 +883,7 @@ class ClientProxy: ClientProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Encryption
|
||||
// MARK: - Crypto
|
||||
|
||||
func ed25519Base64() async -> String? {
|
||||
await client.encryption().ed25519Key()
|
||||
@ -892,6 +892,14 @@ class ClientProxy: ClientProxyProtocol {
|
||||
func curve25519Base64() async -> String? {
|
||||
await client.encryption().curve25519Key()
|
||||
}
|
||||
|
||||
func resetIdentity() async -> Result<IdentityResetHandle?, ClientProxyError> {
|
||||
do {
|
||||
return try await .success(client.encryption().resetIdentity())
|
||||
} catch {
|
||||
return .failure(.sdkError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ClientProxy: MediaLoaderProtocol {
|
||||
|
@ -190,8 +190,10 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
||||
|
||||
func recentConversationCounterparts() async -> [UserProfileProxy]
|
||||
|
||||
// MARK: - Encryption Info
|
||||
// MARK: - Crypto
|
||||
|
||||
func ed25519Base64() async -> String?
|
||||
func curve25519Base64() async -> String?
|
||||
|
||||
func resetIdentity() async -> Result<IdentityResetHandle?, ClientProxyError>
|
||||
}
|
||||
|
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreen-iPad-en-GB.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreen-iPad-en-GB.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreen-iPad-pseudo.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreen-iPad-pseudo.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreen-iPhone-15-en-GB.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreen-iPhone-15-en-GB.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreen-iPhone-15-pseudo.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreen-iPhone-15-pseudo.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreenCheckmarkItem-iPad-en-GB.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreenCheckmarkItem-iPad-en-GB.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreenCheckmarkItem-iPad-pseudo.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreenCheckmarkItem-iPad-pseudo.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreenCheckmarkItem-iPhone-15-en-GB.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreenCheckmarkItem-iPhone-15-en-GB.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreenCheckmarkItem-iPhone-15-pseudo.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_analyticsPromptScreenCheckmarkItem-iPhone-15-pseudo.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetPasswordScreen-iPad-en-GB.1.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetPasswordScreen-iPad-en-GB.1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetPasswordScreen-iPad-pseudo.1.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetPasswordScreen-iPad-pseudo.1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetPasswordScreen-iPhone-15-en-GB.1.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetPasswordScreen-iPhone-15-en-GB.1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetPasswordScreen-iPhone-15-pseudo.1.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetPasswordScreen-iPhone-15-pseudo.1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetScreen-iPad-en-GB.1.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetScreen-iPad-en-GB.1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetScreen-iPad-pseudo.1.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetScreen-iPad-pseudo.1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetScreen-iPhone-15-en-GB.1.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetScreen-iPhone-15-en-GB.1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetScreen-iPhone-15-pseudo.1.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_encryptionResetScreen-iPhone-15-pseudo.1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_identityConfirmationScreen-iPad-en-GB.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_identityConfirmationScreen-iPad-en-GB.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_identityConfirmationScreen-iPad-pseudo.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_identityConfirmationScreen-iPad-pseudo.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_identityConfirmationScreen-iPhone-15-en-GB.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_identityConfirmationScreen-iPhone-15-en-GB.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_identityConfirmationScreen-iPhone-15-pseudo.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_identityConfirmationScreen-iPhone-15-pseudo.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_resetRecoveryKeyScreen-iPad-en-GB.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_resetRecoveryKeyScreen-iPad-en-GB.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_resetRecoveryKeyScreen-iPad-pseudo.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_resetRecoveryKeyScreen-iPad-pseudo.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_resetRecoveryKeyScreen-iPhone-15-en-GB.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_resetRecoveryKeyScreen-iPhone-15-en-GB.1.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_resetRecoveryKeyScreen-iPhone-15-pseudo.1.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_resetRecoveryKeyScreen-iPhone-15-pseudo.1.png
(Stored with Git LFS)
Binary file not shown.
@ -60,7 +60,7 @@ packages:
|
||||
# Element/Matrix dependencies
|
||||
MatrixRustSDK:
|
||||
url: https://github.com/element-hq/matrix-rust-components-swift
|
||||
exactVersion: 1.0.29
|
||||
exactVersion: 1.0.30
|
||||
# path: ../matrix-rust-sdk
|
||||
Compound:
|
||||
url: https://github.com/element-hq/compound-ios
|
||||
|
Loading…
x
Reference in New Issue
Block a user