Add support for sending media within threads.

This patch add the `threadRootEventID` as a parameter to media sending functions and forwards the timeline thread root between various application states to the place where its needed.
The 2 missing items are Locations and Polls which currently don't have any support on the Rust side for being sent within threads. That will come in a separate PR.
This commit is contained in:
Stefan Ceriu
2025-06-10 17:18:32 +03:00
committed by Stefan Ceriu
parent 6481093107
commit 558cdf5be3
18 changed files with 340 additions and 247 deletions
@@ -14,6 +14,7 @@ struct MediaUploadPreviewScreenCoordinatorParameters {
let mediaUploadingPreprocessor: MediaUploadingPreprocessor
let title: String?
let url: URL
let threadRootEventID: String?
let shouldShowCaptionWarning: Bool
}
@@ -36,6 +37,7 @@ final class MediaUploadPreviewScreenCoordinator: CoordinatorProtocol {
mediaUploadingPreprocessor: parameters.mediaUploadingPreprocessor,
title: parameters.title,
url: parameters.url,
threadRootEventID: parameters.threadRootEventID,
shouldShowCaptionWarning: parameters.shouldShowCaptionWarning)
}
@@ -16,6 +16,7 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
private let roomProxy: JoinedRoomProxyProtocol
private let mediaUploadingPreprocessor: MediaUploadingPreprocessor
private let url: URL
private let threadRootEventID: String?
private var processingTask: Task<Result<MediaInfo, MediaUploadingPreprocessorError>, Never>
private var requestHandle: SendAttachmentJoinHandleProtocol?
@@ -31,11 +32,13 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
mediaUploadingPreprocessor: MediaUploadingPreprocessor,
title: String?,
url: URL,
threadRootEventID: String?,
shouldShowCaptionWarning: Bool) {
self.userIndicatorController = userIndicatorController
self.roomProxy = roomProxy
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) }
@@ -57,7 +60,9 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
Task {
switch await processingTask.value {
case .success(let mediaInfo):
switch await sendAttachment(mediaInfo: mediaInfo, caption: caption) {
switch await sendAttachment(mediaInfo: mediaInfo,
caption: caption,
threadRootEventID: threadRootEventID) {
case .success:
actionsSubject.send(.dismiss)
case .failure(let error):
@@ -85,7 +90,7 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
// MARK: - Private
private func sendAttachment(mediaInfo: MediaInfo, caption: String?) async -> Result<Void, TimelineProxyError> {
private func sendAttachment(mediaInfo: MediaInfo, caption: String?, threadRootEventID: String?) async -> Result<Void, TimelineProxyError> {
let requestHandle: ((SendAttachmentJoinHandleProtocol) -> Void) = { [weak self] handle in
self?.requestHandle = handle
}
@@ -96,22 +101,26 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
thumbnailURL: thumbnailURL,
imageInfo: imageInfo,
caption: caption,
threadRootEventID: threadRootEventID,
requestHandle: requestHandle)
case let .video(videoURL, thumbnailURL, videoInfo):
return await roomProxy.timeline.sendVideo(url: videoURL,
thumbnailURL: thumbnailURL,
videoInfo: videoInfo,
caption: caption,
threadRootEventID: threadRootEventID,
requestHandle: requestHandle)
case let .audio(audioURL, audioInfo):
return await roomProxy.timeline.sendAudio(url: audioURL,
audioInfo: audioInfo,
caption: caption,
threadRootEventID: threadRootEventID,
requestHandle: requestHandle)
case let .file(fileURL, fileInfo):
return await roomProxy.timeline.sendFile(url: fileURL,
fileInfo: fileInfo,
caption: caption,
threadRootEventID: threadRootEventID,
requestHandle: requestHandle)
}
}
@@ -232,6 +232,7 @@ struct MediaUploadPreviewScreen_Previews: PreviewProvider, TestablePreview {
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings),
title: "App Icon.png",
url: snapshotURL,
threadRootEventID: nil,
shouldShowCaptionWarning: true)
static var previews: some View {
NavigationStack {