mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Cleanup following the AppMediator introduction (#2723)
- stop using multiple background task, the appCoordinator sync one is enough for the whole app - move the AppMeditor to the MainActor - expose the WindowManager through the AppMediator - hide sensitive WindowManager API behind a different protocol - remove the now unnecessary `BackgroundTaskService`
This commit is contained in:
parent
a3ec0b8505
commit
8ba544bc44
@ -50,7 +50,6 @@
|
|||||||
07CC13C5729C24255348CBBD /* ElementCallWidgetDriver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 309AD8BAE6437C31BA7157BF /* ElementCallWidgetDriver.swift */; };
|
07CC13C5729C24255348CBBD /* ElementCallWidgetDriver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 309AD8BAE6437C31BA7157BF /* ElementCallWidgetDriver.swift */; };
|
||||||
086D01E79C8E8D3F004FAF21 /* AudioPlayerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC9104846487244648D32C6D /* AudioPlayerProtocol.swift */; };
|
086D01E79C8E8D3F004FAF21 /* AudioPlayerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC9104846487244648D32C6D /* AudioPlayerProtocol.swift */; };
|
||||||
08CB4BD12CEEDE6AAE4A18DD /* WindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035177BCD8E8308B098AC3C2 /* WindowManager.swift */; };
|
08CB4BD12CEEDE6AAE4A18DD /* WindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035177BCD8E8308B098AC3C2 /* WindowManager.swift */; };
|
||||||
08E02C56E8B277A22C5E5BA5 /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83D7FA960FE1A1A63622CC5E /* BackgroundTaskProtocol.swift */; };
|
|
||||||
095C0ACFC234E0550A6404C5 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FC803282F9268D49F4ABF14 /* AppCoordinator.swift */; };
|
095C0ACFC234E0550A6404C5 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FC803282F9268D49F4ABF14 /* AppCoordinator.swift */; };
|
||||||
095D3906CF2F940C2D2D17CC /* RoomFlowCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FCB2126C091EEF2454B4D56 /* RoomFlowCoordinatorTests.swift */; };
|
095D3906CF2F940C2D2D17CC /* RoomFlowCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FCB2126C091EEF2454B4D56 /* RoomFlowCoordinatorTests.swift */; };
|
||||||
09713669577CDA8D012EE380 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 6647C55D93508C7CE9D954A5 /* MatrixRustSDK */; };
|
09713669577CDA8D012EE380 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 6647C55D93508C7CE9D954A5 /* MatrixRustSDK */; };
|
||||||
@ -81,7 +80,6 @@
|
|||||||
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */; };
|
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */; };
|
||||||
0EEC614342F823E5BF966C2C /* AppLockTimerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A5B4CD611DE7E94F5BA87B2 /* AppLockTimerTests.swift */; };
|
0EEC614342F823E5BF966C2C /* AppLockTimerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A5B4CD611DE7E94F5BA87B2 /* AppLockTimerTests.swift */; };
|
||||||
0F6C8033FA60CFD36F7CA205 /* AppLockSetupPINScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A019A12C866D64CF072024B9 /* AppLockSetupPINScreenViewModel.swift */; };
|
0F6C8033FA60CFD36F7CA205 /* AppLockSetupPINScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A019A12C866D64CF072024B9 /* AppLockSetupPINScreenViewModel.swift */; };
|
||||||
0F9E38A75337D0146652ACAB /* BackgroundTaskTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DFCAA239095A116976E32C4 /* BackgroundTaskTests.swift */; };
|
|
||||||
10D60D287025B71F4743A425 /* RoomDirectorySearchProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 471BB7276C97AF60B3A5463B /* RoomDirectorySearchProxy.swift */; };
|
10D60D287025B71F4743A425 /* RoomDirectorySearchProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 471BB7276C97AF60B3A5463B /* RoomDirectorySearchProxy.swift */; };
|
||||||
1146E9EDCF8344F7D6E0D553 /* MockCoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0376C429FAB1687C3D905F3E /* MockCoder.swift */; };
|
1146E9EDCF8344F7D6E0D553 /* MockCoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0376C429FAB1687C3D905F3E /* MockCoder.swift */; };
|
||||||
119AE9A3FC6E0606C1146528 /* NotificationSettingsEditScreenRoomCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C97F8963B14EB0AF3940DDBF /* NotificationSettingsEditScreenRoomCell.swift */; };
|
119AE9A3FC6E0606C1146528 /* NotificationSettingsEditScreenRoomCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C97F8963B14EB0AF3940DDBF /* NotificationSettingsEditScreenRoomCell.swift */; };
|
||||||
@ -330,7 +328,6 @@
|
|||||||
4E0D9E09B52CEC4C0E6211A8 /* MediaPickerScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F49FB9EE2913234F06CE68 /* MediaPickerScreenCoordinator.swift */; };
|
4E0D9E09B52CEC4C0E6211A8 /* MediaPickerScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F49FB9EE2913234F06CE68 /* MediaPickerScreenCoordinator.swift */; };
|
||||||
4E36A66E0EDA74BF3A036FD0 /* RoomChangeRolesScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AAD8C633AA57948B34EDCF7 /* RoomChangeRolesScreenViewModelProtocol.swift */; };
|
4E36A66E0EDA74BF3A036FD0 /* RoomChangeRolesScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AAD8C633AA57948B34EDCF7 /* RoomChangeRolesScreenViewModelProtocol.swift */; };
|
||||||
4E8A2A2CFEB212F14E49E1A1 /* AppLockSetupSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5484457C81B325660901B161 /* AppLockSetupSettingsScreen.swift */; };
|
4E8A2A2CFEB212F14E49E1A1 /* AppLockSetupSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5484457C81B325660901B161 /* AppLockSetupSettingsScreen.swift */; };
|
||||||
4E8F17EBA24FBBA6ABB62ECB /* MockBackgroundTaskService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3948D16F021DFDB2CD26EAA8 /* MockBackgroundTaskService.swift */; };
|
|
||||||
4E945AD6862C403F74E57755 /* RoomTimelineItemFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 105B2A8426404EF66F00CFDB /* RoomTimelineItemFactory.swift */; };
|
4E945AD6862C403F74E57755 /* RoomTimelineItemFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 105B2A8426404EF66F00CFDB /* RoomTimelineItemFactory.swift */; };
|
||||||
4EA1CE0E88EA68E862FF0EA2 /* NotificationSettingsEditScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B564D748B67A156F413CD97 /* NotificationSettingsEditScreenModels.swift */; };
|
4EA1CE0E88EA68E862FF0EA2 /* NotificationSettingsEditScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B564D748B67A156F413CD97 /* NotificationSettingsEditScreenModels.swift */; };
|
||||||
4F2DF6138E87A4B8C2488CA3 /* VoiceMessageCacheProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A84EE187D0C772E18A4E39 /* VoiceMessageCacheProtocol.swift */; };
|
4F2DF6138E87A4B8C2488CA3 /* VoiceMessageCacheProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A84EE187D0C772E18A4E39 /* VoiceMessageCacheProtocol.swift */; };
|
||||||
@ -751,7 +748,6 @@
|
|||||||
B22D857D1E8FCA6DD74A58E3 /* UserSessionScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F899D02CF26EA7675EEBE74C /* UserSessionScreenTests.swift */; };
|
B22D857D1E8FCA6DD74A58E3 /* UserSessionScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F899D02CF26EA7675EEBE74C /* UserSessionScreenTests.swift */; };
|
||||||
B245583C63F8F90357B87FAE /* KZFileWatchers in Frameworks */ = {isa = PBXBuildFile; productRef = A2AE110B053B55E38F8D10C7 /* KZFileWatchers */; };
|
B245583C63F8F90357B87FAE /* KZFileWatchers in Frameworks */ = {isa = PBXBuildFile; productRef = A2AE110B053B55E38F8D10C7 /* KZFileWatchers */; };
|
||||||
B2F8E01ABA1BA30265B4ECBE /* RoundedCornerShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839E2C35DF3F9C7B54C3CE49 /* RoundedCornerShape.swift */; };
|
B2F8E01ABA1BA30265B4ECBE /* RoundedCornerShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839E2C35DF3F9C7B54C3CE49 /* RoundedCornerShape.swift */; };
|
||||||
B3066502FA56D9199846C5E7 /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83D7FA960FE1A1A63622CC5E /* BackgroundTaskProtocol.swift */; };
|
|
||||||
B3D652AA1654270742072FB3 /* DeveloperOptionsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86A6F283BC574FDB96ABBB07 /* DeveloperOptionsScreenViewModel.swift */; };
|
B3D652AA1654270742072FB3 /* DeveloperOptionsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86A6F283BC574FDB96ABBB07 /* DeveloperOptionsScreenViewModel.swift */; };
|
||||||
B3EDDEC1839BB5A3747624BB /* FormButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A1CCDEE545CB6453B084BF /* FormButtonStyles.swift */; };
|
B3EDDEC1839BB5A3747624BB /* FormButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A1CCDEE545CB6453B084BF /* FormButtonStyles.swift */; };
|
||||||
B402708F8728DD0DB7C324E2 /* StartChatScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78910787F967CBC6042A101E /* StartChatScreenViewModelProtocol.swift */; };
|
B402708F8728DD0DB7C324E2 /* StartChatScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78910787F967CBC6042A101E /* StartChatScreenViewModelProtocol.swift */; };
|
||||||
@ -850,7 +846,6 @@
|
|||||||
C9F5B48D15B9BCAE1F8D564E /* RoomNotificationModeProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1511766C534367700C8DD75 /* RoomNotificationModeProxy.swift */; };
|
C9F5B48D15B9BCAE1F8D564E /* RoomNotificationModeProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1511766C534367700C8DD75 /* RoomNotificationModeProxy.swift */; };
|
||||||
CA12AE0DCD57D49CD96C699A /* WaveformCursorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB9EABCA9348DFA27439A809 /* WaveformCursorView.swift */; };
|
CA12AE0DCD57D49CD96C699A /* WaveformCursorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB9EABCA9348DFA27439A809 /* WaveformCursorView.swift */; };
|
||||||
CA5BFF0C2EF5A8EF40CA2D69 /* VoiceMessageRecordingComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCB6F36CCE44A29A06FCAF1C /* VoiceMessageRecordingComposer.swift */; };
|
CA5BFF0C2EF5A8EF40CA2D69 /* VoiceMessageRecordingComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCB6F36CCE44A29A06FCAF1C /* VoiceMessageRecordingComposer.swift */; };
|
||||||
CB0C53B67DA62F7E30DDD720 /* UIKitBackgroundTaskService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3199367BC31381F67C870976 /* UIKitBackgroundTaskService.swift */; };
|
|
||||||
CB137BFB3E083C33E398A6CB /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 020597E28A4BC8E1BE8EDF6E /* KeychainAccess */; };
|
CB137BFB3E083C33E398A6CB /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 020597E28A4BC8E1BE8EDF6E /* KeychainAccess */; };
|
||||||
CB498F4E27AA0545DCEF0F6F /* DTCoreText in Frameworks */ = {isa = PBXBuildFile; productRef = 36B7FC232711031AA2B0D188 /* DTCoreText */; };
|
CB498F4E27AA0545DCEF0F6F /* DTCoreText in Frameworks */ = {isa = PBXBuildFile; productRef = 36B7FC232711031AA2B0D188 /* DTCoreText */; };
|
||||||
CB6BCBF28E4B76EA08C2926D /* StateRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16048D30F0438731C41F775 /* StateRoomTimelineItem.swift */; };
|
CB6BCBF28E4B76EA08C2926D /* StateRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16048D30F0438731C41F775 /* StateRoomTimelineItem.swift */; };
|
||||||
@ -910,11 +905,9 @@
|
|||||||
D5FE90A6AF5FD5AE91BD37C7 /* NotificationSettingsEditScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780258F1B9D15E30549FF4BE /* NotificationSettingsEditScreenViewModel.swift */; };
|
D5FE90A6AF5FD5AE91BD37C7 /* NotificationSettingsEditScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780258F1B9D15E30549FF4BE /* NotificationSettingsEditScreenViewModel.swift */; };
|
||||||
D63974A88CF2BC721F109C77 /* Compound in Frameworks */ = {isa = PBXBuildFile; productRef = DCA3C4A997AD28E6918D4CE5 /* Compound */; };
|
D63974A88CF2BC721F109C77 /* Compound in Frameworks */ = {isa = PBXBuildFile; productRef = DCA3C4A997AD28E6918D4CE5 /* Compound */; };
|
||||||
D6661A94DBD97658B2ADBD6A /* MapTilerStaticMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A4D29F2683F5772AC72406F /* MapTilerStaticMap.swift */; };
|
D6661A94DBD97658B2ADBD6A /* MapTilerStaticMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A4D29F2683F5772AC72406F /* MapTilerStaticMap.swift */; };
|
||||||
D798A150BB6569FC07CBEB25 /* BackgroundTaskServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23C089E93ECE0EF83E182ED /* BackgroundTaskServiceProtocol.swift */; };
|
|
||||||
D7CDBAE82782BD0529DECB5F /* AttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52BD6ED18E2EB61E28C340AD /* AttributedString.swift */; };
|
D7CDBAE82782BD0529DECB5F /* AttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52BD6ED18E2EB61E28C340AD /* AttributedString.swift */; };
|
||||||
D8359F67AF3A83516E9083C1 /* MockUserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4756C5A8C8649AD6C10C615 /* MockUserSession.swift */; };
|
D8359F67AF3A83516E9083C1 /* MockUserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4756C5A8C8649AD6C10C615 /* MockUserSession.swift */; };
|
||||||
D876EC0FED3B6D46C806912A /* AvatarSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24B88AD3D1599E8CB1376E0 /* AvatarSize.swift */; };
|
D876EC0FED3B6D46C806912A /* AvatarSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24B88AD3D1599E8CB1376E0 /* AvatarSize.swift */; };
|
||||||
D8ED2FCF46D63A7357E9D502 /* BackgroundTaskServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23C089E93ECE0EF83E182ED /* BackgroundTaskServiceProtocol.swift */; };
|
|
||||||
D9473FC9B077A6EDB7A12001 /* LocationRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 772334731A8BF8E6D90B194D /* LocationRoomTimelineView.swift */; };
|
D9473FC9B077A6EDB7A12001 /* LocationRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 772334731A8BF8E6D90B194D /* LocationRoomTimelineView.swift */; };
|
||||||
D98B5EE8C4F5A2CE84687AE8 /* UTType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 897DF5E9A70CE05A632FC8AF /* UTType.swift */; };
|
D98B5EE8C4F5A2CE84687AE8 /* UTType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 897DF5E9A70CE05A632FC8AF /* UTType.swift */; };
|
||||||
D9F80CE61BF8FF627FDB0543 /* LoadableImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352359663A0E52BA20761EE /* LoadableImage.swift */; };
|
D9F80CE61BF8FF627FDB0543 /* LoadableImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352359663A0E52BA20761EE /* LoadableImage.swift */; };
|
||||||
@ -955,7 +948,6 @@
|
|||||||
E3AC72E3E58F364EF15C1CC7 /* NotificationSettingsScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */; };
|
E3AC72E3E58F364EF15C1CC7 /* NotificationSettingsScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */; };
|
||||||
E3CA565A4B9704F191B191F0 /* JoinedRoomSize+MemberCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF9AEA706926DD0DA2B954C /* JoinedRoomSize+MemberCount.swift */; };
|
E3CA565A4B9704F191B191F0 /* JoinedRoomSize+MemberCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF9AEA706926DD0DA2B954C /* JoinedRoomSize+MemberCount.swift */; };
|
||||||
E3E1E255DC8CB34BD8573E0D /* UserIndicatorControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A12D3B1BCF920880CA8BBB6B /* UserIndicatorControllerProtocol.swift */; };
|
E3E1E255DC8CB34BD8573E0D /* UserIndicatorControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A12D3B1BCF920880CA8BBB6B /* UserIndicatorControllerProtocol.swift */; };
|
||||||
E3E3D645C7F80DD64A86D936 /* UIKitBackgroundTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB49AE5D902C0FE40AF4ADF5 /* UIKitBackgroundTask.swift */; };
|
|
||||||
E45C9FA22BC13B477FD3B4AC /* EmojiDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D99730313BEBF08CDE81EE3 /* EmojiDetection.swift */; };
|
E45C9FA22BC13B477FD3B4AC /* EmojiDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D99730313BEBF08CDE81EE3 /* EmojiDetection.swift */; };
|
||||||
E468CC731C3F4D678499E52F /* LAContextMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BA5A62DA4B543827FF82354 /* LAContextMock.swift */; };
|
E468CC731C3F4D678499E52F /* LAContextMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BA5A62DA4B543827FF82354 /* LAContextMock.swift */; };
|
||||||
E481C8FDCB6C089963C95344 /* DeviceKit in Frameworks */ = {isa = PBXBuildFile; productRef = BC01130651CB23340B899032 /* DeviceKit */; };
|
E481C8FDCB6C089963C95344 /* DeviceKit in Frameworks */ = {isa = PBXBuildFile; productRef = BC01130651CB23340B899032 /* DeviceKit */; };
|
||||||
@ -1339,7 +1331,6 @@
|
|||||||
30ED584467DB380E3CEFB1DB /* NotificationManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManagerTests.swift; sourceTree = "<group>"; };
|
30ED584467DB380E3CEFB1DB /* NotificationManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManagerTests.swift; sourceTree = "<group>"; };
|
||||||
314F1C79850BE46E8ABEAFCB /* ReadReceipt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadReceipt.swift; sourceTree = "<group>"; };
|
314F1C79850BE46E8ABEAFCB /* ReadReceipt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadReceipt.swift; sourceTree = "<group>"; };
|
||||||
317F41A4B5C4F457AF710666 /* PollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollView.swift; sourceTree = "<group>"; };
|
317F41A4B5C4F457AF710666 /* PollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollView.swift; sourceTree = "<group>"; };
|
||||||
3199367BC31381F67C870976 /* UIKitBackgroundTaskService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTaskService.swift; sourceTree = "<group>"; };
|
|
||||||
31A6314FDC51DA25712D9A81 /* PillContextTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillContextTests.swift; sourceTree = "<group>"; };
|
31A6314FDC51DA25712D9A81 /* PillContextTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillContextTests.swift; sourceTree = "<group>"; };
|
||||||
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>"; };
|
||||||
3203C6566DC17B7AECC1B7FD /* RoomNotificationSettingsUserDefinedScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsUserDefinedScreen.swift; sourceTree = "<group>"; };
|
3203C6566DC17B7AECC1B7FD /* RoomNotificationSettingsUserDefinedScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsUserDefinedScreen.swift; sourceTree = "<group>"; };
|
||||||
@ -1369,7 +1360,6 @@
|
|||||||
38345442415E07A931197C55 /* AppLockScreenPINKeypad.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockScreenPINKeypad.swift; sourceTree = "<group>"; };
|
38345442415E07A931197C55 /* AppLockScreenPINKeypad.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockScreenPINKeypad.swift; sourceTree = "<group>"; };
|
||||||
38354164AF59C5006CD05878 /* GlobalSearchScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalSearchScreenViewModel.swift; sourceTree = "<group>"; };
|
38354164AF59C5006CD05878 /* GlobalSearchScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalSearchScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
38E521D6C2BF8DF0DFB35146 /* DeveloperOptionsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreen.swift; sourceTree = "<group>"; };
|
38E521D6C2BF8DF0DFB35146 /* DeveloperOptionsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreen.swift; sourceTree = "<group>"; };
|
||||||
3948D16F021DFDB2CD26EAA8 /* MockBackgroundTaskService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBackgroundTaskService.swift; sourceTree = "<group>"; };
|
|
||||||
3984C93B8E9B10C92DADF9EE /* RoomDirectorySearchScreenScreenModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchScreenScreenModelProtocol.swift; sourceTree = "<group>"; };
|
3984C93B8E9B10C92DADF9EE /* RoomDirectorySearchScreenScreenModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchScreenScreenModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadableFrameModifier.swift; sourceTree = "<group>"; };
|
398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadableFrameModifier.swift; sourceTree = "<group>"; };
|
||||||
39C0D861FC397AC34BCF089E /* KeychainControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerMock.swift; sourceTree = "<group>"; };
|
39C0D861FC397AC34BCF089E /* KeychainControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerMock.swift; sourceTree = "<group>"; };
|
||||||
@ -1561,7 +1551,6 @@
|
|||||||
6DC30DEC0097B9D217493007 /* ResetRecoveryKeyScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetRecoveryKeyScreen.swift; sourceTree = "<group>"; };
|
6DC30DEC0097B9D217493007 /* ResetRecoveryKeyScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetRecoveryKeyScreen.swift; sourceTree = "<group>"; };
|
||||||
6DF438EAFC732D2D95D34BF6 /* StartChatViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartChatViewModelTests.swift; sourceTree = "<group>"; };
|
6DF438EAFC732D2D95D34BF6 /* StartChatViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartChatViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
6DF81D7F2A6BA9DE3F6F8D9D /* InvitesScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreenViewModel.swift; sourceTree = "<group>"; };
|
6DF81D7F2A6BA9DE3F6F8D9D /* InvitesScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
6DFCAA239095A116976E32C4 /* BackgroundTaskTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskTests.swift; sourceTree = "<group>"; };
|
|
||||||
6E2656184491C505700D2405 /* CollapsibleRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleRoomTimelineView.swift; sourceTree = "<group>"; };
|
6E2656184491C505700D2405 /* CollapsibleRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||||
6E5725BC6C63604CB769145B /* LegalInformationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenViewModelTests.swift; sourceTree = "<group>"; };
|
6E5725BC6C63604CB769145B /* LegalInformationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenViewModelTests.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>"; };
|
||||||
@ -1645,7 +1634,6 @@
|
|||||||
8319173DD66C07F45DC48848 /* IdentityConfirmedScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmedScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
8319173DD66C07F45DC48848 /* IdentityConfirmedScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmedScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
837B440C4705E4B899BCB899 /* RoomDetailsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenViewModel.swift; sourceTree = "<group>"; };
|
837B440C4705E4B899BCB899 /* RoomDetailsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
839E2C35DF3F9C7B54C3CE49 /* RoundedCornerShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedCornerShape.swift; sourceTree = "<group>"; };
|
839E2C35DF3F9C7B54C3CE49 /* RoundedCornerShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedCornerShape.swift; sourceTree = "<group>"; };
|
||||||
83D7FA960FE1A1A63622CC5E /* BackgroundTaskProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskProtocol.swift; sourceTree = "<group>"; };
|
|
||||||
84311D707B09854D67F78BBF /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
84311D707B09854D67F78BBF /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
845DDBDE5A0887E73D38B826 /* InviteUsersViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersViewModelTests.swift; sourceTree = "<group>"; };
|
845DDBDE5A0887E73D38B826 /* InviteUsersViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
848F69921527D31CAACB93AF /* SecureBackupLogoutConfirmationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupLogoutConfirmationScreenViewModelTests.swift; sourceTree = "<group>"; };
|
848F69921527D31CAACB93AF /* SecureBackupLogoutConfirmationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupLogoutConfirmationScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
@ -1965,7 +1953,6 @@
|
|||||||
D196116D2DD3F2757D45FCB7 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/SAS.strings; sourceTree = "<group>"; };
|
D196116D2DD3F2757D45FCB7 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/SAS.strings; sourceTree = "<group>"; };
|
||||||
D1BC84BA0AF11C2128D58ABD /* Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Common.swift; sourceTree = "<group>"; };
|
D1BC84BA0AF11C2128D58ABD /* Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Common.swift; sourceTree = "<group>"; };
|
||||||
D1D8479BB704B7EF696F8ABE /* RoomPollsHistoryScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPollsHistoryScreenCoordinator.swift; sourceTree = "<group>"; };
|
D1D8479BB704B7EF696F8ABE /* RoomPollsHistoryScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPollsHistoryScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
D23C089E93ECE0EF83E182ED /* BackgroundTaskServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskServiceProtocol.swift; sourceTree = "<group>"; };
|
|
||||||
D263254AFE5B7993FFBBF324 /* NSE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NSE.entitlements; sourceTree = "<group>"; };
|
D263254AFE5B7993FFBBF324 /* NSE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NSE.entitlements; sourceTree = "<group>"; };
|
||||||
D26813CCE39221FE30BF22CD /* PlatformViewVersionPredicate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformViewVersionPredicate.swift; sourceTree = "<group>"; };
|
D26813CCE39221FE30BF22CD /* PlatformViewVersionPredicate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformViewVersionPredicate.swift; sourceTree = "<group>"; };
|
||||||
D28F7A6CEEA4A2815B0F0F55 /* SettingsFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFlowCoordinator.swift; sourceTree = "<group>"; };
|
D28F7A6CEEA4A2815B0F0F55 /* SettingsFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFlowCoordinator.swift; sourceTree = "<group>"; };
|
||||||
@ -2067,7 +2054,6 @@
|
|||||||
EA880E78AF4BD24E45A7808C /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
EA880E78AF4BD24E45A7808C /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
EAF710CB1C31F8938EAA3A7D /* RoomChangeRolesScreenSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomChangeRolesScreenSection.swift; sourceTree = "<group>"; };
|
EAF710CB1C31F8938EAA3A7D /* RoomChangeRolesScreenSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomChangeRolesScreenSection.swift; sourceTree = "<group>"; };
|
||||||
EB3B237387B8288A5A938F1B /* UserAgentBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAgentBuilderTests.swift; sourceTree = "<group>"; };
|
EB3B237387B8288A5A938F1B /* UserAgentBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAgentBuilderTests.swift; sourceTree = "<group>"; };
|
||||||
EB49AE5D902C0FE40AF4ADF5 /* UIKitBackgroundTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTask.swift; sourceTree = "<group>"; };
|
|
||||||
EB63761D9F9CE8B23CBD6179 /* PollFormScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenModels.swift; sourceTree = "<group>"; };
|
EB63761D9F9CE8B23CBD6179 /* PollFormScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenModels.swift; sourceTree = "<group>"; };
|
||||||
EB76A9AFC6CCAD4998D9B045 /* IdentityConfirmationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenViewModel.swift; sourceTree = "<group>"; };
|
EB76A9AFC6CCAD4998D9B045 /* IdentityConfirmationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
EBEB8D9F4940E161B18FE4BC /* UITestsNotificationCenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsNotificationCenter.swift; sourceTree = "<group>"; };
|
EBEB8D9F4940E161B18FE4BC /* UITestsNotificationCenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsNotificationCenter.swift; sourceTree = "<group>"; };
|
||||||
@ -2327,7 +2313,6 @@
|
|||||||
7803E03F759061C948D66B7E /* AppLock */,
|
7803E03F759061C948D66B7E /* AppLock */,
|
||||||
FCE7249621F507F34A8122FB /* Audio */,
|
FCE7249621F507F34A8122FB /* Audio */,
|
||||||
AAFDD509929A0CCF8BCE51EB /* Authentication */,
|
AAFDD509929A0CCF8BCE51EB /* Authentication */,
|
||||||
C488FC0F4ACF26D0A2C5246E /* BackgroundTasks */,
|
|
||||||
0ED3F5C21537519389C07644 /* BugReport */,
|
0ED3F5C21537519389C07644 /* BugReport */,
|
||||||
8039515BAA53B7C3275AC64A /* Client */,
|
8039515BAA53B7C3275AC64A /* Client */,
|
||||||
8C3BAE06B336D97DABBE2509 /* CreateRoom */,
|
8C3BAE06B336D97DABBE2509 /* CreateRoom */,
|
||||||
@ -3551,7 +3536,6 @@
|
|||||||
C55CC239AE12339C565F6C9A /* AudioRecorderStateTests.swift */,
|
C55CC239AE12339C565F6C9A /* AudioRecorderStateTests.swift */,
|
||||||
2441E2424E78A40FC95DBA76 /* AudioRecorderTests.swift */,
|
2441E2424E78A40FC95DBA76 /* AudioRecorderTests.swift */,
|
||||||
8FB89DC7F9A4A91020037001 /* AuthenticationStartScreenViewModelTests.swift */,
|
8FB89DC7F9A4A91020037001 /* AuthenticationStartScreenViewModelTests.swift */,
|
||||||
6DFCAA239095A116976E32C4 /* BackgroundTaskTests.swift */,
|
|
||||||
240610DF32F3213BEC5611D7 /* BlockedUsersScreenViewModelTests.swift */,
|
240610DF32F3213BEC5611D7 /* BlockedUsersScreenViewModelTests.swift */,
|
||||||
EFFD3200F9960D4996159F10 /* BugReportServiceTests.swift */,
|
EFFD3200F9960D4996159F10 /* BugReportServiceTests.swift */,
|
||||||
7AB7ED3A898B07976F3AA90F /* BugReportViewModelTests.swift */,
|
7AB7ED3A898B07976F3AA90F /* BugReportViewModelTests.swift */,
|
||||||
@ -3689,7 +3673,6 @@
|
|||||||
children = (
|
children = (
|
||||||
3EF1AC723C2609C7705569CA /* MediaLoaderTests.swift */,
|
3EF1AC723C2609C7705569CA /* MediaLoaderTests.swift */,
|
||||||
62A81CCC2516D9CF9322DF01 /* MediaProviderTests.swift */,
|
62A81CCC2516D9CF9322DF01 /* MediaProviderTests.swift */,
|
||||||
3948D16F021DFDB2CD26EAA8 /* MockBackgroundTaskService.swift */,
|
|
||||||
AC1DA29A5A041CC0BACA7CB0 /* MockImageCache.swift */,
|
AC1DA29A5A041CC0BACA7CB0 /* MockImageCache.swift */,
|
||||||
4AB7D7DAAAF662DED9D02379 /* MockMediaLoader.swift */,
|
4AB7D7DAAAF662DED9D02379 /* MockMediaLoader.swift */,
|
||||||
);
|
);
|
||||||
@ -4672,17 +4655,6 @@
|
|||||||
path = RoomDirectorySearchScreen;
|
path = RoomDirectorySearchScreen;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
C488FC0F4ACF26D0A2C5246E /* BackgroundTasks */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
83D7FA960FE1A1A63622CC5E /* BackgroundTaskProtocol.swift */,
|
|
||||||
D23C089E93ECE0EF83E182ED /* BackgroundTaskServiceProtocol.swift */,
|
|
||||||
EB49AE5D902C0FE40AF4ADF5 /* UIKitBackgroundTask.swift */,
|
|
||||||
3199367BC31381F67C870976 /* UIKitBackgroundTaskService.swift */,
|
|
||||||
);
|
|
||||||
path = BackgroundTasks;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
C844840F3DD48A154C65AE0C /* View */ = {
|
C844840F3DD48A154C65AE0C /* View */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -5661,8 +5633,6 @@
|
|||||||
CDCA8A559E098503DDE29477 /* AttributedStringBuilder.swift in Sources */,
|
CDCA8A559E098503DDE29477 /* AttributedStringBuilder.swift in Sources */,
|
||||||
BA43D782BE85C7F5F20C624A /* AttributedStringBuilderProtocol.swift in Sources */,
|
BA43D782BE85C7F5F20C624A /* AttributedStringBuilderProtocol.swift in Sources */,
|
||||||
968A5B890004526AB58A217C /* AvatarSize.swift in Sources */,
|
968A5B890004526AB58A217C /* AvatarSize.swift in Sources */,
|
||||||
08E02C56E8B277A22C5E5BA5 /* BackgroundTaskProtocol.swift in Sources */,
|
|
||||||
D8ED2FCF46D63A7357E9D502 /* BackgroundTaskServiceProtocol.swift in Sources */,
|
|
||||||
9A3B0CDF097E3838FB1B9595 /* Bundle.swift in Sources */,
|
9A3B0CDF097E3838FB1B9595 /* Bundle.swift in Sources */,
|
||||||
B5618E3C948584E5C1F67033 /* DTHTMLElement+AttributedStringBuilder.swift in Sources */,
|
B5618E3C948584E5C1F67033 /* DTHTMLElement+AttributedStringBuilder.swift in Sources */,
|
||||||
DFCA89C4EC2A5332ED6B441F /* DataProtectionManager.swift in Sources */,
|
DFCA89C4EC2A5332ED6B441F /* DataProtectionManager.swift in Sources */,
|
||||||
@ -5736,7 +5706,6 @@
|
|||||||
3042527CB344A9EF1157FC26 /* AudioRecorderStateTests.swift in Sources */,
|
3042527CB344A9EF1157FC26 /* AudioRecorderStateTests.swift in Sources */,
|
||||||
192A3CDCD0174AD1E4A128E4 /* AudioRecorderTests.swift in Sources */,
|
192A3CDCD0174AD1E4A128E4 /* AudioRecorderTests.swift in Sources */,
|
||||||
8ED8AF57A06F5EE9978ED23F /* AuthenticationStartScreenViewModelTests.swift in Sources */,
|
8ED8AF57A06F5EE9978ED23F /* AuthenticationStartScreenViewModelTests.swift in Sources */,
|
||||||
0F9E38A75337D0146652ACAB /* BackgroundTaskTests.swift in Sources */,
|
|
||||||
CEAEA57B7665C8E790599A78 /* BlockedUsersScreenViewModelTests.swift in Sources */,
|
CEAEA57B7665C8E790599A78 /* BlockedUsersScreenViewModelTests.swift in Sources */,
|
||||||
7F61F9ACD5EC9E845EF3EFBF /* BugReportServiceTests.swift in Sources */,
|
7F61F9ACD5EC9E845EF3EFBF /* BugReportServiceTests.swift in Sources */,
|
||||||
C7CFDB4929DDD9A3B5BA085D /* BugReportViewModelTests.swift in Sources */,
|
C7CFDB4929DDD9A3B5BA085D /* BugReportViewModelTests.swift in Sources */,
|
||||||
@ -5772,7 +5741,6 @@
|
|||||||
B9A8C34A00D03094C0CF56F3 /* MediaUploadPreviewScreenViewModelTests.swift in Sources */,
|
B9A8C34A00D03094C0CF56F3 /* MediaUploadPreviewScreenViewModelTests.swift in Sources */,
|
||||||
23701DE32ACD6FD40AA992C3 /* MediaUploadingPreprocessorTests.swift in Sources */,
|
23701DE32ACD6FD40AA992C3 /* MediaUploadingPreprocessorTests.swift in Sources */,
|
||||||
F777C6FEE7D106136E2ED2B2 /* MessageForwardingScreenViewModelTests.swift in Sources */,
|
F777C6FEE7D106136E2ED2B2 /* MessageForwardingScreenViewModelTests.swift in Sources */,
|
||||||
4E8F17EBA24FBBA6ABB62ECB /* MockBackgroundTaskService.swift in Sources */,
|
|
||||||
1146E9EDCF8344F7D6E0D553 /* MockCoder.swift in Sources */,
|
1146E9EDCF8344F7D6E0D553 /* MockCoder.swift in Sources */,
|
||||||
DC68E866D6E664B0D2B06E74 /* MockImageCache.swift in Sources */,
|
DC68E866D6E664B0D2B06E74 /* MockImageCache.swift in Sources */,
|
||||||
A896998A6784DB6F16E912F4 /* MockMediaLoader.swift in Sources */,
|
A896998A6784DB6F16E912F4 /* MockMediaLoader.swift in Sources */,
|
||||||
@ -5944,8 +5912,6 @@
|
|||||||
6146996D5C4DDD5DA816FC87 /* AuthenticationTextFieldStyle.swift in Sources */,
|
6146996D5C4DDD5DA816FC87 /* AuthenticationTextFieldStyle.swift in Sources */,
|
||||||
4AAA8606FBA290E23D15422E /* AvatarHeaderView.swift in Sources */,
|
4AAA8606FBA290E23D15422E /* AvatarHeaderView.swift in Sources */,
|
||||||
D876EC0FED3B6D46C806912A /* AvatarSize.swift in Sources */,
|
D876EC0FED3B6D46C806912A /* AvatarSize.swift in Sources */,
|
||||||
B3066502FA56D9199846C5E7 /* BackgroundTaskProtocol.swift in Sources */,
|
|
||||||
D798A150BB6569FC07CBEB25 /* BackgroundTaskServiceProtocol.swift in Sources */,
|
|
||||||
A4B0BAD62A12ED76BD611B79 /* BadgeView.swift in Sources */,
|
A4B0BAD62A12ED76BD611B79 /* BadgeView.swift in Sources */,
|
||||||
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */,
|
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */,
|
||||||
EB9F4688006B52E69DF5358F /* BlankFormCoordinator.swift in Sources */,
|
EB9F4688006B52E69DF5358F /* BlankFormCoordinator.swift in Sources */,
|
||||||
@ -6541,8 +6507,6 @@
|
|||||||
36AC963F2F04069B7FF1AA0C /* UIConstants.swift in Sources */,
|
36AC963F2F04069B7FF1AA0C /* UIConstants.swift in Sources */,
|
||||||
A37EED79941AD3B7140B3822 /* UIDevice.swift in Sources */,
|
A37EED79941AD3B7140B3822 /* UIDevice.swift in Sources */,
|
||||||
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */,
|
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */,
|
||||||
E3E3D645C7F80DD64A86D936 /* UIKitBackgroundTask.swift in Sources */,
|
|
||||||
CB0C53B67DA62F7E30DDD720 /* UIKitBackgroundTaskService.swift in Sources */,
|
|
||||||
E96005321849DBD7C72A28F2 /* UITestsAppCoordinator.swift in Sources */,
|
E96005321849DBD7C72A28F2 /* UITestsAppCoordinator.swift in Sources */,
|
||||||
384D6B9A7DFD7260139D6852 /* UITestsNotificationCenter.swift in Sources */,
|
384D6B9A7DFD7260139D6852 /* UITestsNotificationCenter.swift in Sources */,
|
||||||
22882C710BC99EC34A5024A0 /* UITestsScreenIdentifier.swift in Sources */,
|
22882C710BC99EC34A5024A0 /* UITestsScreenIdentifier.swift in Sources */,
|
||||||
|
@ -20,7 +20,7 @@ import MatrixRustSDK
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Version
|
import Version
|
||||||
|
|
||||||
class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDelegate, NotificationManagerDelegate, WindowManagerDelegate {
|
class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDelegate, NotificationManagerDelegate, SecureWindowManagerDelegate {
|
||||||
private let stateMachine: AppCoordinatorStateMachine
|
private let stateMachine: AppCoordinatorStateMachine
|
||||||
private let navigationRootCoordinator: NavigationRootCoordinator
|
private let navigationRootCoordinator: NavigationRootCoordinator
|
||||||
private let userSessionStore: UserSessionStoreProtocol
|
private let userSessionStore: UserSessionStoreProtocol
|
||||||
@ -29,7 +29,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
private let appDelegate: AppDelegate
|
private let appDelegate: AppDelegate
|
||||||
|
|
||||||
/// Common background task to continue long-running tasks in the background.
|
/// Common background task to continue long-running tasks in the background.
|
||||||
private var backgroundTask: BackgroundTaskProtocol?
|
private var backgroundTask: UIBackgroundTaskIdentifier?
|
||||||
|
|
||||||
private var isSuspended = false
|
private var isSuspended = false
|
||||||
|
|
||||||
@ -50,15 +50,12 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
private var appLockSetupFlowCoordinator: AppLockSetupFlowCoordinator?
|
private var appLockSetupFlowCoordinator: AppLockSetupFlowCoordinator?
|
||||||
private var userSessionFlowCoordinator: UserSessionFlowCoordinator?
|
private var userSessionFlowCoordinator: UserSessionFlowCoordinator?
|
||||||
private var softLogoutCoordinator: SoftLogoutScreenCoordinator?
|
private var softLogoutCoordinator: SoftLogoutScreenCoordinator?
|
||||||
|
|
||||||
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
|
||||||
|
|
||||||
private var appDelegateObserver: AnyCancellable?
|
private var appDelegateObserver: AnyCancellable?
|
||||||
private var userSessionObserver: AnyCancellable?
|
private var userSessionObserver: AnyCancellable?
|
||||||
private var clientProxyObserver: AnyCancellable?
|
private var clientProxyObserver: AnyCancellable?
|
||||||
private var cancellables = Set<AnyCancellable>()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
let windowManager: WindowManagerProtocol
|
let windowManager: SecureWindowManagerProtocol
|
||||||
let notificationManager: NotificationManagerProtocol
|
let notificationManager: NotificationManagerProtocol
|
||||||
|
|
||||||
private let appRouteURLParser: AppRouteURLParser
|
private let appRouteURLParser: AppRouteURLParser
|
||||||
@ -103,12 +100,9 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
|
|
||||||
navigationRootCoordinator.setRootCoordinator(SplashScreenCoordinator())
|
navigationRootCoordinator.setRootCoordinator(SplashScreenCoordinator())
|
||||||
|
|
||||||
backgroundTaskService = UIKitBackgroundTaskService(appMediator: appMediator)
|
|
||||||
|
|
||||||
let keychainController = KeychainController(service: .sessions,
|
let keychainController = KeychainController(service: .sessions,
|
||||||
accessGroup: InfoPlistReader.main.keychainAccessGroupIdentifier)
|
accessGroup: InfoPlistReader.main.keychainAccessGroupIdentifier)
|
||||||
userSessionStore = UserSessionStore(keychainController: keychainController,
|
userSessionStore = UserSessionStore(keychainController: keychainController)
|
||||||
backgroundTaskService: backgroundTaskService)
|
|
||||||
|
|
||||||
let appLockService = AppLockService(keychainController: keychainController, appSettings: appSettings)
|
let appLockService = AppLockService(keychainController: keychainController, appSettings: appSettings)
|
||||||
let appLockNavigationCoordinator = NavigationRootCoordinator()
|
let appLockNavigationCoordinator = NavigationRootCoordinator()
|
||||||
@ -227,7 +221,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
|
|
||||||
// MARK: - WindowManagerDelegate
|
// MARK: - WindowManagerDelegate
|
||||||
|
|
||||||
func windowManagerDidConfigureWindows(_ windowManager: WindowManagerProtocol) {
|
func windowManagerDidConfigureWindows(_ windowManager: SecureWindowManagerProtocol) {
|
||||||
windowManager.alternateWindow.rootViewController = UIHostingController(rootView: appLockFlowCoordinator.toPresentable())
|
windowManager.alternateWindow.rootViewController = UIHostingController(rootView: appLockFlowCoordinator.toPresentable())
|
||||||
ServiceLocator.shared.userIndicatorController.window = windowManager.overlayWindow
|
ServiceLocator.shared.userIndicatorController.window = windowManager.overlayWindow
|
||||||
}
|
}
|
||||||
@ -413,8 +407,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
appMediator: appMediator,
|
appMediator: appMediator,
|
||||||
appSettings: appSettings,
|
appSettings: appSettings,
|
||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||||
orientationManager: windowManager)
|
|
||||||
authenticationFlowCoordinator?.delegate = self
|
authenticationFlowCoordinator?.delegate = self
|
||||||
|
|
||||||
authenticationFlowCoordinator?.start()
|
authenticationFlowCoordinator?.start()
|
||||||
@ -469,7 +462,6 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
|
|
||||||
let userSessionFlowCoordinator = UserSessionFlowCoordinator(userSession: userSession,
|
let userSessionFlowCoordinator = UserSessionFlowCoordinator(userSession: userSession,
|
||||||
navigationRootCoordinator: navigationRootCoordinator,
|
navigationRootCoordinator: navigationRootCoordinator,
|
||||||
windowManager: windowManager,
|
|
||||||
appLockService: appLockFlowCoordinator.appLockService,
|
appLockService: appLockFlowCoordinator.appLockService,
|
||||||
bugReportService: ServiceLocator.shared.bugReportService,
|
bugReportService: ServiceLocator.shared.bugReportService,
|
||||||
roomTimelineControllerFactory: RoomTimelineControllerFactory(),
|
roomTimelineControllerFactory: RoomTimelineControllerFactory(),
|
||||||
@ -770,14 +762,16 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
guard backgroundTask == nil else {
|
guard backgroundTask == nil else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
backgroundTask = backgroundTaskService.startBackgroundTask(withName: "SuspendApp: \(UUID().uuidString)") { [weak self] in
|
backgroundTask = appMediator.beginBackgroundTask { [weak self] in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
stopSync()
|
stopSync()
|
||||||
|
|
||||||
backgroundTask?.stop()
|
if let backgroundTask {
|
||||||
backgroundTask = nil
|
appMediator.endBackgroundTask(backgroundTask)
|
||||||
|
self.backgroundTask = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isSuspended = true
|
isSuspended = true
|
||||||
@ -791,8 +785,10 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
private func applicationDidBecomeActive() {
|
private func applicationDidBecomeActive() {
|
||||||
MXLog.info("Application did become active")
|
MXLog.info("Application did become active")
|
||||||
|
|
||||||
backgroundTask?.stop()
|
if let backgroundTask {
|
||||||
backgroundTask = nil
|
appMediator.endBackgroundTask(backgroundTask)
|
||||||
|
self.backgroundTask = nil
|
||||||
|
}
|
||||||
|
|
||||||
if isSuspended {
|
if isSuspended {
|
||||||
startSync()
|
startSync()
|
||||||
|
@ -17,6 +17,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
protocol AppCoordinatorProtocol: CoordinatorProtocol {
|
protocol AppCoordinatorProtocol: CoordinatorProtocol {
|
||||||
var windowManager: WindowManagerProtocol { get }
|
var windowManager: SecureWindowManagerProtocol { get }
|
||||||
@discardableResult func handleDeepLink(_ url: URL, isExternalURL: Bool) -> Bool
|
@discardableResult func handleDeepLink(_ url: URL, isExternalURL: Bool) -> Bool
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class AppMediator: AppMediatorProtocol {
|
class AppMediator: AppMediatorProtocol {
|
||||||
private let windowManager: WindowManagerProtocol
|
let windowManager: WindowManagerProtocol
|
||||||
|
|
||||||
init(windowManager: WindowManagerProtocol) {
|
init(windowManager: WindowManagerProtocol) {
|
||||||
self.windowManager = windowManager
|
self.windowManager = windowManager
|
||||||
@ -28,7 +28,6 @@ class AppMediator: AppMediatorProtocol {
|
|||||||
UIApplication.shared
|
UIApplication.shared
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
|
||||||
var appState: UIApplication.State {
|
var appState: UIApplication.State {
|
||||||
switch application.applicationState {
|
switch application.applicationState {
|
||||||
case .active:
|
case .active:
|
||||||
@ -42,12 +41,8 @@ class AppMediator: AppMediatorProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var backgroundTimeRemaining: TimeInterval {
|
func beginBackgroundTask(expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier {
|
||||||
application.backgroundTimeRemaining
|
application.beginBackgroundTask(expirationHandler: handler)
|
||||||
}
|
|
||||||
|
|
||||||
func beginBackgroundTask(withName taskName: String?, expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier {
|
|
||||||
application.beginBackgroundTask(withName: taskName, expirationHandler: handler)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func endBackgroundTask(_ identifier: UIBackgroundTaskIdentifier) {
|
func endBackgroundTask(_ identifier: UIBackgroundTaskIdentifier) {
|
||||||
|
@ -18,12 +18,13 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
// sourcery: AutoMockable
|
// sourcery: AutoMockable
|
||||||
|
@MainActor
|
||||||
protocol AppMediatorProtocol {
|
protocol AppMediatorProtocol {
|
||||||
|
var windowManager: WindowManagerProtocol { get }
|
||||||
|
|
||||||
var appState: UIApplication.State { get }
|
var appState: UIApplication.State { get }
|
||||||
|
|
||||||
var backgroundTimeRemaining: TimeInterval { get }
|
func beginBackgroundTask(expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier
|
||||||
|
|
||||||
func beginBackgroundTask(withName taskName: String?, expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier
|
|
||||||
|
|
||||||
func endBackgroundTask(_ identifier: UIBackgroundTaskIdentifier)
|
func endBackgroundTask(_ identifier: UIBackgroundTaskIdentifier)
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import SwiftUI
|
|||||||
///
|
///
|
||||||
/// We don't support multiple scenes right now, so the implementation is pretty basic.
|
/// We don't support multiple scenes right now, so the implementation is pretty basic.
|
||||||
class SceneDelegate: NSObject, UIWindowSceneDelegate {
|
class SceneDelegate: NSObject, UIWindowSceneDelegate {
|
||||||
weak static var windowManager: WindowManagerProtocol!
|
weak static var windowManager: SecureWindowManagerProtocol!
|
||||||
|
|
||||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||||
guard let windowScene = scene as? UIWindowScene else { return }
|
guard let windowScene = scene as? UIWindowScene else { return }
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
import Combine
|
import Combine
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
class WindowManager: WindowManagerProtocol {
|
class WindowManager: SecureWindowManagerProtocol {
|
||||||
private let appDelegate: AppDelegate
|
private let appDelegate: AppDelegate
|
||||||
weak var windowScene: UIWindowScene?
|
weak var windowScene: UIWindowScene?
|
||||||
weak var delegate: WindowManagerDelegate?
|
weak var delegate: SecureWindowManagerDelegate?
|
||||||
|
|
||||||
private(set) var mainWindow: UIWindow!
|
private(set) var mainWindow: UIWindow!
|
||||||
private(set) var overlayWindow: UIWindow!
|
private(set) var overlayWindow: UIWindow!
|
||||||
|
@ -16,18 +16,29 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
protocol WindowManagerDelegate: AnyObject {
|
protocol SecureWindowManagerDelegate: AnyObject {
|
||||||
/// The window manager has configured its windows.
|
/// The window manager has configured its windows.
|
||||||
func windowManagerDidConfigureWindows(_ windowManager: WindowManagerProtocol)
|
func windowManagerDidConfigureWindows(_ windowManager: SecureWindowManagerProtocol)
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
|
protocol SecureWindowManagerProtocol: WindowManagerProtocol {
|
||||||
|
var delegate: SecureWindowManagerDelegate? { get set }
|
||||||
|
|
||||||
|
/// Configures the window manager to operate on the supplied scene.
|
||||||
|
func configure(with windowScene: UIWindowScene)
|
||||||
|
|
||||||
|
/// Shows the main and overlay window combo, hiding the alternate window.
|
||||||
|
func switchToMain()
|
||||||
|
|
||||||
|
/// Shows the alternate window, hiding the main and overlay combo.
|
||||||
|
func switchToAlternate()
|
||||||
|
}
|
||||||
|
|
||||||
/// A window manager that supports switching between a main app window with an overlay and
|
/// A window manager that supports switching between a main app window with an overlay and
|
||||||
/// an alternate window to switch contexts whilst also preserving the main view hierarchy.
|
/// an alternate window to switch contexts whilst also preserving the main view hierarchy.
|
||||||
/// Heavily inspired by https://www.fivestars.blog/articles/swiftui-windows/
|
/// Heavily inspired by https://www.fivestars.blog/articles/swiftui-windows/
|
||||||
protocol WindowManagerProtocol: AnyObject, OrientationManagerProtocol {
|
protocol WindowManagerProtocol: AnyObject, OrientationManagerProtocol {
|
||||||
var delegate: WindowManagerDelegate? { get set }
|
|
||||||
|
|
||||||
/// The app's main window (we only support a single scene).
|
/// The app's main window (we only support a single scene).
|
||||||
var mainWindow: UIWindow! { get }
|
var mainWindow: UIWindow! { get }
|
||||||
/// Presented on top of the main window, to display e.g. user indicators.
|
/// Presented on top of the main window, to display e.g. user indicators.
|
||||||
@ -40,15 +51,6 @@ protocol WindowManagerProtocol: AnyObject, OrientationManagerProtocol {
|
|||||||
/// All the windows being managed
|
/// All the windows being managed
|
||||||
var windows: [UIWindow] { get }
|
var windows: [UIWindow] { get }
|
||||||
|
|
||||||
/// Configures the window manager to operate on the supplied scene.
|
|
||||||
func configure(with windowScene: UIWindowScene)
|
|
||||||
|
|
||||||
/// Shows the main and overlay window combo, hiding the alternate window.
|
|
||||||
func switchToMain()
|
|
||||||
|
|
||||||
/// Shows the alternate window, hiding the main and overlay combo.
|
|
||||||
func switchToAlternate()
|
|
||||||
|
|
||||||
/// Makes the global search window key. Used to get automatic text field focus.
|
/// Makes the global search window key. Used to get automatic text field focus.
|
||||||
func showGlobalSearch()
|
func showGlobalSearch()
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
private let analytics: AnalyticsService
|
private let analytics: AnalyticsService
|
||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
private let orientationManager: OrientationManagerProtocol
|
|
||||||
|
|
||||||
private var cancellables = Set<AnyCancellable>()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
@ -48,8 +47,7 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
appMediator: AppMediatorProtocol,
|
appMediator: AppMediatorProtocol,
|
||||||
appSettings: AppSettings,
|
appSettings: AppSettings,
|
||||||
analytics: AnalyticsService,
|
analytics: AnalyticsService,
|
||||||
userIndicatorController: UserIndicatorControllerProtocol,
|
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||||
orientationManager: WindowManagerProtocol) {
|
|
||||||
self.authenticationService = authenticationService
|
self.authenticationService = authenticationService
|
||||||
self.bugReportService = bugReportService
|
self.bugReportService = bugReportService
|
||||||
self.navigationRootCoordinator = navigationRootCoordinator
|
self.navigationRootCoordinator = navigationRootCoordinator
|
||||||
@ -57,7 +55,6 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
self.appSettings = appSettings
|
self.appSettings = appSettings
|
||||||
self.analytics = analytics
|
self.analytics = analytics
|
||||||
self.userIndicatorController = userIndicatorController
|
self.userIndicatorController = userIndicatorController
|
||||||
self.orientationManager = orientationManager
|
|
||||||
|
|
||||||
navigationStackCoordinator = NavigationStackCoordinator()
|
navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
}
|
}
|
||||||
@ -110,7 +107,7 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
private func startQRCodeLogin() {
|
private func startQRCodeLogin() {
|
||||||
let coordinator = QRCodeLoginScreenCoordinator(parameters: .init(qrCodeLoginService: QRCodeLoginService(),
|
let coordinator = QRCodeLoginScreenCoordinator(parameters: .init(qrCodeLoginService: QRCodeLoginService(),
|
||||||
orientationManager: orientationManager,
|
orientationManager: appMediator.windowManager,
|
||||||
appMediator: appMediator))
|
appMediator: appMediator))
|
||||||
coordinator.actionsPublisher.sink { [weak self] action in
|
coordinator.actionsPublisher.sink { [weak self] action in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
|
@ -50,7 +50,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
private let analytics: AnalyticsService
|
private let analytics: AnalyticsService
|
||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
private let orientationManager: OrientationManagerProtocol
|
|
||||||
|
|
||||||
private var roomProxy: RoomProxyProtocol!
|
private var roomProxy: RoomProxyProtocol!
|
||||||
|
|
||||||
@ -81,8 +80,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
appMediator: AppMediatorProtocol,
|
appMediator: AppMediatorProtocol,
|
||||||
appSettings: AppSettings,
|
appSettings: AppSettings,
|
||||||
analytics: AnalyticsService,
|
analytics: AnalyticsService,
|
||||||
userIndicatorController: UserIndicatorControllerProtocol,
|
userIndicatorController: UserIndicatorControllerProtocol) async {
|
||||||
orientationManager: OrientationManagerProtocol) async {
|
|
||||||
self.roomID = roomID
|
self.roomID = roomID
|
||||||
self.userSession = userSession
|
self.userSession = userSession
|
||||||
self.isChildFlow = isChildFlow
|
self.isChildFlow = isChildFlow
|
||||||
@ -93,7 +91,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
self.appSettings = appSettings
|
self.appSettings = appSettings
|
||||||
self.analytics = analytics
|
self.analytics = analytics
|
||||||
self.userIndicatorController = userIndicatorController
|
self.userIndicatorController = userIndicatorController
|
||||||
self.orientationManager = orientationManager
|
|
||||||
|
|
||||||
setupStateMachine()
|
setupStateMachine()
|
||||||
|
|
||||||
@ -695,7 +692,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
mediaProvider: userSession.mediaProvider,
|
mediaProvider: userSession.mediaProvider,
|
||||||
navigationStackCoordinator: stackCoordinator,
|
navigationStackCoordinator: stackCoordinator,
|
||||||
userIndicatorController: userIndicatorController,
|
userIndicatorController: userIndicatorController,
|
||||||
orientationManager: orientationManager)
|
orientationManager: appMediator.windowManager)
|
||||||
let roomDetailsEditCoordinator = RoomDetailsEditScreenCoordinator(parameters: roomDetailsEditParameters)
|
let roomDetailsEditCoordinator = RoomDetailsEditScreenCoordinator(parameters: roomDetailsEditParameters)
|
||||||
|
|
||||||
roomDetailsEditCoordinator.actions.sink { [weak self] action in
|
roomDetailsEditCoordinator.actions.sink { [weak self] action in
|
||||||
@ -752,7 +749,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
let mediaPickerCoordinator = MediaPickerScreenCoordinator(userIndicatorController: userIndicatorController,
|
let mediaPickerCoordinator = MediaPickerScreenCoordinator(userIndicatorController: userIndicatorController,
|
||||||
source: source,
|
source: source,
|
||||||
orientationManager: orientationManager) { [weak self] action in
|
orientationManager: appMediator.windowManager) { [weak self] action in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1239,8 +1236,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
appMediator: appMediator,
|
appMediator: appMediator,
|
||||||
appSettings: appSettings,
|
appSettings: appSettings,
|
||||||
analytics: analytics,
|
analytics: analytics,
|
||||||
userIndicatorController: userIndicatorController,
|
userIndicatorController: userIndicatorController)
|
||||||
orientationManager: orientationManager)
|
|
||||||
coordinator.actions.sink { [weak self] action in
|
coordinator.actions.sink { [weak self] action in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
private let userSession: UserSessionProtocol
|
private let userSession: UserSessionProtocol
|
||||||
private let navigationRootCoordinator: NavigationRootCoordinator
|
private let navigationRootCoordinator: NavigationRootCoordinator
|
||||||
private let navigationSplitCoordinator: NavigationSplitCoordinator
|
private let navigationSplitCoordinator: NavigationSplitCoordinator
|
||||||
private let windowManager: WindowManagerProtocol
|
|
||||||
private let bugReportService: BugReportServiceProtocol
|
private let bugReportService: BugReportServiceProtocol
|
||||||
private let appMediator: AppMediatorProtocol
|
private let appMediator: AppMediatorProtocol
|
||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
@ -68,7 +67,6 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
init(userSession: UserSessionProtocol,
|
init(userSession: UserSessionProtocol,
|
||||||
navigationRootCoordinator: NavigationRootCoordinator,
|
navigationRootCoordinator: NavigationRootCoordinator,
|
||||||
windowManager: WindowManagerProtocol,
|
|
||||||
appLockService: AppLockServiceProtocol,
|
appLockService: AppLockServiceProtocol,
|
||||||
bugReportService: BugReportServiceProtocol,
|
bugReportService: BugReportServiceProtocol,
|
||||||
roomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol,
|
roomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol,
|
||||||
@ -80,7 +78,6 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
stateMachine = UserSessionFlowCoordinatorStateMachine()
|
stateMachine = UserSessionFlowCoordinatorStateMachine()
|
||||||
self.userSession = userSession
|
self.userSession = userSession
|
||||||
self.navigationRootCoordinator = navigationRootCoordinator
|
self.navigationRootCoordinator = navigationRootCoordinator
|
||||||
self.windowManager = windowManager
|
|
||||||
self.bugReportService = bugReportService
|
self.bugReportService = bugReportService
|
||||||
self.roomTimelineControllerFactory = roomTimelineControllerFactory
|
self.roomTimelineControllerFactory = roomTimelineControllerFactory
|
||||||
self.appMediator = appMediator
|
self.appMediator = appMediator
|
||||||
@ -96,7 +93,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
navigationSplitCoordinator.setSidebarCoordinator(sidebarNavigationStackCoordinator)
|
navigationSplitCoordinator.setSidebarCoordinator(sidebarNavigationStackCoordinator)
|
||||||
|
|
||||||
settingsFlowCoordinator = SettingsFlowCoordinator(parameters: .init(userSession: userSession,
|
settingsFlowCoordinator = SettingsFlowCoordinator(parameters: .init(userSession: userSession,
|
||||||
windowManager: windowManager,
|
windowManager: appMediator.windowManager,
|
||||||
appLockService: appLockService,
|
appLockService: appLockService,
|
||||||
bugReportService: bugReportService,
|
bugReportService: bugReportService,
|
||||||
notificationSettings: userSession.clientProxy.notificationSettings,
|
notificationSettings: userSession.clientProxy.notificationSettings,
|
||||||
@ -427,8 +424,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
appMediator: appMediator,
|
appMediator: appMediator,
|
||||||
appSettings: appSettings,
|
appSettings: appSettings,
|
||||||
analytics: analytics,
|
analytics: analytics,
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||||
orientationManager: windowManager)
|
|
||||||
|
|
||||||
coordinator.actions.sink { [weak self] action in
|
coordinator.actions.sink { [weak self] action in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
@ -480,7 +476,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
let startChatNavigationStackCoordinator = NavigationStackCoordinator()
|
let startChatNavigationStackCoordinator = NavigationStackCoordinator()
|
||||||
|
|
||||||
let userDiscoveryService = UserDiscoveryService(clientProxy: userSession.clientProxy)
|
let userDiscoveryService = UserDiscoveryService(clientProxy: userSession.clientProxy)
|
||||||
let parameters = StartChatScreenCoordinatorParameters(orientationManager: windowManager,
|
let parameters = StartChatScreenCoordinatorParameters(orientationManager: appMediator.windowManager,
|
||||||
userSession: userSession,
|
userSession: userSession,
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
navigationStackCoordinator: startChatNavigationStackCoordinator,
|
navigationStackCoordinator: startChatNavigationStackCoordinator,
|
||||||
@ -609,14 +605,14 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
let hostingController = UIHostingController(rootView: coordinator.toPresentable())
|
let hostingController = UIHostingController(rootView: coordinator.toPresentable())
|
||||||
hostingController.view.backgroundColor = .clear
|
hostingController.view.backgroundColor = .clear
|
||||||
windowManager.globalSearchWindow.rootViewController = hostingController
|
appMediator.windowManager.globalSearchWindow.rootViewController = hostingController
|
||||||
|
|
||||||
windowManager.showGlobalSearch()
|
appMediator.windowManager.showGlobalSearch()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func dismissGlobalSearch() {
|
private func dismissGlobalSearch() {
|
||||||
windowManager.globalSearchWindow.rootViewController = nil
|
appMediator.windowManager.globalSearchWindow.rootViewController = nil
|
||||||
windowManager.hideGlobalSearch()
|
appMediator.windowManager.hideGlobalSearch()
|
||||||
|
|
||||||
globalSearchScreenCoordinator = nil
|
globalSearchScreenCoordinator = nil
|
||||||
}
|
}
|
||||||
|
@ -18,44 +18,11 @@ import UIKit
|
|||||||
|
|
||||||
extension AppMediatorMock {
|
extension AppMediatorMock {
|
||||||
static var `default`: AppMediatorProtocol {
|
static var `default`: AppMediatorProtocol {
|
||||||
AppMediatorMock(withState: .active,
|
let mock = AppMediatorMock()
|
||||||
backgroundTimeRemaining: 10,
|
|
||||||
allowTasks: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
static var mockBroken: AppMediatorProtocol {
|
|
||||||
AppMediatorMock(withState: .inactive,
|
|
||||||
backgroundTimeRemaining: 0,
|
|
||||||
allowTasks: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
static var mockAboutToSuspend: AppMediatorProtocol {
|
|
||||||
AppMediatorMock(withState: .background,
|
|
||||||
backgroundTimeRemaining: 2,
|
|
||||||
allowTasks: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
private static var bgTaskIdentifier = 0
|
|
||||||
|
|
||||||
convenience init(withState applicationState: UIApplication.State,
|
|
||||||
backgroundTimeRemaining: TimeInterval,
|
|
||||||
allowTasks: Bool) {
|
|
||||||
self.init()
|
|
||||||
|
|
||||||
underlyingAppState = applicationState
|
mock.underlyingAppState = .active
|
||||||
underlyingBackgroundTimeRemaining = backgroundTimeRemaining
|
mock.underlyingWindowManager = WindowManagerMock()
|
||||||
|
|
||||||
beginBackgroundTaskWithNameExpirationHandlerClosure = { _, handler in
|
return mock
|
||||||
guard allowTasks else {
|
|
||||||
return .invalid
|
|
||||||
}
|
|
||||||
Self.bgTaskIdentifier += 1
|
|
||||||
|
|
||||||
let identifier = UIBackgroundTaskIdentifier(rawValue: Self.bgTaskIdentifier)
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
|
||||||
handler?()
|
|
||||||
}
|
|
||||||
return identifier
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -748,28 +748,28 @@ class AppLockServiceMock: AppLockServiceProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
class AppMediatorMock: AppMediatorProtocol {
|
class AppMediatorMock: AppMediatorProtocol {
|
||||||
|
var windowManager: WindowManagerProtocol {
|
||||||
|
get { return underlyingWindowManager }
|
||||||
|
set(value) { underlyingWindowManager = value }
|
||||||
|
}
|
||||||
|
var underlyingWindowManager: WindowManagerProtocol!
|
||||||
var appState: UIApplication.State {
|
var appState: UIApplication.State {
|
||||||
get { return underlyingAppState }
|
get { return underlyingAppState }
|
||||||
set(value) { underlyingAppState = value }
|
set(value) { underlyingAppState = value }
|
||||||
}
|
}
|
||||||
var underlyingAppState: UIApplication.State!
|
var underlyingAppState: UIApplication.State!
|
||||||
var backgroundTimeRemaining: TimeInterval {
|
|
||||||
get { return underlyingBackgroundTimeRemaining }
|
|
||||||
set(value) { underlyingBackgroundTimeRemaining = value }
|
|
||||||
}
|
|
||||||
var underlyingBackgroundTimeRemaining: TimeInterval!
|
|
||||||
|
|
||||||
//MARK: - beginBackgroundTask
|
//MARK: - beginBackgroundTask
|
||||||
|
|
||||||
var beginBackgroundTaskWithNameExpirationHandlerUnderlyingCallsCount = 0
|
var beginBackgroundTaskExpirationHandlerUnderlyingCallsCount = 0
|
||||||
var beginBackgroundTaskWithNameExpirationHandlerCallsCount: Int {
|
var beginBackgroundTaskExpirationHandlerCallsCount: Int {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return beginBackgroundTaskWithNameExpirationHandlerUnderlyingCallsCount
|
return beginBackgroundTaskExpirationHandlerUnderlyingCallsCount
|
||||||
} else {
|
} else {
|
||||||
var returnValue: Int? = nil
|
var returnValue: Int? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = beginBackgroundTaskWithNameExpirationHandlerUnderlyingCallsCount
|
returnValue = beginBackgroundTaskExpirationHandlerUnderlyingCallsCount
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@ -777,27 +777,27 @@ class AppMediatorMock: AppMediatorProtocol {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
beginBackgroundTaskWithNameExpirationHandlerUnderlyingCallsCount = newValue
|
beginBackgroundTaskExpirationHandlerUnderlyingCallsCount = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
beginBackgroundTaskWithNameExpirationHandlerUnderlyingCallsCount = newValue
|
beginBackgroundTaskExpirationHandlerUnderlyingCallsCount = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var beginBackgroundTaskWithNameExpirationHandlerCalled: Bool {
|
var beginBackgroundTaskExpirationHandlerCalled: Bool {
|
||||||
return beginBackgroundTaskWithNameExpirationHandlerCallsCount > 0
|
return beginBackgroundTaskExpirationHandlerCallsCount > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
var beginBackgroundTaskWithNameExpirationHandlerUnderlyingReturnValue: UIBackgroundTaskIdentifier!
|
var beginBackgroundTaskExpirationHandlerUnderlyingReturnValue: UIBackgroundTaskIdentifier!
|
||||||
var beginBackgroundTaskWithNameExpirationHandlerReturnValue: UIBackgroundTaskIdentifier! {
|
var beginBackgroundTaskExpirationHandlerReturnValue: UIBackgroundTaskIdentifier! {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return beginBackgroundTaskWithNameExpirationHandlerUnderlyingReturnValue
|
return beginBackgroundTaskExpirationHandlerUnderlyingReturnValue
|
||||||
} else {
|
} else {
|
||||||
var returnValue: UIBackgroundTaskIdentifier? = nil
|
var returnValue: UIBackgroundTaskIdentifier? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = beginBackgroundTaskWithNameExpirationHandlerUnderlyingReturnValue
|
returnValue = beginBackgroundTaskExpirationHandlerUnderlyingReturnValue
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@ -805,22 +805,22 @@ class AppMediatorMock: AppMediatorProtocol {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
beginBackgroundTaskWithNameExpirationHandlerUnderlyingReturnValue = newValue
|
beginBackgroundTaskExpirationHandlerUnderlyingReturnValue = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
beginBackgroundTaskWithNameExpirationHandlerUnderlyingReturnValue = newValue
|
beginBackgroundTaskExpirationHandlerUnderlyingReturnValue = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var beginBackgroundTaskWithNameExpirationHandlerClosure: ((String?, (() -> Void)?) -> UIBackgroundTaskIdentifier)?
|
var beginBackgroundTaskExpirationHandlerClosure: (((() -> Void)?) -> UIBackgroundTaskIdentifier)?
|
||||||
|
|
||||||
func beginBackgroundTask(withName taskName: String?, expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier {
|
func beginBackgroundTask(expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier {
|
||||||
beginBackgroundTaskWithNameExpirationHandlerCallsCount += 1
|
beginBackgroundTaskExpirationHandlerCallsCount += 1
|
||||||
if let beginBackgroundTaskWithNameExpirationHandlerClosure = beginBackgroundTaskWithNameExpirationHandlerClosure {
|
if let beginBackgroundTaskExpirationHandlerClosure = beginBackgroundTaskExpirationHandlerClosure {
|
||||||
return beginBackgroundTaskWithNameExpirationHandlerClosure(taskName, handler)
|
return beginBackgroundTaskExpirationHandlerClosure(handler)
|
||||||
} else {
|
} else {
|
||||||
return beginBackgroundTaskWithNameExpirationHandlerReturnValue
|
return beginBackgroundTaskExpirationHandlerReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//MARK: - endBackgroundTask
|
//MARK: - endBackgroundTask
|
||||||
@ -12976,122 +12976,12 @@ class VoiceMessageRecorderMock: VoiceMessageRecorderProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
class WindowManagerMock: WindowManagerProtocol {
|
class WindowManagerMock: WindowManagerProtocol {
|
||||||
weak var delegate: WindowManagerDelegate?
|
|
||||||
var mainWindow: UIWindow!
|
var mainWindow: UIWindow!
|
||||||
var overlayWindow: UIWindow!
|
var overlayWindow: UIWindow!
|
||||||
var globalSearchWindow: UIWindow!
|
var globalSearchWindow: UIWindow!
|
||||||
var alternateWindow: UIWindow!
|
var alternateWindow: UIWindow!
|
||||||
var windows: [UIWindow] = []
|
var windows: [UIWindow] = []
|
||||||
|
|
||||||
//MARK: - configure
|
|
||||||
|
|
||||||
var configureWithUnderlyingCallsCount = 0
|
|
||||||
var configureWithCallsCount: Int {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return configureWithUnderlyingCallsCount
|
|
||||||
} else {
|
|
||||||
var returnValue: Int? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = configureWithUnderlyingCallsCount
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
configureWithUnderlyingCallsCount = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
configureWithUnderlyingCallsCount = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var configureWithCalled: Bool {
|
|
||||||
return configureWithCallsCount > 0
|
|
||||||
}
|
|
||||||
var configureWithReceivedWindowScene: UIWindowScene?
|
|
||||||
var configureWithReceivedInvocations: [UIWindowScene] = []
|
|
||||||
var configureWithClosure: ((UIWindowScene) -> Void)?
|
|
||||||
|
|
||||||
func configure(with windowScene: UIWindowScene) {
|
|
||||||
configureWithCallsCount += 1
|
|
||||||
configureWithReceivedWindowScene = windowScene
|
|
||||||
configureWithReceivedInvocations.append(windowScene)
|
|
||||||
configureWithClosure?(windowScene)
|
|
||||||
}
|
|
||||||
//MARK: - switchToMain
|
|
||||||
|
|
||||||
var switchToMainUnderlyingCallsCount = 0
|
|
||||||
var switchToMainCallsCount: Int {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return switchToMainUnderlyingCallsCount
|
|
||||||
} else {
|
|
||||||
var returnValue: Int? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = switchToMainUnderlyingCallsCount
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
switchToMainUnderlyingCallsCount = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
switchToMainUnderlyingCallsCount = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var switchToMainCalled: Bool {
|
|
||||||
return switchToMainCallsCount > 0
|
|
||||||
}
|
|
||||||
var switchToMainClosure: (() -> Void)?
|
|
||||||
|
|
||||||
func switchToMain() {
|
|
||||||
switchToMainCallsCount += 1
|
|
||||||
switchToMainClosure?()
|
|
||||||
}
|
|
||||||
//MARK: - switchToAlternate
|
|
||||||
|
|
||||||
var switchToAlternateUnderlyingCallsCount = 0
|
|
||||||
var switchToAlternateCallsCount: Int {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return switchToAlternateUnderlyingCallsCount
|
|
||||||
} else {
|
|
||||||
var returnValue: Int? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = switchToAlternateUnderlyingCallsCount
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
switchToAlternateUnderlyingCallsCount = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
switchToAlternateUnderlyingCallsCount = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var switchToAlternateCalled: Bool {
|
|
||||||
return switchToAlternateCallsCount > 0
|
|
||||||
}
|
|
||||||
var switchToAlternateClosure: (() -> Void)?
|
|
||||||
|
|
||||||
func switchToAlternate() {
|
|
||||||
switchToAlternateCallsCount += 1
|
|
||||||
switchToAlternateClosure?()
|
|
||||||
}
|
|
||||||
//MARK: - showGlobalSearch
|
//MARK: - showGlobalSearch
|
||||||
|
|
||||||
var showGlobalSearchUnderlyingCallsCount = 0
|
var showGlobalSearchUnderlyingCallsCount = 0
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2022 New Vector Ltd
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
typealias BackgroundTaskExpirationHandler = (BackgroundTaskProtocol) -> Void
|
|
||||||
|
|
||||||
/// BackgroundTaskProtocol is the protocol describing a background task regardless of the platform used.
|
|
||||||
protocol BackgroundTaskProtocol: AnyObject {
|
|
||||||
/// Name of the background task for debug.
|
|
||||||
var name: String { get }
|
|
||||||
|
|
||||||
/// `true` if the background task is currently running.
|
|
||||||
var isRunning: Bool { get }
|
|
||||||
|
|
||||||
/// Flag indicating the background task is reusable. If reusable, `name` is the key to distinguish background tasks.
|
|
||||||
var isReusable: Bool { get }
|
|
||||||
|
|
||||||
/// Method to be called when a task reused one more time. Should only be valid for reusable tasks.
|
|
||||||
func reuse()
|
|
||||||
|
|
||||||
/// Stop the background task. Cannot be started anymore. For reusable tasks, should be called same number of times `reuse` called.
|
|
||||||
func stop()
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2022 New Vector Ltd
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
@MainActor
|
|
||||||
protocol BackgroundTaskServiceProtocol {
|
|
||||||
func startBackgroundTask(withName name: String,
|
|
||||||
isReusable: Bool,
|
|
||||||
expirationHandler: (() -> Void)?) -> BackgroundTaskProtocol?
|
|
||||||
}
|
|
||||||
|
|
||||||
extension BackgroundTaskServiceProtocol {
|
|
||||||
func startBackgroundTask(withName name: String) -> BackgroundTaskProtocol? {
|
|
||||||
startBackgroundTask(withName: name,
|
|
||||||
expirationHandler: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func startBackgroundTask(withName name: String,
|
|
||||||
isReusable: Bool) -> BackgroundTaskProtocol? {
|
|
||||||
startBackgroundTask(withName: name,
|
|
||||||
isReusable: isReusable,
|
|
||||||
expirationHandler: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func startBackgroundTask(withName name: String,
|
|
||||||
expirationHandler: (() -> Void)?) -> BackgroundTaskProtocol? {
|
|
||||||
startBackgroundTask(withName: name,
|
|
||||||
isReusable: false,
|
|
||||||
expirationHandler: expirationHandler)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2022 New Vector Ltd
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
class UIKitBackgroundTask: BackgroundTaskProtocol {
|
|
||||||
let name: String
|
|
||||||
var isRunning: Bool {
|
|
||||||
identifier != .invalid
|
|
||||||
}
|
|
||||||
|
|
||||||
let isReusable: Bool
|
|
||||||
let expirationHandler: BackgroundTaskExpirationHandler?
|
|
||||||
var elapsedTime: TimeInterval {
|
|
||||||
Date().timeIntervalSince(startDate) * 1000
|
|
||||||
}
|
|
||||||
|
|
||||||
private let appMediator: AppMediatorProtocol
|
|
||||||
private var identifier: UIBackgroundTaskIdentifier = .invalid
|
|
||||||
private var useCounter = 0
|
|
||||||
private let startDate = Date()
|
|
||||||
|
|
||||||
init?(name: String,
|
|
||||||
isReusable: Bool,
|
|
||||||
appMediator: AppMediatorProtocol,
|
|
||||||
expirationHandler: BackgroundTaskExpirationHandler?) {
|
|
||||||
self.name = name
|
|
||||||
self.isReusable = isReusable
|
|
||||||
self.appMediator = appMediator
|
|
||||||
self.expirationHandler = expirationHandler
|
|
||||||
|
|
||||||
identifier = appMediator.beginBackgroundTask(withName: name) { [weak self] in
|
|
||||||
guard let self else { return }
|
|
||||||
self.stop()
|
|
||||||
self.expirationHandler?(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
if identifier == .invalid {
|
|
||||||
MXLog.error("Do not start background task: \(name), as OS declined")
|
|
||||||
expirationHandler?(self)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if isReusable {
|
|
||||||
reuse()
|
|
||||||
}
|
|
||||||
|
|
||||||
MXLog.verbose("Start background task #\(identifier.rawValue) - \(name)")
|
|
||||||
}
|
|
||||||
|
|
||||||
func reuse() {
|
|
||||||
guard isReusable else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
useCounter += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func stop() {
|
|
||||||
if isReusable {
|
|
||||||
useCounter -= 1
|
|
||||||
if useCounter <= 0 {
|
|
||||||
endTask()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
endTask()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func endTask() {
|
|
||||||
if identifier != .invalid {
|
|
||||||
MXLog.verbose("End background task #\(identifier.rawValue) - \(name) after \(readableElapsedTime)")
|
|
||||||
|
|
||||||
appMediator.endBackgroundTask(identifier)
|
|
||||||
identifier = .invalid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var readableElapsedTime: String {
|
|
||||||
String(format: "%.3fms", elapsedTime)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2022 New Vector Ltd
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
/// /// UIKitBackgroundTaskService is a concrete implementation of BackgroundTaskServiceProtocol using a given `ApplicationProtocol` instance.
|
|
||||||
class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol {
|
|
||||||
private let appMediator: AppMediatorProtocol
|
|
||||||
private var reusableTasks = NSMapTable<NSString, UIKitBackgroundTask>(keyOptions: .strongMemory, valueOptions: .weakMemory)
|
|
||||||
|
|
||||||
init(appMediator: AppMediatorProtocol) {
|
|
||||||
self.appMediator = appMediator
|
|
||||||
}
|
|
||||||
|
|
||||||
func startBackgroundTask(withName name: String,
|
|
||||||
isReusable: Bool,
|
|
||||||
expirationHandler: (() -> Void)?) -> BackgroundTaskProtocol? {
|
|
||||||
if shouldAvoidStartingNewTasks() {
|
|
||||||
MXLog.error("Do not start background task: \(name), as not enough time exists")
|
|
||||||
// call expiration handler immediately
|
|
||||||
expirationHandler?()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var created = false
|
|
||||||
var result: BackgroundTaskProtocol?
|
|
||||||
|
|
||||||
if isReusable {
|
|
||||||
if let oldTask = reusableTasks.object(forKey: name as NSString), oldTask.isRunning {
|
|
||||||
oldTask.reuse()
|
|
||||||
result = oldTask
|
|
||||||
} else {
|
|
||||||
if let newTask = UIKitBackgroundTask(name: name,
|
|
||||||
isReusable: isReusable,
|
|
||||||
appMediator: appMediator,
|
|
||||||
expirationHandler: { [weak self] task in
|
|
||||||
guard let self else { return }
|
|
||||||
self.reusableTasks.removeObject(forKey: task.name as NSString)
|
|
||||||
expirationHandler?()
|
|
||||||
}) {
|
|
||||||
created = true
|
|
||||||
reusableTasks.setObject(newTask, forKey: name as NSString)
|
|
||||||
result = newTask
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let newTask = UIKitBackgroundTask(name: name,
|
|
||||||
isReusable: isReusable,
|
|
||||||
appMediator: appMediator,
|
|
||||||
expirationHandler: { _ in
|
|
||||||
expirationHandler?()
|
|
||||||
}) {
|
|
||||||
result = newTask
|
|
||||||
created = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let appState = appMediator.appState
|
|
||||||
let remainingTime = readableBackgroundTimeRemaining(appMediator.backgroundTimeRemaining)
|
|
||||||
|
|
||||||
MXLog.verbose("Background task \(name) \(created ? "started" : "reused") with app state: \(appState) and estimated background time remaining: \(remainingTime)")
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private func readableBackgroundTimeRemaining(_ backgroundTimeRemaining: TimeInterval) -> String {
|
|
||||||
if backgroundTimeRemaining == .greatestFiniteMagnitude {
|
|
||||||
return "undetermined"
|
|
||||||
} else {
|
|
||||||
return String(format: "%.0f seconds", backgroundTimeRemaining)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func shouldAvoidStartingNewTasks() -> Bool {
|
|
||||||
if appMediator.appState == .background,
|
|
||||||
appMediator.backgroundTimeRemaining < .backgroundTimeRemainingThresholdToStartTasks {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension TimeInterval {
|
|
||||||
static let backgroundTimeRemainingThresholdToStartTasks: TimeInterval = 5
|
|
||||||
}
|
|
@ -23,7 +23,6 @@ import MatrixRustSDK
|
|||||||
|
|
||||||
class ClientProxy: ClientProxyProtocol {
|
class ClientProxy: ClientProxyProtocol {
|
||||||
private let client: ClientProtocol
|
private let client: ClientProtocol
|
||||||
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
|
||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
private let networkMonitor: NetworkMonitorProtocol
|
private let networkMonitor: NetworkMonitorProtocol
|
||||||
|
|
||||||
@ -122,11 +121,9 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(client: ClientProtocol,
|
init(client: ClientProtocol,
|
||||||
backgroundTaskService: BackgroundTaskServiceProtocol,
|
|
||||||
appSettings: AppSettings,
|
appSettings: AppSettings,
|
||||||
networkMonitor: NetworkMonitorProtocol) async {
|
networkMonitor: NetworkMonitorProtocol) async {
|
||||||
self.client = client
|
self.client = client
|
||||||
self.backgroundTaskService = backgroundTaskService
|
|
||||||
self.appSettings = appSettings
|
self.appSettings = appSettings
|
||||||
self.networkMonitor = networkMonitor
|
self.networkMonitor = networkMonitor
|
||||||
|
|
||||||
@ -134,8 +131,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
|
|
||||||
mediaLoader = MediaLoader(client: client)
|
mediaLoader = MediaLoader(client: client)
|
||||||
|
|
||||||
notificationSettings = NotificationSettingsProxy(notificationSettings: client.getNotificationSettings(),
|
notificationSettings = NotificationSettingsProxy(notificationSettings: client.getNotificationSettings())
|
||||||
backgroundTaskService: backgroundTaskService)
|
|
||||||
|
|
||||||
secureBackupController = SecureBackupController(encryption: client.encryption())
|
secureBackupController = SecureBackupController(encryption: client.encryption())
|
||||||
|
|
||||||
@ -425,8 +421,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
|
|
||||||
if let roomListItem, let room {
|
if let roomListItem, let room {
|
||||||
return await RoomProxy(roomListItem: roomListItem,
|
return await RoomProxy(roomListItem: roomListItem,
|
||||||
room: room,
|
room: room)
|
||||||
backgroundTaskService: backgroundTaskService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Else wait for the visible rooms list to go into fully loaded
|
// Else wait for the visible rooms list to go into fully loaded
|
||||||
@ -453,8 +448,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return await RoomProxy(roomListItem: roomListItem,
|
return await RoomProxy(roomListItem: roomListItem,
|
||||||
room: room,
|
room: room)
|
||||||
backgroundTaskService: backgroundTaskService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func roomPreviewForIdentifier(_ identifier: String) async -> Result<RoomPreviewDetails, ClientProxyError> {
|
func roomPreviewForIdentifier(_ identifier: String) async -> Result<RoomPreviewDetails, ClientProxyError> {
|
||||||
|
@ -20,14 +20,11 @@ import UIKit
|
|||||||
struct MediaProvider: MediaProviderProtocol {
|
struct MediaProvider: MediaProviderProtocol {
|
||||||
private let mediaLoader: MediaLoaderProtocol
|
private let mediaLoader: MediaLoaderProtocol
|
||||||
private let imageCache: Kingfisher.ImageCache
|
private let imageCache: Kingfisher.ImageCache
|
||||||
private let backgroundTaskService: BackgroundTaskServiceProtocol?
|
|
||||||
|
|
||||||
init(mediaLoader: MediaLoaderProtocol,
|
init(mediaLoader: MediaLoaderProtocol,
|
||||||
imageCache: Kingfisher.ImageCache,
|
imageCache: Kingfisher.ImageCache) {
|
||||||
backgroundTaskService: BackgroundTaskServiceProtocol?) {
|
|
||||||
self.mediaLoader = mediaLoader
|
self.mediaLoader = mediaLoader
|
||||||
self.imageCache = imageCache
|
self.imageCache = imageCache
|
||||||
self.backgroundTaskService = backgroundTaskService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Images
|
// MARK: Images
|
||||||
@ -45,11 +42,6 @@ struct MediaProvider: MediaProviderProtocol {
|
|||||||
return .success(image)
|
return .success(image)
|
||||||
}
|
}
|
||||||
|
|
||||||
let loadImageBgTask = await backgroundTaskService?.startBackgroundTask(withName: "LoadImage: \(source.url.hashValue)")
|
|
||||||
defer {
|
|
||||||
loadImageBgTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
let cacheKey = cacheKeyForURL(source.url, size: size)
|
let cacheKey = cacheKeyForURL(source.url, size: size)
|
||||||
|
|
||||||
if case let .success(cacheResult) = await imageCache.retrieveImage(forKey: cacheKey),
|
if case let .success(cacheResult) = await imageCache.retrieveImage(forKey: cacheKey),
|
||||||
@ -92,9 +84,6 @@ struct MediaProvider: MediaProviderProtocol {
|
|||||||
// MARK: Files
|
// MARK: Files
|
||||||
|
|
||||||
func loadFileFromSource(_ source: MediaSourceProxy, body: String?) async -> Result<MediaFileHandleProxy, MediaProviderError> {
|
func loadFileFromSource(_ source: MediaSourceProxy, body: String?) async -> Result<MediaFileHandleProxy, MediaProviderError> {
|
||||||
let loadFileBgTask = await backgroundTaskService?.startBackgroundTask(withName: "LoadFile: \(source.url.hashValue)")
|
|
||||||
defer { loadFileBgTask?.stop() }
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let file = try await mediaLoader.loadMediaFileForSource(source, body: body)
|
let file = try await mediaLoader.loadMediaFileForSource(source, body: body)
|
||||||
return .success(file)
|
return .success(file)
|
||||||
|
@ -36,13 +36,11 @@ private final class WeakNotificationSettingsProxy: NotificationSettingsDelegate
|
|||||||
|
|
||||||
final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
|
final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
|
||||||
private(set) var notificationSettings: MatrixRustSDK.NotificationSettingsProtocol
|
private(set) var notificationSettings: MatrixRustSDK.NotificationSettingsProtocol
|
||||||
private let backgroundTaskService: BackgroundTaskServiceProtocol?
|
|
||||||
|
|
||||||
let callbacks = PassthroughSubject<NotificationSettingsProxyCallback, Never>()
|
let callbacks = PassthroughSubject<NotificationSettingsProxyCallback, Never>()
|
||||||
|
|
||||||
init(notificationSettings: MatrixRustSDK.NotificationSettingsProtocol, backgroundTaskService: BackgroundTaskServiceProtocol?) {
|
init(notificationSettings: MatrixRustSDK.NotificationSettingsProtocol) {
|
||||||
self.notificationSettings = notificationSettings
|
self.notificationSettings = notificationSettings
|
||||||
self.backgroundTaskService = backgroundTaskService
|
|
||||||
notificationSettings.setDelegate(delegate: WeakNotificationSettingsProxy(proxy: self))
|
notificationSettings.setDelegate(delegate: WeakNotificationSettingsProxy(proxy: self))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,9 +50,6 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setNotificationMode(roomId: String, mode: RoomNotificationModeProxy) async throws {
|
func setNotificationMode(roomId: String, mode: RoomNotificationModeProxy) async throws {
|
||||||
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "setNotificationMode")
|
|
||||||
defer { backgroundTask?.stop() }
|
|
||||||
|
|
||||||
try await notificationSettings.setRoomNotificationMode(roomId: roomId, mode: mode.roomNotificationMode)
|
try await notificationSettings.setRoomNotificationMode(roomId: roomId, mode: mode.roomNotificationMode)
|
||||||
await updatedSettings()
|
await updatedSettings()
|
||||||
}
|
}
|
||||||
@ -70,9 +65,6 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setDefaultRoomNotificationMode(isEncrypted: Bool, isOneToOne: Bool, mode: RoomNotificationModeProxy) async throws {
|
func setDefaultRoomNotificationMode(isEncrypted: Bool, isOneToOne: Bool, mode: RoomNotificationModeProxy) async throws {
|
||||||
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "setDefaultRoomNotificationMode")
|
|
||||||
defer { backgroundTask?.stop() }
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try await notificationSettings.setDefaultRoomNotificationMode(isEncrypted: isEncrypted, isOneToOne: isOneToOne, mode: mode.roomNotificationMode)
|
try await notificationSettings.setDefaultRoomNotificationMode(isEncrypted: isEncrypted, isOneToOne: isOneToOne, mode: mode.roomNotificationMode)
|
||||||
} catch NotificationSettingsError.RuleNotFound(let ruleId) {
|
} catch NotificationSettingsError.RuleNotFound(let ruleId) {
|
||||||
@ -86,17 +78,11 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func restoreDefaultNotificationMode(roomId: String) async throws {
|
func restoreDefaultNotificationMode(roomId: String) async throws {
|
||||||
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "restoreDefaultNotificationMode")
|
|
||||||
defer { backgroundTask?.stop() }
|
|
||||||
|
|
||||||
try await notificationSettings.restoreDefaultRoomNotificationMode(roomId: roomId)
|
try await notificationSettings.restoreDefaultRoomNotificationMode(roomId: roomId)
|
||||||
await updatedSettings()
|
await updatedSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmuteRoom(roomId: String, isEncrypted: Bool, isOneToOne: Bool) async throws {
|
func unmuteRoom(roomId: String, isEncrypted: Bool, isOneToOne: Bool) async throws {
|
||||||
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "unmuteRoom")
|
|
||||||
defer { backgroundTask?.stop() }
|
|
||||||
|
|
||||||
try await notificationSettings.unmuteRoom(roomId: roomId, isEncrypted: isEncrypted, isOneToOne: isOneToOne)
|
try await notificationSettings.unmuteRoom(roomId: roomId, isEncrypted: isEncrypted, isOneToOne: isOneToOne)
|
||||||
await updatedSettings()
|
await updatedSettings()
|
||||||
}
|
}
|
||||||
@ -106,9 +92,6 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setRoomMentionEnabled(enabled: Bool) async throws {
|
func setRoomMentionEnabled(enabled: Bool) async throws {
|
||||||
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "setRoomMentionEnabled")
|
|
||||||
defer { backgroundTask?.stop() }
|
|
||||||
|
|
||||||
try await notificationSettings.setRoomMentionEnabled(enabled: enabled)
|
try await notificationSettings.setRoomMentionEnabled(enabled: enabled)
|
||||||
await updatedSettings()
|
await updatedSettings()
|
||||||
}
|
}
|
||||||
@ -118,9 +101,6 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setCallEnabled(enabled: Bool) async throws {
|
func setCallEnabled(enabled: Bool) async throws {
|
||||||
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "setCallEnabled")
|
|
||||||
defer { backgroundTask?.stop() }
|
|
||||||
|
|
||||||
try await notificationSettings.setCallEnabled(enabled: enabled)
|
try await notificationSettings.setCallEnabled(enabled: enabled)
|
||||||
await updatedSettings()
|
await updatedSettings()
|
||||||
}
|
}
|
||||||
@ -130,9 +110,6 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setInviteForMeEnabled(enabled: Bool) async throws {
|
func setInviteForMeEnabled(enabled: Bool) async throws {
|
||||||
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "setInviteForMeEnabled")
|
|
||||||
defer { backgroundTask?.stop() }
|
|
||||||
|
|
||||||
try await notificationSettings.setInviteForMeEnabled(enabled: enabled)
|
try await notificationSettings.setInviteForMeEnabled(enabled: enabled)
|
||||||
await updatedSettings()
|
await updatedSettings()
|
||||||
}
|
}
|
||||||
|
@ -26,13 +26,9 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
private let roomListItem: RoomListItemProtocol
|
private let roomListItem: RoomListItemProtocol
|
||||||
private let room: RoomProtocol
|
private let room: RoomProtocol
|
||||||
let timeline: TimelineProxyProtocol
|
let timeline: TimelineProxyProtocol
|
||||||
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
|
||||||
private let backgroundTaskName = "SendRoomEvent"
|
|
||||||
|
|
||||||
private let userInitiatedDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.user_initiated", qos: .userInitiated)
|
private let userInitiatedDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.user_initiated", qos: .userInitiated)
|
||||||
|
|
||||||
private var sendMessageBackgroundTask: BackgroundTaskProtocol?
|
|
||||||
|
|
||||||
// periphery:ignore - required for instance retention in the rust codebase
|
// periphery:ignore - required for instance retention in the rust codebase
|
||||||
private var roomInfoObservationToken: TaskHandle?
|
private var roomInfoObservationToken: TaskHandle?
|
||||||
// periphery:ignore - required for instance retention in the rust codebase
|
// periphery:ignore - required for instance retention in the rust codebase
|
||||||
@ -60,13 +56,12 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init?(roomListItem: RoomListItemProtocol,
|
init?(roomListItem: RoomListItemProtocol,
|
||||||
room: RoomProtocol,
|
room: RoomProtocol) async {
|
||||||
backgroundTaskService: BackgroundTaskServiceProtocol) async {
|
|
||||||
self.roomListItem = roomListItem
|
self.roomListItem = roomListItem
|
||||||
self.room = room
|
self.room = room
|
||||||
self.backgroundTaskService = backgroundTaskService
|
|
||||||
do {
|
do {
|
||||||
timeline = try await TimelineProxy(timeline: room.timeline(), backgroundTaskService: backgroundTaskService)
|
timeline = try await TimelineProxy(timeline: room.timeline())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed creating timeline with error: \(error)")
|
MXLog.error("Failed creating timeline with error: \(error)")
|
||||||
return nil
|
return nil
|
||||||
@ -165,12 +160,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func redact(_ eventID: String) async -> Result<Void, RoomProxyError> {
|
func redact(_ eventID: String) async -> Result<Void, RoomProxyError> {
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
await Task.dispatch(on: userInitiatedDispatchQueue) {
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Task.dispatch(on: userInitiatedDispatchQueue) {
|
|
||||||
do {
|
do {
|
||||||
try self.room.redact(eventId: eventID, reason: nil)
|
try self.room.redact(eventId: eventID, reason: nil)
|
||||||
return .success(())
|
return .success(())
|
||||||
@ -180,14 +170,9 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func reportContent(_ eventID: String, reason: String?) async -> Result<Void, RoomProxyError> {
|
func reportContent(_ eventID: String, reason: String?) async -> Result<Void, RoomProxyError> {
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
await Task.dispatch(on: userInitiatedDispatchQueue) {
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Task.dispatch(on: userInitiatedDispatchQueue) {
|
|
||||||
do {
|
do {
|
||||||
try self.room.reportContent(eventId: eventID, score: nil, reason: reason)
|
try self.room.reportContent(eventId: eventID, score: nil, reason: reason)
|
||||||
return .success(())
|
return .success(())
|
||||||
@ -226,11 +211,6 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return .success(member)
|
return .success(member)
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let member = try await room.member(userId: userID)
|
let member = try await room.member(userId: userID)
|
||||||
return .success(RoomMemberProxy(member: member))
|
return .success(RoomMemberProxy(member: member))
|
||||||
@ -239,14 +219,9 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return .failure(.sdkError(error))
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func leaveRoom() async -> Result<Void, RoomProxyError> {
|
func leaveRoom() async -> Result<Void, RoomProxyError> {
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
await Task.dispatch(on: .global()) {
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Task.dispatch(on: .global()) {
|
|
||||||
do {
|
do {
|
||||||
try self.room.leave()
|
try self.room.leave()
|
||||||
return .success(())
|
return .success(())
|
||||||
|
@ -20,10 +20,7 @@ import MatrixRustSDK
|
|||||||
|
|
||||||
final class TimelineProxy: TimelineProxyProtocol {
|
final class TimelineProxy: TimelineProxyProtocol {
|
||||||
private let timeline: Timeline
|
private let timeline: Timeline
|
||||||
private var sendMessageBackgroundTask: BackgroundTaskProtocol?
|
|
||||||
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
|
||||||
|
|
||||||
private let backgroundTaskName = "SendRoomEvent"
|
|
||||||
private let lowPriorityDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.low_priority", qos: .utility)
|
private let lowPriorityDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.low_priority", qos: .utility)
|
||||||
private let messageSendingDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.message_sending", qos: .userInitiated)
|
private let messageSendingDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.message_sending", qos: .userInitiated)
|
||||||
private let userInitiatedDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.user_initiated", qos: .userInitiated)
|
private let userInitiatedDispatchQueue = DispatchQueue(label: "io.element.elementx.roomproxy.user_initiated", qos: .userInitiated)
|
||||||
@ -54,9 +51,8 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
roomTimelineObservationToken?.cancel()
|
roomTimelineObservationToken?.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
init(timeline: Timeline, backgroundTaskService: BackgroundTaskServiceProtocol) {
|
init(timeline: Timeline) {
|
||||||
self.timeline = timeline
|
self.timeline = timeline
|
||||||
self.backgroundTaskService = backgroundTaskService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func subscribeForUpdates() async {
|
func subscribeForUpdates() async {
|
||||||
@ -84,11 +80,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
func cancelSend(transactionID: String) async {
|
func cancelSend(transactionID: String) async {
|
||||||
MXLog.info("Cancelling sending for transaction ID: \(transactionID)")
|
MXLog.info("Cancelling sending for transaction ID: \(transactionID)")
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Task.dispatch(on: messageSendingDispatchQueue) {
|
return await Task.dispatch(on: messageSendingDispatchQueue) {
|
||||||
self.timeline.cancelSend(txnId: transactionID)
|
self.timeline.cancelSend(txnId: transactionID)
|
||||||
MXLog.info("Finished cancelling sending for transaction ID: \(transactionID)")
|
MXLog.info("Finished cancelling sending for transaction ID: \(transactionID)")
|
||||||
@ -101,11 +92,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
|
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Editing message with original event ID: \(eventID)")
|
MXLog.info("Editing message with original event ID: \(eventID)")
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
let messageContent = buildMessageContentFor(message,
|
let messageContent = buildMessageContentFor(message,
|
||||||
html: html,
|
html: html,
|
||||||
intentionalMentions: intentionalMentions.toRustMentions())
|
intentionalMentions: intentionalMentions.toRustMentions())
|
||||||
@ -198,11 +184,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
func retrySend(transactionID: String) async {
|
func retrySend(transactionID: String) async {
|
||||||
MXLog.info("Retrying sending for transactionID: \(transactionID)")
|
MXLog.info("Retrying sending for transactionID: \(transactionID)")
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Task.dispatch(on: messageSendingDispatchQueue) {
|
return await Task.dispatch(on: messageSendingDispatchQueue) {
|
||||||
self.timeline.retrySend(txnId: transactionID)
|
self.timeline.retrySend(txnId: transactionID)
|
||||||
MXLog.info("Finished retrying sending for transactionID: \(transactionID)")
|
MXLog.info("Finished retrying sending for transactionID: \(transactionID)")
|
||||||
@ -215,11 +196,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Sending audio")
|
MXLog.info("Sending audio")
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
let handle = timeline.sendAudio(url: url.path(percentEncoded: false), audioInfo: audioInfo, caption: nil, formattedCaption: nil, progressWatcher: UploadProgressListener { progress in
|
let handle = timeline.sendAudio(url: url.path(percentEncoded: false), audioInfo: audioInfo, caption: nil, formattedCaption: nil, progressWatcher: UploadProgressListener { progress in
|
||||||
progressSubject?.send(progress)
|
progressSubject?.send(progress)
|
||||||
})
|
})
|
||||||
@ -245,11 +221,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Sending file")
|
MXLog.info("Sending file")
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
let handle = timeline.sendFile(url: url.path(percentEncoded: false), fileInfo: fileInfo, progressWatcher: UploadProgressListener { progress in
|
let handle = timeline.sendFile(url: url.path(percentEncoded: false), fileInfo: fileInfo, progressWatcher: UploadProgressListener { progress in
|
||||||
progressSubject?.send(progress)
|
progressSubject?.send(progress)
|
||||||
})
|
})
|
||||||
@ -276,11 +247,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Sending image")
|
MXLog.info("Sending image")
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
let handle = timeline.sendImage(url: url.path(percentEncoded: false), thumbnailUrl: thumbnailURL.path(percentEncoded: false), imageInfo: imageInfo, caption: nil, formattedCaption: nil, progressWatcher: UploadProgressListener { progress in
|
let handle = timeline.sendImage(url: url.path(percentEncoded: false), thumbnailUrl: thumbnailURL.path(percentEncoded: false), imageInfo: imageInfo, caption: nil, formattedCaption: nil, progressWatcher: UploadProgressListener { progress in
|
||||||
progressSubject?.send(progress)
|
progressSubject?.send(progress)
|
||||||
})
|
})
|
||||||
@ -307,11 +273,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
assetType: AssetType?) async -> Result<Void, TimelineProxyError> {
|
assetType: AssetType?) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Sending location")
|
MXLog.info("Sending location")
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Task.dispatch(on: messageSendingDispatchQueue) {
|
return await Task.dispatch(on: messageSendingDispatchQueue) {
|
||||||
self.timeline.sendLocation(body: body,
|
self.timeline.sendLocation(body: body,
|
||||||
geoUri: geoURI.string,
|
geoUri: geoURI.string,
|
||||||
@ -334,11 +295,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Sending video")
|
MXLog.info("Sending video")
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
let handle = timeline.sendVideo(url: url.path(percentEncoded: false), thumbnailUrl: thumbnailURL.path(percentEncoded: false), videoInfo: videoInfo, caption: nil, formattedCaption: nil, progressWatcher: UploadProgressListener { progress in
|
let handle = timeline.sendVideo(url: url.path(percentEncoded: false), thumbnailUrl: thumbnailURL.path(percentEncoded: false), videoInfo: videoInfo, caption: nil, formattedCaption: nil, progressWatcher: UploadProgressListener { progress in
|
||||||
progressSubject?.send(progress)
|
progressSubject?.send(progress)
|
||||||
})
|
})
|
||||||
@ -365,11 +321,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Sending voice message")
|
MXLog.info("Sending voice message")
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
let handle = timeline.sendVoiceMessage(url: url.path(percentEncoded: false), audioInfo: audioInfo, waveform: waveform, caption: nil, formattedCaption: nil, progressWatcher: UploadProgressListener { progress in
|
let handle = timeline.sendVoiceMessage(url: url.path(percentEncoded: false), audioInfo: audioInfo, waveform: waveform, caption: nil, formattedCaption: nil, progressWatcher: UploadProgressListener { progress in
|
||||||
progressSubject?.send(progress)
|
progressSubject?.send(progress)
|
||||||
})
|
})
|
||||||
@ -399,11 +350,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
MXLog.info("Sending message")
|
MXLog.info("Sending message")
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
let messageContent = buildMessageContentFor(message,
|
let messageContent = buildMessageContentFor(message,
|
||||||
html: html,
|
html: html,
|
||||||
intentionalMentions: intentionalMentions.toRustMentions())
|
intentionalMentions: intentionalMentions.toRustMentions())
|
||||||
@ -436,12 +382,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
|
|
||||||
func sendMessageEventContent(_ messageContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError> {
|
func sendMessageEventContent(_ messageContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Sending message content")
|
MXLog.info("Sending message content")
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Task.dispatch(on: messageSendingDispatchQueue) {
|
return await Task.dispatch(on: messageSendingDispatchQueue) {
|
||||||
self.timeline.send(msg: messageContent)
|
self.timeline.send(msg: messageContent)
|
||||||
|
|
||||||
@ -456,11 +397,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
func sendReadReceipt(for eventID: String, type: ReceiptType) async -> Result<Void, TimelineProxyError> {
|
func sendReadReceipt(for eventID: String, type: ReceiptType) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.verbose("Sending read receipt for eventID: \(eventID)")
|
MXLog.verbose("Sending read receipt for eventID: \(eventID)")
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Task.dispatch(on: lowPriorityDispatchQueue) {
|
return await Task.dispatch(on: lowPriorityDispatchQueue) {
|
||||||
do {
|
do {
|
||||||
try self.timeline.sendReadReceipt(receiptType: type, eventId: eventID)
|
try self.timeline.sendReadReceipt(receiptType: type, eventId: eventID)
|
||||||
@ -476,11 +412,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
func toggleReaction(_ reaction: String, to eventID: String) async -> Result<Void, TimelineProxyError> {
|
func toggleReaction(_ reaction: String, to eventID: String) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Toggling reaction for eventID: \(eventID)")
|
MXLog.info("Toggling reaction for eventID: \(eventID)")
|
||||||
|
|
||||||
sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
|
|
||||||
defer {
|
|
||||||
sendMessageBackgroundTask?.stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Task.dispatch(on: userInitiatedDispatchQueue) {
|
return await Task.dispatch(on: userInitiatedDispatchQueue) {
|
||||||
do {
|
do {
|
||||||
try self.timeline.toggleReaction(eventId: eventID, key: reaction)
|
try self.timeline.toggleReaction(eventId: eventID, key: reaction)
|
||||||
|
@ -20,7 +20,6 @@ import MatrixRustSDK
|
|||||||
|
|
||||||
class UserSessionStore: UserSessionStoreProtocol {
|
class UserSessionStore: UserSessionStoreProtocol {
|
||||||
private let keychainController: KeychainControllerProtocol
|
private let keychainController: KeychainControllerProtocol
|
||||||
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
|
||||||
private let matrixSDKStateKey = "matrix-sdk-state"
|
private let matrixSDKStateKey = "matrix-sdk-state"
|
||||||
|
|
||||||
/// Whether or not there are sessions in the store.
|
/// Whether or not there are sessions in the store.
|
||||||
@ -33,9 +32,8 @@ class UserSessionStore: UserSessionStoreProtocol {
|
|||||||
|
|
||||||
var clientSessionDelegate: ClientSessionDelegate { keychainController }
|
var clientSessionDelegate: ClientSessionDelegate { keychainController }
|
||||||
|
|
||||||
init(keychainController: KeychainControllerProtocol, backgroundTaskService: BackgroundTaskServiceProtocol) {
|
init(keychainController: KeychainControllerProtocol) {
|
||||||
self.keychainController = keychainController
|
self.keychainController = keychainController
|
||||||
self.backgroundTaskService = backgroundTaskService
|
|
||||||
baseDirectory = .sessionsBaseDirectory
|
baseDirectory = .sessionsBaseDirectory
|
||||||
MXLog.info("Setup base directory at: \(baseDirectory)")
|
MXLog.info("Setup base directory at: \(baseDirectory)")
|
||||||
}
|
}
|
||||||
@ -100,11 +98,9 @@ class UserSessionStore: UserSessionStoreProtocol {
|
|||||||
|
|
||||||
private func buildUserSessionWithClient(_ clientProxy: ClientProxyProtocol) -> UserSessionProtocol {
|
private func buildUserSessionWithClient(_ clientProxy: ClientProxyProtocol) -> UserSessionProtocol {
|
||||||
let mediaProvider = MediaProvider(mediaLoader: clientProxy,
|
let mediaProvider = MediaProvider(mediaLoader: clientProxy,
|
||||||
imageCache: .onlyInMemory,
|
imageCache: .onlyInMemory)
|
||||||
backgroundTaskService: backgroundTaskService)
|
|
||||||
|
|
||||||
let voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
|
let voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider)
|
||||||
backgroundTaskService: backgroundTaskService)
|
|
||||||
|
|
||||||
return UserSession(clientProxy: clientProxy,
|
return UserSession(clientProxy: clientProxy,
|
||||||
mediaProvider: mediaProvider,
|
mediaProvider: mediaProvider,
|
||||||
@ -150,7 +146,6 @@ class UserSessionStore: UserSessionStoreProtocol {
|
|||||||
|
|
||||||
private func setupProxyForClient(_ client: Client) async -> ClientProxyProtocol {
|
private func setupProxyForClient(_ client: Client) async -> ClientProxyProtocol {
|
||||||
await ClientProxy(client: client,
|
await ClientProxy(client: client,
|
||||||
backgroundTaskService: backgroundTaskService,
|
|
||||||
appSettings: ServiceLocator.shared.settings,
|
appSettings: ServiceLocator.shared.settings,
|
||||||
networkMonitor: ServiceLocator.shared.networkMonitor)
|
networkMonitor: ServiceLocator.shared.networkMonitor)
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ class VoiceMessageMediaManager: VoiceMessageMediaManagerProtocol {
|
|||||||
private let voiceMessageCache: VoiceMessageCacheProtocol
|
private let voiceMessageCache: VoiceMessageCacheProtocol
|
||||||
private let audioConverter: AudioConverterProtocol
|
private let audioConverter: AudioConverterProtocol
|
||||||
|
|
||||||
private let backgroundTaskService: BackgroundTaskServiceProtocol?
|
|
||||||
private let processingQueue: DispatchQueue
|
private let processingQueue: DispatchQueue
|
||||||
private var conversionRequests = [MediaSourceProxy: VoiceMessageConversionRequest]()
|
private var conversionRequests = [MediaSourceProxy: VoiceMessageConversionRequest]()
|
||||||
|
|
||||||
@ -39,13 +38,11 @@ class VoiceMessageMediaManager: VoiceMessageMediaManagerProtocol {
|
|||||||
init(mediaProvider: MediaProviderProtocol,
|
init(mediaProvider: MediaProviderProtocol,
|
||||||
voiceMessageCache: VoiceMessageCacheProtocol = VoiceMessageCache(),
|
voiceMessageCache: VoiceMessageCacheProtocol = VoiceMessageCache(),
|
||||||
audioConverter: AudioConverterProtocol = AudioConverter(),
|
audioConverter: AudioConverterProtocol = AudioConverter(),
|
||||||
processingQueue: DispatchQueue = .global(),
|
processingQueue: DispatchQueue = .global()) {
|
||||||
backgroundTaskService: BackgroundTaskServiceProtocol?) {
|
|
||||||
self.mediaProvider = mediaProvider
|
self.mediaProvider = mediaProvider
|
||||||
self.voiceMessageCache = voiceMessageCache
|
self.voiceMessageCache = voiceMessageCache
|
||||||
self.audioConverter = audioConverter
|
self.audioConverter = audioConverter
|
||||||
self.processingQueue = processingQueue
|
self.processingQueue = processingQueue
|
||||||
self.backgroundTaskService = backgroundTaskService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
@ -53,9 +50,6 @@ class VoiceMessageMediaManager: VoiceMessageMediaManagerProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func loadVoiceMessageFromSource(_ source: MediaSourceProxy, body: String?) async throws -> URL {
|
func loadVoiceMessageFromSource(_ source: MediaSourceProxy, body: String?) async throws -> URL {
|
||||||
let loadFileBgTask = await backgroundTaskService?.startBackgroundTask(withName: "LoadFile: \(source.url.hashValue)")
|
|
||||||
defer { loadFileBgTask?.stop() }
|
|
||||||
|
|
||||||
guard let mimeType = source.mimeType, mimeType.starts(with: supportedVoiceMessageMimeType) else {
|
guard let mimeType = source.mimeType, mimeType.starts(with: supportedVoiceMessageMimeType) else {
|
||||||
throw VoiceMessageMediaManagerError.unsupportedMimeTye
|
throw VoiceMessageMediaManagerError.unsupportedMimeTye
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import MatrixRustSDK
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class UITestsAppCoordinator: AppCoordinatorProtocol, WindowManagerDelegate {
|
class UITestsAppCoordinator: AppCoordinatorProtocol, SecureWindowManagerDelegate {
|
||||||
private let navigationRootCoordinator: NavigationRootCoordinator
|
private let navigationRootCoordinator: NavigationRootCoordinator
|
||||||
|
|
||||||
// periphery:ignore - retaining purpose
|
// periphery:ignore - retaining purpose
|
||||||
@ -28,7 +28,7 @@ class UITestsAppCoordinator: AppCoordinatorProtocol, WindowManagerDelegate {
|
|||||||
// periphery:ignore - retaining purpose
|
// periphery:ignore - retaining purpose
|
||||||
private var alternateWindowMockScreen: MockScreen?
|
private var alternateWindowMockScreen: MockScreen?
|
||||||
|
|
||||||
let windowManager: WindowManagerProtocol
|
let windowManager: SecureWindowManagerProtocol
|
||||||
|
|
||||||
init(appDelegate: AppDelegate) {
|
init(appDelegate: AppDelegate) {
|
||||||
windowManager = WindowManager(appDelegate: appDelegate)
|
windowManager = WindowManager(appDelegate: appDelegate)
|
||||||
@ -70,7 +70,7 @@ class UITestsAppCoordinator: AppCoordinatorProtocol, WindowManagerDelegate {
|
|||||||
fatalError("Not implemented.")
|
fatalError("Not implemented.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func windowManagerDidConfigureWindows(_ windowManager: WindowManagerProtocol) {
|
func windowManagerDidConfigureWindows(_ windowManager: SecureWindowManagerProtocol) {
|
||||||
ServiceLocator.shared.userIndicatorController.window = windowManager.overlayWindow
|
ServiceLocator.shared.userIndicatorController.window = windowManager.overlayWindow
|
||||||
|
|
||||||
// Set up the alternate window for the App Lock flow coordinator tests.
|
// Set up the alternate window for the App Lock flow coordinator tests.
|
||||||
@ -92,14 +92,14 @@ class UITestsAppCoordinator: AppCoordinatorProtocol, WindowManagerDelegate {
|
|||||||
@MainActor
|
@MainActor
|
||||||
class MockScreen: Identifiable {
|
class MockScreen: Identifiable {
|
||||||
let id: UITestsScreenIdentifier
|
let id: UITestsScreenIdentifier
|
||||||
let windowManager: WindowManagerProtocol
|
let windowManager: SecureWindowManagerProtocol
|
||||||
let navigationRootCoordinator: NavigationRootCoordinator
|
let navigationRootCoordinator: NavigationRootCoordinator
|
||||||
|
|
||||||
private var retainedState = [Any]()
|
private var retainedState = [Any]()
|
||||||
private var cancellables = Set<AnyCancellable>()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
init(id: UITestsScreenIdentifier,
|
init(id: UITestsScreenIdentifier,
|
||||||
windowManager: WindowManagerProtocol,
|
windowManager: SecureWindowManagerProtocol,
|
||||||
navigationRootCoordinator: NavigationRootCoordinator) {
|
navigationRootCoordinator: NavigationRootCoordinator) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.windowManager = windowManager
|
self.windowManager = windowManager
|
||||||
@ -129,8 +129,7 @@ class MockScreen: Identifiable {
|
|||||||
appMediator: AppMediatorMock.default,
|
appMediator: AppMediatorMock.default,
|
||||||
appSettings: ServiceLocator.shared.settings,
|
appSettings: ServiceLocator.shared.settings,
|
||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||||
orientationManager: windowManager)
|
|
||||||
flowCoordinator.start()
|
flowCoordinator.start()
|
||||||
retainedState.append(flowCoordinator)
|
retainedState.append(flowCoordinator)
|
||||||
return nil
|
return nil
|
||||||
@ -468,7 +467,6 @@ class MockScreen: Identifiable {
|
|||||||
|
|
||||||
let flowCoordinator = UserSessionFlowCoordinator(userSession: MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider(), voiceMessageMediaManager: VoiceMessageMediaManagerMock()),
|
let flowCoordinator = UserSessionFlowCoordinator(userSession: MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider(), voiceMessageMediaManager: VoiceMessageMediaManagerMock()),
|
||||||
navigationRootCoordinator: navigationRootCoordinator,
|
navigationRootCoordinator: navigationRootCoordinator,
|
||||||
windowManager: windowManager,
|
|
||||||
appLockService: AppLockService(keychainController: KeychainControllerMock(),
|
appLockService: AppLockService(keychainController: KeychainControllerMock(),
|
||||||
appSettings: ServiceLocator.shared.settings),
|
appSettings: ServiceLocator.shared.settings),
|
||||||
bugReportService: BugReportServiceMock(),
|
bugReportService: BugReportServiceMock(),
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
class UnitTestsAppCoordinator: AppCoordinatorProtocol {
|
class UnitTestsAppCoordinator: AppCoordinatorProtocol {
|
||||||
let windowManager: WindowManagerProtocol
|
let windowManager: SecureWindowManagerProtocol
|
||||||
|
|
||||||
init(appDelegate: AppDelegate) {
|
init(appDelegate: AppDelegate) {
|
||||||
windowManager = WindowManager(appDelegate: appDelegate)
|
windowManager = WindowManager(appDelegate: appDelegate)
|
||||||
|
@ -22,8 +22,7 @@ final class NSEUserSession {
|
|||||||
private let notificationClient: NotificationClient
|
private let notificationClient: NotificationClient
|
||||||
private let userID: String
|
private let userID: String
|
||||||
private(set) lazy var mediaProvider: MediaProviderProtocol = MediaProvider(mediaLoader: MediaLoader(client: baseClient),
|
private(set) lazy var mediaProvider: MediaProviderProtocol = MediaProvider(mediaLoader: MediaLoader(client: baseClient),
|
||||||
imageCache: .onlyOnDisk,
|
imageCache: .onlyOnDisk)
|
||||||
backgroundTaskService: nil)
|
|
||||||
private let delegateHandle: TaskHandle?
|
private let delegateHandle: TaskHandle?
|
||||||
|
|
||||||
init(credentials: KeychainCredentials, clientSessionDelegate: ClientSessionDelegate) async throws {
|
init(credentials: KeychainCredentials, clientSessionDelegate: ClientSessionDelegate) async throws {
|
||||||
|
@ -97,8 +97,6 @@ targets:
|
|||||||
- path: ../../ElementX/Sources/Other/TestablePreview.swift
|
- path: ../../ElementX/Sources/Other/TestablePreview.swift
|
||||||
- path: ../../ElementX/Sources/Other/Pills/PlainMentionBuilder.swift
|
- path: ../../ElementX/Sources/Other/Pills/PlainMentionBuilder.swift
|
||||||
- path: ../../ElementX/Sources/Other/Pills/PillConstants.swift
|
- path: ../../ElementX/Sources/Other/Pills/PillConstants.swift
|
||||||
- path: ../../ElementX/Sources/Services/BackgroundTasks/BackgroundTaskProtocol.swift
|
|
||||||
- path: ../../ElementX/Sources/Services/BackgroundTasks/BackgroundTaskServiceProtocol.swift
|
|
||||||
- path: ../../ElementX/Sources/Services/Keychain/KeychainController.swift
|
- path: ../../ElementX/Sources/Services/Keychain/KeychainController.swift
|
||||||
- path: ../../ElementX/Sources/Services/Keychain/KeychainControllerProtocol.swift
|
- path: ../../ElementX/Sources/Services/Keychain/KeychainControllerProtocol.swift
|
||||||
- path: ../../ElementX/Sources/Services/Media/Provider
|
- path: ../../ElementX/Sources/Services/Media/Provider
|
||||||
|
@ -1,160 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2022 New Vector Ltd
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
|
|
||||||
import XCTest
|
|
||||||
|
|
||||||
@testable import ElementX
|
|
||||||
|
|
||||||
@MainActor
|
|
||||||
class BackgroundTaskTests: XCTestCase {
|
|
||||||
private enum Constants {
|
|
||||||
static let bgTaskName = "test"
|
|
||||||
}
|
|
||||||
|
|
||||||
func testInitAndStop() {
|
|
||||||
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
|
|
||||||
|
|
||||||
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName) else {
|
|
||||||
XCTFail("Failed to setup test conditions")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
XCTAssertEqual(task.name, Constants.bgTaskName, "Task name should be persisted")
|
|
||||||
XCTAssertFalse(task.isReusable, "Task should be not reusable by default")
|
|
||||||
XCTAssertTrue(task.isRunning, "Task should be running")
|
|
||||||
|
|
||||||
task.stop()
|
|
||||||
|
|
||||||
XCTAssertFalse(task.isRunning, "Task should be stopped")
|
|
||||||
}
|
|
||||||
|
|
||||||
func testNotReusableInit() {
|
|
||||||
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
|
|
||||||
|
|
||||||
// create two not reusable task with the same name
|
|
||||||
guard let task1 = service.startBackgroundTask(withName: Constants.bgTaskName),
|
|
||||||
let task2 = service.startBackgroundTask(withName: Constants.bgTaskName) else {
|
|
||||||
XCTFail("Failed to setup test conditions")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// task1 & task2 should be different instances
|
|
||||||
XCTAssertFalse(task1 === task2,
|
|
||||||
"Handler should create different tasks when reusability disabled")
|
|
||||||
}
|
|
||||||
|
|
||||||
func testReusableInit() {
|
|
||||||
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
|
|
||||||
|
|
||||||
// create two reusable task with the same name
|
|
||||||
guard let task1 = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true),
|
|
||||||
let task2 = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) else {
|
|
||||||
XCTFail("Failed to setup test conditions")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// task1 and task2 should be the same instance
|
|
||||||
XCTAssertTrue(task1 === task2,
|
|
||||||
"Handler should create different tasks when reusability disabled")
|
|
||||||
|
|
||||||
XCTAssertEqual(task1.name, Constants.bgTaskName, "Task name should be persisted")
|
|
||||||
XCTAssertTrue(task1.isReusable, "Task should be reusable")
|
|
||||||
XCTAssertTrue(task1.isRunning, "Task should be running")
|
|
||||||
}
|
|
||||||
|
|
||||||
func testMultipleStops() {
|
|
||||||
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
|
|
||||||
|
|
||||||
// create two reusable task with the same name
|
|
||||||
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true),
|
|
||||||
service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) != nil else {
|
|
||||||
XCTFail("Failed to setup test conditions")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
XCTAssertTrue(task.isRunning, "Task should be running")
|
|
||||||
|
|
||||||
task.stop()
|
|
||||||
|
|
||||||
XCTAssertTrue(task.isRunning, "Task should be still running after one stop call")
|
|
||||||
|
|
||||||
task.stop()
|
|
||||||
|
|
||||||
XCTAssertFalse(task.isRunning, "Task should be stopped after two stop calls")
|
|
||||||
}
|
|
||||||
|
|
||||||
func testNotValidReuse() {
|
|
||||||
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
|
|
||||||
|
|
||||||
// create two reusable task with the same name
|
|
||||||
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) else {
|
|
||||||
XCTFail("Failed to setup test conditions")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
XCTAssertTrue(task.isRunning, "Task should be running")
|
|
||||||
|
|
||||||
task.stop()
|
|
||||||
|
|
||||||
XCTAssertFalse(task.isRunning, "Task should be stopped after stop")
|
|
||||||
|
|
||||||
task.reuse()
|
|
||||||
|
|
||||||
XCTAssertFalse(task.isRunning, "Task should be stopped after one stop call, even if reuse is called after")
|
|
||||||
}
|
|
||||||
|
|
||||||
func testValidReuse() {
|
|
||||||
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
|
|
||||||
|
|
||||||
// create two reusable task with the same name
|
|
||||||
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) else {
|
|
||||||
XCTFail("Failed to setup test conditions")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
XCTAssertTrue(task.isRunning, "Task should be running")
|
|
||||||
|
|
||||||
task.reuse()
|
|
||||||
|
|
||||||
XCTAssertTrue(task.isRunning, "Task should be still running")
|
|
||||||
|
|
||||||
task.stop()
|
|
||||||
|
|
||||||
XCTAssertTrue(task.isRunning, "Task should be still running after one stop call")
|
|
||||||
|
|
||||||
task.stop()
|
|
||||||
|
|
||||||
XCTAssertFalse(task.isRunning, "Task should be stopped after two stop calls")
|
|
||||||
}
|
|
||||||
|
|
||||||
func testBrokenApp() {
|
|
||||||
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.mockBroken)
|
|
||||||
|
|
||||||
// create two reusable task with the same name
|
|
||||||
let task = service.startBackgroundTask(withName: Constants.bgTaskName)
|
|
||||||
|
|
||||||
XCTAssertNil(task, "Task should not be created")
|
|
||||||
}
|
|
||||||
|
|
||||||
func testNoTimeApp() {
|
|
||||||
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.mockAboutToSuspend)
|
|
||||||
|
|
||||||
// create two reusable task with the same name
|
|
||||||
let task = service.startBackgroundTask(withName: Constants.bgTaskName)
|
|
||||||
|
|
||||||
XCTAssertNil(task, "Task should not be created")
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,15 +22,13 @@ import XCTest
|
|||||||
final class MediaProviderTests: XCTestCase {
|
final class MediaProviderTests: XCTestCase {
|
||||||
private let mediaLoader = MockMediaLoader()
|
private let mediaLoader = MockMediaLoader()
|
||||||
private var imageCache: MockImageCache!
|
private var imageCache: MockImageCache!
|
||||||
private var backgroundTaskService = MockBackgroundTaskService()
|
|
||||||
|
|
||||||
var mediaProvider: MediaProvider!
|
var mediaProvider: MediaProvider!
|
||||||
|
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
imageCache = MockImageCache(name: "Test")
|
imageCache = MockImageCache(name: "Test")
|
||||||
mediaProvider = MediaProvider(mediaLoader: mediaLoader,
|
mediaProvider = MediaProvider(mediaLoader: mediaLoader,
|
||||||
imageCache: imageCache,
|
imageCache: imageCache)
|
||||||
backgroundTaskService: backgroundTaskService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_whenImageFromSourceWithSourceNil_nilReturned() throws {
|
func test_whenImageFromSourceWithSourceNil_nilReturned() throws {
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2022 New Vector Ltd
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
@testable import ElementX
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
class MockBackgroundTaskService: BackgroundTaskServiceProtocol {
|
|
||||||
func startBackgroundTask(withName name: String, isReusable: Bool, expirationHandler: (() -> Void)?) -> ElementX.BackgroundTaskProtocol? {
|
|
||||||
nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -295,8 +295,7 @@ class RoomFlowCoordinatorTests: XCTestCase {
|
|||||||
appMediator: AppMediatorMock.default,
|
appMediator: AppMediatorMock.default,
|
||||||
appSettings: ServiceLocator.shared.settings,
|
appSettings: ServiceLocator.shared.settings,
|
||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||||
orientationManager: OrientationManagerMock())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,6 @@ class UserSessionFlowCoordinatorTests: XCTestCase {
|
|||||||
|
|
||||||
userSessionFlowCoordinator = UserSessionFlowCoordinator(userSession: userSession,
|
userSessionFlowCoordinator = UserSessionFlowCoordinator(userSession: userSession,
|
||||||
navigationRootCoordinator: navigationRootCoordinator,
|
navigationRootCoordinator: navigationRootCoordinator,
|
||||||
windowManager: WindowManagerMock(),
|
|
||||||
appLockService: AppLockServiceMock(),
|
appLockService: AppLockServiceMock(),
|
||||||
bugReportService: BugReportServiceMock(),
|
bugReportService: BugReportServiceMock(),
|
||||||
roomTimelineControllerFactory: MockRoomTimelineControllerFactory(),
|
roomTimelineControllerFactory: MockRoomTimelineControllerFactory(),
|
||||||
|
@ -32,8 +32,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
|
|||||||
voiceMessageCache = VoiceMessageCacheMock()
|
voiceMessageCache = VoiceMessageCacheMock()
|
||||||
mediaProvider = MockMediaProvider()
|
mediaProvider = MockMediaProvider()
|
||||||
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
|
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
|
||||||
voiceMessageCache: voiceMessageCache,
|
voiceMessageCache: voiceMessageCache)
|
||||||
backgroundTaskService: MockBackgroundTaskService())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testLoadVoiceMessageFromSourceUnsupportedMedia() async throws {
|
func testLoadVoiceMessageFromSourceUnsupportedMedia() async throws {
|
||||||
@ -65,8 +64,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
|
|||||||
|
|
||||||
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
|
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
|
||||||
voiceMessageCache: voiceMessageCache,
|
voiceMessageCache: voiceMessageCache,
|
||||||
audioConverter: AudioConverterMock(),
|
audioConverter: AudioConverterMock())
|
||||||
backgroundTaskService: MockBackgroundTaskService())
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
_ = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
|
_ = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
|
||||||
@ -119,8 +117,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
|
|||||||
voiceMessageCache.cacheMediaSourceUsingMoveReturnValue = .success(cachedConvertedFileURL)
|
voiceMessageCache.cacheMediaSourceUsingMoveReturnValue = .success(cachedConvertedFileURL)
|
||||||
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
|
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
|
||||||
voiceMessageCache: voiceMessageCache,
|
voiceMessageCache: voiceMessageCache,
|
||||||
audioConverter: audioConverter,
|
audioConverter: audioConverter)
|
||||||
backgroundTaskService: MockBackgroundTaskService())
|
|
||||||
let url = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
|
let url = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
|
||||||
|
|
||||||
// The file must have been converted
|
// The file must have been converted
|
||||||
@ -155,8 +152,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
|
|||||||
|
|
||||||
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
|
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
|
||||||
voiceMessageCache: voiceMessageCache,
|
voiceMessageCache: voiceMessageCache,
|
||||||
audioConverter: audioConverter,
|
audioConverter: audioConverter)
|
||||||
backgroundTaskService: MockBackgroundTaskService())
|
|
||||||
|
|
||||||
let mediaSource = MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
|
let mediaSource = MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
|
||||||
for _ in 0..<10 {
|
for _ in 0..<10 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user