Remove the threadRootEventID associated value from all the RoomFlowCoordinatorStateMachine states and replace them with a UserInfo passed TimelineController.

This commit is contained in:
Stefan Ceriu
2025-07-22 14:03:08 +03:00
committed by Stefan Ceriu
parent 6b94c538bf
commit a5e1743a78
7 changed files with 108 additions and 81 deletions

View File

@@ -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,

View File

@@ -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<String>, 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<String>)
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)

View File

@@ -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)
}

View File

@@ -12,11 +12,12 @@ import SwiftUI
typealias MediaUploadPreviewScreenViewModelType = StateStoreViewModelV2<MediaUploadPreviewScreenViewState, MediaUploadPreviewScreenViewAction>
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<Result<MediaInfo, MediaUploadingPreprocessorError>, 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) }

View File

@@ -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 {

View File

@@ -115,7 +115,11 @@ class MockTimelineController: TimelineControllerProtocol {
intentionalMentions: IntentionalMentions) async { }
func sendVoiceMessage(url: URL, audioInfo: AudioInfo, waveform: [UInt16]) async -> Result<Void, TimelineProxyError> {
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 { }

View File

@@ -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)
}