Skip to content

Commit ef6890a

Browse files
committed
d
Signed-off-by: Timo K <toger5@hotmail.de>
1 parent b585963 commit ef6890a

File tree

4 files changed

+123
-101
lines changed

4 files changed

+123
-101
lines changed

bindings/matrix-sdk-ffi/src/widget.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,10 @@ pub async fn generate_webview_url(
125125
/// call widget.
126126
#[matrix_sdk_ffi_macros::export]
127127
pub fn new_virtual_element_call_widget(
128-
props: matrix_sdk::widget::VirtualElementCallWidgetOptions,
128+
props: matrix_sdk::widget::VirtualElementCallWidgetProperties,
129+
config: matrix_sdk::widget::VirtualElementCallWidgetConfig,
129130
) -> Result<WidgetSettings, ParseError> {
130-
Ok(matrix_sdk::widget::WidgetSettings::new_virtual_element_call_widget(props)
131+
Ok(matrix_sdk::widget::WidgetSettings::new_virtual_element_call_widget(props, config)
131132
.map(|w| w.into())?)
132133
}
133134

crates/matrix-sdk/src/widget/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ pub use self::{
4545
capabilities::{Capabilities, CapabilitiesProvider},
4646
filter::{Filter, MessageLikeEventFilter, StateEventFilter, ToDeviceEventFilter},
4747
settings::{
48-
ClientProperties, EncryptionSystem, Intent, VirtualElementCallWidgetOptions, WidgetSettings,
48+
ClientProperties, EncryptionSystem, Intent, VirtualElementCallWidgetConfig,
49+
VirtualElementCallWidgetProperties, WidgetSettings,
4950
},
5051
};
5152

crates/matrix-sdk/src/widget/settings/element_call.rs

Lines changed: 115 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ use super::{url_params, WidgetSettings};
2626

2727
#[derive(Serialize)]
2828
#[serde(rename_all = "camelCase")]
29-
/// Parameters for the Element Call widget.
29+
/// Serialization struct for URL parameters for the Element Call widget.
3030
/// These are documented at https://github.com/element-hq/element-call/blob/livekit/docs/url-params.md
31-
struct ElementCallParams {
31+
struct ElementCallUrlParams {
3232
user_id: String,
3333
room_id: String,
3434
widget_id: String,
@@ -44,13 +44,13 @@ struct ElementCallParams {
4444
/// compatibility. Set to `true` if intent is `Intent::StartCall`.
4545
skip_lobby: Option<bool>,
4646
confine_to_room: bool,
47-
app_prompt: bool,
47+
app_prompt: Option<bool>,
4848
/// Supported since Element Call v0.13.0.
49-
header: HeaderStyle,
49+
header: Option<HeaderStyle>,
5050
/// Deprecated since Element Call v0.13.0. Included for backwards
5151
/// compatibility. Use header: "standard"|"none" instead.
5252
hide_header: Option<bool>,
53-
preload: bool,
53+
preload: Option<bool>,
5454
/// Deprecated since Element Call v0.9.0. Included for backwards
5555
/// compatibility. Set to the same as `posthog_user_id`.
5656
analytics_id: Option<String>,
@@ -59,7 +59,7 @@ struct ElementCallParams {
5959
font_scale: Option<f64>,
6060
font: Option<String>,
6161
#[serde(rename = "perParticipantE2EE")]
62-
per_participant_e2ee: bool,
62+
per_participant_e2ee: Option<bool>,
6363
password: Option<String>,
6464
/// Supported since Element Call v0.8.0.
6565
intent: Option<Intent>,
@@ -73,8 +73,10 @@ struct ElementCallParams {
7373
sentry_dsn: Option<String>,
7474
/// Supported since Element Call v0.9.0. Only used by the embedded package.
7575
sentry_environment: Option<String>,
76-
hide_screensharing: bool,
77-
controlled_media_devices: bool,
76+
/// Supported since Element Call v0.9.0.
77+
hide_screensharing: Option<bool>,
78+
/// Supported since Element Call v0.13.0.
79+
controlled_audio_devices: Option<bool>,
7880
/// Supported since Element Call v0.14.0.
7981
send_notification_type: Option<NotificationType>,
8082
}
@@ -110,6 +112,11 @@ pub enum Intent {
110112
StartCall,
111113
/// The user wants to join an existing call.
112114
JoinExisting,
115+
/// The user wants to join an existing call that is a "Direct Message" (DM)
116+
/// room.
117+
JoinExistingDM,
118+
/// The user wants to start a call in a "Direct Message" (DM) room.
119+
StartCallDM,
113120
}
114121

115122
/// Defines how (if) element-call renders a header.
@@ -126,40 +133,34 @@ pub enum HeaderStyle {
126133
}
127134

128135
/// Types of call notifications.
129-
#[derive(Debug, PartialEq, Serialize, uniffi::Enum, Clone)]
136+
#[derive(Debug, PartialEq, Serialize, uniffi::Enum, Clone, Default)]
130137
#[serde(rename_all = "snake_case")]
131138
pub enum NotificationType {
132-
/// The receiving client should display a visual notification.
139+
/// The receiving client should display a visual notification.
140+
#[default]
133141
Notification,
134142
/// The receiving client should ring with an audible sound.
135143
Ring,
136144
}
137145

138-
/// Properties to create a new virtual Element Call widget.
146+
/// Configuration parameters, to create a new virtual Element Call widget.
147+
///
148+
/// If `intent` is provided the appropriate default values for all other
149+
/// parameters will be used by element call.
150+
/// In most cases its enough to only set the intent. Use the other properties
151+
/// only if you want to deviate from the `intent` defaults.
152+
///
153+
/// Set [`docs/url-params.md`](https://github.com/element-hq/element-call/blob/livekit/docs/url-params.md)
154+
/// to find out more about the parameters and their defaults.
139155
#[derive(Debug, Default, uniffi::Record, Clone)]
140-
pub struct VirtualElementCallWidgetOptions {
141-
/// The url to the app.
142-
///
143-
/// E.g. <https://call.element.io>, <https://call.element.dev>, <https://call.element.dev/room>
144-
pub element_call_url: String,
156+
pub struct VirtualElementCallWidgetConfig {
157+
/// The intent of showing the call.
158+
/// If the user wants to start a call or join an existing one.
159+
/// Controls if the lobby is skipped or not.
160+
pub intent: Option<Intent>,
145161

146-
/// The widget id.
147-
pub widget_id: String,
148-
149-
/// The url that is used as the target for the PostMessages sent
150-
/// by the widget (to the client).
151-
///
152-
/// For a web app client this is the client url. In case of using other
153-
/// platforms the client most likely is setup up to listen to
154-
/// postmessages in the same webview the widget is hosted. In this case
155-
/// the `parent_url` is set to the url of the webview with the widget. Be
156-
/// aware that this means that the widget will receive its own postmessage
157-
/// messages. The `matrix-widget-api` (js) ignores those so this works but
158-
/// it might break custom implementations.
159-
///
160-
/// Defaults to `element_call_url` for the non-iframe (dedicated webview)
161-
/// usecase.
162-
pub parent_url: Option<String>,
162+
/// Skip the lobby when joining a call.
163+
pub skip_lobby: Option<bool>,
163164

164165
/// Whether the branding header of Element call should be shown or if a
165166
/// mobile header navbar should be render.
@@ -179,11 +180,6 @@ pub struct VirtualElementCallWidgetOptions {
179180
/// Default: `false`
180181
pub preload: Option<bool>,
181182

182-
/// The font scale which will be used inside element call.
183-
///
184-
/// Default: `1`
185-
pub font_scale: Option<f64>,
186-
187183
/// Whether element call should prompt the user to open in the browser or
188184
/// the app.
189185
///
@@ -195,6 +191,53 @@ pub struct VirtualElementCallWidgetOptions {
195191
/// Default: `true`
196192
pub confine_to_room: Option<bool>,
197193

194+
/// Do not show the screenshare button.
195+
pub hide_screensharing: Option<bool>,
196+
197+
/// Make the audio devices be controlled by the os instead of the
198+
/// element-call webview.
199+
pub controlled_audio_devices: Option<bool>,
200+
201+
/// Whether and what type of notification Element Call should send, when
202+
/// starting a call.
203+
pub send_notification_type: Option<NotificationType>,
204+
}
205+
206+
/// Properties to create a new virtual Element Call widget.
207+
///
208+
/// All these are required to start the widget in the first place.
209+
/// This is different from the `VirtualElementCallWidgetConfiguration` which
210+
/// configures the widgets behavior.
211+
#[derive(Debug, Default, uniffi::Record, Clone)]
212+
pub struct VirtualElementCallWidgetProperties {
213+
/// The url to the app.
214+
///
215+
/// E.g. <https://call.element.io>, <https://call.element.dev>, <https://call.element.dev/room>
216+
pub element_call_url: String,
217+
218+
/// The widget id.
219+
pub widget_id: String,
220+
221+
/// The url that is used as the target for the PostMessages sent
222+
/// by the widget (to the client).
223+
///
224+
/// For a web app client this is the client url. In case of using other
225+
/// platforms the client most likely is setup up to listen to
226+
/// postmessages in the same webview the widget is hosted. In this case
227+
/// the `parent_url` is set to the url of the webview with the widget. Be
228+
/// aware that this means that the widget will receive its own postmessage
229+
/// messages. The `matrix-widget-api` (js) ignores those so this works but
230+
/// it might break custom implementations.
231+
///
232+
/// Defaults to `element_call_url` for the non-iframe (dedicated webview)
233+
/// usecase.
234+
pub parent_url: Option<String>,
235+
236+
/// The font scale which will be used inside element call.
237+
///
238+
/// Default: `1`
239+
pub font_scale: Option<f64>,
240+
198241
/// The font to use, to adapt to the system font.
199242
pub font: Option<String>,
200243

@@ -203,14 +246,6 @@ pub struct VirtualElementCallWidgetOptions {
203246
/// Use `EncryptionSystem::Unencrypted` to disable encryption.
204247
pub encryption: EncryptionSystem,
205248

206-
/// The intent of showing the call.
207-
/// If the user wants to start a call or join an existing one.
208-
/// Controls if the lobby is skipped or not.
209-
pub intent: Option<Intent>,
210-
211-
/// Do not show the screenshare button.
212-
pub hide_screensharing: bool,
213-
214249
/// Can be used to pass a PostHog id to element call.
215250
pub posthog_user_id: Option<String>,
216251
/// The host of the posthog api.
@@ -230,14 +265,6 @@ pub struct VirtualElementCallWidgetOptions {
230265
/// Sentry [environment](https://docs.sentry.io/concepts/key-terms/key-terms/)
231266
/// This is only used by the embedded package of Element Call.
232267
pub sentry_environment: Option<String>,
233-
//// - `true`: The webview should show the list of media devices it detects using
234-
//// `enumerateDevices`.
235-
/// - `false`: the webview shows a a list of devices injected by the
236-
/// client. (used on ios & android)
237-
pub controlled_media_devices: bool,
238-
/// Whether and what type of notification Element Call should send, when
239-
/// starting a call.
240-
pub send_notification_type: Option<NotificationType>,
241268
}
242269

243270
impl WidgetSettings {
@@ -255,17 +282,13 @@ impl WidgetSettings {
255282
/// * `props` - A struct containing the configuration parameters for a
256283
/// element call widget.
257284
pub fn new_virtual_element_call_widget(
258-
props: VirtualElementCallWidgetOptions,
285+
props: VirtualElementCallWidgetProperties,
286+
config: VirtualElementCallWidgetConfig,
259287
) -> Result<Self, url::ParseError> {
260288
let mut raw_url: Url = Url::parse(&props.element_call_url)?;
261289

262-
let skip_lobby = if props.intent.as_ref().is_some_and(|x| x == &Intent::StartCall) {
263-
Some(true)
264-
} else {
265-
None
266-
};
267290
#[allow(deprecated)]
268-
let query_params = ElementCallParams {
291+
let query_params = ElementCallUrlParams {
269292
user_id: url_params::USER_ID.to_owned(),
270293
room_id: url_params::ROOM_ID.to_owned(),
271294
widget_id: url_params::WIDGET_ID.to_owned(),
@@ -277,30 +300,30 @@ impl WidgetSettings {
277300
base_url: url_params::HOMESERVER_URL.to_owned(),
278301

279302
parent_url: props.parent_url.unwrap_or(props.element_call_url.clone()),
280-
confine_to_room: props.confine_to_room.unwrap_or(true),
281-
app_prompt: props.app_prompt.unwrap_or_default(),
282-
header: props.header.unwrap_or_default(),
283-
hide_header: props.hide_header,
284-
preload: props.preload.unwrap_or_default(),
303+
confine_to_room: config.confine_to_room.unwrap_or(true),
304+
app_prompt: config.app_prompt,
305+
header: config.header,
306+
hide_header: config.hide_header,
307+
preload: config.preload,
285308
font_scale: props.font_scale,
286309
font: props.font,
287-
per_participant_e2ee: props.encryption == EncryptionSystem::PerParticipantKeys,
310+
per_participant_e2ee: Some(props.encryption == EncryptionSystem::PerParticipantKeys),
288311
password: match props.encryption {
289312
EncryptionSystem::SharedSecret { secret } => Some(secret),
290313
_ => None,
291314
},
292-
intent: props.intent,
293-
skip_lobby,
315+
intent: config.intent,
316+
skip_lobby: config.skip_lobby,
294317
analytics_id: props.posthog_user_id.clone(),
295318
posthog_user_id: props.posthog_user_id,
296319
posthog_api_host: props.posthog_api_host,
297320
posthog_api_key: props.posthog_api_key,
298321
sentry_dsn: props.sentry_dsn,
299322
sentry_environment: props.sentry_environment,
300323
rageshake_submit_url: props.rageshake_submit_url,
301-
hide_screensharing: props.hide_screensharing,
302-
controlled_media_devices: props.controlled_media_devices,
303-
send_notification_type: props.send_notification_type,
324+
hide_screensharing: config.hide_screensharing,
325+
controlled_media_devices: config.controlled_media_devices,
326+
send_notification_type: config.send_notification_type,
304327
};
305328

306329
let query =
@@ -326,7 +349,10 @@ mod tests {
326349
use ruma::api::client::profile::get_profile;
327350
use url::Url;
328351

329-
use crate::widget::{ClientProperties, Intent, WidgetSettings};
352+
use crate::widget::{
353+
settings::element_call::VirtualElementCallWidgetConfig, ClientProperties, Intent,
354+
WidgetSettings,
355+
};
330356

331357
const WIDGET_ID: &str = "1/@#w23";
332358

@@ -336,36 +362,28 @@ mod tests {
336362
rageshake: bool,
337363
sentry: bool,
338364
intent: Option<Intent>,
339-
controlle_output: bool,
365+
controlled_output: bool,
340366
) -> WidgetSettings {
341-
let mut props = VirtualElementCallWidgetOptions {
367+
let props = VirtualElementCallWidgetProperties {
342368
element_call_url: "https://call.element.io".to_owned(),
343369
widget_id: WIDGET_ID.to_owned(),
344-
preload: Some(true),
345-
app_prompt: Some(true),
346-
confine_to_room: Some(true),
370+
posthog_user_id: posthog.then(|| "POSTHOG_USER_ID".to_owned()),
371+
posthog_api_host: posthog.then(|| "posthog.element.io".to_owned()),
372+
posthog_api_key: posthog.then(|| "POSTHOG_KEY".to_owned()),
373+
rageshake_submit_url: rageshake.then(|| "https://rageshake.element.io".to_owned()),
374+
sentry_dsn: sentry.then(|| "SENTRY_DSN".to_owned()),
375+
sentry_environment: sentry.then(|| "SENTRY_ENV".to_owned()),
347376
encryption: encryption.unwrap_or(EncryptionSystem::PerParticipantKeys),
348-
intent,
349-
controlled_media_devices: controlle_output,
350-
..VirtualElementCallWidgetOptions::default()
377+
..VirtualElementCallWidgetProperties::default()
351378
};
352379

353-
if posthog {
354-
props.posthog_user_id = Some("POSTHOG_USER_ID".to_owned());
355-
props.posthog_api_host = Some("posthog.element.io".to_owned());
356-
props.posthog_api_key = Some("POSTHOG_KEY".to_owned());
357-
}
358-
359-
if rageshake {
360-
props.rageshake_submit_url = Some("https://rageshake.element.io".to_owned());
361-
}
362-
363-
if sentry {
364-
props.sentry_dsn = Some("SENTRY_DSN".to_owned());
365-
props.sentry_environment = Some("SENTRY_ENV".to_owned());
366-
}
380+
let config = VirtualElementCallWidgetConfig {
381+
controlled_media_devices: Some(controlled_output),
382+
intent,
383+
..VirtualElementCallWidgetConfig::default()
384+
};
367385

368-
WidgetSettings::new_virtual_element_call_widget(props)
386+
WidgetSettings::new_virtual_element_call_widget(props, config)
369387
.expect("could not parse virtual element call widget")
370388
}
371389

@@ -385,7 +403,7 @@ mod tests {
385403

386404
use serde_html_form::from_str;
387405

388-
use super::{EncryptionSystem, VirtualElementCallWidgetOptions};
406+
use super::{EncryptionSystem, VirtualElementCallWidgetProperties};
389407

390408
fn get_query_sets(url: &Url) -> Option<(QuerySet, QuerySet)> {
391409
let fq = from_str::<QuerySet>(url.fragment_query().unwrap_or_default()).ok()?;

crates/matrix-sdk/src/widget/settings/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ use crate::Room;
2121
mod element_call;
2222
mod url_params;
2323

24-
pub use self::element_call::{EncryptionSystem, Intent, VirtualElementCallWidgetOptions};
24+
pub use self::element_call::{
25+
EncryptionSystem, Intent, VirtualElementCallWidgetConfig, VirtualElementCallWidgetProperties,
26+
};
2527

2628
/// Settings of the widget.
2729
#[derive(Debug, Clone)]

0 commit comments

Comments
 (0)