diff --git a/ElementX/Resources/Localizations/en.lproj/Localizable.strings b/ElementX/Resources/Localizations/en.lproj/Localizable.strings index 14009f0bc..9b58c30ea 100644 --- a/ElementX/Resources/Localizations/en.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/en.lproj/Localizable.strings @@ -117,6 +117,7 @@ "action_view_in_timeline" = "View in timeline"; "action_view_source" = "View source"; "action_yes" = "Yes"; +"action_yes_try_again" = "Yes, try again"; "banner_migrate_to_native_sliding_sync_action" = "Log Out & Upgrade"; "banner_migrate_to_native_sliding_sync_description" = "Your server now supports a new, faster protocol. Log out and log back in to upgrade now. Doing this now will help you avoid a forced logout when the old protocol is removed later."; "banner_migrate_to_native_sliding_sync_force_logout_title" = "Your homeserver no longer supports the old protocol. Please log out and log back in to continue using the app."; @@ -138,7 +139,8 @@ "common_creating_room" = "Creating room…"; "common_current_user_left_room" = "Left room"; "common_dark" = "Dark"; -"common_date_separator_this_month" = "This month"; +"common_date_date_at_time" = "%1$@ at %2$@"; +"common_date_this_month" = "This month"; "common_decryption_error" = "Decryption error"; "common_developer_options" = "Developer options"; "common_device_id" = "Device ID"; @@ -379,7 +381,11 @@ "screen_knock_requests_list_accept_all_alert_description" = "Are you sure you want to accept all requests to join?"; "screen_knock_requests_list_accept_all_alert_title" = "Accept all requests"; "screen_knock_requests_list_accept_all_button_title" = "Accept all"; +"screen_knock_requests_list_accept_all_failed_alert_description" = "We couldn’t accept all requests. Would you like to try again?"; +"screen_knock_requests_list_accept_all_failed_alert_title" = "Failed to accept all requests"; "screen_knock_requests_list_accept_all_loading_title" = "Accepting all requests to join"; +"screen_knock_requests_list_accept_failed_alert_description" = "We couldn’t accept this request. Would you like to try again?"; +"screen_knock_requests_list_accept_failed_alert_title" = "Failed to accept request"; "screen_knock_requests_list_accept_loading_title" = "Accepting request to join"; "screen_knock_requests_list_ban_alert_confirm_button_title" = "Yes, decline and ban"; "screen_knock_requests_list_ban_alert_description" = "Are you sure you want to decline and ban %1$@? This user won’t be able to request access to join this room again."; @@ -389,9 +395,12 @@ "screen_knock_requests_list_decline_alert_description" = "Are you sure you want to decline %1$@ request to join this room?"; "screen_knock_requests_list_decline_alert_title" = "Decline access"; "screen_knock_requests_list_decline_and_ban_action_title" = "Decline and ban"; +"screen_knock_requests_list_decline_failed_alert_description" = "We couldn’t decline this request. Would you like to try again?"; +"screen_knock_requests_list_decline_failed_alert_title" = "Failed to decline request"; "screen_knock_requests_list_decline_loading_title" = "Declining request to join"; "screen_knock_requests_list_empty_state_description" = "When somebody will ask to join the room, you’ll be able to see their request here."; "screen_knock_requests_list_empty_state_title" = "No pending request to join"; +"screen_knock_requests_list_initial_loading_title" = "Loading requests to join…"; "screen_knock_requests_list_title" = "Requests to join"; "screen_media_details_file_format" = "File format"; "screen_media_details_filename" = "File name"; @@ -615,12 +624,14 @@ "screen_login_title_with_homeserver" = "Sign in to %1$@"; "screen_media_browser_delete_confirmation_subtitle" = "This file will be removed from the room and members won’t have access to it."; "screen_media_browser_delete_confirmation_title" = "Delete file?"; -"screen_media_browser_empty_state_subtitle" = "Images and videos uploaded to this room will be shown here."; -"screen_media_browser_empty_state_title" = "No media uploaded yet"; +"screen_media_browser_files_empty_state_subtitle" = "Documents, audio files, and voice messages uploaded to this room will be shown here."; +"screen_media_browser_files_empty_state_title" = "No files uploaded yet"; "screen_media_browser_list_loading_files" = "Loading files…"; "screen_media_browser_list_loading_media" = "Loading media…"; "screen_media_browser_list_mode_files" = "Files"; "screen_media_browser_list_mode_media" = "Media"; +"screen_media_browser_media_empty_state_subtitle" = "Images and videos uploaded to this room will be shown here."; +"screen_media_browser_media_empty_state_title" = "No media uploaded yet"; "screen_media_browser_title" = "Media and files"; "screen_media_picker_error_failed_selection" = "Failed selecting media, please try again."; "screen_migration_message" = "This is a one time process, thanks for waiting."; diff --git a/ElementX/Sources/Generated/Strings.swift b/ElementX/Sources/Generated/Strings.swift index 143b087a5..6ef48306d 100644 --- a/ElementX/Sources/Generated/Strings.swift +++ b/ElementX/Sources/Generated/Strings.swift @@ -270,6 +270,8 @@ internal enum L10n { internal static var actionViewSource: String { return L10n.tr("Localizable", "action_view_source") } /// Yes internal static var actionYes: String { return L10n.tr("Localizable", "action_yes") } + /// Yes, try again + internal static var actionYesTryAgain: String { return L10n.tr("Localizable", "action_yes_try_again") } /// Log Out & Upgrade internal static var bannerMigrateToNativeSlidingSyncAction: String { return L10n.tr("Localizable", "banner_migrate_to_native_sliding_sync_action") } /// Your server now supports a new, faster protocol. Log out and log back in to upgrade now. Doing this now will help you avoid a forced logout when the old protocol is removed later. @@ -314,8 +316,12 @@ internal enum L10n { internal static var commonCurrentUserLeftRoom: String { return L10n.tr("Localizable", "common_current_user_left_room") } /// Dark internal static var commonDark: String { return L10n.tr("Localizable", "common_dark") } + /// %1$@ at %2$@ + internal static func commonDateDateAtTime(_ p1: Any, _ p2: Any) -> String { + return L10n.tr("Localizable", "common_date_date_at_time", String(describing: p1), String(describing: p2)) + } /// This month - internal static var commonDateSeparatorThisMonth: String { return L10n.tr("Localizable", "common_date_separator_this_month") } + internal static var commonDateThisMonth: String { return L10n.tr("Localizable", "common_date_this_month") } /// Decryption error internal static var commonDecryptionError: String { return L10n.tr("Localizable", "common_decryption_error") } /// Developer options @@ -1316,8 +1322,16 @@ internal enum L10n { internal static var screenKnockRequestsListAcceptAllAlertTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_all_alert_title") } /// Accept all internal static var screenKnockRequestsListAcceptAllButtonTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_all_button_title") } + /// We couldn’t accept all requests. Would you like to try again? + internal static var screenKnockRequestsListAcceptAllFailedAlertDescription: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_all_failed_alert_description") } + /// Failed to accept all requests + internal static var screenKnockRequestsListAcceptAllFailedAlertTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_all_failed_alert_title") } /// Accepting all requests to join internal static var screenKnockRequestsListAcceptAllLoadingTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_all_loading_title") } + /// We couldn’t accept this request. Would you like to try again? + internal static var screenKnockRequestsListAcceptFailedAlertDescription: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_failed_alert_description") } + /// Failed to accept request + internal static var screenKnockRequestsListAcceptFailedAlertTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_failed_alert_title") } /// Accepting request to join internal static var screenKnockRequestsListAcceptLoadingTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_accept_loading_title") } /// Yes, decline and ban @@ -1340,12 +1354,18 @@ internal enum L10n { internal static var screenKnockRequestsListDeclineAlertTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_decline_alert_title") } /// Decline and ban internal static var screenKnockRequestsListDeclineAndBanActionTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_decline_and_ban_action_title") } + /// We couldn’t decline this request. Would you like to try again? + internal static var screenKnockRequestsListDeclineFailedAlertDescription: String { return L10n.tr("Localizable", "screen_knock_requests_list_decline_failed_alert_description") } + /// Failed to decline request + internal static var screenKnockRequestsListDeclineFailedAlertTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_decline_failed_alert_title") } /// Declining request to join internal static var screenKnockRequestsListDeclineLoadingTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_decline_loading_title") } /// When somebody will ask to join the room, you’ll be able to see their request here. internal static var screenKnockRequestsListEmptyStateDescription: String { return L10n.tr("Localizable", "screen_knock_requests_list_empty_state_description") } /// No pending request to join internal static var screenKnockRequestsListEmptyStateTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_empty_state_title") } + /// Loading requests to join… + internal static var screenKnockRequestsListInitialLoadingTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_initial_loading_title") } /// Requests to join internal static var screenKnockRequestsListTitle: String { return L10n.tr("Localizable", "screen_knock_requests_list_title") } /// This account has been deactivated. @@ -1372,10 +1392,10 @@ internal enum L10n { internal static var screenMediaBrowserDeleteConfirmationSubtitle: String { return L10n.tr("Localizable", "screen_media_browser_delete_confirmation_subtitle") } /// Delete file? internal static var screenMediaBrowserDeleteConfirmationTitle: String { return L10n.tr("Localizable", "screen_media_browser_delete_confirmation_title") } - /// Images and videos uploaded to this room will be shown here. - internal static var screenMediaBrowserEmptyStateSubtitle: String { return L10n.tr("Localizable", "screen_media_browser_empty_state_subtitle") } - /// No media uploaded yet - internal static var screenMediaBrowserEmptyStateTitle: String { return L10n.tr("Localizable", "screen_media_browser_empty_state_title") } + /// Documents, audio files, and voice messages uploaded to this room will be shown here. + internal static var screenMediaBrowserFilesEmptyStateSubtitle: String { return L10n.tr("Localizable", "screen_media_browser_files_empty_state_subtitle") } + /// No files uploaded yet + internal static var screenMediaBrowserFilesEmptyStateTitle: String { return L10n.tr("Localizable", "screen_media_browser_files_empty_state_title") } /// Loading files… internal static var screenMediaBrowserListLoadingFiles: String { return L10n.tr("Localizable", "screen_media_browser_list_loading_files") } /// Loading media… @@ -1384,6 +1404,10 @@ internal enum L10n { internal static var screenMediaBrowserListModeFiles: String { return L10n.tr("Localizable", "screen_media_browser_list_mode_files") } /// Media internal static var screenMediaBrowserListModeMedia: String { return L10n.tr("Localizable", "screen_media_browser_list_mode_media") } + /// Images and videos uploaded to this room will be shown here. + internal static var screenMediaBrowserMediaEmptyStateSubtitle: String { return L10n.tr("Localizable", "screen_media_browser_media_empty_state_subtitle") } + /// No media uploaded yet + internal static var screenMediaBrowserMediaEmptyStateTitle: String { return L10n.tr("Localizable", "screen_media_browser_media_empty_state_title") } /// Media and files internal static var screenMediaBrowserTitle: String { return L10n.tr("Localizable", "screen_media_browser_title") } /// File format diff --git a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift index a103a42a0..a550bdae6 100644 --- a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift +++ b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift @@ -178,7 +178,7 @@ class MediaEventsTimelineScreenViewModel: MediaEventsTimelineScreenViewModelType private func titleForDate(_ date: Date) -> String { if Calendar.current.isDate(date, equalTo: .now, toGranularity: .month) { - L10n.commonDateSeparatorThisMonth + L10n.commonDateThisMonth } else { date.formatted(.dateTime.month(.wide).year()) } diff --git a/ElementX/Sources/Screens/MediaEventsTimelineScreen/View/MediaEventsTimelineScreen.swift b/ElementX/Sources/Screens/MediaEventsTimelineScreen/View/MediaEventsTimelineScreen.swift index 6957df07b..6a0274b05 100644 --- a/ElementX/Sources/Screens/MediaEventsTimelineScreen/View/MediaEventsTimelineScreen.swift +++ b/ElementX/Sources/Screens/MediaEventsTimelineScreen/View/MediaEventsTimelineScreen.swift @@ -41,22 +41,27 @@ struct MediaEventsTimelineScreen: View { // * flip the grid vertically to counteract the scroll view // but also horizontally to preserve the corect item order // * flip the items on both axes have them render correctly + @ViewBuilder private var mainContent: some View { - ScrollView { - Group { - switch context.viewState.bindings.screenMode { - case .media: - mediaContent - case .files: - filesContent + if context.viewState.groups.isEmpty, !context.viewState.isBackPaginating { + emptyState + } else { + ScrollView { + Group { + switch context.viewState.bindings.screenMode { + case .media: + mediaContent + case .files: + filesContent + } + + header } - - header } - } - .scaleEffect(.init(width: 1, height: -1)) - .onChange(of: context.screenMode) { _, _ in - context.send(viewAction: .changedScreenMode) + .scaleEffect(.init(width: 1, height: -1)) + .onChange(of: context.screenMode) { _, _ in + context.send(viewAction: .changedScreenMode) + } } } @@ -137,7 +142,7 @@ struct MediaEventsTimelineScreen: View { } @ViewBuilder - func viewForTimelineItem(_ item: RoomTimelineItemViewState) -> some View { + private func viewForTimelineItem(_ item: RoomTimelineItemViewState) -> some View { switch item.type { case .image(let timelineItem): ImageMediaEventsTimelineView(timelineItem: timelineItem) @@ -155,36 +160,62 @@ struct MediaEventsTimelineScreen: View { EmptyView() } } + + @ViewBuilder + private var emptyState: some View { + FullscreenDialog(topPadding: UIConstants.iconTopPaddingToNavigationBar, background: .gradient) { + VStack(spacing: 16) { + switch context.screenMode { + case .media: + emptyMedia + case .files: + emptyFiles + } + } + .padding(16) + } bottomContent: { EmptyView() } + } + + private var emptyMedia: some View { + Group { + BigIcon(icon: \.image) + + Text(L10n.screenMediaBrowserMediaEmptyStateTitle) + .foregroundColor(.compound.textPrimary) + .font(.compound.headingMDBold) + .multilineTextAlignment(.center) + + Text(L10n.screenMediaBrowserMediaEmptyStateSubtitle) + .foregroundColor(.compound.textSecondary) + .font(.compound.bodyMD) + .multilineTextAlignment(.center) + } + } + + private var emptyFiles: some View { + Group { + BigIcon(icon: \.document) + + Text(L10n.screenMediaBrowserFilesEmptyStateTitle) + .foregroundColor(.compound.textPrimary) + .font(.compound.headingMDBold) + .multilineTextAlignment(.center) + + Text(L10n.screenMediaBrowserFilesEmptyStateSubtitle) + .foregroundColor(.compound.textSecondary) + .font(.compound.bodyMD) + .multilineTextAlignment(.center) + } + } } // MARK: - Previews struct MediaEventsTimelineScreen_Previews: PreviewProvider, TestablePreview { - static let timelineViewModel: TimelineViewModel = { - let timelineController = MockRoomTimelineController(timelineKind: .media(.mediaFilesScreen)) - return TimelineViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Preview room")), - timelineController: timelineController, - mediaProvider: MediaProviderMock(configuration: .init()), - mediaPlayerProvider: MediaPlayerProviderMock(), - voiceMessageMediaManager: VoiceMessageMediaManagerMock(), - userIndicatorController: UserIndicatorControllerMock(), - appMediator: AppMediatorMock.default, - appSettings: ServiceLocator.shared.settings, - analyticsService: ServiceLocator.shared.analytics, - emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings)) - }() - - static let mediaViewModel = MediaEventsTimelineScreenViewModel(mediaTimelineViewModel: timelineViewModel, - filesTimelineViewModel: timelineViewModel, - mediaProvider: MediaProviderMock(configuration: .init()), - screenMode: .media, - userIndicatorController: UserIndicatorControllerMock()) - - static let filesViewModel = MediaEventsTimelineScreenViewModel(mediaTimelineViewModel: timelineViewModel, - filesTimelineViewModel: timelineViewModel, - mediaProvider: MediaProviderMock(configuration: .init()), - screenMode: .files, - userIndicatorController: UserIndicatorControllerMock()) + static let mediaViewModel = makeViewModel(screenMode: .media) + static let filesViewModel = makeViewModel(screenMode: .files) + static let emptyMediaViewModel = makeViewModel(timelineKind: .detached, screenMode: .media) + static let emptyFilesViewModel = makeViewModel(timelineKind: .detached, screenMode: .files) static var previews: some View { NavigationStack { @@ -196,5 +227,38 @@ struct MediaEventsTimelineScreen_Previews: PreviewProvider, TestablePreview { MediaEventsTimelineScreen(context: filesViewModel.context) } .previewDisplayName("Files") + + NavigationStack { + MediaEventsTimelineScreen(context: emptyMediaViewModel.context) + } + .previewDisplayName("Empty Media") + + NavigationStack { + MediaEventsTimelineScreen(context: emptyFilesViewModel.context) + } + .previewDisplayName("Empty Files") + } + + private static func makeViewModel(timelineKind: TimelineKind = .media(.mediaFilesScreen), + screenMode: MediaEventsTimelineScreenMode) -> MediaEventsTimelineScreenViewModel { + MediaEventsTimelineScreenViewModel(mediaTimelineViewModel: makeTimelineViewModel(timelineKind: timelineKind), + filesTimelineViewModel: makeTimelineViewModel(timelineKind: timelineKind), + mediaProvider: MediaProviderMock(configuration: .init()), + screenMode: screenMode, + userIndicatorController: UserIndicatorControllerMock()) + } + + private static func makeTimelineViewModel(timelineKind: TimelineKind) -> TimelineViewModel { + let timelineController = MockRoomTimelineController(timelineKind: timelineKind) + return TimelineViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Preview room")), + timelineController: timelineController, + mediaProvider: MediaProviderMock(configuration: .init()), + mediaPlayerProvider: MediaPlayerProviderMock(), + voiceMessageMediaManager: VoiceMessageMediaManagerMock(), + userIndicatorController: UserIndicatorControllerMock(), + appMediator: AppMediatorMock.default, + appSettings: ServiceLocator.shared.settings, + analyticsService: ServiceLocator.shared.analytics, + emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings)) } } diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPad-en-GB.Empty-Files.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPad-en-GB.Empty-Files.png new file mode 100644 index 000000000..73dea32c0 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPad-en-GB.Empty-Files.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb3769ea66b8dc7312847f35ee71979324ed2f209a295ee0953afee377eb2176 +size 531223 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPad-en-GB.Empty-Media.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPad-en-GB.Empty-Media.png new file mode 100644 index 000000000..d391e6ac4 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPad-en-GB.Empty-Media.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dfa699d21838219f07d90ae7e0b2e1e28cd9dfc96ce7c47eb6c87d5a421c3e4c +size 524500 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPad-pseudo.Empty-Files.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPad-pseudo.Empty-Files.png new file mode 100644 index 000000000..b50034e36 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPad-pseudo.Empty-Files.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbf40a036347c7da245c280264420c77f47b924f42027c5639b47dd59648182d +size 548028 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPad-pseudo.Empty-Media.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPad-pseudo.Empty-Media.png new file mode 100644 index 000000000..293dfd1be --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPad-pseudo.Empty-Media.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d600dd3d02c2c90a01e7536d6c68095e8bb666cd84ed4750b63296bde09b1dee +size 539182 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPhone-16-en-GB.Empty-Files.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPhone-16-en-GB.Empty-Files.png new file mode 100644 index 000000000..ebc788856 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPhone-16-en-GB.Empty-Files.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ce1c43361e481251f9ee846ed645ae89f1de9442a8c52cd5ef1862b860fb91a +size 341032 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPhone-16-en-GB.Empty-Media.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPhone-16-en-GB.Empty-Media.png new file mode 100644 index 000000000..e8a0ed80b --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPhone-16-en-GB.Empty-Media.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c620f731b5af87b9b7477f717ca38f9b556a49d890bc5a78634d27f49eb27b9 +size 337316 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPhone-16-pseudo.Empty-Files.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPhone-16-pseudo.Empty-Files.png new file mode 100644 index 000000000..1ad118bed --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPhone-16-pseudo.Empty-Files.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b407d22285115eedcc18300d3227b0834fd5d779f5f1c022dff72a4866f4a476 +size 355876 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPhone-16-pseudo.Empty-Media.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPhone-16-pseudo.Empty-Media.png new file mode 100644 index 000000000..9adbee63b --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_mediaEventsTimelineScreen-iPhone-16-pseudo.Empty-Media.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12fe2c7958a06fbe01ee62ba85289c9fad10263aa86f9639dd50dc741776ba9e +size 348701