Add AppLockSetupBiometricsScreen. (#1942)
This commit is contained in:
@@ -119,6 +119,7 @@
|
||||
206F0DBAB6AF042CA1FF2C0D /* SettingsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D487C1185D658F8B15B8F55 /* SettingsViewModelTests.swift */; };
|
||||
208C19811613F9A10F8A7B75 /* MediaLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */; };
|
||||
20C16A3F718802B0E4A19C83 /* URLComponentsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76310030C831D4610A705603 /* URLComponentsTests.swift */; };
|
||||
21813AF91CFC6F3E3896DB53 /* AppLockSetupBiometricsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10F130DF775CE6BC51A4E392 /* AppLockSetupBiometricsScreenModels.swift */; };
|
||||
2185C1F6724C78FFF355D6FA /* WelcomeScreenScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AB10FA6570DD08B3966C159 /* WelcomeScreenScreenUITests.swift */; };
|
||||
21AFEFB8CEFE56A3811A1F5B /* VoiceMessageCacheTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 283974987DA7EC61D2AB57D9 /* VoiceMessageCacheTests.swift */; };
|
||||
21BF2B7CEDFE3CA67C5355AD /* test_image.png in Resources */ = {isa = PBXBuildFile; fileRef = C733D11B421CFE3A657EF230 /* test_image.png */; };
|
||||
@@ -201,6 +202,7 @@
|
||||
36CD6E11B37396E14F032CB6 /* WysiwygComposer in Frameworks */ = {isa = PBXBuildFile; productRef = CA07D57389DACE18AEB6A5E2 /* WysiwygComposer */; };
|
||||
370AF5BFCD4384DD455479B6 /* ElementCallWidgetDriverProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6C11AD9813045E44F950410 /* ElementCallWidgetDriverProtocol.swift */; };
|
||||
377980ABF16525114E72DDE2 /* Version in Frameworks */ = {isa = PBXBuildFile; productRef = 2B9ACE4FCACB5A8812154424 /* Version */; };
|
||||
37906355E207DB5703754675 /* AppLockSetupBiometricsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9F893F4A111CB7BA5C96949 /* AppLockSetupBiometricsScreenViewModel.swift */; };
|
||||
37D789F24199B32E3FD1AA7B /* FileRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 216F0DDC98F2A2C162D09C28 /* FileRoomTimelineItemContent.swift */; };
|
||||
383055C6ABE5BE058CEE1DDB /* WelcomeScreenScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57FE5EF0AFFE360C66420AAE /* WelcomeScreenScreenCoordinator.swift */; };
|
||||
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA1D2CBAEA5D0BD00B90D1B /* BindableState.swift */; };
|
||||
@@ -249,6 +251,7 @@
|
||||
44121202B4A260C98BF615A7 /* RoomMembersListScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5B7A755E985FA14469E86B2 /* RoomMembersListScreenUITests.swift */; };
|
||||
44BDD670FF9095ACE240A3A2 /* VoiceMessageMediaManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4F10BDD56FA77FEC742333 /* VoiceMessageMediaManagerTests.swift */; };
|
||||
44F0E1B576C7599DF8022071 /* SwiftOGG in Frameworks */ = {isa = PBXBuildFile; productRef = 391D11F92DFC91666AA1503F /* SwiftOGG */; };
|
||||
454F8DDC4442C0DE54094902 /* LABiometryType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3F219838588C62198E726E3 /* LABiometryType.swift */; };
|
||||
4557192F5B15A8D9BB920232 /* AdvancedSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E492690C8B27A892C194CC4 /* AdvancedSettingsScreenCoordinator.swift */; };
|
||||
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */; };
|
||||
4681820102DAC8BA586357D4 /* VoiceMessageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB8D7926A5684E18196B538 /* VoiceMessageCache.swift */; };
|
||||
@@ -262,6 +265,7 @@
|
||||
484202C5D50983442D24D061 /* AttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52BD6ED18E2EB61E28C340AD /* AttributedString.swift */; };
|
||||
491D62ACD19E6F134B1766AF /* RoomNotificationSettingsUserDefinedScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3203C6566DC17B7AECC1B7FD /* RoomNotificationSettingsUserDefinedScreen.swift */; };
|
||||
492274DA6691EE985C2FCCAA /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 67E7A6F388D3BF85767609D9 /* Sentry */; };
|
||||
4940B439681767BE9D78CFDB /* AppLockSetupBiometricsScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52F5EE5DE3B55D59299DB5BC /* AppLockSetupBiometricsScreenViewModelTests.swift */; };
|
||||
496CC9D59ACFAB84FD9B3B5F /* AnalyticsPromptScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840E86A67DB2C92C09771EAD /* AnalyticsPromptScreenModels.swift */; };
|
||||
49814A48470F347426513B07 /* TimelineReadReceiptsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1877038D1AD3D5A029F8AE2C /* TimelineReadReceiptsView.swift */; };
|
||||
49F2E7DD8CAACE09CEECE3E6 /* SeparatorRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6390A6DC140CA3D6865A66FF /* SeparatorRoomTimelineView.swift */; };
|
||||
@@ -460,6 +464,7 @@
|
||||
7F7EA51A9A43125A8CB6AC90 /* NotificationSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D560DDA3B20C82766ACFAD /* NotificationSettingsScreenViewModel.swift */; };
|
||||
7FB0BDE26838F1A92782D5E1 /* MediaUploadPreviewScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39B6C8690AEA1E49FF1BAF95 /* MediaUploadPreviewScreenUITests.swift */; };
|
||||
7FF27DA70D833CFC5724EFC5 /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 1CAB56FF1DE17B3E871A0BA2 /* SnapshotTesting */; };
|
||||
8015842CB4DE1BE414D2CDED /* AppLockSetupBiometricsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C62E07C1164F5120727A2A8 /* AppLockSetupBiometricsScreenCoordinator.swift */; };
|
||||
8024BE37156FF0A95A7A3465 /* AnalyticsPromptUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF11DD57D9FACF2A757AB024 /* AnalyticsPromptUITests.swift */; };
|
||||
804C15D8ADE0EA7A5268F58A /* OverridableAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648DD1C10E4957CB791FE0B8 /* OverridableAvatarImage.swift */; };
|
||||
80D00A7C62AAB44F54725C43 /* PermalinkBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F754E66A8970963B15B2A41E /* PermalinkBuilder.swift */; };
|
||||
@@ -587,6 +592,7 @@
|
||||
9EBDC79CAC9B63A0D626E333 /* LegalInformationScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EB2CAA266B921D128C35710 /* LegalInformationScreenCoordinator.swift */; };
|
||||
9F19096BFA629C0AC282B1E4 /* CreateRoomScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8CEB4634C0DD7779C4AB504 /* CreateRoomScreenUITests.swift */; };
|
||||
9FAF6DA7E8E85C9699757764 /* CollapsibleRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E2656184491C505700D2405 /* CollapsibleRoomTimelineView.swift */; };
|
||||
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 */; };
|
||||
A0A0D2A9564BDA3FDE2E360F /* FormattedBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */; };
|
||||
@@ -705,6 +711,7 @@
|
||||
BA4C9049BC96DED3A2F3B82E /* RoomNotificationSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03DD998E523D4EC93C7ED703 /* RoomNotificationSettingsScreenViewModelProtocol.swift */; };
|
||||
BB6BF528BC7F5B87E08C4F18 /* CameraPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8A3B7637DDBD6AA97AC2545 /* CameraPicker.swift */; };
|
||||
BB784A02BADB03C820617A46 /* TextRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90A55430639712CFACA34F43 /* TextRoomTimelineItem.swift */; };
|
||||
BB9B800C6094E34860E89DC5 /* AppLockSetupBiometricsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8CCF9A924521DECA44778C4 /* AppLockSetupBiometricsScreen.swift */; };
|
||||
BCC864190651B3A3CF51E4DF /* MediaFileHandleProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEC1D382565A4E9CAC2F14EA /* MediaFileHandleProxy.swift */; };
|
||||
BD203FC6A7AE7637EA003643 /* RoomProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ABDE6F66532CBEB0E016F94 /* RoomProxyMock.swift */; };
|
||||
BD2BF1EC73FFB0C01552ECDA /* WelcomeScreenScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB782CE6176A5D2C082EC5D /* WelcomeScreenScreenModels.swift */; };
|
||||
@@ -1035,7 +1042,9 @@
|
||||
0BC588051E6572A1AF51D738 /* TimelineSenderAvatarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineSenderAvatarView.swift; sourceTree = "<group>"; };
|
||||
0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
0C34667458773B02AB5FB0B2 /* LegalInformationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
0C62E07C1164F5120727A2A8 /* AppLockSetupBiometricsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
0C671107BDFC6CD1778C0B4C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||
0CCC6C31102E1D8B9106DEDE /* AppLockSetupBiometricsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
0D0B159AFFBBD8ECFD0E37FA /* LoginScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenModels.swift; sourceTree = "<group>"; };
|
||||
0D8F620C8B314840D8602E3F /* NSE.appex */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "wrapper.app-extension"; path = NSE.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0DF5CBAF69BDF5DF31C661E1 /* IntentionalMentions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentionalMentions.swift; sourceTree = "<group>"; };
|
||||
@@ -1050,6 +1059,7 @@
|
||||
105B2A8426404EF66F00CFDB /* RoomTimelineItemFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemFactory.swift; sourceTree = "<group>"; };
|
||||
10B7F8EE25775DE2A305CBB5 /* NotificationCenterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationCenterProtocol.swift; sourceTree = "<group>"; };
|
||||
10CC626F97AD70FF0420C115 /* RoomSummaryProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProviderProtocol.swift; sourceTree = "<group>"; };
|
||||
10F130DF775CE6BC51A4E392 /* AppLockSetupBiometricsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenModels.swift; sourceTree = "<group>"; };
|
||||
10F32E0B4B83D2A11EE8D011 /* InviteUsersScreenSelectedItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenSelectedItem.swift; sourceTree = "<group>"; };
|
||||
11151E78D6BB2B04A8FBD389 /* EmojiPickerScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
111B698739E3410E2CDB7144 /* MXLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXLog.swift; sourceTree = "<group>"; };
|
||||
@@ -1283,6 +1293,7 @@
|
||||
5281C5CDC4A712265A0B5FBF /* PollRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
52BD6ED18E2EB61E28C340AD /* AttributedString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedString.swift; sourceTree = "<group>"; };
|
||||
52D7074991B3267B26D89B22 /* MockRoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomTimelineController.swift; sourceTree = "<group>"; };
|
||||
52F5EE5DE3B55D59299DB5BC /* AppLockSetupBiometricsScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollViewAdapter.swift; sourceTree = "<group>"; };
|
||||
5351EBD7A0B9610548E4B7B2 /* EncryptedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
536E72DCBEEC4A1FE66CFDCE /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
||||
@@ -1679,6 +1690,7 @@
|
||||
C936FDD017808FE416742D64 /* PollRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
C97F8963B14EB0AF3940DDBF /* NotificationSettingsEditScreenRoomCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsEditScreenRoomCell.swift; sourceTree = "<group>"; };
|
||||
C99FDEEB71173C4C6FA2734C /* UserSessionFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionFlowCoordinator.swift; sourceTree = "<group>"; };
|
||||
C9F893F4A111CB7BA5C96949 /* AppLockSetupBiometricsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
CA28F29C9F93E93CC3C2C715 /* NavigationRootCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRootCoordinator.swift; sourceTree = "<group>"; };
|
||||
CA29952595B804DA221A0C1D /* ComposerToolbarViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerToolbarViewModelTests.swift; sourceTree = "<group>"; };
|
||||
CA2A71915C1F075E403F559C /* InvitesScreenCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreenCell.swift; sourceTree = "<group>"; };
|
||||
@@ -1722,6 +1734,7 @@
|
||||
D38391154120264910D19528 /* PollMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollMock.swift; sourceTree = "<group>"; };
|
||||
D39D7F513A36C9C1951DB44C /* AnalyticsSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreen.swift; sourceTree = "<group>"; };
|
||||
D3D455BC2423D911A62ACFB2 /* NSELogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSELogger.swift; sourceTree = "<group>"; };
|
||||
D3F219838588C62198E726E3 /* LABiometryType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LABiometryType.swift; sourceTree = "<group>"; };
|
||||
D3F275432954C8C6B1B7D966 /* AppLockSetupPINScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreen.swift; sourceTree = "<group>"; };
|
||||
D49B9785E3AD7D1C15A29F2F /* MediaSourceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaSourceProxy.swift; sourceTree = "<group>"; };
|
||||
D4DA544B2520BFA65D6DB4BB /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
||||
@@ -1837,6 +1850,7 @@
|
||||
F7E8A8047B50E3607ACD354E /* ImageProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageProviderProtocol.swift; sourceTree = "<group>"; };
|
||||
F875D71347DC81EAE7687446 /* NavigationRootCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRootCoordinatorTests.swift; sourceTree = "<group>"; };
|
||||
F899D02CF26EA7675EEBE74C /* UserSessionScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionScreenTests.swift; sourceTree = "<group>"; };
|
||||
F8CCF9A924521DECA44778C4 /* AppLockSetupBiometricsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreen.swift; sourceTree = "<group>"; };
|
||||
F8CEB4634C0DD7779C4AB504 /* CreateRoomScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomScreenUITests.swift; sourceTree = "<group>"; };
|
||||
F9E785D5137510481733A3E8 /* TextRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
F9ED8E731E21055F728E5FED /* TimelineStartRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStartRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
@@ -2162,7 +2176,9 @@
|
||||
children = (
|
||||
3AD37D7DDF9904587601239D /* AppLockScreen */,
|
||||
CE39C9B97963CC30AB0859E5 /* AppLockSettingsScreen */,
|
||||
4570BFC8DD6665A91381F400 /* AppLockSetupBiometricsScreen */,
|
||||
570026F1BA71A2D167652E48 /* AppLockSetupPINScreen */,
|
||||
FB039572AA54E0690B4051AD /* Common */,
|
||||
);
|
||||
path = AppLock;
|
||||
sourceTree = "<group>";
|
||||
@@ -2419,6 +2435,14 @@
|
||||
path = MessageForwardingScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
33644C893C984570F605D94D /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F8CCF9A924521DECA44778C4 /* AppLockSetupBiometricsScreen.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
337015ADFBA3AB96660DB3A6 /* Generated */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -2667,6 +2691,18 @@
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4570BFC8DD6665A91381F400 /* AppLockSetupBiometricsScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0C62E07C1164F5120727A2A8 /* AppLockSetupBiometricsScreenCoordinator.swift */,
|
||||
10F130DF775CE6BC51A4E392 /* AppLockSetupBiometricsScreenModels.swift */,
|
||||
C9F893F4A111CB7BA5C96949 /* AppLockSetupBiometricsScreenViewModel.swift */,
|
||||
0CCC6C31102E1D8B9106DEDE /* AppLockSetupBiometricsScreenViewModelProtocol.swift */,
|
||||
33644C893C984570F605D94D /* View */,
|
||||
);
|
||||
path = AppLockSetupBiometricsScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4775A7D6FBB210BF21318AD9 /* UserDetailsEditScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -3639,6 +3675,7 @@
|
||||
AC0275CEE9CA078B34028BDF /* AppLockScreenViewModelTests.swift */,
|
||||
DD97F9661ABF08CE002054A2 /* AppLockServiceTests.swift */,
|
||||
B0BA67B3E4EF9D29D14A78CE /* AppLockSettingsScreenViewModelTests.swift */,
|
||||
52F5EE5DE3B55D59299DB5BC /* AppLockSetupBiometricsScreenViewModelTests.swift */,
|
||||
989D7380D9C86B3A10D30B13 /* AppLockSetupPINScreenViewModelTests.swift */,
|
||||
4A5B4CD611DE7E94F5BA87B2 /* AppLockTimerTests.swift */,
|
||||
EF13BFD415CA84B1272E94F8 /* PINTextFieldTests.swift */,
|
||||
@@ -4470,6 +4507,14 @@
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FB039572AA54E0690B4051AD /* Common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D3F219838588C62198E726E3 /* LABiometryType.swift */,
|
||||
);
|
||||
path = Common;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FCDF06BDB123505F0334B4F9 /* Timeline */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -4992,6 +5037,7 @@
|
||||
8478992479B296C45150208F /* AppLockScreenViewModelTests.swift in Sources */,
|
||||
77693820498ABF3508814D49 /* AppLockServiceTests.swift in Sources */,
|
||||
73F33E9776B7A50B65A031D2 /* AppLockSettingsScreenViewModelTests.swift in Sources */,
|
||||
4940B439681767BE9D78CFDB /* AppLockSetupBiometricsScreenViewModelTests.swift in Sources */,
|
||||
25C4C1100B6EA79F5CC7CBB5 /* AppLockSetupPINScreenViewModelTests.swift in Sources */,
|
||||
0EEC614342F823E5BF966C2C /* AppLockTimerTests.swift in Sources */,
|
||||
EA78A7512AFB1E5451744EB1 /* AppRouteURLParserTests.swift in Sources */,
|
||||
@@ -5149,6 +5195,11 @@
|
||||
0AD81E04A8C024C09B7AEAC5 /* AppLockSettingsScreenModels.swift in Sources */,
|
||||
A7BEE8216B4B12BE4C0F2C3F /* AppLockSettingsScreenViewModel.swift in Sources */,
|
||||
0206016CCEF6EF9365916768 /* AppLockSettingsScreenViewModelProtocol.swift in Sources */,
|
||||
BB9B800C6094E34860E89DC5 /* AppLockSetupBiometricsScreen.swift in Sources */,
|
||||
8015842CB4DE1BE414D2CDED /* AppLockSetupBiometricsScreenCoordinator.swift in Sources */,
|
||||
21813AF91CFC6F3E3896DB53 /* AppLockSetupBiometricsScreenModels.swift in Sources */,
|
||||
37906355E207DB5703754675 /* AppLockSetupBiometricsScreenViewModel.swift in Sources */,
|
||||
9FB41B0E8B2AA9B404E52C8B /* AppLockSetupBiometricsScreenViewModelProtocol.swift in Sources */,
|
||||
733E2B19AB1FDA3B93293A28 /* AppLockSetupPINScreen.swift in Sources */,
|
||||
9696ECAFB4F0C079C5C2A526 /* AppLockSetupPINScreenCoordinator.swift in Sources */,
|
||||
E4B07FF075C99D04D9AF792D /* AppLockSetupPINScreenModels.swift in Sources */,
|
||||
@@ -5331,6 +5382,7 @@
|
||||
1FE593ECEC40A43789105D80 /* KeychainController.swift in Sources */,
|
||||
FD29471C72872F8B7580E3E1 /* KeychainControllerMock.swift in Sources */,
|
||||
CB99B0FA38A4AC596F38CC13 /* KeychainControllerProtocol.swift in Sources */,
|
||||
454F8DDC4442C0DE54094902 /* LABiometryType.swift in Sources */,
|
||||
D5681C80D8281560AACE0035 /* Label.swift in Sources */,
|
||||
EEAE954289DE813A61656AE0 /* LayoutDirection.swift in Sources */,
|
||||
42B084FDE621FBEE433AF444 /* LegalInformationScreen.swift in Sources */,
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
"common_enter_your_pin" = "Enter your PIN";
|
||||
"common_error" = "Error";
|
||||
"common_everyone" = "Everyone";
|
||||
"common_face_id_ios" = "Face ID";
|
||||
"common_file" = "File";
|
||||
"common_forward_message" = "Forward message";
|
||||
"common_gif" = "GIF";
|
||||
@@ -116,6 +117,7 @@
|
||||
"common_mute" = "Mute";
|
||||
"common_no_results" = "No results";
|
||||
"common_offline" = "Offline";
|
||||
"common_optic_id_ios" = "Optic ID";
|
||||
"common_password" = "Password";
|
||||
"common_people" = "People";
|
||||
"common_permalink" = "Permalink";
|
||||
@@ -152,6 +154,7 @@
|
||||
"common_thread" = "Thread";
|
||||
"common_topic" = "Topic";
|
||||
"common_topic_placeholder" = "What is this room about?";
|
||||
"common_touch_id_ios" = "Touch ID";
|
||||
"common_unable_to_decrypt" = "Unable to decrypt";
|
||||
"common_unable_to_invite_message" = "Invites couldn't be sent to one or more users.";
|
||||
"common_unable_to_invite_title" = "Unable to send invite(s)";
|
||||
@@ -265,6 +268,8 @@
|
||||
"screen_analytics_prompt_third_party_sharing" = "We won't share your data with third parties";
|
||||
"screen_analytics_prompt_title" = "Help improve %1$@";
|
||||
"screen_analytics_settings_share_data" = "Share analytics data";
|
||||
"screen_app_lock_biometric_authentication" = "biometric authentication";
|
||||
"screen_app_lock_biometric_unlock" = "biometric unlock";
|
||||
"screen_app_lock_forgot_pin" = "Forgot PIN?";
|
||||
"screen_app_lock_settings_change_pin" = "Change PIN code";
|
||||
"screen_app_lock_settings_enable_biometric_unlock" = "Allow biometric unlock";
|
||||
@@ -274,6 +279,9 @@
|
||||
"screen_app_lock_settings_remove_pin" = "Remove PIN";
|
||||
"screen_app_lock_settings_remove_pin_alert_message" = "Are you sure you want to remove PIN?";
|
||||
"screen_app_lock_settings_remove_pin_alert_title" = "Remove PIN?";
|
||||
"screen_app_lock_setup_biometric_unlock_allow_title" = "Allow %1$@";
|
||||
"screen_app_lock_setup_biometric_unlock_skip" = "I’d rather use PIN";
|
||||
"screen_app_lock_setup_biometric_unlock_subtitle" = "Save yourself some time and use %1$@ to unlock the app each time";
|
||||
"screen_app_lock_setup_choose_pin" = "Choose PIN";
|
||||
"screen_app_lock_setup_confirm_pin" = "Confirm PIN";
|
||||
"screen_app_lock_setup_pin_blacklisted_dialog_content" = "You cannot choose this as your PIN code for security reasons";
|
||||
|
||||
@@ -220,6 +220,8 @@ public enum L10n {
|
||||
public static var commonError: String { return L10n.tr("Localizable", "common_error") }
|
||||
/// Everyone
|
||||
public static var commonEveryone: String { return L10n.tr("Localizable", "common_everyone") }
|
||||
/// Face ID
|
||||
public static var commonFaceIdIos: String { return L10n.tr("Localizable", "common_face_id_ios") }
|
||||
/// File
|
||||
public static var commonFile: String { return L10n.tr("Localizable", "common_file") }
|
||||
/// Forward message
|
||||
@@ -258,6 +260,8 @@ public enum L10n {
|
||||
public static var commonNoResults: String { return L10n.tr("Localizable", "common_no_results") }
|
||||
/// Offline
|
||||
public static var commonOffline: String { return L10n.tr("Localizable", "common_offline") }
|
||||
/// Optic ID
|
||||
public static var commonOpticIdIos: String { return L10n.tr("Localizable", "common_optic_id_ios") }
|
||||
/// Password
|
||||
public static var commonPassword: String { return L10n.tr("Localizable", "common_password") }
|
||||
/// People
|
||||
@@ -344,6 +348,8 @@ public enum L10n {
|
||||
public static var commonTopic: String { return L10n.tr("Localizable", "common_topic") }
|
||||
/// What is this room about?
|
||||
public static var commonTopicPlaceholder: String { return L10n.tr("Localizable", "common_topic_placeholder") }
|
||||
/// Touch ID
|
||||
public static var commonTouchIdIos: String { return L10n.tr("Localizable", "common_touch_id_ios") }
|
||||
/// Unable to decrypt
|
||||
public static var commonUnableToDecrypt: String { return L10n.tr("Localizable", "common_unable_to_decrypt") }
|
||||
/// Invites couldn't be sent to one or more users.
|
||||
@@ -648,6 +654,10 @@ public enum L10n {
|
||||
public static var screenAnalyticsSettingsReadTermsContentLink: String { return L10n.tr("Localizable", "screen_analytics_settings_read_terms_content_link") }
|
||||
/// Share analytics data
|
||||
public static var screenAnalyticsSettingsShareData: String { return L10n.tr("Localizable", "screen_analytics_settings_share_data") }
|
||||
/// biometric authentication
|
||||
public static var screenAppLockBiometricAuthentication: String { return L10n.tr("Localizable", "screen_app_lock_biometric_authentication") }
|
||||
/// biometric unlock
|
||||
public static var screenAppLockBiometricUnlock: String { return L10n.tr("Localizable", "screen_app_lock_biometric_unlock") }
|
||||
/// Forgot PIN?
|
||||
public static var screenAppLockForgotPin: String { return L10n.tr("Localizable", "screen_app_lock_forgot_pin") }
|
||||
/// Change PIN code
|
||||
@@ -666,6 +676,16 @@ public enum L10n {
|
||||
public static var screenAppLockSettingsRemovePinAlertMessage: String { return L10n.tr("Localizable", "screen_app_lock_settings_remove_pin_alert_message") }
|
||||
/// Remove PIN?
|
||||
public static var screenAppLockSettingsRemovePinAlertTitle: String { return L10n.tr("Localizable", "screen_app_lock_settings_remove_pin_alert_title") }
|
||||
/// Allow %1$@
|
||||
public static func screenAppLockSetupBiometricUnlockAllowTitle(_ p1: Any) -> String {
|
||||
return L10n.tr("Localizable", "screen_app_lock_setup_biometric_unlock_allow_title", String(describing: p1))
|
||||
}
|
||||
/// I’d rather use PIN
|
||||
public static var screenAppLockSetupBiometricUnlockSkip: String { return L10n.tr("Localizable", "screen_app_lock_setup_biometric_unlock_skip") }
|
||||
/// Save yourself some time and use %1$@ to unlock the app each time
|
||||
public static func screenAppLockSetupBiometricUnlockSubtitle(_ p1: Any) -> String {
|
||||
return L10n.tr("Localizable", "screen_app_lock_setup_biometric_unlock_subtitle", String(describing: p1))
|
||||
}
|
||||
/// Choose PIN
|
||||
public static var screenAppLockSetupChoosePin: String { return L10n.tr("Localizable", "screen_app_lock_setup_choose_pin") }
|
||||
/// Confirm PIN
|
||||
|
||||
@@ -28,21 +28,7 @@ struct AppLockSettingsScreenViewState: BindableState {
|
||||
var bindings: AppLockSettingsScreenViewStateBindings
|
||||
|
||||
var supportsBiometry: Bool { biometryType != .none }
|
||||
var enableBiometryTitle: String {
|
||||
switch biometryType {
|
||||
case .none:
|
||||
return L10n.commonError
|
||||
case .touchID:
|
||||
return L10n.screenAppLockSettingsEnableTouchIdIos
|
||||
case .faceID:
|
||||
return L10n.screenAppLockSettingsEnableFaceIdIos
|
||||
// Requires Xcode 15:
|
||||
// case .opticID:
|
||||
// L10n.screenAppLockSettingsEnableOpticIdIos
|
||||
@unknown default:
|
||||
return L10n.screenAppLockSettingsEnableBiometricUnlock
|
||||
}
|
||||
}
|
||||
var enableBiometryTitle: String { L10n.screenAppLockSetupBiometricUnlockAllowTitle(biometryType.localizedString) }
|
||||
}
|
||||
|
||||
struct AppLockSettingsScreenViewStateBindings {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
struct AppLockSetupBiometricsScreenCoordinatorParameters {
|
||||
let appLockService: AppLockServiceProtocol
|
||||
}
|
||||
|
||||
enum AppLockSetupBiometricsScreenCoordinatorAction {
|
||||
case `continue`
|
||||
}
|
||||
|
||||
final class AppLockSetupBiometricsScreenCoordinator: CoordinatorProtocol {
|
||||
private let parameters: AppLockSetupBiometricsScreenCoordinatorParameters
|
||||
private var viewModel: AppLockSetupBiometricsScreenViewModelProtocol
|
||||
private let actionsSubject: PassthroughSubject<AppLockSetupBiometricsScreenCoordinatorAction, Never> = .init()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
var actions: AnyPublisher<AppLockSetupBiometricsScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(parameters: AppLockSetupBiometricsScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
|
||||
viewModel = AppLockSetupBiometricsScreenViewModel(appLockService: parameters.appLockService)
|
||||
}
|
||||
|
||||
func start() {
|
||||
viewModel.actions.sink { [weak self] action in
|
||||
MXLog.info("Coordinator: received view model action: \(action)")
|
||||
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .continue:
|
||||
self.actionsSubject.send(.continue)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func toPresentable() -> AnyView {
|
||||
AnyView(AppLockSetupBiometricsScreen(context: viewModel.context))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// 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 LocalAuthentication
|
||||
import SFSafeSymbols
|
||||
|
||||
enum AppLockSetupBiometricsScreenViewModelAction {
|
||||
case `continue`
|
||||
}
|
||||
|
||||
struct AppLockSetupBiometricsScreenViewState: BindableState {
|
||||
/// The supported biometry type on this device.
|
||||
let biometryType: LABiometryType
|
||||
|
||||
var icon: SFSymbol { biometryType.systemSymbol }
|
||||
var title: String { L10n.screenAppLockSetupBiometricUnlockAllowTitle(biometryType.localizedString) }
|
||||
var subtitle: String { L10n.screenAppLockSetupBiometricUnlockSubtitle(biometryType.localizedString) }
|
||||
}
|
||||
|
||||
enum AppLockSetupBiometricsScreenViewAction {
|
||||
/// The user would like to use Touch/Face ID.
|
||||
case allow
|
||||
/// The user doesn't want to use biometrics.
|
||||
case skip
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// 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 AppLockSetupBiometricsScreenViewModelType = StateStoreViewModel<AppLockSetupBiometricsScreenViewState, AppLockSetupBiometricsScreenViewAction>
|
||||
|
||||
class AppLockSetupBiometricsScreenViewModel: AppLockSetupBiometricsScreenViewModelType, AppLockSetupBiometricsScreenViewModelProtocol {
|
||||
private let appLockService: AppLockServiceProtocol
|
||||
private var actionsSubject: PassthroughSubject<AppLockSetupBiometricsScreenViewModelAction, Never> = .init()
|
||||
|
||||
var actions: AnyPublisher<AppLockSetupBiometricsScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(appLockService: AppLockServiceProtocol) {
|
||||
self.appLockService = appLockService
|
||||
super.init(initialViewState: AppLockSetupBiometricsScreenViewState(biometryType: appLockService.biometryType))
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
override func process(viewAction: AppLockSetupBiometricsScreenViewAction) {
|
||||
MXLog.info("View model: received view action: \(viewAction)")
|
||||
|
||||
switch viewAction {
|
||||
case .allow:
|
||||
MXLog.info("Enable biometric unlock.")
|
||||
appLockService.biometricUnlockEnabled = true
|
||||
actionsSubject.send(.continue)
|
||||
case .skip:
|
||||
MXLog.info("Disable biometric unlock.")
|
||||
appLockService.biometricUnlockEnabled = false
|
||||
actionsSubject.send(.continue)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// 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 AppLockSetupBiometricsScreenViewModelProtocol {
|
||||
var actions: AnyPublisher<AppLockSetupBiometricsScreenViewModelAction, Never> { get }
|
||||
var context: AppLockSetupBiometricsScreenViewModelType.Context { get }
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
/// The screen shown when setting up App Lock that asks the user whether
|
||||
/// the would like to use Face ID/Touch ID instead of entering their PIN code.
|
||||
struct AppLockSetupBiometricsScreen: View {
|
||||
@ObservedObject var context: AppLockSetupBiometricsScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
VStack(spacing: 48) {
|
||||
header
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.top, UIConstants.iconTopPaddingToNavigationBar)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
.toolbar(.visible, for: .navigationBar)
|
||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||
.safeAreaInset(edge: .bottom) {
|
||||
buttons
|
||||
.padding(.top, 16)
|
||||
.padding(.horizontal, 16)
|
||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||
}
|
||||
}
|
||||
|
||||
var header: some View {
|
||||
VStack(spacing: 8) {
|
||||
Image(systemSymbol: context.viewState.icon)
|
||||
.font(.system(size: 72))
|
||||
.padding(.top, 58)
|
||||
.padding(.bottom, 26)
|
||||
|
||||
Text(context.viewState.title)
|
||||
.font(.compound.headingMDBold)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
|
||||
Text(context.viewState.subtitle)
|
||||
.font(.compound.bodyMD)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.compound.textSecondary)
|
||||
}
|
||||
}
|
||||
|
||||
var buttons: some View {
|
||||
VStack(spacing: 16) {
|
||||
Button(context.viewState.title) { context.send(viewAction: .allow) }
|
||||
.buttonStyle(.compound(.primary))
|
||||
|
||||
Button { context.send(viewAction: .skip) } label: {
|
||||
Text(L10n.screenAppLockSetupBiometricUnlockSkip)
|
||||
.font(.compound.bodyLGSemibold)
|
||||
.padding(14)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct AppLockSetupBiometricsScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static let faceIDViewModel = AppLockSetupBiometricsScreenViewModel(appLockService: AppLockServiceMock.mock(biometryType: .faceID))
|
||||
static let touchIDViewModel = AppLockSetupBiometricsScreenViewModel(appLockService: AppLockServiceMock.mock(biometryType: .touchID))
|
||||
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
AppLockSetupBiometricsScreen(context: faceIDViewModel.context)
|
||||
}
|
||||
.previewDisplayName("Face ID")
|
||||
|
||||
NavigationStack {
|
||||
AppLockSetupBiometricsScreen(context: touchIDViewModel.context)
|
||||
}
|
||||
.previewDisplayName("Touch ID")
|
||||
}
|
||||
}
|
||||
56
ElementX/Sources/Screens/AppLock/Common/LABiometryType.swift
Normal file
56
ElementX/Sources/Screens/AppLock/Common/LABiometryType.swift
Normal file
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// Copyright 2023 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 LocalAuthentication
|
||||
import SFSafeSymbols
|
||||
|
||||
extension LABiometryType {
|
||||
/// The SF Symbol that represents the biometry type.
|
||||
var systemSymbol: SFSymbol {
|
||||
switch self {
|
||||
case .none:
|
||||
MXLog.error("Invalid presentation: Biometry not supported.")
|
||||
return .viewfinder
|
||||
case .touchID:
|
||||
return .touchid
|
||||
case .faceID:
|
||||
return .faceid
|
||||
// Requires Xcode 15:
|
||||
// case .opticID:
|
||||
// .opticid
|
||||
@unknown default:
|
||||
return .viewfinder
|
||||
}
|
||||
}
|
||||
|
||||
/// The localized string for the biometry type.
|
||||
var localizedString: String {
|
||||
switch self {
|
||||
case .none:
|
||||
MXLog.error("Invalid presentation: Biometry not supported.")
|
||||
return L10n.screenAppLockBiometricUnlock
|
||||
case .touchID:
|
||||
return L10n.commonTouchIdIos
|
||||
case .faceID:
|
||||
return L10n.commonFaceIdIos
|
||||
// Requires Xcode 15:
|
||||
// case .opticID:
|
||||
// L10n.commonOpticIdIos
|
||||
@unknown default:
|
||||
return L10n.screenAppLockBiometricUnlock
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// 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 XCTest
|
||||
|
||||
@testable import ElementX
|
||||
|
||||
@MainActor
|
||||
class AppLockSetupBiometricsScreenViewModelTests: XCTestCase {
|
||||
var appLockService: AppLockService!
|
||||
var keychainController: KeychainControllerMock!
|
||||
var viewModel: AppLockSetupBiometricsScreenViewModelProtocol!
|
||||
|
||||
var context: AppLockSetupBiometricsScreenViewModelType.Context { viewModel.context }
|
||||
|
||||
override func setUp() {
|
||||
AppSettings.reset()
|
||||
keychainController = KeychainControllerMock()
|
||||
appLockService = AppLockService(keychainController: keychainController, appSettings: AppSettings())
|
||||
viewModel = AppLockSetupBiometricsScreenViewModel(appLockService: appLockService)
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
AppSettings.reset()
|
||||
}
|
||||
|
||||
func testAllow() async throws {
|
||||
// Given a service that has biometric unlock disabled.
|
||||
XCTAssertFalse(appLockService.biometricUnlockEnabled)
|
||||
|
||||
// When allowing Touch/Face ID.
|
||||
context.send(viewAction: .allow)
|
||||
|
||||
// Then the service should now have biometric unlock enabled.
|
||||
XCTAssertTrue(appLockService.biometricUnlockEnabled)
|
||||
}
|
||||
|
||||
func testSkip() async throws {
|
||||
// Given a service that has biometric unlock disabled.
|
||||
XCTAssertFalse(appLockService.biometricUnlockEnabled)
|
||||
|
||||
// When skipping biometrics.
|
||||
context.send(viewAction: .skip)
|
||||
|
||||
// Then the service should now have biometric unlock enabled.
|
||||
XCTAssertFalse(appLockService.biometricUnlockEnabled)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cb397dc5c399e5859733ae04c2057a25bc53e1fbe97d91a2407c01aa562d18e2
|
||||
size 99917
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b970f859c66bb2037ca1a509c9874b624967afbd0b97b05ef0b6172a921c370f
|
||||
size 111799
|
||||
1
changelog.d/pr-1942.wip
Normal file
1
changelog.d/pr-1942.wip
Normal file
@@ -0,0 +1 @@
|
||||
Add Biometrics screen for enabling Touch/Face ID after creating a PIN.
|
||||
Reference in New Issue
Block a user