mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
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:
committed by
Stefan Ceriu
parent
6481093107
commit
558cdf5be3
@@ -229,15 +229,22 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
func sendAudio(url: URL,
|
||||
audioInfo: AudioInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Sending audio")
|
||||
|
||||
let replyParameters: ReplyParameters? = if let threadRootEventID {
|
||||
ReplyParameters(eventId: threadRootEventID, enforceThread: true, replyWithinThread: false)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
|
||||
do {
|
||||
let handle = try timeline.sendAudio(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||
caption: caption,
|
||||
formattedCaption: nil, // Rust will build this from the caption's markdown.
|
||||
mentions: nil,
|
||||
replyParams: nil,
|
||||
replyParams: replyParameters,
|
||||
useSendQueue: true),
|
||||
audioInfo: audioInfo,
|
||||
progressWatcher: nil)
|
||||
@@ -257,15 +264,22 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
func sendFile(url: URL,
|
||||
fileInfo: FileInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Sending file")
|
||||
|
||||
let replyParameters: ReplyParameters? = if let threadRootEventID {
|
||||
ReplyParameters(eventId: threadRootEventID, enforceThread: true, replyWithinThread: false)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
|
||||
do {
|
||||
let handle = try timeline.sendFile(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||
caption: caption,
|
||||
formattedCaption: nil, // Rust will build this from the caption's markdown.
|
||||
mentions: nil,
|
||||
replyParams: nil,
|
||||
replyParams: replyParameters,
|
||||
useSendQueue: true),
|
||||
fileInfo: fileInfo,
|
||||
progressWatcher: nil)
|
||||
@@ -286,15 +300,22 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
thumbnailURL: URL,
|
||||
imageInfo: ImageInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Sending image")
|
||||
|
||||
let replyParameters: ReplyParameters? = if let threadRootEventID {
|
||||
ReplyParameters(eventId: threadRootEventID, enforceThread: true, replyWithinThread: false)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
|
||||
do {
|
||||
let handle = try timeline.sendImage(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||
caption: caption,
|
||||
formattedCaption: nil, // Rust will build this from the caption's markdown.
|
||||
mentions: nil,
|
||||
replyParams: nil,
|
||||
replyParams: replyParameters,
|
||||
useSendQueue: true),
|
||||
thumbnailPath: thumbnailURL.path(percentEncoded: false),
|
||||
imageInfo: imageInfo,
|
||||
@@ -316,7 +337,8 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
geoURI: GeoURI,
|
||||
description: String?,
|
||||
zoomLevel: UInt8?,
|
||||
assetType: AssetType?) async -> Result<Void, TimelineProxyError> {
|
||||
assetType: AssetType?,
|
||||
threadRootEventID: String?) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Sending location")
|
||||
|
||||
await timeline.sendLocation(body: body,
|
||||
@@ -334,15 +356,22 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
thumbnailURL: URL,
|
||||
videoInfo: VideoInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Sending video")
|
||||
|
||||
let replyParameters: ReplyParameters? = if let threadRootEventID {
|
||||
ReplyParameters(eventId: threadRootEventID, enforceThread: true, replyWithinThread: false)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
|
||||
do {
|
||||
let handle = try timeline.sendVideo(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||
caption: caption,
|
||||
formattedCaption: nil,
|
||||
mentions: nil,
|
||||
replyParams: nil,
|
||||
replyParams: replyParameters,
|
||||
useSendQueue: true),
|
||||
thumbnailPath: thumbnailURL.path(percentEncoded: false),
|
||||
videoInfo: videoInfo,
|
||||
@@ -363,15 +392,22 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
func sendVoiceMessage(url: URL,
|
||||
audioInfo: AudioInfo,
|
||||
waveform: [UInt16],
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Sending voice message")
|
||||
|
||||
let replyParameters: ReplyParameters? = if let threadRootEventID {
|
||||
ReplyParameters(eventId: threadRootEventID, enforceThread: true, replyWithinThread: false)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
|
||||
do {
|
||||
let handle = try timeline.sendVoiceMessage(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||
caption: nil,
|
||||
formattedCaption: nil,
|
||||
mentions: nil,
|
||||
replyParams: nil,
|
||||
replyParams: replyParameters,
|
||||
useSendQueue: true),
|
||||
audioInfo: audioInfo,
|
||||
waveform: waveform,
|
||||
@@ -481,7 +517,9 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
|
||||
// MARK: - Polls
|
||||
|
||||
func createPoll(question: String, answers: [String], pollKind: Poll.Kind) async -> Result<Void, TimelineProxyError> {
|
||||
func createPoll(question: String, answers: [String],
|
||||
pollKind: Poll.Kind,
|
||||
threadRootEventID: String? = nil) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Creating poll")
|
||||
|
||||
do {
|
||||
|
||||
@@ -82,34 +82,40 @@ protocol TimelineProxyProtocol {
|
||||
func sendAudio(url: URL,
|
||||
audioInfo: AudioInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func sendFile(url: URL,
|
||||
fileInfo: FileInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func sendImage(url: URL,
|
||||
thumbnailURL: URL,
|
||||
imageInfo: ImageInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func sendLocation(body: String,
|
||||
geoURI: GeoURI,
|
||||
description: String?,
|
||||
zoomLevel: UInt8?,
|
||||
assetType: AssetType?) async -> Result<Void, TimelineProxyError>
|
||||
assetType: AssetType?,
|
||||
threadRootEventID: String?) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func sendVideo(url: URL,
|
||||
thumbnailURL: URL,
|
||||
videoInfo: VideoInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func sendVoiceMessage(url: URL,
|
||||
audioInfo: AudioInfo,
|
||||
waveform: [UInt16],
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func sendReadReceipt(for eventID: String, type: ReceiptType) async -> Result<Void, TimelineProxyError>
|
||||
@@ -124,7 +130,7 @@ protocol TimelineProxyProtocol {
|
||||
|
||||
func toggleReaction(_ reaction: String, to eventID: TimelineItemIdentifier.EventOrTransactionID) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func createPoll(question: String, answers: [String], pollKind: Poll.Kind) async -> Result<Void, TimelineProxyError>
|
||||
func createPoll(question: String, answers: [String], pollKind: Poll.Kind, threadRootEventID: String?) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func editPoll(original eventID: String,
|
||||
question: String,
|
||||
|
||||
@@ -144,7 +144,9 @@ class VoiceMessageRecorder: VoiceMessageRecorderProtocol {
|
||||
return .success(waveformData)
|
||||
}
|
||||
|
||||
func sendVoiceMessage(inRoom roomProxy: JoinedRoomProxyProtocol, audioConverter: AudioConverterProtocol) async -> Result<Void, VoiceMessageRecorderError> {
|
||||
func sendVoiceMessage(inRoom roomProxy: JoinedRoomProxyProtocol,
|
||||
audioConverter: AudioConverterProtocol,
|
||||
threadRootEventID: String?) async -> Result<Void, VoiceMessageRecorderError> {
|
||||
guard let url = audioRecorder.audioFileURL else {
|
||||
return .failure(VoiceMessageRecorderError.missingRecordingFile)
|
||||
}
|
||||
@@ -178,7 +180,8 @@ class VoiceMessageRecorder: VoiceMessageRecorderProtocol {
|
||||
|
||||
let result = await roomProxy.timeline.sendVoiceMessage(url: oggFile,
|
||||
audioInfo: audioInfo,
|
||||
waveform: waveform) { _ in }
|
||||
waveform: waveform,
|
||||
threadRootEventID: threadRootEventID) { _ in }
|
||||
|
||||
if case .failure(let error) = result {
|
||||
MXLog.error("Failed to send the voice message. \(error)")
|
||||
|
||||
@@ -38,7 +38,9 @@ protocol VoiceMessageRecorderProtocol {
|
||||
func seekPlayback(to progress: Double) async
|
||||
func deleteRecording() async
|
||||
|
||||
func sendVoiceMessage(inRoom roomProxy: JoinedRoomProxyProtocol, audioConverter: AudioConverterProtocol) async -> Result<Void, VoiceMessageRecorderError>
|
||||
func sendVoiceMessage(inRoom roomProxy: JoinedRoomProxyProtocol,
|
||||
audioConverter: AudioConverterProtocol,
|
||||
threadRootEventID: String?) async -> Result<Void, VoiceMessageRecorderError>
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
|
||||
Reference in New Issue
Block a user