use language_tags::LanguageTag;
use ruma::{
DeviceId, RoomId, UserId,
api::client::profile::{AvatarUrl, DisplayName, get_profile},
};
use url::Url;
use crate::Room;
mod element_call;
mod url_params;
pub use self::element_call::{
EncryptionSystem, Intent, VirtualElementCallWidgetConfig, VirtualElementCallWidgetProperties,
};
#[derive(Debug, Clone)]
pub struct WidgetSettings {
widget_id: String,
init_on_content_load: bool,
raw_url: Url,
}
impl WidgetSettings {
pub fn new(
id: String,
init_on_content_load: bool,
raw_url: &str,
) -> Result<Self, url::ParseError> {
Ok(Self { widget_id: id, init_on_content_load, raw_url: Url::parse(raw_url)? })
}
pub fn widget_id(&self) -> &str {
&self.widget_id
}
pub fn init_on_content_load(&self) -> bool {
self.init_on_content_load
}
pub fn raw_url(&self) -> &Url {
&self.raw_url
}
pub fn base_url(&self) -> Option<Url> {
base_url(&self.raw_url)
}
pub async fn generate_webview_url(
&self,
room: &Room,
props: ClientProperties,
) -> Result<Url, url::ParseError> {
self._generate_webview_url(
room.client().account().fetch_user_profile().await.unwrap_or_default(),
room.own_user_id(),
room.room_id(),
room.client().device_id().unwrap_or("UNKNOWN".into()),
room.client().homeserver(),
props,
)
}
fn _generate_webview_url(
&self,
profile: get_profile::v3::Response,
user_id: &UserId,
room_id: &RoomId,
device_id: &DeviceId,
homeserver_url: Url,
client_props: ClientProperties,
) -> Result<Url, url::ParseError> {
let avatar_url = profile
.get_static::<AvatarUrl>()
.ok()
.flatten()
.map(|url| url.to_string())
.unwrap_or_default();
let query_props = url_params::QueryProperties {
widget_id: self.widget_id.clone(),
avatar_url,
display_name: profile.get_static::<DisplayName>().ok().flatten().unwrap_or_default(),
user_id: user_id.into(),
room_id: room_id.into(),
language: client_props.language.to_string(),
client_theme: client_props.theme,
client_id: client_props.client_id,
device_id: device_id.into(),
homeserver_url: homeserver_url.into(),
};
let mut generated_url = self.raw_url.clone();
url_params::replace_properties(&mut generated_url, query_props);
Ok(generated_url)
}
}
#[derive(Debug)]
pub struct ClientProperties {
client_id: String,
language: LanguageTag,
theme: String,
}
impl ClientProperties {
pub fn new(client_id: &str, language: Option<LanguageTag>, theme: Option<String>) -> Self {
let default_language = LanguageTag::parse("en-us").unwrap();
let default_theme = "light".to_owned();
Self {
language: language.unwrap_or(default_language),
client_id: client_id.to_owned(),
theme: theme.unwrap_or(default_theme),
}
}
}
fn base_url(url: &Url) -> Option<Url> {
let mut url = url.clone();
url.path_segments_mut().ok()?.clear();
url.set_query(None);
url.set_fragment(None);
Some(url)
}