Adopt StateStoreViewModelV2 in more screens. (#4275)
* Use StateStoreViewModelV2 in AnalyticsPromptScreen.
* Use StateStoreViewModelV2 in UserProfileScreen.
* Use StateStoreViewModelV2 in MediaUploadPreviewScreen.
* Use StateStoreViewModelV2 in the Roles & Permissions screens.
* Add the asyncStream variant of deferFailure.
* Use StateStoreViewModelV2 in BlockedUsersScreen.
* Use StateStoreViewModelV2 in ManageRoomMemberSheet.
* Use StateStoreViewModelV2 in ResolveVerifiedUserSendFailureScreen.
* Use StateStoreViewModelV2 in ReportContentScreen.
* Use StateStoreViewModelV2 in ReportRoomScreen.
* Use StateStoreViewModelV2 in StaticLocationScreen.
* Use StateStoreViewModelV2 in EmojiPickerScreen.
* Use StateStoreViewModelV2 in PollFormScreen.
* Use StateStoreViewModelV2 in DeclineAndBlockScreen.
* Use StateStoreViewModelV2 in RoomDetailsScreen.
* Fix a random compilation error that just popped up 🤷♂️
* Fix expectation message.
This commit is contained in:
@@ -948,6 +948,7 @@
|
||||
B6DA66EFC13A90846B625836 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 91DE43B8815918E590912DDA /* InfoPlist.strings */; };
|
||||
B6DF6B6FA8734B70F9BF261E /* BlurHashDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */; };
|
||||
B6EC2148FA5443C9289BEEBA /* MediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17EFA1D3D09FC2F9C5E1CB2 /* MediaProvider.swift */; };
|
||||
B73E50AF1AB2EB5477E20710 /* RoomDetailsScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 166D45E1861A73B232109843 /* RoomDetailsScreenViewModelTests.swift */; };
|
||||
B773ACD8881DB18E876D950C /* WaveformSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94028A227645FA880B966211 /* WaveformSource.swift */; };
|
||||
B7888FC1E1DEF816D175C8D6 /* SecureBackupKeyBackupScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD72A9B720D75DBE60AC299F /* SecureBackupKeyBackupScreenModels.swift */; };
|
||||
B796A25F282C0A340D1B9C12 /* ImageRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2B5EDCD05D50BA9B815C66C /* ImageRoomTimelineItemContent.swift */; };
|
||||
@@ -976,6 +977,7 @@
|
||||
BB9B800C6094E34860E89DC5 /* AppLockSetupBiometricsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8CCF9A924521DECA44778C4 /* AppLockSetupBiometricsScreen.swift */; };
|
||||
BC1222EDFF0C240F14259315 /* BloomModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D152423EE6CF0ECCC84091A /* BloomModifier.swift */; };
|
||||
BC7CA1379D7C24F47B1B8B7E /* PaginationIndicatorRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E7F7A975514E850A834B29F /* PaginationIndicatorRoomTimelineView.swift */; };
|
||||
BCA5E2157CE27AB6F1D043D3 /* AsyncAlgorithms in Frameworks */ = {isa = PBXBuildFile; productRef = 5A8EF1A5F9629FCA309D4B2A /* AsyncAlgorithms */; };
|
||||
BCC864190651B3A3CF51E4DF /* MediaFileHandleProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEC1D382565A4E9CAC2F14EA /* MediaFileHandleProxy.swift */; };
|
||||
BD0BE20DBCE31253AE4490A1 /* RoomListFiltersEmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC1DDB2293A51EA4C2739351 /* RoomListFiltersEmptyStateView.swift */; };
|
||||
BD6685592716CA957D7BAAC4 /* RoomChangeRolesScreenSelectedItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D9B45D584D232CB9E5C7734 /* RoomChangeRolesScreenSelectedItem.swift */; };
|
||||
@@ -1092,7 +1094,6 @@
|
||||
D46C33F8B61B55F0C8C2D15F /* LocationRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B2AC540DE619B36832A5DB5 /* LocationRoomTimelineItem.swift */; };
|
||||
D4CB979EB4FE26AAD9F9A72B /* UserProfileScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 604A69C081B935D6A38DE6D8 /* UserProfileScreenModels.swift */; };
|
||||
D4D7CCECC6C0AAFC42E165BB /* NotificationPermissionsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9BBB18FB27F09032AD8769 /* NotificationPermissionsScreenViewModel.swift */; };
|
||||
D53B80EF02C1062E68659EDD /* ReportContentViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086C19086DD16E9B38E25954 /* ReportContentViewModelTests.swift */; };
|
||||
D55AF9B5B55FEED04771A461 /* RoomFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A008E57D52B07B78DFAD1BB /* RoomFlowCoordinator.swift */; };
|
||||
D5681C80D8281560AACE0035 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = 045253F9967A535EE5B16691 /* Label.swift */; };
|
||||
D5B1531A72387D432939D4E0 /* RoomDirectorySearchProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0516C69708D5CBDE1A8E77EC /* RoomDirectorySearchProxyProtocol.swift */; };
|
||||
@@ -1190,7 +1191,6 @@
|
||||
EA6613B29BA671F39CE1B1D2 /* ConfirmationDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = B383DCD3DCB19E00FD478A5F /* ConfirmationDialog.swift */; };
|
||||
EA78A7512AFB1E5451744EB1 /* AppRouteURLParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E461B3C8BBBFCA400B268D14 /* AppRouteURLParserTests.swift */; };
|
||||
EA8D941771E762A5D3D7FA0D /* FileMediaEventsTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430C73079A84654BF46A7FF5 /* FileMediaEventsTimelineView.swift */; };
|
||||
EA974337FA7D040E7C74FE6E /* RoomDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EFE1922F39398ABFB36DF3F /* RoomDetailsViewModelTests.swift */; };
|
||||
EAB3C1F0BC7F671ED8BDF82D /* CompletionSuggestionServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ECF11669EF253E98AA2977A /* CompletionSuggestionServiceProtocol.swift */; };
|
||||
EAC6FE2CD4F50A43068ADCD8 /* PostHog in Frameworks */ = {isa = PBXBuildFile; productRef = 4278261E147DB2DE5CFB7FC5 /* PostHog */; };
|
||||
EAF2B3E6C6AEC4AD3A8BD454 /* RoomMemberDetailsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A87D0471D438A233C2CF4A /* RoomMemberDetailsScreenViewModel.swift */; };
|
||||
@@ -1198,6 +1198,7 @@
|
||||
EB88DBD77221E2CFE463018C /* NSE.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0D8F620C8B314840D8602E3F /* NSE.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
EB9F4688006B52E69DF5358F /* BlankFormCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7F63EB1525E697CAEB002B /* BlankFormCoordinator.swift */; };
|
||||
EBE13FAB4E29738AC41BD3E5 /* InfoPlistReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A580295A56B55A856CC4084 /* InfoPlistReader.swift */; };
|
||||
EC09E502A21E4EAA8B367AB8 /* ReportContentScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30EA681527A8FE65E4C8E9A9 /* ReportContentScreenViewModelTests.swift */; };
|
||||
EC280623A42904341363EAAF /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = A20EA00CCB9DBE0FFB17DD09 /* Collections */; };
|
||||
EC3320639828BED8B3E5F2C6 /* EncryptionResetScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5875F7C0A2398E9F134B1284 /* EncryptionResetScreenViewModel.swift */; };
|
||||
ED3E91E6166E4923791ACA84 /* ResolveVerifiedUserSendFailureScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56852036214ABA9D7D305768 /* ResolveVerifiedUserSendFailureScreenViewModelProtocol.swift */; };
|
||||
@@ -1430,7 +1431,6 @@
|
||||
0825EAFD47332DD459DE893F /* SessionDirectoriesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionDirectoriesTests.swift; sourceTree = "<group>"; };
|
||||
08283301736A6FE9D558B2CB /* AppLockScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
0833F51229E166BCA141D004 /* RoomRolesAndPermissionsFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomRolesAndPermissionsFlowCoordinator.swift; sourceTree = "<group>"; };
|
||||
086C19086DD16E9B38E25954 /* ReportContentViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportContentViewModelTests.swift; sourceTree = "<group>"; };
|
||||
099F2D36C141D845A445B1E6 /* EmojiProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiProviderTests.swift; sourceTree = "<group>"; };
|
||||
0A3E77399BD262D301451BF2 /* RoomDetailsEditScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsEditScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
0A459AE4B6566B2FA99E86B2 /* TimelineItemBubbledStylerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemBubbledStylerView.swift; sourceTree = "<group>"; };
|
||||
@@ -1497,6 +1497,7 @@
|
||||
15A657D96779D1DEB8EF1327 /* CreateRoomViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomViewModel.swift; sourceTree = "<group>"; };
|
||||
161CD412E75F4086F422AE39 /* SessionVerificationScreenStateMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenStateMachine.swift; sourceTree = "<group>"; };
|
||||
1627F2D56477BD331F6D732C /* RoomHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomHeaderView.swift; sourceTree = "<group>"; };
|
||||
166D45E1861A73B232109843 /* RoomDetailsScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
16D09C79746BDCD9173EB3A7 /* RoomDetailsEditScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsEditScreenModels.swift; sourceTree = "<group>"; };
|
||||
16D353E10A64172D863769BF /* TombstonedAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TombstonedAvatarImage.swift; sourceTree = "<group>"; };
|
||||
1715E3D7F53C0748AA50C91C /* PostHogAnalyticsClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostHogAnalyticsClient.swift; sourceTree = "<group>"; };
|
||||
@@ -1630,7 +1631,6 @@
|
||||
2DB0E533508094156D8024C3 /* TimelineStyler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyler.swift; sourceTree = "<group>"; };
|
||||
2E11E7C396ED06A154CF6DF3 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/SAS.strings; sourceTree = "<group>"; };
|
||||
2E88534A39781D76487D59DF /* SecureBackupKeyBackupScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupKeyBackupScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
2EFE1922F39398ABFB36DF3F /* RoomDetailsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsViewModelTests.swift; sourceTree = "<group>"; };
|
||||
2F06F70B9C433BAD4BC6B9F5 /* EncryptedRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
2F36C5D9B37E50915ECBD3EE /* RoomMemberProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberProxy.swift; sourceTree = "<group>"; };
|
||||
2F926D08EB3D622A480BCA71 /* TimelineEventContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineEventContent.swift; sourceTree = "<group>"; };
|
||||
@@ -1640,6 +1640,7 @@
|
||||
307702DD66E7DDCDD9214784 /* IdentityConfirmedScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmedScreen.swift; sourceTree = "<group>"; };
|
||||
30856520F3263D0E195710D7 /* TimelineMediaPreviewFileExportPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMediaPreviewFileExportPicker.swift; sourceTree = "<group>"; };
|
||||
309AD8BAE6437C31BA7157BF /* ElementCallWidgetDriver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementCallWidgetDriver.swift; sourceTree = "<group>"; };
|
||||
30EA681527A8FE65E4C8E9A9 /* ReportContentScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportContentScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
30ED584467DB380E3CEFB1DB /* NotificationManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManagerTests.swift; sourceTree = "<group>"; };
|
||||
314F1C79850BE46E8ABEAFCB /* ReadReceipt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadReceipt.swift; sourceTree = "<group>"; };
|
||||
31A6314FDC51DA25712D9A81 /* PillContextTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillContextTests.swift; sourceTree = "<group>"; };
|
||||
@@ -2668,6 +2669,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7FF27DA70D833CFC5724EFC5 /* MatrixRustSDK in Frameworks */,
|
||||
BCA5E2157CE27AB6F1D043D3 /* AsyncAlgorithms in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -4363,14 +4365,14 @@
|
||||
6FA38E813BE14149F173F461 /* PinnedEventsBannerStateTests.swift */,
|
||||
347D708104CCEF771428C9A3 /* PollFormScreenViewModelTests.swift */,
|
||||
25E7E9B7FEAB6169D960C206 /* QRCodeLoginScreenViewModelTests.swift */,
|
||||
086C19086DD16E9B38E25954 /* ReportContentViewModelTests.swift */,
|
||||
30EA681527A8FE65E4C8E9A9 /* ReportContentScreenViewModelTests.swift */,
|
||||
0C3E9684DCE6B66BD0B5DF67 /* ReportRoomScreenViewModelTests.swift */,
|
||||
57084488B03BDB33C7B7CA0E /* ResolveVerifiedUserSendFailureScreenViewModelTests.swift */,
|
||||
A7978C9EFBDD7DE39BD86726 /* RestorationTokenTests.swift */,
|
||||
41D041A857614A9AE13C7795 /* RoomChangePermissionsScreenViewModelTests.swift */,
|
||||
8F841F219ACDFC1D3F42FEFB /* RoomChangeRolesScreenViewModelTests.swift */,
|
||||
00E5B2CBEF8F96424F095508 /* RoomDetailsEditScreenViewModelTests.swift */,
|
||||
2EFE1922F39398ABFB36DF3F /* RoomDetailsViewModelTests.swift */,
|
||||
166D45E1861A73B232109843 /* RoomDetailsScreenViewModelTests.swift */,
|
||||
EE6BFF453838CF6C3982C5A3 /* RoomDirectorySearchScreenScreenViewModelTests.swift */,
|
||||
6AE5800184E93CD5E02C6543 /* RoomEventStringBuilderTests.swift */,
|
||||
4FCB2126C091EEF2454B4D56 /* RoomFlowCoordinatorTests.swift */,
|
||||
@@ -6258,6 +6260,7 @@
|
||||
name = UnitTests;
|
||||
packageProductDependencies = (
|
||||
C07EA60CAB296D7726210F5B /* MatrixRustSDK */,
|
||||
5A8EF1A5F9629FCA309D4B2A /* AsyncAlgorithms */,
|
||||
);
|
||||
productName = UnitTests;
|
||||
productReference = AAC9344689121887B74877AF /* UnitTests.xctest */;
|
||||
@@ -6479,6 +6482,7 @@
|
||||
packageReferences = (
|
||||
E025F19D013D9BA6C58B37F4 /* XCRemoteSwiftPackageReference "swift-algorithms" */,
|
||||
AC3475112CA40C2C6E78D1EB /* XCRemoteSwiftPackageReference "matrix-analytics-events" */,
|
||||
4A8D3ABF18EABB8066BBD46E /* XCRemoteSwiftPackageReference "swift-async-algorithms" */,
|
||||
F76A08D0EA29A07A54F4EB4D /* XCRemoteSwiftPackageReference "swift-collections" */,
|
||||
F71C70A4404CC6D9C4AF35F2 /* XCRemoteSwiftPackageReference "compound-ios" */,
|
||||
4C34425923978C97409A3EF2 /* XCRemoteSwiftPackageReference "DSWaveformImage" */,
|
||||
@@ -6887,14 +6891,14 @@
|
||||
FF7E8ECC8E7E1D1851517536 /* PollFormScreenViewModelTests.swift in Sources */,
|
||||
E3EBC3BF7CE3960B41757BAA /* Publisher.swift in Sources */,
|
||||
BDC4EB54CC3036730475CB8B /* QRCodeLoginScreenViewModelTests.swift in Sources */,
|
||||
D53B80EF02C1062E68659EDD /* ReportContentViewModelTests.swift in Sources */,
|
||||
EC09E502A21E4EAA8B367AB8 /* ReportContentScreenViewModelTests.swift in Sources */,
|
||||
513AF15E0E84711B80D04B1B /* ReportRoomScreenViewModelTests.swift in Sources */,
|
||||
09D3D7D115318CAD131B4FE7 /* ResolveVerifiedUserSendFailureScreenViewModelTests.swift in Sources */,
|
||||
C5627BCC3EBBB96A943B6D93 /* RestorationTokenTests.swift in Sources */,
|
||||
9B03943616A1147539DF7F08 /* RoomChangePermissionsScreenViewModelTests.swift in Sources */,
|
||||
D2825E013A8ECFB66D9A1DE6 /* RoomChangeRolesScreenViewModelTests.swift in Sources */,
|
||||
9DD84E014ADFB2DD813022D5 /* RoomDetailsEditScreenViewModelTests.swift in Sources */,
|
||||
EA974337FA7D040E7C74FE6E /* RoomDetailsViewModelTests.swift in Sources */,
|
||||
B73E50AF1AB2EB5477E20710 /* RoomDetailsScreenViewModelTests.swift in Sources */,
|
||||
5B7D24A318AFF75AD611A026 /* RoomDirectorySearchScreenScreenViewModelTests.swift in Sources */,
|
||||
E591742E509A2A009BF25F9D /* RoomEventStringBuilderTests.swift in Sources */,
|
||||
095D3906CF2F940C2D2D17CC /* RoomFlowCoordinatorTests.swift in Sources */,
|
||||
@@ -8718,6 +8722,14 @@
|
||||
minimumVersion = 1.2.0;
|
||||
};
|
||||
};
|
||||
4A8D3ABF18EABB8066BBD46E /* XCRemoteSwiftPackageReference "swift-async-algorithms" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/apple/swift-async-algorithms";
|
||||
requirement = {
|
||||
kind = upToNextMinorVersion;
|
||||
minimumVersion = 1.0.0;
|
||||
};
|
||||
};
|
||||
4BDA7F6042968E8422470F3F /* XCRemoteSwiftPackageReference "LoremSwiftum" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/lukaskubanek/LoremSwiftum";
|
||||
@@ -9032,6 +9044,11 @@
|
||||
package = C13F55E4518415CB4C278E73 /* XCRemoteSwiftPackageReference "DTCoreText" */;
|
||||
productName = DTCoreText;
|
||||
};
|
||||
5A8EF1A5F9629FCA309D4B2A /* AsyncAlgorithms */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 4A8D3ABF18EABB8066BBD46E /* XCRemoteSwiftPackageReference "swift-async-algorithms" */;
|
||||
productName = AsyncAlgorithms;
|
||||
};
|
||||
6647C55D93508C7CE9D954A5 /* MatrixRustSDK */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 6FC4820D8D4559CEECA064D7 /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"originHash" : "cb4b4c28930e04929217c9570b7f82a1dc8e3dc51e3f956f11584dbae9bac079",
|
||||
"originHash" : "f573b0754209479f46b77206f67033b0073bb2df38ede53b3289703615c5a48f",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "compound-design-tokens",
|
||||
@@ -216,6 +216,15 @@
|
||||
"version" : "1.2.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-async-algorithms",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-async-algorithms",
|
||||
"state" : {
|
||||
"revision" : "042e1c4d9d19748c9c228f8d4ebc97bb1e339b0b",
|
||||
"version" : "1.0.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-collections",
|
||||
"kind" : "remoteSourceControl",
|
||||
|
||||
@@ -158,6 +158,36 @@ extension XCTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/// XCTest utility that assists in subscribing to an async stream and deferring the failure for a particular value until some other actions have been performed.
|
||||
/// - Parameters:
|
||||
/// - asyncStream: The stream to wait on.
|
||||
/// - timeout: A timeout after which we give up.
|
||||
/// - message: An optional custom expectation message
|
||||
/// - until: callback that evaluates outputs until some condition is reached
|
||||
/// - Returns: The deferred fulfilment to be executed after some actions. The stream's result is not returned from this fulfilment.
|
||||
func deferFailure<Value>(_ asyncStream: AsyncStream<Value>,
|
||||
timeout: TimeInterval,
|
||||
message: String? = nil,
|
||||
until condition: @escaping (Value) -> Bool) -> DeferredFulfillment<Void> {
|
||||
let expectation = expectation(description: message ?? "Awaiting stream")
|
||||
expectation.isInverted = true
|
||||
var hasFulfilled = false
|
||||
|
||||
let task = Task {
|
||||
for await value in asyncStream {
|
||||
if condition(value), !hasFulfilled {
|
||||
expectation.fulfill()
|
||||
hasFulfilled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DeferredFulfillment<Void> {
|
||||
await self.fulfillment(of: [expectation], timeout: timeout)
|
||||
task.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
struct DeferredFulfillment<T> {
|
||||
let closure: () async throws -> T
|
||||
@discardableResult func fulfill() async throws -> T {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias BlockedUsersScreenViewModelType = StateStoreViewModel<BlockedUsersScreenViewState, BlockedUsersScreenViewAction>
|
||||
typealias BlockedUsersScreenViewModelType = StateStoreViewModelV2<BlockedUsersScreenViewState, BlockedUsersScreenViewAction>
|
||||
|
||||
class BlockedUsersScreenViewModel: BlockedUsersScreenViewModelType, BlockedUsersScreenViewModelProtocol {
|
||||
let hideProfiles: Bool
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct BlockedUsersScreen: View {
|
||||
@ObservedObject var context: BlockedUsersScreenViewModel.Context
|
||||
@Bindable var context: BlockedUsersScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
content
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias PollFormScreenViewModelType = StateStoreViewModel<PollFormScreenViewState, PollFormScreenViewAction>
|
||||
typealias PollFormScreenViewModelType = StateStoreViewModelV2<PollFormScreenViewState, PollFormScreenViewAction>
|
||||
|
||||
class PollFormScreenViewModel: PollFormScreenViewModelType, PollFormScreenViewModelProtocol {
|
||||
private var actionsSubject: PassthroughSubject<PollFormScreenViewModelAction, Never> = .init()
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct PollFormScreen: View {
|
||||
@ObservedObject var context: PollFormScreenViewModel.Context
|
||||
@Bindable var context: PollFormScreenViewModel.Context
|
||||
@FocusState var focus: Focus?
|
||||
|
||||
enum Focus: Hashable {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias DeclineAndBlockScreenViewModelType = StateStoreViewModel<DeclineAndBlockScreenViewState, DeclineAndBlockScreenViewAction>
|
||||
typealias DeclineAndBlockScreenViewModelType = StateStoreViewModelV2<DeclineAndBlockScreenViewState, DeclineAndBlockScreenViewAction>
|
||||
|
||||
class DeclineAndBlockScreenViewModel: DeclineAndBlockScreenViewModelType, DeclineAndBlockScreenViewModelProtocol {
|
||||
let userID: String
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct DeclineAndBlockScreen: View {
|
||||
@ObservedObject var context: DeclineAndBlockScreenViewModel.Context
|
||||
@Bindable var context: DeclineAndBlockScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias EmojiPickerScreenViewModelType = StateStoreViewModel<EmojiPickerScreenViewState, EmojiPickerScreenViewAction>
|
||||
typealias EmojiPickerScreenViewModelType = StateStoreViewModelV2<EmojiPickerScreenViewState, EmojiPickerScreenViewAction>
|
||||
|
||||
class EmojiPickerScreenViewModel: EmojiPickerScreenViewModelType, EmojiPickerScreenViewModelProtocol {
|
||||
private var actionsSubject: PassthroughSubject<EmojiPickerScreenViewModelAction, Never> = .init()
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct EmojiPickerScreen: View {
|
||||
@ObservedObject var context: EmojiPickerScreenViewModel.Context
|
||||
let context: EmojiPickerScreenViewModel.Context
|
||||
|
||||
var selectedEmojis = Set<String>()
|
||||
@State var searchString = ""
|
||||
@@ -106,9 +106,7 @@ struct EmojiPickerScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static var previews: some View {
|
||||
EmojiPickerScreen(context: viewModel.context, selectedEmojis: ["😀", "😄"])
|
||||
.previewDisplayName("Screen")
|
||||
.snapshotPreferences(expect: viewModel.context.$viewState.map { state in
|
||||
!state.categories.isEmpty
|
||||
})
|
||||
.snapshotPreferences(expect: viewModel.context.observe(\.viewState.categories).map { !$0.isEmpty }.eraseToStream())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
typealias StaticLocationScreenViewModelType = StateStoreViewModel<StaticLocationScreenViewState, StaticLocationScreenViewAction>
|
||||
typealias StaticLocationScreenViewModelType = StateStoreViewModelV2<StaticLocationScreenViewState, StaticLocationScreenViewAction>
|
||||
|
||||
class StaticLocationScreenViewModel: StaticLocationScreenViewModelType, StaticLocationScreenViewModelProtocol {
|
||||
private let actionsSubject: PassthroughSubject<StaticLocationScreenViewModelAction, Never> = .init()
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct StaticLocationScreen: View {
|
||||
@ObservedObject var context: StaticLocationScreenViewModel.Context
|
||||
@Bindable var context: StaticLocationScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import Combine
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
typealias ManageRoomMemberSheetViewModelType = StateStoreViewModel<ManageRoomMemberSheetViewState, ManageRoomMemberSheetViewAction>
|
||||
typealias ManageRoomMemberSheetViewModelType = StateStoreViewModelV2<ManageRoomMemberSheetViewState, ManageRoomMemberSheetViewAction>
|
||||
|
||||
class ManageRoomMemberSheetViewModel: ManageRoomMemberSheetViewModelType, ManageRoomMemberSheetViewModelProtocol {
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct ManageRoomMemberSheetView: View {
|
||||
@ObservedObject var context: ManageRoomMemberSheetViewModelType.Context
|
||||
@Bindable var context: ManageRoomMemberSheetViewModelType.Context
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
||||
@@ -9,7 +9,7 @@ import Combine
|
||||
import MatrixRustSDK
|
||||
import SwiftUI
|
||||
|
||||
typealias MediaUploadPreviewScreenViewModelType = StateStoreViewModel<MediaUploadPreviewScreenViewState, MediaUploadPreviewScreenViewAction>
|
||||
typealias MediaUploadPreviewScreenViewModelType = StateStoreViewModelV2<MediaUploadPreviewScreenViewState, MediaUploadPreviewScreenViewAction>
|
||||
|
||||
class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType, MediaUploadPreviewScreenViewModelProtocol {
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
@@ -13,7 +13,7 @@ import SwiftUI
|
||||
struct MediaUploadPreviewScreen: View {
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
|
||||
@ObservedObject var context: MediaUploadPreviewScreenViewModel.Context
|
||||
@Bindable var context: MediaUploadPreviewScreenViewModel.Context
|
||||
|
||||
@State private var captionWarningFrame: CGRect = .zero
|
||||
@FocusState private var isComposerFocussed
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias AnalyticsPromptScreenViewModelType = StateStoreViewModel<AnalyticsPromptScreenViewState, AnalyticsPromptScreenViewAction>
|
||||
typealias AnalyticsPromptScreenViewModelType = StateStoreViewModelV2<AnalyticsPromptScreenViewState, AnalyticsPromptScreenViewAction>
|
||||
|
||||
class AnalyticsPromptScreenViewModel: AnalyticsPromptScreenViewModelType, AnalyticsPromptScreenViewModelProtocol {
|
||||
private var actionsSubject: PassthroughSubject<AnalyticsPromptScreenViewModelAction, Never> = .init()
|
||||
|
||||
@@ -10,7 +10,7 @@ import SwiftUI
|
||||
|
||||
/// A prompt that asks the user whether they would like to enable Analytics or not.
|
||||
struct AnalyticsPromptScreen: View {
|
||||
@ObservedObject var context: AnalyticsPromptScreenViewModel.Context
|
||||
let context: AnalyticsPromptScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
FullscreenDialog(topPadding: UIConstants.startScreenBreakerScreenTopPadding, background: .gradient) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias ReportContentScreenViewModelType = StateStoreViewModel<ReportContentScreenViewState, ReportContentScreenViewAction>
|
||||
typealias ReportContentScreenViewModelType = StateStoreViewModelV2<ReportContentScreenViewState, ReportContentScreenViewAction>
|
||||
|
||||
class ReportContentScreenViewModel: ReportContentScreenViewModelType, ReportContentScreenViewModelProtocol {
|
||||
private let eventID: String
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct ReportContentScreen: View {
|
||||
@ObservedObject var context: ReportContentScreenViewModel.Context
|
||||
@Bindable var context: ReportContentScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias ReportRoomScreenViewModelType = StateStoreViewModel<ReportRoomScreenViewState, ReportRoomScreenViewAction>
|
||||
typealias ReportRoomScreenViewModelType = StateStoreViewModelV2<ReportRoomScreenViewState, ReportRoomScreenViewAction>
|
||||
|
||||
class ReportRoomScreenViewModel: ReportRoomScreenViewModelType, ReportRoomScreenViewModelProtocol {
|
||||
let roomProxy: JoinedRoomProxyProtocol
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct ReportRoomScreen: View {
|
||||
@ObservedObject var context: ReportRoomScreenViewModel.Context
|
||||
@Bindable var context: ReportRoomScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias ResolveVerifiedUserSendFailureScreenViewModelType = StateStoreViewModel<ResolveVerifiedUserSendFailureScreenViewState, ResolveVerifiedUserSendFailureScreenViewAction>
|
||||
typealias ResolveVerifiedUserSendFailureScreenViewModelType = StateStoreViewModelV2<ResolveVerifiedUserSendFailureScreenViewState, ResolveVerifiedUserSendFailureScreenViewAction>
|
||||
|
||||
class ResolveVerifiedUserSendFailureScreenViewModel: ResolveVerifiedUserSendFailureScreenViewModelType, ResolveVerifiedUserSendFailureScreenViewModelProtocol {
|
||||
private let iterator: VerifiedUserSendFailureIterator
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct ResolveVerifiedUserSendFailureScreen: View {
|
||||
@ObservedObject var context: ResolveVerifiedUserSendFailureScreenViewModel.Context
|
||||
let context: ResolveVerifiedUserSendFailureScreenViewModel.Context
|
||||
@State private var sheetFrame: CGRect = .zero
|
||||
|
||||
var body: some View {
|
||||
|
||||
@@ -9,7 +9,7 @@ import Combine
|
||||
import MatrixRustSDK
|
||||
import SwiftUI
|
||||
|
||||
typealias RoomChangePermissionsScreenViewModelType = StateStoreViewModel<RoomChangePermissionsScreenViewState, RoomChangePermissionsScreenViewAction>
|
||||
typealias RoomChangePermissionsScreenViewModelType = StateStoreViewModelV2<RoomChangePermissionsScreenViewState, RoomChangePermissionsScreenViewAction>
|
||||
|
||||
class RoomChangePermissionsScreenViewModel: RoomChangePermissionsScreenViewModelType, RoomChangePermissionsScreenViewModelProtocol {
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct RoomChangePermissionsScreen: View {
|
||||
@ObservedObject var context: RoomChangePermissionsScreenViewModel.Context
|
||||
@Bindable var context: RoomChangePermissionsScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias RoomChangeRolesScreenViewModelType = StateStoreViewModel<RoomChangeRolesScreenViewState, RoomChangeRolesScreenViewAction>
|
||||
typealias RoomChangeRolesScreenViewModelType = StateStoreViewModelV2<RoomChangeRolesScreenViewState, RoomChangeRolesScreenViewAction>
|
||||
|
||||
class RoomChangeRolesScreenViewModel: RoomChangeRolesScreenViewModelType, RoomChangeRolesScreenViewModelProtocol {
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct RoomChangeRolesScreen: View {
|
||||
@ObservedObject var context: RoomChangeRolesScreenViewModel.Context
|
||||
@Bindable var context: RoomChangeRolesScreenViewModel.Context
|
||||
|
||||
var showTopSection: Bool { !context.viewState.membersWithRole.isEmpty }
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ struct RoomChangeRolesScreenSection: View {
|
||||
let title: String
|
||||
var isAdministratorsSection = false
|
||||
|
||||
@ObservedObject var context: RoomChangeRolesScreenViewModel.Context
|
||||
let context: RoomChangeRolesScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
if !members.isEmpty {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias RoomDetailsScreenViewModelType = StateStoreViewModel<RoomDetailsScreenViewState, RoomDetailsScreenViewAction>
|
||||
typealias RoomDetailsScreenViewModelType = StateStoreViewModelV2<RoomDetailsScreenViewState, RoomDetailsScreenViewAction>
|
||||
|
||||
class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScreenViewModelProtocol {
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct RoomDetailsScreen: View {
|
||||
@ObservedObject var context: RoomDetailsScreenViewModel.Context
|
||||
@Bindable var context: RoomDetailsScreenViewModel.Context
|
||||
|
||||
@State private var isTopicExpanded = false
|
||||
|
||||
@@ -338,33 +338,23 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
||||
|
||||
static var previews: some View {
|
||||
RoomDetailsScreen(context: genericRoomViewModel.context)
|
||||
.snapshotPreferences(expect: genericRoomViewModel.context.$viewState.map { state in
|
||||
state.permalink != nil
|
||||
})
|
||||
.snapshotPreferences(expect: genericRoomViewModel.context.observe(\.viewState.permalink).map { $0 != nil }.eraseToStream())
|
||||
.previewDisplayName("Generic Room")
|
||||
|
||||
RoomDetailsScreen(context: simpleRoomViewModel.context)
|
||||
.snapshotPreferences(expect: simpleRoomViewModel.context.$viewState.map { state in
|
||||
state.permalink != nil
|
||||
})
|
||||
.snapshotPreferences(expect: simpleRoomViewModel.context.observe(\.viewState.permalink).map { $0 != nil }.eraseToStream())
|
||||
.previewDisplayName("Simple Room")
|
||||
|
||||
RoomDetailsScreen(context: dmRoomViewModel.context)
|
||||
.snapshotPreferences(expect: dmRoomViewModel.context.$viewState.map { state in
|
||||
state.accountOwner != nil
|
||||
})
|
||||
.snapshotPreferences(expect: dmRoomViewModel.context.observe(\.viewState.accountOwner).map { $0 != nil }.eraseToStream())
|
||||
.previewDisplayName("DM Room")
|
||||
|
||||
RoomDetailsScreen(context: dmRoomVerifiedViewModel.context)
|
||||
.snapshotPreferences(expect: dmRoomVerifiedViewModel.context.$viewState.map { state in
|
||||
state.dmRecipientInfo?.verificationState == .verified
|
||||
})
|
||||
.snapshotPreferences(expect: dmRoomVerifiedViewModel.context.observe(\.viewState.dmRecipientInfo?.verificationState).map { $0 == .verified }.eraseToStream())
|
||||
.previewDisplayName("DM Room Verified")
|
||||
|
||||
RoomDetailsScreen(context: dmRoomVerificationViolationViewModel.context)
|
||||
.snapshotPreferences(expect: dmRoomVerificationViolationViewModel.context.$viewState.map { state in
|
||||
state.accountOwner != nil
|
||||
})
|
||||
.snapshotPreferences(expect: dmRoomVerificationViolationViewModel.context.observe(\.viewState.accountOwner).map { $0 != nil }.eraseToStream())
|
||||
.previewDisplayName("DM Room Verification Violation")
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias RoomRolesAndPermissionsScreenViewModelType = StateStoreViewModel<RoomRolesAndPermissionsScreenViewState, RoomRolesAndPermissionsScreenViewAction>
|
||||
typealias RoomRolesAndPermissionsScreenViewModelType = StateStoreViewModelV2<RoomRolesAndPermissionsScreenViewState, RoomRolesAndPermissionsScreenViewAction>
|
||||
|
||||
class RoomRolesAndPermissionsScreenViewModel: RoomRolesAndPermissionsScreenViewModelType, RoomRolesAndPermissionsScreenViewModelProtocol {
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct RoomRolesAndPermissionsScreen: View {
|
||||
@ObservedObject var context: RoomRolesAndPermissionsScreenViewModel.Context
|
||||
@Bindable var context: RoomRolesAndPermissionsScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
||||
@@ -9,7 +9,7 @@ import Combine
|
||||
import MatrixRustSDK
|
||||
import SwiftUI
|
||||
|
||||
typealias UserProfileScreenViewModelType = StateStoreViewModel<UserProfileScreenViewState, UserProfileScreenViewAction>
|
||||
typealias UserProfileScreenViewModelType = StateStoreViewModelV2<UserProfileScreenViewState, UserProfileScreenViewAction>
|
||||
|
||||
class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScreenViewModelProtocol {
|
||||
private let clientProxy: ClientProxyProtocol
|
||||
|
||||
@@ -9,7 +9,7 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct UserProfileScreen: View {
|
||||
@ObservedObject var context: UserProfileScreenViewModel.Context
|
||||
@Bindable var context: UserProfileScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
@@ -103,21 +103,15 @@ struct UserProfileScreen_Previews: PreviewProvider, TestablePreview {
|
||||
|
||||
static var previews: some View {
|
||||
UserProfileScreen(context: verifiedUserViewModel.context)
|
||||
.snapshotPreferences(expect: verifiedUserViewModel.context.$viewState.map { state in
|
||||
state.isVerified != nil
|
||||
})
|
||||
.snapshotPreferences(expect: verifiedUserViewModel.context.observe(\.viewState.isVerified).map { $0 != nil }.eraseToStream())
|
||||
.previewDisplayName("Verified User")
|
||||
|
||||
UserProfileScreen(context: otherUserViewModel.context)
|
||||
.snapshotPreferences(expect: otherUserViewModel.context.$viewState.map { state in
|
||||
state.isVerified != nil
|
||||
})
|
||||
.snapshotPreferences(expect: otherUserViewModel.context.observe(\.viewState.isVerified).map { $0 != nil }.eraseToStream())
|
||||
.previewDisplayName("Other User")
|
||||
|
||||
UserProfileScreen(context: accountOwnerViewModel.context)
|
||||
.snapshotPreferences(expect: accountOwnerViewModel.context.$viewState.map { state in
|
||||
state.isVerified != nil
|
||||
})
|
||||
.snapshotPreferences(expect: accountOwnerViewModel.context.observe(\.viewState.isVerified).map { $0 != nil }.eraseToStream())
|
||||
.previewDisplayName("Account Owner")
|
||||
}
|
||||
|
||||
|
||||
@@ -170,6 +170,14 @@
|
||||
<key>Type</key>
|
||||
<string>PSChildPaneSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>File</key>
|
||||
<string>Packages/swift-async-algorithms</string>
|
||||
<key>Title</key>
|
||||
<string>swift-async-algorithms</string>
|
||||
<key>Type</key>
|
||||
<string>PSChildPaneSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>File</key>
|
||||
<string>Packages/swift-collections</string>
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreferenceSpecifiers</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string> Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
|
||||
## Runtime Library Exception to the Apache 2.0 License: ##
|
||||
|
||||
|
||||
As an exception, if you use this Software to compile your source code and
|
||||
portions of this Software are embedded into the binary product as a result,
|
||||
you may redistribute such product without providing attribution as would
|
||||
otherwise be required by Sections 4(a), 4(b) and 4(d) of the License.
|
||||
</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -20,7 +20,7 @@ class BlockedUsersScreenViewModelTests: XCTestCase {
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
|
||||
let deferred = deferFailure(viewModel.context.$viewState, timeout: 1) { $0.blockedUsers.contains { $0.displayName != nil } }
|
||||
let deferred = deferFailure(viewModel.context.observe(\.viewState.blockedUsers), timeout: 1) { $0.contains { $0.displayName != nil } }
|
||||
try await deferred.fulfill()
|
||||
|
||||
XCTAssertFalse(viewModel.context.viewState.blockedUsers.isEmpty)
|
||||
@@ -35,7 +35,7 @@ class BlockedUsersScreenViewModelTests: XCTestCase {
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
|
||||
let deferred = deferFulfillment(viewModel.context.$viewState) { $0.blockedUsers.contains { $0.displayName != nil } }
|
||||
let deferred = deferFulfillment(viewModel.context.observe(\.viewState.blockedUsers)) { $0.contains { $0.displayName != nil } }
|
||||
try await deferred.fulfill()
|
||||
|
||||
XCTAssertFalse(viewModel.context.viewState.blockedUsers.isEmpty)
|
||||
|
||||
@@ -34,7 +34,7 @@ class ManageRoomMemberSheetViewModelTests: XCTestCase {
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
mediaProvider: MediaProviderMock(configuration: .init()))
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { $0.bindings.alertInfo != nil }
|
||||
let deferred = deferFulfillment(context.observe(\.viewState.bindings.alertInfo)) { $0 != nil }
|
||||
let deferredAction = deferFulfillment(viewModel.actions) { action in
|
||||
action == .dismiss(shouldShowDetails: false)
|
||||
}
|
||||
@@ -65,7 +65,7 @@ class ManageRoomMemberSheetViewModelTests: XCTestCase {
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
mediaProvider: MediaProviderMock(configuration: .init()))
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { $0.bindings.alertInfo != nil }
|
||||
let deferred = deferFulfillment(context.observe(\.viewState.bindings.alertInfo)) { $0 != nil }
|
||||
context.send(viewAction: .ban)
|
||||
try await deferred.fulfill()
|
||||
|
||||
|
||||
@@ -90,9 +90,7 @@ class ReportRoomScreenViewModelTests: XCTestCase {
|
||||
return .failure(.eventNotFound)
|
||||
}
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.bindings.alert != nil
|
||||
}
|
||||
let deferred = deferFulfillment(context.observe(\.viewState.bindings.alert)) { $0 != nil }
|
||||
|
||||
context.reason = reason
|
||||
context.shouldLeaveRoom = true
|
||||
|
||||
@@ -26,7 +26,7 @@ class ResolveVerifiedUserSendFailureScreenViewModelTests: XCTestCase {
|
||||
func testMultipleUnsignedDevices() async throws {
|
||||
// Given a failure where a multiple users have unverified devices.
|
||||
let userIDs = ["@alice:matrix.org", "@bob:matrix.org", "@charlie:matrix.org"]
|
||||
let devices = Dictionary(uniqueKeysWithValues: userIDs.map { (key: $0, value: ["DEVICE1, DEVICE2"]) })
|
||||
let devices = Dictionary(uniqueKeysWithValues: userIDs.map { ($0, ["DEVICE1, DEVICE2"]) })
|
||||
viewModel = makeViewModel(with: .hasUnsignedDevice(devices: devices))
|
||||
|
||||
try await verifyResolving(userIDs: userIDs, assertStrings: false)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import AsyncAlgorithms
|
||||
import Combine
|
||||
import MatrixRustSDK
|
||||
import SwiftUI
|
||||
@@ -48,9 +49,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.bindings.leaveRoomAlertItem != nil
|
||||
}
|
||||
let deferred = deferFulfillment(context.observe(\.viewState.bindings.leaveRoomAlertItem)) { $0 != nil }
|
||||
|
||||
context.send(viewAction: .processTapLeave)
|
||||
try await deferred.fulfill()
|
||||
@@ -71,9 +70,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.bindings.leaveRoomAlertItem != nil
|
||||
}
|
||||
let deferred = deferFulfillment(context.observe(\.viewState.bindings.leaveRoomAlertItem)) { $0 != nil }
|
||||
|
||||
context.send(viewAction: .processTapLeave)
|
||||
|
||||
@@ -150,9 +147,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
let deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.dmRecipientInfo != nil
|
||||
}
|
||||
let deferred = deferFulfillment(viewModel.context.observe(\.viewState.dmRecipientInfo)) { $0 != nil }
|
||||
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -174,21 +169,18 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
var deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.dmRecipientInfo != nil
|
||||
}
|
||||
let deferredRecipient = deferFulfillment(viewModel.context.observe(\.viewState.dmRecipientInfo)) { $0 != nil }
|
||||
|
||||
try await deferred.fulfill()
|
||||
try await deferredRecipient.fulfill()
|
||||
|
||||
XCTAssertEqual(context.viewState.dmRecipientInfo?.member, RoomMemberDetails(withProxy: recipient))
|
||||
|
||||
deferred = deferFulfillment(viewModel.context.$viewState,
|
||||
keyPath: \.isProcessingIgnoreRequest,
|
||||
transitionValues: [false, true, false])
|
||||
let deferredProcessing = deferFulfillment(viewModel.context.observe(\.viewState.isProcessingIgnoreRequest),
|
||||
transitionValues: [false, true, false])
|
||||
|
||||
context.send(viewAction: .ignoreConfirmed)
|
||||
|
||||
try await deferred.fulfill()
|
||||
try await deferredProcessing.fulfill()
|
||||
|
||||
XCTAssert(context.viewState.dmRecipientInfo?.member.isIgnored == true)
|
||||
}
|
||||
@@ -209,21 +201,18 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
var deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.dmRecipientInfo != nil
|
||||
}
|
||||
let deferredRecipient = deferFulfillment(viewModel.context.observe(\.viewState.dmRecipientInfo)) { $0 != nil }
|
||||
|
||||
try await deferred.fulfill()
|
||||
try await deferredRecipient.fulfill()
|
||||
|
||||
XCTAssertEqual(context.viewState.dmRecipientInfo?.member, RoomMemberDetails(withProxy: recipient))
|
||||
|
||||
deferred = deferFulfillment(viewModel.context.$viewState,
|
||||
keyPath: \.isProcessingIgnoreRequest,
|
||||
transitionValues: [false, true, false])
|
||||
let deferredProcessing = deferFulfillment(viewModel.context.observe(\.viewState.isProcessingIgnoreRequest),
|
||||
transitionValues: [false, true, false])
|
||||
|
||||
context.send(viewAction: .ignoreConfirmed)
|
||||
|
||||
try await deferred.fulfill()
|
||||
try await deferredProcessing.fulfill()
|
||||
|
||||
XCTAssert(context.viewState.dmRecipientInfo?.member.isIgnored == false)
|
||||
XCTAssertNotNil(context.alertInfo)
|
||||
@@ -243,21 +232,18 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
var deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.dmRecipientInfo != nil
|
||||
}
|
||||
let deferredRecipient = deferFulfillment(viewModel.context.observe(\.viewState.dmRecipientInfo)) { $0 != nil }
|
||||
|
||||
try await deferred.fulfill()
|
||||
try await deferredRecipient.fulfill()
|
||||
|
||||
XCTAssertEqual(context.viewState.dmRecipientInfo?.member, RoomMemberDetails(withProxy: recipient))
|
||||
|
||||
deferred = deferFulfillment(viewModel.context.$viewState,
|
||||
keyPath: \.isProcessingIgnoreRequest,
|
||||
transitionValues: [false, true, false])
|
||||
let deferredProcessing = deferFulfillment(viewModel.context.observe(\.viewState.isProcessingIgnoreRequest),
|
||||
transitionValues: [false, true, false])
|
||||
|
||||
context.send(viewAction: .unignoreConfirmed)
|
||||
|
||||
try await deferred.fulfill()
|
||||
try await deferredProcessing.fulfill()
|
||||
|
||||
XCTAssert(context.viewState.dmRecipientInfo?.member.isIgnored == false)
|
||||
}
|
||||
@@ -278,21 +264,18 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
var deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.dmRecipientInfo != nil
|
||||
}
|
||||
let deferredRecipient = deferFulfillment(viewModel.context.observe(\.viewState.dmRecipientInfo)) { $0 != nil }
|
||||
|
||||
try await deferred.fulfill()
|
||||
try await deferredRecipient.fulfill()
|
||||
|
||||
XCTAssertEqual(context.viewState.dmRecipientInfo?.member, RoomMemberDetails(withProxy: recipient))
|
||||
|
||||
deferred = deferFulfillment(viewModel.context.$viewState,
|
||||
keyPath: \.isProcessingIgnoreRequest,
|
||||
transitionValues: [false, true, false])
|
||||
let deferredProcessing = deferFulfillment(viewModel.context.observe(\.viewState.isProcessingIgnoreRequest),
|
||||
transitionValues: [false, true, false])
|
||||
|
||||
context.send(viewAction: .unignoreConfirmed)
|
||||
|
||||
try await deferred.fulfill()
|
||||
try await deferredProcessing.fulfill()
|
||||
|
||||
XCTAssert(context.viewState.dmRecipientInfo?.member.isIgnored == true)
|
||||
XCTAssertNotNil(context.alertInfo)
|
||||
@@ -314,7 +297,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||
_ = await context.observe(\.viewState).debounce(for: .milliseconds(100)).first()
|
||||
|
||||
XCTAssertFalse(context.viewState.canInviteUsers)
|
||||
}
|
||||
@@ -332,7 +315,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||
_ = await context.observe(\.viewState).debounce(for: .milliseconds(100)).first()
|
||||
|
||||
XCTAssertTrue(context.viewState.canInviteUsers)
|
||||
|
||||
@@ -385,7 +368,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||
_ = await context.observe(\.viewState).debounce(for: .milliseconds(100)).first()
|
||||
|
||||
XCTAssertTrue(context.viewState.canEditRoomAvatar)
|
||||
XCTAssertFalse(context.viewState.canEditRoomName)
|
||||
@@ -425,7 +408,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||
_ = await context.observe(\.viewState).debounce(for: .milliseconds(100)).first()
|
||||
|
||||
XCTAssertFalse(context.viewState.canEditRoomAvatar)
|
||||
XCTAssertTrue(context.viewState.canEditRoomName)
|
||||
@@ -465,7 +448,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||
_ = await context.observe(\.viewState).debounce(for: .milliseconds(100)).first()
|
||||
|
||||
XCTAssertFalse(context.viewState.canEditRoomAvatar)
|
||||
XCTAssertFalse(context.viewState.canEditRoomName)
|
||||
@@ -486,7 +469,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||
_ = await context.observe(\.viewState).debounce(for: .milliseconds(100)).first()
|
||||
|
||||
XCTAssertFalse(context.viewState.canEditRoomAvatar)
|
||||
XCTAssertFalse(context.viewState.canEditRoomName)
|
||||
@@ -507,7 +490,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||
_ = await context.observe(\.viewState).debounce(for: .milliseconds(100)).first()
|
||||
|
||||
XCTAssertFalse(context.viewState.canEdit)
|
||||
}
|
||||
@@ -526,17 +509,13 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
var deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.notificationSettingsState.isError
|
||||
}
|
||||
var deferred = deferFulfillment(context.observe(\.viewState.notificationSettingsState)) { $0.isError }
|
||||
|
||||
try await deferred.fulfill()
|
||||
|
||||
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
|
||||
|
||||
deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.notificationSettingsState.isError
|
||||
}
|
||||
deferred = deferFulfillment(context.observe(\.viewState.notificationSettingsState)) { $0.isError }
|
||||
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -551,9 +530,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
func testNotificationDefaultMode() async throws {
|
||||
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedIsOneToOneReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .allMessages, isDefault: true))
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.notificationSettingsState.isLoaded
|
||||
}
|
||||
let deferred = deferFulfillment(context.observe(\.viewState.notificationSettingsState)) { $0.isLoaded }
|
||||
|
||||
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
|
||||
try await deferred.fulfill()
|
||||
@@ -564,9 +541,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
func testNotificationCustomMode() async throws {
|
||||
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedIsOneToOneReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .allMessages, isDefault: false))
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.notificationSettingsState.isCustom
|
||||
}
|
||||
let deferred = deferFulfillment(context.observe(\.viewState.notificationSettingsState)) { $0.isCustom }
|
||||
|
||||
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
|
||||
try await deferred.fulfill()
|
||||
@@ -577,14 +552,12 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
func testNotificationRoomMuted() async throws {
|
||||
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedIsOneToOneReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .mute, isDefault: false))
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.notificationSettingsState.isLoaded
|
||||
}
|
||||
let deferred = deferFulfillment(context.observe(\.viewState.notificationSettingsState)) { $0.isLoaded }
|
||||
|
||||
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
|
||||
try await deferred.fulfill()
|
||||
|
||||
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||
_ = await context.observe(\.viewState).debounce(for: .milliseconds(100)).first()
|
||||
|
||||
XCTAssertEqual(context.viewState.notificationShortcutButtonTitle, L10n.commonUnmute)
|
||||
XCTAssertEqual(context.viewState.notificationShortcutButtonIcon, \.notificationsOff)
|
||||
@@ -593,9 +566,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
func testNotificationRoomNotMuted() async throws {
|
||||
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedIsOneToOneReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .mentionsAndKeywordsOnly, isDefault: false))
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.notificationSettingsState.isLoaded
|
||||
}
|
||||
let deferred = deferFulfillment(context.observe(\.viewState.notificationSettingsState)) { $0.isLoaded }
|
||||
|
||||
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
|
||||
try await deferred.fulfill()
|
||||
@@ -667,12 +638,10 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
|
||||
XCTAssertFalse(context.viewState.isProcessingMuteToggleAction)
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
switch state.notificationSettingsState {
|
||||
case .loaded(settings: let settings):
|
||||
return settings.mode == .mute
|
||||
default:
|
||||
return false
|
||||
let deferred = deferFulfillment(context.observe(\.viewState.notificationSettingsState)) { state in
|
||||
switch state {
|
||||
case .loaded(settings: let settings): settings.mode == .mute
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -700,12 +669,10 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
|
||||
XCTAssertFalse(context.viewState.isProcessingMuteToggleAction)
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
switch state.notificationSettingsState {
|
||||
case .loaded(settings: let settings):
|
||||
return settings.mode == .allMessages
|
||||
default:
|
||||
return false
|
||||
let deferred = deferFulfillment(context.observe(\.viewState.notificationSettingsState)) { state in
|
||||
switch state {
|
||||
case .loaded(settings: let settings): settings.mode == .allMessages
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -736,7 +703,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
let deferred = deferFulfillment(context.observe(\.viewState)) { state in
|
||||
state.knockRequestsCount == 2 && state.canSeeKnockingRequests
|
||||
}
|
||||
try await deferred.fulfill()
|
||||
@@ -759,7 +726,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
let deferred = deferFulfillment(context.observe(\.viewState)) { state in
|
||||
state.knockRequestsCount == 0 && state.canSeeKnockingRequests
|
||||
}
|
||||
|
||||
@@ -784,7 +751,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
let deferred = deferFulfillment(context.observe(\.viewState)) { state in
|
||||
state.knockRequestsCount == 2 &&
|
||||
state.dmRecipientInfo == nil &&
|
||||
!state.canSeeKnockingRequests &&
|
||||
@@ -809,7 +776,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
let deferred = deferFulfillment(context.observe(\.viewState)) { state in
|
||||
state.knockRequestsCount == 2 &&
|
||||
!state.canSeeKnockingRequests &&
|
||||
state.dmRecipientInfo != nil &&
|
||||
@@ -26,7 +26,7 @@ class UserProfileScreenViewModelTests: XCTestCase {
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
analytics: ServiceLocator.shared.analytics)
|
||||
|
||||
let waitForMemberToLoad = deferFulfillment(context.$viewState) { $0.userProfile != nil }
|
||||
let waitForMemberToLoad = deferFulfillment(context.observe(\.viewState.userProfile)) { $0 != nil }
|
||||
try await waitForMemberToLoad.fulfill()
|
||||
|
||||
XCTAssertFalse(context.viewState.isOwnUser)
|
||||
@@ -46,7 +46,7 @@ class UserProfileScreenViewModelTests: XCTestCase {
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
analytics: ServiceLocator.shared.analytics)
|
||||
|
||||
let waitForMemberToLoad = deferFulfillment(context.$viewState) { $0.userProfile != nil }
|
||||
let waitForMemberToLoad = deferFulfillment(context.observe(\.viewState.userProfile)) { $0 != nil }
|
||||
try await waitForMemberToLoad.fulfill()
|
||||
|
||||
XCTAssertTrue(context.viewState.isOwnUser)
|
||||
|
||||
@@ -32,6 +32,7 @@ targets:
|
||||
dependencies:
|
||||
- target: ElementX
|
||||
- package: MatrixRustSDK
|
||||
- package: AsyncAlgorithms
|
||||
|
||||
info:
|
||||
path: ../SupportingFiles/Info.plist
|
||||
|
||||
@@ -95,6 +95,9 @@ packages:
|
||||
Algorithms:
|
||||
url: https://github.com/apple/swift-algorithms
|
||||
minorVersion: 1.2.1
|
||||
AsyncAlgorithms:
|
||||
url: https://github.com/apple/swift-async-algorithms
|
||||
minorVersion: 1.0.0
|
||||
Collections:
|
||||
url: https://github.com/apple/swift-collections
|
||||
minorVersion: 1.2.0
|
||||
|
||||
Reference in New Issue
Block a user