mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 13:37:11 +00:00
Security and privacy part 1 (#3617)
* added the security and settings button in details * added content to the view * added enable encryption alert * updated preview tests and the UI * removed wrong plists committed by mistake * pr suggestions
This commit is contained in:
parent
e5da7ebd2d
commit
b11fbc6cce
@ -85,6 +85,7 @@
|
||||
0C932A5158C1D0604DFC5750 /* ComposerToolbarViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA29952595B804DA221A0C1D /* ComposerToolbarViewModelTests.swift */; };
|
||||
0CF81807BE5FBFC9E2BBCECF /* PollFormScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3368395F06AA180138E185B6 /* PollFormScreenUITests.swift */; };
|
||||
0D4EB2ABAA5FE8CB10FDBCB8 /* TimelineItemFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AA3AF94A06D319BB37E52DA /* TimelineItemFactoryTests.swift */; };
|
||||
0D617A152D099D94271D3BA8 /* SecurityAndPrivacyScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D046ABB22E680F7C5054441B /* SecurityAndPrivacyScreenViewModelProtocol.swift */; };
|
||||
0DC815CA24E1BD7F408F37D3 /* CollapsibleTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */; };
|
||||
0E08BB72B2258652CF501A8B /* Version in Frameworks */ = {isa = PBXBuildFile; productRef = 2B9ACE4FCACB5A8812154424 /* Version */; };
|
||||
0E3A2787C6AEC761A81A938A /* AuthenticationStartScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8609BE4CA71C30D1FCE3AF9B /* AuthenticationStartScreenModels.swift */; };
|
||||
@ -466,6 +467,7 @@
|
||||
5FCD8AFA364206EE32B909A3 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B050A6B233D95807A09289E7 /* Settings.bundle */; };
|
||||
601AB75BD52B0B4276CEB84A /* SessionVerificationScreenStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 161CD412E75F4086F422AE39 /* SessionVerificationScreenStateMachine.swift */; };
|
||||
60ED66E63A169E47489348A8 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 886A0A498FA01E8EDD451D05 /* Sentry */; };
|
||||
611BEE29B8B622204E1E6B04 /* SecurityAndPrivacyScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F2F6B6E56055EF173A2DD3 /* SecurityAndPrivacyScreenCoordinator.swift */; };
|
||||
6146996D5C4DDD5DA816FC87 /* AuthenticationTextFieldStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCACD75595C40EACD6AD4A74 /* AuthenticationTextFieldStyle.swift */; };
|
||||
617624A97BDBB75ED3DD8156 /* RoomScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */; };
|
||||
6189B4ABD535CE526FA1107B /* StartChatViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DF438EAFC732D2D95D34BF6 /* StartChatViewModelTests.swift */; };
|
||||
@ -525,6 +527,7 @@
|
||||
6AEB650311F694A5702255C9 /* UserProfileScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B4932E4EFBC8FAC10972CD /* UserProfileScreenCoordinator.swift */; };
|
||||
6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */; };
|
||||
6B61F5B27412ED4BC2F9769C /* test_audio.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 66B96842BF5F8ACA1AC84C55 /* test_audio.mp3 */; };
|
||||
6B80C24A52411EAF10E06E96 /* SecurityAndPrivacyScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBADF8010C813D905C172CE /* SecurityAndPrivacyScreenModels.swift */; };
|
||||
6BAD956B909A6E29F6CC6E7C /* ButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC23C63849452BC86EA2852 /* ButtonStyle.swift */; };
|
||||
6C34237AFB808E38FC8776B9 /* RoomStateEventStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D55702474F279D910D2D162 /* RoomStateEventStringBuilder.swift */; };
|
||||
6C98153D60FF9B648C166C27 /* TimelineItemMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91FFE1F410969ECB23FE9BB2 /* TimelineItemMenu.swift */; };
|
||||
@ -552,6 +555,7 @@
|
||||
71AC1CAAC23403FFE847F2C9 /* ComposerToolbarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C90514BE9B8ACCBCF0AD2489 /* ComposerToolbarViewModel.swift */; };
|
||||
71B62C48B8079D49F3FBC845 /* ExpiringTaskRunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B7A28A6606D58D1E38C55A /* ExpiringTaskRunnerTests.swift */; };
|
||||
71C1347F23868324A4F43940 /* NavigationModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A22A05E472533ED3C5A31B3 /* NavigationModule.swift */; };
|
||||
7254FB2EFDD43BC8BB7A1213 /* SecurityAndPrivacyScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4AE42C19EDE64B7CB7BE4D0 /* SecurityAndPrivacyScreen.swift */; };
|
||||
733E2B19AB1FDA3B93293A28 /* AppLockSetupPINScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3F275432954C8C6B1B7D966 /* AppLockSetupPINScreen.swift */; };
|
||||
7354D094A4C59B555F407FA1 /* RustTracing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 542D4F49FABA056DEEEB3400 /* RustTracing.swift */; };
|
||||
73F33E9776B7A50B65A031D2 /* AppLockSettingsScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0BA67B3E4EF9D29D14A78CE /* AppLockSettingsScreenViewModelTests.swift */; };
|
||||
@ -613,6 +617,7 @@
|
||||
7C0E29E0279866C62EC67A28 /* JoinRoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE5127D6EA05B2E45D0A7D59 /* JoinRoomScreenViewModelTests.swift */; };
|
||||
7C164A642E8932B5F9004550 /* test_voice_message.m4a in Resources */ = {isa = PBXBuildFile; fileRef = DCA2D836BD10303F37FAAEED /* test_voice_message.m4a */; };
|
||||
7C1A7B594B2F8143F0DD0005 /* ElementXAttributeScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = C024C151639C4E1B91FCC68B /* ElementXAttributeScope.swift */; };
|
||||
7C545FFEC9930F7247352593 /* SecurityAndPrivacyScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 978092B01BEAB39F2C4389AE /* SecurityAndPrivacyScreenViewModel.swift */; };
|
||||
7C6376192F578E0BA801BFEC /* AnalyticsSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C64A14EE89928207E3B42B /* AnalyticsSettingsScreenModels.swift */; };
|
||||
7CD16990BA843BE9ED639129 /* ImageRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DFE4453AB0B34C203447162 /* ImageRoomTimelineItem.swift */; };
|
||||
7D249465ED00988EEEC14E05 /* JoinedRoomProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 867DC9530C42F7B5176BE465 /* JoinedRoomProxyMock.swift */; };
|
||||
@ -993,6 +998,7 @@
|
||||
CB6956565D858C523E3E3B16 /* ComposerDraftServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7E37072597F67C4DD8CC2DB /* ComposerDraftServiceProtocol.swift */; };
|
||||
CB6BCBF28E4B76EA08C2926D /* StateRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16048D30F0438731C41F775 /* StateRoomTimelineItem.swift */; };
|
||||
CB99B0FA38A4AC596F38CC13 /* KeychainControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */; };
|
||||
CB9FB2BEF313072C705AC9B5 /* SecurityAndPrivacyScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0315C328FF40F84276364E66 /* SecurityAndPrivacyScreenViewModelTests.swift */; };
|
||||
CBA9EDF305036039166E76FF /* StartChatScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2AEC1AB349A341FE13DEC1 /* StartChatScreenUITests.swift */; };
|
||||
CBD2ABE4C1A47ECD99E1488E /* NotificationSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421FA93BCC2840E66E4F306F /* NotificationSettingsScreenViewModelProtocol.swift */; };
|
||||
CC0D088F505F33A20DC5590F /* RoomStateEventStringBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEEAFB646E583655652C3D04 /* RoomStateEventStringBuilderTests.swift */; };
|
||||
@ -1322,6 +1328,7 @@
|
||||
029D5701F80A9AF7167BB4D0 /* TimelineModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineModels.swift; sourceTree = "<group>"; };
|
||||
02D155E09BF961BBA8F85263 /* InviteUsersScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
02EE0FABA8ED6D6C1D6CE71D /* ReactionsSummaryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactionsSummaryView.swift; sourceTree = "<group>"; };
|
||||
0315C328FF40F84276364E66 /* SecurityAndPrivacyScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
03277E40D0E0DE0712021A71 /* ServerConfirmationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
033DB41C51865A2E83174E87 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
||||
035177BCD8E8308B098AC3C2 /* WindowManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowManager.swift; sourceTree = "<group>"; };
|
||||
@ -1884,6 +1891,7 @@
|
||||
7B3D16709ADD4F4BCC710B1E /* SecureBackupScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupScreenModels.swift; sourceTree = "<group>"; };
|
||||
7B849D2FF2CC12BA411A1651 /* CreateRoomModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomModels.swift; sourceTree = "<group>"; };
|
||||
7B9FCA1CFD07B8CF9BD21266 /* FlowCoordinatorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowCoordinatorProtocol.swift; sourceTree = "<group>"; };
|
||||
7BBADF8010C813D905C172CE /* SecurityAndPrivacyScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreenModels.swift; sourceTree = "<group>"; };
|
||||
7C1AF829F12FDC99717082D9 /* RoomRolesAndPermissionsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomRolesAndPermissionsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
7C28B70BEFD3676F11D5D51F /* RoomRolesAndPermissionsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomRolesAndPermissionsScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
7C71B9802433F1B4252291BB /* IdentityConfirmationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
@ -2014,9 +2022,11 @@
|
||||
974AEAF3FE0C577A6C04AD6E /* RoomPermissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPermissions.swift; sourceTree = "<group>"; };
|
||||
976ED77B772F50C4BAD757E7 /* MediaEventsTimelineScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaEventsTimelineScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
9780389F8A53E4D26E23DD03 /* LoginScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
978092B01BEAB39F2C4389AE /* SecurityAndPrivacyScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
97B2ACA28A854E41AE3AC9AD /* TimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineViewModel.swift; sourceTree = "<group>"; };
|
||||
97C8E13A1FBA717B0C277ECC /* ProgressCursorModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressCursorModifier.swift; sourceTree = "<group>"; };
|
||||
97CE98208321C4D66E363612 /* ShimmerModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShimmerModifier.swift; sourceTree = "<group>"; };
|
||||
97F2F6B6E56055EF173A2DD3 /* SecurityAndPrivacyScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
981663D961C94270FA035FD0 /* Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alert.swift; sourceTree = "<group>"; };
|
||||
9873076F224E4CE09D8BD47D /* TemplateScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenUITests.swift; sourceTree = "<group>"; };
|
||||
989D7380D9C86B3A10D30B13 /* AppLockSetupPINScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
@ -2153,6 +2163,7 @@
|
||||
B43456E73F8A2D52B69B9FB9 /* TemplateScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
B4427AF4B7FB7EF3E3D424C7 /* QRCodeLoginService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeLoginService.swift; sourceTree = "<group>"; };
|
||||
B48B7AD4908C5C374517B892 /* MapAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = MapAssets.xcassets; sourceTree = "<group>"; };
|
||||
B4AE42C19EDE64B7CB7BE4D0 /* SecurityAndPrivacyScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreen.swift; sourceTree = "<group>"; };
|
||||
B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Analytics+SwiftUI.swift"; sourceTree = "<group>"; };
|
||||
B50F03079F6B5EF9CA005F14 /* TimelineProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineProxyProtocol.swift; sourceTree = "<group>"; };
|
||||
B53AC78E49A297AC1D72A7CF /* AppMediator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMediator.swift; sourceTree = "<group>"; };
|
||||
@ -2282,6 +2293,7 @@
|
||||
CEE20623EB4A9B88FB29F2BA /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/SAS.strings; sourceTree = "<group>"; };
|
||||
CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; path = UnitTests.xctestplan; sourceTree = "<group>"; };
|
||||
D01FD1171FF40E34D707FD00 /* BigIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BigIcon.swift; sourceTree = "<group>"; };
|
||||
D046ABB22E680F7C5054441B /* SecurityAndPrivacyScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
D071F86CD47582B9196C9D16 /* UserDiscoverySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoverySection.swift; sourceTree = "<group>"; };
|
||||
D086854995173E897F993C26 /* AdvancedSettingsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
D09227E671DB30795C43FFFD /* KnockRequestsListScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KnockRequestsListScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
@ -3118,6 +3130,14 @@
|
||||
path = Style;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
31602635E5D50101A3A24D51 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B4AE42C19EDE64B7CB7BE4D0 /* SecurityAndPrivacyScreen.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
31CE4DA53232AA534057F912 /* Mocks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -4147,6 +4167,7 @@
|
||||
848F69921527D31CAACB93AF /* SecureBackupLogoutConfirmationScreenViewModelTests.swift */,
|
||||
C0FF08D0BD7D0B4B6877AB7D /* SecureBackupRecoveryKeyScreenViewModelTests.swift */,
|
||||
40316EFFEAC7B206EE9A55AE /* SecureBackupScreenViewModelTests.swift */,
|
||||
0315C328FF40F84276364E66 /* SecurityAndPrivacyScreenViewModelTests.swift */,
|
||||
277C20CDD5B64510401B6D0D /* ServerConfigurationScreenViewStateTests.swift */,
|
||||
F08776C48FFB47CACF64ED10 /* ServerConfirmationScreenViewModelTests.swift */,
|
||||
E45EBAFF1A83538D54ABDF92 /* ServerSelectionScreenViewModelTests.swift */,
|
||||
@ -5256,6 +5277,18 @@
|
||||
path = RoomDirectorySearchScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C59BA103987B953BA374509F /* SecurityAndPrivacyScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97F2F6B6E56055EF173A2DD3 /* SecurityAndPrivacyScreenCoordinator.swift */,
|
||||
7BBADF8010C813D905C172CE /* SecurityAndPrivacyScreenModels.swift */,
|
||||
978092B01BEAB39F2C4389AE /* SecurityAndPrivacyScreenViewModel.swift */,
|
||||
D046ABB22E680F7C5054441B /* SecurityAndPrivacyScreenViewModelProtocol.swift */,
|
||||
31602635E5D50101A3A24D51 /* View */,
|
||||
);
|
||||
path = SecurityAndPrivacyScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C844840F3DD48A154C65AE0C /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -5580,6 +5613,7 @@
|
||||
679E9837ECA8D6776079D16E /* RoomScreen */,
|
||||
2E42D43DB6835A58D88B2F91 /* RoomSelectionScreen */,
|
||||
2565414373E6F68005966B8E /* SecureBackup */,
|
||||
C59BA103987B953BA374509F /* SecurityAndPrivacyScreen */,
|
||||
70B74A432C241E56A7ACE610 /* Settings */,
|
||||
EC4545C7E37E8294D3FE6800 /* StartChatScreen */,
|
||||
15D44FCA9475E660B7F56DB9 /* Timeline */,
|
||||
@ -6593,6 +6627,7 @@
|
||||
EB87DF90CF6F8D5D12404C6E /* SecureBackupLogoutConfirmationScreenViewModelTests.swift in Sources */,
|
||||
06B31F84CE52A7A7C271267C /* SecureBackupRecoveryKeyScreenViewModelTests.swift in Sources */,
|
||||
1B8E30B35BF8F541C1318F19 /* SecureBackupScreenViewModelTests.swift in Sources */,
|
||||
CB9FB2BEF313072C705AC9B5 /* SecurityAndPrivacyScreenViewModelTests.swift in Sources */,
|
||||
53A55748D5F587C9061F98BF /* ServerConfigurationScreenViewStateTests.swift in Sources */,
|
||||
89658A44C9FC19B58FD1C226 /* ServerConfirmationScreenViewModelTests.swift in Sources */,
|
||||
67ECD32538F6DAFE38A623F9 /* ServerSelectionScreenViewModelTests.swift in Sources */,
|
||||
@ -7327,6 +7362,11 @@
|
||||
DA7E867F5EAFF8E20B2EE3B6 /* SecureBackupScreenModels.swift in Sources */,
|
||||
7BF368A78E6D9AFD222F25AF /* SecureBackupScreenViewModel.swift in Sources */,
|
||||
AC90434798E7894370E80E66 /* SecureBackupScreenViewModelProtocol.swift in Sources */,
|
||||
7254FB2EFDD43BC8BB7A1213 /* SecurityAndPrivacyScreen.swift in Sources */,
|
||||
611BEE29B8B622204E1E6B04 /* SecurityAndPrivacyScreenCoordinator.swift in Sources */,
|
||||
6B80C24A52411EAF10E06E96 /* SecurityAndPrivacyScreenModels.swift in Sources */,
|
||||
7C545FFEC9930F7247352593 /* SecurityAndPrivacyScreenViewModel.swift in Sources */,
|
||||
0D617A152D099D94271D3BA8 /* SecurityAndPrivacyScreenViewModelProtocol.swift in Sources */,
|
||||
08547E55DD3686A84550996D /* SeparatorMediaEventsTimelineView.swift in Sources */,
|
||||
14E99D27628B1A6F0CB46FEA /* SeparatorRoomTimelineItem.swift in Sources */,
|
||||
5341D48F833E3E30F16FA2A3 /* SeparatorRoomTimelineView.swift in Sources */,
|
||||
|
@ -405,6 +405,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
return .mediaEventsTimeline(previousState: fromState)
|
||||
case (.mediaEventsTimeline(let previousState), .dismissMediaEventsTimeline):
|
||||
return previousState
|
||||
|
||||
case (.roomDetails, .presentSecurityAndPrivacyScreen):
|
||||
return .securityAndPrivacy(previousState: fromState)
|
||||
case (.securityAndPrivacy(let previousState), .dismissSecurityAndPrivacyScreen):
|
||||
return previousState
|
||||
|
||||
default:
|
||||
return nil
|
||||
@ -571,6 +576,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
Task { await self.startMediaEventsTimelineFlow() }
|
||||
case (.mediaEventsTimeline, .dismissMediaEventsTimeline, .roomDetails):
|
||||
break
|
||||
|
||||
case (.roomDetails, .presentSecurityAndPrivacyScreen, .securityAndPrivacy):
|
||||
presentSecurityAndPrivacyScreen()
|
||||
case (.securityAndPrivacy, .dismissSecurityAndPrivacyScreen, .roomDetails):
|
||||
break
|
||||
|
||||
// Child flow
|
||||
case (_, .startChildFlow(let roomID, let via, let entryPoint), .presentingChild):
|
||||
@ -849,6 +859,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
stateMachine.tryEvent(.presentKnockRequestsListScreen)
|
||||
case .presentMediaEventsTimeline:
|
||||
stateMachine.tryEvent(.presentMediaEventsTimeline)
|
||||
case .presentSecurityAndPrivacyScreen:
|
||||
stateMachine.tryEvent(.presentSecurityAndPrivacyScreen)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
@ -1453,6 +1465,24 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
private func presentSecurityAndPrivacyScreen() {
|
||||
let coordinator = SecurityAndPrivacyScreenCoordinator(parameters: .init(roomProxy: roomProxy))
|
||||
|
||||
coordinator.actionsPublisher.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .done:
|
||||
break
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
navigationStackCoordinator.push(coordinator) { [weak self] in
|
||||
self?.stateMachine.tryEvent(.dismissSecurityAndPrivacyScreen)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Other flows
|
||||
|
||||
private func startChildFlow(for roomID: String, via: [String], entryPoint: RoomFlowCoordinatorEntryPoint) async {
|
||||
@ -1604,6 +1634,7 @@ private extension RoomFlowCoordinator {
|
||||
case resolveSendFailure
|
||||
case knockRequestsList(previousState: State)
|
||||
case mediaEventsTimeline(previousState: State)
|
||||
case securityAndPrivacy(previousState: State)
|
||||
|
||||
/// A child flow is in progress.
|
||||
case presentingChild(childRoomID: String, previousState: State)
|
||||
@ -1687,6 +1718,9 @@ private extension RoomFlowCoordinator {
|
||||
|
||||
case presentMediaEventsTimeline
|
||||
case dismissMediaEventsTimeline
|
||||
|
||||
case presentSecurityAndPrivacyScreen
|
||||
case dismissSecurityAndPrivacyScreen
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ enum RoomDetailsScreenCoordinatorAction {
|
||||
case presentPinnedEventsTimeline
|
||||
case presentMediaEventsTimeline
|
||||
case presentKnockingRequestsListScreen
|
||||
case presentSecurityAndPrivacyScreen
|
||||
}
|
||||
|
||||
final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
||||
@ -85,6 +86,8 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
||||
actionsSubject.send(.presentMediaEventsTimeline)
|
||||
case .displayKnockingRequests:
|
||||
actionsSubject.send(.presentKnockingRequestsListScreen)
|
||||
case .displaySecurityAndPrivacy:
|
||||
actionsSubject.send(.presentSecurityAndPrivacyScreen)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
@ -24,6 +24,7 @@ enum RoomDetailsScreenViewModelAction {
|
||||
case displayPinnedEventsTimeline
|
||||
case displayMediaEventsTimeline
|
||||
case displayKnockingRequests
|
||||
case displaySecurityAndPrivacy
|
||||
}
|
||||
|
||||
// MARK: View
|
||||
@ -56,6 +57,10 @@ struct RoomDetailsScreenViewState: BindableState {
|
||||
knockingEnabled && dmRecipient == nil && isKnockableRoom && (canInviteUsers || canKickUsers || canBanUsers)
|
||||
}
|
||||
|
||||
var canSeeSecurityAndPrivacy: Bool {
|
||||
knockingEnabled && dmRecipient == nil && canEditRolesOrPermissions
|
||||
}
|
||||
|
||||
var mediaBrowserEnabled = false
|
||||
|
||||
var canEdit: Bool {
|
||||
@ -198,6 +203,7 @@ enum RoomDetailsScreenViewAction {
|
||||
case processTapPolls
|
||||
case toggleFavourite(isFavourite: Bool)
|
||||
case processTapRolesAndPermissions
|
||||
case processTapSecurityAndPrivacy
|
||||
case processTapCall
|
||||
case processTapPinnedEvents
|
||||
case processTapMediaEvents
|
||||
|
@ -172,6 +172,8 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
||||
actionsSubject.send(.displayMediaEventsTimeline)
|
||||
case .processTapRequestsToJoin:
|
||||
actionsSubject.send(.displayKnockingRequests)
|
||||
case .processTapSecurityAndPrivacy:
|
||||
actionsSubject.send(.displaySecurityAndPrivacy)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,6 +207,14 @@ struct RoomDetailsScreen: View {
|
||||
.onChange(of: context.isFavourite) { _, newValue in
|
||||
context.send(viewAction: .toggleFavourite(isFavourite: newValue))
|
||||
}
|
||||
|
||||
if context.viewState.canSeeSecurityAndPrivacy {
|
||||
ListRow(label: .default(title: L10n.screenRoomDetailsSecurityAndPrivacyTitle,
|
||||
icon: \.lock),
|
||||
kind: .navigationLink {
|
||||
context.send(viewAction: .processTapSecurityAndPrivacy)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,54 @@
|
||||
//
|
||||
// Copyright 2022-2024 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Please see LICENSE in the repository root for full details.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
struct SecurityAndPrivacyScreenCoordinatorParameters {
|
||||
let roomProxy: JoinedRoomProxyProtocol
|
||||
}
|
||||
|
||||
enum SecurityAndPrivacyScreenCoordinatorAction {
|
||||
case done
|
||||
|
||||
// Consider adding CustomStringConvertible conformance if the actions contain PII
|
||||
}
|
||||
|
||||
final class SecurityAndPrivacyScreenCoordinator: CoordinatorProtocol {
|
||||
private let parameters: SecurityAndPrivacyScreenCoordinatorParameters
|
||||
private let viewModel: SecurityAndPrivacyScreenViewModelProtocol
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SecurityAndPrivacyScreenCoordinatorAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<SecurityAndPrivacyScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(parameters: SecurityAndPrivacyScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
|
||||
viewModel = SecurityAndPrivacyScreenViewModel(roomProxy: parameters.roomProxy)
|
||||
}
|
||||
|
||||
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 .done:
|
||||
actionsSubject.send(.done)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func toPresentable() -> AnyView {
|
||||
AnyView(SecurityAndPrivacyScreen(context: viewModel.context))
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
//
|
||||
// Copyright 2022-2024 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Please see LICENSE in the repository root for full details.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum SecurityAndPrivacyScreenViewModelAction {
|
||||
case done
|
||||
}
|
||||
|
||||
struct SecurityAndPrivacyScreenViewState: BindableState {
|
||||
var bindings: SecurityAndPrivacyScreenViewStateBindings
|
||||
|
||||
var currentSettings: SecurityAndPrivacySettings
|
||||
|
||||
var hasChanges: Bool {
|
||||
currentSettings != bindings.desiredSettings
|
||||
}
|
||||
|
||||
init(accessType: SecurityAndPrivacyRoomAccessType,
|
||||
isEncryptionEnabled: Bool) {
|
||||
let settings = SecurityAndPrivacySettings(accessType: accessType, isEncryptionEnabled: isEncryptionEnabled)
|
||||
currentSettings = settings
|
||||
bindings = SecurityAndPrivacyScreenViewStateBindings(desiredSettings: settings)
|
||||
}
|
||||
}
|
||||
|
||||
struct SecurityAndPrivacyScreenViewStateBindings {
|
||||
var desiredSettings: SecurityAndPrivacySettings
|
||||
var alertInfo: AlertInfo<SecurityAndPrivacyAlertType>?
|
||||
}
|
||||
|
||||
struct SecurityAndPrivacySettings: Equatable {
|
||||
var accessType: SecurityAndPrivacyRoomAccessType
|
||||
var isEncryptionEnabled: Bool
|
||||
}
|
||||
|
||||
enum SecurityAndPrivacyRoomAccessType {
|
||||
case inviteOnly
|
||||
case askToJoin
|
||||
case anyone
|
||||
}
|
||||
|
||||
enum SecurityAndPrivacyAlertType {
|
||||
case enableEncryption
|
||||
}
|
||||
|
||||
enum SecurityAndPrivacyScreenViewAction {
|
||||
case save
|
||||
case tryUpdatingEncryption(Bool)
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
//
|
||||
// Copyright 2022-2024 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Please see LICENSE in the repository root for full details.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias SecurityAndPrivacyScreenViewModelType = StateStoreViewModel<SecurityAndPrivacyScreenViewState, SecurityAndPrivacyScreenViewAction>
|
||||
|
||||
class SecurityAndPrivacyScreenViewModel: SecurityAndPrivacyScreenViewModelType, SecurityAndPrivacyScreenViewModelProtocol {
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SecurityAndPrivacyScreenViewModelAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<SecurityAndPrivacyScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(roomProxy: JoinedRoomProxyProtocol) {
|
||||
self.roomProxy = roomProxy
|
||||
super.init(initialViewState: SecurityAndPrivacyScreenViewState(accessType: roomProxy.infoPublisher.value.roomAccessType,
|
||||
isEncryptionEnabled: roomProxy.isEncrypted))
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
override func process(viewAction: SecurityAndPrivacyScreenViewAction) {
|
||||
MXLog.info("View model: received view action: \(viewAction)")
|
||||
|
||||
switch viewAction {
|
||||
case .save:
|
||||
actionsSubject.send(.done)
|
||||
case .tryUpdatingEncryption(let updatedValue):
|
||||
if updatedValue {
|
||||
state.bindings.alertInfo = .init(id: .enableEncryption,
|
||||
title: L10n.screenSecurityAndPrivacyEnableEncryptionAlertTitle,
|
||||
message: L10n.screenSecurityAndPrivacyEnableEncryptionAlertDescription,
|
||||
primaryButton: .init(title: L10n.screenSecurityAndPrivacyEnableEncryptionAlertConfirmButtonTitle,
|
||||
action: { [weak self] in self?.state.bindings.desiredSettings.isEncryptionEnabled = true }),
|
||||
secondaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil))
|
||||
} else {
|
||||
state.bindings.desiredSettings.isEncryptionEnabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension RoomInfoProxy {
|
||||
var roomAccessType: SecurityAndPrivacyRoomAccessType {
|
||||
switch joinRule {
|
||||
case .invite, .restricted:
|
||||
return .inviteOnly
|
||||
case .knock, .knockRestricted:
|
||||
return .askToJoin
|
||||
default:
|
||||
return .anyone
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
//
|
||||
// Copyright 2022-2024 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Please see LICENSE in the repository root for full details.
|
||||
//
|
||||
|
||||
import Combine
|
||||
|
||||
@MainActor
|
||||
protocol SecurityAndPrivacyScreenViewModelProtocol {
|
||||
var actionsPublisher: AnyPublisher<SecurityAndPrivacyScreenViewModelAction, Never> { get }
|
||||
var context: SecurityAndPrivacyScreenViewModelType.Context { get }
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
//
|
||||
// Copyright 2022-2024 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Please see LICENSE in the repository root for full details.
|
||||
//
|
||||
|
||||
import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct SecurityAndPrivacyScreen: View {
|
||||
@ObservedObject var context: SecurityAndPrivacyScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
roomAccessSection
|
||||
encryptionSection
|
||||
}
|
||||
.compoundList()
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.navigationTitle(L10n.screenSecurityAndPrivacyTitle)
|
||||
.toolbar { toolbar }
|
||||
.alert(item: $context.alertInfo)
|
||||
}
|
||||
|
||||
private var roomAccessSection: some View {
|
||||
Section {
|
||||
ListRow(label: .plain(title: L10n.screenSecurityAndPrivacyRoomAccessInviteOnlyOptionTitle,
|
||||
description: L10n.screenSecurityAndPrivacyRoomAccessInviteOnlyOptionDescription),
|
||||
kind: .selection(isSelected: context.desiredSettings.accessType == .inviteOnly) { context.desiredSettings.accessType = .inviteOnly })
|
||||
ListRow(label: .plain(title: L10n.screenSecurityAndPrivacyAskToJoinOptionTitle,
|
||||
description: L10n.screenSecurityAndPrivacyAskToJoinOptionDescription),
|
||||
kind: .selection(isSelected: context.desiredSettings.accessType == .askToJoin) { context.desiredSettings.accessType = .askToJoin })
|
||||
ListRow(label: .plain(title: L10n.screenSecurityAndPrivacyRoomAccessAnyoneOptionTitle,
|
||||
description: L10n.screenSecurityAndPrivacyRoomAccessAnyoneOptionDescription),
|
||||
kind: .selection(isSelected: context.desiredSettings.accessType == .anyone) { context.desiredSettings.accessType = .anyone })
|
||||
} header: {
|
||||
Text(L10n.screenSecurityAndPrivacyRoomAccessSectionTitle)
|
||||
.compoundListSectionHeader()
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var encryptionSection: some View {
|
||||
let encryptionBinding = Binding<Bool>(get: {
|
||||
context.desiredSettings.isEncryptionEnabled
|
||||
}, set: { newValue in
|
||||
context.send(viewAction: .tryUpdatingEncryption(newValue))
|
||||
})
|
||||
|
||||
Section {
|
||||
ListRow(label: .plain(title: L10n.screenSecurityAndPrivacyEncryptionToggleTitle),
|
||||
kind: .toggle(encryptionBinding))
|
||||
// We don't allow editing the encryption state if the current setting on the server is `enabled`
|
||||
.disabled(context.viewState.currentSettings.isEncryptionEnabled)
|
||||
} header: {
|
||||
Text(L10n.screenSecurityAndPrivacyEncryptionSectionTitle)
|
||||
.compoundListSectionHeader()
|
||||
} footer: {
|
||||
Text(L10n.screenSecurityAndPrivacyEncryptionSectionFooter)
|
||||
.compoundListSectionFooter()
|
||||
}
|
||||
}
|
||||
|
||||
@ToolbarContentBuilder
|
||||
var toolbar: some ToolbarContent {
|
||||
ToolbarItem(placement: .confirmationAction) {
|
||||
Button(L10n.actionSave) {
|
||||
context.send(viewAction: .save)
|
||||
}
|
||||
.disabled(!context.viewState.hasChanges)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
// TODO: Add back TestablePreview, this is WIP so running preview tests for it is not necessary
|
||||
struct SecurityAndPrivacyScreen_Previews: PreviewProvider {
|
||||
static let inviteOnlyViewModel = SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(joinRule: .invite)))
|
||||
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
SecurityAndPrivacyScreen(context: inviteOnlyViewModel.context)
|
||||
}
|
||||
}
|
||||
}
|
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPad-en-GB.Generic-Room.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPad-en-GB.Generic-Room.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPad-en-GB.Simple-Room.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPad-en-GB.Simple-Room.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPad-pseudo.Generic-Room.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPad-pseudo.Generic-Room.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPad-pseudo.Simple-Room.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPad-pseudo.Simple-Room.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPhone-16-en-GB.Generic-Room.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPhone-16-en-GB.Generic-Room.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPhone-16-en-GB.Simple-Room.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPhone-16-en-GB.Simple-Room.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPhone-16-pseudo.Generic-Room.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPhone-16-pseudo.Generic-Room.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPhone-16-pseudo.Simple-Room.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomDetailsScreen-iPhone-16-pseudo.Simple-Room.png
(Stored with Git LFS)
Binary file not shown.
@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright 2022-2024 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Please see LICENSE in the repository root for full details.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
@testable import ElementX
|
||||
|
||||
@MainActor
|
||||
class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
|
||||
var viewModel: SecurityAndPrivacyScreenViewModelProtocol!
|
||||
|
||||
var context: SecurityAndPrivacyScreenViewModelType.Context {
|
||||
viewModel.context
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user