From bc4da6d6a4cdf813b7e0e738c28cd335a3feeb84 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 28 May 2024 11:32:27 +0200 Subject: [PATCH] ffi: expose the abort handle after sending an event --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 45 ++++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index 0371a72e6ae..017856e94c3 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -219,12 +219,22 @@ impl Timeline { Ok(()) } - pub fn send(self: Arc, msg: Arc) { - RUNTIME.spawn(async move { - if let Err(err) = self.inner.send((*msg).to_owned().with_relation(None).into()).await { + /// Queues an event in the room's sending queue so it's processed for + /// sending later. + /// + /// Returns an abort handle that allows to abort sending, if it hasn't + /// happened yet. + pub async fn send( + self: Arc, + msg: Arc, + ) -> Result { + match self.inner.send((*msg).to_owned().with_relation(None).into()).await { + Ok(handle) => Ok(AbortSendHandle { inner: Mutex::new(Some(handle)) }), + Err(err) => { error!("error when sending a message: {err}"); + Err(anyhow::anyhow!(err).into()) } - }); + } } pub fn send_image( @@ -480,7 +490,7 @@ impl Timeline { Ok(()) } - pub fn send_location( + pub async fn send_location( self: Arc, body: String, geo_uri: String, @@ -504,7 +514,8 @@ impl Timeline { let room_message_event_content = RoomMessageEventContentWithoutRelation::new( MessageType::Location(location_event_message_content), ); - self.send(Arc::new(room_message_event_content)) + // Errors are logged in `Self::send` already. + let _ = self.send(Arc::new(room_message_event_content)).await; } pub async fn toggle_reaction(&self, event_id: String, key: String) -> Result<(), ClientError> { @@ -561,6 +572,28 @@ impl Timeline { } } +#[derive(uniffi::Object)] +pub struct AbortSendHandle { + inner: Mutex>, +} + +#[uniffi::export(async_runtime = "tokio")] +impl AbortSendHandle { + /// Try to abort the sending of the current event. + /// + /// If this returns `true`, then the sending could be aborted, because the + /// event hasn't been sent yet. Otherwise, if this returns `false`, the + /// event had already been sent and could not be aborted. + async fn abort(self: Arc) -> bool { + if let Some(inner) = self.inner.lock().await.take() { + inner.abort().await + } else { + warn!("trying to abort an send handle that's already been actioned"); + false + } + } +} + #[derive(Debug, thiserror::Error, uniffi::Error)] pub enum FocusEventError { #[error("the event id parameter {event_id} is incorrect: {err}")]