mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Add room's update publisher (#952)
* Add room update publisher * Cleanup * Update room’s title * Add refresh logic in RoomDetailsScreenViewModel * Fix UTs * Add UT * Update timeline listener in RoomProxy * Fix caching in LoadableAvatarImage * Cleanup * Update RoomProxy api * Inject room proxy in RoomScreenViewModel * Cleanup * Fix UTs
This commit is contained in:
parent
c59921103d
commit
bf2102e5d1
@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 54;
|
||||
objectVersion = 51;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
@ -100,6 +100,7 @@
|
||||
281BED345D59A9A6A99E9D98 /* UNNotificationContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE148A4FFEE853C5A281500C /* UNNotificationContent.swift */; };
|
||||
282A5F3375DDC774AE09B0C3 /* TracingConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1734A445A58ED855B977A0A8 /* TracingConfigurationTests.swift */; };
|
||||
2835FD52F3F618D07F799B3D /* Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7310D8DFE01AF45F0689C3AA /* Publisher.swift */; };
|
||||
28A94A7DF684F2A29C4ADFE9 /* TimelineReceiptView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A5457B0320D028A676C248F /* TimelineReceiptView.swift */; };
|
||||
290FDB0FFDC2F1DDF660343E /* TestMeasurementParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C4048041C1A6B20CB97FD18 /* TestMeasurementParser.swift */; };
|
||||
292827744227DF61C930BDDB /* CreateRoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB0D6CB491777E7FC6B5BA12 /* CreateRoomScreen.swift */; };
|
||||
2955F4C160CFD7794D819C64 /* EffectsScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 024F7398C5FC12586FB10E9D /* EffectsScene.swift */; };
|
||||
@ -138,6 +139,7 @@
|
||||
39929D29B265C3F6606047DE /* AlignedScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8872E9C5E91E9F2BFC4EBCCA /* AlignedScrollView.swift */; };
|
||||
3A08584ECDD4A4541DBF21F8 /* EmojiLoaderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 201305507D7DFD16E544563A /* EmojiLoaderProtocol.swift */; };
|
||||
3A64A93A651A3CB8774ADE8E /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = BA93CD75CCE486660C9040BD /* Collections */; };
|
||||
3A7DD0D13B0FB8876D69D829 /* TextBasedRoomTimelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB2C848BB9A7A9B618B7B89 /* TextBasedRoomTimelineTests.swift */; };
|
||||
3B0F9B57D25B07E66F15762A /* MediaUploadPreviewScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2E7C987AE5DC9087BB19F7D /* MediaUploadPreviewScreenModels.swift */; };
|
||||
3B28408450BCAED911283AA2 /* UserPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35FA991289149D31F4286747 /* UserPreference.swift */; };
|
||||
3C549A0BF39F8A854D45D9FD /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 020597E28A4BC8E1BE8EDF6E /* KeychainAccess */; };
|
||||
@ -302,6 +304,7 @@
|
||||
8285FF4B2C2331758C437FF7 /* ReportContentScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 713B48DBF65DE4B0DD445D66 /* ReportContentScreenViewModelProtocol.swift */; };
|
||||
828EA5009557C2B9DCD4CA0F /* UserDiscoverySection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D071F86CD47582B9196C9D16 /* UserDiscoverySection.swift */; };
|
||||
829062DD3C3F7016FE1A6476 /* RoomDetailsScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BFDAF6918BB096C44788FC9 /* RoomDetailsScreenUITests.swift */; };
|
||||
8317E1314C00DCCC99D30DA8 /* TextBasedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9227F7495DA43324050A863 /* TextBasedRoomTimelineItem.swift */; };
|
||||
83E05DB56BBD6C151602881E /* SettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E0ADE4FAA5A4DB91CB07737 /* SettingsScreen.swift */; };
|
||||
84226AD2E1F1FBC965F3B09E /* UnitTestsAppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A8E19C4645D3F5F9FB02355 /* UnitTestsAppCoordinator.swift */; };
|
||||
84C0CF78BCE085C08CB94D86 /* TimelineEventProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B62EE933FC3D5651AF4607 /* TimelineEventProxy.swift */; };
|
||||
@ -333,6 +336,7 @@
|
||||
8BC8EF6705A78946C1F22891 /* SoftLogoutScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71A7D4DDEEE5D2CA0C8D63CD /* SoftLogoutScreen.swift */; };
|
||||
8C454500B8073E1201F801A9 /* MXLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = A34A814CBD56230BC74FFCF4 /* MXLogger.swift */; };
|
||||
8CC12086CBF91A7E10CDC205 /* HomeScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D653265D006E708E4E51AD64 /* HomeScreenCoordinator.swift */; };
|
||||
8D0C5BC670D514760CC84E2A /* TextBasedRoomTimelineViewMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A542BC40D6EC2E66BC5659B /* TextBasedRoomTimelineViewMock.swift */; };
|
||||
8D3E1FADD78E72504DE0E402 /* UserAgentBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB3B237387B8288A5A938F1B /* UserAgentBuilderTests.swift */; };
|
||||
8D605456793F243649EC96AA /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = CD6B0C4639E066915B5E6463 /* target.yml */; };
|
||||
8D71E5E53F372202379BECCE /* BugReportScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 303FCADE77DF1F3670C086ED /* BugReportScreenViewModel.swift */; };
|
||||
@ -394,6 +398,7 @@
|
||||
A216C83ADCF32BA5EF8A6FBC /* InviteUsersViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845DDBDE5A0887E73D38B826 /* InviteUsersViewModelTests.swift */; };
|
||||
A23B8B27A1436A1049EEF68E /* InfoPlistReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A580295A56B55A856CC4084 /* InfoPlistReader.swift */; };
|
||||
A2434D4DFB49A68E5CD0F53C /* MediaLoaderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A02406480C351B8C6E0682C /* MediaLoaderProtocol.swift */; };
|
||||
A2A5AB2E8B3F5CA769E531FA /* TextBasedRoomTimelineViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E47F18A9A077E351CEA10D4 /* TextBasedRoomTimelineViewProtocol.swift */; };
|
||||
A33784831AD880A670CAA9F9 /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */; };
|
||||
A371629728E597C5FCA3C2B2 /* Analytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73FC861755C6388F62B9280A /* Analytics.swift */; };
|
||||
A37EED79941AD3B7140B3822 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287FC98AF2664EAD79C0D902 /* UIDevice.swift */; };
|
||||
@ -408,11 +413,6 @@
|
||||
A5D551E5691749066E0E0C44 /* RoomDetailsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 837B440C4705E4B899BCB899 /* RoomDetailsScreenViewModel.swift */; };
|
||||
A6DEC1ADEC8FEEC206A0FA37 /* AttributedStringBuilderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72F37B5DA798C9AE436F2C2C /* AttributedStringBuilderProtocol.swift */; };
|
||||
A6F713461DB62AC06293E7B7 /* FilePreviewScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 820637A0F9C2F562FF40CBC8 /* FilePreviewScreenModels.swift */; };
|
||||
A733C86A2A1D17590055ECD6 /* TimelineReceiptView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A733C8692A1D17590055ECD6 /* TimelineReceiptView.swift */; };
|
||||
A733C86C2A1E149E0055ECD6 /* TextBasedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A733C86B2A1E149E0055ECD6 /* TextBasedRoomTimelineItem.swift */; };
|
||||
A733C86E2A1E1C190055ECD6 /* TextBasedRoomTimelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A733C86D2A1E1C190055ECD6 /* TextBasedRoomTimelineTests.swift */; };
|
||||
A7C152962A1F4E4C0089FF9D /* TextBasedRoomTimelineViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7C152952A1F4E4C0089FF9D /* TextBasedRoomTimelineViewProtocol.swift */; };
|
||||
A7C152982A1F4E710089FF9D /* TextBasedRoomTimelineViewMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7C152972A1F4E710089FF9D /* TextBasedRoomTimelineViewMock.swift */; };
|
||||
A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; };
|
||||
A7FD7B992E6EE6E5A8429197 /* RoomSummaryDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142808B69851451AC32A2CEA /* RoomSummaryDetails.swift */; };
|
||||
A816F7087C495D85048AC50E /* RoomMemberDetailsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */; };
|
||||
@ -726,7 +726,7 @@
|
||||
1222DB76B917EB8A55365BA5 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
||||
127A57D053CE8C87B5EFB089 /* Consumable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Consumable.swift; sourceTree = "<group>"; };
|
||||
127C8472672A5BA09EF1ACF8 /* CurrentValuePublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentValuePublisher.swift; sourceTree = "<group>"; };
|
||||
1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = IntegrationTests.xctestplan; sourceTree = "<group>"; };
|
||||
1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; path = IntegrationTests.xctestplan; sourceTree = "<group>"; };
|
||||
130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNTextInputNotificationResponse+Creator.swift"; sourceTree = "<group>"; };
|
||||
13673F95EBA78D40C09CCE35 /* MockUserIndicatorController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUserIndicatorController.swift; sourceTree = "<group>"; };
|
||||
13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||
@ -774,6 +774,7 @@
|
||||
28D116D4633E177BE1AC0E71 /* AnalyticsSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
2A5C6FBF97B6EED3D4FA5EFF /* AttributedStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringBuilder.swift; sourceTree = "<group>"; };
|
||||
2A96A67AD0E32C48941EFBB3 /* SessionVerificationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
2AB2C848BB9A7A9B618B7B89 /* TextBasedRoomTimelineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineTests.swift; sourceTree = "<group>"; };
|
||||
2AFEF3AC64B1358083F76B8B /* List.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = List.swift; sourceTree = "<group>"; };
|
||||
2BB385E148DE55C85C0A02D6 /* SoftLogoutScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftLogoutScreenModels.swift; sourceTree = "<group>"; };
|
||||
2C0197EAE9D45A662B8847B6 /* RoomTimelineControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineControllerProtocol.swift; sourceTree = "<group>"; };
|
||||
@ -806,6 +807,7 @@
|
||||
3948D16F021DFDB2CD26EAA8 /* MockBackgroundTaskService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBackgroundTaskService.swift; sourceTree = "<group>"; };
|
||||
398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadableFrameModifier.swift; sourceTree = "<group>"; };
|
||||
39B6C8690AEA1E49FF1BAF95 /* MediaUploadPreviewScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenUITests.swift; sourceTree = "<group>"; };
|
||||
3A5457B0320D028A676C248F /* TimelineReceiptView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReceiptView.swift; sourceTree = "<group>"; };
|
||||
3B5E97E9615A158C76B2AB77 /* DateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTests.swift; sourceTree = "<group>"; };
|
||||
3BFDAF6918BB096C44788FC9 /* RoomDetailsScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenUITests.swift; sourceTree = "<group>"; };
|
||||
3C1A3D524D63815B28FA4D62 /* EmojiCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiCategory.swift; sourceTree = "<group>"; };
|
||||
@ -837,7 +839,7 @@
|
||||
46C208DA43CE25D13E670F40 /* UITestsAppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsAppCoordinator.swift; sourceTree = "<group>"; };
|
||||
47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = "<group>"; };
|
||||
471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
478BE8591BD13E908EF70C0C /* DesignKit */ = {isa = PBXFileReference; lastKnownFileType = folder; path = DesignKit; sourceTree = SOURCE_ROOT; };
|
||||
478BE8591BD13E908EF70C0C /* DesignKit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = DesignKit; path = DesignKit; sourceTree = SOURCE_ROOT; };
|
||||
4798B3B7A1E8AE3901CEE8C6 /* FramePreferenceKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FramePreferenceKey.swift; sourceTree = "<group>"; };
|
||||
47E6DD75A81D07CD91997D8C /* SettingsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
47EBB5D698CE9A25BB553A2D /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; };
|
||||
@ -845,6 +847,7 @@
|
||||
4959CECEC984B3995616F427 /* DataProtectionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataProtectionManager.swift; sourceTree = "<group>"; };
|
||||
49D2C8E66E83EA578A7F318A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||
49E751D7EDB6043238111D90 /* UNNotificationRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNNotificationRequest.swift; sourceTree = "<group>"; };
|
||||
4A542BC40D6EC2E66BC5659B /* TextBasedRoomTimelineViewMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineViewMock.swift; sourceTree = "<group>"; };
|
||||
4AB7D7DAAAF662DED9D02379 /* MockMediaLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaLoader.swift; sourceTree = "<group>"; };
|
||||
4B41FABA2B0AEF4389986495 /* LoginMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginMode.swift; sourceTree = "<group>"; };
|
||||
4B5046BB295AEAFA6FB81655 /* SessionVerificationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenModels.swift; sourceTree = "<group>"; };
|
||||
@ -852,6 +855,7 @@
|
||||
4CDDDDD9FE1A699D23A5E096 /* LoginScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreen.swift; sourceTree = "<group>"; };
|
||||
4D6E4C37E9F0E53D3DF951AC /* HomeScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenUITests.swift; sourceTree = "<group>"; };
|
||||
4E2245243369B99216C7D84E /* ImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCache.swift; sourceTree = "<group>"; };
|
||||
4E47F18A9A077E351CEA10D4 /* TextBasedRoomTimelineViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineViewProtocol.swift; sourceTree = "<group>"; };
|
||||
4F0CB536D1C3CC15AA740CC6 /* AuthenticationServiceProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationServiceProxyProtocol.swift; sourceTree = "<group>"; };
|
||||
4F1DFE6E746539F33042D3A9 /* FormSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormSection.swift; sourceTree = "<group>"; };
|
||||
4FD6E621CC5E6D4830D96D2D /* MockMediaProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaProvider.swift; sourceTree = "<group>"; };
|
||||
@ -978,7 +982,7 @@
|
||||
8D55702474F279D910D2D162 /* RoomStateEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomStateEventStringBuilder.swift; sourceTree = "<group>"; };
|
||||
8D6094DEAAEB388E1AE118C6 /* MockRoomTimelineProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomTimelineProvider.swift; sourceTree = "<group>"; };
|
||||
8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyle.swift; sourceTree = "<group>"; };
|
||||
8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UITests.xctestplan; sourceTree = "<group>"; };
|
||||
8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; path = UITests.xctestplan; sourceTree = "<group>"; };
|
||||
8E1BBA73B611EDEEA6E20E05 /* InvitesScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreenModels.swift; sourceTree = "<group>"; };
|
||||
8EC57A32ABC80D774CC663DB /* SettingsScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenUITests.swift; sourceTree = "<group>"; };
|
||||
8F61A0DD8243B395499C99A2 /* InvitesScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreenUITests.swift; sourceTree = "<group>"; };
|
||||
@ -1036,12 +1040,7 @@
|
||||
A65F140F9FE5E8D4DAEFF354 /* RoomProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxy.swift; sourceTree = "<group>"; };
|
||||
A6B891A6DA826E2461DBB40F /* PHGPostHogConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PHGPostHogConfiguration.swift; sourceTree = "<group>"; };
|
||||
A6F5CDE754D53A9A403EDBA9 /* DeveloperOptionsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
A733C8692A1D17590055ECD6 /* TimelineReceiptView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReceiptView.swift; sourceTree = "<group>"; };
|
||||
A733C86B2A1E149E0055ECD6 /* TextBasedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
A733C86D2A1E1C190055ECD6 /* TextBasedRoomTimelineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineTests.swift; sourceTree = "<group>"; };
|
||||
A73A07BAEDD74C48795A996A /* AsyncSequence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncSequence.swift; sourceTree = "<group>"; };
|
||||
A7C152952A1F4E4C0089FF9D /* TextBasedRoomTimelineViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineViewProtocol.swift; sourceTree = "<group>"; };
|
||||
A7C152972A1F4E710089FF9D /* TextBasedRoomTimelineViewMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineViewMock.swift; sourceTree = "<group>"; };
|
||||
A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleTimelineItem.swift; sourceTree = "<group>"; };
|
||||
A861DA5932B128FE1DCB5CE2 /* InviteUsersScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
A8903A9F615BBD0E6D7CD133 /* ApplicationProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationProtocol.swift; sourceTree = "<group>"; };
|
||||
@ -1077,7 +1076,7 @@
|
||||
B43AF03660F5FD4FFFA7F1CE /* TimelineItemContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemContextMenu.swift; sourceTree = "<group>"; };
|
||||
B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableAvatarImage.swift; sourceTree = "<group>"; };
|
||||
B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = ConfettiScene.scn; sourceTree = "<group>"; };
|
||||
B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; path = ConfettiScene.scn; sourceTree = "<group>"; };
|
||||
B6311F21F911E23BE4DF51B4 /* ReadMarkerRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadMarkerRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
B6E89E530A8E92EC44301CA1 /* Bundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = "<group>"; };
|
||||
B7DBA101D643B31E813F3AC1 /* AnalyticsSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreen.swift; sourceTree = "<group>"; };
|
||||
@ -1087,6 +1086,7 @@
|
||||
B8A3B7637DDBD6AA97AC2545 /* CameraPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraPicker.swift; sourceTree = "<group>"; };
|
||||
B8F28602AC7AC881AED37EBA /* NavigationCoordinators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationCoordinators.swift; sourceTree = "<group>"; };
|
||||
B902EA6CD3296B0E10EE432B /* HomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = "<group>"; };
|
||||
B9227F7495DA43324050A863 /* TextBasedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
B99E13633862847D8B7E2815 /* StartChatScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartChatScreenModels.swift; sourceTree = "<group>"; };
|
||||
BA241DEEF7C8A7181C0AEDC9 /* UserPreferenceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferenceTests.swift; sourceTree = "<group>"; };
|
||||
BA40B98B098B6F0371B750B3 /* TemplateScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenModels.swift; sourceTree = "<group>"; };
|
||||
@ -1141,7 +1141,7 @@
|
||||
CDB3227C7A74B734924942E9 /* RoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProvider.swift; sourceTree = "<group>"; };
|
||||
CECF45B5E8E795666B8C5013 /* SettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenModels.swift; sourceTree = "<group>"; };
|
||||
CEE0E6043EFCF6FD2A341861 /* TimelineReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReplyView.swift; sourceTree = "<group>"; };
|
||||
CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UnitTests.xctestplan; sourceTree = "<group>"; };
|
||||
CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; path = UnitTests.xctestplan; sourceTree = "<group>"; };
|
||||
CF48AF076424DBC1615C74AD /* AuthenticationServiceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationServiceProxy.swift; sourceTree = "<group>"; };
|
||||
D06A27D9C70E0DCC1E199163 /* OnboardingBackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingBackgroundView.swift; sourceTree = "<group>"; };
|
||||
D071F86CD47582B9196C9D16 /* UserDiscoverySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoverySection.swift; sourceTree = "<group>"; };
|
||||
@ -1203,7 +1203,7 @@
|
||||
ECF79FB25E2D4BD6F50CE7C9 /* RoomMembersListScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenRoomCell.swift; sourceTree = "<group>"; };
|
||||
ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = "<group>"; };
|
||||
ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = message.caf; sourceTree = "<group>"; };
|
||||
ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; path = message.caf; sourceTree = "<group>"; };
|
||||
ED983D4DCA5AFA6E1ED96099 /* StateRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionViewModelTests.swift; sourceTree = "<group>"; };
|
||||
EE378083653EF0C9B5E9D580 /* EmoteRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItemContent.swift; sourceTree = "<group>"; };
|
||||
@ -2188,6 +2188,7 @@
|
||||
32C5DAA1773F57653BF1C4F9 /* SoftLogoutViewModelTests.swift */,
|
||||
6DF438EAFC732D2D95D34BF6 /* StartChatViewModelTests.swift */,
|
||||
2CEBCB9676FCD1D0F13188DD /* StringTests.swift */,
|
||||
2AB2C848BB9A7A9B618B7B89 /* TextBasedRoomTimelineTests.swift */,
|
||||
1734A445A58ED855B977A0A8 /* TracingConfigurationTests.swift */,
|
||||
EB3B237387B8288A5A938F1B /* UserAgentBuilderTests.swift */,
|
||||
0DE6C5C756E1393202BA95CD /* UserNotificationControllerTests.swift */,
|
||||
@ -2197,7 +2198,6 @@
|
||||
7583EAC171059A86B767209F /* MediaProvider */,
|
||||
7DBC911559934065993A5FF4 /* NotificationManager */,
|
||||
1C62F5382CC9D9F7DCEC344A /* UserDiscoveryService */,
|
||||
A733C86D2A1E1C190055ECD6 /* TextBasedRoomTimelineTests.swift */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
@ -2717,13 +2717,13 @@
|
||||
6390A6DC140CA3D6865A66FF /* SeparatorRoomTimelineView.swift */,
|
||||
ED983D4DCA5AFA6E1ED96099 /* StateRoomTimelineView.swift */,
|
||||
612EF972F2A1800682D32C5E /* StickerRoomTimelineView.swift */,
|
||||
B9227F7495DA43324050A863 /* TextBasedRoomTimelineItem.swift */,
|
||||
4A542BC40D6EC2E66BC5659B /* TextBasedRoomTimelineViewMock.swift */,
|
||||
4E47F18A9A077E351CEA10D4 /* TextBasedRoomTimelineViewProtocol.swift */,
|
||||
F9E785D5137510481733A3E8 /* TextRoomTimelineView.swift */,
|
||||
F9ED8E731E21055F728E5FED /* TimelineStartRoomTimelineView.swift */,
|
||||
A2AC3C656E960E15B5905E05 /* UnsupportedRoomTimelineView.swift */,
|
||||
1941C8817E6B6971BA4415F5 /* VideoRoomTimelineView.swift */,
|
||||
A733C86B2A1E149E0055ECD6 /* TextBasedRoomTimelineItem.swift */,
|
||||
A7C152952A1F4E4C0089FF9D /* TextBasedRoomTimelineViewProtocol.swift */,
|
||||
A7C152972A1F4E710089FF9D /* TextBasedRoomTimelineViewMock.swift */,
|
||||
);
|
||||
path = Timeline;
|
||||
sourceTree = "<group>";
|
||||
@ -2834,7 +2834,7 @@
|
||||
children = (
|
||||
D5AC06FC11B6638F7BF1670E /* TimelineDeliveryStatusView.swift */,
|
||||
351E89CE2ED9B73C5CC47955 /* TimelineReactionsView.swift */,
|
||||
A733C8692A1D17590055ECD6 /* TimelineReceiptView.swift */,
|
||||
3A5457B0320D028A676C248F /* TimelineReceiptView.swift */,
|
||||
);
|
||||
path = Supplementary;
|
||||
sourceTree = "<group>";
|
||||
@ -3531,7 +3531,6 @@
|
||||
864C69CF951BF36D25BE0C03 /* DeveloperOptionsScreenViewModelTests.swift in Sources */,
|
||||
9C45CE85325CD591DADBC4CA /* ElementXTests.swift in Sources */,
|
||||
501304F26B52DF7024011B6C /* EmojiMartJSONLoaderTests.swift in Sources */,
|
||||
A733C86E2A1E1C190055ECD6 /* TextBasedRoomTimelineTests.swift in Sources */,
|
||||
25618589E0DE0F1E95FC7B5C /* EmojiProviderTests.swift in Sources */,
|
||||
71B62C48B8079D49F3FBC845 /* ExpiringTaskRunnerTests.swift in Sources */,
|
||||
CA45758F08DF42D41D8A4B29 /* FilePreviewViewModelTests.swift in Sources */,
|
||||
@ -3573,6 +3572,7 @@
|
||||
6189B4ABD535CE526FA1107B /* StartChatViewModelTests.swift in Sources */,
|
||||
1FEC0A4EC6E6DF693C16B32A /* StringTests.swift in Sources */,
|
||||
E75CE800B3E64D0F7F8E228D /* TemplateScreenViewModelTests.swift in Sources */,
|
||||
3A7DD0D13B0FB8876D69D829 /* TextBasedRoomTimelineTests.swift in Sources */,
|
||||
282A5F3375DDC774AE09B0C3 /* TracingConfigurationTests.swift in Sources */,
|
||||
8E650379587C31D7912ED67B /* UNNotification+Creator.swift in Sources */,
|
||||
AF33B9044498211C3D82F1E1 /* UNTextInputNotificationResponse+Creator.swift in Sources */,
|
||||
@ -3652,7 +3652,6 @@
|
||||
B98A20A093A4FB785BFCCA53 /* BugReportScreenCoordinator.swift in Sources */,
|
||||
4FFDC274824F7CC0BBDF581E /* BugReportScreenModels.swift in Sources */,
|
||||
8D71E5E53F372202379BECCE /* BugReportScreenViewModel.swift in Sources */,
|
||||
A733C86C2A1E149E0055ECD6 /* TextBasedRoomTimelineItem.swift in Sources */,
|
||||
B4A0C69370E6008A971463E7 /* BugReportScreenViewModelProtocol.swift in Sources */,
|
||||
3DA57CA0D609A6B37CA1DC2F /* BugReportService.swift in Sources */,
|
||||
172E6E9A612ADCF10A62CF13 /* BugReportServiceProtocol.swift in Sources */,
|
||||
@ -3889,7 +3888,6 @@
|
||||
77D7DAA41AAB36800C1F2E2D /* RoomTimelineProviderProtocol.swift in Sources */,
|
||||
CF82143AA4A4F7BD11D22946 /* RoomTimelineViewProvider.swift in Sources */,
|
||||
B2F8E01ABA1BA30265B4ECBE /* RoundedCornerShape.swift in Sources */,
|
||||
A7C152962A1F4E4C0089FF9D /* TextBasedRoomTimelineViewProtocol.swift in Sources */,
|
||||
50C90117FE25390BFBD40173 /* RustTracing.swift in Sources */,
|
||||
0437765FF480249486893CC7 /* ScreenTrackerViewModifier.swift in Sources */,
|
||||
0BFA67AFD757EE2BA569836A /* ScrollViewAdapter.swift in Sources */,
|
||||
@ -3945,6 +3943,9 @@
|
||||
275EDE8849A2AC1D9309ED7C /* TemplateScreenViewModel.swift in Sources */,
|
||||
2C4C750D0039AFABDF24236C /* TemplateScreenViewModelProtocol.swift in Sources */,
|
||||
D85D4FA590305180B4A41795 /* Tests.swift in Sources */,
|
||||
8317E1314C00DCCC99D30DA8 /* TextBasedRoomTimelineItem.swift in Sources */,
|
||||
8D0C5BC670D514760CC84E2A /* TextBasedRoomTimelineViewMock.swift in Sources */,
|
||||
A2A5AB2E8B3F5CA769E531FA /* TextBasedRoomTimelineViewProtocol.swift in Sources */,
|
||||
BB784A02BADB03C820617A46 /* TextRoomTimelineItem.swift in Sources */,
|
||||
53F1196F9C69512306A2693F /* TextRoomTimelineItemContent.swift in Sources */,
|
||||
5E0F2E612718BB4397A6D40A /* TextRoomTimelineView.swift in Sources */,
|
||||
@ -3954,13 +3955,12 @@
|
||||
157E5FDDF419C0B2CA7E2C28 /* TimelineItemBubbledStylerView.swift in Sources */,
|
||||
01CB8ACFA5E143E89C168CA8 /* TimelineItemContextMenu.swift in Sources */,
|
||||
FBCCF1EA25A071324FCD8544 /* TimelineItemDebugView.swift in Sources */,
|
||||
A733C86A2A1D17590055ECD6 /* TimelineReceiptView.swift in Sources */,
|
||||
A7C152982A1F4E710089FF9D /* TextBasedRoomTimelineViewMock.swift in Sources */,
|
||||
F508683B76EF7B23BB2CBD6D /* TimelineItemPlainStylerView.swift in Sources */,
|
||||
440123E29E2F9B001A775BBE /* TimelineItemProxy.swift in Sources */,
|
||||
9586E90A447C4896C0CA3A8E /* TimelineItemReplyDetails.swift in Sources */,
|
||||
1B88BB631F7FC45A213BB554 /* TimelineItemSender.swift in Sources */,
|
||||
9B582B3EEFEA615D4A6FBF1A /* TimelineReactionsView.swift in Sources */,
|
||||
28A94A7DF684F2A29C4ADFE9 /* TimelineReceiptView.swift in Sources */,
|
||||
2A90DD14DE5C891BFA433950 /* TimelineReplyView.swift in Sources */,
|
||||
ABF3FAB234AD3565B214309B /* TimelineSenderAvatarView.swift in Sources */,
|
||||
C4FE0E11A907C8999F92D5A8 /* TimelineStartRoomTimelineItem.swift in Sources */,
|
||||
|
@ -419,6 +419,11 @@ class RoomProxyMock: RoomProxyProtocol {
|
||||
set(value) { underlyingMembersPublisher = value }
|
||||
}
|
||||
var underlyingMembersPublisher: AnyPublisher<[RoomMemberProxyProtocol], Never>!
|
||||
var updatesPublisher: AnyPublisher<TimelineDiff, Never> {
|
||||
get { return underlyingUpdatesPublisher }
|
||||
set(value) { underlyingUpdatesPublisher = value }
|
||||
}
|
||||
var underlyingUpdatesPublisher: AnyPublisher<TimelineDiff, Never>!
|
||||
var invitedMembersCount: UInt {
|
||||
get { return underlyingInvitedMembersCount }
|
||||
set(value) { underlyingInvitedMembersCount = value }
|
||||
@ -477,39 +482,23 @@ class RoomProxyMock: RoomProxyProtocol {
|
||||
return loadDisplayNameForUserIdReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - addTimelineListener
|
||||
//MARK: - registerTimelineListenerIfNeeded
|
||||
|
||||
var addTimelineListenerListenerCallsCount = 0
|
||||
var addTimelineListenerListenerCalled: Bool {
|
||||
return addTimelineListenerListenerCallsCount > 0
|
||||
var registerTimelineListenerIfNeededCallsCount = 0
|
||||
var registerTimelineListenerIfNeededCalled: Bool {
|
||||
return registerTimelineListenerIfNeededCallsCount > 0
|
||||
}
|
||||
var addTimelineListenerListenerReceivedListener: TimelineListener?
|
||||
var addTimelineListenerListenerReceivedInvocations: [TimelineListener] = []
|
||||
var addTimelineListenerListenerReturnValue: Result<[TimelineItem], RoomProxyError>!
|
||||
var addTimelineListenerListenerClosure: ((TimelineListener) -> Result<[TimelineItem], RoomProxyError>)?
|
||||
var registerTimelineListenerIfNeededReturnValue: Result<[TimelineItem], RoomProxyError>!
|
||||
var registerTimelineListenerIfNeededClosure: (() -> Result<[TimelineItem], RoomProxyError>)?
|
||||
|
||||
func addTimelineListener(listener: TimelineListener) -> Result<[TimelineItem], RoomProxyError> {
|
||||
addTimelineListenerListenerCallsCount += 1
|
||||
addTimelineListenerListenerReceivedListener = listener
|
||||
addTimelineListenerListenerReceivedInvocations.append(listener)
|
||||
if let addTimelineListenerListenerClosure = addTimelineListenerListenerClosure {
|
||||
return addTimelineListenerListenerClosure(listener)
|
||||
func registerTimelineListenerIfNeeded() -> Result<[TimelineItem], RoomProxyError> {
|
||||
registerTimelineListenerIfNeededCallsCount += 1
|
||||
if let registerTimelineListenerIfNeededClosure = registerTimelineListenerIfNeededClosure {
|
||||
return registerTimelineListenerIfNeededClosure()
|
||||
} else {
|
||||
return addTimelineListenerListenerReturnValue
|
||||
return registerTimelineListenerIfNeededReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - removeTimelineListener
|
||||
|
||||
var removeTimelineListenerCallsCount = 0
|
||||
var removeTimelineListenerCalled: Bool {
|
||||
return removeTimelineListenerCallsCount > 0
|
||||
}
|
||||
var removeTimelineListenerClosure: (() -> Void)?
|
||||
|
||||
func removeTimelineListener() {
|
||||
removeTimelineListenerCallsCount += 1
|
||||
removeTimelineListenerClosure?()
|
||||
}
|
||||
//MARK: - paginateBackwards
|
||||
|
||||
var paginateBackwardsRequestSizeUntilNumberOfItemsCallsCount = 0
|
||||
|
@ -73,5 +73,7 @@ extension RoomProxyMock {
|
||||
|
||||
updateMembersClosure = { }
|
||||
acceptInvitationClosure = { .success(()) }
|
||||
registerTimelineListenerIfNeededClosure = { .success([]) }
|
||||
underlyingUpdatesPublisher = Empty(completeImmediately: false).eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,9 @@ struct LoadableAvatarImage: View {
|
||||
} placeholder: {
|
||||
PlaceholderAvatarImage(name: name, contentID: contentID)
|
||||
}
|
||||
// Binds the lifecycle of the LoadableImage to the associated URL.
|
||||
// This fixes the problem of the cache returning old values after a change in the URL.
|
||||
.id(url)
|
||||
} else {
|
||||
PlaceholderAvatarImage(name: name, contentID: contentID)
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
||||
canonicalAlias: roomProxy.canonicalAlias,
|
||||
isEncrypted: roomProxy.isEncrypted,
|
||||
isDirect: roomProxy.isDirect,
|
||||
title: roomProxy.displayName ?? roomProxy.name ?? "Unknown Room",
|
||||
title: roomProxy.roomTitle,
|
||||
topic: roomProxy.topic,
|
||||
avatarURL: roomProxy.avatarURL,
|
||||
permalink: roomProxy.permalink,
|
||||
@ -81,6 +81,13 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
||||
// MARK: - Private
|
||||
|
||||
private func setupSubscriptions() {
|
||||
switch roomProxy.registerTimelineListenerIfNeeded() {
|
||||
case .success, .failure(.roomListenerAlreadyRegistered):
|
||||
break
|
||||
case .failure:
|
||||
MXLog.error("Failed to register a room listener in room's details for the room \(roomProxy.id)")
|
||||
}
|
||||
|
||||
roomProxy.membersPublisher
|
||||
.sink { [weak self] members in
|
||||
guard let self else { return }
|
||||
@ -102,6 +109,16 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
roomProxy.updatesPublisher
|
||||
.throttle(for: .seconds(1), scheduler: DispatchQueue.main, latest: true)
|
||||
.sink { [weak self] _ in
|
||||
guard let self else { return }
|
||||
self.state.title = self.roomProxy.roomTitle
|
||||
self.state.topic = self.roomProxy.topic
|
||||
self.state.avatarURL = self.roomProxy.avatarURL
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
private func buildMembersDetails(members: [RoomMemberProxyProtocol]) async -> RoomMembersDetails {
|
||||
|
@ -44,8 +44,7 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
viewModel = RoomScreenViewModel(timelineController: parameters.timelineController,
|
||||
mediaProvider: parameters.mediaProvider,
|
||||
roomName: parameters.roomProxy.displayName ?? parameters.roomProxy.name,
|
||||
roomAvatarUrl: parameters.roomProxy.avatarURL)
|
||||
roomProxy: parameters.roomProxy)
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
@ -76,7 +75,6 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
||||
}
|
||||
|
||||
func stop() {
|
||||
parameters.roomProxy.removeTimelineListener()
|
||||
viewModel.context.send(viewAction: .markRoomAsRead)
|
||||
}
|
||||
|
||||
|
@ -27,17 +27,18 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
static let toastErrorID = "RoomScreenToastError"
|
||||
}
|
||||
|
||||
private let roomProxy: RoomProxyProtocol
|
||||
private let timelineController: RoomTimelineControllerProtocol
|
||||
|
||||
init(timelineController: RoomTimelineControllerProtocol,
|
||||
mediaProvider: MediaProviderProtocol,
|
||||
roomName: String?,
|
||||
roomAvatarUrl: URL? = nil) {
|
||||
roomProxy: RoomProxyProtocol) {
|
||||
self.roomProxy = roomProxy
|
||||
self.timelineController = timelineController
|
||||
|
||||
super.init(initialViewState: RoomScreenViewState(roomId: timelineController.roomID,
|
||||
roomTitle: roomName ?? "Unknown room 💥",
|
||||
roomAvatarURL: roomAvatarUrl,
|
||||
roomTitle: roomProxy.roomTitle,
|
||||
roomAvatarURL: roomProxy.avatarURL,
|
||||
timelineStyle: ServiceLocator.shared.settings.timelineStyle,
|
||||
bindings: .init(composerText: "", composerFocused: false)),
|
||||
imageProvider: mediaProvider)
|
||||
@ -70,6 +71,16 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
return self.contextMenuActionsForItemId(itemId)
|
||||
}
|
||||
|
||||
roomProxy
|
||||
.updatesPublisher
|
||||
.throttle(for: .seconds(1), scheduler: DispatchQueue.main, latest: true)
|
||||
.sink { [weak self] _ in
|
||||
guard let self else { return }
|
||||
self.state.roomTitle = roomProxy.roomTitle
|
||||
self.state.roomAvatarURL = roomProxy.avatarURL
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
ServiceLocator.shared.settings.$timelineStyle
|
||||
.weakAssign(to: \.state.timelineStyle, on: self)
|
||||
.store(in: &cancellables)
|
||||
@ -406,5 +417,5 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
extension RoomScreenViewModel {
|
||||
static let mock = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: "Preview room")
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "Preview room")))
|
||||
}
|
||||
|
@ -59,8 +59,7 @@ struct RoomHeaderView_Previews: PreviewProvider {
|
||||
static var bodyPlain: some View {
|
||||
let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: "Some Room name",
|
||||
roomAvatarUrl: URL.picturesDirectory)
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "Some Room name", avatarURL: URL.picturesDirectory)))
|
||||
|
||||
RoomHeaderView(context: viewModel.context)
|
||||
.previewLayout(.sizeThatFits)
|
||||
@ -71,8 +70,7 @@ struct RoomHeaderView_Previews: PreviewProvider {
|
||||
static var bodyEncrypted: some View {
|
||||
let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: "Some Room name",
|
||||
roomAvatarUrl: nil)
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "Some Room name")))
|
||||
|
||||
RoomHeaderView(context: viewModel.context)
|
||||
.previewLayout(.sizeThatFits)
|
||||
|
@ -133,7 +133,7 @@ struct RoomScreen: View {
|
||||
struct RoomScreen_Previews: PreviewProvider {
|
||||
static let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: "Preview room")
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "Preview room")))
|
||||
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
|
@ -84,7 +84,7 @@ struct TimelineView: UIViewControllerRepresentable {
|
||||
struct TimelineTableView_Previews: PreviewProvider {
|
||||
static let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: "Preview room")
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "Preview room")))
|
||||
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
|
@ -41,7 +41,29 @@ class RoomProxy: RoomProxyProtocol {
|
||||
var membersPublisher: AnyPublisher<[RoomMemberProxyProtocol], Never> {
|
||||
membersSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
|
||||
private var timelineListener: RoomTimelineListener?
|
||||
private let updatesSubject = PassthroughSubject<TimelineDiff, Never>()
|
||||
var updatesPublisher: AnyPublisher<TimelineDiff, Never> {
|
||||
updatesSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
deinit {
|
||||
Task { @MainActor [roomTimelineObservationToken, slidingSyncRoom] in
|
||||
roomTimelineObservationToken?.cancel()
|
||||
|
||||
let task = ExpiringTaskRunner {
|
||||
let unsubscribeTask = slidingSyncRoom.unsubscribeFromRoom()
|
||||
|
||||
while !unsubscribeTask.isFinished() {
|
||||
try await Task.sleep(for: .seconds(2))
|
||||
}
|
||||
}
|
||||
|
||||
try? await task.run(timeout: .seconds(30))
|
||||
}
|
||||
}
|
||||
|
||||
init(slidingSyncRoom: SlidingSyncRoomProtocol,
|
||||
room: RoomProtocol,
|
||||
backgroundTaskService: BackgroundTaskServiceProtocol) {
|
||||
@ -139,15 +161,27 @@ class RoomProxy: RoomProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
func addTimelineListener(listener: TimelineListener) -> Result<[TimelineItem], RoomProxyError> {
|
||||
let settings = RoomSubscription(requiredState: [RequiredState(key: "m.room.topic", value: ""),
|
||||
func registerTimelineListenerIfNeeded() -> Result<[TimelineItem], RoomProxyError> {
|
||||
guard timelineListener == nil else {
|
||||
return .failure(.roomListenerAlreadyRegistered)
|
||||
}
|
||||
|
||||
let settings = RoomSubscription(requiredState: [RequiredState(key: "m.room.name", value: ""),
|
||||
RequiredState(key: "m.room.topic", value: ""),
|
||||
RequiredState(key: "m.room.avatar", value: ""),
|
||||
RequiredState(key: "m.room.canonical_alias", value: ""),
|
||||
RequiredState(key: "m.room.join_rules", value: "")],
|
||||
timelineLimit: UInt32(SlidingSyncConstants.timelinePrecachingTimelineLimit))
|
||||
roomSubscriptionObservationToken = slidingSyncRoom.subscribeToRoom(settings: settings)
|
||||
|
||||
let listener = RoomTimelineListener { [weak self] timelineDiff in
|
||||
self?.updatesSubject.send(timelineDiff)
|
||||
}
|
||||
|
||||
if let result = try? slidingSyncRoom.addTimelineListener(listener: listener) {
|
||||
roomTimelineObservationToken = result.taskHandle
|
||||
timelineListener = listener
|
||||
|
||||
Task {
|
||||
await fetchMembers()
|
||||
await updateMembers()
|
||||
@ -158,15 +192,6 @@ class RoomProxy: RoomProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
func removeTimelineListener() {
|
||||
roomTimelineObservationToken?.cancel()
|
||||
roomTimelineObservationToken = nil
|
||||
|
||||
roomSubscriptionObservationToken = nil
|
||||
|
||||
roomUnsubscriptionObservationToken = slidingSyncRoom.unsubscribeFromRoom()
|
||||
}
|
||||
|
||||
func paginateBackwards(requestSize: UInt, untilNumberOfItems: UInt) async -> Result<Void, RoomProxyError> {
|
||||
do {
|
||||
try await Task.dispatch(on: .global()) {
|
||||
@ -487,3 +512,15 @@ class RoomProxy: RoomProxyProtocol {
|
||||
self.displayName = displayName
|
||||
}
|
||||
}
|
||||
|
||||
private class RoomTimelineListener: TimelineListener {
|
||||
private let onUpdateClosure: (TimelineDiff) -> Void
|
||||
|
||||
init(_ onUpdateClosure: @escaping (TimelineDiff) -> Void) {
|
||||
self.onUpdateClosure = onUpdateClosure
|
||||
}
|
||||
|
||||
func onUpdate(update: TimelineDiff) {
|
||||
onUpdateClosure(update)
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import MatrixRustSDK
|
||||
|
||||
enum RoomProxyError: Error {
|
||||
case noMoreMessagesToBackPaginate
|
||||
case roomListenerAlreadyRegistered
|
||||
case failedPaginatingBackwards
|
||||
case failedRetrievingMemberAvatarURL
|
||||
case failedRetrievingMemberDisplayName
|
||||
@ -59,14 +60,19 @@ protocol RoomProxyProtocol {
|
||||
var avatarURL: URL? { get }
|
||||
|
||||
var membersPublisher: AnyPublisher<[RoomMemberProxyProtocol], Never> { get }
|
||||
|
||||
/// Publishes the room's updates.
|
||||
/// The publisher starts publishing after the first call to `registerTimelineListenerIfNeeded()`
|
||||
/// The thread on which this publisher sends the output isn't defined.
|
||||
var updatesPublisher: AnyPublisher<TimelineDiff, Never> { get }
|
||||
|
||||
func loadAvatarURLForUserId(_ userId: String) async -> Result<URL?, RoomProxyError>
|
||||
|
||||
func loadDisplayNameForUserId(_ userId: String) async -> Result<String?, RoomProxyError>
|
||||
|
||||
func addTimelineListener(listener: TimelineListener) -> Result<[TimelineItem], RoomProxyError>
|
||||
|
||||
func removeTimelineListener()
|
||||
/// Registers a timeline listener if not registered already.
|
||||
/// Updates for this object will be published on the `updatesPublisher` publisher.
|
||||
func registerTimelineListenerIfNeeded() -> Result<[TimelineItem], RoomProxyError>
|
||||
|
||||
func paginateBackwards(requestSize: UInt, untilNumberOfItems: UInt) async -> Result<Void, RoomProxyError>
|
||||
|
||||
@ -130,4 +136,10 @@ extension RoomProxyProtocol {
|
||||
func sendMessage(_ message: String) async -> Result<Void, RoomProxyError> {
|
||||
await sendMessage(message, inReplyTo: nil)
|
||||
}
|
||||
|
||||
// Avoids to duplicate the same logic around in the app
|
||||
// Probably this should be done in rust.
|
||||
var roomTitle: String {
|
||||
displayName ?? name ?? "Unknown room 💥"
|
||||
}
|
||||
}
|
||||
|
@ -18,14 +18,6 @@ import Combine
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
private class RoomTimelineListener: TimelineListener {
|
||||
let itemsUpdatePublisher = PassthroughSubject<TimelineDiff, Never>()
|
||||
|
||||
func onUpdate(update: TimelineDiff) {
|
||||
itemsUpdatePublisher.send(update)
|
||||
}
|
||||
}
|
||||
|
||||
class RoomTimelineProvider: RoomTimelineProviderProtocol {
|
||||
private let roomProxy: RoomProxyProtocol
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
@ -48,21 +40,21 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol {
|
||||
serialDispatchQueue = DispatchQueue(label: "io.element.elementx.roomtimelineprovider", qos: .utility)
|
||||
itemProxies = []
|
||||
|
||||
Task {
|
||||
let roomTimelineListener = RoomTimelineListener()
|
||||
|
||||
roomTimelineListener
|
||||
.itemsUpdatePublisher
|
||||
Task { @MainActor in
|
||||
roomProxy
|
||||
.updatesPublisher
|
||||
.collect(.byTime(serialDispatchQueue, 0.1))
|
||||
.sink { [weak self] in self?.updateItemsWithDiffs($0) }
|
||||
.store(in: &cancellables)
|
||||
|
||||
switch await roomProxy.addTimelineListener(listener: roomTimelineListener) {
|
||||
case .success(let items):
|
||||
switch roomProxy.registerTimelineListenerIfNeeded() {
|
||||
case let .success(items):
|
||||
itemProxies = items.map(TimelineItemProxy.init)
|
||||
MXLog.info("Added timeline listener, current items (\(items.count)) : \(items.map(\.debugIdentifier))")
|
||||
case .failure(.roomListenerAlreadyRegistered):
|
||||
MXLog.info("Listener already registered for the room: \(roomProxy.id)")
|
||||
case .failure:
|
||||
let roomID = await roomProxy.id
|
||||
let roomID = roomProxy.id
|
||||
MXLog.error("Failed adding timeline listener on room with identifier: \(roomID)")
|
||||
}
|
||||
}
|
||||
|
@ -214,4 +214,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
await Task.yield()
|
||||
XCTAssertTrue(callbackCorrectlyCalled)
|
||||
}
|
||||
|
||||
func testRoomSubscription() async {
|
||||
await context.nextViewState()
|
||||
XCTAssertEqual(roomProxyMock.registerTimelineListenerIfNeededCallsCount, 1)
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
timelineController.timelineItems = items
|
||||
let viewModel = RoomScreenViewModel(timelineController: timelineController,
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: nil)
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "")))
|
||||
|
||||
// Then the messages should be grouped together.
|
||||
XCTAssertEqual(viewModel.state.items[0].timelineGroupStyle, .first, "Nothing should prevent the first message from being grouped.")
|
||||
@ -65,7 +65,7 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
timelineController.timelineItems = items
|
||||
let viewModel = RoomScreenViewModel(timelineController: timelineController,
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: nil)
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "")))
|
||||
|
||||
// Then the messages should be grouped by sender.
|
||||
XCTAssertEqual(viewModel.state.items[0].timelineGroupStyle, .single, "A message should not be grouped when the sender changes.")
|
||||
@ -93,7 +93,7 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
timelineController.timelineItems = items
|
||||
let viewModel = RoomScreenViewModel(timelineController: timelineController,
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: nil)
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "")))
|
||||
|
||||
// Then the first message should not be grouped but the other two should.
|
||||
XCTAssertEqual(viewModel.state.items[0].timelineGroupStyle, .single, "When the first message has reactions it should not be grouped.")
|
||||
@ -118,7 +118,7 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
timelineController.timelineItems = items
|
||||
let viewModel = RoomScreenViewModel(timelineController: timelineController,
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: nil)
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "")))
|
||||
|
||||
// Then the first and second messages should be grouped and the last one should not.
|
||||
XCTAssertEqual(viewModel.state.items[0].timelineGroupStyle, .first, "Nothing should prevent the first message from being grouped.")
|
||||
@ -143,7 +143,7 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
timelineController.timelineItems = items
|
||||
let viewModel = RoomScreenViewModel(timelineController: timelineController,
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomName: nil)
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "")))
|
||||
|
||||
// Then the messages should be grouped together.
|
||||
XCTAssertEqual(viewModel.state.items[0].timelineGroupStyle, .first, "Nothing should prevent the first message from being grouped.")
|
||||
|
Loading…
x
Reference in New Issue
Block a user