WidgetDriver: Introduce new Delay Event update widget action types.

Also update the naming from `future` to `delay` in existing types.
This commit is contained in:
Timo
2024-07-31 19:26:21 +02:00
committed by Andy Balaam
parent 16a638400c
commit 0407dd7eb1
4 changed files with 80 additions and 63 deletions

View File

@@ -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,
};
@@ -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.
@@ -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 [MSC4140](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.
@@ -219,9 +223,10 @@ 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 optional delay (in ms) to send the event at.
/// If provided, the response will contain a delay_id instead of a event_id.
/// Defined by [MSC4157](https://github.com/matrix-org/matrix-spec-proposals/pull/4157)
pub(crate) delay: Option<u64>,
}
impl From<SendEventRequest> for MatrixDriverRequestData {
@@ -245,3 +250,33 @@ impl FromMatrixDriverResponse for SendEventResponse {
}
}
}
/// Ask the client to send a UpdateDelayedEventRequest with the given `delay_id`
/// and `action`. Defined by [MSC4157](https://github.com/matrix-org/matrix-spec-proposals/pull/4157)
#[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
}
}
}
}

View File

@@ -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)]
@@ -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)]
@@ -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 from
/// [`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 {}
}
}

View File

@@ -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;
@@ -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 {

View File

@@ -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::{
@@ -10,7 +8,7 @@ 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,
@@ -18,7 +16,7 @@ fn parse_future_event_widget_action() {
"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",
@@ -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());
}