Skip to content

Commit

Permalink
WidgetDriver: Introduce new Delay Event update widget action types.
Browse files Browse the repository at this point in the history
Also update the naming from `future` to `delay` in existing types.
  • Loading branch information
toger5 committed Jul 31, 2024
1 parent c72dd43 commit a178e5f
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 63 deletions.
46 changes: 41 additions & 5 deletions crates/matrix-sdk/src/widget/machine/driver_req.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use std::marker::PhantomData;

use ruma::{
api::client::{account::request_openid_token, future::FutureParameters},
api::client::{account::request_openid_token, delayed_events::update_delayed_event},
events::{AnyTimelineEvent, MessageLikeEventType, StateEventType, TimelineEventType},
serde::Raw,
};
Expand Down Expand Up @@ -51,6 +51,9 @@ pub(crate) enum MatrixDriverRequestData {

/// Send matrix event that corresponds to the given description.
SendMatrixEvent(SendEventRequest),

/// Data for sending a UpdateDelayedEvent client server api request.
UpdateDelayedEvent(UpdateDelayedEventRequest),
}

/// A handle to a pending `toWidget` request.
Expand Down Expand Up @@ -209,7 +212,8 @@ impl MatrixDriverRequest for ReadStateEventRequest {
}

/// Ask the client to send matrix event that corresponds to the given
/// description and return an event ID as a response.
/// description and returns an event ID (or a delay_id,
/// see delayed events https://github.com/matrix-org/matrix-spec-proposals/pull/4140) as a response.
#[derive(Clone, Debug, Deserialize)]
pub(crate) struct SendEventRequest {
/// The type of the event.
Expand All @@ -219,9 +223,11 @@ pub(crate) struct SendEventRequest {
pub(crate) state_key: Option<String>,
/// Raw content of an event.
pub(crate) content: Box<RawJsonValue>,
/// Additional send event parameters to send a future event.
#[serde(flatten)]
pub(crate) future_event_parameters: Option<FutureParameters>,
/// The delay for this request in ms.
/// The widget does not use the `org.matrix.msc4140.delay` unstable prefix.
/// It uses just an optional `delay` property. If provided the response will
/// contain a delay_id instead of a event_id.
pub(crate) delay: Option<u64>,
}

impl From<SendEventRequest> for MatrixDriverRequestData {
Expand All @@ -245,3 +251,33 @@ impl FromMatrixDriverResponse for SendEventResponse {
}
}
}

/// Ask the client to send a UpdateDelayedEventRequest with the given `delay_id`
/// and `action`.
#[derive(Deserialize, Debug, Clone)]
pub(crate) struct UpdateDelayedEventRequest {
pub(crate) action: update_delayed_event::unstable::UpdateAction,
pub(crate) delay_id: String,
}

impl From<UpdateDelayedEventRequest> for MatrixDriverRequestData {
fn from(value: UpdateDelayedEventRequest) -> Self {
MatrixDriverRequestData::UpdateDelayedEvent(value)
}
}

impl MatrixDriverRequest for UpdateDelayedEventRequest {
type Response = update_delayed_event::unstable::Response;
}

impl FromMatrixDriverResponse for update_delayed_event::unstable::Response {
fn from_response(ev: MatrixDriverResponse) -> Option<Self> {
match ev {
MatrixDriverResponse::MatrixDelayedEventUpdate(response) => Some(response),
_ => {
error!("bug in MatrixDriver, received wrong event response");
None
}
}
}
}
75 changes: 29 additions & 46 deletions crates/matrix-sdk/src/widget/machine/from_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@
use std::fmt;

use ruma::{
api::client::future,
api::client::delayed_events::{
delayed_message_event, delayed_state_event, update_delayed_event,
},
events::{AnyTimelineEvent, MessageLikeEventType, StateEventType},
serde::Raw,
OwnedEventId, OwnedRoomId,
};
use serde::{Deserialize, Serialize};

use super::SendEventRequest;
use super::{SendEventRequest, UpdateDelayedEventRequest};
use crate::widget::StateKeySelector;

#[derive(Deserialize, Debug)]
Expand All @@ -35,6 +37,8 @@ pub(super) enum FromWidgetRequest {
#[serde(rename = "org.matrix.msc2876.read_events")]
ReadEvent(ReadEventRequest),
SendEvent(SendEventRequest),
#[serde(rename = "org.matrix.msc4157.update_delayed_event")]
DelayedEventUpdate(UpdateDelayedEventRequest),
}

