mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 19:44:05 +00:00
Introduce the RoomThreadListServiceProxy and expose it from the RoomProxy
Also update the sdk and app mocks and add a simple `RoomThreadListServiceProxyMock` # Conflicts: # ElementX.xcodeproj/project.pbxproj # ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved # SDKMocks/Sources/Generated/SDKGeneratedMocks.swift # project.yml
This commit is contained in:
committed by
Stefan Ceriu
parent
823e2afa97
commit
e97ed6ec5c
@@ -127,6 +127,7 @@
|
|||||||
12CD8B5CC30A05061228BF9E /* TimelineItemMenuActionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9E6065FC6BC4A1B4C629E08 /* TimelineItemMenuActionProvider.swift */; };
|
12CD8B5CC30A05061228BF9E /* TimelineItemMenuActionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9E6065FC6BC4A1B4C629E08 /* TimelineItemMenuActionProvider.swift */; };
|
||||||
12E6D052D055531A6783E21B /* portrait_test_image.jpg in Resources */ = {isa = PBXBuildFile; fileRef = BC51BF90469412ABDE658CDD /* portrait_test_image.jpg */; };
|
12E6D052D055531A6783E21B /* portrait_test_image.jpg in Resources */ = {isa = PBXBuildFile; fileRef = BC51BF90469412ABDE658CDD /* portrait_test_image.jpg */; };
|
||||||
12EC6BC99F373FE5C6EB9B64 /* TimelineMediaPreviewDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 467498BEA681758BE2F80826 /* TimelineMediaPreviewDetailsView.swift */; };
|
12EC6BC99F373FE5C6EB9B64 /* TimelineMediaPreviewDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 467498BEA681758BE2F80826 /* TimelineMediaPreviewDetailsView.swift */; };
|
||||||
|
12F7172C93873638B23CD6AD /* RoomThreadListServiceProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04EB6035C1F33F25F1EBFB7D /* RoomThreadListServiceProxyProtocol.swift */; };
|
||||||
1307268DC41730E5BCF7D9A0 /* PollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638790D3F915F0909315C47A /* PollView.swift */; };
|
1307268DC41730E5BCF7D9A0 /* PollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638790D3F915F0909315C47A /* PollView.swift */; };
|
||||||
1318721F4E5F307586D98112 /* VoiceMessageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8516302ACCA94A0E680AB3B /* VoiceMessageButton.swift */; };
|
1318721F4E5F307586D98112 /* VoiceMessageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8516302ACCA94A0E680AB3B /* VoiceMessageButton.swift */; };
|
||||||
13C77FDF17C4C6627CFFC205 /* RoomTimelineItemFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D25A35764C7B3DB78954AB5 /* RoomTimelineItemFactoryProtocol.swift */; };
|
13C77FDF17C4C6627CFFC205 /* RoomTimelineItemFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D25A35764C7B3DB78954AB5 /* RoomTimelineItemFactoryProtocol.swift */; };
|
||||||
@@ -337,6 +338,7 @@
|
|||||||
388D39ED9FE1122EA6D76BF2 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BC84BA0AF11C2128D58ABD /* Common.swift */; };
|
388D39ED9FE1122EA6D76BF2 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BC84BA0AF11C2128D58ABD /* Common.swift */; };
|
||||||
3895969759E68FAB90C63EF7 /* ElementCallServiceConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 406C90AF8C3E98DF5D4E5430 /* ElementCallServiceConstants.swift */; };
|
3895969759E68FAB90C63EF7 /* ElementCallServiceConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 406C90AF8C3E98DF5D4E5430 /* ElementCallServiceConstants.swift */; };
|
||||||
38E0F9A4CB5237F039A2EEE6 /* RoomHistorySharingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 722013E20EEED73553EC6F8D /* RoomHistorySharingState.swift */; };
|
38E0F9A4CB5237F039A2EEE6 /* RoomHistorySharingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 722013E20EEED73553EC6F8D /* RoomHistorySharingState.swift */; };
|
||||||
|
38E8F5CC90DC0D716B799DE1 /* RoomThreadListServiceProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7396A6491DEC64FCB66F60A1 /* RoomThreadListServiceProxyMock.swift */; };
|
||||||
3982C505960006B341CFD0C6 /* UserDetailsEditScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27D0EA07BD545CC9F234DB8D /* UserDetailsEditScreenModels.swift */; };
|
3982C505960006B341CFD0C6 /* UserDetailsEditScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27D0EA07BD545CC9F234DB8D /* UserDetailsEditScreenModels.swift */; };
|
||||||
3982E60F9C126437D5E488A3 /* PillContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A6314FDC51DA25712D9A81 /* PillContextTests.swift */; };
|
3982E60F9C126437D5E488A3 /* PillContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A6314FDC51DA25712D9A81 /* PillContextTests.swift */; };
|
||||||
39A987B3E41B976D1DF944C6 /* CallScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A63A59BFDDC494B1C20119 /* CallScreenViewModel.swift */; };
|
39A987B3E41B976D1DF944C6 /* CallScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A63A59BFDDC494B1C20119 /* CallScreenViewModel.swift */; };
|
||||||
@@ -654,6 +656,7 @@
|
|||||||
70558528EF68CAAEF09972D5 /* RoomTimelineItemFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96ED747FF90332EA1333C22 /* RoomTimelineItemFixtures.swift */; };
|
70558528EF68CAAEF09972D5 /* RoomTimelineItemFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96ED747FF90332EA1333C22 /* RoomTimelineItemFixtures.swift */; };
|
||||||
706289B086B0A6B0C211763F /* UITestsSignalling.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7F0192CE2F891141A25B49F /* UITestsSignalling.swift */; };
|
706289B086B0A6B0C211763F /* UITestsSignalling.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7F0192CE2F891141A25B49F /* UITestsSignalling.swift */; };
|
||||||
707E49BE07E8EB8A13C0EB1E /* SessionVerificationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FACD034DB52525A3CEF2BDF /* SessionVerificationScreen.swift */; };
|
707E49BE07E8EB8A13C0EB1E /* SessionVerificationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FACD034DB52525A3CEF2BDF /* SessionVerificationScreen.swift */; };
|
||||||
|
708FC3184CCED825F0A36273 /* RoomThreadListServiceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCE06F4A71FD46C9D8CD432E /* RoomThreadListServiceProxy.swift */; };
|
||||||
709A9B52FC26B4CB86B8B020 /* EncryptedRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F06F70B9C433BAD4BC6B9F5 /* EncryptedRoomTimelineView.swift */; };
|
709A9B52FC26B4CB86B8B020 /* EncryptedRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F06F70B9C433BAD4BC6B9F5 /* EncryptedRoomTimelineView.swift */; };
|
||||||
70B83D44043293B4B77440B9 /* PollFormScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB63761D9F9CE8B23CBD6179 /* PollFormScreenModels.swift */; };
|
70B83D44043293B4B77440B9 /* PollFormScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB63761D9F9CE8B23CBD6179 /* PollFormScreenModels.swift */; };
|
||||||
71643093F87153F633A1B025 /* ThreadDecorator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA4F09CB613C54FDC73AE6A /* ThreadDecorator.swift */; };
|
71643093F87153F633A1B025 /* ThreadDecorator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA4F09CB613C54FDC73AE6A /* ThreadDecorator.swift */; };
|
||||||
@@ -1602,6 +1605,7 @@
|
|||||||
048A21188AB19349D026BECD /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
048A21188AB19349D026BECD /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||||
04BB8DDE245ED86C489BA983 /* AccessibilityIdentifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityIdentifiers.swift; sourceTree = "<group>"; };
|
04BB8DDE245ED86C489BA983 /* AccessibilityIdentifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityIdentifiers.swift; sourceTree = "<group>"; };
|
||||||
04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManager.swift; sourceTree = "<group>"; };
|
04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManager.swift; sourceTree = "<group>"; };
|
||||||
|
04EB6035C1F33F25F1EBFB7D /* RoomThreadListServiceProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomThreadListServiceProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
0516C69708D5CBDE1A8E77EC /* RoomDirectorySearchProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchProxyProtocol.swift; sourceTree = "<group>"; };
|
0516C69708D5CBDE1A8E77EC /* RoomDirectorySearchProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
052A8C0B00FE8AD7C972F2A4 /* LocationSharingScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSharingScreenViewModel.swift; sourceTree = "<group>"; };
|
052A8C0B00FE8AD7C972F2A4 /* LocationSharingScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSharingScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
052B2F924572AFD70B5F500E /* StartChatScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartChatScreenViewModel.swift; sourceTree = "<group>"; };
|
052B2F924572AFD70B5F500E /* StartChatScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartChatScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
@@ -2003,7 +2007,7 @@
|
|||||||
4A2B5274C1D3D2999D643786 /* EncryptionResetPasswordScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
4A2B5274C1D3D2999D643786 /* EncryptionResetPasswordScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
4A5B4CD611DE7E94F5BA87B2 /* AppLockTimerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockTimerTests.swift; sourceTree = "<group>"; };
|
4A5B4CD611DE7E94F5BA87B2 /* AppLockTimerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockTimerTests.swift; sourceTree = "<group>"; };
|
||||||
4AB29A2D95D3469B5F016655 /* SecureBackupControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupControllerMock.swift; sourceTree = "<group>"; };
|
4AB29A2D95D3469B5F016655 /* SecureBackupControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupControllerMock.swift; sourceTree = "<group>"; };
|
||||||
4B1F71AC585827E6C416C15A /* AppIcon.icon */ = {isa = PBXFileReference; lastKnownFileType = wrapper.icon; path = AppIcon.icon; sourceTree = "<group>"; };
|
4B1F71AC585827E6C416C15A /* AppIcon.icon */ = {isa = PBXFileReference; path = AppIcon.icon; sourceTree = "<group>"; };
|
||||||
4B2B564CA6570E1487A7C7CC /* SpaceRoomListProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceRoomListProxy.swift; sourceTree = "<group>"; };
|
4B2B564CA6570E1487A7C7CC /* SpaceRoomListProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceRoomListProxy.swift; sourceTree = "<group>"; };
|
||||||
4B2D4EEBE8C098BBADD10939 /* SecureBackupKeyBackupScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupKeyBackupScreenCoordinator.swift; sourceTree = "<group>"; };
|
4B2D4EEBE8C098BBADD10939 /* SecureBackupKeyBackupScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupKeyBackupScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
4B41FABA2B0AEF4389986495 /* LoginMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginMode.swift; sourceTree = "<group>"; };
|
4B41FABA2B0AEF4389986495 /* LoginMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginMode.swift; sourceTree = "<group>"; };
|
||||||
@@ -2203,6 +2207,7 @@
|
|||||||
7310D8DFE01AF45F0689C3AA /* Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Publisher.swift; sourceTree = "<group>"; };
|
7310D8DFE01AF45F0689C3AA /* Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Publisher.swift; sourceTree = "<group>"; };
|
||||||
7367B3B9A8CAF902220F31D1 /* BugReportFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportFlowCoordinator.swift; sourceTree = "<group>"; };
|
7367B3B9A8CAF902220F31D1 /* BugReportFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportFlowCoordinator.swift; sourceTree = "<group>"; };
|
||||||
739077686814E4EA339B1C83 /* RoomPreviewProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPreviewProxyProtocol.swift; sourceTree = "<group>"; };
|
739077686814E4EA339B1C83 /* RoomPreviewProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPreviewProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
7396A6491DEC64FCB66F60A1 /* RoomThreadListServiceProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomThreadListServiceProxyMock.swift; sourceTree = "<group>"; };
|
||||||
73A5C3F7C9C1DA10CAEC6A98 /* VoiceMessageRecordingComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRecordingComposer.swift; sourceTree = "<group>"; };
|
73A5C3F7C9C1DA10CAEC6A98 /* VoiceMessageRecordingComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRecordingComposer.swift; sourceTree = "<group>"; };
|
||||||
73F3153AB9D628110878E24F /* libMatrixRustSDKMocks.a */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = archive.ar; path = libMatrixRustSDKMocks.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
73F3153AB9D628110878E24F /* libMatrixRustSDKMocks.a */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = archive.ar; path = libMatrixRustSDKMocks.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
73FEE625AB52042049DB9268 /* ThreadTimelineScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadTimelineScreenCoordinator.swift; sourceTree = "<group>"; };
|
73FEE625AB52042049DB9268 /* ThreadTimelineScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadTimelineScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
@@ -2708,6 +2713,7 @@
|
|||||||
CC743C7A85E3171BCBF0A653 /* AvatarHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarHeaderView.swift; sourceTree = "<group>"; };
|
CC743C7A85E3171BCBF0A653 /* AvatarHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarHeaderView.swift; sourceTree = "<group>"; };
|
||||||
CC8E9ECC1118A92FAD5191CD /* SpaceAddRoomsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceAddRoomsScreen.swift; sourceTree = "<group>"; };
|
CC8E9ECC1118A92FAD5191CD /* SpaceAddRoomsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceAddRoomsScreen.swift; sourceTree = "<group>"; };
|
||||||
CCAA1B97A17A750AC706B112 /* SpaceServiceRoom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceServiceRoom.swift; sourceTree = "<group>"; };
|
CCAA1B97A17A750AC706B112 /* SpaceServiceRoom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceServiceRoom.swift; sourceTree = "<group>"; };
|
||||||
|
CCE06F4A71FD46C9D8CD432E /* RoomThreadListServiceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomThreadListServiceProxy.swift; sourceTree = "<group>"; };
|
||||||
CCF71646898A2F720C5BFDF5 /* RoomDirectorySearchScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchScreenViewModel.swift; sourceTree = "<group>"; };
|
CCF71646898A2F720C5BFDF5 /* RoomDirectorySearchScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
CD469F7513574341181F7EAA /* ServerSelectionScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreen.swift; sourceTree = "<group>"; };
|
CD469F7513574341181F7EAA /* ServerSelectionScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreen.swift; sourceTree = "<group>"; };
|
||||||
CD6613DE16AD26B3A74DA1F5 /* LocationRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationRoomTimelineItemContent.swift; sourceTree = "<group>"; };
|
CD6613DE16AD26B3A74DA1F5 /* LocationRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationRoomTimelineItemContent.swift; sourceTree = "<group>"; };
|
||||||
@@ -3714,6 +3720,7 @@
|
|||||||
E944F717FC10A428D027074D /* RoomPowerLevelsProxyMock.swift */,
|
E944F717FC10A428D027074D /* RoomPowerLevelsProxyMock.swift */,
|
||||||
6695C64F066628411EAD21E9 /* RoomPreviewProxyMock.swift */,
|
6695C64F066628411EAD21E9 /* RoomPreviewProxyMock.swift */,
|
||||||
FC83F47D2173B7538AA72E0E /* RoomSummaryProviderMock.swift */,
|
FC83F47D2173B7538AA72E0E /* RoomSummaryProviderMock.swift */,
|
||||||
|
7396A6491DEC64FCB66F60A1 /* RoomThreadListServiceProxyMock.swift */,
|
||||||
4AB29A2D95D3469B5F016655 /* SecureBackupControllerMock.swift */,
|
4AB29A2D95D3469B5F016655 /* SecureBackupControllerMock.swift */,
|
||||||
248649EBA5BC33DB93698734 /* SessionVerificationControllerProxyMock.swift */,
|
248649EBA5BC33DB93698734 /* SessionVerificationControllerProxyMock.swift */,
|
||||||
7DB2A5FF1E68BA580A20D405 /* SpaceRoomListProxyMock.swift */,
|
7DB2A5FF1E68BA580A20D405 /* SpaceRoomListProxyMock.swift */,
|
||||||
@@ -4087,6 +4094,8 @@
|
|||||||
CFFA5E881D281810AB428EA3 /* RoomPowerLevelsProxy.swift */,
|
CFFA5E881D281810AB428EA3 /* RoomPowerLevelsProxy.swift */,
|
||||||
47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */,
|
47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */,
|
||||||
578AF9CE60816069536C0953 /* RoomRole.swift */,
|
578AF9CE60816069536C0953 /* RoomRole.swift */,
|
||||||
|
CCE06F4A71FD46C9D8CD432E /* RoomThreadListServiceProxy.swift */,
|
||||||
|
04EB6035C1F33F25F1EBFB7D /* RoomThreadListServiceProxyProtocol.swift */,
|
||||||
2C0F49BD446849654C0D24E0 /* RoomMember */,
|
2C0F49BD446849654C0D24E0 /* RoomMember */,
|
||||||
4DC0344D2EBD0AE5D71754A9 /* RoomMembershipDetails */,
|
4DC0344D2EBD0AE5D71754A9 /* RoomMembershipDetails */,
|
||||||
7FC3F8FA5EA765AC3B000F55 /* RoomPreview */,
|
7FC3F8FA5EA765AC3B000F55 /* RoomPreview */,
|
||||||
@@ -7250,6 +7259,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = 7AE41FCCF9D1352E2770D1F9 /* Build configuration list for PBXProject "ElementX" */;
|
buildConfigurationList = 7AE41FCCF9D1352E2770D1F9 /* Build configuration list for PBXProject "ElementX" */;
|
||||||
|
compatibilityVersion = "Xcode 14.0";
|
||||||
developmentRegion = en;
|
developmentRegion = en;
|
||||||
hasScannedForEncodings = 0;
|
hasScannedForEncodings = 0;
|
||||||
knownRegions = (
|
knownRegions = (
|
||||||
@@ -7325,7 +7335,6 @@
|
|||||||
C89CF7729E028671C5DC461E /* XCLocalSwiftPackageReference "compound-ios" */,
|
C89CF7729E028671C5DC461E /* XCLocalSwiftPackageReference "compound-ios" */,
|
||||||
);
|
);
|
||||||
preferredProjectObjectVersion = 77;
|
preferredProjectObjectVersion = 77;
|
||||||
productRefGroup = 681566846AF307E9BA4C72C6 /* Products */;
|
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
@@ -8649,6 +8658,9 @@
|
|||||||
983896D611ABF52A5C37498D /* RoomSummaryProvider.swift in Sources */,
|
983896D611ABF52A5C37498D /* RoomSummaryProvider.swift in Sources */,
|
||||||
B5899F18AD6C56CE08FE532B /* RoomSummaryProviderMock.swift in Sources */,
|
B5899F18AD6C56CE08FE532B /* RoomSummaryProviderMock.swift in Sources */,
|
||||||
AA050DF4AEE54A641BA7CA22 /* RoomSummaryProviderProtocol.swift in Sources */,
|
AA050DF4AEE54A641BA7CA22 /* RoomSummaryProviderProtocol.swift in Sources */,
|
||||||
|
708FC3184CCED825F0A36273 /* RoomThreadListServiceProxy.swift in Sources */,
|
||||||
|
38E8F5CC90DC0D716B799DE1 /* RoomThreadListServiceProxyMock.swift in Sources */,
|
||||||
|
12F7172C93873638B23CD6AD /* RoomThreadListServiceProxyProtocol.swift in Sources */,
|
||||||
4E945AD6862C403F74E57755 /* RoomTimelineItemFactory.swift in Sources */,
|
4E945AD6862C403F74E57755 /* RoomTimelineItemFactory.swift in Sources */,
|
||||||
13C77FDF17C4C6627CFFC205 /* RoomTimelineItemFactoryProtocol.swift in Sources */,
|
13C77FDF17C4C6627CFFC205 /* RoomTimelineItemFactoryProtocol.swift in Sources */,
|
||||||
70558528EF68CAAEF09972D5 /* RoomTimelineItemFixtures.swift in Sources */,
|
70558528EF68CAAEF09972D5 /* RoomTimelineItemFixtures.swift in Sources */,
|
||||||
|
|||||||
@@ -4,8 +4,7 @@
|
|||||||
version = "1.7">
|
version = "1.7">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
buildImplicitDependencies = "YES"
|
buildImplicitDependencies = "YES">
|
||||||
runPostActionsOnFailure = "NO">
|
|
||||||
<BuildActionEntries>
|
<BuildActionEntries>
|
||||||
<BuildActionEntry
|
<BuildActionEntry
|
||||||
buildForTesting = "YES"
|
buildForTesting = "YES"
|
||||||
@@ -30,12 +29,6 @@
|
|||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
codeCoverageEnabled = "YES"
|
codeCoverageEnabled = "YES"
|
||||||
onlyGenerateCoverageForSpecifiedTargets = "YES">
|
onlyGenerateCoverageForSpecifiedTargets = "YES">
|
||||||
<TestPlans>
|
|
||||||
<TestPlanReference
|
|
||||||
default = "YES"
|
|
||||||
reference = "container:UnitTests/SupportingFiles/UnitTests.xctestplan">
|
|
||||||
</TestPlanReference>
|
|
||||||
</TestPlans>
|
|
||||||
<MacroExpansion>
|
<MacroExpansion>
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
@@ -45,10 +38,6 @@
|
|||||||
ReferencedContainer = "container:ElementX.xcodeproj">
|
ReferencedContainer = "container:ElementX.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
||||||
<Testables>
|
|
||||||
</Testables>
|
|
||||||
<CommandLineArguments>
|
|
||||||
</CommandLineArguments>
|
|
||||||
<CodeCoverageTargets>
|
<CodeCoverageTargets>
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
@@ -58,6 +47,12 @@
|
|||||||
ReferencedContainer = "container:ElementX.xcodeproj">
|
ReferencedContainer = "container:ElementX.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</CodeCoverageTargets>
|
</CodeCoverageTargets>
|
||||||
|
<TestPlans>
|
||||||
|
<TestPlanReference
|
||||||
|
reference = "container:UnitTests/SupportingFiles/UnitTests.xctestplan"
|
||||||
|
default = "YES">
|
||||||
|
</TestPlanReference>
|
||||||
|
</TestPlans>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@@ -79,8 +74,6 @@
|
|||||||
ReferencedContainer = "container:ElementX.xcodeproj">
|
ReferencedContainer = "container:ElementX.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
<CommandLineArguments>
|
|
||||||
</CommandLineArguments>
|
|
||||||
<EnvironmentVariables>
|
<EnvironmentVariables>
|
||||||
<EnvironmentVariable
|
<EnvironmentVariable
|
||||||
key = "HTTPS_PROXY"
|
key = "HTTPS_PROXY"
|
||||||
@@ -115,8 +108,6 @@
|
|||||||
ReferencedContainer = "container:ElementX.xcodeproj">
|
ReferencedContainer = "container:ElementX.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
<CommandLineArguments>
|
|
||||||
</CommandLineArguments>
|
|
||||||
</ProfileAction>
|
</ProfileAction>
|
||||||
<AnalyzeAction
|
<AnalyzeAction
|
||||||
buildConfiguration = "Debug">
|
buildConfiguration = "Debug">
|
||||||
|
|||||||
@@ -6930,6 +6930,70 @@ class JoinedRoomProxyMock: JoinedRoomProxyProtocol, @unchecked Sendable {
|
|||||||
return threadTimelineEventIDReturnValue
|
return threadTimelineEventIDReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//MARK: - threadListService
|
||||||
|
|
||||||
|
var threadListServiceUnderlyingCallsCount = 0
|
||||||
|
var threadListServiceCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return threadListServiceUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = threadListServiceUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
threadListServiceUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
threadListServiceUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var threadListServiceCalled: Bool {
|
||||||
|
return threadListServiceCallsCount > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var threadListServiceUnderlyingReturnValue: RoomThreadListServiceProxyProtocol!
|
||||||
|
var threadListServiceReturnValue: RoomThreadListServiceProxyProtocol! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return threadListServiceUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: RoomThreadListServiceProxyProtocol? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = threadListServiceUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
threadListServiceUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
threadListServiceUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var threadListServiceClosure: (() async -> RoomThreadListServiceProxyProtocol)?
|
||||||
|
|
||||||
|
func threadListService() async -> RoomThreadListServiceProxyProtocol {
|
||||||
|
threadListServiceCallsCount += 1
|
||||||
|
if let threadListServiceClosure = threadListServiceClosure {
|
||||||
|
return await threadListServiceClosure()
|
||||||
|
} else {
|
||||||
|
return threadListServiceReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
//MARK: - loadOrFetchEventDetails
|
//MARK: - loadOrFetchEventDetails
|
||||||
|
|
||||||
var loadOrFetchEventDetailsForUnderlyingCallsCount = 0
|
var loadOrFetchEventDetailsForUnderlyingCallsCount = 0
|
||||||
@@ -15957,6 +16021,83 @@ class RoomSummaryProviderMock: RoomSummaryProviderProtocol, @unchecked Sendable
|
|||||||
setRoomListClosure?(roomList)
|
setRoomListClosure?(roomList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class RoomThreadListServiceProxyMock: RoomThreadListServiceProxyProtocol, @unchecked Sendable {
|
||||||
|
var itemsPublisher: CurrentValuePublisher<[RoomThreadListItem], Never> {
|
||||||
|
get { return underlyingItemsPublisher }
|
||||||
|
set(value) { underlyingItemsPublisher = value }
|
||||||
|
}
|
||||||
|
var underlyingItemsPublisher: CurrentValuePublisher<[RoomThreadListItem], Never>!
|
||||||
|
var paginationStatePublisher: CurrentValuePublisher<RoomThreadListPaginationState, Never> {
|
||||||
|
get { return underlyingPaginationStatePublisher }
|
||||||
|
set(value) { underlyingPaginationStatePublisher = value }
|
||||||
|
}
|
||||||
|
var underlyingPaginationStatePublisher: CurrentValuePublisher<RoomThreadListPaginationState, Never>!
|
||||||
|
|
||||||
|
//MARK: - paginate
|
||||||
|
|
||||||
|
var paginateUnderlyingCallsCount = 0
|
||||||
|
var paginateCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return paginateUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = paginateUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
paginateUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
paginateUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var paginateCalled: Bool {
|
||||||
|
return paginateCallsCount > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var paginateUnderlyingReturnValue: Result<Void, RoomProxyError>!
|
||||||
|
var paginateReturnValue: Result<Void, RoomProxyError>! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return paginateUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: Result<Void, RoomProxyError>? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = paginateUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
paginateUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
paginateUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var paginateClosure: (() async -> Result<Void, RoomProxyError>)?
|
||||||
|
|
||||||
|
func paginate() async -> Result<Void, RoomProxyError> {
|
||||||
|
paginateCallsCount += 1
|
||||||
|
if let paginateClosure = paginateClosure {
|
||||||
|
return await paginateClosure()
|
||||||
|
} else {
|
||||||
|
return paginateReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
class SecureBackupControllerMock: SecureBackupControllerProtocol, @unchecked Sendable {
|
class SecureBackupControllerMock: SecureBackupControllerProtocol, @unchecked Sendable {
|
||||||
var recoveryState: CurrentValuePublisher<SecureBackupRecoveryState, Never> {
|
var recoveryState: CurrentValuePublisher<SecureBackupRecoveryState, Never> {
|
||||||
get { return underlyingRecoveryState }
|
get { return underlyingRecoveryState }
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2026 Element Creations Ltd.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
// Please see LICENSE files in the repository root for full details.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
struct RoomThreadListProxyMockConfiguration {
|
||||||
|
var items: [RoomThreadListItem] = .mocks
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RoomThreadListServiceProxyMock {
|
||||||
|
convenience init(_ configuration: RoomThreadListProxyMockConfiguration) {
|
||||||
|
self.init()
|
||||||
|
|
||||||
|
itemsPublisher = CurrentValueSubject(configuration.items).asCurrentValuePublisher()
|
||||||
|
|
||||||
|
paginateReturnValue = .success(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Array where Element == RoomThreadListItem {
|
||||||
|
static let mocks: [RoomThreadListItem] = [
|
||||||
|
.init(id: "1",
|
||||||
|
rootMessageDetails: .init(sender: .init(id: "@alice:matrix.org", displayName: "Alice", avatarURL: .mockMXCUserAvatar),
|
||||||
|
timestamp: .distantPast,
|
||||||
|
message: .init("Ping")),
|
||||||
|
latestMessageDetails: .init(sender: .init(id: "@bob:matrix.org"),
|
||||||
|
timestamp: .distantFuture,
|
||||||
|
message: .init("Pong")),
|
||||||
|
numberOfReplies: 5),
|
||||||
|
.init(id: "2",
|
||||||
|
rootMessageDetails: .init(sender: .init(id: "@alice:matrix.org", displayName: "Alice", avatarURL: .mockMXCUserAvatar),
|
||||||
|
timestamp: .distantPast,
|
||||||
|
message: .init("Can we schedule a meeting for next week?")),
|
||||||
|
latestMessageDetails: .init(sender: .init(id: "@bob:matrix.org"),
|
||||||
|
timestamp: .distantFuture,
|
||||||
|
message: .init("Looking forward to our next steps!")),
|
||||||
|
numberOfReplies: 10)
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -197,6 +197,18 @@ extension SDKListener: KnockRequestsListener where T == [KnockRequest] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension SDKListener: ThreadListEntriesListener where T == [ThreadListUpdate] {
|
||||||
|
func onUpdate(diff: [ThreadListUpdate]) {
|
||||||
|
onUpdateClosure(diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SDKListener: ThreadListPaginationStateListener where T == ThreadListPaginationState {
|
||||||
|
func onUpdate(state: ThreadListPaginationState) {
|
||||||
|
onUpdateClosure(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: TimelineProxy
|
// MARK: TimelineProxy
|
||||||
|
|
||||||
extension SDKListener: PaginationStatusListener where T == PaginationStatus {
|
extension SDKListener: PaginationStatusListener where T == PaginationStatus {
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
|
|
||||||
let spaceService: SpaceServiceProxyProtocol
|
let spaceService: SpaceServiceProxyProtocol
|
||||||
|
|
||||||
|
let eventStringBuilder: RoomEventStringBuilder
|
||||||
|
|
||||||
private static var roomCreationPowerLevelOverrides: PowerLevels {
|
private static var roomCreationPowerLevelOverrides: PowerLevels {
|
||||||
.init(usersDefault: nil,
|
.init(usersDefault: nil,
|
||||||
eventsDefault: nil,
|
eventsDefault: nil,
|
||||||
@@ -216,6 +218,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
roomSummaryProvider = configuredAppService.roomSummaryProvider
|
roomSummaryProvider = configuredAppService.roomSummaryProvider
|
||||||
alternateRoomSummaryProvider = configuredAppService.alternateRoomSummaryProvider
|
alternateRoomSummaryProvider = configuredAppService.alternateRoomSummaryProvider
|
||||||
staticRoomSummaryProvider = configuredAppService.staticRoomSummaryProvider
|
staticRoomSummaryProvider = configuredAppService.staticRoomSummaryProvider
|
||||||
|
eventStringBuilder = configuredAppService.eventStringBuilder
|
||||||
|
|
||||||
syncServiceStateUpdateTaskHandle = createSyncServiceStateObserver(syncService)
|
syncServiceStateUpdateTaskHandle = createSyncServiceStateObserver(syncService)
|
||||||
roomListStateUpdateTaskHandle = createRoomListServiceObserver(roomListService)
|
roomListStateUpdateTaskHandle = createRoomListServiceObserver(roomListService)
|
||||||
@@ -1169,7 +1172,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
let roomProxy = try await JoinedRoomProxy(roomListService: roomListService,
|
let roomProxy = try await JoinedRoomProxy(roomListService: roomListService,
|
||||||
room: room,
|
room: room,
|
||||||
appSettings: appSettings,
|
appSettings: appSettings,
|
||||||
analyticsService: analyticsService)
|
analyticsService: analyticsService,
|
||||||
|
eventStringBuilder: eventStringBuilder)
|
||||||
|
|
||||||
return .joined(roomProxy)
|
return .joined(roomProxy)
|
||||||
case .left:
|
case .left:
|
||||||
@@ -1318,6 +1322,7 @@ private struct ClientProxyServices {
|
|||||||
let roomSummaryProvider: RoomSummaryProviderProtocol
|
let roomSummaryProvider: RoomSummaryProviderProtocol
|
||||||
let alternateRoomSummaryProvider: RoomSummaryProviderProtocol
|
let alternateRoomSummaryProvider: RoomSummaryProviderProtocol
|
||||||
let staticRoomSummaryProvider: StaticRoomSummaryProviderProtocol
|
let staticRoomSummaryProvider: StaticRoomSummaryProviderProtocol
|
||||||
|
let eventStringBuilder: RoomEventStringBuilder
|
||||||
|
|
||||||
init(client: ClientProtocol,
|
init(client: ClientProtocol,
|
||||||
actionsSubject: PassthroughSubject<ClientProxyAction, Never>,
|
actionsSubject: PassthroughSubject<ClientProxyAction, Never>,
|
||||||
@@ -1334,10 +1339,11 @@ private struct ClientProxyServices {
|
|||||||
let roomMessageEventStringBuilder = RoomMessageEventStringBuilder(attributedStringBuilder: AttributedStringBuilder(cacheKey: "roomList",
|
let roomMessageEventStringBuilder = RoomMessageEventStringBuilder(attributedStringBuilder: AttributedStringBuilder(cacheKey: "roomList",
|
||||||
mentionBuilder: PlainMentionBuilder()),
|
mentionBuilder: PlainMentionBuilder()),
|
||||||
style: .senderPrefixed)
|
style: .senderPrefixed)
|
||||||
let eventStringBuilder = try RoomEventStringBuilder(stateEventStringBuilder: RoomStateEventStringBuilder(userID: client.userId(), shouldDisambiguateDisplayNames: false),
|
|
||||||
messageEventStringBuilder: roomMessageEventStringBuilder,
|
eventStringBuilder = try RoomEventStringBuilder(stateEventStringBuilder: RoomStateEventStringBuilder(userID: client.userId(), shouldDisambiguateDisplayNames: false),
|
||||||
shouldDisambiguateDisplayNames: false,
|
messageEventStringBuilder: roomMessageEventStringBuilder,
|
||||||
shouldPrefixSenderName: true)
|
shouldDisambiguateDisplayNames: false,
|
||||||
|
shouldPrefixSenderName: true)
|
||||||
|
|
||||||
roomSummaryProvider = RoomSummaryProvider(roomListService: roomListService,
|
roomSummaryProvider = RoomSummaryProvider(roomListService: roomListService,
|
||||||
eventStringBuilder: eventStringBuilder,
|
eventStringBuilder: eventStringBuilder,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol {
|
|||||||
private let room: RoomProtocol
|
private let room: RoomProtocol
|
||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
private let analyticsService: AnalyticsService
|
private let analyticsService: AnalyticsService
|
||||||
|
private let eventStringBuilder: RoomEventStringBuilder
|
||||||
|
|
||||||
// periphery:ignore - required for instance retention in the rust codebase
|
// periphery:ignore - required for instance retention in the rust codebase
|
||||||
private var roomInfoObservationToken: TaskHandle?
|
private var roomInfoObservationToken: TaskHandle?
|
||||||
@@ -78,11 +79,13 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol {
|
|||||||
init(roomListService: RoomListServiceProtocol,
|
init(roomListService: RoomListServiceProtocol,
|
||||||
room: RoomProtocol,
|
room: RoomProtocol,
|
||||||
appSettings: AppSettings,
|
appSettings: AppSettings,
|
||||||
analyticsService: AnalyticsService) async throws {
|
analyticsService: AnalyticsService,
|
||||||
|
eventStringBuilder: RoomEventStringBuilder) async throws {
|
||||||
self.roomListService = roomListService
|
self.roomListService = roomListService
|
||||||
self.room = room
|
self.room = room
|
||||||
self.appSettings = appSettings
|
self.appSettings = appSettings
|
||||||
self.analyticsService = analyticsService
|
self.analyticsService = analyticsService
|
||||||
|
self.eventStringBuilder = eventStringBuilder
|
||||||
|
|
||||||
infoSubject = try await .init(RoomInfoProxy(roomInfo: room.roomInfo()))
|
infoSubject = try await .init(RoomInfoProxy(roomInfo: room.roomInfo()))
|
||||||
|
|
||||||
@@ -200,6 +203,10 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func threadListService() async -> RoomThreadListServiceProxyProtocol {
|
||||||
|
await RoomThreadListProxy(threadListService: room.threadListService(), eventStringBuilder: eventStringBuilder)
|
||||||
|
}
|
||||||
|
|
||||||
func loadOrFetchEventDetails(for eventID: String) async -> Result<TimelineEvent, RoomProxyError> {
|
func loadOrFetchEventDetails(for eventID: String) async -> Result<TimelineEvent, RoomProxyError> {
|
||||||
do {
|
do {
|
||||||
let event = try await room.loadOrFetchEvent(eventId: eventID)
|
let event = try await room.loadOrFetchEvent(eventId: eventID)
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ protocol JoinedRoomProxyProtocol: RoomProxyProtocol {
|
|||||||
|
|
||||||
func threadTimeline(eventID: String) async -> Result<TimelineProxyProtocol, RoomProxyError>
|
func threadTimeline(eventID: String) async -> Result<TimelineProxyProtocol, RoomProxyError>
|
||||||
|
|
||||||
|
func threadListService() async -> RoomThreadListServiceProxyProtocol
|
||||||
|
|
||||||
func loadOrFetchEventDetails(for eventID: String) async -> Result<TimelineEvent, RoomProxyError>
|
func loadOrFetchEventDetails(for eventID: String) async -> Result<TimelineEvent, RoomProxyError>
|
||||||
|
|
||||||
func messageFilteredTimeline(focus: TimelineFocus,
|
func messageFilteredTimeline(focus: TimelineFocus,
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2026 Element Creations Ltd.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
// Please see LICENSE files in the repository root for full details.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
import MatrixRustSDK
|
||||||
|
|
||||||
|
class RoomThreadListProxy: RoomThreadListServiceProxyProtocol {
|
||||||
|
private let threadListService: ThreadListServiceProtocol
|
||||||
|
private let eventStringBuilder: RoomEventStringBuilder
|
||||||
|
|
||||||
|
private var itemUpdatesHandle: TaskHandle?
|
||||||
|
private let itemsSubject = CurrentValueSubject<[RoomThreadListItem], Never>([])
|
||||||
|
var itemsPublisher: CurrentValuePublisher<[RoomThreadListItem], Never> {
|
||||||
|
itemsSubject.asCurrentValuePublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var paginationStateHandle: TaskHandle?
|
||||||
|
let paginationStatePublisher: CurrentValuePublisher<RoomThreadListPaginationState, Never>
|
||||||
|
|
||||||
|
init(threadListService: ThreadListServiceProtocol, eventStringBuilder: RoomEventStringBuilder, paginationToken: String? = nil) {
|
||||||
|
self.threadListService = threadListService
|
||||||
|
self.eventStringBuilder = eventStringBuilder
|
||||||
|
|
||||||
|
let paginationStateSubject = CurrentValueSubject<RoomThreadListPaginationState, Never>(.init(sdkState: threadListService.paginationState()))
|
||||||
|
paginationStatePublisher = paginationStateSubject.asCurrentValuePublisher()
|
||||||
|
|
||||||
|
paginationStateHandle = threadListService.subscribeToPaginationStateUpdates(listener: SDKListener { state in
|
||||||
|
paginationStateSubject.send(.init(sdkState: state))
|
||||||
|
})
|
||||||
|
|
||||||
|
updateItems()
|
||||||
|
|
||||||
|
itemUpdatesHandle = self.threadListService.subscribeToItemsUpdates(listener: SDKListener { [weak self] _ in
|
||||||
|
self?.updateItems()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func paginate() async -> Result<Void, RoomProxyError> {
|
||||||
|
do {
|
||||||
|
try await threadListService.paginate()
|
||||||
|
return .success(())
|
||||||
|
} catch {
|
||||||
|
MXLog.error("Failed paginating with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func updateItems() {
|
||||||
|
let items = threadListService.items().map { item in
|
||||||
|
guard let rootMessageDetails = buildMessageDetails(item.rootEvent) else {
|
||||||
|
fatalError("This should never fail™")
|
||||||
|
}
|
||||||
|
|
||||||
|
let latestMessageDetails = buildMessageDetails(item.latestEvent)
|
||||||
|
|
||||||
|
return RoomThreadListItem(id: item.rootEvent.eventId,
|
||||||
|
rootMessageDetails: rootMessageDetails,
|
||||||
|
latestMessageDetails: latestMessageDetails,
|
||||||
|
numberOfReplies: UInt(item.numReplies))
|
||||||
|
}
|
||||||
|
|
||||||
|
itemsSubject.send(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func buildMessageDetails(_ threadListItemEvent: ThreadListItemEvent?) -> RoomThreadListItem.MessageDetails? {
|
||||||
|
guard let threadListItemEvent else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let sender = TimelineItemSender(senderID: threadListItemEvent.sender, senderProfile: threadListItemEvent.senderProfile)
|
||||||
|
let timestamp = Date(timeIntervalSince1970: TimeInterval(threadListItemEvent.timestamp / 1000))
|
||||||
|
|
||||||
|
let message: AttributedString? = if let content = threadListItemEvent.content {
|
||||||
|
eventStringBuilder.buildAttributedString(for: content,
|
||||||
|
sender: sender,
|
||||||
|
isOutgoing: threadListItemEvent.isOwn)
|
||||||
|
} else {
|
||||||
|
nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return .init(sender: sender, timestamp: timestamp, message: message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RoomThreadListPaginationState {
|
||||||
|
init(sdkState: MatrixRustSDK.ThreadListPaginationState) {
|
||||||
|
switch sdkState {
|
||||||
|
case .loading:
|
||||||
|
self = .loading
|
||||||
|
case .idle(let endReached):
|
||||||
|
self = .idle(endReached: endReached)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2026 Element Creations Ltd.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
// Please see LICENSE files in the repository root for full details.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// sourcery: AutoMockable
|
||||||
|
protocol RoomThreadListServiceProxyProtocol {
|
||||||
|
var itemsPublisher: CurrentValuePublisher<[RoomThreadListItem], Never> { get }
|
||||||
|
|
||||||
|
var paginationStatePublisher: CurrentValuePublisher<RoomThreadListPaginationState, Never> { get }
|
||||||
|
|
||||||
|
func paginate() async -> Result<Void, RoomProxyError>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RoomThreadListItem: Identifiable {
|
||||||
|
struct MessageDetails {
|
||||||
|
let sender: TimelineItemSender
|
||||||
|
let timestamp: Date
|
||||||
|
let message: AttributedString?
|
||||||
|
}
|
||||||
|
|
||||||
|
let id: String
|
||||||
|
|
||||||
|
let rootMessageDetails: MessageDetails
|
||||||
|
let latestMessageDetails: MessageDetails?
|
||||||
|
|
||||||
|
let numberOfReplies: UInt
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RoomThreadListPaginationState: Equatable {
|
||||||
|
case idle(endReached: Bool)
|
||||||
|
case loading
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user