diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index 9ecf5d38c9d..155d4e8c4d6 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -55,6 +55,7 @@ experimental-sliding-sync = [ "reqwest/gzip", "dep:eyeball-im-util", ] +experimental-widget-api = [] docsrs = ["e2e-encryption", "sqlite", "sso-login", "qrcode", "image-proc"] diff --git a/crates/matrix-sdk/src/lib.rs b/crates/matrix-sdk/src/lib.rs index ecadc8c710b..ad0057f6eef 100644 --- a/crates/matrix-sdk/src/lib.rs +++ b/crates/matrix-sdk/src/lib.rs @@ -34,6 +34,8 @@ pub mod attachment; mod authentication; mod client; pub mod config; +#[cfg(feature = "e2e-encryption")] +pub mod encryption; mod error; pub mod event_handler; mod http_client; @@ -43,13 +45,12 @@ pub mod notification_settings; #[cfg(feature = "experimental-oidc")] pub mod oidc; pub mod room; -pub mod sync; - #[cfg(feature = "experimental-sliding-sync")] pub mod sliding_sync; +pub mod sync; +#[cfg(feature = "experimental-widget-api")] +pub mod widget; -#[cfg(feature = "e2e-encryption")] -pub mod encryption; pub use account::Account; pub use authentication::{AuthApi, AuthSession}; pub use client::{Client, ClientBuildError, ClientBuilder, LoopCtrl, SendRequest, UnknownToken}; diff --git a/crates/matrix-sdk/src/widget/mod.rs b/crates/matrix-sdk/src/widget/mod.rs new file mode 100644 index 00000000000..aab47402d6d --- /dev/null +++ b/crates/matrix-sdk/src/widget/mod.rs @@ -0,0 +1,52 @@ +//! Client widget API implementation. + +use tokio::sync::mpsc::{Receiver, Sender}; + +use crate::room::Room as JoinedRoom; + +mod permissions; + +pub use self::permissions::{Permissions, PermissionsProvider}; + +/// Describes a widget. +#[derive(Debug)] +pub struct Widget { + /// Information about the widget. + pub info: Info, + /// Communication channels with a widget. + pub comm: Comm, +} + +/// Information about a widget. +#[derive(Debug)] +pub struct Info { + /// Widget's unique identifier. + pub id: String, + /// Whether or not the widget should be initialized on load message + /// (`ContentLoad` message), or upon creation/attaching of the widget to + /// the SDK's state machine that drives the API. + pub init_on_load: bool, +} + +/// Communication "pipes" with a widget. +#[derive(Debug)] +pub struct Comm { + /// Raw incoming messages from the widget (normally, formatted as JSON). + pub from: Receiver, + /// Raw outgoing messages from the client (SDK) to the widget (normally + /// formatted as JSON). + pub to: Sender, +} + +/// Starts a client widget API state machine for a given `widget` in a given +/// joined `room`. The function returns once the widget is disconnected or any +/// terminal error occurs. +/// +/// Not implemented yet, currently always panics. +pub async fn run_widget_api( + _room: JoinedRoom, + _widget: Widget, + _permissions_provider: impl PermissionsProvider, +) -> Result<(), ()> { + todo!() +} diff --git a/crates/matrix-sdk/src/widget/permissions.rs b/crates/matrix-sdk/src/widget/permissions.rs new file mode 100644 index 00000000000..9ebe1392676 --- /dev/null +++ b/crates/matrix-sdk/src/widget/permissions.rs @@ -0,0 +1,46 @@ +//! Types and traits related to the permissions that a widget can request from a +//! client. + +use async_trait::async_trait; + +use crate::ruma::events::{MessageLikeEventType, StateEventType}; + +/// Must be implemented by a component that provides functionality of deciding +/// whether a widget is allowed to use certain capabilities (typically by +/// providing a prompt to the user). +#[async_trait] +pub trait PermissionsProvider: Send + Sync + 'static { + /// Receives a request for given permissions and returns the actual + /// permissions that the clients grants to a given widget (usually by + /// prompting the user). + async fn acquire_permissions(&self, permissions: Permissions) -> Permissions; +} + +/// Permissions that a widget can request from a client. +#[derive(Debug)] +pub struct Permissions { + /// Types of the messages that a widget wants to be able to fetch. + pub read: Vec, + /// Types of the messages that a widget wants to be able to send. + pub send: Vec, +} + +/// Different kinds of filters that could be applied to the timeline events. +#[derive(Debug)] +pub enum EventFilter { + /// Message-like events. + MessageLike { + /// The type of the message-like event. + event_type: MessageLikeEventType, + /// Additional filter for the msgtype, currently only used for + /// `m.room.message`. + msgtype: Option, + }, + /// State events. + State { + /// The type of the state event. + event_type: StateEventType, + /// State key that could be `None`, `None` means "any state key". + state_key: Option, + }, +}