#[derive(Serialize)]
Expand Down Expand Up @@ -137,64 +141,43 @@ pub(super) struct ReadEventResponse {
pub(crate) struct SendEventResponse {
/// The room id for the send event.
pub(crate) room_id: Option<OwnedRoomId>,
/// The event id of the send event. It's optional because if it's a future
/// The event id of the send event. It's optional because if it's a delayed
/// event, it does not get the event_id at this point.
pub(crate) event_id: Option<OwnedEventId>,
/// A token to send/insert the future event into the DAG.
pub(crate) send_token: Option<String>,
/// A token to cancel this future event. It will never be sent if this is
/// called.
pub(crate) cancel_token: Option<String>,
/// The `future_group_id` generated for this future event. Used to connect
/// multiple future events. Only one of the connected future events will be
/// sent and inserted into the DAG.
pub(crate) future_group_id: Option<String>,
/// A token used to refresh the timer of the future event. This allows
/// to implement heartbeat-like capabilities. An event is only sent once
/// a refresh in the timeout interval is missed.
///
/// If the future event does not have a timeout this will be `None`.
pub(crate) refresh_token: Option<String>,
/// The `delay_id` generated for this delayed event. Used to interact with
/// the delayed event.
pub(crate) delay_id: Option<String>,
}

impl SendEventResponse {
pub(crate) fn from_event_id(event_id: OwnedEventId) -> Self {
SendEventResponse {
room_id: None,
event_id: Some(event_id),
send_token: None,
cancel_token: None,
future_group_id: None,
refresh_token: None,
}
SendEventResponse { room_id: None, event_id: Some(event_id), delay_id: None }
}
pub(crate) fn set_room_id(&mut self, room_id: OwnedRoomId) {
self.room_id = Some(room_id);
}
}

impl From<future::send_future_message_event::unstable::Response> for SendEventResponse {
fn from(val: future::send_future_message_event::unstable::Response) -> Self {
SendEventResponse {
room_id: None,
event_id: None,
send_token: Some(val.send_token),
cancel_token: Some(val.cancel_token),
future_group_id: Some(val.future_group_id),
refresh_token: val.refresh_token,
}
impl From<delayed_message_event::unstable::Response> for SendEventResponse {
fn from(val: delayed_message_event::unstable::Response) -> Self {
SendEventResponse { room_id: None, event_id: None, delay_id: Some(val.delay_id) }
}
}

impl From<future::send_future_state_event::unstable::Response> for SendEventResponse {
fn from(val: future::send_future_state_event::unstable::Response) -> Self {
SendEventResponse {
room_id: None,
event_id: None,
send_token: Some(val.send_token),
cancel_token: Some(val.cancel_token),
future_group_id: Some(val.future_group_id),
refresh_token: val.refresh_token,
}
impl From<delayed_state_event::unstable::Response> for SendEventResponse {
fn from(val: delayed_state_event::unstable::Response) -> Self {
SendEventResponse { room_id: None, event_id: None, delay_id: Some(val.delay_id) }
}
}

/// A wrapper type for the empty okay response form
/// [`update_delayed_event`](update_delayed_event::unstable::Response)
/// which derives Serialize. (The response struct from Ruma does not derive
/// serialize)
#[derive(Serialize, Debug)]
pub(crate) struct UpdateDelayedEventResponse {}
impl From<update_delayed_event::unstable::Response> for UpdateDelayedEventResponse {
fn from(_: update_delayed_event::unstable::Response) -> Self {
Self {}
}
}
7 changes: 6 additions & 1 deletion crates/matrix-sdk/src/widget/machine/incoming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use ruma::{api::client::account::request_openid_token, events::AnyTimelineEvent, serde::Raw};
use ruma::{
api::client::{account::request_openid_token, delayed_events},
events::AnyTimelineEvent,
serde::Raw,
};
use serde::{de, Deserialize, Deserializer};
use serde_json::value::RawValue as RawJsonValue;
use uuid::Uuid;
Expand Down Expand Up @@ -58,6 +62,7 @@ pub(crate) enum MatrixDriverResponse {
/// Client sent some matrix event. The response contains the event ID.
/// A response to an `Action::SendMatrixEvent` command.
MatrixEventSent(SendEventResponse),
MatrixDelayedEventUpdate(delayed_events::update_delayed_event::unstable::Response),
}

pub(super) struct IncomingWidgetMessage {
Expand Down
16 changes: 5 additions & 11 deletions crates/matrix-sdk/src/widget/machine/tests/send_event.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::time::Duration;

use assert_matches2::assert_let;
use ruma::{api::client::future::FutureParameters, events::TimelineEventType};
use ruma::events::TimelineEventType;

use super::WIDGET_ID;
use crate::widget::machine::{
Expand All @@ -10,15 +8,15 @@ use crate::widget::machine::{
};

#[test]
fn parse_future_event_widget_action() {
fn parse_delayed_event_widget_action() {
let raw = json_string!({
"api": "fromWidget",
"widgetId": WIDGET_ID,
"requestId": "send_event-request-id",
"action": "send_event",
"data": {
"content": {},
"future_timeout": 10000,
"delay": 10000,
"room_id": "!rXAYvblqYaGiJmeRdR:matrix.org",
"state_key": "_@abc:example.org_VFKPEKYWMP",
"type": "org.matrix.msc3401.call.member",
Expand All @@ -31,13 +29,9 @@ fn parse_future_event_widget_action() {
assert_let!(
FromWidgetRequest::SendEvent(send_event_request) = incoming_request.deserialize().unwrap()
);
assert_let!(
FutureParameters::Timeout { timeout, group_id } =
send_event_request.future_event_parameters.unwrap()
);
assert_let!(delay = send_event_request.delay.unwrap());

assert_eq!(timeout, Duration::from_millis(10000));
assert_eq!(group_id, None);
assert_eq!(delay, 10000);
assert_eq!(send_event_request.event_type, TimelineEventType::CallMember);
assert_eq!(send_event_request.state_key.unwrap(), "_@abc:example.org_VFKPEKYWMP".to_owned());
}

0 comments on commit a178e5f

Please sign in to comment.