From 2d486ece33f50f5b83435935969a8bba52ffea23 Mon Sep 17 00:00:00 2001 From: Mauro <34335419+Velin92@users.noreply.github.com> Date: Tue, 30 Jun 2026 14:01:08 +0200 Subject: [PATCH] Use iOS 26 Observation for Unit and Preview tests. (#5797) * use observation in unit and preview tests instead of the async stream * use a parsing approach that is independent of the sourcery annotation * Fix observation deferred fulfillments not receiving the initial value Observation's observe only emits transitions, not the value present at subscription time. Drop the leading initial value from the affected transitionValues sequences and assert it directly with #expect instead. * improved docs --- ElementX.xcodeproj/project.pbxproj | 4 + .../Sources/Other/Extensions/Observable.swift | 16 +- .../TestablePreviewsDictionary.swift | 455 +++++++++--------- .../LoginScreen/View/LoginScreen.swift | 1 + .../View/ServerSelectionScreen.swift | 1 + .../View/EmojiPickerScreen.swift | 1 + .../TimelineMediaPreviewDetailsView.swift | 1 + .../View/LinkNewDeviceScreen.swift | 1 + .../View/IdentityConfirmationScreen.swift | 1 + .../View/RoomDetailsScreen.swift | 1 + ...SecureBackupLogoutConfirmationScreen.swift | 1 + .../View/SecureBackupRecoveryKeyScreen.swift | 1 + .../View/SecureBackupScreen.swift | 1 + .../View/NotificationSettingsScreen.swift | 1 + .../SettingsScreen/View/SettingsScreen.swift | 1 + .../View/SpaceAddRoomsScreen.swift | 1 + .../Spaces/SpaceScreen/View/SpaceScreen.swift | 1 + .../View/UserProfileScreen.swift | 1 + PreviewTests/SupportingFiles/target.yml | 2 + .../ElementX/View/TemplateScreen.swift | 1 + .../TestablePreviewsDictionary.stencil | 20 +- ...tionSettingsEditScreenViewModelTests.swift | 16 +- ...ficationSettingsScreenViewModelTests.swift | 16 +- UnitTests/SupportingFiles/target.yml | 2 + 24 files changed, 308 insertions(+), 239 deletions(-) diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 06bba875c..21e45a6a7 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -9609,6 +9609,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; INFOPLIST_FILE = PreviewTests/SupportingFiles/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -9720,6 +9721,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; INFOPLIST_FILE = UnitTests/SupportingFiles/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -9919,6 +9921,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; INFOPLIST_FILE = UnitTests/SupportingFiles/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -10082,6 +10085,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; INFOPLIST_FILE = PreviewTests/SupportingFiles/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/ElementX/Sources/Other/Extensions/Observable.swift b/ElementX/Sources/Other/Extensions/Observable.swift index 1f559fb89..f4530fc7d 100644 --- a/ElementX/Sources/Other/Extensions/Observable.swift +++ b/ElementX/Sources/Other/Extensions/Observable.swift @@ -7,13 +7,25 @@ // import Foundation +import Observation import Synchronization extension Observable { - /// Creates an async stream for the specified property on this object. We probably won't need this once SE-0475 is available: - /// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0475-observed.md + /// A convenience wrapper around the `Observations` sequence (SE-0475). /// /// - Parameter property: The key path to the property you would like to observe. + @available(iOS 26.0, *) + @MainActor func observe(_ property: KeyPath) -> Observations { + Observations { self[keyPath: property] } + } + + /// Creates an async stream for the specified property on this object. + /// + /// iOS 18 fallback for ``observe(_:)``. Remove once the minimum deployment target reaches iOS 26. + /// + /// - Parameter property: The key path to the property you would like to observe. + @available(iOS, deprecated: 26.0, message: "Use observe(_:) which is backed by the Observations sequence.") + @_disfavoredOverload @MainActor func observe(_ property: KeyPath) -> AsyncStream { let (stream, continuation) = AsyncStream.makeStream() let (changeSignals, changeSignaller) = AsyncStream.makeStream() diff --git a/ElementX/Sources/Other/TestablePreview/TestablePreviewsDictionary.swift b/ElementX/Sources/Other/TestablePreview/TestablePreviewsDictionary.swift index 5ffd9b792..86c0695c9 100644 --- a/ElementX/Sources/Other/TestablePreview/TestablePreviewsDictionary.swift +++ b/ElementX/Sources/Other/TestablePreview/TestablePreviewsDictionary.swift @@ -8,230 +8,237 @@ import SwiftUI enum TestablePreviewsDictionary { - static let dictionary: [String: any PreviewProvider.Type] = [ - "AdvancedSettingsScreen_Previews" : AdvancedSettingsScreen_Previews.self, - "AnalyticsPromptScreen_Previews" : AnalyticsPromptScreen_Previews.self, - "AnalyticsSettingsScreen_Previews" : AnalyticsSettingsScreen_Previews.self, - "AppLockScreen_Previews" : AppLockScreen_Previews.self, - "AppLockSetupBiometricsScreen_Previews" : AppLockSetupBiometricsScreen_Previews.self, - "AppLockSetupPINScreen_Previews" : AppLockSetupPINScreen_Previews.self, - "AppLockSetupSettingsScreen_Previews" : AppLockSetupSettingsScreen_Previews.self, - "AudioMediaEventsTimelineView_Previews" : AudioMediaEventsTimelineView_Previews.self, - "AudioRoomTimelineView_Previews" : AudioRoomTimelineView_Previews.self, - "AuthenticationClassicAppBackupInstructionsView_Previews" : AuthenticationClassicAppBackupInstructionsView_Previews.self, - "AuthenticationStartScreen_Previews" : AuthenticationStartScreen_Previews.self, - "AvatarHeaderView_Previews" : AvatarHeaderView_Previews.self, - "BadgeLabel_Previews" : BadgeLabel_Previews.self, - "BlockedUsersScreen_Previews" : BlockedUsersScreen_Previews.self, - "BloomModifier_Previews" : BloomModifier_Previews.self, - "BugReportScreen_Previews" : BugReportScreen_Previews.self, - "CallInviteRoomTimelineView_Previews" : CallInviteRoomTimelineView_Previews.self, - "CallNotificationRoomTimelineView_Previews" : CallNotificationRoomTimelineView_Previews.self, - "ChatsSpaceFilterCell_Previews" : ChatsSpaceFilterCell_Previews.self, - "ChatsSpaceFiltersScreen_Previews" : ChatsSpaceFiltersScreen_Previews.self, - "CollapsibleRoomTimelineView_Previews" : CollapsibleRoomTimelineView_Previews.self, - "CompletionSuggestion_Previews" : CompletionSuggestion_Previews.self, - "ComposerToolbar_Previews" : ComposerToolbar_Previews.self, - "CopyTextButton_Previews" : CopyTextButton_Previews.self, - "CreateRoomSpaceSelectionSheet_Previews" : CreateRoomSpaceSelectionSheet_Previews.self, - "CreateRoom_Previews" : CreateRoom_Previews.self, - "DeactivateAccountScreen_Previews" : DeactivateAccountScreen_Previews.self, - "DeclineAndBlockScreen_Previews" : DeclineAndBlockScreen_Previews.self, - "EditRoomAddressScreen_Previews" : EditRoomAddressScreen_Previews.self, - "EmojiPickerScreenHeaderView_Previews" : EmojiPickerScreenHeaderView_Previews.self, - "EmojiPickerScreen_Previews" : EmojiPickerScreen_Previews.self, - "EmoteRoomTimelineView_Previews" : EmoteRoomTimelineView_Previews.self, - "EncryptedRoomTimelineView_Previews" : EncryptedRoomTimelineView_Previews.self, - "EncryptionResetPasswordScreen_Previews" : EncryptionResetPasswordScreen_Previews.self, - "EncryptionResetScreen_Previews" : EncryptionResetScreen_Previews.self, - "EstimatedWaveformView_Previews" : EstimatedWaveformView_Previews.self, - "FileMediaEventsTimelineView_Previews" : FileMediaEventsTimelineView_Previews.self, - "FileRoomTimelineView_Previews" : FileRoomTimelineView_Previews.self, - "FloatingDateBadge_Previews" : FloatingDateBadge_Previews.self, - "FormButtonStyles_Previews" : FormButtonStyles_Previews.self, - "FormattedBodyText_Previews" : FormattedBodyText_Previews.self, - "FormattingToolbar_Previews" : FormattingToolbar_Previews.self, - "FullscreenDialog_Previews" : FullscreenDialog_Previews.self, - "HighlightedTimelineItemModifier_Previews" : HighlightedTimelineItemModifier_Previews.self, - "HomeScreenEmptyStateView_Previews" : HomeScreenEmptyStateView_Previews.self, - "HomeScreenInviteCell_Previews" : HomeScreenInviteCell_Previews.self, - "HomeScreenKnockedCell_Previews" : HomeScreenKnockedCell_Previews.self, - "HomeScreenNewSoundBanner_Previews" : HomeScreenNewSoundBanner_Previews.self, - "HomeScreenRecoveryKeyConfirmationBanner_Previews" : HomeScreenRecoveryKeyConfirmationBanner_Previews.self, - "HomeScreenRoomCell_Previews" : HomeScreenRoomCell_Previews.self, - "HomeScreen_Previews" : HomeScreen_Previews.self, - "IdentityConfirmationScreen_Previews" : IdentityConfirmationScreen_Previews.self, - "IdentityConfirmedScreen_Previews" : IdentityConfirmedScreen_Previews.self, - "ImageMediaEventsTimelineView_Previews" : ImageMediaEventsTimelineView_Previews.self, - "ImageRoomTimelineView_Previews" : ImageRoomTimelineView_Previews.self, - "InviteUsersConfirmationSheetView_Previews" : InviteUsersConfirmationSheetView_Previews.self, - "InviteUsersScreenSelectedItem_Previews" : InviteUsersScreenSelectedItem_Previews.self, - "InviteUsersScreen_Previews" : InviteUsersScreen_Previews.self, - "JoinRoomByAddressView_Previews" : JoinRoomByAddressView_Previews.self, - "JoinRoomScreenSpace_Previews" : JoinRoomScreenSpace_Previews.self, - "JoinRoomScreen_Previews" : JoinRoomScreen_Previews.self, - "JoinedMembersBadgeView_Previews" : JoinedMembersBadgeView_Previews.self, - "KnockRequestCell_Previews" : KnockRequestCell_Previews.self, - "KnockRequestsBannerView_Previews" : KnockRequestsBannerView_Previews.self, - "KnockRequestsListEmptyStateView_Previews" : KnockRequestsListEmptyStateView_Previews.self, - "KnockRequestsListScreen_Previews" : KnockRequestsListScreen_Previews.self, - "LabsScreen_Previews" : LabsScreen_Previews.self, - "LeaveSpaceRoomDetailsCell_Previews" : LeaveSpaceRoomDetailsCell_Previews.self, - "LeaveSpaceView_Previews" : LeaveSpaceView_Previews.self, - "LegalInformationScreen_Previews" : LegalInformationScreen_Previews.self, - "LinkNewDeviceScreen_Previews" : LinkNewDeviceScreen_Previews.self, - "LiveLocationRoomTimelineView_Previews" : LiveLocationRoomTimelineView_Previews.self, - "LiveLocationSharingBannerView_Previews" : LiveLocationSharingBannerView_Previews.self, - "LiveLocationSheet_Previews" : LiveLocationSheet_Previews.self, - "LoadableImage_Previews" : LoadableImage_Previews.self, - "LocationMarkerView_Previews" : LocationMarkerView_Previews.self, - "LocationPickerSheet_Previews" : LocationPickerSheet_Previews.self, - "LocationRoomTimelineView_Previews" : LocationRoomTimelineView_Previews.self, - "LocationSharingScreen_Previews" : LocationSharingScreen_Previews.self, - "LoginScreen_Previews" : LoginScreen_Previews.self, - "LongPressWithFeedback_Previews" : LongPressWithFeedback_Previews.self, - "ManageAuthorizedSpacesScreen_Previews" : ManageAuthorizedSpacesScreen_Previews.self, - "ManageRoomMemberSheetView_Previews" : ManageRoomMemberSheetView_Previews.self, - "MapLibreStaticMapView_Previews" : MapLibreStaticMapView_Previews.self, - "MatrixUserPermalink_Previews" : MatrixUserPermalink_Previews.self, - "MediaEventsTimelineScreen_Previews" : MediaEventsTimelineScreen_Previews.self, - "MediaUploadPreviewScreen_Previews" : MediaUploadPreviewScreen_Previews.self, - "MentionSuggestionItemView_Previews" : MentionSuggestionItemView_Previews.self, - "MessageComposerTextField_Previews" : MessageComposerTextField_Previews.self, - "MessageComposer_Previews" : MessageComposer_Previews.self, - "MessageForwardingScreen_Previews" : MessageForwardingScreen_Previews.self, - "MessageText_Previews" : MessageText_Previews.self, - "NoticeRoomTimelineView_Previews" : NoticeRoomTimelineView_Previews.self, - "NotificationPermissionsScreen_Previews" : NotificationPermissionsScreen_Previews.self, - "NotificationSettingsEditScreenRoomCell_Previews" : NotificationSettingsEditScreenRoomCell_Previews.self, - "NotificationSettingsEditScreen_Previews" : NotificationSettingsEditScreen_Previews.self, - "NotificationSettingsScreen_Previews" : NotificationSettingsScreen_Previews.self, - "PINTextField_Previews" : PINTextField_Previews.self, - "PaginationIndicatorRoomTimelineView_Previews" : PaginationIndicatorRoomTimelineView_Previews.self, - "PillViewOnBubble_Previews" : PillViewOnBubble_Previews.self, - "PillView_Previews" : PillView_Previews.self, - "PinnedEventsTimelineScreen_Previews" : PinnedEventsTimelineScreen_Previews.self, - "PinnedItemsBannerView_Previews" : PinnedItemsBannerView_Previews.self, - "PinnedItemsIndicatorView_Previews" : PinnedItemsIndicatorView_Previews.self, - "PlaceholderAvatarImage_Previews" : PlaceholderAvatarImage_Previews.self, - "PlaceholderScreen_Previews" : PlaceholderScreen_Previews.self, - "PlaybackSpeedButton_Previews" : PlaybackSpeedButton_Previews.self, - "PollFormScreen_Previews" : PollFormScreen_Previews.self, - "PollOptionView_Previews" : PollOptionView_Previews.self, - "PollRoomTimelineView_Previews" : PollRoomTimelineView_Previews.self, - "PollView_Previews" : PollView_Previews.self, - "QRCodeErrorView_Previews" : QRCodeErrorView_Previews.self, - "QRCodeLoginScreen_Previews" : QRCodeLoginScreen_Previews.self, - "ReactionsSummaryView_Previews" : ReactionsSummaryView_Previews.self, - "ReadMarkerRoomTimelineView_Previews" : ReadMarkerRoomTimelineView_Previews.self, - "ReadReceiptCell_Previews" : ReadReceiptCell_Previews.self, - "ReadReceiptsSummaryView_Previews" : ReadReceiptsSummaryView_Previews.self, - "RedactedRoomTimelineView_Previews" : RedactedRoomTimelineView_Previews.self, - "ReportContentScreen_Previews" : ReportContentScreen_Previews.self, - "ReportRoomScreen_Previews" : ReportRoomScreen_Previews.self, - "ResolveVerifiedUserSendFailureScreen_Previews" : ResolveVerifiedUserSendFailureScreen_Previews.self, - "RoomAttachmentPicker_Previews" : RoomAttachmentPicker_Previews.self, - "RoomAvatarImage_Previews" : RoomAvatarImage_Previews.self, - "RoomChangePermissionsScreen_Previews" : RoomChangePermissionsScreen_Previews.self, - "RoomChangeRolesScreenRow_Previews" : RoomChangeRolesScreenRow_Previews.self, - "RoomChangeRolesScreenSelectedItem_Previews" : RoomChangeRolesScreenSelectedItem_Previews.self, - "RoomChangeRolesScreen_Previews" : RoomChangeRolesScreen_Previews.self, - "RoomDetailsEditScreen_Previews" : RoomDetailsEditScreen_Previews.self, - "RoomDetailsScreen_Previews" : RoomDetailsScreen_Previews.self, - "RoomDirectorySearchCell_Previews" : RoomDirectorySearchCell_Previews.self, - "RoomDirectorySearchScreen_Previews" : RoomDirectorySearchScreen_Previews.self, - "RoomHeaderView_Previews" : RoomHeaderView_Previews.self, - "RoomInviterLabel_Previews" : RoomInviterLabel_Previews.self, - "RoomListFilterView_Previews" : RoomListFilterView_Previews.self, - "RoomListFiltersEmptyStateView_Previews" : RoomListFiltersEmptyStateView_Previews.self, - "RoomListFiltersView_Previews" : RoomListFiltersView_Previews.self, - "RoomMemberDetailsScreen_Previews" : RoomMemberDetailsScreen_Previews.self, - "RoomMembersListMemberCell_Previews" : RoomMembersListMemberCell_Previews.self, - "RoomMembersListScreen_Previews" : RoomMembersListScreen_Previews.self, - "RoomNotificationSettingsCustomSectionView_Previews" : RoomNotificationSettingsCustomSectionView_Previews.self, - "RoomNotificationSettingsScreen_Previews" : RoomNotificationSettingsScreen_Previews.self, - "RoomNotificationSettingsUserDefinedScreen_Previews" : RoomNotificationSettingsUserDefinedScreen_Previews.self, - "RoomPollsHistoryScreen_Previews" : RoomPollsHistoryScreen_Previews.self, - "RoomRolesAndPermissionsScreen_Previews" : RoomRolesAndPermissionsScreen_Previews.self, - "RoomScreenFooterView_Previews" : RoomScreenFooterView_Previews.self, - "RoomScreen_Previews" : RoomScreen_Previews.self, - "RoomSelectionScreen_Previews" : RoomSelectionScreen_Previews.self, - "RoomThreadListScreen_Previews" : RoomThreadListScreen_Previews.self, - "SFNumberedListView_Previews" : SFNumberedListView_Previews.self, - "SearchScreen_Previews" : SearchScreen_Previews.self, - "SecureBackupKeyBackupScreen_Previews" : SecureBackupKeyBackupScreen_Previews.self, - "SecureBackupLogoutConfirmationScreen_Previews" : SecureBackupLogoutConfirmationScreen_Previews.self, - "SecureBackupRecoveryKeyScreen_Previews" : SecureBackupRecoveryKeyScreen_Previews.self, - "SecureBackupScreen_Previews" : SecureBackupScreen_Previews.self, - "SecurityAndPrivacyScreen_Previews" : SecurityAndPrivacyScreen_Previews.self, - "SendInviteConfirmationView_Previews" : SendInviteConfirmationView_Previews.self, - "SeparatorMediaEventsTimelineView_Previews" : SeparatorMediaEventsTimelineView_Previews.self, - "SeparatorRoomTimelineView_Previews" : SeparatorRoomTimelineView_Previews.self, - "ServerConfirmationScreen_Previews" : ServerConfirmationScreen_Previews.self, - "ServerSelection_Previews" : ServerSelection_Previews.self, - "SessionVerificationRequestDetailsView_Previews" : SessionVerificationRequestDetailsView_Previews.self, - "SessionVerification_Previews" : SessionVerification_Previews.self, - "SettingsScreen_Previews" : SettingsScreen_Previews.self, - "ShimmerOverlay_Previews" : ShimmerOverlay_Previews.self, - "SoftLogoutScreen_Previews" : SoftLogoutScreen_Previews.self, - "SpaceAddRoomsScreenSelectedItem_Previews" : SpaceAddRoomsScreenSelectedItem_Previews.self, - "SpaceAddRoomsScreen_Previews" : SpaceAddRoomsScreen_Previews.self, - "SpaceHeaderTopicSheetView_Previews" : SpaceHeaderTopicSheetView_Previews.self, - "SpaceHeaderView_Previews" : SpaceHeaderView_Previews.self, - "SpaceRemoveChildrenConfirmationView_Previews" : SpaceRemoveChildrenConfirmationView_Previews.self, - "SpaceRoomCell_Previews" : SpaceRoomCell_Previews.self, - "SpaceScreen_Previews" : SpaceScreen_Previews.self, - "SpaceSettingsScreen_Previews" : SpaceSettingsScreen_Previews.self, - "SpacesScreen_Previews" : SpacesScreen_Previews.self, - "SplashScreen_Previews" : SplashScreen_Previews.self, - "StackedAvatarsView_Previews" : StackedAvatarsView_Previews.self, - "StartChatScreen_Previews" : StartChatScreen_Previews.self, - "StateRoomTimelineView_Previews" : StateRoomTimelineView_Previews.self, - "StaticLocationSheet_Previews" : StaticLocationSheet_Previews.self, - "StickerRoomTimelineView_Previews" : StickerRoomTimelineView_Previews.self, - "SwipeRightAction_Previews" : SwipeRightAction_Previews.self, - "SwipeToReplyView_Previews" : SwipeToReplyView_Previews.self, - "TextRoomTimelineView_Previews" : TextRoomTimelineView_Previews.self, - "ThreadDecorator_Previews" : ThreadDecorator_Previews.self, - "TimelineDeliveryStatusView_Previews" : TimelineDeliveryStatusView_Previews.self, - "TimelineItemBubbledStylerView_Previews" : TimelineItemBubbledStylerView_Previews.self, - "TimelineItemDebugView_Previews" : TimelineItemDebugView_Previews.self, - "TimelineItemMenu_Previews" : TimelineItemMenu_Previews.self, - "TimelineItemSendInfoLabel_Previews" : TimelineItemSendInfoLabel_Previews.self, - "TimelineItemStyler_Previews" : TimelineItemStyler_Previews.self, - "TimelineMediaPreviewDetailsView_Previews" : TimelineMediaPreviewDetailsView_Previews.self, - "TimelineMediaPreviewRedactConfirmationView_Previews" : TimelineMediaPreviewRedactConfirmationView_Previews.self, - "TimelineReactionView_Previews" : TimelineReactionView_Previews.self, - "TimelineReadReceiptsView_Previews" : TimelineReadReceiptsView_Previews.self, - "TimelineReplyView_Previews" : TimelineReplyView_Previews.self, - "TimelineScrollButton_Previews" : TimelineScrollButton_Previews.self, - "TimelineStartRoomTimelineView_Previews" : TimelineStartRoomTimelineView_Previews.self, - "TimelineThreadSummaryView_Previews" : TimelineThreadSummaryView_Previews.self, - "TombstonedAvatarImage_Previews" : TombstonedAvatarImage_Previews.self, - "ToolbarButton_Previews" : ToolbarButton_Previews.self, - "TypingIndicatorView_Previews" : TypingIndicatorView_Previews.self, - "UnsupportedRoomTimelineView_Previews" : UnsupportedRoomTimelineView_Previews.self, - "UserDetailsEditScreen_Previews" : UserDetailsEditScreen_Previews.self, - "UserIndicatorModalView_Previews" : UserIndicatorModalView_Previews.self, - "UserIndicatorToastView_Previews" : UserIndicatorToastView_Previews.self, - "UserLocationCell_Previews" : UserLocationCell_Previews.self, - "UserProfileCell_Previews" : UserProfileCell_Previews.self, - "UserProfileScreen_Previews" : UserProfileScreen_Previews.self, - "VerificationBadge_Previews" : VerificationBadge_Previews.self, - "VideoMediaEventsTimelineView_Previews" : VideoMediaEventsTimelineView_Previews.self, - "VideoRoomTimelineView_Previews" : VideoRoomTimelineView_Previews.self, - "VisualListItem_Previews" : VisualListItem_Previews.self, - "VoiceMessageButton_Previews" : VoiceMessageButton_Previews.self, - "VoiceMessageMediaEventsTimelineView_Previews" : VoiceMessageMediaEventsTimelineView_Previews.self, - "VoiceMessagePreviewComposer_Previews" : VoiceMessagePreviewComposer_Previews.self, - "VoiceMessageRecordingButton_Previews" : VoiceMessageRecordingButton_Previews.self, - "VoiceMessageRecordingComposer_Previews" : VoiceMessageRecordingComposer_Previews.self, - "VoiceMessageRecordingView_Previews" : VoiceMessageRecordingView_Previews.self, - "VoiceMessageRoomPlaybackView_Previews" : VoiceMessageRoomPlaybackView_Previews.self, - "VoiceMessageRoomTimelineView_Previews" : VoiceMessageRoomTimelineView_Previews.self, - "VoiceMessageTrashButton_Previews" : VoiceMessageTrashButton_Previews.self, - "WaveformCursorView_Previews" : WaveformCursorView_Previews.self, - ] + static let dictionary: [String: any PreviewProvider.Type] = { + var dictionary: [String: any PreviewProvider.Type] = [ + "AdvancedSettingsScreen_Previews" : AdvancedSettingsScreen_Previews.self, + "AnalyticsPromptScreen_Previews" : AnalyticsPromptScreen_Previews.self, + "AnalyticsSettingsScreen_Previews" : AnalyticsSettingsScreen_Previews.self, + "AppLockScreen_Previews" : AppLockScreen_Previews.self, + "AppLockSetupBiometricsScreen_Previews" : AppLockSetupBiometricsScreen_Previews.self, + "AppLockSetupPINScreen_Previews" : AppLockSetupPINScreen_Previews.self, + "AppLockSetupSettingsScreen_Previews" : AppLockSetupSettingsScreen_Previews.self, + "AudioMediaEventsTimelineView_Previews" : AudioMediaEventsTimelineView_Previews.self, + "AudioRoomTimelineView_Previews" : AudioRoomTimelineView_Previews.self, + "AuthenticationClassicAppBackupInstructionsView_Previews" : AuthenticationClassicAppBackupInstructionsView_Previews.self, + "AuthenticationStartScreen_Previews" : AuthenticationStartScreen_Previews.self, + "AvatarHeaderView_Previews" : AvatarHeaderView_Previews.self, + "BadgeLabel_Previews" : BadgeLabel_Previews.self, + "BlockedUsersScreen_Previews" : BlockedUsersScreen_Previews.self, + "BloomModifier_Previews" : BloomModifier_Previews.self, + "BugReportScreen_Previews" : BugReportScreen_Previews.self, + "CallInviteRoomTimelineView_Previews" : CallInviteRoomTimelineView_Previews.self, + "CallNotificationRoomTimelineView_Previews" : CallNotificationRoomTimelineView_Previews.self, + "ChatsSpaceFilterCell_Previews" : ChatsSpaceFilterCell_Previews.self, + "ChatsSpaceFiltersScreen_Previews" : ChatsSpaceFiltersScreen_Previews.self, + "CollapsibleRoomTimelineView_Previews" : CollapsibleRoomTimelineView_Previews.self, + "CompletionSuggestion_Previews" : CompletionSuggestion_Previews.self, + "ComposerToolbar_Previews" : ComposerToolbar_Previews.self, + "CopyTextButton_Previews" : CopyTextButton_Previews.self, + "CreateRoomSpaceSelectionSheet_Previews" : CreateRoomSpaceSelectionSheet_Previews.self, + "CreateRoom_Previews" : CreateRoom_Previews.self, + "DeactivateAccountScreen_Previews" : DeactivateAccountScreen_Previews.self, + "DeclineAndBlockScreen_Previews" : DeclineAndBlockScreen_Previews.self, + "EditRoomAddressScreen_Previews" : EditRoomAddressScreen_Previews.self, + "EmojiPickerScreenHeaderView_Previews" : EmojiPickerScreenHeaderView_Previews.self, + "EmoteRoomTimelineView_Previews" : EmoteRoomTimelineView_Previews.self, + "EncryptedRoomTimelineView_Previews" : EncryptedRoomTimelineView_Previews.self, + "EncryptionResetPasswordScreen_Previews" : EncryptionResetPasswordScreen_Previews.self, + "EncryptionResetScreen_Previews" : EncryptionResetScreen_Previews.self, + "EstimatedWaveformView_Previews" : EstimatedWaveformView_Previews.self, + "FileMediaEventsTimelineView_Previews" : FileMediaEventsTimelineView_Previews.self, + "FileRoomTimelineView_Previews" : FileRoomTimelineView_Previews.self, + "FloatingDateBadge_Previews" : FloatingDateBadge_Previews.self, + "FormButtonStyles_Previews" : FormButtonStyles_Previews.self, + "FormattedBodyText_Previews" : FormattedBodyText_Previews.self, + "FormattingToolbar_Previews" : FormattingToolbar_Previews.self, + "FullscreenDialog_Previews" : FullscreenDialog_Previews.self, + "HighlightedTimelineItemModifier_Previews" : HighlightedTimelineItemModifier_Previews.self, + "HomeScreenEmptyStateView_Previews" : HomeScreenEmptyStateView_Previews.self, + "HomeScreenInviteCell_Previews" : HomeScreenInviteCell_Previews.self, + "HomeScreenKnockedCell_Previews" : HomeScreenKnockedCell_Previews.self, + "HomeScreenNewSoundBanner_Previews" : HomeScreenNewSoundBanner_Previews.self, + "HomeScreenRecoveryKeyConfirmationBanner_Previews" : HomeScreenRecoveryKeyConfirmationBanner_Previews.self, + "HomeScreenRoomCell_Previews" : HomeScreenRoomCell_Previews.self, + "HomeScreen_Previews" : HomeScreen_Previews.self, + "IdentityConfirmedScreen_Previews" : IdentityConfirmedScreen_Previews.self, + "ImageMediaEventsTimelineView_Previews" : ImageMediaEventsTimelineView_Previews.self, + "ImageRoomTimelineView_Previews" : ImageRoomTimelineView_Previews.self, + "InviteUsersConfirmationSheetView_Previews" : InviteUsersConfirmationSheetView_Previews.self, + "InviteUsersScreenSelectedItem_Previews" : InviteUsersScreenSelectedItem_Previews.self, + "InviteUsersScreen_Previews" : InviteUsersScreen_Previews.self, + "JoinRoomByAddressView_Previews" : JoinRoomByAddressView_Previews.self, + "JoinRoomScreenSpace_Previews" : JoinRoomScreenSpace_Previews.self, + "JoinRoomScreen_Previews" : JoinRoomScreen_Previews.self, + "JoinedMembersBadgeView_Previews" : JoinedMembersBadgeView_Previews.self, + "KnockRequestCell_Previews" : KnockRequestCell_Previews.self, + "KnockRequestsBannerView_Previews" : KnockRequestsBannerView_Previews.self, + "KnockRequestsListEmptyStateView_Previews" : KnockRequestsListEmptyStateView_Previews.self, + "KnockRequestsListScreen_Previews" : KnockRequestsListScreen_Previews.self, + "LabsScreen_Previews" : LabsScreen_Previews.self, + "LeaveSpaceRoomDetailsCell_Previews" : LeaveSpaceRoomDetailsCell_Previews.self, + "LeaveSpaceView_Previews" : LeaveSpaceView_Previews.self, + "LegalInformationScreen_Previews" : LegalInformationScreen_Previews.self, + "LiveLocationRoomTimelineView_Previews" : LiveLocationRoomTimelineView_Previews.self, + "LiveLocationSharingBannerView_Previews" : LiveLocationSharingBannerView_Previews.self, + "LiveLocationSheet_Previews" : LiveLocationSheet_Previews.self, + "LoadableImage_Previews" : LoadableImage_Previews.self, + "LocationMarkerView_Previews" : LocationMarkerView_Previews.self, + "LocationPickerSheet_Previews" : LocationPickerSheet_Previews.self, + "LocationRoomTimelineView_Previews" : LocationRoomTimelineView_Previews.self, + "LocationSharingScreen_Previews" : LocationSharingScreen_Previews.self, + "LongPressWithFeedback_Previews" : LongPressWithFeedback_Previews.self, + "ManageAuthorizedSpacesScreen_Previews" : ManageAuthorizedSpacesScreen_Previews.self, + "ManageRoomMemberSheetView_Previews" : ManageRoomMemberSheetView_Previews.self, + "MapLibreStaticMapView_Previews" : MapLibreStaticMapView_Previews.self, + "MatrixUserPermalink_Previews" : MatrixUserPermalink_Previews.self, + "MediaEventsTimelineScreen_Previews" : MediaEventsTimelineScreen_Previews.self, + "MediaUploadPreviewScreen_Previews" : MediaUploadPreviewScreen_Previews.self, + "MentionSuggestionItemView_Previews" : MentionSuggestionItemView_Previews.self, + "MessageComposerTextField_Previews" : MessageComposerTextField_Previews.self, + "MessageComposer_Previews" : MessageComposer_Previews.self, + "MessageForwardingScreen_Previews" : MessageForwardingScreen_Previews.self, + "MessageText_Previews" : MessageText_Previews.self, + "NoticeRoomTimelineView_Previews" : NoticeRoomTimelineView_Previews.self, + "NotificationPermissionsScreen_Previews" : NotificationPermissionsScreen_Previews.self, + "NotificationSettingsEditScreenRoomCell_Previews" : NotificationSettingsEditScreenRoomCell_Previews.self, + "NotificationSettingsEditScreen_Previews" : NotificationSettingsEditScreen_Previews.self, + "PINTextField_Previews" : PINTextField_Previews.self, + "PaginationIndicatorRoomTimelineView_Previews" : PaginationIndicatorRoomTimelineView_Previews.self, + "PillViewOnBubble_Previews" : PillViewOnBubble_Previews.self, + "PillView_Previews" : PillView_Previews.self, + "PinnedEventsTimelineScreen_Previews" : PinnedEventsTimelineScreen_Previews.self, + "PinnedItemsBannerView_Previews" : PinnedItemsBannerView_Previews.self, + "PinnedItemsIndicatorView_Previews" : PinnedItemsIndicatorView_Previews.self, + "PlaceholderAvatarImage_Previews" : PlaceholderAvatarImage_Previews.self, + "PlaceholderScreen_Previews" : PlaceholderScreen_Previews.self, + "PlaybackSpeedButton_Previews" : PlaybackSpeedButton_Previews.self, + "PollFormScreen_Previews" : PollFormScreen_Previews.self, + "PollOptionView_Previews" : PollOptionView_Previews.self, + "PollRoomTimelineView_Previews" : PollRoomTimelineView_Previews.self, + "PollView_Previews" : PollView_Previews.self, + "QRCodeErrorView_Previews" : QRCodeErrorView_Previews.self, + "QRCodeLoginScreen_Previews" : QRCodeLoginScreen_Previews.self, + "ReactionsSummaryView_Previews" : ReactionsSummaryView_Previews.self, + "ReadMarkerRoomTimelineView_Previews" : ReadMarkerRoomTimelineView_Previews.self, + "ReadReceiptCell_Previews" : ReadReceiptCell_Previews.self, + "ReadReceiptsSummaryView_Previews" : ReadReceiptsSummaryView_Previews.self, + "RedactedRoomTimelineView_Previews" : RedactedRoomTimelineView_Previews.self, + "ReportContentScreen_Previews" : ReportContentScreen_Previews.self, + "ReportRoomScreen_Previews" : ReportRoomScreen_Previews.self, + "ResolveVerifiedUserSendFailureScreen_Previews" : ResolveVerifiedUserSendFailureScreen_Previews.self, + "RoomAttachmentPicker_Previews" : RoomAttachmentPicker_Previews.self, + "RoomAvatarImage_Previews" : RoomAvatarImage_Previews.self, + "RoomChangePermissionsScreen_Previews" : RoomChangePermissionsScreen_Previews.self, + "RoomChangeRolesScreenRow_Previews" : RoomChangeRolesScreenRow_Previews.self, + "RoomChangeRolesScreenSelectedItem_Previews" : RoomChangeRolesScreenSelectedItem_Previews.self, + "RoomChangeRolesScreen_Previews" : RoomChangeRolesScreen_Previews.self, + "RoomDetailsEditScreen_Previews" : RoomDetailsEditScreen_Previews.self, + "RoomDirectorySearchCell_Previews" : RoomDirectorySearchCell_Previews.self, + "RoomDirectorySearchScreen_Previews" : RoomDirectorySearchScreen_Previews.self, + "RoomHeaderView_Previews" : RoomHeaderView_Previews.self, + "RoomInviterLabel_Previews" : RoomInviterLabel_Previews.self, + "RoomListFilterView_Previews" : RoomListFilterView_Previews.self, + "RoomListFiltersEmptyStateView_Previews" : RoomListFiltersEmptyStateView_Previews.self, + "RoomListFiltersView_Previews" : RoomListFiltersView_Previews.self, + "RoomMemberDetailsScreen_Previews" : RoomMemberDetailsScreen_Previews.self, + "RoomMembersListMemberCell_Previews" : RoomMembersListMemberCell_Previews.self, + "RoomMembersListScreen_Previews" : RoomMembersListScreen_Previews.self, + "RoomNotificationSettingsCustomSectionView_Previews" : RoomNotificationSettingsCustomSectionView_Previews.self, + "RoomNotificationSettingsScreen_Previews" : RoomNotificationSettingsScreen_Previews.self, + "RoomNotificationSettingsUserDefinedScreen_Previews" : RoomNotificationSettingsUserDefinedScreen_Previews.self, + "RoomPollsHistoryScreen_Previews" : RoomPollsHistoryScreen_Previews.self, + "RoomRolesAndPermissionsScreen_Previews" : RoomRolesAndPermissionsScreen_Previews.self, + "RoomScreenFooterView_Previews" : RoomScreenFooterView_Previews.self, + "RoomScreen_Previews" : RoomScreen_Previews.self, + "RoomSelectionScreen_Previews" : RoomSelectionScreen_Previews.self, + "RoomThreadListScreen_Previews" : RoomThreadListScreen_Previews.self, + "SFNumberedListView_Previews" : SFNumberedListView_Previews.self, + "SearchScreen_Previews" : SearchScreen_Previews.self, + "SecureBackupKeyBackupScreen_Previews" : SecureBackupKeyBackupScreen_Previews.self, + "SecurityAndPrivacyScreen_Previews" : SecurityAndPrivacyScreen_Previews.self, + "SendInviteConfirmationView_Previews" : SendInviteConfirmationView_Previews.self, + "SeparatorMediaEventsTimelineView_Previews" : SeparatorMediaEventsTimelineView_Previews.self, + "SeparatorRoomTimelineView_Previews" : SeparatorRoomTimelineView_Previews.self, + "ServerConfirmationScreen_Previews" : ServerConfirmationScreen_Previews.self, + "SessionVerificationRequestDetailsView_Previews" : SessionVerificationRequestDetailsView_Previews.self, + "SessionVerification_Previews" : SessionVerification_Previews.self, + "ShimmerOverlay_Previews" : ShimmerOverlay_Previews.self, + "SoftLogoutScreen_Previews" : SoftLogoutScreen_Previews.self, + "SpaceAddRoomsScreenSelectedItem_Previews" : SpaceAddRoomsScreenSelectedItem_Previews.self, + "SpaceHeaderTopicSheetView_Previews" : SpaceHeaderTopicSheetView_Previews.self, + "SpaceHeaderView_Previews" : SpaceHeaderView_Previews.self, + "SpaceRemoveChildrenConfirmationView_Previews" : SpaceRemoveChildrenConfirmationView_Previews.self, + "SpaceRoomCell_Previews" : SpaceRoomCell_Previews.self, + "SpaceSettingsScreen_Previews" : SpaceSettingsScreen_Previews.self, + "SpacesScreen_Previews" : SpacesScreen_Previews.self, + "SplashScreen_Previews" : SplashScreen_Previews.self, + "StackedAvatarsView_Previews" : StackedAvatarsView_Previews.self, + "StartChatScreen_Previews" : StartChatScreen_Previews.self, + "StateRoomTimelineView_Previews" : StateRoomTimelineView_Previews.self, + "StaticLocationSheet_Previews" : StaticLocationSheet_Previews.self, + "StickerRoomTimelineView_Previews" : StickerRoomTimelineView_Previews.self, + "SwipeRightAction_Previews" : SwipeRightAction_Previews.self, + "SwipeToReplyView_Previews" : SwipeToReplyView_Previews.self, + "TextRoomTimelineView_Previews" : TextRoomTimelineView_Previews.self, + "ThreadDecorator_Previews" : ThreadDecorator_Previews.self, + "TimelineDeliveryStatusView_Previews" : TimelineDeliveryStatusView_Previews.self, + "TimelineItemBubbledStylerView_Previews" : TimelineItemBubbledStylerView_Previews.self, + "TimelineItemDebugView_Previews" : TimelineItemDebugView_Previews.self, + "TimelineItemMenu_Previews" : TimelineItemMenu_Previews.self, + "TimelineItemSendInfoLabel_Previews" : TimelineItemSendInfoLabel_Previews.self, + "TimelineItemStyler_Previews" : TimelineItemStyler_Previews.self, + "TimelineMediaPreviewRedactConfirmationView_Previews" : TimelineMediaPreviewRedactConfirmationView_Previews.self, + "TimelineReactionView_Previews" : TimelineReactionView_Previews.self, + "TimelineReadReceiptsView_Previews" : TimelineReadReceiptsView_Previews.self, + "TimelineReplyView_Previews" : TimelineReplyView_Previews.self, + "TimelineScrollButton_Previews" : TimelineScrollButton_Previews.self, + "TimelineStartRoomTimelineView_Previews" : TimelineStartRoomTimelineView_Previews.self, + "TimelineThreadSummaryView_Previews" : TimelineThreadSummaryView_Previews.self, + "TombstonedAvatarImage_Previews" : TombstonedAvatarImage_Previews.self, + "ToolbarButton_Previews" : ToolbarButton_Previews.self, + "TypingIndicatorView_Previews" : TypingIndicatorView_Previews.self, + "UnsupportedRoomTimelineView_Previews" : UnsupportedRoomTimelineView_Previews.self, + "UserDetailsEditScreen_Previews" : UserDetailsEditScreen_Previews.self, + "UserIndicatorModalView_Previews" : UserIndicatorModalView_Previews.self, + "UserIndicatorToastView_Previews" : UserIndicatorToastView_Previews.self, + "UserLocationCell_Previews" : UserLocationCell_Previews.self, + "UserProfileCell_Previews" : UserProfileCell_Previews.self, + "VerificationBadge_Previews" : VerificationBadge_Previews.self, + "VideoMediaEventsTimelineView_Previews" : VideoMediaEventsTimelineView_Previews.self, + "VideoRoomTimelineView_Previews" : VideoRoomTimelineView_Previews.self, + "VisualListItem_Previews" : VisualListItem_Previews.self, + "VoiceMessageButton_Previews" : VoiceMessageButton_Previews.self, + "VoiceMessageMediaEventsTimelineView_Previews" : VoiceMessageMediaEventsTimelineView_Previews.self, + "VoiceMessagePreviewComposer_Previews" : VoiceMessagePreviewComposer_Previews.self, + "VoiceMessageRecordingButton_Previews" : VoiceMessageRecordingButton_Previews.self, + "VoiceMessageRecordingComposer_Previews" : VoiceMessageRecordingComposer_Previews.self, + "VoiceMessageRecordingView_Previews" : VoiceMessageRecordingView_Previews.self, + "VoiceMessageRoomPlaybackView_Previews" : VoiceMessageRoomPlaybackView_Previews.self, + "VoiceMessageRoomTimelineView_Previews" : VoiceMessageRoomTimelineView_Previews.self, + "VoiceMessageTrashButton_Previews" : VoiceMessageTrashButton_Previews.self, + "WaveformCursorView_Previews" : WaveformCursorView_Previews.self, + ] + // Previews carrying an @available attribute (e.g. those observing state through the iOS 26 + // Observations-based observe(_:)) can't be referenced unconditionally in this iOS 18 target. + if #available(iOS 26.0, *) { + dictionary["EmojiPickerScreen_Previews"] = EmojiPickerScreen_Previews.self + dictionary["IdentityConfirmationScreen_Previews"] = IdentityConfirmationScreen_Previews.self + dictionary["LinkNewDeviceScreen_Previews"] = LinkNewDeviceScreen_Previews.self + dictionary["LoginScreen_Previews"] = LoginScreen_Previews.self + dictionary["NotificationSettingsScreen_Previews"] = NotificationSettingsScreen_Previews.self + dictionary["RoomDetailsScreen_Previews"] = RoomDetailsScreen_Previews.self + dictionary["SecureBackupLogoutConfirmationScreen_Previews"] = SecureBackupLogoutConfirmationScreen_Previews.self + dictionary["SecureBackupRecoveryKeyScreen_Previews"] = SecureBackupRecoveryKeyScreen_Previews.self + dictionary["SecureBackupScreen_Previews"] = SecureBackupScreen_Previews.self + dictionary["ServerSelection_Previews"] = ServerSelection_Previews.self + dictionary["SettingsScreen_Previews"] = SettingsScreen_Previews.self + dictionary["SpaceAddRoomsScreen_Previews"] = SpaceAddRoomsScreen_Previews.self + dictionary["SpaceScreen_Previews"] = SpaceScreen_Previews.self + dictionary["TimelineMediaPreviewDetailsView_Previews"] = TimelineMediaPreviewDetailsView_Previews.self + dictionary["UserProfileScreen_Previews"] = UserProfileScreen_Previews.self + } + return dictionary + }() } // swiftlint:enable all diff --git a/ElementX/Sources/Screens/Authentication/LoginScreen/View/LoginScreen.swift b/ElementX/Sources/Screens/Authentication/LoginScreen/View/LoginScreen.swift index 108f9c8b5..234cb1244 100644 --- a/ElementX/Sources/Screens/Authentication/LoginScreen/View/LoginScreen.swift +++ b/ElementX/Sources/Screens/Authentication/LoginScreen/View/LoginScreen.swift @@ -123,6 +123,7 @@ struct LoginScreen: View { // MARK: - Previews +@available(iOS 26.0, *) struct LoginScreen_Previews: PreviewProvider, TestablePreview { static let viewModel = makeViewModel() static let credentialsViewModel = makeViewModel(withCredentials: true) diff --git a/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/View/ServerSelectionScreen.swift b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/View/ServerSelectionScreen.swift index 2930c2400..3e00acc02 100644 --- a/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/View/ServerSelectionScreen.swift +++ b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/View/ServerSelectionScreen.swift @@ -91,6 +91,7 @@ struct ServerSelectionScreen: View { // MARK: - Previews +@available(iOS 26.0, *) struct ServerSelection_Previews: PreviewProvider, TestablePreview { static let matrixViewModel = makeViewModel(for: "https://matrix.org") static let emptyViewModel = makeViewModel(for: "") diff --git a/ElementX/Sources/Screens/EmojiPickerScreen/View/EmojiPickerScreen.swift b/ElementX/Sources/Screens/EmojiPickerScreen/View/EmojiPickerScreen.swift index 80e94145e..0a1492d09 100644 --- a/ElementX/Sources/Screens/EmojiPickerScreen/View/EmojiPickerScreen.swift +++ b/ElementX/Sources/Screens/EmojiPickerScreen/View/EmojiPickerScreen.swift @@ -100,6 +100,7 @@ struct EmojiPickerScreen: View { // MARK: - Previews +@available(iOS 26.0, *) struct EmojiPickerScreen_Previews: PreviewProvider, TestablePreview { static let viewModel = EmojiPickerScreenViewModel(itemID: .randomEvent, selectedEmojis: ["😀", "😄"], diff --git a/ElementX/Sources/Screens/FilePreviewScreen/View/TimelineMediaPreviewDetailsView.swift b/ElementX/Sources/Screens/FilePreviewScreen/View/TimelineMediaPreviewDetailsView.swift index d559c7391..990cf2011 100644 --- a/ElementX/Sources/Screens/FilePreviewScreen/View/TimelineMediaPreviewDetailsView.swift +++ b/ElementX/Sources/Screens/FilePreviewScreen/View/TimelineMediaPreviewDetailsView.swift @@ -169,6 +169,7 @@ struct TimelineMediaPreviewDetailsView: View { import UniformTypeIdentifiers +@available(iOS 26.0, *) struct TimelineMediaPreviewDetailsView_Previews: PreviewProvider, TestablePreview { static let viewModel = makeViewModel(contentType: .jpeg, isOutgoing: true) static let loadingViewModel = makeViewModel(contentType: .jpeg, isOutgoing: true, isDownloaded: false) diff --git a/ElementX/Sources/Screens/LinkNewDeviceScreen/View/LinkNewDeviceScreen.swift b/ElementX/Sources/Screens/LinkNewDeviceScreen/View/LinkNewDeviceScreen.swift index 3d0576c74..a27631f3c 100644 --- a/ElementX/Sources/Screens/LinkNewDeviceScreen/View/LinkNewDeviceScreen.swift +++ b/ElementX/Sources/Screens/LinkNewDeviceScreen/View/LinkNewDeviceScreen.swift @@ -103,6 +103,7 @@ struct LinkNewDeviceScreen: View { // MARK: - Previews +@available(iOS 26.0, *) struct LinkNewDeviceScreen_Previews: PreviewProvider, TestablePreview { static let viewModel = makeViewModel(mode: .readyToLink(.idle)) static let verifyingViewModel = makeViewModel(mode: .readyToLink(.verifyingDeviceOwner)) diff --git a/ElementX/Sources/Screens/Onboarding/IdentityConfirmationScreen/View/IdentityConfirmationScreen.swift b/ElementX/Sources/Screens/Onboarding/IdentityConfirmationScreen/View/IdentityConfirmationScreen.swift index df0a2829a..6cec258e6 100644 --- a/ElementX/Sources/Screens/Onboarding/IdentityConfirmationScreen/View/IdentityConfirmationScreen.swift +++ b/ElementX/Sources/Screens/Onboarding/IdentityConfirmationScreen/View/IdentityConfirmationScreen.swift @@ -116,6 +116,7 @@ struct IdentityConfirmationScreen: View { // MARK: - Previews +@available(iOS 26.0, *) struct IdentityConfirmationScreen_Previews: PreviewProvider, TestablePreview { static var viewModel = makeViewModel() static var loadingViewModel = makeViewModel(recoveryState: .unknown) diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift b/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift index 77eb2ba53..dd440e0d3 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift @@ -359,6 +359,7 @@ struct RoomDetailsScreen: View { import MatrixRustSDK +@available(iOS 26.0, *) struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview { static let genericWorldReadableRoomViewModel = makeGenericRoomViewModel(historyVisibility: .worldReadable) static let genericJoinedRoomViewModel = makeGenericRoomViewModel(historyVisibility: .joined) diff --git a/ElementX/Sources/Screens/SecureBackup/SecureBackupLogoutConfirmationScreen/View/SecureBackupLogoutConfirmationScreen.swift b/ElementX/Sources/Screens/SecureBackup/SecureBackupLogoutConfirmationScreen/View/SecureBackupLogoutConfirmationScreen.swift index 52d6051b3..efa506024 100644 --- a/ElementX/Sources/Screens/SecureBackup/SecureBackupLogoutConfirmationScreen/View/SecureBackupLogoutConfirmationScreen.swift +++ b/ElementX/Sources/Screens/SecureBackup/SecureBackupLogoutConfirmationScreen/View/SecureBackupLogoutConfirmationScreen.swift @@ -110,6 +110,7 @@ struct SecureBackupLogoutConfirmationScreen: View { // MARK: - Previews +@available(iOS 26.0, *) struct SecureBackupLogoutConfirmationScreen_Previews: PreviewProvider, TestablePreview { static let viewModel = makeViewModel(mode: .saveRecoveryKey) static let waitingViewModel = makeViewModel(mode: .waitingToStart(hasStalled: false)) diff --git a/ElementX/Sources/Screens/SecureBackup/SecureBackupRecoveryKeyScreen/View/SecureBackupRecoveryKeyScreen.swift b/ElementX/Sources/Screens/SecureBackup/SecureBackupRecoveryKeyScreen/View/SecureBackupRecoveryKeyScreen.swift index 77d7c529d..5110c7654 100644 --- a/ElementX/Sources/Screens/SecureBackup/SecureBackupRecoveryKeyScreen/View/SecureBackupRecoveryKeyScreen.swift +++ b/ElementX/Sources/Screens/SecureBackup/SecureBackupRecoveryKeyScreen/View/SecureBackupRecoveryKeyScreen.swift @@ -237,6 +237,7 @@ private struct RecoveryKeyView: View { // MARK: - Previews +@available(iOS 26.0, *) struct SecureBackupRecoveryKeyScreen_Previews: PreviewProvider, TestablePreview { static let key = "EsTM njec uHYA yHmh dQdW Nj4o bNRU 9jMN XGMc KUNM UFr5 R8GY" static let notSetUpViewModel = viewModel(recoveryState: .disabled) diff --git a/ElementX/Sources/Screens/SecureBackup/SecureBackupScreen/View/SecureBackupScreen.swift b/ElementX/Sources/Screens/SecureBackup/SecureBackupScreen/View/SecureBackupScreen.swift index a5d5b04a1..190bba8d0 100644 --- a/ElementX/Sources/Screens/SecureBackup/SecureBackupScreen/View/SecureBackupScreen.swift +++ b/ElementX/Sources/Screens/SecureBackup/SecureBackupScreen/View/SecureBackupScreen.swift @@ -116,6 +116,7 @@ struct SecureBackupScreen: View { // MARK: - Previews +@available(iOS 26.0, *) struct SecureBackupScreen_Previews: PreviewProvider, TestablePreview { static let bothSetupViewModel = viewModel(keyBackupState: .enabled, recoveryState: .enabled) static let onlyKeyBackupSetUpViewModel = viewModel(keyBackupState: .enabled, recoveryState: .disabled) diff --git a/ElementX/Sources/Screens/Settings/NotificationSettingsScreen/View/NotificationSettingsScreen.swift b/ElementX/Sources/Screens/Settings/NotificationSettingsScreen/View/NotificationSettingsScreen.swift index cd0babb61..0db1b8446 100644 --- a/ElementX/Sources/Screens/Settings/NotificationSettingsScreen/View/NotificationSettingsScreen.swift +++ b/ElementX/Sources/Screens/Settings/NotificationSettingsScreen/View/NotificationSettingsScreen.swift @@ -264,6 +264,7 @@ struct NotificationSettingsScreen: View { // MARK: - Previews +@available(iOS 26.0, *) struct NotificationSettingsScreen_Previews: PreviewProvider, TestablePreview { static let viewModel: NotificationSettingsScreenViewModel = { let appSettings = AppSettings.volatile() diff --git a/ElementX/Sources/Screens/Settings/SettingsScreen/View/SettingsScreen.swift b/ElementX/Sources/Screens/Settings/SettingsScreen/View/SettingsScreen.swift index fae0089aa..18df0f904 100644 --- a/ElementX/Sources/Screens/Settings/SettingsScreen/View/SettingsScreen.swift +++ b/ElementX/Sources/Screens/Settings/SettingsScreen/View/SettingsScreen.swift @@ -255,6 +255,7 @@ struct SettingsScreen: View { // MARK: - Previews +@available(iOS 26.0, *) struct SettingsScreen_Previews: PreviewProvider, TestablePreview { static let viewModel = makeViewModel() static let bugReportDisabledViewModel = makeViewModel(isBugReportServiceEnabled: false) diff --git a/ElementX/Sources/Screens/Spaces/SpaceAddRoomsScreen/View/SpaceAddRoomsScreen.swift b/ElementX/Sources/Screens/Spaces/SpaceAddRoomsScreen/View/SpaceAddRoomsScreen.swift index 694b3197c..0c2394c3e 100644 --- a/ElementX/Sources/Screens/Spaces/SpaceAddRoomsScreen/View/SpaceAddRoomsScreen.swift +++ b/ElementX/Sources/Screens/Spaces/SpaceAddRoomsScreen/View/SpaceAddRoomsScreen.swift @@ -157,6 +157,7 @@ private struct SpaceAddRoomsListRow: View { // MARK: - Previews +@available(iOS 26.0, *) struct SpaceAddRoomsScreen_Previews: PreviewProvider, TestablePreview { static let summaryProvider = RoomSummaryProviderMock(.init(state: .loaded(.mockRooms))) static let viewModel = makeViewModel() diff --git a/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift b/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift index 74dcfd86f..c1d28a41b 100644 --- a/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift +++ b/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift @@ -184,6 +184,7 @@ struct SpaceScreen: View { // MARK: - Previews +@available(iOS 26.0, *) struct SpaceScreen_Previews: PreviewProvider, TestablePreview { static let viewModel = makeViewModel() static let managingViewModel = makeViewModel(isManagingRooms: true) diff --git a/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift b/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift index 4097ea052..2e3af668b 100644 --- a/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift +++ b/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift @@ -106,6 +106,7 @@ struct UserProfileScreen: View { // MARK: - Previews +@available(iOS 26.0, *) struct UserProfileScreen_Previews: PreviewProvider, TestablePreview { static let verifiedUserViewModel = makeViewModel(userID: RoomMemberProxyMock.mockDan.userID) static let otherUserViewModel = makeViewModel(userID: RoomMemberProxyMock.mockAlice.userID) diff --git a/PreviewTests/SupportingFiles/target.yml b/PreviewTests/SupportingFiles/target.yml index a82a6abe5..ae6173051 100644 --- a/PreviewTests/SupportingFiles/target.yml +++ b/PreviewTests/SupportingFiles/target.yml @@ -41,6 +41,8 @@ targets: base: PRODUCT_NAME: PreviewTests PRODUCT_BUNDLE_IDENTIFIER: ${BASE_BUNDLE_IDENTIFIER}.preview.tests + # Requires iOS 26 as the generated tests reference previews gated to the Observations-based observe(_:). + IPHONEOS_DEPLOYMENT_TARGET: '26.0' SWIFT_VERSION: 6.2 SWIFT_APPROACHABLE_CONCURRENCY: YES SWIFT_DEFAULT_ACTOR_ISOLATION: MainActor diff --git a/Tools/Scripts/Templates/SimpleScreenExample/ElementX/View/TemplateScreen.swift b/Tools/Scripts/Templates/SimpleScreenExample/ElementX/View/TemplateScreen.swift index cd37f602c..361305ce2 100644 --- a/Tools/Scripts/Templates/SimpleScreenExample/ElementX/View/TemplateScreen.swift +++ b/Tools/Scripts/Templates/SimpleScreenExample/ElementX/View/TemplateScreen.swift @@ -42,6 +42,7 @@ struct TemplateScreen: View { // MARK: - Previews +@available(iOS 26.0, *) struct TemplateScreen_Previews: PreviewProvider, TestablePreview { static let viewModel = makeViewModel() static let incrementedViewModel = makeViewModel(counterValue: 1) diff --git a/Tools/Sourcery/TestablePreviewsDictionary.stencil b/Tools/Sourcery/TestablePreviewsDictionary.stencil index 15f764459..204496ec6 100644 --- a/Tools/Sourcery/TestablePreviewsDictionary.stencil +++ b/Tools/Sourcery/TestablePreviewsDictionary.stencil @@ -18,11 +18,21 @@ import {{ import }} {% endfor %} enum TestablePreviewsDictionary { - static let dictionary: [String: any PreviewProvider.Type] = [ - {% for type in types.types where (type.implements.TestablePreview or type.based.TestablePreview or type|annotated:"TestablePreview") and type.name != "TestablePreview" %} - "{{ type.name }}" : {{ type.name }}.self, - {% endfor %} - ] + static let dictionary: [String: any PreviewProvider.Type] = { + var dictionary: [String: any PreviewProvider.Type] = [ + {% for type in types.types where (type.implements.TestablePreview or type.based.TestablePreview or type|annotated:"TestablePreview") and type.name != "TestablePreview" and not type.attributes.available %} + "{{ type.name }}" : {{ type.name }}.self, + {% endfor %} + ] + // Previews carrying an @available attribute (e.g. those observing state through the iOS 26 + // Observations-based observe(_:)) can't be referenced unconditionally in this iOS 18 target. + if #available(iOS 26.0, *) { + {% for type in types.types where (type.implements.TestablePreview or type.based.TestablePreview or type|annotated:"TestablePreview") and type.name != "TestablePreview" and type.attributes.available %} + dictionary["{{ type.name }}"] = {{ type.name }}.self + {% endfor %} + } + return dictionary + }() } // swiftlint:enable all diff --git a/UnitTests/Sources/NotificationSettingsEditScreenViewModelTests.swift b/UnitTests/Sources/NotificationSettingsEditScreenViewModelTests.swift index f1ab5893c..d7afff2b7 100644 --- a/UnitTests/Sources/NotificationSettingsEditScreenViewModelTests.swift +++ b/UnitTests/Sources/NotificationSettingsEditScreenViewModelTests.swift @@ -112,8 +112,10 @@ struct NotificationSettingsEditScreenViewModelTests { try await deferred.fulfill() + #expect(viewModel.context.viewState.pendingMode == nil) + var deferredViewState = deferFulfillment(viewModel.context.observe(\.viewState.pendingMode), - transitionValues: [nil, .allMessages, nil]) + transitionValues: [.allMessages, nil]) context.send(viewAction: .setMode(.allMessages)) @@ -150,8 +152,10 @@ struct NotificationSettingsEditScreenViewModelTests { try await deferred.fulfill() + #expect(viewModel.context.viewState.pendingMode == nil) + var deferredViewState = deferFulfillment(viewModel.context.observe(\.viewState.pendingMode), - transitionValues: [nil, .mentionsAndKeywordsOnly, nil]) + transitionValues: [.mentionsAndKeywordsOnly, nil]) context.send(viewAction: .setMode(.mentionsAndKeywordsOnly)) @@ -190,8 +194,10 @@ struct NotificationSettingsEditScreenViewModelTests { try await deferred.fulfill() + #expect(viewModel.context.viewState.pendingMode == nil) + let deferredViewState = deferFulfillment(viewModel.context.observe(\.viewState.pendingMode), - transitionValues: [nil, .allMessages, nil]) + transitionValues: [.allMessages, nil]) context.send(viewAction: .setMode(.allMessages)) @@ -222,8 +228,10 @@ struct NotificationSettingsEditScreenViewModelTests { try await deferred.fulfill() + #expect(viewModel.context.viewState.pendingMode == nil) + let deferredViewState = deferFulfillment(viewModel.context.observe(\.viewState.pendingMode), - transitionValues: [nil, .allMessages, nil]) + transitionValues: [.allMessages, nil]) context.send(viewAction: .setMode(.allMessages)) diff --git a/UnitTests/Sources/RoomNotificationSettingsScreenViewModelTests.swift b/UnitTests/Sources/RoomNotificationSettingsScreenViewModelTests.swift index 3cd6501f0..c054e0dd0 100644 --- a/UnitTests/Sources/RoomNotificationSettingsScreenViewModelTests.swift +++ b/UnitTests/Sources/RoomNotificationSettingsScreenViewModelTests.swift @@ -141,8 +141,10 @@ struct RoomNotificationSettingsScreenViewModelTests { notificationSettingsProxyMock.callbacks.send(.settingsDidChange) try await deferred.fulfill() + #expect(viewModel.context.viewState.isRestoringDefaultSetting == false) + let deferredIsRestoringDefaultSettings = deferFulfillment(viewModel.context.observe(\.viewState.isRestoringDefaultSetting), - transitionValues: [false, true, false]) + transitionValues: [true, false]) viewModel.state.bindings.allowCustomSetting = false viewModel.context.send(viewAction: .changedAllowCustomSettings) @@ -200,8 +202,10 @@ struct RoomNotificationSettingsScreenViewModelTests { notificationSettingsProxyMock.callbacks.send(.settingsDidChange) try await deferred.fulfill() + #expect(viewModel.context.viewState.pendingCustomMode == nil) + var deferredMode = deferFulfillment(viewModel.context.observe(\.viewState.pendingCustomMode), - transitionValues: [nil, .allMessages, nil]) + transitionValues: [.allMessages, nil]) viewModel.context.send(viewAction: .setCustomMode(.allMessages)) try await deferredMode.fulfill() @@ -210,8 +214,10 @@ struct RoomNotificationSettingsScreenViewModelTests { #expect(notificationSettingsProxyMock.setNotificationModeRoomIdModeReceivedArguments?.1 == .allMessages) #expect(notificationSettingsProxyMock.setNotificationModeRoomIdModeCallsCount == 1) + #expect(viewModel.context.viewState.pendingCustomMode == nil) + deferredMode = deferFulfillment(viewModel.context.observe(\.viewState.pendingCustomMode), - transitionValues: [nil, .mute, nil]) + transitionValues: [.mute, nil]) viewModel.context.send(viewAction: .setCustomMode(.mute)) try await deferredMode.fulfill() @@ -222,8 +228,10 @@ struct RoomNotificationSettingsScreenViewModelTests { try await Task.sleep(for: .milliseconds(10)) // Workaround for flaky test + #expect(viewModel.context.viewState.pendingCustomMode == nil) + deferredMode = deferFulfillment(viewModel.context.observe(\.viewState.pendingCustomMode), - transitionValues: [nil, .mentionsAndKeywordsOnly, nil]) + transitionValues: [.mentionsAndKeywordsOnly, nil]) viewModel.context.send(viewAction: .setCustomMode(.mentionsAndKeywordsOnly)) try await deferredMode.fulfill() diff --git a/UnitTests/SupportingFiles/target.yml b/UnitTests/SupportingFiles/target.yml index 5ff8c5bd6..2388cd86e 100644 --- a/UnitTests/SupportingFiles/target.yml +++ b/UnitTests/SupportingFiles/target.yml @@ -45,6 +45,8 @@ targets: base: PRODUCT_NAME: UnitTests PRODUCT_BUNDLE_IDENTIFIER: ${BASE_BUNDLE_IDENTIFIER}.unit.tests + # Requires iOS 26 so tests exercise the Observations-based observe(_:) overload. + IPHONEOS_DEPLOYMENT_TARGET: '26.0' SWIFT_VERSION: 6.2 SWIFT_APPROACHABLE_CONCURRENCY: YES SWIFT_DEFAULT_ACTOR_ISOLATION: MainActor