From a5e1743a7818714ceb115f0f247835bf4140eabd Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 22 Jul 2025 14:03:08 +0300 Subject: [PATCH] Remove the `threadRootEventID` associated value from all the `RoomFlowCoordinatorStateMachine` states and replace them with a `UserInfo` passed `TimelineController`. --- .../RoomFlowCoordinator.swift | 99 +++++++++++-------- .../RoomFlowCoordinatorStateMachine.swift | 47 ++++----- .../MediaUploadPreviewScreenCoordinator.swift | 10 +- .../MediaUploadPreviewScreenViewModel.swift | 15 +-- .../View/MediaUploadPreviewScreen.swift | 6 +- .../MockTimelineController.swift | 6 +- ...diaUploadPreviewScreenViewModelTests.swift | 6 +- 7 files changed, 108 insertions(+), 81 deletions(-) diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift index df3296067..6721ddc35 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift @@ -268,6 +268,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { .store(in: &cancellables) } + // swiftlint:disable:next function_body_length private func setupStateMachine() { addRouteMapping(stateMachine: stateMachine) @@ -280,9 +281,13 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { // Room case (_, .presentRoom(let presentationAction), .room): + guard let timelineController = (context.userInfo as? EventUserInfo)?.timelineController else { + fatalError() + } Task { await self.presentRoom(fromState: context.fromState, presentationAction: presentationAction, + timelineController: timelineController, animated: animated) } case (_, .dismissFlow, .complete): @@ -294,15 +299,18 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { // Thread case (.room, .presentThread(let itemID), .thread): - Task { await self.presentThread(itemID: itemID) } + Task { await self.presentThread(itemID: itemID, animated: animated) } // Thread + Room case (_, .presentReportContent, .reportContent(let itemID, let senderID, _)): presentReportContent(for: itemID, from: senderID) - case (_, .presentMediaUploadPicker, .mediaUploadPicker(let source, let threadRootEventID, _)): - presentMediaUploadPickerWithSource(source, threadRootEventID: threadRootEventID) + case (_, .presentMediaUploadPicker, .mediaUploadPicker(let source, _)): + guard let timelineController = (context.userInfo as? EventUserInfo)?.timelineController else { + fatalError() + } + presentMediaUploadPickerWithSource(source, timelineController: timelineController, animated: animated) case (_, .presentEmojiPicker, .emojiPicker(let itemID, let selectedEmoji, _)): presentEmojiPicker(for: itemID, selectedEmoji: selectedEmoji) @@ -310,8 +318,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { case (_, .presentMessageForwarding(let forwardingItem), .messageForwarding): presentMessageForwarding(with: forwardingItem) - case (_, .presentMapNavigator(let mode, let threadRootEventID), .mapNavigator): - presentMapNavigator(interactionMode: mode, threadRootEventID: threadRootEventID) + case (_, .presentMapNavigator(let mode), .mapNavigator): + guard let timelineController = (context.userInfo as? EventUserInfo)?.timelineController else { + fatalError() + } + presentMapNavigator(interactionMode: mode, timelineController: timelineController, animated: animated) case (_, .presentPollForm(let mode), .pollForm): presentPollForm(mode: mode) @@ -387,8 +398,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { case (.pollsHistory, .presentPollForm(let mode), .pollsHistoryForm): presentPollForm(mode: mode) - case (_, .presentMediaUploadPreview, .mediaUploadPreview(let fileURL, let threadRootEventID, _)): - presentMediaUploadPreviewScreen(for: fileURL, threadRootEventID: threadRootEventID, animated: animated) + case (_, .presentMediaUploadPreview, .mediaUploadPreview(let fileURL, _)): + guard let timelineController = (context.userInfo as? EventUserInfo)?.timelineController else { + fatalError() + } + presentMediaUploadPreviewScreen(for: fileURL, timelineController: timelineController, animated: animated) case (_, .presentInviteUsersScreen, .inviteUsersScreen): presentInviteUsersScreen() @@ -418,9 +432,13 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { /// Updates the navigation stack so it displays the timeline for the given room /// - Parameters: /// - fromState: The state that asked for the room presentation. - /// - focussedEvent: An (optional) struct that contains the event ID that the timeline should be focussed around, and a boolean telling if such event should update the pinned events banner + /// - presentationAction: The action that should happen after the room is presented + /// - timelineController: This room's main timeline controller /// - animated: whether it should animate the transition - private func presentRoom(fromState: State, presentationAction: PresentationAction?, animated: Bool) async { + private func presentRoom(fromState: State, + presentationAction: PresentationAction?, + timelineController: TimelineControllerProtocol, + animated: Bool) async { // If any sheets are presented dismiss them, rely on their dismissal callbacks to transition the state machine // through the correct states before presenting the room navigationStackCoordinator.setSheetCoordinator(nil) @@ -441,8 +459,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { case .eventFocus(let focusedEvent): roomScreenCoordinator?.focusOnEvent(focusedEvent) case .share(.mediaFile(_, let mediaFile)): - stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: mediaFile.url, threadRootEventID: nil), - userInfo: EventUserInfo(animated: animated)) + stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: mediaFile.url), + userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) case .share(.text(_, let text)): roomScreenCoordinator?.shareText(text) case .none: @@ -458,7 +476,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { analytics.trackViewRoom(isDM: roomProxy.infoPublisher.value.isDirect, isSpace: roomProxy.infoPublisher.value.isSpace) - let coordinator = makeRoomScreenCoordinator(presentationAction: presentationAction) + let coordinator = makeRoomScreenCoordinator(presentationAction: presentationAction, animated: animated) roomScreenCoordinator = coordinator if !isChildFlow { @@ -478,8 +496,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { switch presentationAction { case .share(.mediaFile(_, let mediaFile)): - stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: mediaFile.url, threadRootEventID: nil), - userInfo: EventUserInfo(animated: animated)) + stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: mediaFile.url), + userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) case .share(.text), .eventFocus: break // These are both handled in the coordinator's init. case .none: @@ -487,7 +505,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { } } - private func makeRoomScreenCoordinator(presentationAction: PresentationAction?) -> RoomScreenCoordinator { + private func makeRoomScreenCoordinator(presentationAction: PresentationAction?, animated: Bool) -> RoomScreenCoordinator { let userID = userSession.clientProxy.userID let timelineItemFactory = RoomTimelineItemFactory(userID: userID, attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()), @@ -533,22 +551,22 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { stateMachine.tryEvent(.presentReportContent(itemID: itemID, senderID: senderID)) case .presentMediaUploadPicker(let source): - stateMachine.tryEvent(.presentMediaUploadPicker(source: source, - threadRootEventID: nil)) + stateMachine.tryEvent(.presentMediaUploadPicker(source: source), + userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) case .presentMediaUploadPreviewScreen(let url): - stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: url, - threadRootEventID: nil)) + stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: url), + userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) case .presentEmojiPicker(let itemID, let selectedEmojis): stateMachine.tryEvent(.presentEmojiPicker(itemID: itemID, selectedEmojis: selectedEmojis)) case .presentLocationPicker: - stateMachine.tryEvent(.presentMapNavigator(interactionMode: .picker, - threadRootEventID: nil)) + stateMachine.tryEvent(.presentMapNavigator(interactionMode: .picker), + userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) case .presentPollForm(let mode): stateMachine.tryEvent(.presentPollForm(mode: mode)) case .presentLocationViewer(_, let geoURI, let description): - stateMachine.tryEvent(.presentMapNavigator(interactionMode: .viewOnly(geoURI: geoURI, description: description), - threadRootEventID: nil)) + stateMachine.tryEvent(.presentMapNavigator(interactionMode: .viewOnly(geoURI: geoURI, description: description)), + userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) case .presentRoomMemberDetails(userID: let userID): stateMachine.tryEvent(.presentRoomMemberDetails(userID: userID)) case .presentMessageForwarding(let forwardingItem): @@ -575,7 +593,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { return coordinator } - private func presentThread(itemID: TimelineItemIdentifier) async { + private func presentThread(itemID: TimelineItemIdentifier, animated: Bool) async { showLoadingIndicator() defer { hideLoadingIndicator() } @@ -621,20 +639,20 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { case .presentReportContent(let itemID, let senderID): stateMachine.tryEvent(.presentReportContent(itemID: itemID, senderID: senderID)) case .presentMediaUploadPicker(let source, let threadRootEventID): - stateMachine.tryEvent(.presentMediaUploadPicker(source: source, - threadRootEventID: threadRootEventID)) + stateMachine.tryEvent(.presentMediaUploadPicker(source: source), + userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) case .presentMediaUploadPreviewScreen(let url, let threadRootEventID): - stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: url, - threadRootEventID: threadRootEventID)) + stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: url), + userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) case .presentLocationPicker(let threadRootEventID): - stateMachine.tryEvent(.presentMapNavigator(interactionMode: .picker, - threadRootEventID: threadRootEventID)) + stateMachine.tryEvent(.presentMapNavigator(interactionMode: .picker), + userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) case .presentPollForm(let mode): stateMachine.tryEvent(.presentPollForm(mode: mode)) case .presentLocationViewer(_, let geoURI, let description, let threadRootEventID): stateMachine.tryEvent(.presentMapNavigator(interactionMode: .viewOnly(geoURI: geoURI, - description: description), - threadRootEventID: threadRootEventID)) + description: description)), + userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) case .presentEmojiPicker(let itemID, let selectedEmojis): stateMachine.tryEvent(.presentEmojiPicker(itemID: itemID, selectedEmojis: selectedEmojis)) @@ -890,7 +908,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { } private func presentMediaUploadPickerWithSource(_ source: MediaPickerScreenSource, - threadRootEventID: String?) { + timelineController: TimelineControllerProtocol, + animated: Bool) { let stackCoordinator = NavigationStackCoordinator() let mediaPickerCoordinator = MediaPickerScreenCoordinator(userIndicatorController: userIndicatorController, @@ -903,7 +922,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { case .cancel: navigationStackCoordinator.setSheetCoordinator(nil) case .selectMediaAtURL(let url): - stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: url, threadRootEventID: threadRootEventID)) + stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: url), + userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) } } @@ -917,16 +937,16 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { } private func presentMediaUploadPreviewScreen(for url: URL, - threadRootEventID: String?, + timelineController: TimelineControllerProtocol, animated: Bool) { let stackCoordinator = NavigationStackCoordinator() - let parameters = MediaUploadPreviewScreenCoordinatorParameters(userIndicatorController: userIndicatorController, - roomProxy: roomProxy, + let parameters = MediaUploadPreviewScreenCoordinatorParameters(roomProxy: roomProxy, + timelineController: timelineController, + userIndicatorController: userIndicatorController, mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: appSettings), title: url.lastPathComponent, url: url, - threadRootEventID: threadRootEventID, shouldShowCaptionWarning: appSettings.shouldShowMediaCaptionWarning) let mediaUploadPreviewScreenCoordinator = MediaUploadPreviewScreenCoordinator(parameters: parameters) @@ -980,7 +1000,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { } private func presentMapNavigator(interactionMode: StaticLocationInteractionMode, - threadRootEventID: String?) { + timelineController: TimelineControllerProtocol, + animated: Bool) { let stackCoordinator = NavigationStackCoordinator() let params = StaticLocationScreenCoordinatorParameters(interactionMode: interactionMode, diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinatorStateMachine.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinatorStateMachine.swift index c8ed2b56c..4ec4b2b6b 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinatorStateMachine.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinatorStateMachine.swift @@ -57,10 +57,10 @@ extension RoomFlowCoordinator { case roomMemberDetails(userID: String, previousState: State) case userProfile(userID: String, previousState: State) case inviteUsersScreen(previousState: State) - case mediaUploadPicker(source: MediaPickerScreenSource, threadRootEventID: String?, previousState: State) - case mediaUploadPreview(fileURL: URL, threadRootEventID: String?, previousState: State) + case mediaUploadPicker(source: MediaPickerScreenSource, previousState: State) + case mediaUploadPreview(fileURL: URL, previousState: State) case emojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set, previousState: State) - case mapNavigator(threadRootEventID: String?, previousState: State) + case mapNavigator(previousState: State) case messageForwarding(forwardingItem: MessageForwardingItem, previousState: State) case reportContent(itemID: TimelineItemIdentifier, senderID: String, previousState: State) case pollForm(previousState: State) @@ -83,6 +83,7 @@ extension RoomFlowCoordinator { struct EventUserInfo { let animated: Bool + var timelineController: TimelineControllerProtocol? } enum Event: EventType { @@ -122,16 +123,16 @@ extension RoomFlowCoordinator { case presentInviteUsersScreen case dismissInviteUsersScreen - case presentMediaUploadPicker(source: MediaPickerScreenSource, threadRootEventID: String?) + case presentMediaUploadPicker(source: MediaPickerScreenSource) case dismissMediaUploadPicker - case presentMediaUploadPreview(fileURL: URL, threadRootEventID: String?) + case presentMediaUploadPreview(fileURL: URL) case dismissMediaUploadPreview case presentEmojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set) case dismissEmojiPicker - case presentMapNavigator(interactionMode: StaticLocationInteractionMode, threadRootEventID: String?) + case presentMapNavigator(interactionMode: StaticLocationInteractionMode) case dismissMapNavigator case presentMessageForwarding(forwardingItem: MessageForwardingItem) @@ -184,11 +185,11 @@ extension RoomFlowCoordinator { case (.room, .presentReportContent(let itemID, let senderID)): return .reportContent(itemID: itemID, senderID: senderID, previousState: fromState) - case (.room, .presentMediaUploadPicker(let source, let threadRootEventID)): - return .mediaUploadPicker(source: source, threadRootEventID: threadRootEventID, previousState: fromState) + case (.room, .presentMediaUploadPicker(let source)): + return .mediaUploadPicker(source: source, previousState: fromState) - case (.room, .presentMediaUploadPreview(let fileURL, let threadRootEventID)): - return .mediaUploadPreview(fileURL: fileURL, threadRootEventID: threadRootEventID, previousState: fromState) + case (.room, .presentMediaUploadPreview(let fileURL)): + return .mediaUploadPreview(fileURL: fileURL, previousState: fromState) case (.room, .presentEmojiPicker(let itemID, let selectedEmoji)): return .emojiPicker(itemID: itemID, selectedEmojis: selectedEmoji, previousState: fromState) @@ -196,8 +197,8 @@ extension RoomFlowCoordinator { case (.room, .presentMessageForwarding(let forwardingItem)): return .messageForwarding(forwardingItem: forwardingItem, previousState: fromState) - case (.room, .presentMapNavigator(_, let threadRootEventID)): - return .mapNavigator(threadRootEventID: threadRootEventID, previousState: fromState) + case (.room, .presentMapNavigator(_)): + return .mapNavigator(previousState: fromState) case (.room, .presentPollForm): return .pollForm(previousState: fromState) @@ -221,11 +222,11 @@ extension RoomFlowCoordinator { case (.thread, .presentReportContent(let itemID, let senderID)): return .reportContent(itemID: itemID, senderID: senderID, previousState: fromState) - case (.thread, .presentMediaUploadPicker(let source, let threadRootEventID)): - return .mediaUploadPicker(source: source, threadRootEventID: threadRootEventID, previousState: fromState) + case (.thread, .presentMediaUploadPicker(let source)): + return .mediaUploadPicker(source: source, previousState: fromState) - case (.thread, .presentMediaUploadPreview(let fileURL, let threadRootEventID)): - return .mediaUploadPreview(fileURL: fileURL, threadRootEventID: threadRootEventID, previousState: fromState) + case (.thread, .presentMediaUploadPreview(let fileURL)): + return .mediaUploadPreview(fileURL: fileURL, previousState: fromState) case (.thread, .presentEmojiPicker(let itemID, let selectedEmoji)): return .emojiPicker(itemID: itemID, selectedEmojis: selectedEmoji, previousState: fromState) @@ -233,8 +234,8 @@ extension RoomFlowCoordinator { case (.thread, .presentMessageForwarding(let forwardingItem)): return .messageForwarding(forwardingItem: forwardingItem, previousState: fromState) - case (.thread, .presentMapNavigator(_, let threadRootEventID)): - return .mapNavigator(threadRootEventID: threadRootEventID, previousState: fromState) + case (.thread, .presentMapNavigator(_)): + return .mapNavigator(previousState: fromState) case (.thread, .presentPollForm): return .pollForm(previousState: fromState) @@ -244,7 +245,7 @@ extension RoomFlowCoordinator { // Room + Thread - case (.mediaUploadPicker(_, _, let previousState), .dismissMediaUploadPicker): + case (.mediaUploadPicker(_, let previousState), .dismissMediaUploadPicker): return previousState case (.emojiPicker(_, _, let previouState), .dismissEmojiPicker): @@ -256,7 +257,7 @@ extension RoomFlowCoordinator { case (.messageForwarding(_, let previousState), .dismissMessageForwarding): return previousState - case (.mapNavigator(_, let previousState), .dismissMapNavigator): + case (.mapNavigator(let previousState), .dismissMapNavigator): return previousState case (.pollForm(let previousState), .dismissPollForm): @@ -343,7 +344,7 @@ extension RoomFlowCoordinator { case (.knockRequestsList(let previousState), .dismissKnockRequestsListScreen): return previousState - case (.mediaUploadPreview(_, _, let previousState), .dismissMediaUploadPreview): + case (.mediaUploadPreview(_, let previousState), .dismissMediaUploadPreview): return previousState case (.notificationSettings, .presentGlobalNotificationSettingsScreen): @@ -361,8 +362,8 @@ extension RoomFlowCoordinator { case (.pollsHistoryForm, .dismissPollForm): return .pollsHistory - case (.mediaUploadPicker(_, _, let previousMediaUploadPickerState), .presentMediaUploadPreview(let fileURL, let threadRootEventID)): - return .mediaUploadPreview(fileURL: fileURL, threadRootEventID: threadRootEventID, previousState: previousMediaUploadPickerState) + case (.mediaUploadPicker(_, let previousMediaUploadPickerState), .presentMediaUploadPreview(let fileURL)): + return .mediaUploadPreview(fileURL: fileURL, previousState: previousMediaUploadPickerState) case (_, .presentInviteUsersScreen): return .inviteUsersScreen(previousState: fromState) diff --git a/ElementX/Sources/Screens/MediaUploadPreviewScreen/MediaUploadPreviewScreenCoordinator.swift b/ElementX/Sources/Screens/MediaUploadPreviewScreen/MediaUploadPreviewScreenCoordinator.swift index 850c56f64..989402ec7 100644 --- a/ElementX/Sources/Screens/MediaUploadPreviewScreen/MediaUploadPreviewScreenCoordinator.swift +++ b/ElementX/Sources/Screens/MediaUploadPreviewScreen/MediaUploadPreviewScreenCoordinator.swift @@ -9,12 +9,12 @@ import Combine import SwiftUI struct MediaUploadPreviewScreenCoordinatorParameters { - let userIndicatorController: UserIndicatorControllerProtocol let roomProxy: JoinedRoomProxyProtocol + let timelineController: TimelineControllerProtocol + let userIndicatorController: UserIndicatorControllerProtocol let mediaUploadingPreprocessor: MediaUploadingPreprocessor let title: String? let url: URL - let threadRootEventID: String? let shouldShowCaptionWarning: Bool } @@ -32,12 +32,12 @@ final class MediaUploadPreviewScreenCoordinator: CoordinatorProtocol { } init(parameters: MediaUploadPreviewScreenCoordinatorParameters) { - viewModel = MediaUploadPreviewScreenViewModel(userIndicatorController: parameters.userIndicatorController, - roomProxy: parameters.roomProxy, + viewModel = MediaUploadPreviewScreenViewModel(roomProxy: parameters.roomProxy, + timelineController: parameters.timelineController, + userIndicatorController: parameters.userIndicatorController, mediaUploadingPreprocessor: parameters.mediaUploadingPreprocessor, title: parameters.title, url: parameters.url, - threadRootEventID: parameters.threadRootEventID, shouldShowCaptionWarning: parameters.shouldShowCaptionWarning) } diff --git a/ElementX/Sources/Screens/MediaUploadPreviewScreen/MediaUploadPreviewScreenViewModel.swift b/ElementX/Sources/Screens/MediaUploadPreviewScreen/MediaUploadPreviewScreenViewModel.swift index 8f1fccc5a..793da7c40 100644 --- a/ElementX/Sources/Screens/MediaUploadPreviewScreen/MediaUploadPreviewScreenViewModel.swift +++ b/ElementX/Sources/Screens/MediaUploadPreviewScreen/MediaUploadPreviewScreenViewModel.swift @@ -12,11 +12,12 @@ import SwiftUI typealias MediaUploadPreviewScreenViewModelType = StateStoreViewModelV2 class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType, MediaUploadPreviewScreenViewModelProtocol { - private let userIndicatorController: UserIndicatorControllerProtocol private let roomProxy: JoinedRoomProxyProtocol + private let timelineController: TimelineControllerProtocol + private let userIndicatorController: UserIndicatorControllerProtocol + private let mediaUploadingPreprocessor: MediaUploadingPreprocessor private let url: URL - private let threadRootEventID: String? private var processingTask: Task, Never> private var requestHandle: SendAttachmentJoinHandleProtocol? @@ -27,18 +28,18 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType, actionsSubject.eraseToAnyPublisher() } - init(userIndicatorController: UserIndicatorControllerProtocol, - roomProxy: JoinedRoomProxyProtocol, + init(roomProxy: JoinedRoomProxyProtocol, + timelineController: TimelineControllerProtocol, + userIndicatorController: UserIndicatorControllerProtocol, mediaUploadingPreprocessor: MediaUploadingPreprocessor, title: String?, url: URL, - threadRootEventID: String?, shouldShowCaptionWarning: Bool) { - self.userIndicatorController = userIndicatorController self.roomProxy = roomProxy + self.timelineController = timelineController + self.userIndicatorController = userIndicatorController self.mediaUploadingPreprocessor = mediaUploadingPreprocessor self.url = url - self.threadRootEventID = threadRootEventID // Start processing the media whilst the user is reviewing it/adding a caption. processingTask = Task { await mediaUploadingPreprocessor.processMedia(at: url) } diff --git a/ElementX/Sources/Screens/MediaUploadPreviewScreen/View/MediaUploadPreviewScreen.swift b/ElementX/Sources/Screens/MediaUploadPreviewScreen/View/MediaUploadPreviewScreen.swift index 06413fdb4..372cf1bfb 100644 --- a/ElementX/Sources/Screens/MediaUploadPreviewScreen/View/MediaUploadPreviewScreen.swift +++ b/ElementX/Sources/Screens/MediaUploadPreviewScreen/View/MediaUploadPreviewScreen.swift @@ -227,12 +227,12 @@ struct MediaUploadPreviewScreen_Previews: PreviewProvider, TestablePreview { static let snapshotURL = URL.picturesDirectory static let testURL = Bundle.main.url(forResource: "AppIcon60x60@2x", withExtension: "png") - static let viewModel = MediaUploadPreviewScreenViewModel(userIndicatorController: UserIndicatorControllerMock.default, - roomProxy: JoinedRoomProxyMock(.init()), + static let viewModel = MediaUploadPreviewScreenViewModel(roomProxy: JoinedRoomProxyMock(.init()), + timelineController: MockTimelineController(), + userIndicatorController: UserIndicatorControllerMock.default, mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings), title: "App Icon.png", url: snapshotURL, - threadRootEventID: nil, shouldShowCaptionWarning: true) static var previews: some View { NavigationStack { diff --git a/ElementX/Sources/Services/Timeline/TimelineController/MockTimelineController.swift b/ElementX/Sources/Services/Timeline/TimelineController/MockTimelineController.swift index 02cd6e0fd..18ec8a7bc 100644 --- a/ElementX/Sources/Services/Timeline/TimelineController/MockTimelineController.swift +++ b/ElementX/Sources/Services/Timeline/TimelineController/MockTimelineController.swift @@ -115,7 +115,11 @@ class MockTimelineController: TimelineControllerProtocol { intentionalMentions: IntentionalMentions) async { } func sendVoiceMessage(url: URL, audioInfo: AudioInfo, waveform: [UInt16]) async -> Result { - await timelineProxy?.sendVoiceMessage(url: url, audioInfo: audioInfo, waveform: waveform, requestHandle: { _ in }) ?? .success(()) + if let timelineProxy { + return await timelineProxy.sendVoiceMessage(url: url, audioInfo: audioInfo, waveform: waveform) { _ in } + } + + return .success(()) } func toggleReaction(_ reaction: String, to eventID: TimelineItemIdentifier.EventOrTransactionID) async { } diff --git a/UnitTests/Sources/MediaUploadPreviewScreenViewModelTests.swift b/UnitTests/Sources/MediaUploadPreviewScreenViewModelTests.swift index 03c59588b..2eda1621f 100644 --- a/UnitTests/Sources/MediaUploadPreviewScreenViewModelTests.swift +++ b/UnitTests/Sources/MediaUploadPreviewScreenViewModelTests.swift @@ -121,12 +121,12 @@ class MediaUploadPreviewScreenViewModelTests: XCTestCase { let roomProxy = JoinedRoomProxyMock(.init()) roomProxy.timeline = timelineProxy - viewModel = MediaUploadPreviewScreenViewModel(userIndicatorController: UserIndicatorControllerMock(), - roomProxy: roomProxy, + viewModel = MediaUploadPreviewScreenViewModel(roomProxy: roomProxy, + timelineController: MockTimelineController(timelineProxy: timelineProxy), + userIndicatorController: UserIndicatorControllerMock(), mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings), title: "Some File", url: url, - threadRootEventID: nil, shouldShowCaptionWarning: true) }