mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-06 04:18:31 +00:00
vector-im/element-x-ios/issues/31 - Implement simple SaS sesson verification
* vector-im/element-x-ios/issues/31 - Session verification unit and UI tests * Fix ImageAnonymizer tests when running on Apple Silicon * Rename SessionVerification to SessionVerificationScreen
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 52;
|
objectVersion = 51;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
@@ -18,11 +18,13 @@
|
|||||||
04A16B45228F7678A027C079 /* RoomHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 422724361B6555364C43281E /* RoomHeaderView.swift */; };
|
04A16B45228F7678A027C079 /* RoomHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 422724361B6555364C43281E /* RoomHeaderView.swift */; };
|
||||||
05776B005C57E92582F0CF08 /* BuildSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F87116470221880017CF522 /* BuildSettings.swift */; };
|
05776B005C57E92582F0CF08 /* BuildSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F87116470221880017CF522 /* BuildSettings.swift */; };
|
||||||
059173B3C77056C406906B6D /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = D4DA544B2520BFA65D6DB4BB /* target.yml */; };
|
059173B3C77056C406906B6D /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = D4DA544B2520BFA65D6DB4BB /* target.yml */; };
|
||||||
|
05EC896A4B9AF4A56670C0BB /* SessionVerificationUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D4777F0142E330A75C46FE4 /* SessionVerificationUITests.swift */; };
|
||||||
0602FA07557F580086782A9E /* UserIndicatorPresentationContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FA072E995316CD18BC29313 /* UserIndicatorPresentationContext.swift */; };
|
0602FA07557F580086782A9E /* UserIndicatorPresentationContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FA072E995316CD18BC29313 /* UserIndicatorPresentationContext.swift */; };
|
||||||
066A1E9B94723EE9F3038044 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47EBB5D698CE9A25BB553A2D /* Strings.swift */; };
|
066A1E9B94723EE9F3038044 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47EBB5D698CE9A25BB553A2D /* Strings.swift */; };
|
||||||
06E93B2E3B32740B40F47CC5 /* ElementNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF4B39D52CAE7D21D276ABEE /* ElementNavigationController.swift */; };
|
06E93B2E3B32740B40F47CC5 /* ElementNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF4B39D52CAE7D21D276ABEE /* ElementNavigationController.swift */; };
|
||||||
072BA9DBA932374CCA300125 /* MessageComposerTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE6C10032A77AE7DC5AA4C50 /* MessageComposerTextField.swift */; };
|
072BA9DBA932374CCA300125 /* MessageComposerTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE6C10032A77AE7DC5AA4C50 /* MessageComposerTextField.swift */; };
|
||||||
0B1F80C2BF7D223159FBA82C /* ImageAnonymizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6045E825AE900A92D61FEFF0 /* ImageAnonymizerTests.swift */; };
|
0B1F80C2BF7D223159FBA82C /* ImageAnonymizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6045E825AE900A92D61FEFF0 /* ImageAnonymizerTests.swift */; };
|
||||||
|
0C38C3E771B472E27295339D /* SessionVerificationModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4BB9A17AC512A7EF4B106E5 /* SessionVerificationModels.swift */; };
|
||||||
0E8C480700870BB34A2A360F /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 78A5A8DE1E2B09C978C7F3B0 /* KeychainAccess */; };
|
0E8C480700870BB34A2A360F /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 78A5A8DE1E2B09C978C7F3B0 /* KeychainAccess */; };
|
||||||
0EA6537A07E2DC882AEA5962 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 187853A7E643995EE49FAD43 /* Localizable.stringsdict */; };
|
0EA6537A07E2DC882AEA5962 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 187853A7E643995EE49FAD43 /* Localizable.stringsdict */; };
|
||||||
0ED951768EC443A8728DE1D7 /* TimelineStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */; };
|
0ED951768EC443A8728DE1D7 /* TimelineStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */; };
|
||||||
@@ -35,6 +37,7 @@
|
|||||||
132D241B09F9044711FD70A5 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 91DE43B8815918E590912DDA /* InfoPlist.strings */; };
|
132D241B09F9044711FD70A5 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 91DE43B8815918E590912DDA /* InfoPlist.strings */; };
|
||||||
13C77FDF17C4C6627CFFC205 /* RoomTimelineItemFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D25A35764C7B3DB78954AB5 /* RoomTimelineItemFactoryProtocol.swift */; };
|
13C77FDF17C4C6627CFFC205 /* RoomTimelineItemFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D25A35764C7B3DB78954AB5 /* RoomTimelineItemFactoryProtocol.swift */; };
|
||||||
149D1942DC005D0485FB8D93 /* LoggingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC1943ADE6A62ED5129D7C8 /* LoggingTests.swift */; };
|
149D1942DC005D0485FB8D93 /* LoggingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC1943ADE6A62ED5129D7C8 /* LoggingTests.swift */; };
|
||||||
|
1555A7643D85187D4851040C /* TemplateScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4549FCB53F43DB0B278374BC /* TemplateScreen.swift */; };
|
||||||
157E5FDDF419C0B2CA7E2C28 /* TimelineItemBubbledStylerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A2932515EA11D3DD8A3506 /* TimelineItemBubbledStylerView.swift */; };
|
157E5FDDF419C0B2CA7E2C28 /* TimelineItemBubbledStylerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A2932515EA11D3DD8A3506 /* TimelineItemBubbledStylerView.swift */; };
|
||||||
15D1F9C415D9C921643BA82E /* UserIndicatorRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B73D5E21F524A9BE44448D /* UserIndicatorRequest.swift */; };
|
15D1F9C415D9C921643BA82E /* UserIndicatorRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B73D5E21F524A9BE44448D /* UserIndicatorRequest.swift */; };
|
||||||
172E6E9A612ADCF10A62CF13 /* BugReportServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A68BCE6438873D2661D93D0 /* BugReportServiceProtocol.swift */; };
|
172E6E9A612ADCF10A62CF13 /* BugReportServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A68BCE6438873D2661D93D0 /* BugReportServiceProtocol.swift */; };
|
||||||
@@ -52,6 +55,7 @@
|
|||||||
224A55EEAEECF5336B14A4A5 /* EmoteRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE2DF459F1737A594667CC46 /* EmoteRoomMessage.swift */; };
|
224A55EEAEECF5336B14A4A5 /* EmoteRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE2DF459F1737A594667CC46 /* EmoteRoomMessage.swift */; };
|
||||||
226027BE23AF64FA61C7A4C0 /* TimelineStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */; };
|
226027BE23AF64FA61C7A4C0 /* TimelineStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */; };
|
||||||
22DADD537401E79D66132134 /* NavigationRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4173A48FD8542CD4AD3645C /* NavigationRouter.swift */; };
|
22DADD537401E79D66132134 /* NavigationRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4173A48FD8542CD4AD3645C /* NavigationRouter.swift */; };
|
||||||
|
237FC70AA257B935F53316BA /* SessionVerificationControllerProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D7E514F9DE4E3D72FDCAD /* SessionVerificationControllerProxy.swift */; };
|
||||||
24906A1E82D0046655958536 /* MessageComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E18CF12478983A5EB390FB26 /* MessageComposer.swift */; };
|
24906A1E82D0046655958536 /* MessageComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E18CF12478983A5EB390FB26 /* MessageComposer.swift */; };
|
||||||
24BDDD09A90B8BFE3793F3AA /* ClientProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6033779EB37259F27F938937 /* ClientProxyProtocol.swift */; };
|
24BDDD09A90B8BFE3793F3AA /* ClientProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6033779EB37259F27F938937 /* ClientProxyProtocol.swift */; };
|
||||||
2797C9D9BA642370F1C85D78 /* Untranslated.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = F75DF9500D69A3AAF8339E69 /* Untranslated.stringsdict */; };
|
2797C9D9BA642370F1C85D78 /* Untranslated.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = F75DF9500D69A3AAF8339E69 /* Untranslated.stringsdict */; };
|
||||||
@@ -63,7 +67,6 @@
|
|||||||
2BAA5B222856068158D0B3C6 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = B1E8B697DF78FE7F61FC6CA4 /* MatrixRustSDK */; };
|
2BAA5B222856068158D0B3C6 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = B1E8B697DF78FE7F61FC6CA4 /* MatrixRustSDK */; };
|
||||||
2C0CE61E5DC177938618E0B1 /* RootRouterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90733775209F4D4D366A268F /* RootRouterType.swift */; };
|
2C0CE61E5DC177938618E0B1 /* RootRouterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90733775209F4D4D366A268F /* RootRouterType.swift */; };
|
||||||
2E59008365E01F0AFB3A6B24 /* ImageRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BF686BA36D0C2FA3C63DFDF /* ImageRoomMessage.swift */; };
|
2E59008365E01F0AFB3A6B24 /* ImageRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BF686BA36D0C2FA3C63DFDF /* ImageRoomMessage.swift */; };
|
||||||
2E68C57E7D644E94778743D5 /* TemplateScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B66E05B6009B0EB1BDBFA6E /* TemplateScreenUITests.swift */; };
|
|
||||||
2F1CF90A3460C153154427F0 /* RoomScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086B997409328F091EBA43CE /* RoomScreenUITests.swift */; };
|
2F1CF90A3460C153154427F0 /* RoomScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086B997409328F091EBA43CE /* RoomScreenUITests.swift */; };
|
||||||
2F30EFEB7BD39242D1AD96F3 /* LoginViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E1FB768A24FDD2A5CA16E3C /* LoginViewModelProtocol.swift */; };
|
2F30EFEB7BD39242D1AD96F3 /* LoginViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E1FB768A24FDD2A5CA16E3C /* LoginViewModelProtocol.swift */; };
|
||||||
2F94054F50E312AF30BE07F3 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B21E611DADDEF00307E7AC /* String.swift */; };
|
2F94054F50E312AF30BE07F3 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B21E611DADDEF00307E7AC /* String.swift */; };
|
||||||
@@ -78,7 +81,6 @@
|
|||||||
35E975CFDA60E05362A7CF79 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 1222DB76B917EB8A55365BA5 /* target.yml */; };
|
35E975CFDA60E05362A7CF79 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 1222DB76B917EB8A55365BA5 /* target.yml */; };
|
||||||
368C8758FCD079E6AAA18C2C /* NoticeRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */; };
|
368C8758FCD079E6AAA18C2C /* NoticeRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */; };
|
||||||
36AC963F2F04069B7FF1AA0C /* UIConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6D88E8AFFBF2C1D589C0FA /* UIConstants.swift */; };
|
36AC963F2F04069B7FF1AA0C /* UIConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6D88E8AFFBF2C1D589C0FA /* UIConstants.swift */; };
|
||||||
3772354754450F2B54107E17 /* TemplateViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF4EDB32B97910AAAFE632B2 /* TemplateViewModelProtocol.swift */; };
|
|
||||||
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA1D2CBAEA5D0BD00B90D1B /* BindableState.swift */; };
|
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA1D2CBAEA5D0BD00B90D1B /* BindableState.swift */; };
|
||||||
388FD50AC66E9E684DDFA9D8 /* ServerSelectionScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5D2C0950F8196232D88045C /* ServerSelectionScreen.swift */; };
|
388FD50AC66E9E684DDFA9D8 /* ServerSelectionScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5D2C0950F8196232D88045C /* ServerSelectionScreen.swift */; };
|
||||||
38C76D586404C1FDED095F3A /* LoginModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B01468022EC826CB2FD2C0 /* LoginModels.swift */; };
|
38C76D586404C1FDED095F3A /* LoginModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B01468022EC826CB2FD2C0 /* LoginModels.swift */; };
|
||||||
@@ -90,6 +92,7 @@
|
|||||||
418B4AEFD03DC7A6D2C9D5C8 /* EventBriefFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36322DD0D4E29D31B0945ADC /* EventBriefFactory.swift */; };
|
418B4AEFD03DC7A6D2C9D5C8 /* EventBriefFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36322DD0D4E29D31B0945ADC /* EventBriefFactory.swift */; };
|
||||||
41DFDD212D1BE57CA50D783B /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 7731767AE437BA3BD2CC14A8 /* Sentry */; };
|
41DFDD212D1BE57CA50D783B /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 7731767AE437BA3BD2CC14A8 /* Sentry */; };
|
||||||
438FB9BC535BC95948AA5F34 /* SettingsViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B2F9D5C39A4494D19F33E38 /* SettingsViewModelProtocol.swift */; };
|
438FB9BC535BC95948AA5F34 /* SettingsViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B2F9D5C39A4494D19F33E38 /* SettingsViewModelProtocol.swift */; };
|
||||||
|
43FD77998F33C32718C51450 /* TemplateCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBD460ED7ED1E03B85DEA25C /* TemplateCoordinator.swift */; };
|
||||||
462813B93C39DF93B1249403 /* RoundedToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFABDF2E19D349DAAAC18C65 /* RoundedToastView.swift */; };
|
462813B93C39DF93B1249403 /* RoundedToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFABDF2E19D349DAAAC18C65 /* RoundedToastView.swift */; };
|
||||||
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */; };
|
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */; };
|
||||||
4669804D0369FBED4E8625D1 /* ToastViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4470B8CB654B097D807AA713 /* ToastViewPresenter.swift */; };
|
4669804D0369FBED4E8625D1 /* ToastViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4470B8CB654B097D807AA713 /* ToastViewPresenter.swift */; };
|
||||||
@@ -116,13 +119,14 @@
|
|||||||
59C41313AED7566C3AC51163 /* RoomSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A953B6C0C431DBF4DD00B4 /* RoomSummary.swift */; };
|
59C41313AED7566C3AC51163 /* RoomSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A953B6C0C431DBF4DD00B4 /* RoomSummary.swift */; };
|
||||||
5B2C4C17888FC095ED6880B2 /* SplashViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 48971F1FFD7FC5C466889FC7 /* SplashViewController.xib */; };
|
5B2C4C17888FC095ED6880B2 /* SplashViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 48971F1FFD7FC5C466889FC7 /* SplashViewController.xib */; };
|
||||||
5C8AFBF168A41E20835F3B86 /* LoginScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB34B0C74CD242FED9DD069 /* LoginScreenUITests.swift */; };
|
5C8AFBF168A41E20835F3B86 /* LoginScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB34B0C74CD242FED9DD069 /* LoginScreenUITests.swift */; };
|
||||||
5CABC57F620FBB39F4EC127C /* TemplateScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9BA045DC4CA12D030ACF558 /* TemplateScreen.swift */; };
|
|
||||||
5D430CDE11EAC3E8E6B80A66 /* RoomTimelineViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FEE631F3A4AFDC6652DD9DA /* RoomTimelineViewFactory.swift */; };
|
5D430CDE11EAC3E8E6B80A66 /* RoomTimelineViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FEE631F3A4AFDC6652DD9DA /* RoomTimelineViewFactory.swift */; };
|
||||||
5E0F2E612718BB4397A6D40A /* TextRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9E785D5137510481733A3E8 /* TextRoomTimelineView.swift */; };
|
5E0F2E612718BB4397A6D40A /* TextRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9E785D5137510481733A3E8 /* TextRoomTimelineView.swift */; };
|
||||||
5E1FCC43B738941D5A5F1794 /* SplashScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B73A8C3118EAC7BF3F3EE7A /* SplashScreenViewModelProtocol.swift */; };
|
5E1FCC43B738941D5A5F1794 /* SplashScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B73A8C3118EAC7BF3F3EE7A /* SplashScreenViewModelProtocol.swift */; };
|
||||||
|
5F1FDE49DFD0C680386E48F9 /* TemplateViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B80895CE021B49847BD7D74 /* TemplateViewModelProtocol.swift */; };
|
||||||
5F5488FBC9CFEB6F433D74A4 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7109E709A7738E6BCC4553E6 /* Localizable.strings */; };
|
5F5488FBC9CFEB6F433D74A4 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7109E709A7738E6BCC4553E6 /* Localizable.strings */; };
|
||||||
617624A97BDBB75ED3DD8156 /* RoomScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */; };
|
617624A97BDBB75ED3DD8156 /* RoomScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */; };
|
||||||
62BBF5BE7B905222F0477FF2 /* MediaSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8210612D17A39369480FC183 /* MediaSource.swift */; };
|
62BBF5BE7B905222F0477FF2 /* MediaSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8210612D17A39369480FC183 /* MediaSource.swift */; };
|
||||||
|
63C9AF0FB8278AF1C0388A0C /* TemplateModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAB10E673916D2B8D21FD197 /* TemplateModels.swift */; };
|
||||||
6647430A45B4A8E692909A8F /* EmoteRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77C060C2ACC4CB7336A29E7 /* EmoteRoomTimelineItem.swift */; };
|
6647430A45B4A8E692909A8F /* EmoteRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77C060C2ACC4CB7336A29E7 /* EmoteRoomTimelineItem.swift */; };
|
||||||
67E391A2E00709FB41903B36 /* MockMediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6920A4869821BF72FFC58842 /* MockMediaProvider.swift */; };
|
67E391A2E00709FB41903B36 /* MockMediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6920A4869821BF72FFC58842 /* MockMediaProvider.swift */; };
|
||||||
6832733838C57A7D3FE8FEB5 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 04C28663564E008DB32B5972 /* Introspect */; };
|
6832733838C57A7D3FE8FEB5 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 04C28663564E008DB32B5972 /* Introspect */; };
|
||||||
@@ -140,8 +144,10 @@
|
|||||||
72F6E890820FF606A7E276C8 /* SplashScreenPageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A534A4619D8FEFB6439FCC /* SplashScreenPageView.swift */; };
|
72F6E890820FF606A7E276C8 /* SplashScreenPageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A534A4619D8FEFB6439FCC /* SplashScreenPageView.swift */; };
|
||||||
7405B4824D45BA7C3D943E76 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D0CBC76C80E04345E11F2DB /* Application.swift */; };
|
7405B4824D45BA7C3D943E76 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D0CBC76C80E04345E11F2DB /* Application.swift */; };
|
||||||
74604ACFDBE7F54260E7B617 /* ApplicationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8903A9F615BBD0E6D7CD133 /* ApplicationProtocol.swift */; };
|
74604ACFDBE7F54260E7B617 /* ApplicationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8903A9F615BBD0E6D7CD133 /* ApplicationProtocol.swift */; };
|
||||||
|
755727E0B756430DFFEC4732 /* SessionVerificationViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF05DA24F71B455E8EFEBC3B /* SessionVerificationViewModelTests.swift */; };
|
||||||
758BF44CA565AB0AB84F2185 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7109E709A7738E6BCC4553E6 /* Localizable.strings */; };
|
758BF44CA565AB0AB84F2185 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7109E709A7738E6BCC4553E6 /* Localizable.strings */; };
|
||||||
75D98001C5AC38B6A5CA897C /* UITestScreenIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FD9D66B75292F2CC11AA4D2 /* UITestScreenIdentifier.swift */; };
|
75D98001C5AC38B6A5CA897C /* UITestScreenIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FD9D66B75292F2CC11AA4D2 /* UITestScreenIdentifier.swift */; };
|
||||||
|
75EA4ABBFAA810AFF289D6F4 /* TemplateViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDB6E40BAD4504D899FAAC9A /* TemplateViewModel.swift */; };
|
||||||
7756C4E90CABE6F14F7920A0 /* BugReportUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6FEA87EA3752203065ECE27 /* BugReportUITests.swift */; };
|
7756C4E90CABE6F14F7920A0 /* BugReportUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6FEA87EA3752203065ECE27 /* BugReportUITests.swift */; };
|
||||||
77D7DAA41AAB36800C1F2E2D /* RoomTimelineProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095AED4CF56DFF3EB7BB84C8 /* RoomTimelineProviderProtocol.swift */; };
|
77D7DAA41AAB36800C1F2E2D /* RoomTimelineProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095AED4CF56DFF3EB7BB84C8 /* RoomTimelineProviderProtocol.swift */; };
|
||||||
77E192BA943B90F9F310CA23 /* WeakDictionaryKeyReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FFCC48E7F701B6C24484593 /* WeakDictionaryKeyReference.swift */; };
|
77E192BA943B90F9F310CA23 /* WeakDictionaryKeyReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FFCC48E7F701B6C24484593 /* WeakDictionaryKeyReference.swift */; };
|
||||||
@@ -149,6 +155,7 @@
|
|||||||
7963F98CDFDEAC75E072BD81 /* TextRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A8C632CEF4600107792899 /* TextRoomTimelineItem.swift */; };
|
7963F98CDFDEAC75E072BD81 /* TextRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A8C632CEF4600107792899 /* TextRoomTimelineItem.swift */; };
|
||||||
79A6E08ADE6E7C460A8A17A5 /* UserSessionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C37FB986891D90BEAA93EAE /* UserSessionStore.swift */; };
|
79A6E08ADE6E7C460A8A17A5 /* UserSessionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C37FB986891D90BEAA93EAE /* UserSessionStore.swift */; };
|
||||||
7A54700193DC1F264368746A /* UserIndicatorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E077F76026C85ED96FEBB810 /* UserIndicatorPresenter.swift */; };
|
7A54700193DC1F264368746A /* UserIndicatorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E077F76026C85ED96FEBB810 /* UserIndicatorPresenter.swift */; };
|
||||||
|
7AE1FFB132F2B84EB8A2AEBC /* TemplateViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3340ABAE3A4647E80163AE18 /* TemplateViewModelTests.swift */; };
|
||||||
7BB31E67648CF32D2AB5E502 /* RoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE3C90E487B255B735D73C8 /* RoomScreenViewModel.swift */; };
|
7BB31E67648CF32D2AB5E502 /* RoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE3C90E487B255B735D73C8 /* RoomScreenViewModel.swift */; };
|
||||||
7C1A7B594B2F8143F0DD0005 /* ElementXAttributeScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = C024C151639C4E1B91FCC68B /* ElementXAttributeScope.swift */; };
|
7C1A7B594B2F8143F0DD0005 /* ElementXAttributeScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = C024C151639C4E1B91FCC68B /* ElementXAttributeScope.swift */; };
|
||||||
7D1DAAA364A9A29D554BD24E /* PlaceholderAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0950733DD4BA83EEE752E259 /* PlaceholderAvatarImage.swift */; };
|
7D1DAAA364A9A29D554BD24E /* PlaceholderAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0950733DD4BA83EEE752E259 /* PlaceholderAvatarImage.swift */; };
|
||||||
@@ -160,6 +167,7 @@
|
|||||||
80E04BE80A89A78FBB4863BB /* UserIndicatorViewPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193FB285430D3956B6E61E4D /* UserIndicatorViewPresentable.swift */; };
|
80E04BE80A89A78FBB4863BB /* UserIndicatorViewPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193FB285430D3956B6E61E4D /* UserIndicatorViewPresentable.swift */; };
|
||||||
83E5054739949181CA981193 /* LoginCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD667C4BB98CF4F3FE2CE3B0 /* LoginCoordinator.swift */; };
|
83E5054739949181CA981193 /* LoginCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD667C4BB98CF4F3FE2CE3B0 /* LoginCoordinator.swift */; };
|
||||||
85AFBB433AD56704A880F8A0 /* FramePreferenceKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4798B3B7A1E8AE3901CEE8C6 /* FramePreferenceKey.swift */; };
|
85AFBB433AD56704A880F8A0 /* FramePreferenceKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4798B3B7A1E8AE3901CEE8C6 /* FramePreferenceKey.swift */; };
|
||||||
|
86675910612A12409262DFBD /* SessionVerificationStateMachineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1C22B1B5FA3A765EADB2CC9 /* SessionVerificationStateMachineTests.swift */; };
|
||||||
86C2E93920FD15AD17E193A9 /* BugReportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E532D95330139D118A9BF88 /* BugReportViewModel.swift */; };
|
86C2E93920FD15AD17E193A9 /* BugReportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E532D95330139D118A9BF88 /* BugReportViewModel.swift */; };
|
||||||
872A6457DF573AF8CEAE927A /* LoginHomeserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9349F590E35CE514A71E6764 /* LoginHomeserver.swift */; };
|
872A6457DF573AF8CEAE927A /* LoginHomeserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9349F590E35CE514A71E6764 /* LoginHomeserver.swift */; };
|
||||||
87756CA950ED55870A1AAE8F /* ServerSelectionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D7D706FFF438CAF16F44D8C /* ServerSelectionCoordinator.swift */; };
|
87756CA950ED55870A1AAE8F /* ServerSelectionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D7D706FFF438CAF16F44D8C /* ServerSelectionCoordinator.swift */; };
|
||||||
@@ -173,6 +181,7 @@
|
|||||||
90EB25D13AE6EEF034BDE9D2 /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71D52BAA5BADB06E5E8C295D /* Assets.swift */; };
|
90EB25D13AE6EEF034BDE9D2 /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71D52BAA5BADB06E5E8C295D /* Assets.swift */; };
|
||||||
93875ADD456142D20823ED24 /* ServerSelectionViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */; };
|
93875ADD456142D20823ED24 /* ServerSelectionViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */; };
|
||||||
93BA4A81B6D893271101F9F0 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 5986E300FC849DEAB2EE7AEB /* Introspect */; };
|
93BA4A81B6D893271101F9F0 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 5986E300FC849DEAB2EE7AEB /* Introspect */; };
|
||||||
|
94A65DD8A353DF112EBEF67A /* SessionVerificationControllerProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D56469A9EE0CFA2B7BA9760 /* SessionVerificationControllerProxyProtocol.swift */; };
|
||||||
94D0F36A87E596A93C0C178A /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E89E530A8E92EC44301CA1 /* Bundle.swift */; };
|
94D0F36A87E596A93C0C178A /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E89E530A8E92EC44301CA1 /* Bundle.swift */; };
|
||||||
94E062D08E27B0387658E364 /* SplashScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5CF94E124616FD89424B73 /* SplashScreenViewModelTests.swift */; };
|
94E062D08E27B0387658E364 /* SplashScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5CF94E124616FD89424B73 /* SplashScreenViewModelTests.swift */; };
|
||||||
964B9D2EC38C488C360CE0C9 /* HomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B902EA6CD3296B0E10EE432B /* HomeScreen.swift */; };
|
964B9D2EC38C488C360CE0C9 /* HomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B902EA6CD3296B0E10EE432B /* HomeScreen.swift */; };
|
||||||
@@ -190,6 +199,7 @@
|
|||||||
9CB5129C83F75921E5E28028 /* ToastViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C82DAE0B8EB28234E84E6CF /* ToastViewState.swift */; };
|
9CB5129C83F75921E5E28028 /* ToastViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C82DAE0B8EB28234E84E6CF /* ToastViewState.swift */; };
|
||||||
9D2E03DB175A6AB14589076D /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 020597E28A4BC8E1BE8EDF6E /* KeychainAccess */; };
|
9D2E03DB175A6AB14589076D /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 020597E28A4BC8E1BE8EDF6E /* KeychainAccess */; };
|
||||||
9DC5FB22B8F86C3B51E907C1 /* HomeScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D6E4C37E9F0E53D3DF951AC /* HomeScreenUITests.swift */; };
|
9DC5FB22B8F86C3B51E907C1 /* HomeScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D6E4C37E9F0E53D3DF951AC /* HomeScreenUITests.swift */; };
|
||||||
|
9E8AE387FD03E4F1C1B8815A /* SessionVerificationStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = C06FCD42EEFEFC220F14EAC5 /* SessionVerificationStateMachine.swift */; };
|
||||||
A00DFC1DD3567B1EDC9F8D16 /* SplashScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 325A2B3278875554DDEB8A9B /* SplashScreenUITests.swift */; };
|
A00DFC1DD3567B1EDC9F8D16 /* SplashScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 325A2B3278875554DDEB8A9B /* SplashScreenUITests.swift */; };
|
||||||
A0A0D2A9564BDA3FDE2E360F /* FormattedBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */; };
|
A0A0D2A9564BDA3FDE2E360F /* FormattedBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */; };
|
||||||
A32517FB1CA0BBCE2BC75249 /* BugReportCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD6C07DA7D3FF193F7419F55 /* BugReportCoordinator.swift */; };
|
A32517FB1CA0BBCE2BC75249 /* BugReportCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD6C07DA7D3FF193F7419F55 /* BugReportCoordinator.swift */; };
|
||||||
@@ -201,10 +211,10 @@
|
|||||||
A6DEC1ADEC8FEEC206A0FA37 /* AttributedStringBuilderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72F37B5DA798C9AE436F2C2C /* AttributedStringBuilderProtocol.swift */; };
|
A6DEC1ADEC8FEEC206A0FA37 /* AttributedStringBuilderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72F37B5DA798C9AE436F2C2C /* AttributedStringBuilderProtocol.swift */; };
|
||||||
A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; };
|
A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; };
|
||||||
A851635B3255C6DC07034A12 /* RoomScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8108C8F0ACF6A7EB72D0117 /* RoomScreenCoordinator.swift */; };
|
A851635B3255C6DC07034A12 /* RoomScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8108C8F0ACF6A7EB72D0117 /* RoomScreenCoordinator.swift */; };
|
||||||
|
A8EC7C9D886244DAE9433E37 /* SessionVerificationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4C18FAAD59AE7F1462D817E /* SessionVerificationViewModel.swift */; };
|
||||||
AB34401E4E1CAD5D2EC3072B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9760103CF316DF68698BCFE6 /* LaunchScreen.storyboard */; };
|
AB34401E4E1CAD5D2EC3072B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9760103CF316DF68698BCFE6 /* LaunchScreen.storyboard */; };
|
||||||
ABF3FAB234AD3565B214309B /* TimelineSenderAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BC588051E6572A1AF51D738 /* TimelineSenderAvatarView.swift */; };
|
ABF3FAB234AD3565B214309B /* TimelineSenderAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BC588051E6572A1AF51D738 /* TimelineSenderAvatarView.swift */; };
|
||||||
B037C365CF8A58A0D149A2DB /* AuthenticationIconImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97755C01C3971474EFAD5367 /* AuthenticationIconImage.swift */; };
|
B037C365CF8A58A0D149A2DB /* AuthenticationIconImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97755C01C3971474EFAD5367 /* AuthenticationIconImage.swift */; };
|
||||||
B0EDAF55877DE19B67837C22 /* TemplateModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1C29670CEC77346F31EE94C /* TemplateModels.swift */; };
|
|
||||||
B245583C63F8F90357B87FAE /* SwiftState in Frameworks */ = {isa = PBXBuildFile; productRef = 3853B78FB8531B83936C5DA6 /* SwiftState */; };
|
B245583C63F8F90357B87FAE /* SwiftState in Frameworks */ = {isa = PBXBuildFile; productRef = 3853B78FB8531B83936C5DA6 /* SwiftState */; };
|
||||||
B3357B00F1AA930E54F76609 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47EBB5D698CE9A25BB553A2D /* Strings.swift */; };
|
B3357B00F1AA930E54F76609 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47EBB5D698CE9A25BB553A2D /* Strings.swift */; };
|
||||||
B3FDB1D9CF40777695DBBD1D /* AppCoordinatorStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A9AB74614131D6706894E0C /* AppCoordinatorStateMachine.swift */; };
|
B3FDB1D9CF40777695DBBD1D /* AppCoordinatorStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A9AB74614131D6706894E0C /* AppCoordinatorStateMachine.swift */; };
|
||||||
@@ -215,14 +225,15 @@
|
|||||||
B80C4FABB5529DF12436FFDA /* AppIcon.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 16DC8C5B2991724903F1FA6A /* AppIcon.pdf */; };
|
B80C4FABB5529DF12436FFDA /* AppIcon.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 16DC8C5B2991724903F1FA6A /* AppIcon.pdf */; };
|
||||||
B94368839BDB69172E28E245 /* MXLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111B698739E3410E2CDB7144 /* MXLog.swift */; };
|
B94368839BDB69172E28E245 /* MXLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111B698739E3410E2CDB7144 /* MXLog.swift */; };
|
||||||
BB01CC19C3D3322308D1B2CF /* ServerSelectionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 167521635A1CC27624FCEB7F /* ServerSelectionViewModel.swift */; };
|
BB01CC19C3D3322308D1B2CF /* ServerSelectionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 167521635A1CC27624FCEB7F /* ServerSelectionViewModel.swift */; };
|
||||||
|
BB6B0B91CE11E06330017000 /* SessionVerificationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AC1A01C3A745BDF1D3697D3 /* SessionVerificationScreen.swift */; };
|
||||||
BCC3EDB7AD0902797CB4BBC2 /* MXLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = EF188681D6B6068CFAEAFC3F /* MXLogger.m */; };
|
BCC3EDB7AD0902797CB4BBC2 /* MXLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = EF188681D6B6068CFAEAFC3F /* MXLogger.m */; };
|
||||||
BCEC41FB1F2BB663183863E4 /* LoginServerInfoSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D379E13DD9D987470A3C70C /* LoginServerInfoSection.swift */; };
|
BCEC41FB1F2BB663183863E4 /* LoginServerInfoSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D379E13DD9D987470A3C70C /* LoginServerInfoSection.swift */; };
|
||||||
BE3237142FA6E1A13C0E7D11 /* RoomSummaryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C21ECC295F4DE8DAA86D62AC /* RoomSummaryProtocol.swift */; };
|
BE3237142FA6E1A13C0E7D11 /* RoomSummaryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C21ECC295F4DE8DAA86D62AC /* RoomSummaryProtocol.swift */; };
|
||||||
BEEC06EFD30BFCA02F0FD559 /* UserIndicatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D8EA85D4F10D7445BB6368A /* UserIndicatorTests.swift */; };
|
BEEC06EFD30BFCA02F0FD559 /* UserIndicatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D8EA85D4F10D7445BB6368A /* UserIndicatorTests.swift */; };
|
||||||
BF35062D06888FA80BD139FF /* Presentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB7F9D6FC121204D59E18DF /* Presentable.swift */; };
|
BF35062D06888FA80BD139FF /* Presentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB7F9D6FC121204D59E18DF /* Presentable.swift */; };
|
||||||
C052A8CDC7A8E7A2D906674F /* UserIndicatorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FAA6438B00FDB130F404E31 /* UserIndicatorStore.swift */; };
|
C052A8CDC7A8E7A2D906674F /* UserIndicatorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FAA6438B00FDB130F404E31 /* UserIndicatorStore.swift */; };
|
||||||
C1156BBE4F977AEEE1E80C48 /* TemplateCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2869CFFF6CD2A642AB4B743 /* TemplateCoordinator.swift */; };
|
|
||||||
C2CF93B067FD935E4F82FE44 /* SplashScreenPageIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850064FF8D7DB9C875E7AA1A /* SplashScreenPageIndicator.swift */; };
|
C2CF93B067FD935E4F82FE44 /* SplashScreenPageIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850064FF8D7DB9C875E7AA1A /* SplashScreenPageIndicator.swift */; };
|
||||||
|
C4180F418235DAD9DD173951 /* TemplateScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9873076F224E4CE09D8BD47D /* TemplateScreenUITests.swift */; };
|
||||||
C4F69156C31A447FEFF2A47C /* DTHTMLElement+AttributedStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E508AB0EDEE017FF4F6F8D1 /* DTHTMLElement+AttributedStringBuilder.swift */; };
|
C4F69156C31A447FEFF2A47C /* DTHTMLElement+AttributedStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E508AB0EDEE017FF4F6F8D1 /* DTHTMLElement+AttributedStringBuilder.swift */; };
|
||||||
C55A44C99F64A479ABA85B46 /* RoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */; };
|
C55A44C99F64A479ABA85B46 /* RoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */; };
|
||||||
C76892321558E75101E68ED6 /* ReadableFrameModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */; };
|
C76892321558E75101E68ED6 /* ReadableFrameModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */; };
|
||||||
@@ -237,8 +248,10 @@
|
|||||||
CEB8FB1269DE20536608B957 /* LoginMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41FABA2B0AEF4389986495 /* LoginMode.swift */; };
|
CEB8FB1269DE20536608B957 /* LoginMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41FABA2B0AEF4389986495 /* LoginMode.swift */; };
|
||||||
CF82143AA4A4F7BD11D22946 /* RoomTimelineViewProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACB6C5E4950B6C9842F35A38 /* RoomTimelineViewProvider.swift */; };
|
CF82143AA4A4F7BD11D22946 /* RoomTimelineViewProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACB6C5E4950B6C9842F35A38 /* RoomTimelineViewProvider.swift */; };
|
||||||
D013E70C8E28E43497820444 /* TextRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4110685D9CA159F3FD2D6BA1 /* TextRoomMessage.swift */; };
|
D013E70C8E28E43497820444 /* TextRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4110685D9CA159F3FD2D6BA1 /* TextRoomMessage.swift */; };
|
||||||
|
D034A195A3494E38BF060485 /* MockSessionVerificationControllerProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1A9CCCF53495CF3D7B19FCE /* MockSessionVerificationControllerProxy.swift */; };
|
||||||
D0619D2E6B9C511190FBEB95 /* RoomMessageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607974D08BD2AF83725D817A /* RoomMessageProtocol.swift */; };
|
D0619D2E6B9C511190FBEB95 /* RoomMessageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607974D08BD2AF83725D817A /* RoomMessageProtocol.swift */; };
|
||||||
D5EA4C6C80579279770D5804 /* ImageRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */; };
|
D5EA4C6C80579279770D5804 /* ImageRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */; };
|
||||||
|
D6417E5A799C3C7F14F9EC0A /* SessionVerificationViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3069ADED46D063202FE7698 /* SessionVerificationViewModelProtocol.swift */; };
|
||||||
D826154612415D2A3BB6EBF3 /* ListTableViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E854E7CF531DAC5CBEBDC75 /* ListTableViewAdapter.swift */; };
|
D826154612415D2A3BB6EBF3 /* ListTableViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E854E7CF531DAC5CBEBDC75 /* ListTableViewAdapter.swift */; };
|
||||||
D8CFF02C2730EE5BC4F17ABF /* ElementToggleStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0960A7F5C1B0B6679BDF26F9 /* ElementToggleStyle.swift */; };
|
D8CFF02C2730EE5BC4F17ABF /* ElementToggleStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0960A7F5C1B0B6679BDF26F9 /* ElementToggleStyle.swift */; };
|
||||||
D94F664677C380A3CAB8D7F6 /* ActivityIndicatorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68706A66BBA04268F7747A2F /* ActivityIndicatorPresenter.swift */; };
|
D94F664677C380A3CAB8D7F6 /* ActivityIndicatorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68706A66BBA04268F7747A2F /* ActivityIndicatorPresenter.swift */; };
|
||||||
@@ -249,13 +262,12 @@
|
|||||||
DFF7D6A6C26DDD40D00AE579 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = F012CB5EE3F2B67359F6CC52 /* target.yml */; };
|
DFF7D6A6C26DDD40D00AE579 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = F012CB5EE3F2B67359F6CC52 /* target.yml */; };
|
||||||
E0A4DCA633D174EB43AD599F /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */; };
|
E0A4DCA633D174EB43AD599F /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */; };
|
||||||
E1DF24D085572A55C9758A2D /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E89E530A8E92EC44301CA1 /* Bundle.swift */; };
|
E1DF24D085572A55C9758A2D /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E89E530A8E92EC44301CA1 /* Bundle.swift */; };
|
||||||
E75CE800B3E64D0F7F8E228D /* TemplateViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C08E9043618AE5B0BF7B07E1 /* TemplateViewModelTests.swift */; };
|
E5895C74615CBE8462FB840F /* SessionVerificationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCF86010A0A719A9A50EEC59 /* SessionVerificationCoordinator.swift */; };
|
||||||
E81EEC1675F2371D12A880A3 /* MockRoomTimelineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61ADFB893DEF81E58DF3FAB9 /* MockRoomTimelineController.swift */; };
|
E81EEC1675F2371D12A880A3 /* MockRoomTimelineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61ADFB893DEF81E58DF3FAB9 /* MockRoomTimelineController.swift */; };
|
||||||
EA1E7949533E19C6D862680A /* MediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 885D8C42DD17625B5261BEFF /* MediaProvider.swift */; };
|
EA1E7949533E19C6D862680A /* MediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 885D8C42DD17625B5261BEFF /* MediaProvider.swift */; };
|
||||||
EA31DD9043B91ECB8E45A9A6 /* ScreenshotDetectorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F03C9D319676F3C0DC6B0203 /* ScreenshotDetectorTests.swift */; };
|
EA31DD9043B91ECB8E45A9A6 /* ScreenshotDetectorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F03C9D319676F3C0DC6B0203 /* ScreenshotDetectorTests.swift */; };
|
||||||
EA65360A0EC026DD83AC0CF5 /* AuthenticationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6CA5F386C7701C129398945 /* AuthenticationCoordinator.swift */; };
|
EA65360A0EC026DD83AC0CF5 /* AuthenticationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6CA5F386C7701C129398945 /* AuthenticationCoordinator.swift */; };
|
||||||
EBD6C79705B3DDB2F7E5F554 /* UserSessionStoreProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1B52D0ABBA7091A991CAFE /* UserSessionStoreProtocol.swift */; };
|
EBD6C79705B3DDB2F7E5F554 /* UserSessionStoreProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1B52D0ABBA7091A991CAFE /* UserSessionStoreProtocol.swift */; };
|
||||||
ED4F663C783E9A8C0E80B983 /* TemplateViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47543EB19F3DCF308751F53C /* TemplateViewModel.swift */; };
|
|
||||||
EE8491AD81F47DF3C192497B /* DecorationTimelineItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 184CF8C196BE143AE226628D /* DecorationTimelineItemProtocol.swift */; };
|
EE8491AD81F47DF3C192497B /* DecorationTimelineItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 184CF8C196BE143AE226628D /* DecorationTimelineItemProtocol.swift */; };
|
||||||
EEC40663922856C65D1E0DF5 /* KeychainControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB9C37196A4C79F24CE80C6 /* KeychainControllerTests.swift */; };
|
EEC40663922856C65D1E0DF5 /* KeychainControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB9C37196A4C79F24CE80C6 /* KeychainControllerTests.swift */; };
|
||||||
EF99A92701E401C4CD5ADC50 /* SplashScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCE978A6118C131D7F2A04B3 /* SplashScreenModels.swift */; };
|
EF99A92701E401C4CD5ADC50 /* SplashScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCE978A6118C131D7F2A04B3 /* SplashScreenModels.swift */; };
|
||||||
@@ -334,6 +346,7 @@
|
|||||||
1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Strings+Untranslated.swift"; sourceTree = "<group>"; };
|
1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Strings+Untranslated.swift"; sourceTree = "<group>"; };
|
||||||
1A63815AD6A5C306453342F2 /* ImageRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineItem.swift; sourceTree = "<group>"; };
|
1A63815AD6A5C306453342F2 /* ImageRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
1C429043E986008B97736636 /* ab */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ab; path = ab.lproj/Localizable.strings; sourceTree = "<group>"; };
|
1C429043E986008B97736636 /* ab */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ab; path = ab.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
1D56469A9EE0CFA2B7BA9760 /* SessionVerificationControllerProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
1DB34B0C74CD242FED9DD069 /* LoginScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenUITests.swift; sourceTree = "<group>"; };
|
1DB34B0C74CD242FED9DD069 /* LoginScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenUITests.swift; sourceTree = "<group>"; };
|
||||||
1E1FB768A24FDD2A5CA16E3C /* LoginViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModelProtocol.swift; sourceTree = "<group>"; };
|
1E1FB768A24FDD2A5CA16E3C /* LoginViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
1E508AB0EDEE017FF4F6F8D1 /* DTHTMLElement+AttributedStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DTHTMLElement+AttributedStringBuilder.swift"; sourceTree = "<group>"; };
|
1E508AB0EDEE017FF4F6F8D1 /* DTHTMLElement+AttributedStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DTHTMLElement+AttributedStringBuilder.swift"; sourceTree = "<group>"; };
|
||||||
@@ -352,6 +365,7 @@
|
|||||||
29A953B6C0C431DBF4DD00B4 /* RoomSummary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummary.swift; sourceTree = "<group>"; };
|
29A953B6C0C431DBF4DD00B4 /* RoomSummary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummary.swift; sourceTree = "<group>"; };
|
||||||
2A5C6FBF97B6EED3D4FA5EFF /* AttributedStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringBuilder.swift; sourceTree = "<group>"; };
|
2A5C6FBF97B6EED3D4FA5EFF /* AttributedStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringBuilder.swift; sourceTree = "<group>"; };
|
||||||
2AE83A3DD63BCFBB956FE5CB /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = nl; path = nl.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
2AE83A3DD63BCFBB956FE5CB /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = nl; path = nl.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
|
2B80895CE021B49847BD7D74 /* TemplateViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskProtocol.swift; sourceTree = "<group>"; };
|
2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskProtocol.swift; sourceTree = "<group>"; };
|
||||||
2CF9FE7E0CF9F40D1509E63A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = bg; path = bg.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
2CF9FE7E0CF9F40D1509E63A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = bg; path = bg.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
2EEB64CC6F3DF5B68736A6B4 /* AlertInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertInfo.swift; sourceTree = "<group>"; };
|
2EEB64CC6F3DF5B68736A6B4 /* AlertInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertInfo.swift; sourceTree = "<group>"; };
|
||||||
@@ -359,6 +373,7 @@
|
|||||||
31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = "<group>"; };
|
31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
325A2B3278875554DDEB8A9B /* SplashScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenUITests.swift; sourceTree = "<group>"; };
|
325A2B3278875554DDEB8A9B /* SplashScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenUITests.swift; sourceTree = "<group>"; };
|
||||||
32CE6D4FF64C9A3C18619224 /* SplashScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreen.swift; sourceTree = "<group>"; };
|
32CE6D4FF64C9A3C18619224 /* SplashScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreen.swift; sourceTree = "<group>"; };
|
||||||
|
3340ABAE3A4647E80163AE18 /* TemplateViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
33E49C5C6F802B4D94CA78D1 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = "<group>"; };
|
33E49C5C6F802B4D94CA78D1 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
35AFCF4C05DEED04E3DB1A16 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
|
35AFCF4C05DEED04E3DB1A16 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
36322DD0D4E29D31B0945ADC /* EventBriefFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBriefFactory.swift; sourceTree = "<group>"; };
|
36322DD0D4E29D31B0945ADC /* EventBriefFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBriefFactory.swift; sourceTree = "<group>"; };
|
||||||
@@ -390,9 +405,9 @@
|
|||||||
4488F5F92A64A137665C96CD /* pa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pa; path = pa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
4488F5F92A64A137665C96CD /* pa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pa; path = pa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
44AEEE13AC1BF303AE48CBF8 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/Localizable.strings; sourceTree = "<group>"; };
|
44AEEE13AC1BF303AE48CBF8 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
453E722A43D092C06FB8E3FA /* tzm */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tzm; path = tzm.lproj/Localizable.strings; sourceTree = "<group>"; };
|
453E722A43D092C06FB8E3FA /* tzm */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tzm; path = tzm.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
4549FCB53F43DB0B278374BC /* TemplateScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreen.swift; sourceTree = "<group>"; };
|
||||||
47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = "<group>"; };
|
47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineView.swift; sourceTree = "<group>"; };
|
471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||||
47543EB19F3DCF308751F53C /* TemplateViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateViewModel.swift; sourceTree = "<group>"; };
|
|
||||||
475EB595D7527E9A8A14043E /* uz */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uz; path = uz.lproj/Localizable.strings; sourceTree = "<group>"; };
|
475EB595D7527E9A8A14043E /* uz */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uz; path = uz.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
4798B3B7A1E8AE3901CEE8C6 /* FramePreferenceKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FramePreferenceKey.swift; sourceTree = "<group>"; };
|
4798B3B7A1E8AE3901CEE8C6 /* FramePreferenceKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FramePreferenceKey.swift; sourceTree = "<group>"; };
|
||||||
47EBB5D698CE9A25BB553A2D /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; };
|
47EBB5D698CE9A25BB553A2D /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; };
|
||||||
@@ -404,7 +419,6 @@
|
|||||||
49EAD710A2C16EFF7C3EA16F /* Benchmark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Benchmark.swift; sourceTree = "<group>"; };
|
49EAD710A2C16EFF7C3EA16F /* Benchmark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Benchmark.swift; sourceTree = "<group>"; };
|
||||||
4B40B7F6FCCE2D8C242492D9 /* ga */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ga; path = ga.lproj/Localizable.strings; sourceTree = "<group>"; };
|
4B40B7F6FCCE2D8C242492D9 /* ga */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ga; path = ga.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
4B41FABA2B0AEF4389986495 /* LoginMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginMode.swift; sourceTree = "<group>"; };
|
4B41FABA2B0AEF4389986495 /* LoginMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginMode.swift; sourceTree = "<group>"; };
|
||||||
4B66E05B6009B0EB1BDBFA6E /* TemplateScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenUITests.swift; sourceTree = "<group>"; };
|
|
||||||
4C82DAE0B8EB28234E84E6CF /* ToastViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastViewState.swift; sourceTree = "<group>"; };
|
4C82DAE0B8EB28234E84E6CF /* ToastViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastViewState.swift; sourceTree = "<group>"; };
|
||||||
4C8D988E82A8DFA13BE46F7C /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = pl; path = pl.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
4C8D988E82A8DFA13BE46F7C /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = pl; path = pl.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
4CD6AC7546E8D7E5C73CEA48 /* ElementX.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = ElementX.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
4CD6AC7546E8D7E5C73CEA48 /* ElementX.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = ElementX.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@@ -454,6 +468,7 @@
|
|||||||
6A152791A2F56BD193BFE986 /* MemberDetailsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberDetailsProvider.swift; sourceTree = "<group>"; };
|
6A152791A2F56BD193BFE986 /* MemberDetailsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberDetailsProvider.swift; sourceTree = "<group>"; };
|
||||||
6A901D95158B02CA96C79C7F /* InfoPlist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoPlist.swift; sourceTree = "<group>"; };
|
6A901D95158B02CA96C79C7F /* InfoPlist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoPlist.swift; sourceTree = "<group>"; };
|
||||||
6B73A8C3118EAC7BF3F3EE7A /* SplashScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
6B73A8C3118EAC7BF3F3EE7A /* SplashScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
6D4777F0142E330A75C46FE4 /* SessionVerificationUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationUITests.swift; sourceTree = "<group>"; };
|
||||||
6DB53055CB130F0651C70763 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = "<group>"; };
|
6DB53055CB130F0651C70763 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
6DFCAA239095A116976E32C4 /* BackgroundTaskTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskTests.swift; sourceTree = "<group>"; };
|
6DFCAA239095A116976E32C4 /* BackgroundTaskTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskTests.swift; sourceTree = "<group>"; };
|
||||||
6E5E9C044BEB7C70B1378E91 /* UserSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSession.swift; sourceTree = "<group>"; };
|
6E5E9C044BEB7C70B1378E91 /* UserSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSession.swift; sourceTree = "<group>"; };
|
||||||
@@ -496,6 +511,7 @@
|
|||||||
8888D13645C04AC9818F5778 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
8888D13645C04AC9818F5778 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
892E29C98C4E8182C9037F84 /* TimelineStyler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyler.swift; sourceTree = "<group>"; };
|
892E29C98C4E8182C9037F84 /* TimelineStyler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyler.swift; sourceTree = "<group>"; };
|
||||||
8A9AE4967817E9608E22EB44 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
8A9AE4967817E9608E22EB44 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
|
8AC1A01C3A745BDF1D3697D3 /* SessionVerificationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreen.swift; sourceTree = "<group>"; };
|
||||||
8BF686BA36D0C2FA3C63DFDF /* ImageRoomMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomMessage.swift; sourceTree = "<group>"; };
|
8BF686BA36D0C2FA3C63DFDF /* ImageRoomMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomMessage.swift; sourceTree = "<group>"; };
|
||||||
8C0AA893D6F8A2F563E01BB9 /* in */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = in; path = in.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
8C0AA893D6F8A2F563E01BB9 /* in */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = in; path = in.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
8C2ABC1A9B62BDB3D216E7FD /* MemberDetailProviderManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberDetailProviderManager.swift; sourceTree = "<group>"; };
|
8C2ABC1A9B62BDB3D216E7FD /* MemberDetailProviderManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberDetailProviderManager.swift; sourceTree = "<group>"; };
|
||||||
@@ -517,6 +533,7 @@
|
|||||||
9772C1D2223108EB3131AEE4 /* zh-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-CN"; path = "zh-CN.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
9772C1D2223108EB3131AEE4 /* zh-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-CN"; path = "zh-CN.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
97755C01C3971474EFAD5367 /* AuthenticationIconImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationIconImage.swift; sourceTree = "<group>"; };
|
97755C01C3971474EFAD5367 /* AuthenticationIconImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationIconImage.swift; sourceTree = "<group>"; };
|
||||||
97F893DBB5F88D746C6DCDE5 /* ku */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ku; path = ku.lproj/Localizable.strings; sourceTree = "<group>"; };
|
97F893DBB5F88D746C6DCDE5 /* ku */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ku; path = ku.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
9873076F224E4CE09D8BD47D /* TemplateScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenUITests.swift; sourceTree = "<group>"; };
|
||||||
98A2932515EA11D3DD8A3506 /* TimelineItemBubbledStylerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemBubbledStylerView.swift; sourceTree = "<group>"; };
|
98A2932515EA11D3DD8A3506 /* TimelineItemBubbledStylerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemBubbledStylerView.swift; sourceTree = "<group>"; };
|
||||||
997783054A2E95F9E624217E /* kaa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = kaa; path = kaa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
997783054A2E95F9E624217E /* kaa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = kaa; path = kaa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
99DE232F24EAD72A3DF7EF1A /* kab */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = kab; path = kab.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
99DE232F24EAD72A3DF7EF1A /* kab */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = kab; path = kab.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
@@ -528,7 +545,7 @@
|
|||||||
A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
A05707BF550D770168A406DB /* LoginViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModelTests.swift; sourceTree = "<group>"; };
|
A05707BF550D770168A406DB /* LoginViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
A0A20AE75FF4FF35B1FF6CA7 /* MockServerSelectionScreenState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockServerSelectionScreenState.swift; sourceTree = "<group>"; };
|
A0A20AE75FF4FF35B1FF6CA7 /* MockServerSelectionScreenState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockServerSelectionScreenState.swift; sourceTree = "<group>"; };
|
||||||
A1C29670CEC77346F31EE94C /* TemplateModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModels.swift; sourceTree = "<group>"; };
|
A1C22B1B5FA3A765EADB2CC9 /* SessionVerificationStateMachineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationStateMachineTests.swift; sourceTree = "<group>"; };
|
||||||
A1ED7E89865201EE7D53E6DA /* SeparatorRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorRoomTimelineItem.swift; sourceTree = "<group>"; };
|
A1ED7E89865201EE7D53E6DA /* SeparatorRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
A2B6433F516F1E6DFA0E2D89 /* vls */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vls; path = vls.lproj/Localizable.strings; sourceTree = "<group>"; };
|
A2B6433F516F1E6DFA0E2D89 /* vls */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vls; path = vls.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
A30A1758E2B73EF38E7C42F8 /* ServerSelectionModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionModels.swift; sourceTree = "<group>"; };
|
A30A1758E2B73EF38E7C42F8 /* ServerSelectionModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionModels.swift; sourceTree = "<group>"; };
|
||||||
@@ -558,8 +575,10 @@
|
|||||||
B1183B55FF4B01022DA721CB /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
B1183B55FF4B01022DA721CB /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
B12969CEC0051BC750DA5068 /* WeakKeyDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakKeyDictionary.swift; sourceTree = "<group>"; };
|
B12969CEC0051BC750DA5068 /* WeakKeyDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakKeyDictionary.swift; sourceTree = "<group>"; };
|
||||||
B1D1532B5D9FB0C8461A1453 /* UserIndicatorDismissal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorDismissal.swift; sourceTree = "<group>"; };
|
B1D1532B5D9FB0C8461A1453 /* UserIndicatorDismissal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorDismissal.swift; sourceTree = "<group>"; };
|
||||||
|
B3069ADED46D063202FE7698 /* SessionVerificationViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
B4173A48FD8542CD4AD3645C /* NavigationRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRouter.swift; sourceTree = "<group>"; };
|
B4173A48FD8542CD4AD3645C /* NavigationRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRouter.swift; sourceTree = "<group>"; };
|
||||||
B43AF03660F5FD4FFFA7F1CE /* TimelineItemContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemContextMenu.swift; sourceTree = "<group>"; };
|
B43AF03660F5FD4FFFA7F1CE /* TimelineItemContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemContextMenu.swift; sourceTree = "<group>"; };
|
||||||
|
B4C18FAAD59AE7F1462D817E /* SessionVerificationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationViewModel.swift; sourceTree = "<group>"; };
|
||||||
B516212D9FE785DDD5E490D1 /* BugReportModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportModels.swift; sourceTree = "<group>"; };
|
B516212D9FE785DDD5E490D1 /* BugReportModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportModels.swift; sourceTree = "<group>"; };
|
||||||
B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineView.swift; sourceTree = "<group>"; };
|
B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||||
B64F3A3D0DF86ED5A241AB05 /* ActivityIndicatorView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ActivityIndicatorView.xib; sourceTree = "<group>"; };
|
B64F3A3D0DF86ED5A241AB05 /* ActivityIndicatorView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ActivityIndicatorView.xib; sourceTree = "<group>"; };
|
||||||
@@ -578,11 +597,12 @@
|
|||||||
BEE6BF9BA63FF42F8AF6EEEA /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sr; path = sr.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
BEE6BF9BA63FF42F8AF6EEEA /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sr; path = sr.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
BF1B52D0ABBA7091A991CAFE /* UserSessionStoreProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStoreProtocol.swift; sourceTree = "<group>"; };
|
BF1B52D0ABBA7091A991CAFE /* UserSessionStoreProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStoreProtocol.swift; sourceTree = "<group>"; };
|
||||||
C024C151639C4E1B91FCC68B /* ElementXAttributeScope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXAttributeScope.swift; sourceTree = "<group>"; };
|
C024C151639C4E1B91FCC68B /* ElementXAttributeScope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXAttributeScope.swift; sourceTree = "<group>"; };
|
||||||
|
C06FCD42EEFEFC220F14EAC5 /* SessionVerificationStateMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationStateMachine.swift; sourceTree = "<group>"; };
|
||||||
C070FD43DC6BF4E50217965A /* LocalizationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationTests.swift; sourceTree = "<group>"; };
|
C070FD43DC6BF4E50217965A /* LocalizationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationTests.swift; sourceTree = "<group>"; };
|
||||||
C08E9043618AE5B0BF7B07E1 /* TemplateViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateViewModelTests.swift; sourceTree = "<group>"; };
|
|
||||||
C21ECC295F4DE8DAA86D62AC /* RoomSummaryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProtocol.swift; sourceTree = "<group>"; };
|
C21ECC295F4DE8DAA86D62AC /* RoomSummaryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProtocol.swift; sourceTree = "<group>"; };
|
||||||
C2886615BEBAE33A0AA4D5F8 /* RoomScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenModels.swift; sourceTree = "<group>"; };
|
C2886615BEBAE33A0AA4D5F8 /* RoomScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenModels.swift; sourceTree = "<group>"; };
|
||||||
C483956FA3D665E3842E319A /* SettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreen.swift; sourceTree = "<group>"; };
|
C483956FA3D665E3842E319A /* SettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreen.swift; sourceTree = "<group>"; };
|
||||||
|
C55D7E514F9DE4E3D72FDCAD /* SessionVerificationControllerProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxy.swift; sourceTree = "<group>"; };
|
||||||
C6FEA87EA3752203065ECE27 /* BugReportUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportUITests.swift; sourceTree = "<group>"; };
|
C6FEA87EA3752203065ECE27 /* BugReportUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportUITests.swift; sourceTree = "<group>"; };
|
||||||
C88508B6F7974CFABEC4B261 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = "<group>"; };
|
C88508B6F7974CFABEC4B261 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
C888BCD78E2A55DCE364F160 /* MediaProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProviderProtocol.swift; sourceTree = "<group>"; };
|
C888BCD78E2A55DCE364F160 /* MediaProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProviderProtocol.swift; sourceTree = "<group>"; };
|
||||||
@@ -597,6 +617,7 @@
|
|||||||
CC680E0E79D818706CB28CF8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
CC680E0E79D818706CB28CF8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
CC7CCC6DE5FA623E31BA8546 /* RoomTimelineControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineControllerProtocol.swift; sourceTree = "<group>"; };
|
CC7CCC6DE5FA623E31BA8546 /* RoomTimelineControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineControllerProtocol.swift; sourceTree = "<group>"; };
|
||||||
CCA431E6EDD71F7067B5F9E7 /* UITestsRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsRootView.swift; sourceTree = "<group>"; };
|
CCA431E6EDD71F7067B5F9E7 /* UITestsRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsRootView.swift; sourceTree = "<group>"; };
|
||||||
|
CCF86010A0A719A9A50EEC59 /* SessionVerificationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationCoordinator.swift; sourceTree = "<group>"; };
|
||||||
CDE3F3911FF7CC639BDE5844 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
CDE3F3911FF7CC639BDE5844 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
CED34C87277BA3CCC6B6EC7A /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/Localizable.strings; sourceTree = "<group>"; };
|
CED34C87277BA3CCC6B6EC7A /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
CF3EDF23226895776553F04A /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = "<group>"; };
|
CF3EDF23226895776553F04A /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = "<group>"; };
|
||||||
@@ -604,6 +625,7 @@
|
|||||||
CF4B39D52CAE7D21D276ABEE /* ElementNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementNavigationController.swift; sourceTree = "<group>"; };
|
CF4B39D52CAE7D21D276ABEE /* ElementNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementNavigationController.swift; sourceTree = "<group>"; };
|
||||||
CF847B3C1873B8E81CEE7FAC /* SplashScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenViewModel.swift; sourceTree = "<group>"; };
|
CF847B3C1873B8E81CEE7FAC /* SplashScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineView.swift; sourceTree = "<group>"; };
|
D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||||
|
D1A9CCCF53495CF3D7B19FCE /* MockSessionVerificationControllerProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSessionVerificationControllerProxy.swift; sourceTree = "<group>"; };
|
||||||
D29EBCBFEC6FD0941749404D /* NavigationRouterStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRouterStore.swift; sourceTree = "<group>"; };
|
D29EBCBFEC6FD0941749404D /* NavigationRouterStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRouterStore.swift; sourceTree = "<group>"; };
|
||||||
D31DC8105C6233E5FFD9B84C /* element-x-ios */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "element-x-ios"; path = .; sourceTree = SOURCE_ROOT; };
|
D31DC8105C6233E5FFD9B84C /* element-x-ios */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "element-x-ios"; path = .; sourceTree = SOURCE_ROOT; };
|
||||||
D4DA544B2520BFA65D6DB4BB /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
D4DA544B2520BFA65D6DB4BB /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
||||||
@@ -612,18 +634,20 @@
|
|||||||
D6CA5F386C7701C129398945 /* AuthenticationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationCoordinator.swift; sourceTree = "<group>"; };
|
D6CA5F386C7701C129398945 /* AuthenticationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationCoordinator.swift; sourceTree = "<group>"; };
|
||||||
D6D094C15E8DB424F1C6FC94 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
D6D094C15E8DB424F1C6FC94 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
D6DC38E64A5ED3FDB201029A /* BugReportService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportService.swift; sourceTree = "<group>"; };
|
D6DC38E64A5ED3FDB201029A /* BugReportService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportService.swift; sourceTree = "<group>"; };
|
||||||
|
DBD460ED7ED1E03B85DEA25C /* TemplateCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateCoordinator.swift; sourceTree = "<group>"; };
|
||||||
DBFEAC3AC691CBB84983E275 /* ElementXTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXTests.swift; sourceTree = "<group>"; };
|
DBFEAC3AC691CBB84983E275 /* ElementXTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXTests.swift; sourceTree = "<group>"; };
|
||||||
DCE978A6118C131D7F2A04B3 /* SplashScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenModels.swift; sourceTree = "<group>"; };
|
DCE978A6118C131D7F2A04B3 /* SplashScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenModels.swift; sourceTree = "<group>"; };
|
||||||
DD667C4BB98CF4F3FE2CE3B0 /* LoginCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginCoordinator.swift; sourceTree = "<group>"; };
|
DD667C4BB98CF4F3FE2CE3B0 /* LoginCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginCoordinator.swift; sourceTree = "<group>"; };
|
||||||
DD73FAAA4A76CE4A1F3014D9 /* UserIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicator.swift; sourceTree = "<group>"; };
|
DD73FAAA4A76CE4A1F3014D9 /* UserIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicator.swift; sourceTree = "<group>"; };
|
||||||
DED59F9EFF273BFA2055FFDF /* BugReportScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreen.swift; sourceTree = "<group>"; };
|
DED59F9EFF273BFA2055FFDF /* BugReportScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreen.swift; sourceTree = "<group>"; };
|
||||||
|
DF05DA24F71B455E8EFEBC3B /* SessionVerificationViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
E077F76026C85ED96FEBB810 /* UserIndicatorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorPresenter.swift; sourceTree = "<group>"; };
|
E077F76026C85ED96FEBB810 /* UserIndicatorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorPresenter.swift; sourceTree = "<group>"; };
|
||||||
E0FCA0957FAA0E15A9F5579D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Untranslated.stringsdict; sourceTree = "<group>"; };
|
E0FCA0957FAA0E15A9F5579D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Untranslated.stringsdict; sourceTree = "<group>"; };
|
||||||
E157152B11E347F735C3FD6E /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = tr; path = tr.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
E157152B11E347F735C3FD6E /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = tr; path = tr.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
E18CF12478983A5EB390FB26 /* MessageComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageComposer.swift; sourceTree = "<group>"; };
|
E18CF12478983A5EB390FB26 /* MessageComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageComposer.swift; sourceTree = "<group>"; };
|
||||||
E2869CFFF6CD2A642AB4B743 /* TemplateCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateCoordinator.swift; sourceTree = "<group>"; };
|
|
||||||
E3E29F98CF0E960689A410E3 /* SettingsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUITests.swift; sourceTree = "<group>"; };
|
E3E29F98CF0E960689A410E3 /* SettingsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUITests.swift; sourceTree = "<group>"; };
|
||||||
E45C57120F28F8D619150219 /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sr; path = sr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
E45C57120F28F8D619150219 /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sr; path = sr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
E4BB9A17AC512A7EF4B106E5 /* SessionVerificationModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationModels.swift; sourceTree = "<group>"; };
|
||||||
E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = "<group>"; };
|
E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = "<group>"; };
|
||||||
E579A0DA01F488C97B771EF6 /* lv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = lv; path = lv.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
E579A0DA01F488C97B771EF6 /* lv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = lv; path = lv.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
E5D2C0950F8196232D88045C /* ServerSelectionScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreen.swift; sourceTree = "<group>"; };
|
E5D2C0950F8196232D88045C /* ServerSelectionScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreen.swift; sourceTree = "<group>"; };
|
||||||
@@ -634,6 +658,7 @@
|
|||||||
EBE5502760CF6CA2D7201883 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ja; path = ja.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
EBE5502760CF6CA2D7201883 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ja; path = ja.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = "<group>"; };
|
ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = "<group>"; };
|
||||||
EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionViewModelTests.swift; sourceTree = "<group>"; };
|
EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
|
EDB6E40BAD4504D899FAAC9A /* TemplateViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateViewModel.swift; sourceTree = "<group>"; };
|
||||||
EE8BCD14EFED23459A43FDFF /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
|
EE8BCD14EFED23459A43FDFF /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
EEE384418EB1FEDFA62C9CD0 /* RoomTimelineViewFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineViewFactoryProtocol.swift; sourceTree = "<group>"; };
|
EEE384418EB1FEDFA62C9CD0 /* RoomTimelineViewFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineViewFactoryProtocol.swift; sourceTree = "<group>"; };
|
||||||
EF188681D6B6068CFAEAFC3F /* MXLogger.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MXLogger.m; sourceTree = "<group>"; };
|
EF188681D6B6068CFAEAFC3F /* MXLogger.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MXLogger.m; sourceTree = "<group>"; };
|
||||||
@@ -651,12 +676,11 @@
|
|||||||
F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormattedBodyText.swift; sourceTree = "<group>"; };
|
F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormattedBodyText.swift; sourceTree = "<group>"; };
|
||||||
F77C060C2ACC4CB7336A29E7 /* EmoteRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItem.swift; sourceTree = "<group>"; };
|
F77C060C2ACC4CB7336A29E7 /* EmoteRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
F7B81C8227BBEA95CCE86037 /* MatrixEntitityRegex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixEntitityRegex.swift; sourceTree = "<group>"; };
|
F7B81C8227BBEA95CCE86037 /* MatrixEntitityRegex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixEntitityRegex.swift; sourceTree = "<group>"; };
|
||||||
F9BA045DC4CA12D030ACF558 /* TemplateScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreen.swift; sourceTree = "<group>"; };
|
|
||||||
F9E785D5137510481733A3E8 /* TextRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineView.swift; sourceTree = "<group>"; };
|
F9E785D5137510481733A3E8 /* TextRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||||
FA154570F693D93513E584C1 /* RoomMessageFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageFactory.swift; sourceTree = "<group>"; };
|
FA154570F693D93513E584C1 /* RoomMessageFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageFactory.swift; sourceTree = "<group>"; };
|
||||||
|
FAB10E673916D2B8D21FD197 /* TemplateModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModels.swift; sourceTree = "<group>"; };
|
||||||
FDB9C37196A4C79F24CE80C6 /* KeychainControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerTests.swift; sourceTree = "<group>"; };
|
FDB9C37196A4C79F24CE80C6 /* KeychainControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerTests.swift; sourceTree = "<group>"; };
|
||||||
FE2DF459F1737A594667CC46 /* EmoteRoomMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomMessage.swift; sourceTree = "<group>"; };
|
FE2DF459F1737A594667CC46 /* EmoteRoomMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomMessage.swift; sourceTree = "<group>"; };
|
||||||
FF4EDB32B97910AAAFE632B2 /* TemplateViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateViewModelProtocol.swift; sourceTree = "<group>"; };
|
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -735,6 +759,7 @@
|
|||||||
79E560F5113ED25D172E550C /* Media */,
|
79E560F5113ED25D172E550C /* Media */,
|
||||||
40E6246F03D1FE377BC5D963 /* Room */,
|
40E6246F03D1FE377BC5D963 /* Room */,
|
||||||
82D5AD3EAE3A5C1068A44A88 /* Session */,
|
82D5AD3EAE3A5C1068A44A88 /* Session */,
|
||||||
|
5329E48968EB951235E83DAE /* SessionVerification */,
|
||||||
FCDF06BDB123505F0334B4F9 /* Timeline */,
|
FCDF06BDB123505F0334B4F9 /* Timeline */,
|
||||||
90C85A862720155C0CF63B02 /* UserSessionStore */,
|
90C85A862720155C0CF63B02 /* UserSessionStore */,
|
||||||
);
|
);
|
||||||
@@ -753,6 +778,14 @@
|
|||||||
path = SupportingFiles;
|
path = SupportingFiles;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
0BA8C419737BDA72B553B129 /* View */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
8AC1A01C3A745BDF1D3697D3 /* SessionVerificationScreen.swift */,
|
||||||
|
);
|
||||||
|
path = View;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
0ED3F5C21537519389C07644 /* BugReport */ = {
|
0ED3F5C21537519389C07644 /* BugReport */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -915,7 +948,7 @@
|
|||||||
4AC3BA2B379A928301E21004 /* View */ = {
|
4AC3BA2B379A928301E21004 /* View */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
F9BA045DC4CA12D030ACF558 /* TemplateScreen.swift */,
|
4549FCB53F43DB0B278374BC /* TemplateScreen.swift */,
|
||||||
);
|
);
|
||||||
path = View;
|
path = View;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -945,6 +978,16 @@
|
|||||||
path = Scripts;
|
path = Scripts;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
5329E48968EB951235E83DAE /* SessionVerification */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D1A9CCCF53495CF3D7B19FCE /* MockSessionVerificationControllerProxy.swift */,
|
||||||
|
C55D7E514F9DE4E3D72FDCAD /* SessionVerificationControllerProxy.swift */,
|
||||||
|
1D56469A9EE0CFA2B7BA9760 /* SessionVerificationControllerProxyProtocol.swift */,
|
||||||
|
);
|
||||||
|
path = SessionVerification;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
58F951CB7BD7F96C37BE5CAD /* View */ = {
|
58F951CB7BD7F96C37BE5CAD /* View */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1020,7 +1063,7 @@
|
|||||||
73AB116809AE89292624CD8E /* Unit */ = {
|
73AB116809AE89292624CD8E /* Unit */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C08E9043618AE5B0BF7B07E1 /* TemplateViewModelTests.swift */,
|
3340ABAE3A4647E80163AE18 /* TemplateViewModelTests.swift */,
|
||||||
);
|
);
|
||||||
path = Unit;
|
path = Unit;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1042,6 +1085,8 @@
|
|||||||
93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */,
|
93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */,
|
||||||
F03C9D319676F3C0DC6B0203 /* ScreenshotDetectorTests.swift */,
|
F03C9D319676F3C0DC6B0203 /* ScreenshotDetectorTests.swift */,
|
||||||
EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */,
|
EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */,
|
||||||
|
A1C22B1B5FA3A765EADB2CC9 /* SessionVerificationStateMachineTests.swift */,
|
||||||
|
DF05DA24F71B455E8EFEBC3B /* SessionVerificationViewModelTests.swift */,
|
||||||
3D487C1185D658F8B15B8F55 /* SettingsViewModelTests.swift */,
|
3D487C1185D658F8B15B8F55 /* SettingsViewModelTests.swift */,
|
||||||
7B5CF94E124616FD89424B73 /* SplashScreenViewModelTests.swift */,
|
7B5CF94E124616FD89424B73 /* SplashScreenViewModelTests.swift */,
|
||||||
AF552BB969DC98A4BB8CF8D5 /* UserIndicators */,
|
AF552BB969DC98A4BB8CF8D5 /* UserIndicators */,
|
||||||
@@ -1073,10 +1118,10 @@
|
|||||||
789DD6B31BA8BB4B3A40EF7C /* ElementX */ = {
|
789DD6B31BA8BB4B3A40EF7C /* ElementX */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
E2869CFFF6CD2A642AB4B743 /* TemplateCoordinator.swift */,
|
DBD460ED7ED1E03B85DEA25C /* TemplateCoordinator.swift */,
|
||||||
A1C29670CEC77346F31EE94C /* TemplateModels.swift */,
|
FAB10E673916D2B8D21FD197 /* TemplateModels.swift */,
|
||||||
47543EB19F3DCF308751F53C /* TemplateViewModel.swift */,
|
EDB6E40BAD4504D899FAAC9A /* TemplateViewModel.swift */,
|
||||||
FF4EDB32B97910AAAFE632B2 /* TemplateViewModelProtocol.swift */,
|
2B80895CE021B49847BD7D74 /* TemplateViewModelProtocol.swift */,
|
||||||
4AC3BA2B379A928301E21004 /* View */,
|
4AC3BA2B379A928301E21004 /* View */,
|
||||||
);
|
);
|
||||||
path = ElementX;
|
path = ElementX;
|
||||||
@@ -1191,6 +1236,7 @@
|
|||||||
4D6E4C37E9F0E53D3DF951AC /* HomeScreenUITests.swift */,
|
4D6E4C37E9F0E53D3DF951AC /* HomeScreenUITests.swift */,
|
||||||
1DB34B0C74CD242FED9DD069 /* LoginScreenUITests.swift */,
|
1DB34B0C74CD242FED9DD069 /* LoginScreenUITests.swift */,
|
||||||
086B997409328F091EBA43CE /* RoomScreenUITests.swift */,
|
086B997409328F091EBA43CE /* RoomScreenUITests.swift */,
|
||||||
|
6D4777F0142E330A75C46FE4 /* SessionVerificationUITests.swift */,
|
||||||
E3E29F98CF0E960689A410E3 /* SettingsUITests.swift */,
|
E3E29F98CF0E960689A410E3 /* SettingsUITests.swift */,
|
||||||
325A2B3278875554DDEB8A9B /* SplashScreenUITests.swift */,
|
325A2B3278875554DDEB8A9B /* SplashScreenUITests.swift */,
|
||||||
);
|
);
|
||||||
@@ -1296,7 +1342,7 @@
|
|||||||
AD5FCF9340D670C526AD17E4 /* UI */ = {
|
AD5FCF9340D670C526AD17E4 /* UI */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
4B66E05B6009B0EB1BDBFA6E /* TemplateScreenUITests.swift */,
|
9873076F224E4CE09D8BD47D /* TemplateScreenUITests.swift */,
|
||||||
);
|
);
|
||||||
path = UI;
|
path = UI;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1389,6 +1435,19 @@
|
|||||||
path = Layout;
|
path = Layout;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
D958761758AA1110476DE6A3 /* SessionVerification */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CCF86010A0A719A9A50EEC59 /* SessionVerificationCoordinator.swift */,
|
||||||
|
E4BB9A17AC512A7EF4B106E5 /* SessionVerificationModels.swift */,
|
||||||
|
C06FCD42EEFEFC220F14EAC5 /* SessionVerificationStateMachine.swift */,
|
||||||
|
B4C18FAAD59AE7F1462D817E /* SessionVerificationViewModel.swift */,
|
||||||
|
B3069ADED46D063202FE7698 /* SessionVerificationViewModelProtocol.swift */,
|
||||||
|
0BA8C419737BDA72B553B129 /* View */,
|
||||||
|
);
|
||||||
|
path = SessionVerification;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
E59565F441830B19DBAE567C /* Screens */ = {
|
E59565F441830B19DBAE567C /* Screens */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1396,6 +1455,7 @@
|
|||||||
4009BE2E791C16AC6EE39A7E /* BugReport */,
|
4009BE2E791C16AC6EE39A7E /* BugReport */,
|
||||||
B53CA9BECD3F97805E1432D0 /* HomeScreen */,
|
B53CA9BECD3F97805E1432D0 /* HomeScreen */,
|
||||||
679E9837ECA8D6776079D16E /* RoomScreen */,
|
679E9837ECA8D6776079D16E /* RoomScreen */,
|
||||||
|
D958761758AA1110476DE6A3 /* SessionVerification */,
|
||||||
70B74A432C241E56A7ACE610 /* Settings */,
|
70B74A432C241E56A7ACE610 /* Settings */,
|
||||||
02175C9269C4632DB6D12C25 /* Splash */,
|
02175C9269C4632DB6D12C25 /* Splash */,
|
||||||
B1A847595434E3DD177F5143 /* SplashScreen */,
|
B1A847595434E3DD177F5143 /* SplashScreen */,
|
||||||
@@ -1604,7 +1664,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = 7AE41FCCF9D1352E2770D1F9 /* Build configuration list for PBXProject "ElementX" */;
|
buildConfigurationList = 7AE41FCCF9D1352E2770D1F9 /* Build configuration list for PBXProject "ElementX" */;
|
||||||
compatibilityVersion = "Xcode 11.0";
|
compatibilityVersion = "Xcode 10.0";
|
||||||
developmentRegion = en;
|
developmentRegion = en;
|
||||||
hasScannedForEncodings = 0;
|
hasScannedForEncodings = 0;
|
||||||
knownRegions = (
|
knownRegions = (
|
||||||
@@ -1808,9 +1868,11 @@
|
|||||||
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */,
|
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */,
|
||||||
EA31DD9043B91ECB8E45A9A6 /* ScreenshotDetectorTests.swift in Sources */,
|
EA31DD9043B91ECB8E45A9A6 /* ScreenshotDetectorTests.swift in Sources */,
|
||||||
93875ADD456142D20823ED24 /* ServerSelectionViewModelTests.swift in Sources */,
|
93875ADD456142D20823ED24 /* ServerSelectionViewModelTests.swift in Sources */,
|
||||||
|
86675910612A12409262DFBD /* SessionVerificationStateMachineTests.swift in Sources */,
|
||||||
|
755727E0B756430DFFEC4732 /* SessionVerificationViewModelTests.swift in Sources */,
|
||||||
206F0DBAB6AF042CA1FF2C0D /* SettingsViewModelTests.swift in Sources */,
|
206F0DBAB6AF042CA1FF2C0D /* SettingsViewModelTests.swift in Sources */,
|
||||||
94E062D08E27B0387658E364 /* SplashScreenViewModelTests.swift in Sources */,
|
94E062D08E27B0387658E364 /* SplashScreenViewModelTests.swift in Sources */,
|
||||||
E75CE800B3E64D0F7F8E228D /* TemplateViewModelTests.swift in Sources */,
|
7AE1FFB132F2B84EB8A2AEBC /* TemplateViewModelTests.swift in Sources */,
|
||||||
226027BE23AF64FA61C7A4C0 /* TimelineStyle.swift in Sources */,
|
226027BE23AF64FA61C7A4C0 /* TimelineStyle.swift in Sources */,
|
||||||
1151DCC5EC2C6585826545EC /* UserIndicatorPresenterSpy.swift in Sources */,
|
1151DCC5EC2C6585826545EC /* UserIndicatorPresenterSpy.swift in Sources */,
|
||||||
4B8A2C45FF906ADBB1F5C3B4 /* UserIndicatorQueueTests.swift in Sources */,
|
4B8A2C45FF906ADBB1F5C3B4 /* UserIndicatorQueueTests.swift in Sources */,
|
||||||
@@ -1907,6 +1969,7 @@
|
|||||||
29AEE68A604940180AB9EBFF /* MockRoomSummary.swift in Sources */,
|
29AEE68A604940180AB9EBFF /* MockRoomSummary.swift in Sources */,
|
||||||
E81EEC1675F2371D12A880A3 /* MockRoomTimelineController.swift in Sources */,
|
E81EEC1675F2371D12A880A3 /* MockRoomTimelineController.swift in Sources */,
|
||||||
9BE7A9CF6C593251D734B461 /* MockServerSelectionScreenState.swift in Sources */,
|
9BE7A9CF6C593251D734B461 /* MockServerSelectionScreenState.swift in Sources */,
|
||||||
|
D034A195A3494E38BF060485 /* MockSessionVerificationControllerProxy.swift in Sources */,
|
||||||
4ED453A61AF45EBE18D8BC69 /* NavigationModule.swift in Sources */,
|
4ED453A61AF45EBE18D8BC69 /* NavigationModule.swift in Sources */,
|
||||||
22DADD537401E79D66132134 /* NavigationRouter.swift in Sources */,
|
22DADD537401E79D66132134 /* NavigationRouter.swift in Sources */,
|
||||||
12F70C493FB69F4D7E9A37EA /* NavigationRouterStore.swift in Sources */,
|
12F70C493FB69F4D7E9A37EA /* NavigationRouterStore.swift in Sources */,
|
||||||
@@ -1953,6 +2016,14 @@
|
|||||||
388FD50AC66E9E684DDFA9D8 /* ServerSelectionScreen.swift in Sources */,
|
388FD50AC66E9E684DDFA9D8 /* ServerSelectionScreen.swift in Sources */,
|
||||||
BB01CC19C3D3322308D1B2CF /* ServerSelectionViewModel.swift in Sources */,
|
BB01CC19C3D3322308D1B2CF /* ServerSelectionViewModel.swift in Sources */,
|
||||||
19839F3526CE8C35AAF241AD /* ServerSelectionViewModelProtocol.swift in Sources */,
|
19839F3526CE8C35AAF241AD /* ServerSelectionViewModelProtocol.swift in Sources */,
|
||||||
|
237FC70AA257B935F53316BA /* SessionVerificationControllerProxy.swift in Sources */,
|
||||||
|
94A65DD8A353DF112EBEF67A /* SessionVerificationControllerProxyProtocol.swift in Sources */,
|
||||||
|
E5895C74615CBE8462FB840F /* SessionVerificationCoordinator.swift in Sources */,
|
||||||
|
0C38C3E771B472E27295339D /* SessionVerificationModels.swift in Sources */,
|
||||||
|
BB6B0B91CE11E06330017000 /* SessionVerificationScreen.swift in Sources */,
|
||||||
|
9E8AE387FD03E4F1C1B8815A /* SessionVerificationStateMachine.swift in Sources */,
|
||||||
|
A8EC7C9D886244DAE9433E37 /* SessionVerificationViewModel.swift in Sources */,
|
||||||
|
D6417E5A799C3C7F14F9EC0A /* SessionVerificationViewModelProtocol.swift in Sources */,
|
||||||
34966D4C1C2C6D37FE3F7F50 /* SettingsCoordinator.swift in Sources */,
|
34966D4C1C2C6D37FE3F7F50 /* SettingsCoordinator.swift in Sources */,
|
||||||
3B770CB4DED51CC362C66D47 /* SettingsModels.swift in Sources */,
|
3B770CB4DED51CC362C66D47 /* SettingsModels.swift in Sources */,
|
||||||
7FED310F6AB7A70CBFB7C8A3 /* SettingsScreen.swift in Sources */,
|
7FED310F6AB7A70CBFB7C8A3 /* SettingsScreen.swift in Sources */,
|
||||||
@@ -1970,11 +2041,11 @@
|
|||||||
2F94054F50E312AF30BE07F3 /* String.swift in Sources */,
|
2F94054F50E312AF30BE07F3 /* String.swift in Sources */,
|
||||||
A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */,
|
A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */,
|
||||||
066A1E9B94723EE9F3038044 /* Strings.swift in Sources */,
|
066A1E9B94723EE9F3038044 /* Strings.swift in Sources */,
|
||||||
5CABC57F620FBB39F4EC127C /* TemplateScreen.swift in Sources */,
|
43FD77998F33C32718C51450 /* TemplateCoordinator.swift in Sources */,
|
||||||
C1156BBE4F977AEEE1E80C48 /* TemplateCoordinator.swift in Sources */,
|
63C9AF0FB8278AF1C0388A0C /* TemplateModels.swift in Sources */,
|
||||||
B0EDAF55877DE19B67837C22 /* TemplateModels.swift in Sources */,
|
1555A7643D85187D4851040C /* TemplateScreen.swift in Sources */,
|
||||||
ED4F663C783E9A8C0E80B983 /* TemplateViewModel.swift in Sources */,
|
75EA4ABBFAA810AFF289D6F4 /* TemplateViewModel.swift in Sources */,
|
||||||
3772354754450F2B54107E17 /* TemplateViewModelProtocol.swift in Sources */,
|
5F1FDE49DFD0C680386E48F9 /* TemplateViewModelProtocol.swift in Sources */,
|
||||||
D013E70C8E28E43497820444 /* TextRoomMessage.swift in Sources */,
|
D013E70C8E28E43497820444 /* TextRoomMessage.swift in Sources */,
|
||||||
7963F98CDFDEAC75E072BD81 /* TextRoomTimelineItem.swift in Sources */,
|
7963F98CDFDEAC75E072BD81 /* TextRoomTimelineItem.swift in Sources */,
|
||||||
5E0F2E612718BB4397A6D40A /* TextRoomTimelineView.swift in Sources */,
|
5E0F2E612718BB4397A6D40A /* TextRoomTimelineView.swift in Sources */,
|
||||||
@@ -2026,11 +2097,12 @@
|
|||||||
9DC5FB22B8F86C3B51E907C1 /* HomeScreenUITests.swift in Sources */,
|
9DC5FB22B8F86C3B51E907C1 /* HomeScreenUITests.swift in Sources */,
|
||||||
5C8AFBF168A41E20835F3B86 /* LoginScreenUITests.swift in Sources */,
|
5C8AFBF168A41E20835F3B86 /* LoginScreenUITests.swift in Sources */,
|
||||||
2F1CF90A3460C153154427F0 /* RoomScreenUITests.swift in Sources */,
|
2F1CF90A3460C153154427F0 /* RoomScreenUITests.swift in Sources */,
|
||||||
|
05EC896A4B9AF4A56670C0BB /* SessionVerificationUITests.swift in Sources */,
|
||||||
490E606044B18985055FF690 /* SettingsUITests.swift in Sources */,
|
490E606044B18985055FF690 /* SettingsUITests.swift in Sources */,
|
||||||
A00DFC1DD3567B1EDC9F8D16 /* SplashScreenUITests.swift in Sources */,
|
A00DFC1DD3567B1EDC9F8D16 /* SplashScreenUITests.swift in Sources */,
|
||||||
DD9B70DE54B24E0694A35D8A /* Strings+Untranslated.swift in Sources */,
|
DD9B70DE54B24E0694A35D8A /* Strings+Untranslated.swift in Sources */,
|
||||||
B3357B00F1AA930E54F76609 /* Strings.swift in Sources */,
|
B3357B00F1AA930E54F76609 /* Strings.swift in Sources */,
|
||||||
2E68C57E7D644E94778743D5 /* TemplateScreenUITests.swift in Sources */,
|
C4180F418235DAD9DD173951 /* TemplateScreenUITests.swift in Sources */,
|
||||||
0ED951768EC443A8728DE1D7 /* TimelineStyle.swift in Sources */,
|
0ED951768EC443A8728DE1D7 /* TimelineStyle.swift in Sources */,
|
||||||
75D98001C5AC38B6A5CA897C /* UITestScreenIdentifier.swift in Sources */,
|
75D98001C5AC38B6A5CA897C /* UITestScreenIdentifier.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,11 +7,12 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import Combine
|
||||||
|
|
||||||
class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
||||||
private let window: UIWindow
|
private let window: UIWindow
|
||||||
|
|
||||||
private var stateMachine: AppCoordinatorStateMachine
|
private let stateMachine: AppCoordinatorStateMachine
|
||||||
|
|
||||||
private let mainNavigationController: UINavigationController
|
private let mainNavigationController: UINavigationController
|
||||||
private let splashViewController: UIViewController
|
private let splashViewController: UIViewController
|
||||||
@@ -142,10 +143,17 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
self.tearDownUserSession()
|
self.tearDownUserSession()
|
||||||
case (.signingOut, .failedSigningOut, _):
|
case (.signingOut, .failedSigningOut, _):
|
||||||
self.showLogoutErrorToast()
|
self.showLogoutErrorToast()
|
||||||
|
|
||||||
case (.homeScreen, .showSettingsScreen, .settingsScreen):
|
case (.homeScreen, .showSettingsScreen, .settingsScreen):
|
||||||
self.presentSettingsScreen()
|
self.presentSettingsScreen()
|
||||||
case (.settingsScreen, .dismissedSettingsScreen, .homeScreen):
|
case (.settingsScreen, .dismissedSettingsScreen, .homeScreen):
|
||||||
self.tearDownDismissedSettingsScreen()
|
self.tearDownDismissedSettingsScreen()
|
||||||
|
|
||||||
|
case (.homeScreen, .showSessionVerificationScreen, .sessionVerificationScreen):
|
||||||
|
self.presentSessionVerification()
|
||||||
|
case (.sessionVerificationScreen, .dismissedSessionVerificationScreen, .homeScreen):
|
||||||
|
self.tearDownDismissedSessionVerificationScreen()
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fatalError("Unknown transition: \(context)")
|
fatalError("Unknown transition: \(context)")
|
||||||
}
|
}
|
||||||
@@ -205,6 +213,8 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
self.stateMachine.processEvent(.showRoomScreen(roomId: roomIdentifier))
|
self.stateMachine.processEvent(.showRoomScreen(roomId: roomIdentifier))
|
||||||
case .presentSettings:
|
case .presentSettings:
|
||||||
self.stateMachine.processEvent(.showSettingsScreen)
|
self.stateMachine.processEvent(.showSettingsScreen)
|
||||||
|
case .verifySession:
|
||||||
|
self.stateMachine.processEvent(.showSessionVerificationScreen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,26 +226,7 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func presentSettingsScreen() {
|
// MARK: Rooms
|
||||||
let parameters = SettingsCoordinatorParameters(navigationRouter: navigationRouter,
|
|
||||||
bugReportService: bugReportService)
|
|
||||||
let coordinator = SettingsCoordinator(parameters: parameters)
|
|
||||||
coordinator.callback = { [weak self] action in
|
|
||||||
guard let self = self else { return }
|
|
||||||
switch action {
|
|
||||||
case .logout:
|
|
||||||
self.stateMachine.processEvent(.attemptSignOut)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
add(childCoordinator: coordinator)
|
|
||||||
coordinator.start()
|
|
||||||
navigationRouter.push(coordinator) { [weak self] in
|
|
||||||
guard let self = self else { return }
|
|
||||||
|
|
||||||
self.stateMachine.processEvent(.dismissedSettingsScreen)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func presentRoomWithIdentifier(_ roomIdentifier: String) {
|
private func presentRoomWithIdentifier(_ roomIdentifier: String) {
|
||||||
guard let roomProxy = userSession.clientProxy.rooms.first(where: { $0.id == roomIdentifier }) else {
|
guard let roomProxy = userSession.clientProxy.rooms.first(where: { $0.id == roomIdentifier }) else {
|
||||||
@@ -277,6 +268,29 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
remove(childCoordinator: coordinator)
|
remove(childCoordinator: coordinator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Settings
|
||||||
|
|
||||||
|
private func presentSettingsScreen() {
|
||||||
|
let parameters = SettingsCoordinatorParameters(navigationRouter: navigationRouter,
|
||||||
|
bugReportService: bugReportService)
|
||||||
|
let coordinator = SettingsCoordinator(parameters: parameters)
|
||||||
|
coordinator.callback = { [weak self] action in
|
||||||
|
guard let self = self else { return }
|
||||||
|
switch action {
|
||||||
|
case .logout:
|
||||||
|
self.stateMachine.processEvent(.attemptSignOut)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add(childCoordinator: coordinator)
|
||||||
|
coordinator.start()
|
||||||
|
navigationRouter.push(coordinator) { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
self.stateMachine.processEvent(.dismissedSettingsScreen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func tearDownDismissedSettingsScreen() {
|
private func tearDownDismissedSettingsScreen() {
|
||||||
guard let coordinator = childCoordinators.last as? SettingsCoordinator else {
|
guard let coordinator = childCoordinators.last as? SettingsCoordinator else {
|
||||||
fatalError("Invalid coordinator hierarchy: \(childCoordinators)")
|
fatalError("Invalid coordinator hierarchy: \(childCoordinators)")
|
||||||
@@ -285,22 +299,6 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
remove(childCoordinator: coordinator)
|
remove(childCoordinator: coordinator)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func showLoadingIndicator() {
|
|
||||||
loadingIndicator = indicatorPresenter.present(.loading(label: ElementL10n.loading, isInteractionBlocking: true))
|
|
||||||
}
|
|
||||||
|
|
||||||
private func hideLoadingIndicator() {
|
|
||||||
loadingIndicator = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
private func showLoginErrorToast() {
|
|
||||||
statusIndicator = indicatorPresenter.present(.error(label: "Failed logging in"))
|
|
||||||
}
|
|
||||||
|
|
||||||
private func showLogoutErrorToast() {
|
|
||||||
statusIndicator = indicatorPresenter.present(.error(label: "Failed logging out"))
|
|
||||||
}
|
|
||||||
|
|
||||||
private func showCrashPopup() {
|
private func showCrashPopup() {
|
||||||
let alert = UIAlertController(title: nil,
|
let alert = UIAlertController(title: nil,
|
||||||
message: ElementL10n.sendBugReportAppCrashed,
|
message: ElementL10n.sendBugReportAppCrashed,
|
||||||
@@ -360,4 +358,54 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
navigationRouter.dismissModule()
|
navigationRouter.dismissModule()
|
||||||
remove(childCoordinator: bugReportCoordinator)
|
remove(childCoordinator: bugReportCoordinator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Session verification
|
||||||
|
|
||||||
|
private func presentSessionVerification() {
|
||||||
|
Task {
|
||||||
|
guard let sessionVerificationController = userSession.sessionVerificationController else {
|
||||||
|
fatalError("The sessionVerificationController should aways be valid at this point")
|
||||||
|
}
|
||||||
|
|
||||||
|
let parameters = SessionVerificationCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController)
|
||||||
|
|
||||||
|
let coordinator = SessionVerificationCoordinator(parameters: parameters)
|
||||||
|
|
||||||
|
coordinator.callback = { [weak self] in
|
||||||
|
self?.navigationRouter.dismissModule()
|
||||||
|
self?.stateMachine.processEvent(.dismissedSessionVerificationScreen)
|
||||||
|
}
|
||||||
|
|
||||||
|
add(childCoordinator: coordinator)
|
||||||
|
navigationRouter.present(coordinator)
|
||||||
|
|
||||||
|
coordinator.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func tearDownDismissedSessionVerificationScreen() {
|
||||||
|
guard let coordinator = childCoordinators.last as? SessionVerificationCoordinator else {
|
||||||
|
fatalError("Invalid coordinator hierarchy: \(childCoordinators)")
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(childCoordinator: coordinator)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Toasts and loading indicators
|
||||||
|
|
||||||
|
private func showLoadingIndicator() {
|
||||||
|
loadingIndicator = indicatorPresenter.present(.loading(label: ElementL10n.loading, isInteractionBlocking: true))
|
||||||
|
}
|
||||||
|
|
||||||
|
private func hideLoadingIndicator() {
|
||||||
|
loadingIndicator = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
private func showLoginErrorToast() {
|
||||||
|
statusIndicator = indicatorPresenter.present(.error(label: "Failed logging in"))
|
||||||
|
}
|
||||||
|
|
||||||
|
private func showLogoutErrorToast() {
|
||||||
|
statusIndicator = indicatorPresenter.present(.error(label: "Failed logging out"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,17 @@ class AppCoordinatorStateMachine {
|
|||||||
case restoringSession
|
case restoringSession
|
||||||
/// Showing the home screen
|
/// Showing the home screen
|
||||||
case homeScreen
|
case homeScreen
|
||||||
/// Showing the settings screen
|
|
||||||
case settingsScreen
|
|
||||||
/// Showing a particular room's timeline
|
/// Showing a particular room's timeline
|
||||||
/// - Parameter roomId: that room's identifier
|
/// - Parameter roomId: that room's identifier
|
||||||
case roomScreen(roomId: String)
|
case roomScreen(roomId: String)
|
||||||
|
|
||||||
|
/// Showing the session verification flows
|
||||||
|
case sessionVerificationScreen
|
||||||
|
|
||||||
|
/// Showing the settings screen
|
||||||
|
case settingsScreen
|
||||||
|
|
||||||
/// Processing a sign out request
|
/// Processing a sign out request
|
||||||
case signingOut
|
case signingOut
|
||||||
}
|
}
|
||||||
@@ -61,10 +67,16 @@ class AppCoordinatorStateMachine {
|
|||||||
case showRoomScreen(roomId: String)
|
case showRoomScreen(roomId: String)
|
||||||
/// The room screen has been dismissed
|
/// The room screen has been dismissed
|
||||||
case dismissedRoomScreen
|
case dismissedRoomScreen
|
||||||
/// The settings screen has been dismissed
|
|
||||||
case dismissedSettingsScreen
|
/// Request the start of the session verification flow
|
||||||
|
case showSessionVerificationScreen
|
||||||
|
/// Session verification has finished
|
||||||
|
case dismissedSessionVerificationScreen
|
||||||
|
|
||||||
/// Request settings screen presentation
|
/// Request settings screen presentation
|
||||||
case showSettingsScreen
|
case showSettingsScreen
|
||||||
|
/// The settings screen has been dismissed
|
||||||
|
case dismissedSettingsScreen
|
||||||
}
|
}
|
||||||
|
|
||||||
private let stateMachine: StateMachine<State, Event>
|
private let stateMachine: StateMachine<State, Event>
|
||||||
@@ -84,9 +96,13 @@ class AppCoordinatorStateMachine {
|
|||||||
|
|
||||||
machine.addRoutes(event: .succeededSigningOut, transitions: [ .signingOut => .signedOut ])
|
machine.addRoutes(event: .succeededSigningOut, transitions: [ .signingOut => .signedOut ])
|
||||||
machine.addRoutes(event: .failedSigningOut, transitions: [ .signingOut => .settingsScreen ])
|
machine.addRoutes(event: .failedSigningOut, transitions: [ .signingOut => .settingsScreen ])
|
||||||
|
|
||||||
machine.addRoutes(event: .showSettingsScreen, transitions: [ .homeScreen => .settingsScreen ])
|
machine.addRoutes(event: .showSettingsScreen, transitions: [ .homeScreen => .settingsScreen ])
|
||||||
machine.addRoutes(event: .dismissedSettingsScreen, transitions: [ .settingsScreen => .homeScreen ])
|
machine.addRoutes(event: .dismissedSettingsScreen, transitions: [ .settingsScreen => .homeScreen ])
|
||||||
|
|
||||||
|
machine.addRoutes(event: .showSessionVerificationScreen, transitions: [ .homeScreen => .sessionVerificationScreen ])
|
||||||
|
machine.addRoutes(event: .dismissedSessionVerificationScreen, transitions: [ .sessionVerificationScreen => .homeScreen ])
|
||||||
|
|
||||||
// Transitions with associated values need to be handled through `addRouteMapping`
|
// Transitions with associated values need to be handled through `addRouteMapping`
|
||||||
machine.addRouteMapping { event, fromState, _ in
|
machine.addRouteMapping { event, fromState, _ in
|
||||||
switch (event, fromState) {
|
switch (event, fromState) {
|
||||||
|
|||||||
@@ -62,6 +62,12 @@ struct ImageAnonymizer {
|
|||||||
// revision3 doesn't work!
|
// revision3 doesn't work!
|
||||||
faceRequest.revision = VNDetectFaceRectanglesRequestRevision2
|
faceRequest.revision = VNDetectFaceRectanglesRequestRevision2
|
||||||
|
|
||||||
|
#if targetEnvironment(simulator)
|
||||||
|
// Avoid `Could not create inference context` errors on Apple Silicon
|
||||||
|
// https://www.caseyliss.com/2022/6/20/feedback-is-broken-stop-trying-to-make-radar-happen
|
||||||
|
faceRequest.usesCPUOnly = true
|
||||||
|
#endif
|
||||||
|
|
||||||
// perform requests
|
// perform requests
|
||||||
try handler.perform([
|
try handler.perform([
|
||||||
textRequest,
|
textRequest,
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ struct HomeScreenCoordinatorParameters {
|
|||||||
enum HomeScreenCoordinatorAction {
|
enum HomeScreenCoordinatorAction {
|
||||||
case presentRoom(roomIdentifier: String)
|
case presentRoom(roomIdentifier: String)
|
||||||
case presentSettings
|
case presentSettings
|
||||||
|
case verifySession
|
||||||
}
|
}
|
||||||
|
|
||||||
final class HomeScreenCoordinator: Coordinator, Presentable {
|
final class HomeScreenCoordinator: Coordinator, Presentable {
|
||||||
@@ -66,19 +67,31 @@ final class HomeScreenCoordinator: Coordinator, Presentable {
|
|||||||
self.callback?(.presentRoom(roomIdentifier: roomIdentifier))
|
self.callback?(.presentRoom(roomIdentifier: roomIdentifier))
|
||||||
case .tapUserAvatar:
|
case .tapUserAvatar:
|
||||||
self.callback?(.presentSettings)
|
self.callback?(.presentSettings)
|
||||||
|
case .verifySession:
|
||||||
|
self.callback?(.verifySession)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters.userSession.clientProxy
|
parameters.userSession.clientProxy
|
||||||
.callbacks
|
.callbacks
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] action in
|
.sink { [weak self] callback in
|
||||||
switch action {
|
if case .updatedRoomsList = callback {
|
||||||
case .updatedRoomsList:
|
|
||||||
self?.updateRoomsList()
|
self?.updateRoomsList()
|
||||||
}
|
}
|
||||||
}.store(in: &cancellables)
|
}.store(in: &cancellables)
|
||||||
|
|
||||||
|
parameters.userSession.callbacks
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink { [weak self] callback in
|
||||||
|
switch callback {
|
||||||
|
case .sessionVerificationNeeded:
|
||||||
|
self?.viewModel.showSessionVerificationBanner()
|
||||||
|
case .didVerifySession:
|
||||||
|
self?.viewModel.hideSessionVerificationBanner()
|
||||||
|
}
|
||||||
|
}.store(in: &cancellables)
|
||||||
|
|
||||||
updateRoomsList()
|
updateRoomsList()
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
|
|||||||
@@ -20,18 +20,22 @@ import UIKit
|
|||||||
enum HomeScreenViewModelAction {
|
enum HomeScreenViewModelAction {
|
||||||
case selectRoom(roomIdentifier: String)
|
case selectRoom(roomIdentifier: String)
|
||||||
case tapUserAvatar
|
case tapUserAvatar
|
||||||
|
case verifySession
|
||||||
}
|
}
|
||||||
|
|
||||||
enum HomeScreenViewAction {
|
enum HomeScreenViewAction {
|
||||||
case loadRoomData(roomIdentifier: String)
|
case loadRoomData(roomIdentifier: String)
|
||||||
case selectRoom(roomIdentifier: String)
|
case selectRoom(roomIdentifier: String)
|
||||||
case tapUserAvatar
|
case tapUserAvatar
|
||||||
|
case verifySession
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HomeScreenViewState: BindableState {
|
struct HomeScreenViewState: BindableState {
|
||||||
var userDisplayName: String?
|
var userDisplayName: String?
|
||||||
var userAvatar: UIImage?
|
var userAvatar: UIImage?
|
||||||
|
|
||||||
|
var showSessionVerificationBanner: Bool = false
|
||||||
|
|
||||||
var rooms: [HomeScreenRoom] = []
|
var rooms: [HomeScreenRoom] = []
|
||||||
|
|
||||||
var isLoadingRooms: Bool = false
|
var isLoadingRooms: Bool = false
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
|
|
||||||
private var roomSummaries: [RoomSummaryProtocol]? {
|
private var roomSummaries: [RoomSummaryProtocol]? {
|
||||||
didSet {
|
didSet {
|
||||||
self.state.isLoadingRooms = (roomSummaries?.count ?? 0 == 0)
|
state.isLoadingRooms = (roomSummaries?.count ?? 0 == 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,6 +51,8 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
callback?(.selectRoom(roomIdentifier: roomIdentifier))
|
callback?(.selectRoom(roomIdentifier: roomIdentifier))
|
||||||
case .tapUserAvatar:
|
case .tapUserAvatar:
|
||||||
callback?(.tapUserAvatar)
|
callback?(.tapUserAvatar)
|
||||||
|
case .verifySession:
|
||||||
|
callback?(.verifySession)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,11 +86,19 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateWithUserAvatar(_ avatar: UIImage) {
|
func updateWithUserAvatar(_ avatar: UIImage) {
|
||||||
self.state.userAvatar = avatar
|
state.userAvatar = avatar
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateWithUserDisplayName(_ displayName: String) {
|
func updateWithUserDisplayName(_ displayName: String) {
|
||||||
self.state.userDisplayName = displayName
|
state.userDisplayName = displayName
|
||||||
|
}
|
||||||
|
|
||||||
|
func showSessionVerificationBanner() {
|
||||||
|
state.showSessionVerificationBanner = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func hideSessionVerificationBanner() {
|
||||||
|
state.showSessionVerificationBanner = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
@@ -105,7 +115,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
private func buildOrUpdateRoomFromSummary(_ roomSummary: RoomSummaryProtocol) -> HomeScreenRoom {
|
private func buildOrUpdateRoomFromSummary(_ roomSummary: RoomSummaryProtocol) -> HomeScreenRoom {
|
||||||
let lastMessage = lastMessageFromEventBrief(roomSummary.lastMessage)
|
let lastMessage = lastMessageFromEventBrief(roomSummary.lastMessage)
|
||||||
|
|
||||||
guard var room = self.state.rooms.first(where: { $0.id == roomSummary.id }) else {
|
guard var room = state.rooms.first(where: { $0.id == roomSummary.id }) else {
|
||||||
return HomeScreenRoom(id: roomSummary.id,
|
return HomeScreenRoom(id: roomSummary.id,
|
||||||
displayName: roomSummary.displayName,
|
displayName: roomSummary.displayName,
|
||||||
topic: roomSummary.topic,
|
topic: roomSummary.topic,
|
||||||
|
|||||||
@@ -26,4 +26,7 @@ protocol HomeScreenViewModelProtocol {
|
|||||||
func updateWithUserAvatar(_ avatar: UIImage)
|
func updateWithUserAvatar(_ avatar: UIImage)
|
||||||
func updateWithUserDisplayName(_ displayName: String)
|
func updateWithUserDisplayName(_ displayName: String)
|
||||||
func updateWithRoomSummaries(_ roomSummaries: [RoomSummaryProtocol])
|
func updateWithRoomSummaries(_ roomSummaries: [RoomSummaryProtocol])
|
||||||
|
|
||||||
|
func showSessionVerificationBanner()
|
||||||
|
func hideSessionVerificationBanner()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,13 +23,27 @@ struct HomeScreen: View {
|
|||||||
// MARK: Views
|
// MARK: Views
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: 16.0) {
|
VStack(spacing: 0.0) {
|
||||||
if context.viewState.isLoadingRooms {
|
if context.viewState.isLoadingRooms {
|
||||||
VStack {
|
VStack {
|
||||||
Text(ElementL10n.loading)
|
Text(ElementL10n.loading)
|
||||||
ProgressView()
|
ProgressView()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if context.viewState.showSessionVerificationBanner {
|
||||||
|
HStack {
|
||||||
|
Text(ElementL10n.verificationVerifyDevice)
|
||||||
|
Spacer()
|
||||||
|
Button(ElementL10n.startVerification) {
|
||||||
|
context.send(viewAction: .verifySession)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.background(Color.element.quaternaryContent)
|
||||||
|
.padding(.top, 1)
|
||||||
|
}
|
||||||
|
|
||||||
List {
|
List {
|
||||||
Section(ElementL10n.rooms) {
|
Section(ElementL10n.rooms) {
|
||||||
ForEach(context.viewState.visibleRooms) { room in
|
ForEach(context.viewState.visibleRooms) { room in
|
||||||
@@ -52,6 +66,8 @@ struct HomeScreen: View {
|
|||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
.background(Color.element.background)
|
.background(Color.element.background)
|
||||||
|
.transition(.slide)
|
||||||
|
.animation(.default, value: context.viewState.showSessionVerificationBanner)
|
||||||
.ignoresSafeArea(.all, edges: .bottom)
|
.ignoresSafeArea(.all, edges: .bottom)
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
@@ -100,6 +116,8 @@ struct HomeScreen: View {
|
|||||||
|
|
||||||
struct RoomCell: View {
|
struct RoomCell: View {
|
||||||
|
|
||||||
|
@ScaledMetric private var avatarSize = 32.0
|
||||||
|
|
||||||
let room: HomeScreenRoom
|
let room: HomeScreenRoom
|
||||||
let context: HomeScreenViewModel.Context
|
let context: HomeScreenViewModel.Context
|
||||||
|
|
||||||
@@ -112,12 +130,12 @@ struct RoomCell: View {
|
|||||||
Image(uiImage: avatar)
|
Image(uiImage: avatar)
|
||||||
.resizable()
|
.resizable()
|
||||||
.scaledToFill()
|
.scaledToFill()
|
||||||
.frame(width: 40, height: 40)
|
.frame(width: avatarSize, height: avatarSize)
|
||||||
.clipShape(Circle())
|
.clipShape(Circle())
|
||||||
} else {
|
} else {
|
||||||
PlaceholderAvatarImage(text: room.displayName ?? room.id)
|
PlaceholderAvatarImage(text: room.displayName ?? room.id)
|
||||||
.clipShape(Circle())
|
.clipShape(Circle())
|
||||||
.frame(width: 40, height: 40)
|
.frame(width: avatarSize, height: avatarSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 2.0) {
|
VStack(alignment: .leading, spacing: 2.0) {
|
||||||
@@ -182,6 +200,8 @@ struct HomeScreen_Previews: PreviewProvider {
|
|||||||
viewModel.updateWithUserAvatar(avatarImage)
|
viewModel.updateWithUserAvatar(avatarImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.showSessionVerificationBanner()
|
||||||
|
|
||||||
return NavigationView {
|
return NavigationView {
|
||||||
HomeScreen(context: viewModel.context)
|
HomeScreen(context: viewModel.context)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2021 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 SessionVerificationCoordinatorParameters {
|
||||||
|
let sessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol
|
||||||
|
}
|
||||||
|
|
||||||
|
final class SessionVerificationCoordinator: Coordinator, Presentable {
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
// MARK: Private
|
||||||
|
|
||||||
|
private let parameters: SessionVerificationCoordinatorParameters
|
||||||
|
private let sessionVerificationHostingController: UIViewController
|
||||||
|
private var sessionVerificationViewModel: SessionVerificationViewModelProtocol
|
||||||
|
|
||||||
|
// MARK: Public
|
||||||
|
|
||||||
|
// Must be used only internally
|
||||||
|
var childCoordinators: [Coordinator] = []
|
||||||
|
var callback: (() -> Void)?
|
||||||
|
|
||||||
|
// MARK: - Setup
|
||||||
|
|
||||||
|
init(parameters: SessionVerificationCoordinatorParameters) {
|
||||||
|
self.parameters = parameters
|
||||||
|
|
||||||
|
let viewModel = SessionVerificationViewModel(sessionVerificationControllerProxy: parameters.sessionVerificationControllerProxy)
|
||||||
|
let view = SessionVerificationScreen(context: viewModel.context)
|
||||||
|
sessionVerificationViewModel = viewModel
|
||||||
|
sessionVerificationHostingController = UIHostingController(rootView: view)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Public
|
||||||
|
|
||||||
|
func start() {
|
||||||
|
MXLog.debug("[SessionVerificationCoordinator] did start.")
|
||||||
|
sessionVerificationViewModel.callback = { [weak self] action in
|
||||||
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
switch action {
|
||||||
|
case .finished:
|
||||||
|
self.callback?()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toPresentable() -> UIViewController {
|
||||||
|
sessionVerificationHostingController
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2021 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
|
||||||
|
|
||||||
|
// MARK: View model
|
||||||
|
|
||||||
|
enum SessionVerificationViewModelAction {
|
||||||
|
case finished
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: View
|
||||||
|
|
||||||
|
struct SessionVerificationViewState: BindableState {
|
||||||
|
var verificationState: SessionVerificationStateMachine.State = .initial
|
||||||
|
|
||||||
|
var shouldDisableDismissButton: Bool {
|
||||||
|
verificationState != .verified
|
||||||
|
}
|
||||||
|
|
||||||
|
var shouldDisableCancelButton: Bool {
|
||||||
|
verificationState == .verified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SessionVerificationViewAction {
|
||||||
|
case start
|
||||||
|
case restart
|
||||||
|
case accept
|
||||||
|
case decline
|
||||||
|
case dismiss
|
||||||
|
case cancel
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
//
|
||||||
|
// SessionVerificationStateMachine.swift
|
||||||
|
// ElementX
|
||||||
|
//
|
||||||
|
// Created by Stefan Ceriu on 15/06/2022.
|
||||||
|
// Copyright © 2022 Element. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import SwiftState
|
||||||
|
|
||||||
|
class SessionVerificationStateMachine {
|
||||||
|
/// States the SessionVerificationViewModel can find itself in
|
||||||
|
enum State: StateType {
|
||||||
|
/// The initial state, before verification started
|
||||||
|
case initial
|
||||||
|
/// Waiting for verification acceptance
|
||||||
|
case requestingVerification
|
||||||
|
/// Verification accepted and emojis received
|
||||||
|
case showingChallenge(emojis: [SessionVerificationEmoji])
|
||||||
|
/// Emojis match locally
|
||||||
|
case acceptingChallenge(emojis: [SessionVerificationEmoji])
|
||||||
|
/// Emojis do not match locally
|
||||||
|
case decliningChallenge(emojis: [SessionVerificationEmoji])
|
||||||
|
/// Verification successful
|
||||||
|
case verified
|
||||||
|
/// User requested verification cancellation
|
||||||
|
case cancelling
|
||||||
|
/// The verification has been cancelled, remotely or locally
|
||||||
|
case cancelled
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Events that can be triggered on the SessionVerification state machine
|
||||||
|
enum Event: EventType {
|
||||||
|
/// Request verification
|
||||||
|
case requestVerification
|
||||||
|
/// Has received emojis
|
||||||
|
case didReceiveChallenge(emojis: [SessionVerificationEmoji])
|
||||||
|
/// Emojis match
|
||||||
|
case acceptChallenge
|
||||||
|
/// Emojis do not match
|
||||||
|
case declineChallenge
|
||||||
|
/// Remote accepted challenge
|
||||||
|
case didAcceptChallenge
|
||||||
|
/// Request cancellation
|
||||||
|
case cancel
|
||||||
|
/// Verification cancelled
|
||||||
|
case didCancel
|
||||||
|
/// Request failed
|
||||||
|
case didFail
|
||||||
|
/// Restart the verification flow
|
||||||
|
case restart
|
||||||
|
}
|
||||||
|
|
||||||
|
private let stateMachine: StateMachine<State, Event>
|
||||||
|
|
||||||
|
var state: State {
|
||||||
|
stateMachine.state
|
||||||
|
}
|
||||||
|
|
||||||
|
// swiftlint:disable cyclomatic_complexity
|
||||||
|
init() {
|
||||||
|
stateMachine = StateMachine(state: .initial) { machine in
|
||||||
|
machine.addRoutes(event: .requestVerification, transitions: [ .initial => .requestingVerification ])
|
||||||
|
machine.addRoutes(event: .didFail, transitions: [ .requestingVerification => .initial ])
|
||||||
|
|
||||||
|
machine.addRoutes(event: .cancel, transitions: [ .requestingVerification => .cancelling ])
|
||||||
|
machine.addRoutes(event: .didCancel, transitions: [ .requestingVerification => .cancelled ])
|
||||||
|
|
||||||
|
// Cancellation request from the other party should either take us from `.cancelling`
|
||||||
|
// to `.cancelled` or keep us in `.cancelled` if already there. There is more `.didCancel`
|
||||||
|
// handling in `addRouteMapping` for states containing associated values
|
||||||
|
machine.addRoutes(event: .didCancel, transitions: [ .cancelling => .cancelled ])
|
||||||
|
machine.addRoutes(event: .didCancel, transitions: [ .cancelled => .cancelled ])
|
||||||
|
machine.addRoutes(event: .didFail, transitions: [ .cancelled => .cancelled ])
|
||||||
|
|
||||||
|
machine.addRoutes(event: .restart, transitions: [ .cancelled => .initial ])
|
||||||
|
|
||||||
|
// Transitions with associated values need to be handled through `addRouteMapping`
|
||||||
|
machine.addRouteMapping { event, fromState, _ in
|
||||||
|
switch (event, fromState) {
|
||||||
|
case (.didReceiveChallenge(let emojis), .requestingVerification):
|
||||||
|
return .showingChallenge(emojis: emojis)
|
||||||
|
|
||||||
|
case (.acceptChallenge, .showingChallenge(let emojis)):
|
||||||
|
return .acceptingChallenge(emojis: emojis)
|
||||||
|
case (.didFail, .acceptingChallenge(let emojis)):
|
||||||
|
return .showingChallenge(emojis: emojis)
|
||||||
|
|
||||||
|
case (.didAcceptChallenge, .acceptingChallenge):
|
||||||
|
return .verified
|
||||||
|
|
||||||
|
case (.declineChallenge, .showingChallenge(let emojis)):
|
||||||
|
return .decliningChallenge(emojis: emojis)
|
||||||
|
case (.didFail, .decliningChallenge(let emojis)):
|
||||||
|
return .showingChallenge(emojis: emojis)
|
||||||
|
|
||||||
|
case (.cancel, .showingChallenge):
|
||||||
|
return .cancelling
|
||||||
|
case (.cancel, .acceptingChallenge):
|
||||||
|
return .cancelling
|
||||||
|
case (.cancel, .decliningChallenge):
|
||||||
|
return .cancelling
|
||||||
|
|
||||||
|
case (.didCancel, .showingChallenge):
|
||||||
|
return .cancelled
|
||||||
|
case (.didCancel, .acceptingChallenge):
|
||||||
|
return .cancelled
|
||||||
|
case (.didCancel, .decliningChallenge):
|
||||||
|
return .cancelled
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// swiftlint:enable cyclomatic_complexity
|
||||||
|
|
||||||
|
/// Attempt to move the state machine to another state through an event
|
||||||
|
/// It will either invoke the `transitionHandler` or the `errorHandler` depending on its current state
|
||||||
|
func processEvent(_ event: Event) {
|
||||||
|
stateMachine.tryEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Registers a callback for processing state machine transitions
|
||||||
|
func addTransitionHandler(_ handler: @escaping StateMachine<State, Event>.Handler) {
|
||||||
|
stateMachine.addAnyHandler(.any => .any, handler: handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Registers a callback for processing state machine errors
|
||||||
|
func addErrorHandler(_ handler: @escaping StateMachine<State, Event>.Handler) {
|
||||||
|
stateMachine.addErrorHandler(handler: handler)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2021 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
|
||||||
|
|
||||||
|
typealias SessionVerificationViewModelType = StateStoreViewModel<SessionVerificationViewState, SessionVerificationViewAction>
|
||||||
|
|
||||||
|
class SessionVerificationViewModel: SessionVerificationViewModelType, SessionVerificationViewModelProtocol {
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
// MARK: Private
|
||||||
|
|
||||||
|
private let sessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol
|
||||||
|
|
||||||
|
private var stateMachine: SessionVerificationStateMachine
|
||||||
|
|
||||||
|
// MARK: Public
|
||||||
|
|
||||||
|
var callback: ((SessionVerificationViewModelAction) -> Void)?
|
||||||
|
|
||||||
|
// MARK: - Setup
|
||||||
|
|
||||||
|
init(sessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol,
|
||||||
|
initialState: SessionVerificationViewState = SessionVerificationViewState()) {
|
||||||
|
|
||||||
|
self.sessionVerificationControllerProxy = sessionVerificationControllerProxy
|
||||||
|
|
||||||
|
stateMachine = SessionVerificationStateMachine()
|
||||||
|
|
||||||
|
super.init(initialViewState: initialState)
|
||||||
|
|
||||||
|
setupStateMachine()
|
||||||
|
|
||||||
|
sessionVerificationControllerProxy.callbacks
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink { [weak self] callback in
|
||||||
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
switch callback {
|
||||||
|
case .receivedVerificationData(let emojis):
|
||||||
|
self.stateMachine.processEvent(.didReceiveChallenge(emojis: emojis))
|
||||||
|
case .finished:
|
||||||
|
self.stateMachine.processEvent(.didAcceptChallenge)
|
||||||
|
case .cancelled:
|
||||||
|
self.stateMachine.processEvent(.didCancel)
|
||||||
|
case .failed:
|
||||||
|
self.stateMachine.processEvent(.didFail)
|
||||||
|
}
|
||||||
|
}.store(in: &cancellables)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Public
|
||||||
|
|
||||||
|
override func process(viewAction: SessionVerificationViewAction) async {
|
||||||
|
switch viewAction {
|
||||||
|
case .start:
|
||||||
|
stateMachine.processEvent(.requestVerification)
|
||||||
|
case .restart:
|
||||||
|
stateMachine.processEvent(.restart)
|
||||||
|
case .dismiss:
|
||||||
|
callback?(.finished)
|
||||||
|
case .cancel:
|
||||||
|
guard stateMachine.state == .initial ||
|
||||||
|
stateMachine.state == .verified ||
|
||||||
|
stateMachine.state == .cancelled else {
|
||||||
|
stateMachine.processEvent(.cancel)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
callback?(.finished)
|
||||||
|
case .accept:
|
||||||
|
stateMachine.processEvent(.acceptChallenge)
|
||||||
|
case .decline:
|
||||||
|
stateMachine.processEvent(.declineChallenge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func setupStateMachine() {
|
||||||
|
stateMachine.addTransitionHandler { [weak self] context in
|
||||||
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
self.state.verificationState = context.toState
|
||||||
|
|
||||||
|
switch (context.fromState, context.event, context.toState) {
|
||||||
|
case (.initial, .requestVerification, .requestingVerification):
|
||||||
|
self.requestVerification()
|
||||||
|
case (.showingChallenge, .acceptChallenge, .acceptingChallenge):
|
||||||
|
self.acceptChallenge()
|
||||||
|
case (.showingChallenge, .declineChallenge, .decliningChallenge):
|
||||||
|
self.declineChallenge()
|
||||||
|
case (_, .cancel, .cancelling):
|
||||||
|
self.cancelVerification()
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stateMachine.addErrorHandler { context in
|
||||||
|
fatalError("Failed transition with context: \(context)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func requestVerification() {
|
||||||
|
Task {
|
||||||
|
switch await sessionVerificationControllerProxy.requestVerification() {
|
||||||
|
case.success:
|
||||||
|
// Need to wait for the callback from the remote
|
||||||
|
break
|
||||||
|
case .failure:
|
||||||
|
stateMachine.processEvent(.didFail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func cancelVerification() {
|
||||||
|
Task {
|
||||||
|
switch await sessionVerificationControllerProxy.cancelVerification() {
|
||||||
|
case.success:
|
||||||
|
stateMachine.processEvent(.didCancel)
|
||||||
|
case .failure:
|
||||||
|
stateMachine.processEvent(.didFail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func acceptChallenge() {
|
||||||
|
Task {
|
||||||
|
switch await sessionVerificationControllerProxy.approveVerification() {
|
||||||
|
case.success:
|
||||||
|
// Need to wait for the callback from the remote
|
||||||
|
break
|
||||||
|
case .failure:
|
||||||
|
stateMachine.processEvent(.didFail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func declineChallenge() {
|
||||||
|
Task {
|
||||||
|
switch await sessionVerificationControllerProxy.declineVerification() {
|
||||||
|
case.success:
|
||||||
|
stateMachine.processEvent(.didCancel)
|
||||||
|
case .failure:
|
||||||
|
stateMachine.processEvent(.didFail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2021 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
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
protocol SessionVerificationViewModelProtocol {
|
||||||
|
var callback: ((SessionVerificationViewModelAction) -> Void)? { get set }
|
||||||
|
var context: SessionVerificationViewModelType.Context { get }
|
||||||
|
}
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2021 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
|
||||||
|
import MatrixRustSDK
|
||||||
|
|
||||||
|
struct SessionVerificationScreen: View {
|
||||||
|
|
||||||
|
@ObservedObject var context: SessionVerificationViewModel.Context
|
||||||
|
|
||||||
|
// MARK: Views
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
NavigationView {
|
||||||
|
VStack(spacing: 32.0) {
|
||||||
|
Text(heading)
|
||||||
|
.font(.body)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.foregroundColor(.element.primaryContent)
|
||||||
|
.accessibilityIdentifier("titleLabel")
|
||||||
|
|
||||||
|
switch context.viewState.verificationState {
|
||||||
|
case .initial:
|
||||||
|
StateIcon(systemName: "lock.shield")
|
||||||
|
Button(ElementL10n.startVerification) {
|
||||||
|
context.send(viewAction: .start)
|
||||||
|
}
|
||||||
|
.buttonStyle(.elementAction(.regular))
|
||||||
|
.accessibilityIdentifier("startButton")
|
||||||
|
|
||||||
|
case .cancelled:
|
||||||
|
StateIcon(systemName: "xmark.shield")
|
||||||
|
.accessibilityIdentifier("sessionVerificationFailedIcon")
|
||||||
|
|
||||||
|
Button(ElementL10n.globalRetry) {
|
||||||
|
context.send(viewAction: .restart)
|
||||||
|
}
|
||||||
|
.buttonStyle(.elementAction(.regular))
|
||||||
|
.accessibilityIdentifier("restartButton")
|
||||||
|
|
||||||
|
case .requestingVerification:
|
||||||
|
ProgressView()
|
||||||
|
.accessibilityIdentifier("requestingVerificationProgressView")
|
||||||
|
case .cancelling:
|
||||||
|
ProgressView()
|
||||||
|
.accessibilityIdentifier("cancellingVerificationProgressView")
|
||||||
|
case .acceptingChallenge:
|
||||||
|
ProgressView()
|
||||||
|
.accessibilityIdentifier("acceptingChallengeProgressView")
|
||||||
|
case .decliningChallenge:
|
||||||
|
ProgressView()
|
||||||
|
.accessibilityIdentifier("decliningChallengeProgressView")
|
||||||
|
|
||||||
|
case .showingChallenge(let emojis):
|
||||||
|
HStack(spacing: 8.0) {
|
||||||
|
ForEach(emojis.prefix(4), id: \.self) { emoji in
|
||||||
|
EmojiView(emoji: emoji)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HStack(spacing: 8.0) {
|
||||||
|
ForEach(emojis.suffix(from: 4), id: \.self) { emoji in
|
||||||
|
EmojiView(emoji: emoji)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actionButtons
|
||||||
|
case .verified:
|
||||||
|
StateIcon(systemName: "checkmark.shield")
|
||||||
|
.accessibilityIdentifier("sessionVerificationSucceededIcon")
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.padding(.top, 64)
|
||||||
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
.navigationTitle(ElementL10n.verificationVerifyDevice)
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .confirmationAction) {
|
||||||
|
Button(ElementL10n.done) {
|
||||||
|
context.send(viewAction: .dismiss)
|
||||||
|
}
|
||||||
|
.disabled(context.viewState.shouldDisableDismissButton)
|
||||||
|
.accessibilityIdentifier("dismissButton")
|
||||||
|
}
|
||||||
|
ToolbarItem(placement: .cancellationAction) {
|
||||||
|
Button(ElementL10n.actionCancel) {
|
||||||
|
context.send(viewAction: .cancel)
|
||||||
|
}
|
||||||
|
.disabled(context.viewState.shouldDisableCancelButton)
|
||||||
|
.accessibilityIdentifier("cancelButton")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationViewStyle(StackNavigationViewStyle())
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
private var heading: String {
|
||||||
|
switch context.viewState.verificationState {
|
||||||
|
case .initial:
|
||||||
|
return ElementL10n.verificationOpenOtherToVerify
|
||||||
|
case .requestingVerification:
|
||||||
|
return ElementL10n.verificationRequestWaiting
|
||||||
|
case .acceptingChallenge:
|
||||||
|
return ElementL10n.verificationRequestWaiting
|
||||||
|
case .decliningChallenge:
|
||||||
|
return ElementL10n.verificationRequestWaiting
|
||||||
|
case .cancelling:
|
||||||
|
return ElementL10n.verificationRequestWaiting
|
||||||
|
case .showingChallenge:
|
||||||
|
return ElementL10n.verificationEmojiNotice
|
||||||
|
case .verified:
|
||||||
|
return ElementL10n.verificationConclusionOkSelfNotice
|
||||||
|
case .cancelled:
|
||||||
|
return ElementL10n.verificationCancelled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var actionButtons: some View {
|
||||||
|
HStack(spacing: 16.0) {
|
||||||
|
Button(ElementL10n.verificationSasDoNotMatch) {
|
||||||
|
context.send(viewAction: .decline)
|
||||||
|
}
|
||||||
|
.buttonStyle(.elementAction(.regular, color: .red))
|
||||||
|
.accessibilityLabel("challengeDeclineButton")
|
||||||
|
|
||||||
|
Button(ElementL10n.verificationSasMatch) {
|
||||||
|
context.send(viewAction: .accept)
|
||||||
|
}
|
||||||
|
.buttonStyle(.elementAction(.regular))
|
||||||
|
.accessibilityLabel("challengeAcceptButton")
|
||||||
|
}
|
||||||
|
.padding(32.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct EmojiView: View {
|
||||||
|
let emoji: SessionVerificationEmoji
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 16.0) {
|
||||||
|
Text(emoji.symbol)
|
||||||
|
.font(.largeTitle)
|
||||||
|
Text(emoji.description)
|
||||||
|
.font(.body)
|
||||||
|
}
|
||||||
|
.padding(8.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StateIcon: View {
|
||||||
|
let systemName: String
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Image(systemName: systemName)
|
||||||
|
.resizable()
|
||||||
|
.scaledToFit()
|
||||||
|
.foregroundColor(.element.accent)
|
||||||
|
.frame(width: 100, height: 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Previews
|
||||||
|
|
||||||
|
struct SessionVerification_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
body.preferredColorScheme(.light)
|
||||||
|
body.preferredColorScheme(.dark)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
static var body: some View {
|
||||||
|
Group {
|
||||||
|
sessionVerificationScreen(state: .initial)
|
||||||
|
sessionVerificationScreen(state: .requestingVerification)
|
||||||
|
sessionVerificationScreen(state: .cancelled)
|
||||||
|
|
||||||
|
sessionVerificationScreen(state: .showingChallenge(emojis: MockSessionVerificationControllerProxy.emojis))
|
||||||
|
sessionVerificationScreen(state: .verified)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func sessionVerificationScreen(state: SessionVerificationStateMachine.State) -> some View {
|
||||||
|
let viewModel = SessionVerificationViewModel(sessionVerificationControllerProxy: MockSessionVerificationControllerProxy(),
|
||||||
|
initialState: SessionVerificationViewState(verificationState: state))
|
||||||
|
|
||||||
|
return SessionVerificationScreen(context: viewModel.context)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
|
|
||||||
private let client: Client
|
private let client: Client
|
||||||
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
||||||
|
private var sessionVerificationControllerProxy: SessionVerificationControllerProxy?
|
||||||
|
|
||||||
private(set) var rooms: [RoomProxy] = [] {
|
private(set) var rooms: [RoomProxy] = [] {
|
||||||
didSet {
|
didSet {
|
||||||
@@ -96,11 +97,25 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
return Data(bytes: bytes, count: bytes.count)
|
return Data(bytes: bytes, count: bytes.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sessionVerificationControllerProxy() async -> Result<SessionVerificationControllerProxyProtocol, ClientProxyError> {
|
||||||
|
await Task.detached {
|
||||||
|
do {
|
||||||
|
let sessionVerificationController = try self.client.getSessionVerificationController()
|
||||||
|
return .success(SessionVerificationControllerProxy(sessionVerificationController: sessionVerificationController))
|
||||||
|
} catch {
|
||||||
|
return .failure(.failedRetrievingSessionVerificationController)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.value
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
fileprivate func didReceiveSyncUpdate() {
|
fileprivate func didReceiveSyncUpdate() {
|
||||||
Benchmark.logElapsedDurationForIdentifier("ClientSync", message: "Received sync update")
|
Benchmark.logElapsedDurationForIdentifier("ClientSync", message: "Received sync update")
|
||||||
|
|
||||||
|
callbacks.send(.receivedSyncUpdate)
|
||||||
|
|
||||||
Task.detached {
|
Task.detached {
|
||||||
await self.updateRooms()
|
await self.updateRooms()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,13 @@ import Combine
|
|||||||
|
|
||||||
enum ClientProxyCallback {
|
enum ClientProxyCallback {
|
||||||
case updatedRoomsList
|
case updatedRoomsList
|
||||||
|
case receivedSyncUpdate
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ClientProxyError: Error {
|
enum ClientProxyError: Error {
|
||||||
case failedRetrievingAvatarURL
|
case failedRetrievingAvatarURL
|
||||||
case failedRetrievingDisplayName
|
case failedRetrievingDisplayName
|
||||||
|
case failedRetrievingSessionVerificationController
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol ClientProxyProtocol {
|
protocol ClientProxyProtocol {
|
||||||
@@ -33,4 +35,6 @@ protocol ClientProxyProtocol {
|
|||||||
func mediaSourceForURLString(_ urlString: String) -> MatrixRustSDK.MediaSource
|
func mediaSourceForURLString(_ urlString: String) -> MatrixRustSDK.MediaSource
|
||||||
|
|
||||||
func loadMediaContentForSource(_ source: MatrixRustSDK.MediaSource) throws -> Data
|
func loadMediaContentForSource(_ source: MatrixRustSDK.MediaSource) throws -> Data
|
||||||
|
|
||||||
|
func sessionVerificationControllerProxy() async -> Result<SessionVerificationControllerProxyProtocol, ClientProxyError>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
backwardStream = room.startLiveEventListener()
|
backwardStream = room.startLiveEventListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
room.setDelegate(delegate: nil)
|
||||||
|
}
|
||||||
|
|
||||||
var id: String {
|
var id: String {
|
||||||
room.id()
|
room.id()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,64 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import Combine
|
||||||
|
|
||||||
class UserSession: UserSessionProtocol {
|
class UserSession: UserSessionProtocol {
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
private var checkForSessionVerificationControllerCancellable: AnyCancellable?
|
||||||
|
|
||||||
let clientProxy: ClientProxyProtocol
|
let clientProxy: ClientProxyProtocol
|
||||||
let mediaProvider: MediaProviderProtocol
|
let mediaProvider: MediaProviderProtocol
|
||||||
|
let callbacks = PassthroughSubject<UserSessionCallback, Never>()
|
||||||
|
private(set) var sessionVerificationController: SessionVerificationControllerProxyProtocol?
|
||||||
|
|
||||||
init(clientProxy: ClientProxyProtocol, mediaProvider: MediaProviderProtocol) {
|
init(clientProxy: ClientProxyProtocol, mediaProvider: MediaProviderProtocol) {
|
||||||
self.clientProxy = clientProxy
|
self.clientProxy = clientProxy
|
||||||
self.mediaProvider = mediaProvider
|
self.mediaProvider = mediaProvider
|
||||||
|
|
||||||
|
setupSessionVerificationWatchdog()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func setupSessionVerificationWatchdog() {
|
||||||
|
checkForSessionVerificationControllerCancellable = clientProxy.callbacks
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink { [weak self] callback in
|
||||||
|
if case .receivedSyncUpdate = callback {
|
||||||
|
self?.attemptSessionVerification()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func attemptSessionVerification() {
|
||||||
|
Task {
|
||||||
|
switch await clientProxy.sessionVerificationControllerProxy() {
|
||||||
|
case .success(let sessionVerificationController):
|
||||||
|
tearDownSessionVerificationControllerWatchdog()
|
||||||
|
|
||||||
|
if !sessionVerificationController.isVerified {
|
||||||
|
callbacks.send(.sessionVerificationNeeded)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.sessionVerificationController = sessionVerificationController
|
||||||
|
|
||||||
|
sessionVerificationController.callbacks.sink { callback in
|
||||||
|
switch callback {
|
||||||
|
case .finished:
|
||||||
|
self.callbacks.send(.didVerifySession)
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}.store(in: &cancellables)
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
MXLog.error("Failed getting session verification controller with error: \(error). Will retry on the next sync update.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func tearDownSessionVerificationControllerWatchdog() {
|
||||||
|
checkForSessionVerificationControllerCancellable = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,18 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
enum UserSessionCallback {
|
||||||
|
case sessionVerificationNeeded
|
||||||
|
case didVerifySession
|
||||||
|
}
|
||||||
|
|
||||||
protocol UserSessionProtocol {
|
protocol UserSessionProtocol {
|
||||||
var clientProxy: ClientProxyProtocol { get }
|
var clientProxy: ClientProxyProtocol { get }
|
||||||
var mediaProvider: MediaProviderProtocol { get }
|
var mediaProvider: MediaProviderProtocol { get }
|
||||||
|
|
||||||
|
var sessionVerificationController: SessionVerificationControllerProxyProtocol? { get }
|
||||||
|
|
||||||
|
var callbacks: PassthroughSubject<UserSessionCallback, Never> { get }
|
||||||
}
|
}
|
||||||
|
|||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// MockSessionVerificationControllerProxy.swift
|
||||||
|
// ElementX
|
||||||
|
//
|
||||||
|
// Created by Stefan Ceriu on 07/06/2022.
|
||||||
|
// Copyright © 2022 Element. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import MatrixRustSDK
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
struct MockSessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol {
|
||||||
|
var callbacks = PassthroughSubject<SessionVerificationControllerProxyCallback, Never>()
|
||||||
|
|
||||||
|
var isVerified: Bool = false
|
||||||
|
|
||||||
|
func requestVerification() async -> Result<Void, SessionVerificationControllerProxyError> {
|
||||||
|
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 2.0) {
|
||||||
|
callbacks.send(.receivedVerificationData(Self.emojis))
|
||||||
|
}
|
||||||
|
|
||||||
|
return .success(())
|
||||||
|
}
|
||||||
|
|
||||||
|
func approveVerification() async -> Result<Void, SessionVerificationControllerProxyError> {
|
||||||
|
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 2.0) {
|
||||||
|
callbacks.send(.finished)
|
||||||
|
}
|
||||||
|
|
||||||
|
return .success(())
|
||||||
|
}
|
||||||
|
|
||||||
|
func declineVerification() async -> Result<Void, SessionVerificationControllerProxyError> {
|
||||||
|
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 2.0) {
|
||||||
|
callbacks.send(.cancelled)
|
||||||
|
}
|
||||||
|
|
||||||
|
return .success(())
|
||||||
|
}
|
||||||
|
|
||||||
|
func cancelVerification() async -> Result<Void, SessionVerificationControllerProxyError> {
|
||||||
|
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 2.0) {
|
||||||
|
callbacks.send(.cancelled)
|
||||||
|
}
|
||||||
|
|
||||||
|
return .success(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
static var emojis: [SessionVerificationEmoji] {
|
||||||
|
[SessionVerificationEmoji(symbol: "🦋", description: "Butterfly"),
|
||||||
|
SessionVerificationEmoji(symbol: "🐘", description: "Elephant"),
|
||||||
|
SessionVerificationEmoji(symbol: "🦋", description: "Butterfly"),
|
||||||
|
SessionVerificationEmoji(symbol: "🎂", description: "Cake"),
|
||||||
|
SessionVerificationEmoji(symbol: "🎂", description: "Cake"),
|
||||||
|
SessionVerificationEmoji(symbol: "🏁", description: "Flag"),
|
||||||
|
SessionVerificationEmoji(symbol: "🌏", description: "Globe")
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
+124
@@ -0,0 +1,124 @@
|
|||||||
|
//
|
||||||
|
// SessionVerificationControllerProxy.swift
|
||||||
|
// ElementX
|
||||||
|
//
|
||||||
|
// Created by Stefan Ceriu on 06/06/2022.
|
||||||
|
// Copyright © 2022 Element. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import MatrixRustSDK
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
private class WeakSessionVerificationControllerProxy: SessionVerificationControllerDelegate {
|
||||||
|
private weak var proxy: SessionVerificationControllerProxy?
|
||||||
|
|
||||||
|
init(proxy: SessionVerificationControllerProxy) {
|
||||||
|
self.proxy = proxy
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - SessionVerificationControllerDelegate
|
||||||
|
|
||||||
|
func didReceiveVerificationData(data: [MatrixRustSDK.SessionVerificationEmoji]) {
|
||||||
|
proxy?.didReceiveData(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func didFail() {
|
||||||
|
proxy?.didFail()
|
||||||
|
}
|
||||||
|
|
||||||
|
func didCancel() {
|
||||||
|
proxy?.didCancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
func didFinish() {
|
||||||
|
proxy?.didFinish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SessionVerificationControllerProxy: SessionVerificationControllerProxyProtocol {
|
||||||
|
private let sessionVerificationController: SessionVerificationController
|
||||||
|
|
||||||
|
init(sessionVerificationController: SessionVerificationController) {
|
||||||
|
self.sessionVerificationController = sessionVerificationController
|
||||||
|
sessionVerificationController.setDelegate(delegate: WeakSessionVerificationControllerProxy(proxy: self))
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
sessionVerificationController.setDelegate(delegate: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
let callbacks = PassthroughSubject<SessionVerificationControllerProxyCallback, Never>()
|
||||||
|
|
||||||
|
var isVerified: Bool {
|
||||||
|
sessionVerificationController.isVerified()
|
||||||
|
}
|
||||||
|
|
||||||
|
func requestVerification() async -> Result<Void, SessionVerificationControllerProxyError> {
|
||||||
|
await Task.detached {
|
||||||
|
do {
|
||||||
|
try self.sessionVerificationController.requestVerification()
|
||||||
|
return .success(())
|
||||||
|
} catch {
|
||||||
|
return .failure(.failedRequestingVerification)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func approveVerification() async -> Result<Void, SessionVerificationControllerProxyError> {
|
||||||
|
await Task.detached {
|
||||||
|
do {
|
||||||
|
try self.sessionVerificationController.approveVerification()
|
||||||
|
return .success(())
|
||||||
|
} catch {
|
||||||
|
return .failure(.failedApprovingVerification)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func declineVerification() async -> Result<Void, SessionVerificationControllerProxyError> {
|
||||||
|
await Task.detached {
|
||||||
|
do {
|
||||||
|
try self.sessionVerificationController.declineVerification()
|
||||||
|
return .success(())
|
||||||
|
} catch {
|
||||||
|
return .failure(.failedDecliningVerification)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func cancelVerification() async -> Result<Void, SessionVerificationControllerProxyError> {
|
||||||
|
await Task.detached {
|
||||||
|
do {
|
||||||
|
try self.sessionVerificationController.cancelVerification()
|
||||||
|
return .success(())
|
||||||
|
} catch {
|
||||||
|
return .failure(.failedCancellingVerification)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
fileprivate func didReceiveData(_ data: [MatrixRustSDK.SessionVerificationEmoji]) {
|
||||||
|
callbacks.send(.receivedVerificationData(data.map { emoji in
|
||||||
|
SessionVerificationEmoji(symbol: emoji.symbol(), description: emoji.description())
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func didFail() {
|
||||||
|
callbacks.send(.failed)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func didFinish() {
|
||||||
|
callbacks.send(.finished)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func didCancel() {
|
||||||
|
callbacks.send(.cancelled)
|
||||||
|
}
|
||||||
|
}
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// SessionVerificationControllerProxyProtocol.swift
|
||||||
|
// ElementX
|
||||||
|
//
|
||||||
|
// Created by Stefan Ceriu on 07/06/2022.
|
||||||
|
// Copyright © 2022 Element. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
enum SessionVerificationControllerProxyError: Error {
|
||||||
|
case failedRequestingVerification
|
||||||
|
case failedApprovingVerification
|
||||||
|
case failedDecliningVerification
|
||||||
|
case failedCancellingVerification
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SessionVerificationControllerProxyCallback {
|
||||||
|
case receivedVerificationData([SessionVerificationEmoji])
|
||||||
|
case finished
|
||||||
|
case cancelled
|
||||||
|
case failed
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SessionVerificationEmoji: Hashable {
|
||||||
|
let symbol: String
|
||||||
|
let description: String
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol SessionVerificationControllerProxyProtocol {
|
||||||
|
var callbacks: PassthroughSubject<SessionVerificationControllerProxyCallback, Never> { get }
|
||||||
|
|
||||||
|
var isVerified: Bool { get }
|
||||||
|
|
||||||
|
func requestVerification() async -> Result<Void, SessionVerificationControllerProxyError>
|
||||||
|
|
||||||
|
func approveVerification() async -> Result<Void, SessionVerificationControllerProxyError>
|
||||||
|
|
||||||
|
func declineVerification() async -> Result<Void, SessionVerificationControllerProxyError>
|
||||||
|
|
||||||
|
func cancelVerification() async -> Result<Void, SessionVerificationControllerProxyError>
|
||||||
|
}
|
||||||
@@ -18,7 +18,9 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol {
|
|||||||
init(roomProxy: RoomProxyProtocol) {
|
init(roomProxy: RoomProxyProtocol) {
|
||||||
self.roomProxy = roomProxy
|
self.roomProxy = roomProxy
|
||||||
|
|
||||||
self.roomProxy.callbacks.sink { [weak self] callback in
|
self.roomProxy.callbacks
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink { [weak self] callback in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
switch callback {
|
switch callback {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ enum UITestScreenIdentifier: String {
|
|||||||
case splash
|
case splash
|
||||||
case roomPlainNoAvatar
|
case roomPlainNoAvatar
|
||||||
case roomEncryptedWithAvatar
|
case roomEncryptedWithAvatar
|
||||||
|
case sessionVerification
|
||||||
}
|
}
|
||||||
|
|
||||||
extension UITestScreenIdentifier: CustomStringConvertible {
|
extension UITestScreenIdentifier: CustomStringConvertible {
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ class UITestsAppCoordinator: Coordinator {
|
|||||||
window.tintColor = .element.accent
|
window.tintColor = .element.accent
|
||||||
|
|
||||||
let screens = mockScreens()
|
let screens = mockScreens()
|
||||||
screens.forEach { $0.coordinator.start() }
|
|
||||||
|
|
||||||
let rootView = UITestsRootView(mockScreens: screens) { id in
|
let rootView = UITestsRootView(mockScreens: screens) { id in
|
||||||
guard let screen = screens.first(where: { $0.id == id }) else {
|
guard let screen = screens.first(where: { $0.id == id }) else {
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
screen.coordinator.start()
|
||||||
|
|
||||||
self.mainNavigationController.pushViewController(screen.coordinator.toPresentable(), animated: true)
|
self.mainNavigationController.pushViewController(screen.coordinator.toPresentable(), animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,9 +45,9 @@ class UITestsAppCoordinator: Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
struct MockScreen: Identifiable {
|
class MockScreen: Identifiable {
|
||||||
let id: UITestScreenIdentifier
|
let id: UITestScreenIdentifier
|
||||||
var coordinator: Coordinator & Presentable {
|
lazy var coordinator: Coordinator & Presentable = {
|
||||||
switch id {
|
switch id {
|
||||||
case .login:
|
case .login:
|
||||||
let router = NavigationRouter(navigationController: ElementNavigationController())
|
let router = NavigationRouter(navigationController: ElementNavigationController())
|
||||||
@@ -78,17 +78,24 @@ struct MockScreen: Identifiable {
|
|||||||
case .splash:
|
case .splash:
|
||||||
return SplashScreenCoordinator()
|
return SplashScreenCoordinator()
|
||||||
case .roomPlainNoAvatar:
|
case .roomPlainNoAvatar:
|
||||||
let params = RoomScreenCoordinatorParameters(timelineController: MockRoomTimelineController(),
|
let parameters = RoomScreenCoordinatorParameters(timelineController: MockRoomTimelineController(),
|
||||||
roomName: "Some room name",
|
roomName: "Some room name",
|
||||||
roomAvatar: nil,
|
roomAvatar: nil,
|
||||||
roomEncryptionBadge: nil)
|
roomEncryptionBadge: nil)
|
||||||
return RoomScreenCoordinator(parameters: params)
|
return RoomScreenCoordinator(parameters: parameters)
|
||||||
case .roomEncryptedWithAvatar:
|
case .roomEncryptedWithAvatar:
|
||||||
let params = RoomScreenCoordinatorParameters(timelineController: MockRoomTimelineController(),
|
let parameters = RoomScreenCoordinatorParameters(timelineController: MockRoomTimelineController(),
|
||||||
roomName: "Some room name",
|
roomName: "Some room name",
|
||||||
roomAvatar: Asset.Images.appLogo.image,
|
roomAvatar: Asset.Images.appLogo.image,
|
||||||
roomEncryptionBadge: Asset.Images.encryptionTrusted.image)
|
roomEncryptionBadge: Asset.Images.encryptionTrusted.image)
|
||||||
return RoomScreenCoordinator(parameters: params)
|
return RoomScreenCoordinator(parameters: parameters)
|
||||||
|
case .sessionVerification:
|
||||||
|
let parameters = SessionVerificationCoordinatorParameters(sessionVerificationControllerProxy: MockSessionVerificationControllerProxy())
|
||||||
|
return SessionVerificationCoordinator(parameters: parameters)
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
init(id: UITestScreenIdentifier) {
|
||||||
|
self.id = id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2021 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
|
||||||
|
import ElementX
|
||||||
|
|
||||||
|
class SessionVerificationUITests: XCTestCase {
|
||||||
|
|
||||||
|
func testChallengeMatches() {
|
||||||
|
let app = Application.launch()
|
||||||
|
app.goToScreenWithIdentifier(.sessionVerification)
|
||||||
|
|
||||||
|
XCTAssert(app.navigationBars["Verify this session"].exists)
|
||||||
|
|
||||||
|
XCTAssert(app.buttons["startButton"].exists)
|
||||||
|
XCTAssert(app.buttons["dismissButton"].exists)
|
||||||
|
XCTAssert(app.staticTexts["titleLabel"].exists)
|
||||||
|
|
||||||
|
app.buttons["startButton"].tap()
|
||||||
|
|
||||||
|
XCTAssert(app.activityIndicators["requestingVerificationProgressView"].exists)
|
||||||
|
XCTAssert(app.buttons["cancelButton"].exists)
|
||||||
|
|
||||||
|
XCTAssert(app.buttons["challengeAcceptButton"].waitForExistence(timeout: 5.0))
|
||||||
|
XCTAssert(app.buttons["challengeDeclineButton"].waitForExistence(timeout: 5.0))
|
||||||
|
XCTAssert(app.buttons["cancelButton"].waitForExistence(timeout: 5.0))
|
||||||
|
|
||||||
|
app.buttons["challengeAcceptButton"].tap()
|
||||||
|
|
||||||
|
XCTAssert(app.activityIndicators["acceptingChallengeProgressView"].exists)
|
||||||
|
XCTAssert(app.buttons["cancelButton"].exists)
|
||||||
|
|
||||||
|
XCTAssert(app.images["sessionVerificationSucceededIcon"].waitForExistence(timeout: 5.0))
|
||||||
|
|
||||||
|
XCTAssert(app.buttons["dismissButton"].exists)
|
||||||
|
app.buttons["dismissButton"].tap()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testChallengeDoesNotMatch() {
|
||||||
|
let app = Application.launch()
|
||||||
|
app.goToScreenWithIdentifier(.sessionVerification)
|
||||||
|
|
||||||
|
XCTAssert(app.navigationBars["Verify this session"].exists)
|
||||||
|
|
||||||
|
XCTAssert(app.buttons["startButton"].exists)
|
||||||
|
XCTAssert(app.buttons["dismissButton"].exists)
|
||||||
|
XCTAssert(app.staticTexts["titleLabel"].exists)
|
||||||
|
|
||||||
|
app.buttons["startButton"].tap()
|
||||||
|
|
||||||
|
XCTAssert(app.activityIndicators["requestingVerificationProgressView"].exists)
|
||||||
|
XCTAssert(app.buttons["cancelButton"].exists)
|
||||||
|
|
||||||
|
XCTAssert(app.buttons["challengeAcceptButton"].waitForExistence(timeout: 5.0))
|
||||||
|
XCTAssert(app.buttons["challengeDeclineButton"].waitForExistence(timeout: 5.0))
|
||||||
|
XCTAssert(app.buttons["cancelButton"].waitForExistence(timeout: 5.0))
|
||||||
|
|
||||||
|
app.buttons["challengeDeclineButton"].tap()
|
||||||
|
|
||||||
|
XCTAssert(app.images["sessionVerificationFailedIcon"].exists)
|
||||||
|
XCTAssert(app.buttons["restartButton"].exists)
|
||||||
|
|
||||||
|
XCTAssert(app.buttons["dismissButton"].exists)
|
||||||
|
app.buttons["dismissButton"].tap()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSessionVerificationCancelation() {
|
||||||
|
let app = Application.launch()
|
||||||
|
app.goToScreenWithIdentifier(.sessionVerification)
|
||||||
|
|
||||||
|
XCTAssert(app.navigationBars["Verify this session"].exists)
|
||||||
|
|
||||||
|
XCTAssert(app.buttons["startButton"].exists)
|
||||||
|
XCTAssert(app.buttons["dismissButton"].exists)
|
||||||
|
XCTAssert(app.staticTexts["titleLabel"].exists)
|
||||||
|
|
||||||
|
app.buttons["startButton"].tap()
|
||||||
|
|
||||||
|
XCTAssert(app.activityIndicators["requestingVerificationProgressView"].exists)
|
||||||
|
XCTAssert(app.buttons["cancelButton"].exists)
|
||||||
|
|
||||||
|
app.buttons["cancelButton"].tap()
|
||||||
|
|
||||||
|
XCTAssert(app.images["sessionVerificationFailedIcon"].exists)
|
||||||
|
XCTAssert(app.buttons["restartButton"].exists)
|
||||||
|
|
||||||
|
XCTAssert(app.buttons["dismissButton"].exists)
|
||||||
|
app.buttons["dismissButton"].tap()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
//
|
||||||
|
// SessionVerificationStateMachineTests.swift
|
||||||
|
// UnitTests
|
||||||
|
//
|
||||||
|
// Created by Stefan Ceriu on 28/06/2022.
|
||||||
|
// Copyright © 2022 Element. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@testable import ElementX
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
class SessionVerificationStateMachineTests: XCTestCase {
|
||||||
|
private var stateMachine: SessionVerificationStateMachine!
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
override func setUpWithError() throws {
|
||||||
|
stateMachine = SessionVerificationStateMachine()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAcceptChallenge() {
|
||||||
|
XCTAssertEqual(stateMachine.state, .initial)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.requestVerification)
|
||||||
|
XCTAssertEqual(stateMachine.state, .requestingVerification)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.didReceiveChallenge(emojis: MockSessionVerificationControllerProxy.emojis))
|
||||||
|
XCTAssertEqual(stateMachine.state, .showingChallenge(emojis: MockSessionVerificationControllerProxy.emojis))
|
||||||
|
|
||||||
|
stateMachine.processEvent(.acceptChallenge)
|
||||||
|
XCTAssertEqual(stateMachine.state, .acceptingChallenge(emojis: MockSessionVerificationControllerProxy.emojis))
|
||||||
|
|
||||||
|
stateMachine.processEvent(.didAcceptChallenge)
|
||||||
|
XCTAssertEqual(stateMachine.state, .verified)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDeclineChallenge() {
|
||||||
|
XCTAssertEqual(stateMachine.state, .initial)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.requestVerification)
|
||||||
|
XCTAssertEqual(stateMachine.state, .requestingVerification)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.didReceiveChallenge(emojis: MockSessionVerificationControllerProxy.emojis))
|
||||||
|
XCTAssertEqual(stateMachine.state, .showingChallenge(emojis: MockSessionVerificationControllerProxy.emojis))
|
||||||
|
|
||||||
|
stateMachine.processEvent(.declineChallenge)
|
||||||
|
XCTAssertEqual(stateMachine.state, .decliningChallenge(emojis: MockSessionVerificationControllerProxy.emojis))
|
||||||
|
|
||||||
|
stateMachine.processEvent(.didCancel)
|
||||||
|
XCTAssertEqual(stateMachine.state, .cancelled)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.restart)
|
||||||
|
XCTAssertEqual(stateMachine.state, .initial)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCancellation() {
|
||||||
|
XCTAssertEqual(stateMachine.state, .initial)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.requestVerification)
|
||||||
|
XCTAssertEqual(stateMachine.state, .requestingVerification)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.cancel)
|
||||||
|
XCTAssertEqual(stateMachine.state, .cancelling)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.didCancel)
|
||||||
|
XCTAssertEqual(stateMachine.state, .cancelled)
|
||||||
|
|
||||||
|
// This duplication is intentional
|
||||||
|
stateMachine.processEvent(.didCancel)
|
||||||
|
XCTAssertEqual(stateMachine.state, .cancelled)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.restart)
|
||||||
|
XCTAssertEqual(stateMachine.state, .initial)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.requestVerification)
|
||||||
|
XCTAssertEqual(stateMachine.state, .requestingVerification)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.didReceiveChallenge(emojis: MockSessionVerificationControllerProxy.emojis))
|
||||||
|
XCTAssertEqual(stateMachine.state, .showingChallenge(emojis: MockSessionVerificationControllerProxy.emojis))
|
||||||
|
|
||||||
|
stateMachine.processEvent(.cancel)
|
||||||
|
XCTAssertEqual(stateMachine.state, .cancelling)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.didCancel)
|
||||||
|
XCTAssertEqual(stateMachine.state, .cancelled)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.restart)
|
||||||
|
XCTAssertEqual(stateMachine.state, .initial)
|
||||||
|
|
||||||
|
stateMachine.processEvent(.restart)
|
||||||
|
XCTAssertEqual(stateMachine.state, .initial)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2021 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
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
@testable import ElementX
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
class SessionVerificationViewModelTests: XCTestCase {
|
||||||
|
|
||||||
|
var viewModel: SessionVerificationViewModelProtocol!
|
||||||
|
var context: SessionVerificationViewModelType.Context!
|
||||||
|
var sessionVerificationController: SessionVerificationControllerProxyProtocol!
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
override func setUpWithError() throws {
|
||||||
|
sessionVerificationController = MockSessionVerificationControllerProxy()
|
||||||
|
viewModel = SessionVerificationViewModel(sessionVerificationControllerProxy: sessionVerificationController)
|
||||||
|
context = viewModel.context
|
||||||
|
}
|
||||||
|
|
||||||
|
func testRequestVerification() async {
|
||||||
|
XCTAssertEqual(context.viewState.verificationState, .initial)
|
||||||
|
|
||||||
|
context.send(viewAction: .start)
|
||||||
|
|
||||||
|
await Task.yield()
|
||||||
|
|
||||||
|
XCTAssertEqual(context.viewState.verificationState, .requestingVerification)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testVerificationCancellation() async {
|
||||||
|
XCTAssertEqual(context.viewState.verificationState, .initial)
|
||||||
|
|
||||||
|
context.send(viewAction: .start)
|
||||||
|
|
||||||
|
context.send(viewAction: .cancel)
|
||||||
|
|
||||||
|
await Task.yield()
|
||||||
|
|
||||||
|
XCTAssertEqual(context.viewState.verificationState, .cancelling)
|
||||||
|
|
||||||
|
await Task.yield()
|
||||||
|
|
||||||
|
XCTAssertEqual(context.viewState.verificationState, .cancelled)
|
||||||
|
|
||||||
|
context.send(viewAction: .restart)
|
||||||
|
|
||||||
|
await Task.yield()
|
||||||
|
|
||||||
|
XCTAssertEqual(context.viewState.verificationState, .initial)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testReceiveChallenge() {
|
||||||
|
setupChallengeReceived()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAcceptChallenge() {
|
||||||
|
|
||||||
|
setupChallengeReceived()
|
||||||
|
|
||||||
|
let waitForAcceptance = XCTestExpectation(description: "Wait for acceptance")
|
||||||
|
|
||||||
|
let cancellable = sessionVerificationController.callbacks
|
||||||
|
.debounce(for: .seconds(2.0), scheduler: DispatchQueue.main)
|
||||||
|
.sink { callback in
|
||||||
|
switch callback {
|
||||||
|
case .finished:
|
||||||
|
waitForAcceptance.fulfill()
|
||||||
|
default:
|
||||||
|
XCTFail("Unexpected session verification controller callback")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer {
|
||||||
|
cancellable.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
context.send(viewAction: .accept)
|
||||||
|
|
||||||
|
wait(for: [waitForAcceptance], timeout: 10.0)
|
||||||
|
|
||||||
|
XCTAssertEqual(context.viewState.verificationState, .verified)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDeclineChallenge() {
|
||||||
|
|
||||||
|
setupChallengeReceived()
|
||||||
|
|
||||||
|
let expectation = XCTestExpectation(description: "Wait for cancellation")
|
||||||
|
|
||||||
|
let cancellable = sessionVerificationController.callbacks
|
||||||
|
.debounce(for: .seconds(2.0), scheduler: DispatchQueue.main)
|
||||||
|
.sink { callback in
|
||||||
|
switch callback {
|
||||||
|
case .cancelled:
|
||||||
|
expectation.fulfill()
|
||||||
|
default:
|
||||||
|
XCTFail("Unexpected session verification controller callback")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer {
|
||||||
|
cancellable.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
context.send(viewAction: .decline)
|
||||||
|
|
||||||
|
wait(for: [expectation], timeout: 10.0)
|
||||||
|
|
||||||
|
XCTAssertEqual(context.viewState.verificationState, .cancelled)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func setupChallengeReceived() {
|
||||||
|
let expectation = XCTestExpectation(description: "Wait for challenge")
|
||||||
|
|
||||||
|
let cancellable = sessionVerificationController.callbacks
|
||||||
|
.debounce(for: .seconds(2.0), scheduler: DispatchQueue.main)
|
||||||
|
.sink { callback in
|
||||||
|
switch callback {
|
||||||
|
case .receivedVerificationData:
|
||||||
|
expectation.fulfill()
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer {
|
||||||
|
cancellable.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
context.send(viewAction: .start)
|
||||||
|
|
||||||
|
wait(for: [expectation], timeout: 10.0)
|
||||||
|
|
||||||
|
XCTAssertEqual(context.viewState.verificationState, .showingChallenge(emojis: MockSessionVerificationControllerProxy.emojis))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@ packages:
|
|||||||
MatrixRustSDK:
|
MatrixRustSDK:
|
||||||
url: https://github.com/matrix-org/matrix-rust-components-swift.git
|
url: https://github.com/matrix-org/matrix-rust-components-swift.git
|
||||||
exactVersion: 1.0.11-alpha
|
exactVersion: 1.0.11-alpha
|
||||||
|
# path: ../matrix-rust-components-swift
|
||||||
DesignKit:
|
DesignKit:
|
||||||
path: ./
|
path: ./
|
||||||
DTCoreText:
|
DTCoreText:
|
||||||
|
|||||||
Reference in New Issue
Block a user