Forward current composer text to the media upload preview screen as captions

This commit is contained in:
Stefan Ceriu
2026-05-22 10:12:08 +03:00
parent a8cff4ded2
commit ac20ff0fc3
9 changed files with 64 additions and 47 deletions
@@ -426,11 +426,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
case (_, .presentReportContent, .reportContent(let itemID, let senderID, _)): case (_, .presentReportContent, .reportContent(let itemID, let senderID, _)):
presentReportContent(for: itemID, from: senderID) presentReportContent(for: itemID, from: senderID)
case (_, .presentMediaUploadPicker, .mediaUploadPicker(let mode, _)): case (_, .presentMediaUploadPicker, .mediaUploadPicker(let mode, let caption, _)):
guard let timelineController = (context.userInfo as? EventUserInfo)?.timelineController else { guard let timelineController = (context.userInfo as? EventUserInfo)?.timelineController else {
fatalError("Missing required TimelineController") fatalError("Missing required TimelineController")
} }
presentMediaUploadPickerWithMode(mode, timelineController: timelineController, animated: animated) presentMediaUploadPickerWithMode(mode, caption: caption, timelineController: timelineController, animated: animated)
case (_, .presentEmojiPicker, .emojiPicker(let itemID, let selectedEmoji, _)): case (_, .presentEmojiPicker, .emojiPicker(let itemID, let selectedEmoji, _)):
guard let timelineController = (context.userInfo as? EventUserInfo)?.timelineController else { guard let timelineController = (context.userInfo as? EventUserInfo)?.timelineController else {
@@ -537,12 +537,12 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
} }
presentPollForm(mode: mode, timelineController: timelineController) presentPollForm(mode: mode, timelineController: timelineController)
case (_, .presentMediaUploadPreview, .mediaUploadPreview(let mediaURLs, _)): case (_, .presentMediaUploadPreview, .mediaUploadPreview(let mediaURLs, let caption, _)):
guard let timelineController = (context.userInfo as? EventUserInfo)?.timelineController else { guard let timelineController = (context.userInfo as? EventUserInfo)?.timelineController else {
fatalError("Missing required TimelineController") fatalError("Missing required TimelineController")
} }
presentMediaUploadPreviewScreen(for: mediaURLs, timelineController: timelineController, animated: animated) presentMediaUploadPreviewScreen(for: mediaURLs, caption: caption, timelineController: timelineController, animated: animated)
case (_, .presentInviteUsersScreen(let flow), .inviteUsersScreen): case (_, .presentInviteUsersScreen(let flow), .inviteUsersScreen):
presentInviteUsersScreen(flow: flow) presentInviteUsersScreen(flow: flow)
@@ -600,7 +600,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
case .eventFocus(let focusedEvent): case .eventFocus(let focusedEvent):
roomScreenCoordinator?.focusOnEvent(focusedEvent) roomScreenCoordinator?.focusOnEvent(focusedEvent)
case .share(.mediaFiles(_, let mediaFiles)): case .share(.mediaFiles(_, let mediaFiles)):
stateMachine.tryEvent(.presentMediaUploadPreview(mediaURLs: mediaFiles.map(\.url)), stateMachine.tryEvent(.presentMediaUploadPreview(mediaURLs: mediaFiles.map(\.url), caption: nil),
userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) userInfo: EventUserInfo(animated: animated, timelineController: timelineController))
case .share(.text(_, let text)): case .share(.text(_, let text)):
roomScreenCoordinator?.shareText(text) roomScreenCoordinator?.shareText(text)
@@ -645,7 +645,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
switch presentationAction { switch presentationAction {
case .share(.mediaFiles(_, let mediaFiles)): case .share(.mediaFiles(_, let mediaFiles)):
stateMachine.tryEvent(.presentMediaUploadPreview(mediaURLs: mediaFiles.map(\.url)), stateMachine.tryEvent(.presentMediaUploadPreview(mediaURLs: mediaFiles.map(\.url), caption: nil),
userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) userInfo: EventUserInfo(animated: animated, timelineController: timelineController))
case .thread(let rootEventID, let focusEvent): case .thread(let rootEventID, let focusEvent):
stateMachine.tryEvent(.presentThread(threadRootEventID: rootEventID, focusEventID: focusEvent?.eventID)) stateMachine.tryEvent(.presentThread(threadRootEventID: rootEventID, focusEventID: focusEvent?.eventID))
@@ -702,11 +702,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
case .presentReportContent(let itemID, let senderID): case .presentReportContent(let itemID, let senderID):
stateMachine.tryEvent(.presentReportContent(itemID: itemID, stateMachine.tryEvent(.presentReportContent(itemID: itemID,
senderID: senderID)) senderID: senderID))
case .presentMediaUploadPicker(let mode): case .presentMediaUploadPicker(let mode, let caption):
stateMachine.tryEvent(.presentMediaUploadPicker(mode: mode), stateMachine.tryEvent(.presentMediaUploadPicker(mode: mode, caption: caption),
userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) userInfo: EventUserInfo(animated: animated, timelineController: timelineController))
case .presentMediaUploadPreviewScreen(let url): case .presentMediaUploadPreviewScreen(let url, let caption):
stateMachine.tryEvent(.presentMediaUploadPreview(mediaURLs: url), stateMachine.tryEvent(.presentMediaUploadPreview(mediaURLs: url, caption: caption),
userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) userInfo: EventUserInfo(animated: animated, timelineController: timelineController))
case .presentEmojiPicker(let itemID, let selectedEmojis): case .presentEmojiPicker(let itemID, let selectedEmojis):
stateMachine.tryEvent(.presentEmojiPicker(itemID: itemID, selectedEmojis: selectedEmojis), stateMachine.tryEvent(.presentEmojiPicker(itemID: itemID, selectedEmojis: selectedEmojis),
@@ -814,11 +814,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
switch action { switch action {
case .presentReportContent(let itemID, let senderID): case .presentReportContent(let itemID, let senderID):
stateMachine.tryEvent(.presentReportContent(itemID: itemID, senderID: senderID)) stateMachine.tryEvent(.presentReportContent(itemID: itemID, senderID: senderID))
case .presentMediaUploadPicker(let mode): case .presentMediaUploadPicker(let mode, let caption):
stateMachine.tryEvent(.presentMediaUploadPicker(mode: mode), stateMachine.tryEvent(.presentMediaUploadPicker(mode: mode, caption: caption),
userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) userInfo: EventUserInfo(animated: animated, timelineController: timelineController))
case .presentMediaUploadPreviewScreen(let mediaURLs): case .presentMediaUploadPreviewScreen(let mediaURLs, let caption):
stateMachine.tryEvent(.presentMediaUploadPreview(mediaURLs: mediaURLs), stateMachine.tryEvent(.presentMediaUploadPreview(mediaURLs: mediaURLs, caption: caption),
userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) userInfo: EventUserInfo(animated: animated, timelineController: timelineController))
case .presentLocationPicker: case .presentLocationPicker:
stateMachine.tryEvent(.presentMapNavigator(interactionMode: .picker(shouldShowLiveLocationOption: false)), stateMachine.tryEvent(.presentMapNavigator(interactionMode: .picker(shouldShowLiveLocationOption: false)),
@@ -1079,6 +1079,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
} }
private func presentMediaUploadPickerWithMode(_ mode: MediaPickerScreenMode, private func presentMediaUploadPickerWithMode(_ mode: MediaPickerScreenMode,
caption: NSAttributedString,
timelineController: TimelineControllerProtocol, timelineController: TimelineControllerProtocol,
animated: Bool) { animated: Bool) {
let stackCoordinator = NavigationStackCoordinator() let stackCoordinator = NavigationStackCoordinator()
@@ -1093,7 +1094,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
case .cancel: case .cancel:
navigationStackCoordinator.setSheetCoordinator(nil) navigationStackCoordinator.setSheetCoordinator(nil)
case .selectedMediaAtURLs(let urls): case .selectedMediaAtURLs(let urls):
stateMachine.tryEvent(.presentMediaUploadPreview(mediaURLs: urls), stateMachine.tryEvent(.presentMediaUploadPreview(mediaURLs: urls, caption: caption),
userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) userInfo: EventUserInfo(animated: animated, timelineController: timelineController))
} }
} }
@@ -1108,6 +1109,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
} }
private func presentMediaUploadPreviewScreen(for mediaURLs: [URL], private func presentMediaUploadPreviewScreen(for mediaURLs: [URL],
caption: NSAttributedString?,
timelineController: TimelineControllerProtocol, timelineController: TimelineControllerProtocol,
animated: Bool) { animated: Bool) {
let stackCoordinator = NavigationStackCoordinator() let stackCoordinator = NavigationStackCoordinator()
@@ -1119,6 +1121,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
} }
let parameters = MediaUploadPreviewScreenCoordinatorParameters(mediaURLs: mediaURLs, let parameters = MediaUploadPreviewScreenCoordinatorParameters(mediaURLs: mediaURLs,
caption: caption,
title: title, title: title,
isRoomEncrypted: roomProxy.infoPublisher.value.isEncrypted, isRoomEncrypted: roomProxy.infoPublisher.value.isEncrypted,
shouldShowCaptionWarning: flowParameters.appSettings.shouldShowMediaCaptionWarning, shouldShowCaptionWarning: flowParameters.appSettings.shouldShowMediaCaptionWarning,
@@ -66,8 +66,8 @@ extension RoomFlowCoordinator {
case notificationSettings case notificationSettings
case globalNotificationSettings case globalNotificationSettings
case inviteUsersScreen(flow: InviteUsersFlow, previousState: State) case inviteUsersScreen(flow: InviteUsersFlow, previousState: State)
case mediaUploadPicker(mode: MediaPickerScreenMode, previousState: State) case mediaUploadPicker(mode: MediaPickerScreenMode, caption: NSAttributedString, previousState: State)
case mediaUploadPreview(mediaURLs: [URL], previousState: State) case mediaUploadPreview(mediaURLs: [URL], caption: NSAttributedString?, previousState: State)
case emojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>, previousState: State) case emojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>, previousState: State)
case mapNavigator(previousState: State) case mapNavigator(previousState: State)
case messageForwarding(forwardingItem: MessageForwardingItem, previousState: State) case messageForwarding(forwardingItem: MessageForwardingItem, previousState: State)
@@ -139,10 +139,10 @@ extension RoomFlowCoordinator {
case presentInviteUsersScreen(flow: InviteUsersFlow) case presentInviteUsersScreen(flow: InviteUsersFlow)
case dismissInviteUsersScreen case dismissInviteUsersScreen
case presentMediaUploadPicker(mode: MediaPickerScreenMode) case presentMediaUploadPicker(mode: MediaPickerScreenMode, caption: NSAttributedString)
case dismissMediaUploadPicker case dismissMediaUploadPicker
case presentMediaUploadPreview(mediaURLs: [URL]) case presentMediaUploadPreview(mediaURLs: [URL], caption: NSAttributedString?)
case dismissMediaUploadPreview case dismissMediaUploadPreview
case presentEmojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>) case presentEmojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>)
@@ -210,11 +210,11 @@ extension RoomFlowCoordinator {
case (.room, .presentReportContent(let itemID, let senderID)): case (.room, .presentReportContent(let itemID, let senderID)):
return .reportContent(itemID: itemID, senderID: senderID, previousState: fromState) return .reportContent(itemID: itemID, senderID: senderID, previousState: fromState)
case (.room, .presentMediaUploadPicker(let mode)): case (.room, .presentMediaUploadPicker(let mode, let caption)):
return .mediaUploadPicker(mode: mode, previousState: fromState) return .mediaUploadPicker(mode: mode, caption: caption, previousState: fromState)
case (.room, .presentMediaUploadPreview(let mediaURLs)): case (.room, .presentMediaUploadPreview(let mediaURLs, let caption)):
return .mediaUploadPreview(mediaURLs: mediaURLs, previousState: fromState) return .mediaUploadPreview(mediaURLs: mediaURLs, caption: caption, previousState: fromState)
case (.room, .presentEmojiPicker(let itemID, let selectedEmoji)): case (.room, .presentEmojiPicker(let itemID, let selectedEmoji)):
return .emojiPicker(itemID: itemID, selectedEmojis: selectedEmoji, previousState: fromState) return .emojiPicker(itemID: itemID, selectedEmojis: selectedEmoji, previousState: fromState)
@@ -259,11 +259,11 @@ extension RoomFlowCoordinator {
case (.thread, .presentReportContent(let itemID, let senderID)): case (.thread, .presentReportContent(let itemID, let senderID)):
return .reportContent(itemID: itemID, senderID: senderID, previousState: fromState) return .reportContent(itemID: itemID, senderID: senderID, previousState: fromState)
case (.thread, .presentMediaUploadPicker(let mode)): case (.thread, .presentMediaUploadPicker(let mode, let caption)):
return .mediaUploadPicker(mode: mode, previousState: fromState) return .mediaUploadPicker(mode: mode, caption: caption, previousState: fromState)
case (.thread, .presentMediaUploadPreview(let mediaURLs)): case (.thread, .presentMediaUploadPreview(let mediaURLs, let caption)):
return .mediaUploadPreview(mediaURLs: mediaURLs, previousState: fromState) return .mediaUploadPreview(mediaURLs: mediaURLs, caption: caption, previousState: fromState)
case (.thread, .presentEmojiPicker(let itemID, let selectedEmoji)): case (.thread, .presentEmojiPicker(let itemID, let selectedEmoji)):
return .emojiPicker(itemID: itemID, selectedEmojis: selectedEmoji, previousState: fromState) return .emojiPicker(itemID: itemID, selectedEmojis: selectedEmoji, previousState: fromState)
@@ -282,7 +282,7 @@ extension RoomFlowCoordinator {
// Room + Thread // Room + Thread
case (.mediaUploadPicker(_, let previousState), .dismissMediaUploadPicker): case (.mediaUploadPicker(_, _, let previousState), .dismissMediaUploadPicker):
return previousState return previousState
case (.emojiPicker(_, _, let previouState), .dismissEmojiPicker): case (.emojiPicker(_, _, let previouState), .dismissEmojiPicker):
@@ -388,7 +388,7 @@ extension RoomFlowCoordinator {
case (.knockRequestsList(let previousState), .dismissKnockRequestsListScreen): case (.knockRequestsList(let previousState), .dismissKnockRequestsListScreen):
return previousState return previousState
case (.mediaUploadPreview(_, let previousState), .dismissMediaUploadPreview): case (.mediaUploadPreview(_, _, let previousState), .dismissMediaUploadPreview):
return previousState return previousState
case (.notificationSettings, .presentGlobalNotificationSettingsScreen): case (.notificationSettings, .presentGlobalNotificationSettingsScreen):
@@ -401,8 +401,8 @@ extension RoomFlowCoordinator {
case (.pollsHistoryForm, .dismissPollForm): case (.pollsHistoryForm, .dismissPollForm):
return .pollsHistory return .pollsHistory
case (.mediaUploadPicker(_, let previousMediaUploadPickerState), .presentMediaUploadPreview(let mediaURLs)): case (.mediaUploadPicker(_, _, let previousMediaUploadPickerState), .presentMediaUploadPreview(let mediaURLs, let caption)):
return .mediaUploadPreview(mediaURLs: mediaURLs, previousState: previousMediaUploadPickerState) return .mediaUploadPreview(mediaURLs: mediaURLs, caption: caption, previousState: previousMediaUploadPickerState)
case (_, .presentInviteUsersScreen(let flow)): case (_, .presentInviteUsersScreen(let flow)):
return .inviteUsersScreen(flow: flow, previousState: fromState) return .inviteUsersScreen(flow: flow, previousState: fromState)
@@ -11,6 +11,7 @@ import SwiftUI
struct MediaUploadPreviewScreenCoordinatorParameters { struct MediaUploadPreviewScreenCoordinatorParameters {
let mediaURLs: [URL] let mediaURLs: [URL]
let caption: NSAttributedString?
let title: String? let title: String?
let isRoomEncrypted: Bool let isRoomEncrypted: Bool
let shouldShowCaptionWarning: Bool let shouldShowCaptionWarning: Bool
@@ -35,6 +36,7 @@ final class MediaUploadPreviewScreenCoordinator: CoordinatorProtocol {
init(parameters: MediaUploadPreviewScreenCoordinatorParameters) { init(parameters: MediaUploadPreviewScreenCoordinatorParameters) {
viewModel = MediaUploadPreviewScreenViewModel(mediaURLs: parameters.mediaURLs, viewModel = MediaUploadPreviewScreenViewModel(mediaURLs: parameters.mediaURLs,
caption: parameters.caption,
title: parameters.title, title: parameters.title,
isRoomEncrypted: parameters.isRoomEncrypted, isRoomEncrypted: parameters.isRoomEncrypted,
shouldShowCaptionWarning: parameters.shouldShowCaptionWarning, shouldShowCaptionWarning: parameters.shouldShowCaptionWarning,
@@ -22,11 +22,11 @@ struct MediaUploadPreviewScreenViewState: BindableState {
var mediaEditVersion = 0 var mediaEditVersion = 0
var bindings = MediaUploadPreviewScreenBindings() var bindings: MediaUploadPreviewScreenBindings
} }
struct MediaUploadPreviewScreenBindings: BindableState { struct MediaUploadPreviewScreenBindings: BindableState {
var caption = NSAttributedString() var caption: NSAttributedString
var presendCallback: (() -> Void)? var presendCallback: (() -> Void)?
var selectedRange = NSRange(location: 0, length: 0) var selectedRange = NSRange(location: 0, length: 0)
@@ -30,6 +30,7 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
} }
init(mediaURLs: [URL], init(mediaURLs: [URL],
caption: NSAttributedString?,
title: String?, title: String?,
isRoomEncrypted: Bool, isRoomEncrypted: Bool,
shouldShowCaptionWarning: Bool, shouldShowCaptionWarning: Bool,
@@ -49,7 +50,8 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
super.init(initialViewState: MediaUploadPreviewScreenViewState(mediaURLs: mediaURLs, super.init(initialViewState: MediaUploadPreviewScreenViewState(mediaURLs: mediaURLs,
title: title, title: title,
shouldShowCaptionWarning: shouldShowCaptionWarning, shouldShowCaptionWarning: shouldShowCaptionWarning,
isRoomEncrypted: isRoomEncrypted)) isRoomEncrypted: isRoomEncrypted,
bindings: .init(caption: caption ?? NSAttributedString())))
} }
override func process(viewAction: MediaUploadPreviewScreenViewAction) { override func process(viewAction: MediaUploadPreviewScreenViewAction) {
@@ -367,6 +367,7 @@ struct MediaUploadPreviewScreen_Previews: PreviewProvider, TestablePreview {
static let testURL = Bundle.main.url(forResource: "AppIcon60x60@2x", withExtension: "png") static let testURL = Bundle.main.url(forResource: "AppIcon60x60@2x", withExtension: "png")
static let viewModel = MediaUploadPreviewScreenViewModel(mediaURLs: [snapshotURL], static let viewModel = MediaUploadPreviewScreenViewModel(mediaURLs: [snapshotURL],
caption: nil,
title: "App Icon.png", title: "App Icon.png",
isRoomEncrypted: true, isRoomEncrypted: true,
shouldShowCaptionWarning: true, shouldShowCaptionWarning: true,
@@ -34,8 +34,8 @@ struct RoomScreenCoordinatorParameters {
enum RoomScreenCoordinatorAction { enum RoomScreenCoordinatorAction {
case presentReportContent(itemID: TimelineItemIdentifier, senderID: String) case presentReportContent(itemID: TimelineItemIdentifier, senderID: String)
case presentMediaUploadPicker(mode: MediaPickerScreenMode) case presentMediaUploadPicker(mode: MediaPickerScreenMode, caption: NSAttributedString)
case presentMediaUploadPreviewScreen(mediaURLs: [URL]) case presentMediaUploadPreviewScreen(mediaURLs: [URL], caption: NSAttributedString)
case presentRoomDetails case presentRoomDetails
case presentLocationPicker case presentLocationPicker
case presentPollForm(mode: PollFormMode) case presentPollForm(mode: PollFormMode)
@@ -122,11 +122,14 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
case .displayReportContent(let itemID, let senderID): case .displayReportContent(let itemID, let senderID):
actionsSubject.send(.presentReportContent(itemID: itemID, senderID: senderID)) actionsSubject.send(.presentReportContent(itemID: itemID, senderID: senderID))
case .displayCameraPicker: case .displayCameraPicker:
actionsSubject.send(.presentMediaUploadPicker(mode: .init(source: .camera, selectionType: .multiple))) actionsSubject.send(.presentMediaUploadPicker(mode: .init(source: .camera, selectionType: .multiple),
caption: composerViewModel.context.plainComposerText))
case .displayMediaPicker: case .displayMediaPicker:
actionsSubject.send(.presentMediaUploadPicker(mode: .init(source: .photoLibrary, selectionType: .multiple))) actionsSubject.send(.presentMediaUploadPicker(mode: .init(source: .photoLibrary, selectionType: .multiple),
caption: composerViewModel.context.plainComposerText))
case .displayDocumentPicker: case .displayDocumentPicker:
actionsSubject.send(.presentMediaUploadPicker(mode: .init(source: .documents(), selectionType: .multiple))) actionsSubject.send(.presentMediaUploadPicker(mode: .init(source: .documents(), selectionType: .multiple),
caption: composerViewModel.context.plainComposerText))
case .displayMediaPreview(let mediaPreviewViewModel): case .displayMediaPreview(let mediaPreviewViewModel):
roomViewModel.displayMediaPreview(mediaPreviewViewModel) roomViewModel.displayMediaPreview(mediaPreviewViewModel)
case .displayLocationPicker: case .displayLocationPicker:
@@ -134,7 +137,8 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
case .displayPollForm(let mode): case .displayPollForm(let mode):
actionsSubject.send(.presentPollForm(mode: mode)) actionsSubject.send(.presentPollForm(mode: mode))
case .displayMediaUploadPreviewScreen(let mediaURLs): case .displayMediaUploadPreviewScreen(let mediaURLs):
actionsSubject.send(.presentMediaUploadPreviewScreen(mediaURLs: mediaURLs)) actionsSubject.send(.presentMediaUploadPreviewScreen(mediaURLs: mediaURLs,
caption: composerViewModel.context.plainComposerText))
case .displaySenderDetails(userID: let userID): case .displaySenderDetails(userID: let userID):
actionsSubject.send(.presentRoomMemberDetails(userID: userID)) actionsSubject.send(.presentRoomMemberDetails(userID: userID))
case .displayMessageForwarding(let forwardingItem): case .displayMessageForwarding(let forwardingItem):
@@ -30,8 +30,8 @@ struct ThreadTimelineScreenCoordinatorParameters {
enum ThreadTimelineScreenCoordinatorAction { enum ThreadTimelineScreenCoordinatorAction {
case presentReportContent(itemID: TimelineItemIdentifier, senderID: String) case presentReportContent(itemID: TimelineItemIdentifier, senderID: String)
case presentMediaUploadPicker(mode: MediaPickerScreenMode) case presentMediaUploadPicker(mode: MediaPickerScreenMode, caption: NSAttributedString)
case presentMediaUploadPreviewScreen(mediaURLs: [URL]) case presentMediaUploadPreviewScreen(mediaURLs: [URL], caption: NSAttributedString)
case presentLocationPicker case presentLocationPicker
case presentLocationViewer(StaticLocationData) case presentLocationViewer(StaticLocationData)
case presentLiveLocationViewer(sender: TimelineItemSender, initialLiveLocationShare: LiveLocationShare) case presentLiveLocationViewer(sender: TimelineItemSender, initialLiveLocationShare: LiveLocationShare)
@@ -110,11 +110,14 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol {
case .displayReportContent(let itemID, let senderID): case .displayReportContent(let itemID, let senderID):
actionsSubject.send(.presentReportContent(itemID: itemID, senderID: senderID)) actionsSubject.send(.presentReportContent(itemID: itemID, senderID: senderID))
case .displayCameraPicker: case .displayCameraPicker:
actionsSubject.send(.presentMediaUploadPicker(mode: .init(source: .camera, selectionType: .multiple))) actionsSubject.send(.presentMediaUploadPicker(mode: .init(source: .camera, selectionType: .multiple),
caption: composerViewModel.context.plainComposerText))
case .displayMediaPicker: case .displayMediaPicker:
actionsSubject.send(.presentMediaUploadPicker(mode: .init(source: .photoLibrary, selectionType: .multiple))) actionsSubject.send(.presentMediaUploadPicker(mode: .init(source: .photoLibrary, selectionType: .multiple),
caption: composerViewModel.context.plainComposerText))
case .displayDocumentPicker: case .displayDocumentPicker:
actionsSubject.send(.presentMediaUploadPicker(mode: .init(source: .documents(), selectionType: .multiple))) actionsSubject.send(.presentMediaUploadPicker(mode: .init(source: .documents(), selectionType: .multiple),
caption: composerViewModel.context.plainComposerText))
case .displayMediaPreview(let mediaPreviewViewModel): case .displayMediaPreview(let mediaPreviewViewModel):
viewModel.displayMediaPreview(mediaPreviewViewModel) viewModel.displayMediaPreview(mediaPreviewViewModel)
case .displayLocationPicker: case .displayLocationPicker:
@@ -126,7 +129,8 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol {
case .displayPollForm(let mode): case .displayPollForm(let mode):
actionsSubject.send(.presentPollForm(mode: mode)) actionsSubject.send(.presentPollForm(mode: mode))
case .displayMediaUploadPreviewScreen(let mediaURLs): case .displayMediaUploadPreviewScreen(let mediaURLs):
actionsSubject.send(.presentMediaUploadPreviewScreen(mediaURLs: mediaURLs)) actionsSubject.send(.presentMediaUploadPreviewScreen(mediaURLs: mediaURLs,
caption: composerViewModel.context.plainComposerText))
case .displaySenderDetails(userID: let userID): case .displaySenderDetails(userID: let userID):
actionsSubject.send(.presentRoomMemberDetails(userID: userID)) actionsSubject.send(.presentRoomMemberDetails(userID: userID))
case .displayMessageForwarding(let forwardingItem): case .displayMessageForwarding(let forwardingItem):
@@ -288,6 +288,7 @@ final class MediaUploadPreviewScreenViewModelTests {
} }
viewModel = MediaUploadPreviewScreenViewModel(mediaURLs: urls, viewModel = MediaUploadPreviewScreenViewModel(mediaURLs: urls,
caption: nil,
title: "Some File", title: "Some File",
isRoomEncrypted: true, isRoomEncrypted: true,
shouldShowCaptionWarning: true, shouldShowCaptionWarning: true,