diff --git a/ElementX/Sources/FlowCoordinators/MediaEventsTimelineFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/MediaEventsTimelineFlowCoordinator.swift index 7d9920f04..88ca05bdc 100644 --- a/ElementX/Sources/FlowCoordinators/MediaEventsTimelineFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/MediaEventsTimelineFlowCoordinator.swift @@ -10,6 +10,7 @@ import Foundation enum MediaEventsTimelineFlowCoordinatorAction { case viewInRoomTimeline(TimelineItemIdentifier) + case displayMessageForwarding(MessageForwardingItem) case finished } @@ -91,10 +92,13 @@ class MediaEventsTimelineFlowCoordinator: FlowCoordinatorProtocol { coordinator.actions .sink { [weak self] action in + guard let self else { return } switch action { + case .displayMessageForwarding(let forwardingItem): + actionsSubject.send(.displayMessageForwarding(forwardingItem)) case .viewInRoomTimeline(let itemID): - self?.navigationStackCoordinator.pop(animated: false) - self?.actionsSubject.send(.viewInRoomTimeline(itemID)) + navigationStackCoordinator.pop(animated: false) + actionsSubject.send(.viewInRoomTimeline(itemID)) } } .store(in: &cancellables) diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift index f1d573a60..7799a0260 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift @@ -1592,12 +1592,15 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { case .viewInRoomTimeline(let itemID): guard let eventID = itemID.eventID else { MXLog.error("Unable to present room timeline for event \(itemID)") + return } stateMachine.tryEvent(.presentRoom(presentationAction: .eventFocus(.init(eventID: eventID, shouldSetPin: false))), userInfo: EventUserInfo(animated: false)) // No animation so the timeline visible when the preview animates away. case .finished: stateMachine.tryEvent(.dismissMediaEventsTimeline) + case .displayMessageForwarding(let forwardingItem): + stateMachine.tryEvent(.presentMessageForwarding(forwardingItem: forwardingItem)) } } .store(in: &cancellables) diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinatorStateMachine.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinatorStateMachine.swift index ccb18db0e..bee112642 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinatorStateMachine.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinatorStateMachine.swift @@ -198,6 +198,8 @@ extension RoomFlowCoordinator { case (.room, .presentMessageForwarding(let forwardingItem)): return .messageForwarding(forwardingItem: forwardingItem, previousState: fromState) + case (.mediaEventsTimeline, .presentMessageForwarding(forwardingItem: let forwardingItem)): + return .messageForwarding(forwardingItem: forwardingItem, previousState: fromState) case (.room, .presentMapNavigator(_)): return .mapNavigator(previousState: fromState) diff --git a/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewModels.swift b/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewModels.swift index e3c6cfd86..ffff35a18 100644 --- a/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewModels.swift +++ b/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewModels.swift @@ -10,6 +10,7 @@ import SwiftUI enum TimelineMediaPreviewViewModelAction: Equatable { case viewInRoomTimeline(TimelineItemIdentifier) + case displayMessageForwarding(MessageForwardingItem) case dismiss } diff --git a/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewViewModel.swift b/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewViewModel.swift index 9e85b0b5d..935994123 100644 --- a/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewViewModel.swift +++ b/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewViewModel.swift @@ -11,6 +11,8 @@ import Foundation typealias TimelineMediaPreviewViewModelType = StateStoreViewModel class TimelineMediaPreviewViewModel: TimelineMediaPreviewViewModelType { + static let displayMessageForwardingDelay: TimeInterval = 1.0 + let instanceID = UUID() private let timelineViewModel: TimelineViewModelProtocol @@ -86,6 +88,8 @@ class TimelineMediaPreviewViewModel: TimelineMediaPreviewViewModelType { Task { await saveCurrentItem() } case .redact: state.bindings.redactConfirmationItem = item + case .forward(let itemID): + Task { await forwardItem(itemID: itemID) } default: MXLog.error("Received unexpected action: \(action)") } @@ -96,6 +100,12 @@ class TimelineMediaPreviewViewModel: TimelineMediaPreviewViewModelType { } } + private func forwardItem(itemID: TimelineItemIdentifier) async { + guard let forwardingItem = await timelineViewModel.makeForwardingItem(for: itemID) else { return } + state.previewControllerDriver.send(.dismissDetailsSheet) + actionsSubject.send(.displayMessageForwarding(forwardingItem)) + } + private func updateCurrentItem(_ previewItem: TimelineMediaPreviewItem) async { if case let .media(item) = previewItem { item.downloadError = nil // Clear any existing error. diff --git a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenCoordinator.swift b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenCoordinator.swift index 6a9d9898a..7e2547e06 100644 --- a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenCoordinator.swift +++ b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenCoordinator.swift @@ -25,6 +25,7 @@ struct MediaEventsTimelineScreenCoordinatorParameters { enum MediaEventsTimelineScreenCoordinatorAction { case viewInRoomTimeline(TimelineItemIdentifier) + case displayMessageForwarding(MessageForwardingItem) } final class MediaEventsTimelineScreenCoordinator: CoordinatorProtocol { @@ -73,9 +74,12 @@ final class MediaEventsTimelineScreenCoordinator: CoordinatorProtocol { viewModel.actionsPublisher .sink { [weak self] action in + guard let self else { return } switch action { + case .displayMessageForwarding(let forwardingItem): + actionsSubject.send(.displayMessageForwarding(forwardingItem)) case .viewInRoomTimeline(let itemID): - self?.actionsSubject.send(.viewInRoomTimeline(itemID)) + actionsSubject.send(.viewInRoomTimeline(itemID)) } } .store(in: &cancellables) diff --git a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenModels.swift b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenModels.swift index c9cbb3afe..affb53776 100644 --- a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenModels.swift +++ b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenModels.swift @@ -8,6 +8,7 @@ import SwiftUI enum MediaEventsTimelineScreenViewModelAction { + case displayMessageForwarding(MessageForwardingItem) case viewInRoomTimeline(TimelineItemIdentifier) } diff --git a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift index 845ef49d2..941690768 100644 --- a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift +++ b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift @@ -155,6 +155,8 @@ class MediaEventsTimelineScreenViewModel: MediaEventsTimelineScreenViewModelType sheetModel.actions.sink { [weak self] action in guard let self else { return } switch action { + case .displayMessageForwarding(let forwardingItem): + displayMessageForwarding(forwardingItem: forwardingItem) case .viewInRoomTimeline(let itemID): actionsSubject.send(.viewInRoomTimeline(itemID)) case .dismiss: @@ -222,6 +224,8 @@ class MediaEventsTimelineScreenViewModel: MediaEventsTimelineScreenViewModelType viewModel.actions.sink { [weak self] action in guard let self else { return } switch action { + case .displayMessageForwarding(let forwardingItem): + displayMessageForwarding(forwardingItem: forwardingItem) case .viewInRoomTimeline(let itemID): state.bindings.mediaPreviewViewModel = nil actionsSubject.send(.viewInRoomTimeline(itemID)) @@ -241,4 +245,13 @@ class MediaEventsTimelineScreenViewModel: MediaEventsTimelineScreenViewModelType date.formatted(.dateTime.month(.wide).year()) } } + + private func displayMessageForwarding(forwardingItem: MessageForwardingItem) { + state.bindings.mediaPreviewViewModel = nil + state.bindings.mediaPreviewSheetViewModel = nil + // We need a small delay because we need to wait for the presented sheet to be fully dismissed. + DispatchQueue.main.asyncAfter(deadline: .now() + TimelineMediaPreviewViewModel.displayMessageForwardingDelay) { + self.actionsSubject.send(.displayMessageForwarding(forwardingItem)) + } + } } diff --git a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift index 1447d6912..949095717 100644 --- a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift +++ b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift @@ -65,6 +65,8 @@ final class PinnedEventsTimelineScreenCoordinator: CoordinatorProtocol { guard let self else { return } switch action { + case .displayMessageForwarding(let forwardingItem): + actionsSubject.send(.displayMessageForwarding(forwardingItem: forwardingItem)) case .viewInRoomTimeline(let itemID): guard let eventID = itemID.eventID else { fatalError("A pinned event must have an event ID.") } actionsSubject.send(.displayRoomScreenWithFocussedPin(eventID: eventID)) diff --git a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenModels.swift b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenModels.swift index 80c5ee4d5..249261e28 100644 --- a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenModels.swift +++ b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenModels.swift @@ -9,6 +9,7 @@ import Foundation enum PinnedEventsTimelineScreenViewModelAction { case viewInRoomTimeline(itemID: TimelineItemIdentifier) + case displayMessageForwarding(MessageForwardingItem) case dismiss } diff --git a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenViewModel.swift b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenViewModel.swift index d46f2053e..bd83fe164 100644 --- a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenViewModel.swift +++ b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenViewModel.swift @@ -42,11 +42,18 @@ class PinnedEventsTimelineScreenViewModel: PinnedEventsTimelineScreenViewModelTy func displayMediaPreview(_ mediaPreviewViewModel: TimelineMediaPreviewViewModel) { mediaPreviewViewModel.actions.sink { [weak self] action in + guard let self else { return } switch action { + case .displayMessageForwarding(let forwardingItem): + state.bindings.mediaPreviewViewModel = nil + // We need a small delay because we need to wait for the media preview to be fully dismissed. + DispatchQueue.main.asyncAfter(deadline: .now() + TimelineMediaPreviewViewModel.displayMessageForwardingDelay) { + self.actionsSubject.send(.displayMessageForwarding(forwardingItem)) + } case .viewInRoomTimeline(let itemID): - self?.actionsSubject.send(.viewInRoomTimeline(itemID: itemID)) + actionsSubject.send(.viewInRoomTimeline(itemID: itemID)) case .dismiss: - self?.state.bindings.mediaPreviewViewModel = nil + state.bindings.mediaPreviewViewModel = nil } } .store(in: &cancellables) diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift index 012222610..9d109bb97 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift @@ -181,6 +181,8 @@ final class RoomScreenCoordinator: CoordinatorProtocol { actionsSubject.send(.presentKnockRequestsList) case .displayRoom(let roomID, let via): actionsSubject.send(.presentRoom(roomID: roomID, via: via)) + case .displayMessageForwarding(let forwardingItem): + actionsSubject.send(.presentMessageForwarding(forwardingItem: forwardingItem)) } } .store(in: &cancellables) diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift index 145c36041..113ec2fa9 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift @@ -16,6 +16,7 @@ enum RoomScreenViewModelAction: Equatable { case removeComposerFocus case displayKnockRequests case displayRoom(roomID: String, via: [String]) + case displayMessageForwarding(MessageForwardingItem) } enum RoomScreenViewAction { diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index b7ee88e10..1b77b1ab7 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -136,11 +136,18 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol func displayMediaPreview(_ mediaPreviewViewModel: TimelineMediaPreviewViewModel) { mediaPreviewViewModel.actions.sink { [weak self] action in + guard let self else { return } switch action { - case .viewInRoomTimeline: - fatalError("viewInRoomTimeline should not be visible on a room preview.") case .dismiss: - self?.state.bindings.mediaPreviewViewModel = nil + state.bindings.mediaPreviewViewModel = nil + case .displayMessageForwarding(let forwardingItem): + state.bindings.mediaPreviewViewModel = nil + // We need a small delay because we need to wait for the media preview to be fully dismissed. + DispatchQueue.main.asyncAfter(deadline: .now() + TimelineMediaPreviewViewModel.displayMessageForwardingDelay) { + self.actionsSubject.send(.displayMessageForwarding(forwardingItem)) + } + case .viewInRoomTimeline: + fatalError("\(action) should not be visible on a room preview.") } } .store(in: &cancellables) diff --git a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift index d45535531..5cacaf883 100644 --- a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift +++ b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift @@ -88,6 +88,16 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol { } func start() { + viewModel.actionsPublisher + .sink { [weak self] action in + guard let self else { return } + switch action { + case .displayMessageForwarding(let forwardingItem): + actionsSubject.send(.presentMessageForwarding(forwardingItem: forwardingItem)) + } + } + .store(in: &cancellables) + timelineViewModel.actions .sink { [weak self] action in guard let self else { return } diff --git a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenModels.swift b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenModels.swift index 8006f786f..59a1d9762 100644 --- a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenModels.swift +++ b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenModels.swift @@ -7,7 +7,9 @@ import Foundation -enum ThreadTimelineScreenViewModelAction { } +enum ThreadTimelineScreenViewModelAction { + case displayMessageForwarding(MessageForwardingItem) +} struct ThreadTimelineScreenViewState: BindableState { var roomTitle: String diff --git a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenViewModel.swift b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenViewModel.swift index 96bfea584..bd3611160 100644 --- a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenViewModel.swift +++ b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenViewModel.swift @@ -61,11 +61,18 @@ class ThreadTimelineScreenViewModel: ThreadTimelineScreenViewModelType, ThreadTi func displayMediaPreview(_ mediaPreviewViewModel: TimelineMediaPreviewViewModel) { mediaPreviewViewModel.actions.sink { [weak self] action in + guard let self else { return } switch action { case .viewInRoomTimeline: - fatalError("viewInRoomTimeline should not be visible on a thread preview.") + fatalError("\(action) should not be visible on a thread preview.") + case .displayMessageForwarding(let forwardingItem): + state.bindings.mediaPreviewViewModel = nil + // We need a small delay because we need to wait for the media preview to be fully dismissed. + DispatchQueue.main.asyncAfter(deadline: .now() + TimelineMediaPreviewViewModel.displayMessageForwardingDelay) { + self.actionsSubject.send(.displayMessageForwarding(forwardingItem)) + } case .dismiss: - self?.state.bindings.mediaPreviewViewModel = nil + state.bindings.mediaPreviewViewModel = nil } } .store(in: &cancellables) diff --git a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift index dcfe08ca2..0cd7c80c7 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift @@ -270,6 +270,11 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { } } + func makeForwardingItem(for itemID: TimelineItemIdentifier) async -> MessageForwardingItem? { + guard let content = await timelineController.messageEventContent(for: itemID) else { return nil } + return .init(id: itemID, roomID: roomProxy.id, content: content) + } + // MARK: - Private private func handleTappedOnSenderDetails(sender: TimelineItemSender) { @@ -899,8 +904,8 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { // MARK: - Message forwarding private func forwardMessage(itemID: TimelineItemIdentifier) async { - guard let content = await timelineController.messageEventContent(for: itemID) else { return } - actionsSubject.send(.displayMessageForwarding(forwardingItem: .init(id: itemID, roomID: roomProxy.id, content: content))) + guard let forwardingItem = await makeForwardingItem(for: itemID) else { return } + actionsSubject.send(.displayMessageForwarding(forwardingItem: forwardingItem)) } // MARK: Pills diff --git a/ElementX/Sources/Screens/Timeline/TimelineViewModelProtocol.swift b/ElementX/Sources/Screens/Timeline/TimelineViewModelProtocol.swift index eecee50a2..c251646dc 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineViewModelProtocol.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineViewModelProtocol.swift @@ -17,4 +17,7 @@ protocol TimelineViewModelProtocol { func process(composerAction: ComposerToolbarViewModelAction) /// Updates the timeline to show and highlight the item with the corresponding event ID. func focusOnEvent(eventID: String) async + + /// Handles getting the content to forward an item given its item ID. + func makeForwardingItem(for itemID: TimelineItemIdentifier) async -> MessageForwardingItem? } diff --git a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuAction.swift b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuAction.swift index 058a9f45d..96cdc674a 100644 --- a/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuAction.swift +++ b/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMenuAction.swift @@ -131,7 +131,7 @@ enum TimelineItemMenuAction: Identifiable, Hashable { var canAppearInMediaDetails: Bool { switch self { - case .viewInRoomTimeline, .share, .save, .redact: + case .viewInRoomTimeline, .share, .save, .redact, .forward: true default: false diff --git a/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift b/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift index 4f53ff394..0a82e5b1d 100644 --- a/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift +++ b/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift @@ -323,12 +323,27 @@ private extension View { struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview { static let viewModel: TimelineViewModel = { - ServiceLocator.shared.settings.threadsEnabled = true - return TimelineViewModel.mock + let appSettings = AppSettings() + appSettings.threadsEnabled = true + + let roomProxy = JoinedRoomProxyMock(.init()) + return TimelineViewModel(roomProxy: roomProxy, + focussedEventID: nil, + timelineController: MockTimelineController(), + userSession: UserSessionMock(.init()), + mediaPlayerProvider: MediaPlayerProviderMock(), + userIndicatorController: ServiceLocator.shared.userIndicatorController, + appMediator: AppMediatorMock.default, + appSettings: appSettings, + analyticsService: ServiceLocator.shared.analytics, + emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings), + linkMetadataProvider: LinkMetadataProvider(), + timelineControllerFactory: TimelineControllerFactoryMock(.init())) }() static let viewModelWithPins: TimelineViewModel = { - ServiceLocator.shared.settings.threadsEnabled = true + let appSettings = AppSettings() + appSettings.threadsEnabled = true let roomProxy = JoinedRoomProxyMock(.init(name: "Preview Room", pinnedEventIDs: ["pinned"])) return TimelineViewModel(roomProxy: roomProxy, @@ -338,7 +353,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview mediaPlayerProvider: MediaPlayerProviderMock(), userIndicatorController: ServiceLocator.shared.userIndicatorController, appMediator: AppMediatorMock.default, - appSettings: ServiceLocator.shared.settings, + appSettings: appSettings, analyticsService: ServiceLocator.shared.analytics, emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings), linkMetadataProvider: LinkMetadataProvider(), diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/joinedMembersBadgeView.iPad-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/joinedMembersBadgeView.iPad-en-GB-0.png new file mode 100644 index 000000000..5df578e99 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/joinedMembersBadgeView.iPad-en-GB-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2cc67bdf871dd02120f5e380fdf1755d81332c35c904e2818bd27d5f9c8fb9b6 +size 74274 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/joinedMembersBadgeView.iPad-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/joinedMembersBadgeView.iPad-pseudo-0.png new file mode 100644 index 000000000..ca1e2fd41 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/joinedMembersBadgeView.iPad-pseudo-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33bb51b6d23a5bf42945c7d1b93257d7b729fe81b70f5cfbf6a2871c3e462122 +size 75495 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/joinedMembersBadgeView.iPhone-16-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/joinedMembersBadgeView.iPhone-16-en-GB-0.png new file mode 100644 index 000000000..1ea8f992d --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/joinedMembersBadgeView.iPhone-16-en-GB-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad670b56be16888c137dc8060b34a7ff91b07490b4160a9c299af9406bbee477 +size 33301 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/joinedMembersBadgeView.iPhone-16-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/joinedMembersBadgeView.iPhone-16-pseudo-0.png new file mode 100644 index 000000000..d21bc3d59 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/joinedMembersBadgeView.iPhone-16-pseudo-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a886c81562cf3a34b098389e8e5fc5e97e1c3a6d719c41006a28ee537d554fd +size 34819 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPad-en-GB.png index 07f240d0f..8bd49618d 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aa6ed0d0629081afcc922b86d27b0d3547687dbd7a69b8b1be6bb55b47572ff9 -size 126115 +oid sha256:4bdebb424a46a99ad6aedf1c477c236f8a02b35ce4ca21fd0a7b1682bddd0044 +size 130062 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPad-pseudo.png index dcded9f4a..74e209356 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6b90fa3b8e212590d32b5392bca159d6ab87aa68b6f5a41894b08df7d5a7e9b0 -size 135759 +oid sha256:e5765f64f5dd6fcf108ed8d75832a1a82d1d246a50af0c957aaf77568fc96c14 +size 139865 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPhone-16-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPhone-16-en-GB.png index 670a893f7..631cc7405 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPhone-16-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPhone-16-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ceeacead9e4c3dafd66654b48465cc2a563ca103b6c49270dd14ef6d595b4194 -size 78662 +oid sha256:f946edd1fc5bd9ad5172008ae0829dc71016239918dae4505312bb0d8691c1e9 +size 81809 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPhone-16-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPhone-16-pseudo.png index e1a207c48..0c52a5d58 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPhone-16-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Image-iPhone-16-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:459e2955bf05cb30da558b38d0973f147a517e817f41ed2a581c6f9827b3449e -size 88294 +oid sha256:eb35e096e50d72b505f17511cc10dbafbdb3d6bd75488d03541604a1cb9c54d4 +size 92716 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPad-en-GB.png index 01166794e..552fe62ef 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f08e6c7b2f5bca6355e25dc11d33a8af8712ac63ad905ff1c255354a1b185fb2 -size 108014 +oid sha256:34326b90af3706b06a3db702bfc068419df5e313e9ea6e34871d39e573c6dfe0 +size 112687 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPad-pseudo.png index 53523f8e7..f67a27756 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7abad7e0e48e480fb53f6f68bb35654da21cdb98c0f16b97ef9bb1be6a24b48e -size 114917 +oid sha256:9eda1c1794e8e4c26ad973e3181358295449bac44df3841abb6f5506eec7fbcb +size 119856 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPhone-16-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPhone-16-en-GB.png index 5d96ea1b9..415991d8a 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPhone-16-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPhone-16-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:16390a5a292262c44356cfba087399b08305878a19ac38994882269a0642e683 -size 61793 +oid sha256:91b84d0fbaf7c8beb7b866f8f622c7d721bea7494a1a62121d2d131559428ef5 +size 66231 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPhone-16-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPhone-16-pseudo.png index 89fbf0247..773fb1f02 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPhone-16-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Incoming-on-Room-iPhone-16-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:741cbf529043dd003a8180b94ebae71f91ee790f0808650afea1e52e9580a24e -size 68207 +oid sha256:55b819c3e149db5df36777dd9be8779e8d3644d3c92c34d55d2fdc8079bd060d +size 74238 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPad-en-GB.png index c8f1f4271..42b28f785 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:52d9f7aeec96fa06bd189bcb6a5387be38a82a8af0d1ddcb19a2710ba8144c56 -size 120171 +oid sha256:38723c5a2d87690fb1f57ca66ecf696e7c91272a40979449aaa2b0996433a09a +size 123617 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPad-pseudo.png index 1a925440a..6a5038391 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd84aacc5ad5459640ff0dd1ebf312d7b34cfd65b6fa3521bd2223584d81bb07 -size 129280 +oid sha256:d3bbf56dc154230dec9e6a4e456a86e2f616870061ee24d3e090be785bb2375d +size 132971 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPhone-16-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPhone-16-en-GB.png index 8f5ce8033..7e12f8939 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPhone-16-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPhone-16-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:81a204268e94094c076727c8208aacdcc614ea309ec35e208de4405b31644984 -size 72990 +oid sha256:c1ea2752b2825c440c2ce6a93c79505338ba34f597be350dcdfc0260d130302d +size 76307 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPhone-16-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPhone-16-pseudo.png index 773907eb4..1a06ab727 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPhone-16-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Loading-iPhone-16-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3fd2f8dce85962a0b63ff6c8c34e09a67a174c7d141a76dc647f07b5d11b42ab -size 81150 +oid sha256:5cdbc286f8527cd584732a235058ff455ca93b883c904269540649e286b47580 +size 86008 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPad-en-GB.png index 7ddbbc025..7702882e6 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:69456a05b7a366553418e28ef88f2c0b510f1b5aac2982fad3e053fbdb3df017 -size 113743 +oid sha256:527531157a910ae4f7c2e2ffef4a3e986482e1de2b9b366c153dceaf63652d2b +size 117197 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPad-pseudo.png index 14fea6585..34d926543 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b0e15faa23cab6f6b4f61ad5ecb91187eaffd100af6f6e0fa9c14ae5f51d2213 -size 121471 +oid sha256:bc836edafebb818a804ed20932624fae810b2496daf0293553db448d0e0481a6 +size 125172 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPhone-16-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPhone-16-en-GB.png index b19f7f592..022d38767 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPhone-16-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPhone-16-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4f73f08b7b07a057ad75f6e07401da24b3e0526c46b08fe7efd676b1c3d6162c -size 67534 +oid sha256:6eee65dc7f2dc39dca3e6bf868e6c040ddefa910065c5821bde34a0f30290e12 +size 70796 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPhone-16-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPhone-16-pseudo.png index abfac308f..a3695578e 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPhone-16-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineMediaPreviewDetailsView.Unknown-type-iPhone-16-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2502e5b5bea2fb048fe9c121a9965e991246a81820e9deaf9d318928d743c013 -size 74710 +oid sha256:96a69389b506efe0e1d9ce365bad1dafb346e287dbe9c5460b74917362ce218d +size 79452 diff --git a/UnitTests/Sources/AnalyticsSettingsScreenViewModelTests.swift b/UnitTests/Sources/AnalyticsSettingsScreenViewModelTests.swift index 510bdd484..a9b9e8ba7 100644 --- a/UnitTests/Sources/AnalyticsSettingsScreenViewModelTests.swift +++ b/UnitTests/Sources/AnalyticsSettingsScreenViewModelTests.swift @@ -15,6 +15,10 @@ class AnalyticsSettingsScreenViewModelTests: XCTestCase { private var viewModel: AnalyticsSettingsScreenViewModelProtocol! private var context: AnalyticsSettingsScreenViewModelType.Context! + override func setUp() { + AppSettings.resetAllSettings() + } + override func tearDown() { AppSettings.resetAllSettings() }