mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
parent
088ca622a1
commit
74b36ce870
@ -118,6 +118,7 @@
|
||||
2CA6ABBC9A88EB89EA52FCCB /* ConfettiScene.scn in Resources */ = {isa = PBXBuildFile; fileRef = B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */; };
|
||||
2CB6787E25B11711518E9588 /* OnboardingCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6281B199D8A8F0892490C2E /* OnboardingCoordinator.swift */; };
|
||||
2E43A3D221BE9587BC19C3F1 /* MatrixEntityRegexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F31F59030205A6F65B057E1A /* MatrixEntityRegexTests.swift */; };
|
||||
2E8C6672D0EE7D5B1BEDB8E2 /* ServerConfirmationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7478623CECC9438014244BA /* ServerConfirmationScreen.swift */; };
|
||||
2F1CF90A3460C153154427F0 /* RoomScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086B997409328F091EBA43CE /* RoomScreenUITests.swift */; };
|
||||
2F94054F50E312AF30BE07F3 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B21E611DADDEF00307E7AC /* String.swift */; };
|
||||
308BD9343B95657FAA583FB7 /* SwiftState in Frameworks */ = {isa = PBXBuildFile; productRef = 19CD5B074D7DD44AF4C58BB6 /* SwiftState */; };
|
||||
@ -152,6 +153,7 @@
|
||||
3F1893D73EEBF6ED4FCF6747 /* AnalyticsSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85890C78055B786CCABC9194 /* AnalyticsSettingsScreenModels.swift */; };
|
||||
3F2148F11164C7C5609984EB /* GZIP in Frameworks */ = {isa = PBXBuildFile; productRef = 2B788C81F6369D164ADEB917 /* GZIP */; };
|
||||
3F70E237CE4C3FAB02FC227F /* NotificationConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C830A64609CBD152F06E0457 /* NotificationConstants.swift */; };
|
||||
401BB28CD6B7DD6B4E7863E7 /* ServerConfirmationScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9342F5D6729627B6393AF853 /* ServerConfirmationScreenModels.swift */; };
|
||||
407DCE030E0F9B7C9861D38A /* PostHog in Frameworks */ = {isa = PBXBuildFile; productRef = 4278261E147DB2DE5CFB7FC5 /* PostHog */; };
|
||||
40B79D20A873620F7F128A2C /* UserPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35FA991289149D31F4286747 /* UserPreference.swift */; };
|
||||
414F50CFCFEEE2611127DCFB /* RestorationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3558A15CFB934F9229301527 /* RestorationToken.swift */; };
|
||||
@ -194,6 +196,7 @@
|
||||
518C93DC6516D3D018DE065F /* UNNotificationRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49E751D7EDB6043238111D90 /* UNNotificationRequest.swift */; };
|
||||
520EEDAFBC778AB0B41F2F53 /* ClientMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADE6170EFE6A161B0A68AB61 /* ClientMock.swift */; };
|
||||
5375902175B2FEA2949D7D74 /* LoginScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CDDDDD9FE1A699D23A5E096 /* LoginScreen.swift */; };
|
||||
53A55748D5F587C9061F98BF /* ServerConfigurationScreenViewStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 277C20CDD5B64510401B6D0D /* ServerConfigurationScreenViewStateTests.swift */; };
|
||||
53DEF39F0C4DE02E3FC56D91 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 800631D7250B7F93195035F1 /* KeychainAccess */; };
|
||||
53F1196F9C69512306A2693F /* TextRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28C19F54A0C4FC9AB7ABD583 /* TextRoomTimelineItemContent.swift */; };
|
||||
5455147CAC63F71E48F7D699 /* NSELogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3D455BC2423D911A62ACFB2 /* NSELogger.swift */; };
|
||||
@ -204,6 +207,7 @@
|
||||
56F0A22972A3BB519DA2261C /* HomeScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F5530B2212862FA4BEFF2D /* HomeScreenViewModelProtocol.swift */; };
|
||||
5770C4906668C6D3008A2AC9 /* SessionVerificationScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5046BB295AEAFA6FB81655 /* SessionVerificationScreenModels.swift */; };
|
||||
588411C8FD72B2A2DFE5F7DE /* XCUIElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = E992D7B8BE54B2AB454613AF /* XCUIElement.swift */; };
|
||||
5894C2514400A4FBC9327632 /* ServerConfirmationScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03277E40D0E0DE0712021A71 /* ServerConfirmationScreenCoordinator.swift */; };
|
||||
5897A59DDBD3592282092223 /* MediaSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49B9785E3AD7D1C15A29F2F /* MediaSourceProxy.swift */; };
|
||||
595965CAD43B4E6CD615C17D /* AnalyticsSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28D116D4633E177BE1AC0E71 /* AnalyticsSettingsScreenViewModel.swift */; };
|
||||
59F940FCBE6BC343AECEF75E /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2245243369B99216C7D84E /* ImageCache.swift */; };
|
||||
@ -330,6 +334,7 @@
|
||||
890F0D453FE388756479AC97 /* AnalyticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C687844F60BFF532D49A994C /* AnalyticsTests.swift */; };
|
||||
8922219C5C934C4155E8CA50 /* SharedUserDefaultsKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA8DC95C079805B0B56E8A9 /* SharedUserDefaultsKeys.swift */; };
|
||||
8944548A684F1C837CEC47F4 /* RoomMembersListScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0946F77B696176E062D037 /* RoomMembersListScreenModels.swift */; };
|
||||
89658A44C9FC19B58FD1C226 /* ServerConfirmationScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F08776C48FFB47CACF64ED10 /* ServerConfirmationScreenViewModelTests.swift */; };
|
||||
899793EFC63DF93C3E0141E7 /* RoomMemberDetailsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FA60F848D1C14F873F9621A /* RoomMemberDetailsScreenCoordinator.swift */; };
|
||||
8A0BD60CA4A6004DB06B5403 /* MediaUploadingPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669F35C505ACE1110589F875 /* MediaUploadingPreprocessor.swift */; };
|
||||
8AB8ED1051216546CB35FA0E /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5E9C044BEB7C70B1378E91 /* UserSession.swift */; };
|
||||
@ -400,6 +405,7 @@
|
||||
A14A9419105A1CD42F0511C4 /* UserIndicatorModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E43005941B3A2C9671E23C85 /* UserIndicatorModalView.swift */; };
|
||||
A17FAD2EBC53E17B5FD384DB /* InviteUsersScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22730A30C50AC2E3D5BA8642 /* InviteUsersScreenViewModelProtocol.swift */; };
|
||||
A182920710146E5BEAA1A705 /* AnalyticsSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7DBA101D643B31E813F3AC1 /* AnalyticsSettingsScreen.swift */; };
|
||||
A1D4033881320C9EB88196E6 /* ServerConfirmationScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE846DDA83BFD7EC5C03760B /* ServerConfirmationScreenUITests.swift */; };
|
||||
A216C83ADCF32BA5EF8A6FBC /* InviteUsersViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845DDBDE5A0887E73D38B826 /* InviteUsersViewModelTests.swift */; };
|
||||
A23B8B27A1436A1049EEF68E /* InfoPlistReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A580295A56B55A856CC4084 /* InfoPlistReader.swift */; };
|
||||
A2434D4DFB49A68E5CD0F53C /* MediaLoaderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A02406480C351B8C6E0682C /* MediaLoaderProtocol.swift */; };
|
||||
@ -478,7 +484,6 @@
|
||||
BB6BF528BC7F5B87E08C4F18 /* CameraPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8A3B7637DDBD6AA97AC2545 /* CameraPicker.swift */; };
|
||||
BB784A02BADB03C820617A46 /* TextRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90A55430639712CFACA34F43 /* TextRoomTimelineItem.swift */; };
|
||||
BCC864190651B3A3CF51E4DF /* MediaFileHandleProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEC1D382565A4E9CAC2F14EA /* MediaFileHandleProxy.swift */; };
|
||||
BCEC41FB1F2BB663183863E4 /* LoginServerInfoSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D379E13DD9D987470A3C70C /* LoginServerInfoSection.swift */; };
|
||||
BD203FC6A7AE7637EA003643 /* RoomProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ABDE6F66532CBEB0E016F94 /* RoomProxyMock.swift */; };
|
||||
BD6D98676111DA8FC2BE4908 /* InvitesScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86873A768B13069BB5CAECF6 /* InvitesScreenViewModelProtocol.swift */; };
|
||||
BD782053BE4C3D2F0BDE5699 /* ServiceLocator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57F95CADD0A5DBD76B990FCB /* ServiceLocator.swift */; };
|
||||
@ -605,6 +610,7 @@
|
||||
EF7924005216B8189898F370 /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */; };
|
||||
F06CE9132855E81EBB6DDC32 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 940C605265DD82DA0C655E23 /* Kingfisher */; };
|
||||
F07D88421A9BC4D03D4A5055 /* VideoRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F348B5F2C12F9D4F4B4D3884 /* VideoRoomTimelineItem.swift */; };
|
||||
F0A26CD502C3A5868353B0FA /* ServerConfirmationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24DEE0682C95F897B6C7CB0D /* ServerConfirmationScreenViewModel.swift */; };
|
||||
F0F82C3C848C865C3098AA52 /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 21C83087604B154AA30E9A8F /* SnapshotTesting */; };
|
||||
F118DD449066E594F63C697D /* RoomMemberProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32B5E17028C02DFA7DDA3931 /* RoomMemberProxyProtocol.swift */; };
|
||||
F16109A6F6DF03DA26D59233 /* RoomDetailsEditScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 122186B7CD1BC46A9C629DD9 /* RoomDetailsEditScreenUITests.swift */; };
|
||||
@ -640,6 +646,7 @@
|
||||
FBF09B6C900415800DDF2A21 /* EmojiProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C113E0CB7E15E9765B1817A /* EmojiProvider.swift */; };
|
||||
FC10228E73323BDC09526F97 /* GZIP in Frameworks */ = {isa = PBXBuildFile; productRef = 997C7385E1A07E061D7E2100 /* GZIP */; };
|
||||
FCD3F2B82CAB29A07887A127 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 2B43F2AF7456567FE37270A7 /* KeychainAccess */; };
|
||||
FD762761C5D0C30E6255C3D8 /* ServerConfirmationScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA4CF2F5B4F68D02E412004 /* ServerConfirmationScreenViewModelProtocol.swift */; };
|
||||
FE4593FC2A02AAF92E089565 /* ElementAnimations.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF1593DD87F974F8509BB619 /* ElementAnimations.swift */; };
|
||||
FF149F0A3550A54C50ECBE7A /* AppRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C843CF833BF6485B64AC87E1 /* AppRouter.swift */; };
|
||||
FFD3E4FF948E06C7585317FC /* TimelineStyler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892E29C98C4E8182C9037F84 /* TimelineStyler.swift */; };
|
||||
@ -699,6 +706,7 @@
|
||||
024F7398C5FC12586FB10E9D /* EffectsScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EffectsScene.swift; sourceTree = "<group>"; };
|
||||
0287793F11C480E242B03DF5 /* UserDiscoveryServiceTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoveryServiceTest.swift; sourceTree = "<group>"; };
|
||||
02D155E09BF961BBA8F85263 /* InviteUsersScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenViewModel.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>"; };
|
||||
0376C429FAB1687C3D905F3E /* MockCoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCoder.swift; sourceTree = "<group>"; };
|
||||
03FABD73FD8086EFAB699F42 /* MediaUploadPreviewScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
@ -783,9 +791,11 @@
|
||||
227AC5D71A4CE43512062243 /* URL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URL.swift; sourceTree = "<group>"; };
|
||||
24227FF9A2797F6EA7F69CDD /* HomeScreenInvitesButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenInvitesButton.swift; sourceTree = "<group>"; };
|
||||
248649EBA5BC33DB93698734 /* SessionVerificationControllerProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxyMock.swift; sourceTree = "<group>"; };
|
||||
24DEE0682C95F897B6C7CB0D /* ServerConfirmationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
24F5530B2212862FA4BEFF2D /* HomeScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
25F7FE40EF7490A7E09D7BE6 /* NotificationItemProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationItemProxy.swift; sourceTree = "<group>"; };
|
||||
260004737C573A56FA01E86E /* Encodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Encodable.swift; sourceTree = "<group>"; };
|
||||
277C20CDD5B64510401B6D0D /* ServerConfigurationScreenViewStateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfigurationScreenViewStateTests.swift; sourceTree = "<group>"; };
|
||||
27A1AD6389A4659AF0CEAE62 /* NotificationServiceExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationServiceExtension.swift; sourceTree = "<group>"; };
|
||||
287FC98AF2664EAD79C0D902 /* UIDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDevice.swift; sourceTree = "<group>"; };
|
||||
28C19F54A0C4FC9AB7ABD583 /* TextRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineItemContent.swift; sourceTree = "<group>"; };
|
||||
@ -969,7 +979,6 @@
|
||||
7B9FCA1CFD07B8CF9BD21266 /* FlowCoordinatorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowCoordinatorProtocol.swift; sourceTree = "<group>"; };
|
||||
7D0CBC76C80E04345E11F2DB /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
||||
7D25A35764C7B3DB78954AB5 /* RoomTimelineItemFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemFactoryProtocol.swift; sourceTree = "<group>"; };
|
||||
7D379E13DD9D987470A3C70C /* LoginServerInfoSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginServerInfoSection.swift; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
7E0ADE4FAA5A4DB91CB07737 /* SettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreen.swift; sourceTree = "<group>"; };
|
||||
@ -1016,6 +1025,7 @@
|
||||
92B45A6B13D32A131FCA4EFF /* FilePreviewScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilePreviewScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
92FCD9116ADDE820E4E30F92 /* UIKitBackgroundTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTask.swift; sourceTree = "<group>"; };
|
||||
9332DFE9642F0A46ECA0497B /* BlurHashEncode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashEncode.swift; sourceTree = "<group>"; };
|
||||
9342F5D6729627B6393AF853 /* ServerConfirmationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenModels.swift; sourceTree = "<group>"; };
|
||||
9349F590E35CE514A71E6764 /* LoginHomeserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginHomeserver.swift; sourceTree = "<group>"; };
|
||||
935C2FB18EFB8EEE96B26330 /* CreateRoomFlowParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomFlowParameters.swift; sourceTree = "<group>"; };
|
||||
93B3513E60591237A49EE102 /* AnalyticsSettingsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
@ -1075,6 +1085,7 @@
|
||||
AAD01F7FC2BBAC7351948595 /* UserProfile+Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserProfile+Mock.swift"; sourceTree = "<group>"; };
|
||||
AAE73D571D4F9C36DD45255A /* BackgroundTaskServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskServiceProtocol.swift; sourceTree = "<group>"; };
|
||||
AB8E75B9CB6C78BE8D09B1AF /* OnboardingScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingScreen.swift; sourceTree = "<group>"; };
|
||||
ABA4CF2F5B4F68D02E412004 /* ServerConfirmationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
AC1DA29A5A041CC0BACA7CB0 /* MockImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockImageCache.swift; sourceTree = "<group>"; };
|
||||
AC3F82523D6F48B926D6AF68 /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.swift; sourceTree = "<group>"; };
|
||||
ACB6C5E4950B6C9842F35A38 /* RoomTimelineViewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineViewProvider.swift; sourceTree = "<group>"; };
|
||||
@ -1194,6 +1205,7 @@
|
||||
DBA8DC95C079805B0B56E8A9 /* SharedUserDefaultsKeys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedUserDefaultsKeys.swift; sourceTree = "<group>"; };
|
||||
DBFEAC3AC691CBB84983E275 /* ElementXTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXTests.swift; sourceTree = "<group>"; };
|
||||
DC0AEA686E425F86F6BA0404 /* UNNotification+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNNotification+Creator.swift"; sourceTree = "<group>"; };
|
||||
DE846DDA83BFD7EC5C03760B /* ServerConfirmationScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenUITests.swift; sourceTree = "<group>"; };
|
||||
DEC1D382565A4E9CAC2F14EA /* MediaFileHandleProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaFileHandleProxy.swift; sourceTree = "<group>"; };
|
||||
DF05DA24F71B455E8EFEBC3B /* SessionVerificationViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationViewModelTests.swift; sourceTree = "<group>"; };
|
||||
DF38B69D2C331A499276F400 /* FilePreviewViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilePreviewViewModelTests.swift; sourceTree = "<group>"; };
|
||||
@ -1240,6 +1252,7 @@
|
||||
EFF7BF82A950B91BC5469E91 /* ViewFrameReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewFrameReader.swift; sourceTree = "<group>"; };
|
||||
EFFD3200F9960D4996159F10 /* BugReportServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportServiceTests.swift; sourceTree = "<group>"; };
|
||||
F012CB5EE3F2B67359F6CC52 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
||||
F08776C48FFB47CACF64ED10 /* ServerConfirmationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
F174A5627CDB3CAF280D1880 /* EmojiPickerScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenModels.swift; sourceTree = "<group>"; };
|
||||
F17EFA1D3D09FC2F9C5E1CB2 /* MediaProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProvider.swift; sourceTree = "<group>"; };
|
||||
F1964EE08550BEDBD0B0F5FD /* FilePreviewScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilePreviewScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
@ -1255,6 +1268,7 @@
|
||||
F57C8022B8A871A1DCD1750A /* UserIndicatorToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorToastView.swift; sourceTree = "<group>"; };
|
||||
F72EFC8C634469F9262659C7 /* NSItemProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSItemProvider.swift; sourceTree = "<group>"; };
|
||||
F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormattedBodyText.swift; sourceTree = "<group>"; };
|
||||
F7478623CECC9438014244BA /* ServerConfirmationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreen.swift; sourceTree = "<group>"; };
|
||||
F754E66A8970963B15B2A41E /* PermalinkBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermalinkBuilder.swift; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
@ -1560,6 +1574,14 @@
|
||||
path = RoomMember;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2CAAA563083EAC0FA6BDC4F3 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F7478623CECC9438014244BA /* ServerConfirmationScreen.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2D0D49B0533C4C2EB889BF3A /* ServerSelectionScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -2056,7 +2078,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4CDDDDD9FE1A699D23A5E096 /* LoginScreen.swift */,
|
||||
7D379E13DD9D987470A3C70C /* LoginServerInfoSection.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
@ -2231,6 +2252,8 @@
|
||||
69B63F817FE305548DB4B512 /* RoomMembersListViewModelTests.swift */,
|
||||
93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */,
|
||||
AEEAFB646E583655652C3D04 /* RoomStateEventStringBuilderTests.swift */,
|
||||
277C20CDD5B64510401B6D0D /* ServerConfigurationScreenViewStateTests.swift */,
|
||||
F08776C48FFB47CACF64ED10 /* ServerConfirmationScreenViewModelTests.swift */,
|
||||
EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */,
|
||||
A1C22B1B5FA3A765EADB2CC9 /* SessionVerificationStateMachineTests.swift */,
|
||||
DF05DA24F71B455E8EFEBC3B /* SessionVerificationViewModelTests.swift */,
|
||||
@ -2546,6 +2569,7 @@
|
||||
0F19DBE940499D3E3DD405D8 /* RoomMemberDetailsScreenUITests.swift */,
|
||||
C5B7A755E985FA14469E86B2 /* RoomMembersListScreenUITests.swift */,
|
||||
086B997409328F091EBA43CE /* RoomScreenUITests.swift */,
|
||||
DE846DDA83BFD7EC5C03760B /* ServerConfirmationScreenUITests.swift */,
|
||||
054F469E433864CC6FE6EE8E /* ServerSelectionUITests.swift */,
|
||||
6D4777F0142E330A75C46FE4 /* SessionVerificationUITests.swift */,
|
||||
8EC57A32ABC80D774CC663DB /* SettingsScreenUITests.swift */,
|
||||
@ -2793,6 +2817,18 @@
|
||||
path = RoomMemberDetailsScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BA1938A75D8C780F694CEB62 /* ServerConfirmationScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
03277E40D0E0DE0712021A71 /* ServerConfirmationScreenCoordinator.swift */,
|
||||
9342F5D6729627B6393AF853 /* ServerConfirmationScreenModels.swift */,
|
||||
24DEE0682C95F897B6C7CB0D /* ServerConfirmationScreenViewModel.swift */,
|
||||
ABA4CF2F5B4F68D02E412004 /* ServerConfirmationScreenViewModelProtocol.swift */,
|
||||
2CAAA563083EAC0FA6BDC4F3 /* View */,
|
||||
);
|
||||
path = ServerConfirmationScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C0937E3B06A8F0E2DB7C8241 /* Other */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -3067,6 +3103,7 @@
|
||||
92390F9FA98255440A6BF5F8 /* OIDCAuthenticationPresenter.swift */,
|
||||
9E6D88E8AFFBF2C1D589C0FA /* UIConstants.swift */,
|
||||
90F48FEF84016ED42A94BA24 /* LoginScreen */,
|
||||
BA1938A75D8C780F694CEB62 /* ServerConfirmationScreen */,
|
||||
2D0D49B0533C4C2EB889BF3A /* ServerSelectionScreen */,
|
||||
5B2C520AB9863B8CBC8EB3CA /* SoftLogoutScreen */,
|
||||
);
|
||||
@ -3640,6 +3677,8 @@
|
||||
CAF8755E152204F55F8D6B5B /* RoomMembersListViewModelTests.swift in Sources */,
|
||||
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */,
|
||||
CC0D088F505F33A20DC5590F /* RoomStateEventStringBuilderTests.swift in Sources */,
|
||||
53A55748D5F587C9061F98BF /* ServerConfigurationScreenViewStateTests.swift in Sources */,
|
||||
89658A44C9FC19B58FD1C226 /* ServerConfirmationScreenViewModelTests.swift in Sources */,
|
||||
93875ADD456142D20823ED24 /* ServerSelectionViewModelTests.swift in Sources */,
|
||||
86675910612A12409262DFBD /* SessionVerificationStateMachineTests.swift in Sources */,
|
||||
755727E0B756430DFFEC4732 /* SessionVerificationViewModelTests.swift in Sources */,
|
||||
@ -3845,7 +3884,6 @@
|
||||
C5A07E2D88BE7D51DCECD166 /* LoginScreenModels.swift in Sources */,
|
||||
BDA68E8D95B2B24B28825B8B /* LoginScreenViewModel.swift in Sources */,
|
||||
A5B9EF45C7B8ACEB4954AE36 /* LoginScreenViewModelProtocol.swift in Sources */,
|
||||
BCEC41FB1F2BB663183863E4 /* LoginServerInfoSection.swift in Sources */,
|
||||
B94368839BDB69172E28E245 /* MXLog.swift in Sources */,
|
||||
B66757D0254843162595B25D /* MXLogger.swift in Sources */,
|
||||
67C05C50AD734283374605E3 /* MatrixEntityRegex.swift in Sources */,
|
||||
@ -3979,6 +4017,11 @@
|
||||
0BFA67AFD757EE2BA569836A /* ScrollViewAdapter.swift in Sources */,
|
||||
14E99D27628B1A6F0CB46FEA /* SeparatorRoomTimelineItem.swift in Sources */,
|
||||
49F2E7DD8CAACE09CEECE3E6 /* SeparatorRoomTimelineView.swift in Sources */,
|
||||
2E8C6672D0EE7D5B1BEDB8E2 /* ServerConfirmationScreen.swift in Sources */,
|
||||
5894C2514400A4FBC9327632 /* ServerConfirmationScreenCoordinator.swift in Sources */,
|
||||
401BB28CD6B7DD6B4E7863E7 /* ServerConfirmationScreenModels.swift in Sources */,
|
||||
F0A26CD502C3A5868353B0FA /* ServerConfirmationScreenViewModel.swift in Sources */,
|
||||
FD762761C5D0C30E6255C3D8 /* ServerConfirmationScreenViewModelProtocol.swift in Sources */,
|
||||
43F35A7E5703D64DB0519C59 /* ServerSelectionScreen.swift in Sources */,
|
||||
E5F4C992845388B50BABACAA /* ServerSelectionScreenCoordinator.swift in Sources */,
|
||||
6530865EB9A8C0F0AF0216DA /* ServerSelectionScreenModels.swift in Sources */,
|
||||
@ -4123,6 +4166,7 @@
|
||||
A8771F5975A82759FA5138AE /* RoomMemberDetailsScreenUITests.swift in Sources */,
|
||||
44121202B4A260C98BF615A7 /* RoomMembersListScreenUITests.swift in Sources */,
|
||||
2F1CF90A3460C153154427F0 /* RoomScreenUITests.swift in Sources */,
|
||||
A1D4033881320C9EB88196E6 /* ServerConfirmationScreenUITests.swift in Sources */,
|
||||
77FACC29F98FE2E65BBB6A5F /* ServerSelectionUITests.swift in Sources */,
|
||||
05EC896A4B9AF4A56670C0BB /* SessionVerificationUITests.swift in Sources */,
|
||||
9C5A07E7C33F3F40287D7861 /* SettingsScreenUITests.swift in Sources */,
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
// MARK: - Soft logout
|
||||
|
||||
"soft_logout_forgot_password" = "Forgot password";
|
||||
"soft_logout_signin_title" = "Sign in";
|
||||
"soft_logout_signin_notice" = "Your homeserver (%1$s) admin has signed you out of your account %2$s (%3$s).";
|
||||
"soft_logout_signin_e2e_warning_notice" = "Sign in to recover encryption keys stored exclusively on this device. You need them to read all of your secure messages on any device.";
|
||||
|
@ -23,8 +23,6 @@ public enum UntranslatedL10n {
|
||||
public static var softLogoutClearDataSubmit: String { return UntranslatedL10n.tr("Untranslated", "soft_logout_clear_data_submit") }
|
||||
/// Clear personal data
|
||||
public static var softLogoutClearDataTitle: String { return UntranslatedL10n.tr("Untranslated", "soft_logout_clear_data_title") }
|
||||
/// Forgot password
|
||||
public static var softLogoutForgotPassword: String { return UntranslatedL10n.tr("Untranslated", "soft_logout_forgot_password") }
|
||||
/// Sign in to recover encryption keys stored exclusively on this device. You need them to read all of your secure messages on any device.
|
||||
public static var softLogoutSigninE2eWarningNotice: String { return UntranslatedL10n.tr("Untranslated", "soft_logout_signin_e2e_warning_notice") }
|
||||
/// Your homeserver (%1$s) admin has signed you out of your account %2$s (%3$s).
|
||||
|
@ -26,6 +26,7 @@ struct A11yIdentifiers {
|
||||
static let reportContent = ReportContent()
|
||||
static let roomScreen = RoomScreen()
|
||||
static let roomDetailsScreen = RoomDetailsScreen()
|
||||
static let serverConfirmationScreen = ServerConfirmationScreen()
|
||||
static let sessionVerificationScreen = SessionVerificationScreen()
|
||||
static let softLogoutScreen = SoftLogoutScreen()
|
||||
static let startChatScreen = StartChatScreen()
|
||||
@ -73,7 +74,6 @@ struct A11yIdentifiers {
|
||||
let emailUsername = "login-email_username"
|
||||
let password = "login-password"
|
||||
let `continue` = "login-continue"
|
||||
let changeServer = "login-change_server"
|
||||
let oidc = "login-oidc"
|
||||
let unsupportedServer = "login-unsupported_server"
|
||||
}
|
||||
@ -106,6 +106,11 @@ struct A11yIdentifiers {
|
||||
let unignore = "room_member_details-unignore"
|
||||
}
|
||||
|
||||
struct ServerConfirmationScreen {
|
||||
let `continue` = "server_confirmation-continue"
|
||||
let changeServer = "server_confirmation-change_server"
|
||||
}
|
||||
|
||||
struct SessionVerificationScreen {
|
||||
let requestVerification = "session_verification-request_verification"
|
||||
let startSasVerification = "session_verification-start_sas_verification"
|
||||
|
@ -14,6 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
@ -26,6 +27,8 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
||||
private let authenticationService: AuthenticationServiceProxyProtocol
|
||||
private let navigationStackCoordinator: NavigationStackCoordinator
|
||||
|
||||
private var cancellables: Set<AnyCancellable> = []
|
||||
|
||||
weak var delegate: AuthenticationCoordinatorDelegate?
|
||||
|
||||
init(authenticationService: AuthenticationServiceProxyProtocol,
|
||||
@ -64,17 +67,20 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
||||
switch await authenticationService.configure(for: ServiceLocator.shared.settings.defaultHomeserverAddress) {
|
||||
case .success:
|
||||
stopLoading()
|
||||
showLoginScreen()
|
||||
showServerConfirmationScreen()
|
||||
case .failure:
|
||||
stopLoading()
|
||||
showServerSelectionScreen()
|
||||
showServerSelectionScreen(isModallyPresented: false)
|
||||
}
|
||||
}
|
||||
|
||||
private func showServerSelectionScreen() {
|
||||
private func showServerSelectionScreen(isModallyPresented: Bool) {
|
||||
let navigationCoordinator = NavigationStackCoordinator()
|
||||
let userIndicatorController: UserIndicatorControllerProtocol! = isModallyPresented ? UserIndicatorController(rootCoordinator: navigationCoordinator) : ServiceLocator.shared.userIndicatorController
|
||||
|
||||
let parameters = ServerSelectionScreenCoordinatorParameters(authenticationService: authenticationService,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
isModallyPresented: false)
|
||||
userIndicatorController: userIndicatorController,
|
||||
isModallyPresented: isModallyPresented)
|
||||
let coordinator = ServerSelectionScreenCoordinator(parameters: parameters)
|
||||
|
||||
coordinator.callback = { [weak self] action in
|
||||
@ -82,18 +88,46 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
||||
|
||||
switch action {
|
||||
case .updated:
|
||||
self.showLoginScreen()
|
||||
if isModallyPresented {
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
} else {
|
||||
showLoginScreen()
|
||||
}
|
||||
case .dismiss:
|
||||
MXLog.failure("ServerSelectionScreen is requesting dismiss when part of a stack.")
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
}
|
||||
}
|
||||
|
||||
if isModallyPresented {
|
||||
navigationCoordinator.setRootCoordinator(coordinator)
|
||||
navigationStackCoordinator.setSheetCoordinator(userIndicatorController)
|
||||
} else {
|
||||
navigationStackCoordinator.push(coordinator)
|
||||
}
|
||||
}
|
||||
|
||||
private func showServerConfirmationScreen() {
|
||||
let parameters = ServerConfirmationScreenCoordinatorParameters(authenticationService: authenticationService,
|
||||
authenticationFlow: .login)
|
||||
let coordinator = ServerConfirmationScreenCoordinator(parameters: parameters)
|
||||
|
||||
coordinator.actions.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .confirm:
|
||||
self.showLoginScreen()
|
||||
case .changeServer:
|
||||
self.showServerSelectionScreen(isModallyPresented: true)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
navigationStackCoordinator.push(coordinator)
|
||||
}
|
||||
|
||||
private func showLoginScreen() {
|
||||
let parameters = LoginScreenCoordinatorParameters(authenticationService: authenticationService,
|
||||
navigationStackCoordinator: navigationStackCoordinator)
|
||||
let parameters = LoginScreenCoordinatorParameters(authenticationService: authenticationService)
|
||||
let coordinator = LoginScreenCoordinator(parameters: parameters)
|
||||
|
||||
coordinator.callback = { [weak self] action in
|
||||
|
@ -20,8 +20,6 @@ import SwiftUI
|
||||
struct LoginScreenCoordinatorParameters {
|
||||
/// The service used to authenticate the user.
|
||||
let authenticationService: AuthenticationServiceProxyProtocol
|
||||
/// The navigation router used to present the server selection screen.
|
||||
let navigationStackCoordinator: NavigationStackCoordinator
|
||||
}
|
||||
|
||||
enum LoginScreenCoordinatorAction {
|
||||
@ -37,7 +35,6 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
private let oidcAuthenticationPresenter: OIDCAuthenticationPresenter
|
||||
private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService }
|
||||
private var navigationStackCoordinator: NavigationStackCoordinator { parameters.navigationStackCoordinator }
|
||||
|
||||
var callback: (@MainActor (LoginScreenCoordinatorAction) -> Void)?
|
||||
|
||||
@ -46,7 +43,7 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
|
||||
init(parameters: LoginScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
|
||||
viewModel = LoginScreenViewModel(homeserver: parameters.authenticationService.homeserver)
|
||||
viewModel = LoginScreenViewModel(homeserver: parameters.authenticationService.homeserver.value)
|
||||
|
||||
oidcAuthenticationPresenter = OIDCAuthenticationPresenter(authenticationService: parameters.authenticationService)
|
||||
}
|
||||
@ -58,8 +55,6 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .selectServer:
|
||||
self.presentServerSelectionScreen()
|
||||
case .parseUsername(let username):
|
||||
self.parseUsername(username)
|
||||
case .forgotPassword:
|
||||
@ -193,35 +188,10 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
/// Updates the view model with a different homeserver.
|
||||
private func updateViewModel() {
|
||||
viewModel.update(homeserver: authenticationService.homeserver)
|
||||
viewModel.update(homeserver: authenticationService.homeserver.value)
|
||||
indicateSuccess()
|
||||
}
|
||||
|
||||
/// Presents the server selection screen as a modal.
|
||||
private func presentServerSelectionScreen() {
|
||||
let parameters = ServerSelectionScreenCoordinatorParameters(authenticationService: authenticationService,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
isModallyPresented: false)
|
||||
|
||||
let coordinator = ServerSelectionScreenCoordinator(parameters: parameters)
|
||||
coordinator.callback = { [weak self, weak coordinator] action in
|
||||
guard let self, let coordinator else { return }
|
||||
self.serverSelectionCoordinator(coordinator, didCompleteWith: action)
|
||||
}
|
||||
|
||||
navigationStackCoordinator.push(coordinator)
|
||||
}
|
||||
|
||||
/// Handles the result from the server selection modal, dismissing it after updating the view.
|
||||
private func serverSelectionCoordinator(_ coordinator: ServerSelectionScreenCoordinator,
|
||||
didCompleteWith action: ServerSelectionScreenCoordinatorAction) {
|
||||
if action == .updated {
|
||||
updateViewModel()
|
||||
}
|
||||
|
||||
navigationStackCoordinator.pop()
|
||||
}
|
||||
|
||||
/// Shows the forgot password screen.
|
||||
private func showForgotPasswordScreen() {
|
||||
viewModel.displayError(.alert("Not implemented."))
|
||||
|
@ -17,8 +17,6 @@
|
||||
import Foundation
|
||||
|
||||
enum LoginScreenViewModelAction: CustomStringConvertible {
|
||||
/// The user would like to select another server.
|
||||
case selectServer
|
||||
/// Parse the username and update the homeserver if included.
|
||||
case parseUsername(String)
|
||||
/// The user would like to reset their password.
|
||||
@ -31,8 +29,6 @@ enum LoginScreenViewModelAction: CustomStringConvertible {
|
||||
/// A string representation of the action, ignoring any associated values that could leak PII.
|
||||
var description: String {
|
||||
switch self {
|
||||
case .selectServer:
|
||||
return "selectServer"
|
||||
case .parseUsername:
|
||||
return "parseUsername"
|
||||
case .forgotPassword:
|
||||
@ -77,8 +73,6 @@ struct LoginScreenBindings {
|
||||
}
|
||||
|
||||
enum LoginScreenViewAction {
|
||||
/// The user would like to select another server.
|
||||
case selectServer
|
||||
/// Parse the username to detect if a homeserver is included.
|
||||
case parseUsername
|
||||
/// The user would like to reset their password.
|
||||
|
@ -30,8 +30,6 @@ class LoginScreenViewModel: LoginScreenViewModelType, LoginScreenViewModelProtoc
|
||||
|
||||
override func process(viewAction: LoginScreenViewAction) {
|
||||
switch viewAction {
|
||||
case .selectServer:
|
||||
callback?(.selectServer)
|
||||
case .parseUsername:
|
||||
callback?(.parseUsername(state.bindings.username))
|
||||
case .forgotPassword:
|
||||
|
@ -31,9 +31,6 @@ struct LoginScreen: View {
|
||||
.padding(.top, UIConstants.titleTopPaddingToNavigationBar)
|
||||
.padding(.bottom, 32)
|
||||
|
||||
serverInfo
|
||||
.padding(.bottom, 32)
|
||||
|
||||
switch context.viewState.loginMode {
|
||||
case .password:
|
||||
loginForm
|
||||
@ -51,19 +48,18 @@ struct LoginScreen: View {
|
||||
.alert(item: $context.alertInfo) { $0.alert }
|
||||
}
|
||||
|
||||
/// The header containing a Welcome Back title.
|
||||
/// The header containing the title and icon.
|
||||
var header: some View {
|
||||
Text(L10n.screenLoginTitle)
|
||||
.font(.compound.headingLGBold)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
}
|
||||
VStack(spacing: 8) {
|
||||
AuthenticationIconImage(image: Image(systemName: "lock.fill"))
|
||||
.padding(.bottom, 8)
|
||||
|
||||
/// The sever information section that includes a button to select a different server.
|
||||
var serverInfo: some View {
|
||||
LoginServerInfoSection(address: context.viewState.homeserver.address) {
|
||||
context.send(viewAction: .selectServer)
|
||||
Text(L10n.screenLoginTitleWithHomeserver(context.viewState.homeserver.address))
|
||||
.font(.compound.headingMDBold)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
}
|
||||
|
||||
/// The form with text fields for username and password, along with a submit button.
|
||||
|
@ -1,65 +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 SwiftUI
|
||||
|
||||
/// A view that shows information about the chosen homeserver,
|
||||
/// along with an edit button to pick a different one.
|
||||
struct LoginServerInfoSection: View {
|
||||
// MARK: - Public
|
||||
|
||||
/// The address shown for the server.
|
||||
let address: String
|
||||
/// The action performed when tapping the edit button.
|
||||
let editAction: () -> Void
|
||||
|
||||
// MARK: - Views
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text(L10n.screenLoginServerHeader)
|
||||
.font(.compound.bodySM)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
.padding(.horizontal, 16)
|
||||
|
||||
Button(action: editAction) {
|
||||
HStack {
|
||||
Text(address)
|
||||
.font(.compound.bodyMDSemibold)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.vertical)
|
||||
|
||||
Spacer()
|
||||
|
||||
Image(systemName: "chevron.right")
|
||||
.font(.compound.bodyMD.bold())
|
||||
.foregroundColor(.element.tertiaryContent)
|
||||
.padding(.trailing, 16)
|
||||
}
|
||||
.background(RoundedRectangle(cornerRadius: 14).fill(Color.element.system))
|
||||
}
|
||||
.accessibilityIdentifier(A11yIdentifiers.loginScreen.changeServer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LoginServerInfoSection_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
LoginServerInfoSection(address: "matrix.org", editAction: { })
|
||||
.padding()
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
//
|
||||
// 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 ServerConfirmationScreenCoordinatorParameters {
|
||||
let authenticationService: AuthenticationServiceProxyProtocol
|
||||
let authenticationFlow: AuthenticationFlow
|
||||
}
|
||||
|
||||
enum ServerConfirmationScreenCoordinatorAction {
|
||||
case confirm
|
||||
case changeServer
|
||||
}
|
||||
|
||||
final class ServerConfirmationScreenCoordinator: CoordinatorProtocol {
|
||||
private let parameters: ServerConfirmationScreenCoordinatorParameters
|
||||
private var viewModel: ServerConfirmationScreenViewModelProtocol
|
||||
private let actionsSubject: PassthroughSubject<ServerConfirmationScreenCoordinatorAction, Never> = .init()
|
||||
private var cancellables: Set<AnyCancellable> = .init()
|
||||
|
||||
var actions: AnyPublisher<ServerConfirmationScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(parameters: ServerConfirmationScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
|
||||
viewModel = ServerConfirmationScreenViewModel(authenticationService: parameters.authenticationService,
|
||||
authenticationFlow: parameters.authenticationFlow)
|
||||
}
|
||||
|
||||
func start() {
|
||||
viewModel.actions.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .confirm:
|
||||
self.actionsSubject.send(.confirm)
|
||||
case .changeServer:
|
||||
self.actionsSubject.send(.changeServer)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func toPresentable() -> AnyView {
|
||||
AnyView(ServerConfirmationScreen(context: viewModel.context))
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
//
|
||||
// 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 ServerConfirmationScreenViewModelAction {
|
||||
/// The user would like to continue with the current homeserver.
|
||||
case confirm
|
||||
/// The user would like to change to a different homeserver.
|
||||
case changeServer
|
||||
}
|
||||
|
||||
struct ServerConfirmationScreenViewState: BindableState {
|
||||
/// The homeserver address input by the user.
|
||||
var homeserverAddress: String
|
||||
/// The flow being attempted on the selected homeserver.
|
||||
let authenticationFlow: AuthenticationFlow
|
||||
|
||||
/// The screen's title.
|
||||
var title: String {
|
||||
switch authenticationFlow {
|
||||
case .login:
|
||||
return L10n.screenServerConfirmationTitleLogin(homeserverAddress)
|
||||
case .register:
|
||||
return L10n.screenServerConfirmationTitleRegister(homeserverAddress)
|
||||
}
|
||||
}
|
||||
|
||||
/// The message shown beneath the title.
|
||||
var message: String {
|
||||
switch authenticationFlow {
|
||||
case .login:
|
||||
if homeserverAddress == "matrix.org" {
|
||||
return L10n.screenServerConfirmationMessageLoginMatrixDotOrg
|
||||
} else if homeserverAddress == "element.io" {
|
||||
return L10n.screenServerConfirmationMessageLoginElementDotIo
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
case .register:
|
||||
return L10n.screenServerConfirmationMessageRegister
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ServerConfirmationScreenViewAction {
|
||||
/// The user would like to continue with the current homeserver.
|
||||
case confirm
|
||||
/// The user would like to change to a different homeserver.
|
||||
case changeServer
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
//
|
||||
// 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 ServerConfirmationScreenViewModelType = StateStoreViewModel<ServerConfirmationScreenViewState, ServerConfirmationScreenViewAction>
|
||||
|
||||
class ServerConfirmationScreenViewModel: ServerConfirmationScreenViewModelType, ServerConfirmationScreenViewModelProtocol {
|
||||
private var actionsSubject: PassthroughSubject<ServerConfirmationScreenViewModelAction, Never> = .init()
|
||||
|
||||
var actions: AnyPublisher<ServerConfirmationScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(authenticationService: AuthenticationServiceProxyProtocol, authenticationFlow: AuthenticationFlow) {
|
||||
super.init(initialViewState: ServerConfirmationScreenViewState(homeserverAddress: authenticationService.homeserver.value.address,
|
||||
authenticationFlow: authenticationFlow))
|
||||
|
||||
authenticationService.homeserver
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] homeserver in
|
||||
guard let self else { return }
|
||||
state.homeserverAddress = homeserver.address
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
override func process(viewAction: ServerConfirmationScreenViewAction) {
|
||||
switch viewAction {
|
||||
case .confirm:
|
||||
actionsSubject.send(.confirm)
|
||||
case .changeServer:
|
||||
actionsSubject.send(.changeServer)
|
||||
}
|
||||
}
|
||||
}
|
@ -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 ServerConfirmationScreenViewModelProtocol {
|
||||
var actions: AnyPublisher<ServerConfirmationScreenViewModelAction, Never> { get }
|
||||
var context: ServerConfirmationScreenViewModelType.Context { get }
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
//
|
||||
// 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 SwiftUI
|
||||
|
||||
struct ServerConfirmationScreen: View {
|
||||
@ObservedObject var context: ServerConfirmationScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
header
|
||||
.padding(.top, UIConstants.iconTopPaddingToNavigationBar)
|
||||
.padding(.horizontal, 16)
|
||||
.readableFrame()
|
||||
}
|
||||
.background(Color.element.background.ignoresSafeArea())
|
||||
.safeAreaInset(edge: .bottom) {
|
||||
buttons
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.vertical, 16)
|
||||
.readableFrame()
|
||||
.background(Color.element.background.ignoresSafeArea())
|
||||
}
|
||||
}
|
||||
|
||||
/// The main content of the view to be shown in a scroll view.
|
||||
var header: some View {
|
||||
VStack(spacing: 8) {
|
||||
AuthenticationIconImage(image: Image(systemName: "person.crop.circle.fill"))
|
||||
.padding(.bottom, 8)
|
||||
|
||||
Text(context.viewState.title)
|
||||
.font(.compound.headingMDBold)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
|
||||
Text(context.viewState.message)
|
||||
.font(.compound.bodyMD)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.element.tertiaryContent)
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
}
|
||||
|
||||
/// The action buttons shown at the bottom of the view.
|
||||
var buttons: some View {
|
||||
VStack(spacing: 24) {
|
||||
Button { context.send(viewAction: .confirm) } label: {
|
||||
Text(L10n.actionContinue)
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
.accessibilityIdentifier(A11yIdentifiers.serverConfirmationScreen.continue)
|
||||
|
||||
Button { context.send(viewAction: .changeServer) } label: {
|
||||
Text(L10n.screenServerConfirmationChangeServer)
|
||||
.font(.compound.bodyLGSemibold)
|
||||
.padding(.vertical, 14)
|
||||
}
|
||||
.accessibilityIdentifier(A11yIdentifiers.serverConfirmationScreen.changeServer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct ServerConfirmationScreen_Previews: PreviewProvider {
|
||||
static let loginViewModel = ServerConfirmationScreenViewModel(authenticationService: MockAuthenticationServiceProxy(),
|
||||
authenticationFlow: .login)
|
||||
static let registerViewModel = ServerConfirmationScreenViewModel(authenticationService: MockAuthenticationServiceProxy(),
|
||||
authenticationFlow: .register)
|
||||
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
ServerConfirmationScreen(context: loginViewModel.context)
|
||||
.toolbar(.visible, for: .navigationBar)
|
||||
}
|
||||
.previewDisplayName("Login")
|
||||
|
||||
NavigationStack {
|
||||
ServerConfirmationScreen(context: registerViewModel.context)
|
||||
.toolbar(.visible, for: .navigationBar)
|
||||
}
|
||||
.previewDisplayName("Register")
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ final class ServerSelectionScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
init(parameters: ServerSelectionScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
viewModel = ServerSelectionScreenViewModel(homeserverAddress: parameters.authenticationService.homeserver.address,
|
||||
viewModel = ServerSelectionScreenViewModel(homeserverAddress: parameters.authenticationService.homeserver.value.address,
|
||||
isModallyPresented: parameters.isModallyPresented)
|
||||
userIndicatorController = parameters.userIndicatorController
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ final class SoftLogoutScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
let homeserver = parameters.authenticationService.homeserver
|
||||
viewModel = SoftLogoutScreenViewModel(credentials: parameters.credentials,
|
||||
homeserver: homeserver,
|
||||
homeserver: homeserver.value,
|
||||
keyBackupNeeded: parameters.keyBackupNeeded)
|
||||
|
||||
oidcAuthenticationPresenter = OIDCAuthenticationPresenter(authenticationService: parameters.authenticationService)
|
||||
|
@ -87,7 +87,7 @@ struct SoftLogoutScreen: View {
|
||||
.accessibilityIdentifier(A11yIdentifiers.softLogoutScreen.password)
|
||||
|
||||
Button { context.send(viewAction: .forgotPassword) } label: {
|
||||
Text(UntranslatedL10n.softLogoutForgotPassword)
|
||||
Text(L10n.actionForgotPassword)
|
||||
.font(.compound.bodyLG)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
|
@ -14,6 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
@ -21,7 +22,9 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
|
||||
private let authenticationService: AuthenticationService
|
||||
private let userSessionStore: UserSessionStoreProtocol
|
||||
|
||||
private(set) var homeserver = LoginHomeserver(address: ServiceLocator.shared.settings.defaultHomeserverAddress, loginMode: .unknown)
|
||||
private let homeserverSubject: CurrentValueSubject<LoginHomeserver, Never> = .init(LoginHomeserver(address: ServiceLocator.shared.settings.defaultHomeserverAddress,
|
||||
loginMode: .unknown))
|
||||
var homeserver: CurrentValuePublisher<LoginHomeserver, Never> { homeserverSubject.asCurrentValuePublisher() }
|
||||
|
||||
init(userSessionStore: UserSessionStoreProtocol) {
|
||||
self.userSessionStore = userSessionStore
|
||||
@ -60,7 +63,7 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
self.homeserver = homeserver
|
||||
homeserverSubject.send(homeserver)
|
||||
return .success(())
|
||||
} catch AuthenticationError.SlidingSyncNotAvailable {
|
||||
MXLog.info("User entered a homeserver that isn't configured for sliding sync.")
|
||||
|
@ -17,6 +17,14 @@
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
/// Represents a particular authentication flow.
|
||||
enum AuthenticationFlow {
|
||||
/// The flow for signing in to an existing account.
|
||||
case login
|
||||
/// The flow for creating a new account.
|
||||
case register
|
||||
}
|
||||
|
||||
enum AuthenticationServiceError: Error {
|
||||
/// An error occurred during OIDC authentication.
|
||||
case oidcError(OIDCError)
|
||||
@ -29,7 +37,8 @@ enum AuthenticationServiceError: Error {
|
||||
}
|
||||
|
||||
protocol AuthenticationServiceProxyProtocol {
|
||||
var homeserver: LoginHomeserver { get }
|
||||
/// The currently configured homeserver.
|
||||
var homeserver: CurrentValuePublisher<LoginHomeserver, Never> { get }
|
||||
|
||||
/// Sets up the service for login on the specified homeserver address.
|
||||
func configure(for homeserverAddress: String) async -> Result<Void, AuthenticationServiceError>
|
||||
|
@ -14,27 +14,33 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
class MockAuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
|
||||
let validCredentials = (username: "alice", password: "12345678")
|
||||
|
||||
private(set) var homeserver: LoginHomeserver = .mockMatrixDotOrg
|
||||
private let homeserverSubject: CurrentValueSubject<LoginHomeserver, Never>
|
||||
var homeserver: CurrentValuePublisher<LoginHomeserver, Never> { homeserverSubject.asCurrentValuePublisher() }
|
||||
|
||||
init(homeserver: LoginHomeserver = .mockMatrixDotOrg) {
|
||||
homeserverSubject = .init(homeserver)
|
||||
}
|
||||
|
||||
func configure(for homeserverAddress: String) async -> Result<Void, AuthenticationServiceError> {
|
||||
// Map the address to the mock homeservers
|
||||
if LoginHomeserver.mockMatrixDotOrg.address.contains(homeserverAddress) {
|
||||
homeserver = .mockMatrixDotOrg
|
||||
homeserverSubject.send(.mockMatrixDotOrg)
|
||||
return .success(())
|
||||
} else if LoginHomeserver.mockOIDC.address.contains(homeserverAddress) {
|
||||
homeserver = .mockOIDC
|
||||
homeserverSubject.send(.mockOIDC)
|
||||
return .success(())
|
||||
} else if LoginHomeserver.mockBasicServer.address.contains(homeserverAddress) {
|
||||
homeserver = .mockBasicServer
|
||||
homeserverSubject.send(.mockBasicServer)
|
||||
return .success(())
|
||||
} else if LoginHomeserver.mockUnsupported.address.contains(homeserverAddress) {
|
||||
homeserver = .mockUnsupported
|
||||
homeserverSubject.send(.mockUnsupported)
|
||||
return .success(())
|
||||
} else {
|
||||
// Otherwise fail with an invalid server.
|
||||
|
@ -75,8 +75,19 @@ class MockScreen: Identifiable {
|
||||
switch id {
|
||||
case .login:
|
||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||
let coordinator = LoginScreenCoordinator(parameters: .init(authenticationService: MockAuthenticationServiceProxy(),
|
||||
navigationStackCoordinator: navigationStackCoordinator))
|
||||
let coordinator = LoginScreenCoordinator(parameters: .init(authenticationService: MockAuthenticationServiceProxy()))
|
||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||
return navigationStackCoordinator
|
||||
case .serverConfirmationLogin:
|
||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||
let coordinator = ServerConfirmationScreenCoordinator(parameters: .init(authenticationService: MockAuthenticationServiceProxy(homeserver: .mockMatrixDotOrg),
|
||||
authenticationFlow: .login))
|
||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||
return navigationStackCoordinator
|
||||
case .serverConfirmationRegister:
|
||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||
let coordinator = ServerConfirmationScreenCoordinator(parameters: .init(authenticationService: MockAuthenticationServiceProxy(homeserver: .mockOIDC),
|
||||
authenticationFlow: .register))
|
||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||
return navigationStackCoordinator
|
||||
case .serverSelection:
|
||||
|
@ -18,6 +18,8 @@ import Foundation
|
||||
|
||||
enum UITestsScreenIdentifier: String {
|
||||
case login
|
||||
case serverConfirmationLogin
|
||||
case serverConfirmationRegister
|
||||
case serverSelection
|
||||
case serverSelectionNonModal
|
||||
case authenticationFlow
|
||||
|
@ -43,9 +43,9 @@ class LoginTests: XCTestCase {
|
||||
XCTAssertTrue(getStartedButton.waitForExistence(timeout: 10.0))
|
||||
getStartedButton.tap()
|
||||
|
||||
let editHomeserverButton = app.buttons[A11yIdentifiers.loginScreen.changeServer]
|
||||
XCTAssertTrue(editHomeserverButton.waitForExistence(timeout: 10.0))
|
||||
editHomeserverButton.tap()
|
||||
let changeHomeserverButton = app.buttons[A11yIdentifiers.serverConfirmationScreen.changeServer]
|
||||
XCTAssertTrue(changeHomeserverButton.waitForExistence(timeout: 10.0))
|
||||
changeHomeserverButton.tap()
|
||||
|
||||
let homeserverTextField = app.textFields[A11yIdentifiers.changeServerScreen.server]
|
||||
XCTAssertTrue(homeserverTextField.waitForExistence(timeout: 10.0))
|
||||
@ -56,6 +56,10 @@ class LoginTests: XCTestCase {
|
||||
XCTAssertTrue(confirmButton.waitForExistence(timeout: 10.0))
|
||||
confirmButton.tap()
|
||||
|
||||
let continueButton = app.buttons[A11yIdentifiers.serverConfirmationScreen.continue]
|
||||
XCTAssertTrue(continueButton.waitForExistence(timeout: 10.0))
|
||||
continueButton.tap()
|
||||
|
||||
let usernameTextField = app.textFields[A11yIdentifiers.loginScreen.emailUsername]
|
||||
XCTAssertTrue(usernameTextField.waitForExistence(timeout: 10.0))
|
||||
|
||||
|
@ -27,8 +27,13 @@ class AuthenticationCoordinatorUITests: XCTestCase {
|
||||
// Splash Screen: Tap get started button
|
||||
app.buttons[A11yIdentifiers.onboardingScreen.signIn].tap()
|
||||
|
||||
// Login Screen: Enter valid credentials
|
||||
// Server Confirmation: Tap continue button
|
||||
app.buttons[A11yIdentifiers.serverConfirmationScreen.continue].tap()
|
||||
|
||||
// Login Screen: Confirm password login is available and not OIDC.
|
||||
XCTAssertFalse(app.buttons[A11yIdentifiers.loginScreen.oidc].exists, "The OIDC button shouldn't be shown before entering a supported homeserver.")
|
||||
|
||||
// Login Screen: Enter valid credentials
|
||||
app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("alice\n")
|
||||
app.secureTextFields[A11yIdentifiers.loginScreen.password].clearAndTypeText("12345678")
|
||||
|
||||
@ -47,6 +52,9 @@ class AuthenticationCoordinatorUITests: XCTestCase {
|
||||
// Splash Screen: Tap get started button
|
||||
app.buttons[A11yIdentifiers.onboardingScreen.signIn].tap()
|
||||
|
||||
// Server Confirmation: Tap continue button
|
||||
app.buttons[A11yIdentifiers.serverConfirmationScreen.continue].tap()
|
||||
|
||||
// Login Screen: Enter invalid credentials
|
||||
app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("alice")
|
||||
app.secureTextFields[A11yIdentifiers.loginScreen.password].clearAndTypeText("87654321")
|
||||
@ -68,16 +76,16 @@ class AuthenticationCoordinatorUITests: XCTestCase {
|
||||
// Splash Screen: Tap get started button
|
||||
app.buttons[A11yIdentifiers.onboardingScreen.signIn].tap()
|
||||
|
||||
// Login Screen: Tap edit server button.
|
||||
XCTAssertFalse(app.buttons[A11yIdentifiers.loginScreen.oidc].exists, "The OIDC button shouldn't be shown before entering a supported homeserver.")
|
||||
app.buttons[A11yIdentifiers.loginScreen.changeServer].tap()
|
||||
// Server Confirmation: Tap change server button
|
||||
app.buttons[A11yIdentifiers.serverConfirmationScreen.changeServer].tap()
|
||||
|
||||
// Server Selection: Clear the default and enter OIDC server.
|
||||
// Server Selection: Clear the default, enter OIDC server and continue.
|
||||
app.textFields[A11yIdentifiers.changeServerScreen.server].clearAndTypeText("company.com")
|
||||
|
||||
// Dismiss server screen.
|
||||
app.buttons[A11yIdentifiers.changeServerScreen.continue].tap()
|
||||
|
||||
// Server Confirmation: Tap continue button
|
||||
app.buttons[A11yIdentifiers.serverConfirmationScreen.continue].tap()
|
||||
|
||||
// Then the login form should be updated for OIDC.
|
||||
XCTAssertTrue(app.buttons[A11yIdentifiers.loginScreen.oidc].waitForExistence(timeout: 1), "The OIDC button should be shown after selecting a homeserver with OIDC.")
|
||||
}
|
||||
|
31
UITests/Sources/ServerConfirmationScreenUITests.swift
Normal file
31
UITests/Sources/ServerConfirmationScreenUITests.swift
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// 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 ElementX
|
||||
import XCTest
|
||||
|
||||
@MainActor
|
||||
class ServerConfirmationScreenUITests: XCTestCase {
|
||||
func testLoginScreen() async throws {
|
||||
let app = Application.launch(.serverConfirmationLogin)
|
||||
try await app.assertScreenshot(.serverConfirmationLogin)
|
||||
}
|
||||
|
||||
func testRegisterScreen() async throws {
|
||||
let app = Application.launch(.serverConfirmationRegister)
|
||||
try await app.assertScreenshot(.serverConfirmationRegister)
|
||||
}
|
||||
}
|
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.authenticationFlow.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.authenticationFlow.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.login-0.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.login-0.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.login-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.login-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.login-2.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.login-2.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.login.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.login.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.serverConfirmationLogin.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.serverConfirmationLogin.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.serverConfirmationRegister.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.serverConfirmationRegister.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.authenticationFlow.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.authenticationFlow.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.login-0.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.login-0.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.login-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.login-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.login-2.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.login-2.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.login.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.login.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.serverConfirmationLogin.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.serverConfirmationLogin.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.serverConfirmationRegister.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.serverConfirmationRegister.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.authenticationFlow.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.authenticationFlow.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.login-0.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.login-0.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.login-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.login-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.login-2.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.login-2.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.login.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.login.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.serverConfirmationLogin.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.serverConfirmationLogin.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.serverConfirmationRegister.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.serverConfirmationRegister.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.authenticationFlow.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.authenticationFlow.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.login-0.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.login-0.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.login-1.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.login-1.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.login-2.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.login-2.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.login.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.login.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.serverConfirmationLogin.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.serverConfirmationLogin.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.serverConfirmationRegister.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.serverConfirmationRegister.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,45 @@
|
||||
//
|
||||
// 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 XCTest
|
||||
|
||||
@testable import ElementX
|
||||
|
||||
class ServerConfirmationScreenViewStateTests: XCTestCase {
|
||||
func testLoginMessageString() {
|
||||
let matrixDotOrgLogin = ServerConfirmationScreenViewState(homeserverAddress: LoginHomeserver.mockMatrixDotOrg.address,
|
||||
authenticationFlow: .login)
|
||||
XCTAssertEqual(matrixDotOrgLogin.message, L10n.screenServerConfirmationMessageLoginMatrixDotOrg, "matrix.org should have a custom message.")
|
||||
|
||||
let elementDotIoLogin = ServerConfirmationScreenViewState(homeserverAddress: "element.io",
|
||||
authenticationFlow: .login)
|
||||
XCTAssertEqual(elementDotIoLogin.message, L10n.screenServerConfirmationMessageLoginElementDotIo, "element.io should have a custom message.")
|
||||
|
||||
let otherLogin = ServerConfirmationScreenViewState(homeserverAddress: LoginHomeserver.mockOIDC.address,
|
||||
authenticationFlow: .login)
|
||||
XCTAssertTrue(otherLogin.message.isEmpty, "Other servers should not show a message.")
|
||||
}
|
||||
|
||||
func testRegisterMessageString() {
|
||||
let matrixDotOrgLogin = ServerConfirmationScreenViewState(homeserverAddress: LoginHomeserver.mockMatrixDotOrg.address,
|
||||
authenticationFlow: .register)
|
||||
XCTAssertEqual(matrixDotOrgLogin.message, L10n.screenServerConfirmationMessageRegister, "The registration message should always be the same.")
|
||||
|
||||
let otherLogin = ServerConfirmationScreenViewState(homeserverAddress: LoginHomeserver.mockOIDC.address,
|
||||
authenticationFlow: .register)
|
||||
XCTAssertEqual(otherLogin.message, L10n.screenServerConfirmationMessageRegister, "The registration message should always be the same.")
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
//
|
||||
// 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 ServerConfirmationScreenViewModelTests: XCTestCase {
|
||||
// Nothing to test, the view model has no mutable state.
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user