From 536e7fd1bb77e81d60586c614dfddd1dbef6f6ed Mon Sep 17 00:00:00 2001 From: Timo Date: Wed, 31 Jul 2024 19:29:29 +0200 Subject: [PATCH] WidgetDriver: Introduce new capabilities for sending and updating delayed events. Those capabilities are also exposed to the FFI. + related tests --- bindings/matrix-sdk-ffi/src/widget.rs | 10 +++++ crates/matrix-sdk/src/widget/capabilities.rs | 46 +++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/widget.rs b/bindings/matrix-sdk-ffi/src/widget.rs index 73d9e7080ab..c564d51120a 100644 --- a/bindings/matrix-sdk-ffi/src/widget.rs +++ b/bindings/matrix-sdk-ffi/src/widget.rs @@ -318,6 +318,8 @@ pub fn get_element_call_required_permissions( }, ], requires_client: true, + update_delayed_event: true, + send_delayed_event: true, } } @@ -379,6 +381,10 @@ pub struct WidgetCapabilities { /// This means clients should not offer to open the widget in a separate /// browser/tab/webview that is not connected to the postmessage widget-api. pub requires_client: bool, + /// This allows the widget to ask the client to update delayed events. + pub update_delayed_event: bool, + /// This allows the widget to send events with a delay. + pub send_delayed_event: bool, } impl From for matrix_sdk::widget::Capabilities { @@ -387,6 +393,8 @@ impl From for matrix_sdk::widget::Capabilities { read: value.read.into_iter().map(Into::into).collect(), send: value.send.into_iter().map(Into::into).collect(), requires_client: value.requires_client, + update_delayed_event: value.update_delayed_event, + send_delayed_event: value.send_delayed_event, } } } @@ -397,6 +405,8 @@ impl From for WidgetCapabilities { read: value.read.into_iter().map(Into::into).collect(), send: value.send.into_iter().map(Into::into).collect(), requires_client: value.requires_client, + update_delayed_event: value.update_delayed_event, + send_delayed_event: value.send_delayed_event, } } } diff --git a/crates/matrix-sdk/src/widget/capabilities.rs b/crates/matrix-sdk/src/widget/capabilities.rs index c6b9ba4720d..4f20fc0eec3 100644 --- a/crates/matrix-sdk/src/widget/capabilities.rs +++ b/crates/matrix-sdk/src/widget/capabilities.rs @@ -51,6 +51,10 @@ pub struct Capabilities { /// This means clients should not offer to open the widget in a separate /// browser/tab/webview that is not connected to the postmessage widget-api. pub requires_client: bool, + /// This allows the widget to ask the client to update delayed events. + pub update_delayed_event: bool, + /// This allows the widget to send events with a delay. + pub send_delayed_event: bool, } impl Capabilities { @@ -73,6 +77,8 @@ const READ_EVENT: &str = "org.matrix.msc2762.receive.event"; const SEND_STATE: &str = "org.matrix.msc2762.send.state_event"; const READ_STATE: &str = "org.matrix.msc2762.receive.state_event"; const REQUIRES_CLIENT: &str = "io.element.requires_client"; +pub const SEND_DELAYED_EVENT: &str = "org.matrix.msc4157.send.delayed_event"; +pub const UPDATE_DELAYED_EVENT: &str = "org.matrix.msc4157.update_delayed_event"; impl Serialize for Capabilities { fn serialize(&self, serializer: S) -> Result @@ -117,12 +123,22 @@ impl Serialize for Capabilities { } } - let seq_len = self.requires_client as usize + self.read.len() + self.send.len(); + let seq_len = self.requires_client as usize + + self.update_delayed_event as usize + + self.send_delayed_event as usize + + self.read.len() + + self.send.len(); let mut seq = serializer.serialize_seq(Some(seq_len))?; if self.requires_client { seq.serialize_element(REQUIRES_CLIENT)?; } + if self.update_delayed_event { + seq.serialize_element(UPDATE_DELAYED_EVENT)?; + } + if self.send_delayed_event { + seq.serialize_element(SEND_DELAYED_EVENT)?; + } for filter in &self.read { let name = match filter { EventFilter::MessageLike(_) => READ_EVENT, @@ -149,6 +165,8 @@ impl<'de> Deserialize<'de> for Capabilities { { enum Permission { RequiresClient, + UpdateDelayedEvent, + SendDelayedEvent, Read(EventFilter), Send(EventFilter), Unknown, @@ -163,6 +181,12 @@ impl<'de> Deserialize<'de> for Capabilities { if s == REQUIRES_CLIENT { return Ok(Self::RequiresClient); } + if s == UPDATE_DELAYED_EVENT { + return Ok(Self::UpdateDelayedEvent); + } + if s == SEND_DELAYED_EVENT { + return Ok(Self::SendDelayedEvent); + } match s.split_once(':') { Some((READ_EVENT, filter_s)) => Ok(Permission::Read(EventFilter::MessageLike( @@ -211,6 +235,8 @@ impl<'de> Deserialize<'de> for Capabilities { Permission::Send(filter) => capabilities.send.push(filter), // ignore unknown capabilities Permission::Unknown => {} + Permission::UpdateDelayedEvent => capabilities.update_delayed_event = true, + Permission::SendDelayedEvent => capabilities.send_delayed_event = true, } } @@ -224,6 +250,16 @@ mod tests { use super::*; + #[test] + fn deserialization_of_no_capabilities() { + let capabilities_str = r#"[]"#; + + let parsed = serde_json::from_str::(capabilities_str).unwrap(); + let expected = Capabilities::default(); + + assert_eq!(parsed, expected); + } + #[test] fn deserialization_of_capabilities() { let capabilities_str = r#"[ @@ -233,7 +269,9 @@ mod tests { "org.matrix.msc2762.receive.state_event:m.room.member", "org.matrix.msc2762.receive.state_event:org.matrix.msc3401.call.member", "org.matrix.msc2762.send.event:org.matrix.rageshake_request", - "org.matrix.msc2762.send.state_event:org.matrix.msc3401.call.member#@user:matrix.server" + "org.matrix.msc2762.send.state_event:org.matrix.msc3401.call.member#@user:matrix.server", + "org.matrix.msc4157.send.delayed_event", + "org.matrix.msc4157.update_delayed_event" ]"#; let parsed = serde_json::from_str::(capabilities_str).unwrap(); @@ -257,6 +295,8 @@ mod tests { )), ], requires_client: true, + update_delayed_event: true, + send_delayed_event: true, }; assert_eq!(parsed, expected); @@ -285,6 +325,8 @@ mod tests { )), ], requires_client: true, + update_delayed_event: false, + send_delayed_event: false, }; let capabilities_str = serde_json::to_string(&capabilities).unwrap();