diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 4dd135a19..374721869 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 63; objects = { /* Begin PBXAggregateTarget section */ @@ -485,7 +485,7 @@ 5DD85A0FE3D85AEC3C7EFE36 /* DeveloperOptionsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7C7CFA6B2A62A685FF6CE3 /* DeveloperOptionsScreenCoordinator.swift */; }; 5DFC2A889D3B39DD47AC63A8 /* PillUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C537DE821FED94D23467B6C4 /* PillUtilities.swift */; }; 5EB116B58533C9A0EBA22717 /* ThreadTimelineScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC2E7CEE6E9314FD69FE0ED9 /* ThreadTimelineScreen.swift */; }; - 5EC046E41755C095DAB1C3FF /* TimelineProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8C9BBB729C941BEE0E2A63 /* TimelineProviderProtocol.swift */; }; + 5EC046E41755C095DAB1C3FF /* TimelineItemProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8C9BBB729C941BEE0E2A63 /* TimelineItemProviderProtocol.swift */; }; 5EDBDE802761B5ECB54E6787 /* LogLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2711E5996016ABD6EAAEB58A /* LogLevel.swift */; }; 5F06AD3C66884CE793AE6119 /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */; }; 5F0B5797D1BFF2A51084B4C3 /* PinnedEventsTimelineScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86D7CD5CA270BFC3EBB450CA /* PinnedEventsTimelineScreenViewModel.swift */; }; @@ -1105,7 +1105,7 @@ D97C782FE0005995C36FA04A /* portrait_test_video.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = E5E7D4EE7CA295E5039FDA21 /* portrait_test_video.mp4 */; }; D98B5EE8C4F5A2CE84687AE8 /* UTType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 897DF5E9A70CE05A632FC8AF /* UTType.swift */; }; D9F80CE61BF8FF627FDB0543 /* LoadableImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352359663A0E52BA20761EE /* LoadableImage.swift */; }; - DA03B4F28C4D248EECE3429F /* TimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371B248460BD1A3F20318137 /* TimelineProvider.swift */; }; + DA03B4F28C4D248EECE3429F /* TimelineItemProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371B248460BD1A3F20318137 /* TimelineItemProvider.swift */; }; DA10C99BA43A0F1E732F6274 /* LogLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2711E5996016ABD6EAAEB58A /* LogLevel.swift */; }; DA7E867F5EAFF8E20B2EE3B6 /* SecureBackupScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3D16709ADD4F4BCC710B1E /* SecureBackupScreenModels.swift */; }; DAF63A9CF9932CA8F6830F11 /* ShareExtensionModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCAC01A97A43BE07B9E94E43 /* ShareExtensionModels.swift */; }; @@ -1395,7 +1395,7 @@ 044E501B8331B339874D1B96 /* CompoundIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompoundIcon.swift; sourceTree = ""; }; 045253F9967A535EE5B16691 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = ""; }; 046C0D3F53B0B5EF0A1F5BEA /* RoomSummaryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryTests.swift; sourceTree = ""; }; - 048A21188AB19349D026BECD /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; + 048A21188AB19349D026BECD /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 04BB8DDE245ED86C489BA983 /* AccessibilityIdentifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityIdentifiers.swift; sourceTree = ""; }; 04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManager.swift; sourceTree = ""; }; 0516C69708D5CBDE1A8E77EC /* RoomDirectorySearchProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchProxyProtocol.swift; sourceTree = ""; }; @@ -1468,7 +1468,7 @@ 128501375217576AF0FE3E92 /* RoomAttachmentPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomAttachmentPicker.swift; sourceTree = ""; }; 12B09A94C519227264A41208 /* RoomMembershipDetailsProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembershipDetailsProxy.swift; sourceTree = ""; }; 12FD5280AF55AB7F50F8E47D /* preview_avatar_room.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = preview_avatar_room.jpg; sourceTree = ""; }; - 1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; path = IntegrationTests.xctestplan; sourceTree = ""; }; + 1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = IntegrationTests.xctestplan; sourceTree = ""; }; 130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNTextInputNotificationResponse+Creator.swift"; sourceTree = ""; }; 136F80A613B55BDD071DCEA5 /* JoinRoomScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinRoomScreenModels.swift; sourceTree = ""; }; 13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; @@ -1571,7 +1571,7 @@ 25F7FE40EF7490A7E09D7BE6 /* NotificationItemProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationItemProxy.swift; sourceTree = ""; }; 25F8664F1FB95AF3C4202478 /* PollFormScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenCoordinator.swift; sourceTree = ""; }; 260004737C573A56FA01E86E /* Encodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Encodable.swift; sourceTree = ""; }; - 267BB1D5B08A9511F894CB57 /* PreviewTests.xctestplan */ = {isa = PBXFileReference; path = PreviewTests.xctestplan; sourceTree = ""; }; + 267BB1D5B08A9511F894CB57 /* PreviewTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = PreviewTests.xctestplan; sourceTree = ""; }; 26B0A96B8FE4849227945067 /* VoiceMessageRecorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRecorder.swift; sourceTree = ""; }; 26EAAB54C6CE91D64B69A9F8 /* AppLockServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockServiceProtocol.swift; sourceTree = ""; }; 2711E5996016ABD6EAAEB58A /* LogLevel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogLevel.swift; sourceTree = ""; }; @@ -1648,9 +1648,9 @@ 3558A15CFB934F9229301527 /* RestorationToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorationToken.swift; sourceTree = ""; }; 35AFCF4C05DEED04E3DB1A16 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; 35FA991289149D31F4286747 /* UserPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreference.swift; sourceTree = ""; }; - 36DA824791172B9821EACBED /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; + 36DA824791172B9821EACBED /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 36FD673E24FBFCFDF398716A /* RoomMemberProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberProxyMock.swift; sourceTree = ""; }; - 371B248460BD1A3F20318137 /* TimelineProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineProvider.swift; sourceTree = ""; }; + 371B248460BD1A3F20318137 /* TimelineItemProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemProvider.swift; sourceTree = ""; }; 37A63A59BFDDC494B1C20119 /* CallScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallScreenViewModel.swift; sourceTree = ""; }; 37CA26F55123E36B50DB0B3A /* AttributedStringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringTests.swift; sourceTree = ""; }; 37F46CC4FD89ECF4CF26391A /* AuthenticationFlowCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationFlowCoordinatorTests.swift; sourceTree = ""; }; @@ -2062,7 +2062,7 @@ 8D55702474F279D910D2D162 /* RoomStateEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomStateEventStringBuilder.swift; sourceTree = ""; }; 8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = ""; }; 8DA1E8F287680C8ED25EDBAC /* NetworkMonitorMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkMonitorMock.swift; sourceTree = ""; }; - 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; path = UITests.xctestplan; sourceTree = ""; }; + 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UITests.xctestplan; sourceTree = ""; }; 8E1584F8BCF407BB94F48F04 /* EncryptionResetPasswordScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreen.swift; sourceTree = ""; }; 8EAF4A49F3ACD8BB8B0D2371 /* ClientSDKMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientSDKMock.swift; sourceTree = ""; }; 8F062DD2CCD95DC33528A16F /* KnockRequestProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KnockRequestProxy.swift; sourceTree = ""; }; @@ -2265,7 +2265,7 @@ B53AC78E49A297AC1D72A7CF /* AppMediator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMediator.swift; sourceTree = ""; }; B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableAvatarImage.swift; sourceTree = ""; }; B5D829FD8958376614504B18 /* TargetConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TargetConfiguration.swift; sourceTree = ""; }; - B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; path = ConfettiScene.scn; sourceTree = ""; }; + B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = ConfettiScene.scn; sourceTree = ""; }; B63B69F9A2BC74DD40DC75C8 /* AdvancedSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModel.swift; sourceTree = ""; }; B6404166CBF5CC88673FF9E2 /* RoomDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetails.swift; sourceTree = ""; }; B655A536341D2695158C6664 /* AuthenticationClientBuilderFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationClientBuilderFactory.swift; sourceTree = ""; }; @@ -2293,7 +2293,7 @@ BA40B98B098B6F0371B750B3 /* TemplateScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenModels.swift; sourceTree = ""; }; BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreen.swift; sourceTree = ""; }; BB284643AF7AB131E307DCE0 /* AudioSessionProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioSessionProtocol.swift; sourceTree = ""; }; - BB576F4118C35E6B5124FA22 /* test_apple_image.heic */ = {isa = PBXFileReference; path = test_apple_image.heic; sourceTree = ""; }; + BB576F4118C35E6B5124FA22 /* test_apple_image.heic */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_apple_image.heic; sourceTree = ""; }; BB5B00A014307CE37B2812CD /* TimelineViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineViewModelProtocol.swift; sourceTree = ""; }; BB6ED50FE104992419310EEB /* NotificationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationHandler.swift; sourceTree = ""; }; BB8BC4C791D0E88CFCF4E5DF /* ServerSelectionScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreenCoordinator.swift; sourceTree = ""; }; @@ -2394,7 +2394,7 @@ CDB3227C7A74B734924942E9 /* RoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProvider.swift; sourceTree = ""; }; CDE3F3911FF7CC639BDE5844 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; CEE20623EB4A9B88FB29F2BA /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/SAS.strings; sourceTree = ""; }; - CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; path = UnitTests.xctestplan; sourceTree = ""; }; + CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UnitTests.xctestplan; sourceTree = ""; }; D01FD1171FF40E34D707FD00 /* BigIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BigIcon.swift; sourceTree = ""; }; D046ABB22E680F7C5054441B /* SecurityAndPrivacyScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreenViewModelProtocol.swift; sourceTree = ""; }; D071F86CD47582B9196C9D16 /* UserDiscoverySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoverySection.swift; sourceTree = ""; }; @@ -2457,11 +2457,11 @@ DC0AEA686E425F86F6BA0404 /* UNNotification+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNNotification+Creator.swift"; sourceTree = ""; }; DC10CCC8D68B863E20660DBC /* MessageForwardingScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreenViewModelProtocol.swift; sourceTree = ""; }; DC528B3764E3CF7FCFEF40E7 /* PollInteractionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollInteractionHandler.swift; sourceTree = ""; }; - DCA2D836BD10303F37FAAEED /* test_voice_message.m4a */ = {isa = PBXFileReference; path = test_voice_message.m4a; sourceTree = ""; }; + DCA2D836BD10303F37FAAEED /* test_voice_message.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_voice_message.m4a; sourceTree = ""; }; DCAC01A97A43BE07B9E94E43 /* ShareExtensionModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareExtensionModels.swift; sourceTree = ""; }; DCDAB580109C09A6AA97AF7E /* PollFormScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenTests.swift; sourceTree = ""; }; DCF239C619971FDE48132550 /* SecureBackupLogoutConfirmationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupLogoutConfirmationScreenModels.swift; sourceTree = ""; }; - DD8C9BBB729C941BEE0E2A63 /* TimelineProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineProviderProtocol.swift; sourceTree = ""; }; + DD8C9BBB729C941BEE0E2A63 /* TimelineItemProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemProviderProtocol.swift; sourceTree = ""; }; DD955A0380C287C418F1A74D /* PhotoLibraryManagerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryManagerMock.swift; sourceTree = ""; }; DD97F9661ABF08CE002054A2 /* AppLockServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockServiceTests.swift; sourceTree = ""; }; DE5127D6EA05B2E45D0A7D59 /* JoinRoomScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinRoomScreenViewModelTests.swift; sourceTree = ""; }; @@ -2500,7 +2500,7 @@ E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = ""; }; E53BFB7E4F329621C844E8C3 /* AnalyticsPromptScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPromptScreen.swift; sourceTree = ""; }; E55B5EA766E89FF1F87C3ACB /* RoomNotificationSettingsProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsProxyProtocol.swift; sourceTree = ""; }; - E5E7D4EE7CA295E5039FDA21 /* portrait_test_video.mp4 */ = {isa = PBXFileReference; path = portrait_test_video.mp4; sourceTree = ""; }; + E5E7D4EE7CA295E5039FDA21 /* portrait_test_video.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = portrait_test_video.mp4; sourceTree = ""; }; E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerProtocol.swift; sourceTree = ""; }; E5F2B6443D1ED8602F328539 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = ""; }; E5FDFAA04174CC99FB66391C /* EditRoomAddressScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditRoomAddressScreenViewModel.swift; sourceTree = ""; }; @@ -2542,7 +2542,7 @@ ED0CBEAB5F796BEFBAF7BB6A /* VideoRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRoomTimelineView.swift; sourceTree = ""; }; ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = ""; }; ED33988DA4FD4FC666800106 /* SessionVerificationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModel.swift; sourceTree = ""; }; - ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; path = message.caf; sourceTree = ""; }; + ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = message.caf; sourceTree = ""; }; ED49073BB1C1FC649DAC2CCD /* LocationRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationRoomTimelineView.swift; sourceTree = ""; }; ED60E4D2CD678E1EBF16F77A /* BlockedUsersScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersScreen.swift; sourceTree = ""; }; EE378083653EF0C9B5E9D580 /* EmoteRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItemContent.swift; sourceTree = ""; }; @@ -6086,8 +6086,8 @@ E48C91C8BE55CAE1A3DBC3BC /* TimelineItemIdentifier.swift */, 2D505843AB66822EB91F0DF0 /* TimelineItemProxy.swift */, 55AEEF8142DF1B59DB40FB93 /* TimelineItemSender.swift */, - 371B248460BD1A3F20318137 /* TimelineProvider.swift */, - DD8C9BBB729C941BEE0E2A63 /* TimelineProviderProtocol.swift */, + 371B248460BD1A3F20318137 /* TimelineItemProvider.swift */, + DD8C9BBB729C941BEE0E2A63 /* TimelineItemProviderProtocol.swift */, F9E543072DE58E751F028998 /* TimelineProxy.swift */, B50F03079F6B5EF9CA005F14 /* TimelineProxyProtocol.swift */, 3EA31CC7012EA2A5653DAFC9 /* Fixtures */, @@ -6468,7 +6468,6 @@ EC6D0C817B1C21D9D096505A /* XCRemoteSwiftPackageReference "Version" */, EE40B0E16A55BD23ECBFFD22 /* XCRemoteSwiftPackageReference "matrix-rich-text-editor-swift" */, ); - preferredProjectObjectVersion = 54; projectDirPath = ""; projectRoot = ""; targets = ( @@ -7762,9 +7761,9 @@ A32384E3D85CA65342D3A908 /* TimelineMediaPreviewRedactConfirmationView.swift in Sources */, 86769B62BAE17601B3AE1B60 /* TimelineMediaPreviewViewModel.swift in Sources */, B818580464CFB5400A3EF6AE /* TimelineModels.swift in Sources */, - DA03B4F28C4D248EECE3429F /* TimelineProvider.swift in Sources */, + DA03B4F28C4D248EECE3429F /* TimelineItemProvider.swift in Sources */, 4E4EF97B9F9CEFAC726BA72F /* TimelineProviderMock.swift in Sources */, - 5EC046E41755C095DAB1C3FF /* TimelineProviderProtocol.swift in Sources */, + 5EC046E41755C095DAB1C3FF /* TimelineItemProviderProtocol.swift in Sources */, E82E13CC3EB923CCB8F8273C /* TimelineProxy.swift in Sources */, 16A1F6C703305FCAF4E14EC6 /* TimelineProxyMock.swift in Sources */, 2FEC6652055984389CE1BBEC /* TimelineProxyProtocol.swift in Sources */, @@ -8124,9 +8123,7 @@ "@executable_path/../../Frameworks", ); MARKETING_VERSION = "$(MARKETING_VERSION)"; - OTHER_SWIFT_FLAGS = ( - "-DIS_NSE", - ); + OTHER_SWIFT_FLAGS = "-DIS_NSE"; PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.nse"; PRODUCT_DISPLAY_NAME = "$(APP_DISPLAY_NAME)"; PRODUCT_NAME = NSE; @@ -8175,9 +8172,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = "$(MARKETING_VERSION)"; - OTHER_SWIFT_FLAGS = ( - "-DIS_MAIN_APP", - ); + OTHER_SWIFT_FLAGS = "-DIS_MAIN_APP"; PILLS_UT_TYPE_IDENTIFIER = "$(BASE_BUNDLE_IDENTIFIER).pills"; PRODUCT_BUNDLE_IDENTIFIER = "$(BASE_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(APP_NAME)"; @@ -8203,9 +8198,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = "$(MARKETING_VERSION)"; - OTHER_SWIFT_FLAGS = ( - "-DIS_MAIN_APP", - ); + OTHER_SWIFT_FLAGS = "-DIS_MAIN_APP"; PILLS_UT_TYPE_IDENTIFIER = "$(BASE_BUNDLE_IDENTIFIER).pills"; PRODUCT_BUNDLE_IDENTIFIER = "$(BASE_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(APP_NAME)"; @@ -8430,9 +8423,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - OTHER_SWIFT_FLAGS = ( - "-DDEBUG", - ); + OTHER_SWIFT_FLAGS = "-DDEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.ui.tests"; PRODUCT_NAME = UITests; SDKROOT = iphoneos; @@ -8451,9 +8442,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - OTHER_SWIFT_FLAGS = ( - "-DRELEASE", - ); + OTHER_SWIFT_FLAGS = "-DRELEASE"; PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.ui.tests"; PRODUCT_NAME = UITests; SDKROOT = iphoneos; @@ -8475,9 +8464,7 @@ "@executable_path/../../Frameworks", ); MARKETING_VERSION = "$(MARKETING_VERSION)"; - OTHER_SWIFT_FLAGS = ( - "-DIS_NSE", - ); + OTHER_SWIFT_FLAGS = "-DIS_NSE"; PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.nse"; PRODUCT_DISPLAY_NAME = "$(APP_DISPLAY_NAME)"; PRODUCT_NAME = NSE; diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 8fff2377f..204b0f574 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -15297,7 +15297,7 @@ class TimelineControllerFactoryMock: TimelineControllerFactoryProtocol, @uncheck } } } -class TimelineProviderMock: TimelineProviderProtocol, @unchecked Sendable { +class TimelineItemProviderMock: TimelineItemProviderProtocol, @unchecked Sendable { var updatePublisher: AnyPublisher<([TimelineItemProxy], PaginationState), Never> { get { return underlyingUpdatePublisher } set(value) { underlyingUpdatePublisher = value } @@ -15322,11 +15322,11 @@ class TimelineProviderMock: TimelineProviderProtocol, @unchecked Sendable { } class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable { - var timelineProvider: TimelineProviderProtocol { - get { return underlyingTimelineProvider } - set(value) { underlyingTimelineProvider = value } + var timelineItemProvider: TimelineItemProviderProtocol { + get { return underlyingTimelineItemProvider } + set(value) { underlyingTimelineItemProvider = value } } - var underlyingTimelineProvider: TimelineProviderProtocol! + var underlyingTimelineItemProvider: TimelineItemProviderProtocol! //MARK: - subscribeForUpdates diff --git a/ElementX/Sources/Mocks/TimelineProviderMock.swift b/ElementX/Sources/Mocks/TimelineProviderMock.swift index 73f10c0ed..bc0527150 100644 --- a/ElementX/Sources/Mocks/TimelineProviderMock.swift +++ b/ElementX/Sources/Mocks/TimelineProviderMock.swift @@ -10,7 +10,7 @@ import Foundation import MatrixRustSDK @MainActor -class AutoUpdatingTimelineProviderMock: TimelineProvider { +class AutoUpdatingTimelineItemProviderMock: TimelineItemProvider { static var timelineListener: TimelineListener? private let innerPaginationStatePublisher: PassthroughSubject diff --git a/ElementX/Sources/Mocks/TimelineProxyMock.swift b/ElementX/Sources/Mocks/TimelineProxyMock.swift index 08faa97a2..dae96feb2 100644 --- a/ElementX/Sources/Mocks/TimelineProxyMock.swift +++ b/ElementX/Sources/Mocks/TimelineProxyMock.swift @@ -24,12 +24,12 @@ extension TimelineProxyMock { sendReadReceiptForTypeReturnValue = .success(()) if configuration.isAutoUpdating { - underlyingTimelineProvider = AutoUpdatingTimelineProviderMock() + underlyingTimelineItemProvider = AutoUpdatingTimelineItemProviderMock() } else { - let timelineProvider = TimelineProviderMock() - timelineProvider.paginationState = .init(backward: configuration.timelineStartReached ? .timelineEndReached : .idle, forward: .timelineEndReached) - timelineProvider.underlyingMembershipChangePublisher = PassthroughSubject().eraseToAnyPublisher() - underlyingTimelineProvider = timelineProvider + let timelineItemProvider = TimelineItemProviderMock() + timelineItemProvider.paginationState = .init(backward: configuration.timelineStartReached ? .timelineEndReached : .idle, forward: .timelineEndReached) + timelineItemProvider.underlyingMembershipChangePublisher = PassthroughSubject().eraseToAnyPublisher() + underlyingTimelineItemProvider = timelineItemProvider } } } diff --git a/ElementX/Sources/Other/NetworkMonitor/NetworkMonitor.swift b/ElementX/Sources/Other/NetworkMonitor/NetworkMonitor.swift index bdc42a32c..16bd1e1b1 100644 --- a/ElementX/Sources/Other/NetworkMonitor/NetworkMonitor.swift +++ b/ElementX/Sources/Other/NetworkMonitor/NetworkMonitor.swift @@ -19,7 +19,7 @@ class NetworkMonitor: NetworkMonitorProtocol { } init() { - queue = DispatchQueue(label: "io.element.elementx.networkmonitor", qos: .background) + queue = DispatchQueue(label: "io.element.elementx.network_monitor", qos: .background) pathMonitor = NWPathMonitor() reachabilitySubject = CurrentValueSubject(.reachable) diff --git a/ElementX/Sources/Other/SDKListener.swift b/ElementX/Sources/Other/SDKListener.swift index 65749f9b1..985a21776 100644 --- a/ElementX/Sources/Other/SDKListener.swift +++ b/ElementX/Sources/Other/SDKListener.swift @@ -94,7 +94,7 @@ extension SDKListener: ProgressWatcher where T == Double { } } -// MARK: TimelineProvider +// MARK: TimelineItemProvider extension SDKListener: TimelineListener where T == [TimelineDiff] { func onUpdate(diff: [TimelineDiff]) { onUpdateClosure(diff) } diff --git a/ElementX/Sources/Screens/RoomChangeRolesScreen/RoomChangeRolesScreenViewModel.swift b/ElementX/Sources/Screens/RoomChangeRolesScreen/RoomChangeRolesScreenViewModel.swift index ca8d279dc..67297a505 100644 --- a/ElementX/Sources/Screens/RoomChangeRolesScreen/RoomChangeRolesScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomChangeRolesScreen/RoomChangeRolesScreenViewModel.swift @@ -45,7 +45,7 @@ class RoomChangeRolesScreenViewModel: RoomChangeRolesScreenViewModelType, RoomCh } .store(in: &cancellables) - roomProxy.timeline.timelineProvider.membershipChangePublisher.sink { [roomProxy] in + roomProxy.timeline.timelineItemProvider.membershipChangePublisher.sink { [roomProxy] in Task { await roomProxy.updateMembers() } } .store(in: &cancellables) diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift index ed9544f0e..939ea8f19 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift @@ -20,15 +20,15 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr private let attributedStringBuilder: AttributedStringBuilderProtocol private let appSettings: AppSettings - private var pinnedEventsTimelineProvider: TimelineProviderProtocol? { + private var pinnedEventsTimelineItemProvider: TimelineItemProviderProtocol? { didSet { - guard let pinnedEventsTimelineProvider else { + guard let pinnedEventsTimelineItemProvider else { return } - state.pinnedEventsActionState = .loaded(numberOfItems: pinnedEventsTimelineProvider.itemProxies.filter(\.isEvent).count) + state.pinnedEventsActionState = .loaded(numberOfItems: pinnedEventsTimelineItemProvider.itemProxies.filter(\.isEvent).count) - pinnedEventsTimelineProvider.updatePublisher + pinnedEventsTimelineItemProvider.updatePublisher // When pinning or unpinning an item, the timeline might return empty for a short while, so we need to debounce it to prevent weird UI behaviours like the banner disappearing .debounce(for: .milliseconds(100), scheduler: DispatchQueue.main) .sink { [weak self] updatedItems, _ in @@ -86,7 +86,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr .filter { $0 == .reachable } .receive(on: DispatchQueue.main) .sink { [weak self] _ in - self?.setupPinnedEventsTimelineProviderIfNeeded() + self?.setupPinnedEventsTimelineItemProviderIfNeeded() } .store(in: &cancellables) @@ -439,8 +439,8 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr } } - private func setupPinnedEventsTimelineProviderIfNeeded() { - guard pinnedEventsTimelineProvider == nil else { + private func setupPinnedEventsTimelineItemProviderIfNeeded() { + guard pinnedEventsTimelineItemProvider == nil else { return } @@ -449,8 +449,8 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr return } - if pinnedEventsTimelineProvider == nil { - pinnedEventsTimelineProvider = pinnedEventsTimeline.timelineProvider + if pinnedEventsTimelineItemProvider == nil { + pinnedEventsTimelineItemProvider = pinnedEventsTimeline.timelineItemProvider } } } diff --git a/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenViewModel.swift b/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenViewModel.swift index f9de111b4..b267adf90 100644 --- a/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenViewModel.swift @@ -78,7 +78,7 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe } .store(in: &cancellables) - roomProxy.timeline.timelineProvider.membershipChangePublisher.sink { [roomProxy] _ in + roomProxy.timeline.timelineItemProvider.membershipChangePublisher.sink { [roomProxy] _ in Task { await roomProxy.updateMembers() } } .store(in: &cancellables) diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index d8f398edd..53f2c8131 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -32,14 +32,14 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol actionsSubject.eraseToAnyPublisher() } - private var pinnedEventsTimelineProvider: TimelineProviderProtocol? { + private var pinnedEventsTimelineItemProvider: TimelineItemProviderProtocol? { didSet { - guard let pinnedEventsTimelineProvider else { + guard let pinnedEventsTimelineItemProvider else { return } - buildPinnedEventContents(timelineItems: pinnedEventsTimelineProvider.itemProxies) - pinnedEventsTimelineProvider.updatePublisher + buildPinnedEventContents(timelineItems: pinnedEventsTimelineItemProvider.itemProxies) + pinnedEventsTimelineItemProvider.updatePublisher // When pinning or unpinning an item, the timeline might return empty for a short while, so we need to debounce it to prevent weird UI behaviours like the banner disappearing .debounce(for: .milliseconds(100), scheduler: DispatchQueue.main) .sink { [weak self] updatedItems, _ in @@ -193,7 +193,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol .filter { $0 == .reachable } .receive(on: DispatchQueue.main) .sink { [weak self] _ in - self?.setupPinnedEventsTimelineProviderIfNeeded() + self?.setupPinnedEventsTimelineItemProviderIfNeeded() } .store(in: &cancellables) @@ -347,8 +347,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol state.canBan = await (try? roomProxy.canUserBan(userID: ownUserID).get()) == true } - private func setupPinnedEventsTimelineProviderIfNeeded() { - guard pinnedEventsTimelineProvider == nil else { + private func setupPinnedEventsTimelineItemProviderIfNeeded() { + guard pinnedEventsTimelineItemProvider == nil else { return } @@ -357,8 +357,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol return } - if pinnedEventsTimelineProvider == nil { - pinnedEventsTimelineProvider = pinnedEventsTimeline.timelineProvider + if pinnedEventsTimelineItemProvider == nil { + pinnedEventsTimelineItemProvider = pinnedEventsTimeline.timelineItemProvider } } } diff --git a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift index d8cfb79a3..1a4ac72ef 100644 --- a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift +++ b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift @@ -63,7 +63,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol { notificationSettings: NotificationSettingsProxyProtocol, appSettings: AppSettings) { self.roomListService = roomListService - serialDispatchQueue = DispatchQueue(label: "io.element.elementx.roomsummaryprovider", qos: .default) + serialDispatchQueue = DispatchQueue(label: "io.element.elementx.room_summary_provider", qos: .default) self.eventStringBuilder = eventStringBuilder self.name = name self.shouldUpdateVisibleRange = shouldUpdateVisibleRange diff --git a/ElementX/Sources/Services/RoomDirectorySearch/RoomDirectorySearchProxy.swift b/ElementX/Sources/Services/RoomDirectorySearch/RoomDirectorySearchProxy.swift index 810ccfd55..b08e2570d 100644 --- a/ElementX/Sources/Services/RoomDirectorySearch/RoomDirectorySearchProxy.swift +++ b/ElementX/Sources/Services/RoomDirectorySearch/RoomDirectorySearchProxy.swift @@ -13,7 +13,7 @@ import MatrixRustSDK final class RoomDirectorySearchProxy: RoomDirectorySearchProxyProtocol { private let roomDirectorySearch: RoomDirectorySearchProtocol private let appSettings: AppSettings - private let serialDispatchQueue = DispatchQueue(label: "io.element.elementx.roomdirectorysearch", qos: .default) + private let serialDispatchQueue = DispatchQueue(label: "io.element.elementx.room_directory_search_proxy", qos: .default) private let resultsSubject = CurrentValueSubject<[RoomDirectorySearchResult], Never>([]) diff --git a/ElementX/Sources/Services/Timeline/TimelineController/TimelineController.swift b/ElementX/Sources/Services/Timeline/TimelineController/TimelineController.swift index 756991c92..e7d8ccf05 100644 --- a/ElementX/Sources/Services/Timeline/TimelineController/TimelineController.swift +++ b/ElementX/Sources/Services/Timeline/TimelineController/TimelineController.swift @@ -13,19 +13,17 @@ import UIKit class TimelineController: TimelineControllerProtocol { private let roomProxy: JoinedRoomProxyProtocol - private let liveTimelineProvider: TimelineProviderProtocol + private let liveTimelineItemProvider: TimelineItemProviderProtocol private let timelineItemFactory: RoomTimelineItemFactoryProtocol private let mediaProvider: MediaProviderProtocol private let appSettings: AppSettings - private let serialDispatchQueue: DispatchQueue - let callbacks = PassthroughSubject() private var activeTimeline: TimelineProxyProtocol - private var activeTimelineProvider: TimelineProviderProtocol { + private var activeTimelineItemProvider: TimelineItemProviderProtocol { didSet { - configureActiveTimelineProvider() + configureActiveTimelineItemProvider() } } @@ -42,7 +40,7 @@ class TimelineController: TimelineControllerProtocol { } var timelineKind: TimelineKind { - activeTimelineProvider.kind + activeTimelineItemProvider.kind } init(roomProxy: JoinedRoomProxyProtocol, @@ -52,18 +50,16 @@ class TimelineController: TimelineControllerProtocol { mediaProvider: MediaProviderProtocol, appSettings: AppSettings) { self.roomProxy = roomProxy - liveTimelineProvider = timelineProxy.timelineProvider + liveTimelineItemProvider = timelineProxy.timelineItemProvider self.timelineItemFactory = timelineItemFactory self.mediaProvider = mediaProvider self.appSettings = appSettings - serialDispatchQueue = DispatchQueue(label: "io.element.elementx.timelineprovider", qos: .utility) - activeTimeline = timelineProxy - activeTimelineProvider = liveTimelineProvider + activeTimelineItemProvider = liveTimelineItemProvider guard let initialFocussedEventID else { - configureActiveTimelineProvider() + configureActiveTimelineItemProvider() return } @@ -75,7 +71,7 @@ class TimelineController: TimelineControllerProtocol { break case .failure: // Setup the live timeline as a fallback. - configureActiveTimelineProvider() + configureActiveTimelineItemProvider() } } } @@ -85,7 +81,7 @@ class TimelineController: TimelineControllerProtocol { case .success(let timeline): await timeline.subscribeForUpdates() activeTimeline = timeline - activeTimelineProvider = timeline.timelineProvider + activeTimelineItemProvider = timeline.timelineItemProvider return .success(()) case .failure(let error): if case .eventNotFound = error { @@ -98,7 +94,7 @@ class TimelineController: TimelineControllerProtocol { func focusLive() { activeTimeline = roomProxy.timeline - activeTimelineProvider = liveTimelineProvider + activeTimelineItemProvider = liveTimelineItemProvider } func paginateBackwards(requestSize: UInt16) async -> Result { @@ -328,7 +324,7 @@ class TimelineController: TimelineControllerProtocol { // Handle this parallel to the timeline items so we're not forced // to bundle the Rust side objects within them func debugInfo(for itemID: TimelineItemIdentifier) -> TimelineItemDebugInfo { - for timelineItemProxy in activeTimelineProvider.itemProxies { + for timelineItemProxy in activeTimelineItemProvider.itemProxies { switch timelineItemProxy { case .event(let item): if item.id == itemID { @@ -343,7 +339,7 @@ class TimelineController: TimelineControllerProtocol { } func sendHandle(for itemID: TimelineItemIdentifier) -> SendHandleProxy? { - for timelineItemProxy in activeTimelineProvider.itemProxies { + for timelineItemProxy in activeTimelineItemProvider.itemProxies { switch timelineItemProxy { case .event(let item): if item.id == itemID { @@ -361,24 +357,24 @@ class TimelineController: TimelineControllerProtocol { /// The cancellable used to update the timeline items. private var updateTimelineItemsCancellable: AnyCancellable? - /// The controller is switching the `activeTimelineProvider`. + /// The controller is switching the `activeTimelineItemProvider`. private var isSwitchingTimelines = false /// Configures the controller to listen to `activeTimeline` for events. /// - Parameter clearExistingItems: Whether or not to clear any existing items before loading the timeline's contents. - private func configureActiveTimelineProvider() { + private func configureActiveTimelineItemProvider() { updateTimelineItemsCancellable = nil isSwitchingTimelines = true // Inform the world that the initial items are loading from the store paginationState = PaginationState(backward: .paginating, forward: .paginating) - callbacks.send(.isLive(activeTimelineProvider.kind == .live)) + callbacks.send(.isLive(activeTimelineItemProvider.kind == .live)) - updateTimelineItemsCancellable = Task { [weak self, activeTimelineProvider] in + updateTimelineItemsCancellable = Task { [weak self, activeTimelineItemProvider] in let contentSizeChangePublisher = NotificationCenter.default.publisher(for: UIContentSizeCategory.didChangeNotification) - let timelineUpdates = activeTimelineProvider.updatePublisher.merge(with: contentSizeChangePublisher.map { _ in - (activeTimelineProvider.itemProxies, activeTimelineProvider.paginationState) + let timelineUpdates = activeTimelineItemProvider.updatePublisher.merge(with: contentSizeChangePublisher.map { _ in + (activeTimelineItemProvider.itemProxies, activeTimelineItemProvider.paginationState) }) for await (items, paginationState) in timelineUpdates.values { @@ -506,7 +502,7 @@ class TimelineController: TimelineControllerProtocol { } func eventTimestamp(for itemID: TimelineItemIdentifier) -> Date? { - for itemProxy in activeTimelineProvider.itemProxies { + for itemProxy in activeTimelineItemProvider.itemProxies { switch itemProxy { case .event(let eventTimelineItemProxy): if eventTimelineItemProxy.id == itemID { diff --git a/ElementX/Sources/Services/Timeline/TimelineProvider.swift b/ElementX/Sources/Services/Timeline/TimelineItemProvider.swift similarity index 98% rename from ElementX/Sources/Services/Timeline/TimelineProvider.swift rename to ElementX/Sources/Services/Timeline/TimelineItemProvider.swift index 2fe37fb41..89724b2dc 100644 --- a/ElementX/Sources/Services/Timeline/TimelineProvider.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItemProvider.swift @@ -9,7 +9,7 @@ import Combine import Foundation import MatrixRustSDK -class TimelineProvider: TimelineProviderProtocol { +class TimelineItemProvider: TimelineItemProviderProtocol { private var cancellables = Set() private let serialDispatchQueue: DispatchQueue @@ -46,7 +46,7 @@ class TimelineProvider: TimelineProviderProtocol { } init(timeline: Timeline, kind: TimelineKind, paginationStatePublisher: AnyPublisher) { - serialDispatchQueue = DispatchQueue(label: "io.element.elementx.timelineprovider", qos: .utility) + serialDispatchQueue = DispatchQueue(label: "io.element.elementx.timeline_item_provider", qos: .utility) itemProxiesSubject = CurrentValueSubject<[TimelineItemProxy], Never>([]) self.kind = kind diff --git a/ElementX/Sources/Services/Timeline/TimelineProviderProtocol.swift b/ElementX/Sources/Services/Timeline/TimelineItemProviderProtocol.swift similarity index 97% rename from ElementX/Sources/Services/Timeline/TimelineProviderProtocol.swift rename to ElementX/Sources/Services/Timeline/TimelineItemProviderProtocol.swift index 8e60c7dea..0541aa11f 100644 --- a/ElementX/Sources/Services/Timeline/TimelineProviderProtocol.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItemProviderProtocol.swift @@ -29,7 +29,7 @@ struct PaginationState: Equatable { @MainActor // sourcery: AutoMockable -protocol TimelineProviderProtocol { +protocol TimelineItemProviderProtocol { /// A publisher that signals when ``itemProxies`` or ``paginationState`` are changed. var updatePublisher: AnyPublisher<([TimelineItemProxy], PaginationState), Never> { get } /// The current set of items in the timeline. diff --git a/ElementX/Sources/Services/Timeline/TimelineProxy.swift b/ElementX/Sources/Services/Timeline/TimelineProxy.swift index 6e418eccc..ab0d26a25 100644 --- a/ElementX/Sources/Services/Timeline/TimelineProxy.swift +++ b/ElementX/Sources/Services/Timeline/TimelineProxy.swift @@ -24,9 +24,9 @@ final class TimelineProxy: TimelineProxyProtocol { private let kind: TimelineKind - private var innerTimelineProvider: TimelineProviderProtocol! - var timelineProvider: TimelineProviderProtocol { - innerTimelineProvider + private var innerTimelineItemProvider: TimelineItemProviderProtocol! + var timelineItemProvider: TimelineItemProviderProtocol { + innerTimelineItemProvider } deinit { @@ -39,7 +39,7 @@ final class TimelineProxy: TimelineProxyProtocol { } func subscribeForUpdates() async { - guard innerTimelineProvider == nil else { + guard innerTimelineItemProvider == nil else { MXLog.warning("Timeline already subscribed for updates") return } @@ -51,12 +51,12 @@ final class TimelineProxy: TimelineProxyProtocol { await subscribeToPagination() - let provider = await TimelineProvider(timeline: timeline, kind: kind, paginationStatePublisher: paginationStatePublisher) + let provider = await TimelineItemProvider(timeline: timeline, kind: kind, paginationStatePublisher: paginationStatePublisher) // Make sure the existing items are built so that we have content in the timeline before // determining whether or not the timeline should paginate to load more items. await provider.waitForInitialItems() - innerTimelineProvider = provider + innerTimelineItemProvider = provider Task { await timeline.fetchMembers() @@ -76,7 +76,7 @@ final class TimelineProxy: TimelineProxyProtocol { } func messageEventContent(for timelineItemID: TimelineItemIdentifier) async -> RoomMessageEventContentWithoutRelation? { - guard let content = await timelineProvider.itemProxies.firstEventTimelineItemUsingStableID(timelineItemID)?.content, + guard let content = await timelineItemProvider.itemProxies.firstEventTimelineItemUsingStableID(timelineItemID)?.content, case let .msgLike(messageLikeContent) = content, case let .message(messageContent) = messageLikeContent.kind else { return nil diff --git a/ElementX/Sources/Services/Timeline/TimelineProxyProtocol.swift b/ElementX/Sources/Services/Timeline/TimelineProxyProtocol.swift index 55b28377c..97e76e8ac 100644 --- a/ElementX/Sources/Services/Timeline/TimelineProxyProtocol.swift +++ b/ElementX/Sources/Services/Timeline/TimelineProxyProtocol.swift @@ -39,7 +39,7 @@ enum TimelineProxyError: Error { // sourcery: AutoMockable protocol TimelineProxyProtocol { - var timelineProvider: TimelineProviderProtocol { get } + var timelineItemProvider: TimelineItemProviderProtocol { get } func subscribeForUpdates() async diff --git a/UnitTests/Sources/RoomScreenViewModelTests.swift b/UnitTests/Sources/RoomScreenViewModelTests.swift index 0b68be1ff..b97ecc9dd 100644 --- a/UnitTests/Sources/RoomScreenViewModelTests.swift +++ b/UnitTests/Sources/RoomScreenViewModelTests.swift @@ -70,12 +70,12 @@ class RoomScreenViewModelTests: XCTestCase { // setup the loaded pinned events injection in the timeline let pinnedTimelineMock = TimelineProxyMock() - let pinnedTimelineProviderMock = TimelineProviderMock() + let pinnedTimelineItemProviderMock = TimelineItemProviderMock() let providerUpdateSubject = PassthroughSubject<([TimelineItemProxy], PaginationState), Never>() - pinnedTimelineProviderMock.underlyingUpdatePublisher = providerUpdateSubject.eraseToAnyPublisher() - pinnedTimelineMock.timelineProvider = pinnedTimelineProviderMock - pinnedTimelineProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: .init("1"))), - .event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: .init("2")))] + pinnedTimelineItemProviderMock.underlyingUpdatePublisher = providerUpdateSubject.eraseToAnyPublisher() + pinnedTimelineMock.timelineItemProvider = pinnedTimelineItemProviderMock + pinnedTimelineItemProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: .init("1"))), + .event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: .init("2")))] // check if the banner is now in a loaded state and is showing the counter deferred = deferFulfillment(viewModel.context.$viewState) { viewState in @@ -111,12 +111,12 @@ class RoomScreenViewModelTests: XCTestCase { let roomProxyMock = JoinedRoomProxyMock(.init()) // setup a way to inject the mock of the pinned events timeline let pinnedTimelineMock = TimelineProxyMock() - let pinnedTimelineProviderMock = TimelineProviderMock() - pinnedTimelineMock.timelineProvider = pinnedTimelineProviderMock - pinnedTimelineProviderMock.underlyingUpdatePublisher = Empty<([TimelineItemProxy], PaginationState), Never>().eraseToAnyPublisher() - pinnedTimelineProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: .init("1"))), - .event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: .init("2"))), - .event(.init(item: EventTimelineItem(configuration: .init(eventID: "test3")), uniqueID: .init("3")))] + let pinnedTimelineItemProviderMock = TimelineItemProviderMock() + pinnedTimelineMock.timelineItemProvider = pinnedTimelineItemProviderMock + pinnedTimelineItemProviderMock.underlyingUpdatePublisher = Empty<([TimelineItemProxy], PaginationState), Never>().eraseToAnyPublisher() + pinnedTimelineItemProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: .init("1"))), + .event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: .init("2"))), + .event(.init(item: EventTimelineItem(configuration: .init(eventID: "test3")), uniqueID: .init("3")))] roomProxyMock.pinnedEventsTimelineReturnValue = .success(pinnedTimelineMock) let viewModel = RoomScreenViewModel(clientProxy: ClientProxyMock(), roomProxy: roomProxyMock,