Optimize invites list (part 2) (#1268)

* Optimise invites list

* Fix failing tests

* Cleanup

* Add weak self

* Refactor ReportContentViewModelTests
This commit is contained in:
Alfonso Grillo 2023-07-11 10:08:27 +02:00 committed by GitHub
parent 5ae227179c
commit 98dabe8500
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 120 additions and 88 deletions

View File

@ -3,7 +3,7 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 54; objectVersion = 51;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
@ -134,6 +134,7 @@
30CC1DB7CE357659C82AA115 /* MediaProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85EB16E7FE59A947CA441531 /* MediaProviderProtocol.swift */; }; 30CC1DB7CE357659C82AA115 /* MediaProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85EB16E7FE59A947CA441531 /* MediaProviderProtocol.swift */; };
30CC4F796B27BE8B1DFDBF5A /* NSEUserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAA2832D93EC7D2608703FB /* NSEUserSession.swift */; }; 30CC4F796B27BE8B1DFDBF5A /* NSEUserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAA2832D93EC7D2608703FB /* NSEUserSession.swift */; };
3113065AABBC14CEAE6843FA /* UserSessionFlowCoordinatorStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8774CF614849664B5B3C2A1 /* UserSessionFlowCoordinatorStateMachine.swift */; }; 3113065AABBC14CEAE6843FA /* UserSessionFlowCoordinatorStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8774CF614849664B5B3C2A1 /* UserSessionFlowCoordinatorStateMachine.swift */; };
3116693C5EB476E028990416 /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74611A4182DCF5F4D42696EC /* XCTestCase.swift */; };
329571083B132E4941131835 /* OnboardingBackgroundImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 686BCFA37AC6C67FF973CE67 /* OnboardingBackgroundImage.swift */; }; 329571083B132E4941131835 /* OnboardingBackgroundImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 686BCFA37AC6C67FF973CE67 /* OnboardingBackgroundImage.swift */; };
339BC18777912E1989F2F17D /* Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584A61D9C459FAFEF038A7C0 /* Section.swift */; }; 339BC18777912E1989F2F17D /* Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584A61D9C459FAFEF038A7C0 /* Section.swift */; };
339D847497C51F2B36E3666B /* FixedIconSizeLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3518637393394901BF5BFAC3 /* FixedIconSizeLabelStyle.swift */; }; 339D847497C51F2B36E3666B /* FixedIconSizeLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3518637393394901BF5BFAC3 /* FixedIconSizeLabelStyle.swift */; };
@ -267,7 +268,6 @@
659E5B766F76FDEC1BF393A4 /* RoomDetailsEditScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E413F4CBD7BF0588F394A9DD /* RoomDetailsEditScreenViewModel.swift */; }; 659E5B766F76FDEC1BF393A4 /* RoomDetailsEditScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E413F4CBD7BF0588F394A9DD /* RoomDetailsEditScreenViewModel.swift */; };
65EDA77363BEDC40CDE43B43 /* InvitesScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42ADEA322D2089391E049535 /* InvitesScreen.swift */; }; 65EDA77363BEDC40CDE43B43 /* InvitesScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42ADEA322D2089391E049535 /* InvitesScreen.swift */; };
663E198678778F7426A9B27D /* Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FAFE1C2149E6AC8156ED2B /* Collection.swift */; }; 663E198678778F7426A9B27D /* Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FAFE1C2149E6AC8156ED2B /* Collection.swift */; };
664F77F02A57617A00FB9B24 /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 664F77EF2A57617A00FB9B24 /* XCTestCase.swift */; };
6713835120D94BAA8ED7E3E5 /* MessageForwardingScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59846FA04E1DBBFDD8829C2A /* MessageForwardingScreenUITests.swift */; }; 6713835120D94BAA8ED7E3E5 /* MessageForwardingScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59846FA04E1DBBFDD8829C2A /* MessageForwardingScreenUITests.swift */; };
67160204A8D362BB7D4AD259 /* Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 693E16574C6F7F9FA1015A8C /* Search.swift */; }; 67160204A8D362BB7D4AD259 /* Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 693E16574C6F7F9FA1015A8C /* Search.swift */; };
6786C4B0936AC84D993B20BF /* NotificationSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5F06F2F09B2EDD067DC2174 /* NotificationSettingsScreen.swift */; }; 6786C4B0936AC84D993B20BF /* NotificationSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5F06F2F09B2EDD067DC2174 /* NotificationSettingsScreen.swift */; };
@ -847,7 +847,7 @@
127C8472672A5BA09EF1ACF8 /* CurrentValuePublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentValuePublisher.swift; sourceTree = "<group>"; }; 127C8472672A5BA09EF1ACF8 /* CurrentValuePublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentValuePublisher.swift; sourceTree = "<group>"; };
12EDAFB64FA5F6812D54F39A /* MigrationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationScreenViewModel.swift; sourceTree = "<group>"; }; 12EDAFB64FA5F6812D54F39A /* MigrationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationScreenViewModel.swift; sourceTree = "<group>"; };
12F1E7F9C2BE8BB751037826 /* WaitlistScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreenCoordinator.swift; sourceTree = "<group>"; }; 12F1E7F9C2BE8BB751037826 /* WaitlistScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreenCoordinator.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>"; }; 130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNTextInputNotificationResponse+Creator.swift"; sourceTree = "<group>"; };
13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; }; 13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
1423AB065857FA546444DB15 /* NotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = "<group>"; }; 1423AB065857FA546444DB15 /* NotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = "<group>"; };
@ -985,7 +985,7 @@
47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = "<group>"; }; 47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = "<group>"; };
471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineView.swift; sourceTree = "<group>"; }; 471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineView.swift; sourceTree = "<group>"; };
47873756E45B46683D97DC32 /* LegalInformationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenModels.swift; sourceTree = "<group>"; }; 47873756E45B46683D97DC32 /* LegalInformationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenModels.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>"; }; 4798B3B7A1E8AE3901CEE8C6 /* FramePreferenceKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FramePreferenceKey.swift; sourceTree = "<group>"; };
47EBB5D698CE9A25BB553A2D /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; }; 47EBB5D698CE9A25BB553A2D /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; };
47F29139BC2A804CE5E0757E /* MediaUploadPreviewScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModel.swift; sourceTree = "<group>"; }; 47F29139BC2A804CE5E0757E /* MediaUploadPreviewScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModel.swift; sourceTree = "<group>"; };
@ -1063,7 +1063,6 @@
653610CB5F9776EAAAB98155 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fr; path = fr.lproj/Localizable.stringsdict; sourceTree = "<group>"; }; 653610CB5F9776EAAAB98155 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fr; path = fr.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
65AAD845E53B0C8B5E0812C2 /* UserDiscoveryService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoveryService.swift; sourceTree = "<group>"; }; 65AAD845E53B0C8B5E0812C2 /* UserDiscoveryService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoveryService.swift; sourceTree = "<group>"; };
65C2B80DD0BF6F10BB5FA922 /* MockAuthenticationServiceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockAuthenticationServiceProxy.swift; sourceTree = "<group>"; }; 65C2B80DD0BF6F10BB5FA922 /* MockAuthenticationServiceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockAuthenticationServiceProxy.swift; sourceTree = "<group>"; };
664F77EF2A57617A00FB9B24 /* XCTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestCase.swift; sourceTree = "<group>"; };
6654859746B0BE9611459391 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = cs; path = cs.lproj/Localizable.stringsdict; sourceTree = "<group>"; }; 6654859746B0BE9611459391 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = cs; path = cs.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
667DD3A9D932D7D9EB380CAA /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sk; path = sk.lproj/Localizable.stringsdict; sourceTree = "<group>"; }; 667DD3A9D932D7D9EB380CAA /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sk; path = sk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
669F35C505ACE1110589F875 /* MediaUploadingPreprocessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadingPreprocessor.swift; sourceTree = "<group>"; }; 669F35C505ACE1110589F875 /* MediaUploadingPreprocessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadingPreprocessor.swift; sourceTree = "<group>"; };
@ -1109,6 +1108,7 @@
72F37B5DA798C9AE436F2C2C /* AttributedStringBuilderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringBuilderProtocol.swift; sourceTree = "<group>"; }; 72F37B5DA798C9AE436F2C2C /* AttributedStringBuilderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringBuilderProtocol.swift; sourceTree = "<group>"; };
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>"; };
745323FCF9AF21A117252C53 /* RoundedLabelItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedLabelItem.swift; sourceTree = "<group>"; }; 745323FCF9AF21A117252C53 /* RoundedLabelItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedLabelItem.swift; sourceTree = "<group>"; };
74611A4182DCF5F4D42696EC /* XCTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestCase.swift; sourceTree = "<group>"; };
7475C5AE20BA896930907EA8 /* AudioRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRoomTimelineItemContent.swift; sourceTree = "<group>"; }; 7475C5AE20BA896930907EA8 /* AudioRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRoomTimelineItemContent.swift; sourceTree = "<group>"; };
748AE77AC3B0A01223033B87 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; 748AE77AC3B0A01223033B87 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
74DD0855F2F76D47E5555082 /* MediaUploadPreviewScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenCoordinator.swift; sourceTree = "<group>"; }; 74DD0855F2F76D47E5555082 /* MediaUploadPreviewScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenCoordinator.swift; sourceTree = "<group>"; };
@ -1160,7 +1160,7 @@
8D55702474F279D910D2D162 /* RoomStateEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomStateEventStringBuilder.swift; sourceTree = "<group>"; }; 8D55702474F279D910D2D162 /* RoomStateEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomStateEventStringBuilder.swift; sourceTree = "<group>"; };
8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; }; 8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyle.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>"; }; 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>"; }; 8EC57A32ABC80D774CC663DB /* SettingsScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenUITests.swift; sourceTree = "<group>"; };
8F21ED7205048668BEB44A38 /* AppActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppActivityView.swift; sourceTree = "<group>"; }; 8F21ED7205048668BEB44A38 /* AppActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppActivityView.swift; sourceTree = "<group>"; };
@ -1268,7 +1268,7 @@
B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Analytics+SwiftUI.swift"; sourceTree = "<group>"; }; B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Analytics+SwiftUI.swift"; sourceTree = "<group>"; };
B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableAvatarImage.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>"; }; 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>"; }; B6311F21F911E23BE4DF51B4 /* ReadMarkerRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadMarkerRoomTimelineView.swift; sourceTree = "<group>"; };
B697816AF93DA06EC58C5D70 /* WaitlistScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreenViewModelProtocol.swift; sourceTree = "<group>"; }; B697816AF93DA06EC58C5D70 /* WaitlistScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreenViewModelProtocol.swift; sourceTree = "<group>"; };
B6E89E530A8E92EC44301CA1 /* Bundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = "<group>"; }; B6E89E530A8E92EC44301CA1 /* Bundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = "<group>"; };
@ -1350,7 +1350,7 @@
CD6B0C4639E066915B5E6463 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; }; CD6B0C4639E066915B5E6463 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
CDB3227C7A74B734924942E9 /* RoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProvider.swift; sourceTree = "<group>"; }; CDB3227C7A74B734924942E9 /* RoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProvider.swift; sourceTree = "<group>"; };
CEE0E6043EFCF6FD2A341861 /* TimelineReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReplyView.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>"; }; CF48AF076424DBC1615C74AD /* AuthenticationServiceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationServiceProxy.swift; sourceTree = "<group>"; };
D0140615D2232612C813FD6C /* EncryptedHistoryRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedHistoryRoomTimelineItem.swift; sourceTree = "<group>"; }; D0140615D2232612C813FD6C /* EncryptedHistoryRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedHistoryRoomTimelineItem.swift; sourceTree = "<group>"; };
D071F86CD47582B9196C9D16 /* UserDiscoverySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoverySection.swift; sourceTree = "<group>"; }; D071F86CD47582B9196C9D16 /* UserDiscoverySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoverySection.swift; sourceTree = "<group>"; };
@ -1420,7 +1420,7 @@
ECF79FB25E2D4BD6F50CE7C9 /* RoomMembersListScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenViewModel.swift; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; EE378083653EF0C9B5E9D580 /* EmoteRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItemContent.swift; sourceTree = "<group>"; };
@ -2377,7 +2377,7 @@
children = ( children = (
60F18AECC9D38C2B6D85F99C /* Publisher.swift */, 60F18AECC9D38C2B6D85F99C /* Publisher.swift */,
818CBE6249ED6E8FC30E8366 /* ViewModelContext.swift */, 818CBE6249ED6E8FC30E8366 /* ViewModelContext.swift */,
664F77EF2A57617A00FB9B24 /* XCTestCase.swift */, 74611A4182DCF5F4D42696EC /* XCTestCase.swift */,
); );
path = Extensions; path = Extensions;
sourceTree = "<group>"; sourceTree = "<group>";
@ -4067,7 +4067,6 @@
CC961529F9F1854BEC3272C9 /* LayoutMocks.swift in Sources */, CC961529F9F1854BEC3272C9 /* LayoutMocks.swift in Sources */,
8AC256AF0EC54658321C9241 /* LegalInformationScreenViewModelTests.swift in Sources */, 8AC256AF0EC54658321C9241 /* LegalInformationScreenViewModelTests.swift in Sources */,
0033481EE363E4914295F188 /* LocalizationTests.swift in Sources */, 0033481EE363E4914295F188 /* LocalizationTests.swift in Sources */,
664F77F02A57617A00FB9B24 /* XCTestCase.swift in Sources */,
149D1942DC005D0485FB8D93 /* LoggingTests.swift in Sources */, 149D1942DC005D0485FB8D93 /* LoggingTests.swift in Sources */,
1E59B77A0B2CE83DCC1B203C /* LoginViewModelTests.swift in Sources */, 1E59B77A0B2CE83DCC1B203C /* LoginViewModelTests.swift in Sources */,
2E43A3D221BE9587BC19C3F1 /* MatrixEntityRegexTests.swift in Sources */, 2E43A3D221BE9587BC19C3F1 /* MatrixEntityRegexTests.swift in Sources */,
@ -4121,6 +4120,7 @@
99F8DA4CCC6772EE5FE68E24 /* ViewModelContext.swift in Sources */, 99F8DA4CCC6772EE5FE68E24 /* ViewModelContext.swift in Sources */,
FB9A1DD83EF641A75ABBCE69 /* WaitlistScreenViewModelTests.swift in Sources */, FB9A1DD83EF641A75ABBCE69 /* WaitlistScreenViewModelTests.swift in Sources */,
7F02063FB3D1C3E5601471A1 /* WelcomeScreenScreenViewModelTests.swift in Sources */, 7F02063FB3D1C3E5601471A1 /* WelcomeScreenScreenViewModelTests.swift in Sources */,
3116693C5EB476E028990416 /* XCTestCase.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -21,6 +21,10 @@ enum InvitesScreenViewModelAction {
struct InvitesScreenViewState: BindableState { struct InvitesScreenViewState: BindableState {
var invites: [InvitesScreenRoomDetails] = [] var invites: [InvitesScreenRoomDetails] = []
var bindings: InvitesScreenViewStateBindings = .init() var bindings: InvitesScreenViewStateBindings = .init()
// ideally we wanted to derive this state from `invites` being `Optional.none`.
// But we needed to make it a non optional array due to a strange crash in release builds (https://github.com/vector-im/element-x-ios/pull/1120)
var isLoading = true
} }
struct InvitesScreenViewStateBindings { struct InvitesScreenViewStateBindings {

View File

@ -28,7 +28,7 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel
private let previouslySeenInvites: Set<String> private let previouslySeenInvites: Set<String>
private let actionsSubject: PassthroughSubject<InvitesScreenViewModelAction, Never> = .init() private let actionsSubject: PassthroughSubject<InvitesScreenViewModelAction, Never> = .init()
@CancellableTask private var fetchInvitersTask: Task<Void, Never>? @CancellableTask private var fetchInvitersTask: Task<Void, Never>?
var actions: AnyPublisher<InvitesScreenViewModelAction, Never> { var actions: AnyPublisher<InvitesScreenViewModelAction, Never> {
actionsSubject.eraseToAnyPublisher() actionsSubject.eraseToAnyPublisher()
} }
@ -75,62 +75,57 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel
} }
inviteSummaryProvider.roomListPublisher inviteSummaryProvider.roomListPublisher
.receive(on: DispatchQueue.main) .removeDuplicates()
.sink { [weak self] roomSummaries in .sink { [weak self] roomSummaries in
guard let self else { return } guard let self else { return }
let invites = self.buildInvites(from: roomSummaries)
appSettings.seenInvites = Set(invites.map(\.roomDetails.id))
self.state.invites = invites
fetchInviters(invites: invites) fetchInvitersTask = Task { [weak self] in
guard let self else { return }
let fullInvites = await self.buildInvites(from: roomSummaries)
guard !Task.isCancelled else { return }
self.state.invites = fullInvites
self.state.isLoading = false
self.appSettings.seenInvites = Set(fullInvites.map(\.roomDetails.id))
}
} }
.store(in: &cancellables) .store(in: &cancellables)
} }
private func buildInvites(from summaries: [RoomSummary]) -> [InvitesScreenRoomDetails] {
summaries.compactMap { summary in
guard case .filled(let details) = summary else {
return nil
}
return InvitesScreenRoomDetails(roomDetails: details, isUnread: !previouslySeenInvites.contains(details.id))
}
}
private func fetchInviters(invites: [InvitesScreenRoomDetails]) { private func buildInvites(from summaries: [RoomSummary]) async -> [InvitesScreenRoomDetails] {
fetchInvitersTask = Task { [weak self] in await Task.detached {
await withTaskGroup(of: (String, RoomMemberProxyProtocol)?.self) { group in let invites: [InvitesScreenRoomDetails] = summaries.compactMap { summary in
for invite in invites { guard case .filled(let details) = summary else {
group.addTask { [weak self] in return nil
let roomID = invite.roomDetails.id }
guard let inviter = await self?.fetchInviter(for: roomID) else { return InvitesScreenRoomDetails(roomDetails: details, isUnread: !self.previouslySeenInvites.contains(details.id))
}
// fetch the inviters...
return await withTaskGroup(of: (Int, RoomMemberProxyProtocol)?.self) { [clientProxy = self.clientProxy] group in
var invitesWithInviters = invites
for inviteIndex in 0..<invites.count {
group.addTask {
let roomID = invites[inviteIndex].roomDetails.id
guard let inviter = await clientProxy.roomForIdentifier(roomID)?.inviter() else {
return nil return nil
} }
return (roomID, inviter) return (inviteIndex, inviter)
} }
} }
for await result in group { for await result in group {
guard let self, !Task.isCancelled else { guard let (inviteIndex, inviter) = result else {
break
}
guard let (roomID, inviter) = result else {
continue continue
} }
guard let inviteIndex = self.state.invites.firstIndex(where: { $0.roomDetails.id == roomID }) else { invitesWithInviters[inviteIndex].inviter = inviter
return
}
self.state.invites[inviteIndex].inviter = inviter
} }
return invitesWithInviters
} }
} }
} .value
private func fetchInviter(for roomID: String) async -> RoomMemberProxyProtocol? {
await clientProxy.roomForIdentifier(roomID)?.inviter()
} }
private func startDeclineFlow(invite: InvitesScreenRoomDetails) { private func startDeclineFlow(invite: InvitesScreenRoomDetails) {

View File

@ -20,6 +20,23 @@ struct InvitesScreen: View {
@ObservedObject var context: InvitesScreenViewModel.Context @ObservedObject var context: InvitesScreenViewModel.Context
var body: some View { var body: some View {
Group {
if context.viewState.isLoading {
ProgressView()
} else {
mainContent
}
}
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
.navigationTitle(L10n.actionInvitesList)
.alert(item: $context.alertInfo)
.track(screen: .invites)
}
// MARK: - Private
@ViewBuilder
private var mainContent: some View {
ScrollView { ScrollView {
if !context.viewState.invites.isEmpty { if !context.viewState.invites.isEmpty {
LazyVStack(spacing: 0) { LazyVStack(spacing: 0) {
@ -34,14 +51,8 @@ struct InvitesScreen: View {
noInvitesContent noInvitesContent
} }
} }
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
.navigationTitle(L10n.actionInvitesList)
.alert(item: $context.alertInfo)
.track(screen: .invites)
} }
// MARK: - Private
private var noInvitesContent: some View { private var noInvitesContent: some View {
Text(L10n.screenInvitesEmptyList) Text(L10n.screenInvitesEmptyList)
.font(.compound.bodyLG) .font(.compound.bodyLG)

View File

@ -85,10 +85,10 @@ class RoomProxy: RoomProxyProtocol {
subscribeToBackpagination() subscribeToBackpagination()
innerTimelineProvider = RoomTimelineProvider(currentItems: result.items, innerTimelineProvider = await RoomTimelineProvider(currentItems: result.items,
updatePublisher: updatesPublisher, updatePublisher: updatesPublisher,
backPaginationStatePublisher: backPaginationStateSubject.eraseToAnyPublisher()) backPaginationStatePublisher: backPaginationStateSubject.eraseToAnyPublisher())
Task { Task {
await fetchMembers() await fetchMembers()
await updateMembers() await updateMembers()
@ -209,7 +209,7 @@ class RoomProxy: RoomProxyProtocol {
} }
func sendReadReceipt(for eventID: String) async -> Result<Void, RoomProxyError> { func sendReadReceipt(for eventID: String) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -229,7 +229,7 @@ class RoomProxy: RoomProxyProtocol {
} }
func sendMessageEventContent(_ messageContent: RoomMessageEventContent) async -> Result<Void, RoomProxyError> { func sendMessageEventContent(_ messageContent: RoomMessageEventContent) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -243,7 +243,7 @@ class RoomProxy: RoomProxyProtocol {
} }
func sendMessage(_ message: String, inReplyTo eventID: String? = nil) async -> Result<Void, RoomProxyError> { func sendMessage(_ message: String, inReplyTo eventID: String? = nil) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -266,7 +266,7 @@ class RoomProxy: RoomProxyProtocol {
} }
func toggleReaction(_ reaction: String, to eventID: String) async -> Result<Void, RoomProxyError> { func toggleReaction(_ reaction: String, to eventID: String) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -286,7 +286,7 @@ class RoomProxy: RoomProxyProtocol {
imageInfo: ImageInfo, imageInfo: ImageInfo,
progressSubject: CurrentValueSubject<Double, Never>?, progressSubject: CurrentValueSubject<Double, Never>?,
requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> { requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -311,7 +311,7 @@ class RoomProxy: RoomProxyProtocol {
videoInfo: VideoInfo, videoInfo: VideoInfo,
progressSubject: CurrentValueSubject<Double, Never>?, progressSubject: CurrentValueSubject<Double, Never>?,
requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> { requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -335,7 +335,7 @@ class RoomProxy: RoomProxyProtocol {
audioInfo: AudioInfo, audioInfo: AudioInfo,
progressSubject: CurrentValueSubject<Double, Never>?, progressSubject: CurrentValueSubject<Double, Never>?,
requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> { requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -359,7 +359,7 @@ class RoomProxy: RoomProxyProtocol {
fileInfo: FileInfo, fileInfo: FileInfo,
progressSubject: CurrentValueSubject<Double, Never>?, progressSubject: CurrentValueSubject<Double, Never>?,
requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> { requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -384,7 +384,7 @@ class RoomProxy: RoomProxyProtocol {
description: String?, description: String?,
zoomLevel: UInt8?, zoomLevel: UInt8?,
assetType: AssetType?) async -> Result<Void, RoomProxyError> { assetType: AssetType?) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -402,7 +402,7 @@ class RoomProxy: RoomProxyProtocol {
} }
func retrySend(transactionID: String) async { func retrySend(transactionID: String) async {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -413,7 +413,7 @@ class RoomProxy: RoomProxyProtocol {
} }
func cancelSend(transactionID: String) async { func cancelSend(transactionID: String) async {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -424,7 +424,7 @@ class RoomProxy: RoomProxyProtocol {
} }
func editMessage(_ newMessage: String, original eventID: String) async -> Result<Void, RoomProxyError> { func editMessage(_ newMessage: String, original eventID: String) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -442,7 +442,7 @@ class RoomProxy: RoomProxyProtocol {
} }
func redact(_ eventID: String) async -> Result<Void, RoomProxyError> { func redact(_ eventID: String) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -460,7 +460,7 @@ class RoomProxy: RoomProxyProtocol {
} }
func reportContent(_ eventID: String, reason: String?) async -> Result<Void, RoomProxyError> { func reportContent(_ eventID: String, reason: String?) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -490,7 +490,7 @@ class RoomProxy: RoomProxyProtocol {
} }
func getMember(userID: String) async -> Result<RoomMemberProxyProtocol, RoomProxyError> { func getMember(userID: String) async -> Result<RoomMemberProxyProtocol, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -506,7 +506,7 @@ class RoomProxy: RoomProxyProtocol {
} }
func ignoreUser(_ userID: String) async -> Result<Void, RoomProxyError> { func ignoreUser(_ userID: String) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
@ -528,7 +528,7 @@ class RoomProxy: RoomProxyProtocol {
} }
func leaveRoom() async -> Result<Void, RoomProxyError> { func leaveRoom() async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = await backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }

View File

@ -43,7 +43,6 @@ enum RoomProxyError: Error, Equatable {
case failedUploadingAvatar case failedUploadingAvatar
} }
@MainActor
// sourcery: AutoMockable // sourcery: AutoMockable
protocol RoomProxyProtocol { protocol RoomProxyProtocol {
var id: String { get } var id: String { get }

View File

@ -41,7 +41,7 @@ enum RoomSummaryProviderState {
} }
} }
enum RoomSummary: CustomStringConvertible { enum RoomSummary: CustomStringConvertible, Equatable {
case empty case empty
case filled(details: RoomSummaryDetails) case filled(details: RoomSummaryDetails)
case invalidated(details: RoomSummaryDetails) case invalidated(details: RoomSummaryDetails)
@ -74,6 +74,17 @@ enum RoomSummary: CustomStringConvertible {
return "\(String(describing: Self.self)): Filled(\(details.id))" return "\(String(describing: Self.self)): Filled(\(details.id))"
} }
} }
static func == (lhs: RoomSummary, rhs: RoomSummary) -> Bool {
switch (lhs, rhs) {
case (.empty, .empty):
return true
case (.filled(let lhsDetails), .filled(let rhsDetails)), (.invalidated(let lhsDetails), .invalidated(let rhsDetails)):
return lhsDetails.id == rhsDetails.id
default:
return false
}
}
} }
protocol RoomSummaryProviderProtocol { protocol RoomSummaryProviderProtocol {

View File

@ -96,6 +96,7 @@ class HomeScreenViewModelTests: XCTestCase {
func testLeaveRoomSuccess() async throws { func testLeaveRoomSuccess() async throws {
let mockRoomId = "1" let mockRoomId = "1"
var correctResult = false var correctResult = false
let expectation = expectation(description: #function)
viewModel.callback = { result in viewModel.callback = { result in
switch result { switch result {
case .roomLeft(let roomIdentifier): case .roomLeft(let roomIdentifier):
@ -103,12 +104,13 @@ class HomeScreenViewModelTests: XCTestCase {
default: default:
break break
} }
expectation.fulfill()
} }
let room: RoomProxyMock = .init(with: .init(id: mockRoomId, displayName: "Some room")) let room: RoomProxyMock = .init(with: .init(id: mockRoomId, displayName: "Some room"))
room.leaveRoomClosure = { .success(()) } room.leaveRoomClosure = { .success(()) }
clientProxy.roomForIdentifierMocks[mockRoomId] = room clientProxy.roomForIdentifierMocks[mockRoomId] = room
context.send(viewAction: .confirmLeaveRoom(roomIdentifier: mockRoomId)) context.send(viewAction: .confirmLeaveRoom(roomIdentifier: mockRoomId))
await Task.yield() await fulfillment(of: [expectation])
XCTAssertNil(context.alertInfo) XCTAssertNil(context.alertInfo)
XCTAssertTrue(correctResult) XCTAssertTrue(correctResult)
} }

View File

@ -49,7 +49,7 @@ class ReportContentScreenViewModelTests: XCTestCase {
XCTAssertNil(roomProxy.ignoreUserReceivedUserID, "The sender shouldn't have been ignored.") XCTAssertNil(roomProxy.ignoreUserReceivedUserID, "The sender shouldn't have been ignored.")
} }
func testReportIgnoringSender() async { func testReportIgnoringSender() async throws {
// Given the report content view for some content. // Given the report content view for some content.
let roomProxy = RoomProxyMock(with: .init(displayName: "test")) let roomProxy = RoomProxyMock(with: .init(displayName: "test"))
roomProxy.reportContentReasonReturnValue = .success(()) roomProxy.reportContentReasonReturnValue = .success(())
@ -61,9 +61,11 @@ class ReportContentScreenViewModelTests: XCTestCase {
// When reporting the content and also ignoring the user. // When reporting the content and also ignoring the user.
viewModel.state.bindings.reasonText = reportReason viewModel.state.bindings.reasonText = reportReason
viewModel.state.bindings.ignoreUser = true viewModel.state.bindings.ignoreUser = true
let deferred = deferFulfillment(viewModel.actions.collect(2).first())
viewModel.context.send(viewAction: .submit) viewModel.context.send(viewAction: .submit)
let result = try await deferred.fulfill()
_ = await viewModel.actions.values.first() XCTAssertEqual(result, [.submitStarted, .submitFinished])
// Then the content should be reported, and the user should be ignored. // Then the content should be reported, and the user should be ignored.
XCTAssertEqual(roomProxy.reportContentReasonCallsCount, 1, "The content should always be reported.") XCTAssertEqual(roomProxy.reportContentReasonCallsCount, 1, "The content should always be reported.")

View File

@ -68,6 +68,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
} }
func testLeaveRoomSuccess() async { func testLeaveRoomSuccess() async {
let expectation = expectation(description: #function)
roomProxyMock.leaveRoomClosure = { roomProxyMock.leaveRoomClosure = {
.success(()) .success(())
} }
@ -78,18 +79,23 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
default: default:
XCTFail("leftRoom expected") XCTFail("leftRoom expected")
} }
expectation.fulfill()
} }
context.send(viewAction: .confirmLeave) context.send(viewAction: .confirmLeave)
await Task.yield() await fulfillment(of: [expectation])
XCTAssertEqual(roomProxyMock.leaveRoomCallsCount, 1) XCTAssertEqual(roomProxyMock.leaveRoomCallsCount, 1)
} }
func testLeaveRoomError() async { func testLeaveRoomError() async {
let expectation = expectation(description: #function)
roomProxyMock.leaveRoomClosure = { roomProxyMock.leaveRoomClosure = {
.failure(.failedLeavingRoom) defer {
expectation.fulfill()
}
return .failure(.failedLeavingRoom)
} }
context.send(viewAction: .confirmLeave) context.send(viewAction: .confirmLeave)
await context.nextViewState() await fulfillment(of: [expectation])
XCTAssertEqual(roomProxyMock.leaveRoomCallsCount, 1) XCTAssertEqual(roomProxyMock.leaveRoomCallsCount, 1)
XCTAssertNotNil(context.alertInfo) XCTAssertNotNil(context.alertInfo)
} }

View File

@ -178,6 +178,7 @@ class RoomScreenViewModelTests: XCTestCase {
func testGoToUserDetailsSuccessNoDelay() async { func testGoToUserDetailsSuccessNoDelay() async {
// Setup // Setup
let expectation = expectation(description: #function)
let timelineController = MockRoomTimelineController() let timelineController = MockRoomTimelineController()
let roomProxyMock = RoomProxyMock(with: .init(displayName: "")) let roomProxyMock = RoomProxyMock(with: .init(displayName: ""))
let roomMemberMock = RoomMemberProxyMock() let roomMemberMock = RoomMemberProxyMock()
@ -197,11 +198,12 @@ class RoomScreenViewModelTests: XCTestCase {
default: default:
XCTFail("Did not received the expected action") XCTFail("Did not received the expected action")
} }
expectation.fulfill()
} }
// Test // Test
viewModel.context.send(viewAction: .tappedOnUser(userID: "bob")) viewModel.context.send(viewAction: .tappedOnUser(userID: "bob"))
await Task.yield() await fulfillment(of: [expectation])
XCTAssert(userIndicatorControllerMock.submitIndicatorDelayCallsCount == 1) XCTAssert(userIndicatorControllerMock.submitIndicatorDelayCallsCount == 1)
XCTAssert(roomProxyMock.getMemberUserIDCallsCount == 1) XCTAssert(roomProxyMock.getMemberUserIDCallsCount == 1)
XCTAssertEqual(roomProxyMock.getMemberUserIDReceivedUserID, "bob") XCTAssertEqual(roomProxyMock.getMemberUserIDReceivedUserID, "bob")
@ -288,7 +290,7 @@ class RoomScreenViewModelTests: XCTestCase {
// Test // Test
viewModel.context.send(viewAction: .retrySend(transactionID: "test retry send id")) viewModel.context.send(viewAction: .retrySend(transactionID: "test retry send id"))
await Task.yield() try? await Task.sleep(for: .microseconds(500))
XCTAssert(roomProxyMock.retrySendTransactionIDCallsCount == 1) XCTAssert(roomProxyMock.retrySendTransactionIDCallsCount == 1)
XCTAssert(roomProxyMock.retrySendTransactionIDReceivedInvocations == ["test retry send id"]) XCTAssert(roomProxyMock.retrySendTransactionIDReceivedInvocations == ["test retry send id"])
} }
@ -325,7 +327,7 @@ class RoomScreenViewModelTests: XCTestCase {
// Test // Test
viewModel.context.send(viewAction: .cancelSend(transactionID: "test cancel send id")) viewModel.context.send(viewAction: .cancelSend(transactionID: "test cancel send id"))
await Task.yield() try? await Task.sleep(for: .microseconds(500))
XCTAssert(roomProxyMock.cancelSendTransactionIDCallsCount == 1) XCTAssert(roomProxyMock.cancelSendTransactionIDCallsCount == 1)
XCTAssert(roomProxyMock.cancelSendTransactionIDReceivedInvocations == ["test cancel send id"]) XCTAssert(roomProxyMock.cancelSendTransactionIDReceivedInvocations == ["test cancel send id"])
} }