diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 992e0d4e1..15fba4ab3 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -3291,11 +3291,11 @@ char* dc_msg_get_videochat_url (const dc_msg_t* msg); /** - * Check if the videochat is a "basic webrtc" videochat. + * Get type of videochat. * * Calling this functions only makes sense for messages of type #DC_MSG_VIDEOCHAT_INVITATION, * in this case, if "basic webrtc" as of https://github.com/cracker0dks/basicwebrtc was used to initiate the videochat, - * dc_msg_is_basic_videochat() returns true. + * dc_msg_get_videochat_type() returns DC_VIDEOCHATTYPE_BASICWEBRTC. * "basic webrtc" videochat may be processed natively by the app * whereas for other urls just the browser is opened. * @@ -3303,13 +3303,12 @@ char* dc_msg_get_videochat_url (const dc_msg_t* msg); * To check if a message is a videochat invitation at all, check the message type for #DC_MSG_VIDEOCHAT_INVITATION. * * @param msg The message object. - * @return 0=message is no "basic webrtc" videochat invitation - * 1=message is a "basic webrtc" videochat invitation. + * @return Type of the videochat as of DC_VIDEOCHATTYPE_BASICWEBRTC or DC_VIDEOCHATTYPE_UNKNOWN. * * Example: * ~~~ * if (dc_msg_get_viewtype(msg) == DC_MSG_VIDEOCHAT_INVITATION) { - * if (dc_msg_is_basic_videochat(msg)) { + * if (dc_msg_get_videochat_type(msg) == DC_VIDEOCHATTYPE_BASICWEBRTC) { * // videochat invitation that we ship a client for * } else { * // use browser for videochat, just open the url @@ -3319,7 +3318,10 @@ char* dc_msg_get_videochat_url (const dc_msg_t* msg); * } * ~~~ */ -int dc_msg_is_basic_videochat (const dc_msg_t* msg); +int dc_msg_get_videochat_type (const dc_msg_t* msg); + +#define DC_VIDEOCHATTYPE_UNKNOWN 0 +#define DC_VIDEOCHATTYPE_BASICWEBRTC 1 /** diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index eb42050d6..643017977 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -2847,19 +2847,21 @@ pub unsafe extern "C" fn dc_msg_get_videochat_url(msg: *mut dc_msg_t) -> *mut li } let ffi_msg = &*msg; - block_on(ffi_msg.message.get_videochat_url()) + ffi_msg + .message + .get_videochat_url() .unwrap_or_default() .strdup() } #[no_mangle] -pub unsafe extern "C" fn dc_msg_is_basic_videochat(msg: *mut dc_msg_t) -> libc::c_int { +pub unsafe extern "C" fn dc_msg_get_videochat_type(msg: *mut dc_msg_t) -> libc::c_int { if msg.is_null() { - eprintln!("ignoring careless call to dc_msg_is_basic_videochat()"); + eprintln!("ignoring careless call to dc_msg_get_videochat_type()"); return 0; } let ffi_msg = &*msg; - ffi_msg.message.is_basic_videochat().into() + ffi_msg.message.get_videochat_type().unwrap_or_default() as i32 } #[no_mangle] diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index da3216574..b6fd67a3d 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -204,9 +204,9 @@ async fn log_msg(context: &Context, prefix: impl AsRef, msg: &Message) { if msg.is_info() { "[INFO]" } else { "" }, if msg.get_viewtype() == Viewtype::VideochatInvitation { format!( - "[VIDEOCHAT-INVITATION: {}, basic={}]", - msg.get_videochat_url().await.unwrap_or_default(), - msg.is_basic_videochat() + "[VIDEOCHAT-INVITATION: {}, type={}]", + msg.get_videochat_url().unwrap_or_default(), + msg.get_videochat_type().unwrap_or_default() ) } else { "".to_string() diff --git a/src/chat.rs b/src/chat.rs index e1483128b..8d9c58d8a 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1633,13 +1633,14 @@ pub async fn send_videochat_invitation(context: &Context, chat_id: ChatId) -> Re format!("{}{}", instance, room) }; - let url = instance.replace("basicwebrtc:", ""); - let mut msg = Message::new(Viewtype::VideochatInvitation); msg.param.set(Param::WebrtcInstance, &instance); msg.text = Some( context - .stock_string_repl_str(StockMessage::VideochatInviteMsgBody, url) + .stock_string_repl_str( + StockMessage::VideochatInviteMsgBody, + Message::parse_webrtc_instance(&instance).1, + ) .await, ); send_msg(context, chat_id, &mut msg).await diff --git a/src/constants.rs b/src/constants.rs index 2e93f508e..eb9e2a6f8 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -84,6 +84,19 @@ impl Default for KeyGenType { } } +#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql)] +#[repr(i8)] +pub enum VideochatType { + Unknown = 0, + BasicWebrtc = 1, +} + +impl Default for VideochatType { + fn default() -> Self { + VideochatType::Unknown + } +} + pub const DC_HANDSHAKE_CONTINUE_NORMAL_PROCESSING: i32 = 0x01; pub const DC_HANDSHAKE_STOP_NORMAL_PROCESSING: i32 = 0x02; pub const DC_HANDSHAKE_ADD_DELETE_JOB: i32 = 0x04; diff --git a/src/message.rs b/src/message.rs index affdfa2c1..b4859c6ef 100644 --- a/src/message.rs +++ b/src/message.rs @@ -638,22 +638,37 @@ impl Message { None } - pub async fn get_videochat_url(&self) -> Option { + /// split a webrtc_instance as defined by the corresponding config-value into a type and a url + pub fn parse_webrtc_instance(instance: &str) -> (VideochatType, String) { + let mut split = instance.splitn(2, ':'); + let type_str = split.next().unwrap_or_default().to_lowercase(); + let url = split.next(); + if type_str == "basicwebrtc" { + ( + VideochatType::BasicWebrtc, + url.unwrap_or_default().to_string(), + ) + } else { + (VideochatType::Unknown, instance.to_string()) + } + } + + pub fn get_videochat_url(&self) -> Option { if self.viewtype == Viewtype::VideochatInvitation { if let Some(instance) = self.param.get(Param::WebrtcInstance) { - return Some(instance.replace("basicwebrtc:", "")); + return Some(Message::parse_webrtc_instance(instance).1); } } None } - pub fn is_basic_videochat(&self) -> bool { + pub fn get_videochat_type(&self) -> Option { if self.viewtype == Viewtype::VideochatInvitation { if let Some(instance) = self.param.get(Param::WebrtcInstance) { - return instance.starts_with("basicwebrtc:"); + return Some(Message::parse_webrtc_instance(instance).0); } } - false + None } pub fn set_text(&mut self, text: Option) { @@ -1824,4 +1839,19 @@ mod tests { "Autocrypt Setup Message" // file name is not added for autocrypt setup messages ); } + + #[async_std::test] + async fn test_parse_webrtc_instance() { + let (webrtc_type, url) = Message::parse_webrtc_instance("basicwebrtc:https://foo/bar"); + assert_eq!(webrtc_type, VideochatType::BasicWebrtc); + assert_eq!(url, "https://foo/bar"); + + let (webrtc_type, url) = Message::parse_webrtc_instance("bAsIcwEbrTc:url"); + assert_eq!(webrtc_type, VideochatType::BasicWebrtc); + assert_eq!(url, "url"); + + let (webrtc_type, url) = Message::parse_webrtc_instance("https://foo/bar?key=val#key=val"); + assert_eq!(webrtc_type, VideochatType::Unknown); + assert_eq!(url, "https://foo/bar?key=val#key=val"); + } }