diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 1e36c51e4..053f5fc12 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -458,12 +458,6 @@ char* dc_get_blobdir (const dc_context_t* context); * The library uses the `media_quality` setting to use different defaults * for recoding images sent with type #DC_MSG_IMAGE. * If needed, recoding other file types is up to the UI. - * - `webrtc_instance` = webrtc instance to use for videochats in the form - * `[basicwebrtc:|jitsi:]https://example.com/subdir#roomname=$ROOM` - * if the URL is prefixed by `basicwebrtc`, the server is assumed to be of the type - * https://github.com/cracker0dks/basicwebrtc which some UIs have native support for. - * The type `jitsi:` may be handled by external apps. - * If no type is prefixed, the videochat is handled completely in a browser. * - `bot` = Set to "1" if this is a bot. * Prevents adding the "Device messages" and "Saved messages" chats, * adds Auto-Submitted header to outgoing messages, @@ -575,11 +569,10 @@ int dc_set_stock_translation(dc_context_t* context, uint32_t stock_i /** * Set configuration values from a QR code. * Before this function is called, dc_check_qr() should confirm the type of the - * QR code is DC_QR_ACCOUNT, DC_QR_LOGIN or DC_QR_WEBRTC_INSTANCE. + * QR code is DC_QR_ACCOUNT or DC_QR_LOGIN. * * Internally, the function will call dc_set_config() with the appropriate keys, - * e.g. `addr` and `mail_pw` for DC_QR_ACCOUNT and DC_QR_LOGIN - * or `webrtc_instance` for DC_QR_WEBRTC_INSTANCE. + * e.g. `addr` and `mail_pw` for DC_QR_ACCOUNT and DC_QR_LOGIN. * * @memberof dc_context_t * @param context The context object. @@ -1052,42 +1045,6 @@ void dc_send_edit_request (dc_context_t* context, uint32_t ms void dc_send_delete_request (dc_context_t* context, const uint32_t* msg_ids, int msg_cnt); -/** - * Send invitation to a videochat. - * - * This function reads the `webrtc_instance` config value, - * may check that the server is working in some way - * and creates a unique room for this chat, if needed doing a TOKEN roundtrip for that. - * - * After that, the function sends out a message that contains information to join the room: - * - * - To allow non-delta-clients to join the chat, - * the message contains a text-area with some descriptive text - * and a URL that can be opened in a supported browser to join the videochat. - * - * - delta-clients can get all information needed from - * the message object, using e.g. - * dc_msg_get_videochat_url() and check dc_msg_get_viewtype() for #DC_MSG_VIDEOCHAT_INVITATION. - * - * dc_send_videochat_invitation() is blocking and may take a while, - * so the UIs will typically call the function from within a thread. - * Moreover, UIs will typically enter the room directly without an additional click on the message, - * for this purpose, the function returns the message id directly. - * - * As for other messages sent, this function - * sends the event #DC_EVENT_MSGS_CHANGED on success, the message has a delivery state, and so on. - * The recipient will get noticed by the call as usual by #DC_EVENT_INCOMING_MSG or #DC_EVENT_MSGS_CHANGED, - * However, UIs might some things differently, e.g. play a different sound. - * - * @memberof dc_context_t - * @param context The context object. - * @param chat_id The chat to start a videochat for. - * @return The ID of the message sent out - * or 0 for errors. - */ -uint32_t dc_send_videochat_invitation (dc_context_t* context, uint32_t chat_id); - - /** * A webxdc instance sends a status update to its other members. * @@ -2615,7 +2572,6 @@ void dc_stop_ongoing_process (dc_context_t* context); #define DC_QR_BACKUP 251 // deprecated #define DC_QR_BACKUP2 252 #define DC_QR_BACKUP_TOO_NEW 255 -#define DC_QR_WEBRTC_INSTANCE 260 // text1=domain, text2=instance pattern #define DC_QR_PROXY 271 // text1=address (e.g. "127.0.0.1:9050") #define DC_QR_ADDR 320 // id=contact #define DC_QR_TEXT 330 // text1=text @@ -2669,10 +2625,6 @@ void dc_stop_ongoing_process (dc_context_t* context); * show a hint to the user that this backup comes from a newer Delta Chat version * and this device needs an update * - * - DC_QR_WEBRTC_INSTANCE with dc_lot_t::text1=domain: - * ask the user if they want to use the given service for video chats; - * if so, call dc_set_config_from_qr(). - * * - DC_QR_PROXY with dc_lot_t::text1=address: * ask the user if they want to use the given proxy. * if so, call dc_set_config_from_qr() and restart I/O. @@ -4744,22 +4696,6 @@ int dc_msg_is_setupmessage (const dc_msg_t* msg); char* dc_msg_get_setupcodebegin (const dc_msg_t* msg); -/** - * Get URL of a videochat invitation. - * - * Videochat invitations are sent out using dc_send_videochat_invitation() - * and dc_msg_get_viewtype() returns #DC_MSG_VIDEOCHAT_INVITATION for such invitations. - * - * @memberof dc_msg_t - * @param msg The message object. - * @return If the message contains a videochat invitation, - * the URL of the invitation is returned. - * If the message is no videochat invitation, NULL is returned. - * Must be released using dc_str_unref() when done. - */ -char* dc_msg_get_videochat_url (const dc_msg_t* msg); - - /** * Gets the error status of the message. * If there is no error associated with the message, NULL is returned. @@ -4782,41 +4718,6 @@ char* dc_msg_get_videochat_url (const dc_msg_t* msg); char* dc_msg_get_error (const dc_msg_t* msg); -/** - * Get type of videochat. - * - * Calling this functions only makes sense for messages of type #DC_MSG_VIDEOCHAT_INVITATION, - * in this case, if `basicwebrtc:` as of https://github.com/cracker0dks/basicwebrtc or `jitsi` - * were used to initiate the videochat, - * dc_msg_get_videochat_type() returns the corresponding type. - * - * The videochat URL can be retrieved using dc_msg_get_videochat_url(). - * To check if a message is a videochat invitation at all, check the message type for #DC_MSG_VIDEOCHAT_INVITATION. - * - * @memberof dc_msg_t - * @param msg The message object. - * @return Type of the videochat as of DC_VIDEOCHATTYPE_BASICWEBRTC, DC_VIDEOCHATTYPE_JITSI or DC_VIDEOCHATTYPE_UNKNOWN. - * - * Example: - * ~~~ - * if (dc_msg_get_viewtype(msg) == DC_MSG_VIDEOCHAT_INVITATION) { - * if (dc_msg_get_videochat_type(msg) == DC_VIDEOCHATTYPE_BASICWEBRTC) { - * // videochat invitation that we ship a client for - * } else { - * // use browser for videochat - or add an additional check for DC_VIDEOCHATTYPE_JITSI - * } - * } else { - * // not a videochat invitation - * } - * ~~~ - */ -int dc_msg_get_videochat_type (const dc_msg_t* msg); - -#define DC_VIDEOCHATTYPE_UNKNOWN 0 -#define DC_VIDEOCHATTYPE_BASICWEBRTC 1 -#define DC_VIDEOCHATTYPE_JITSI 2 - - /** * Checks if the message has a full HTML version. * @@ -5715,17 +5616,6 @@ int64_t dc_lot_get_timestamp (const dc_lot_t* lot); #define DC_MSG_FILE 60 -/** - * Message indicating an incoming or outgoing videochat. - * The message was created via dc_send_videochat_invitation() on this or a remote device. - * - * Typically, such messages are rendered differently by the UIs, - * e.g. contain a button to join the videochat. - * The URL for joining can be retrieved using dc_msg_get_videochat_url(). - */ -#define DC_MSG_VIDEOCHAT_INVITATION 70 - - /** * Message indicating an incoming or outgoing call. * @@ -7276,17 +7166,6 @@ void dc_event_unref(dc_event_t* event); /// @deprecated Deprecated 2021-01-30, DC_STR_EPHEMERAL_WEEKS is used instead. #define DC_STR_EPHEMERAL_FOUR_WEEKS 81 -/// "Video chat invitation" -/// -/// Used in summaries. -#define DC_STR_VIDEOCHAT_INVITATION 82 - -/// "You are invited to a video chat, click %1$s to join." -/// -/// Used as message text of outgoing video chat invitations. -/// - %1$s will be replaced by the URL of the video chat -#define DC_STR_VIDEOCHAT_INVITE_MSG_BODY 83 - /// "Error: %1$s" /// /// Used in error strings. diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 22e45f81d..96157e4bb 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -1098,25 +1098,6 @@ pub unsafe extern "C" fn dc_send_delete_request( .ok(); } -#[no_mangle] -pub unsafe extern "C" fn dc_send_videochat_invitation( - context: *mut dc_context_t, - chat_id: u32, -) -> u32 { - if context.is_null() { - eprintln!("ignoring careless call to dc_send_videochat_invitation()"); - return 0; - } - let ctx = &*context; - - block_on(async move { - chat::send_videochat_invitation(ctx, ChatId::new(chat_id)) - .await - .map(|msg_id| msg_id.to_u32()) - .unwrap_or_log_default(ctx, "Failed to send video chat invitation") - }) -} - #[no_mangle] pub unsafe extern "C" fn dc_send_webxdc_status_update( context: *mut dc_context_t, @@ -3854,31 +3835,6 @@ pub unsafe extern "C" fn dc_msg_has_html(msg: *mut dc_msg_t) -> libc::c_int { ffi_msg.message.has_html().into() } -#[no_mangle] -pub unsafe extern "C" fn dc_msg_get_videochat_url(msg: *mut dc_msg_t) -> *mut libc::c_char { - if msg.is_null() { - eprintln!("ignoring careless call to dc_msg_get_videochat_url()"); - return "".strdup(); - } - let ffi_msg = &*msg; - - ffi_msg - .message - .get_videochat_url() - .unwrap_or_default() - .strdup() -} - -#[no_mangle] -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_get_videochat_type()"); - return 0; - } - let ffi_msg = &*msg; - ffi_msg.message.get_videochat_type().unwrap_or_default() as i32 -} - #[no_mangle] pub unsafe extern "C" fn dc_msg_get_setupcodebegin(msg: *mut dc_msg_t) -> *mut libc::c_char { if msg.is_null() { diff --git a/deltachat-ffi/src/lot.rs b/deltachat-ffi/src/lot.rs index e77483ef7..11b6cb405 100644 --- a/deltachat-ffi/src/lot.rs +++ b/deltachat-ffi/src/lot.rs @@ -51,7 +51,6 @@ impl Lot { Qr::Account { domain } => Some(Cow::Borrowed(domain)), Qr::Backup2 { .. } => None, Qr::BackupTooNew { .. } => None, - Qr::WebrtcInstance { domain, .. } => Some(Cow::Borrowed(domain)), Qr::Proxy { host, port, .. } => Some(Cow::Owned(format!("{host}:{port}"))), Qr::Addr { draft, .. } => draft.as_deref().map(Cow::Borrowed), Qr::Url { url } => Some(Cow::Borrowed(url)), @@ -105,7 +104,6 @@ impl Lot { Qr::Account { .. } => LotState::QrAccount, Qr::Backup2 { .. } => LotState::QrBackup2, Qr::BackupTooNew { .. } => LotState::QrBackupTooNew, - Qr::WebrtcInstance { .. } => LotState::QrWebrtcInstance, Qr::Proxy { .. } => LotState::QrProxy, Qr::Addr { .. } => LotState::QrAddr, Qr::Url { .. } => LotState::QrUrl, @@ -132,7 +130,6 @@ impl Lot { Qr::Account { .. } => Default::default(), Qr::Backup2 { .. } => Default::default(), Qr::BackupTooNew { .. } => Default::default(), - Qr::WebrtcInstance { .. } => Default::default(), Qr::Proxy { .. } => Default::default(), Qr::Addr { contact_id, .. } => contact_id.to_u32(), Qr::Url { .. } => Default::default(), @@ -185,9 +182,6 @@ pub enum LotState { QrBackupTooNew = 255, - /// text1=domain, text2=instance pattern - QrWebrtcInstance = 260, - /// text1=address, text2=protocol QrProxy = 271, diff --git a/deltachat-jsonrpc/src/api.rs b/deltachat-jsonrpc/src/api.rs index 0773016fb..148c11285 100644 --- a/deltachat-jsonrpc/src/api.rs +++ b/deltachat-jsonrpc/src/api.rs @@ -2282,13 +2282,6 @@ impl CommandApi { } } - async fn send_videochat_invitation(&self, account_id: u32, chat_id: u32) -> Result { - let ctx = self.get_context(account_id).await?; - chat::send_videochat_invitation(&ctx, ChatId::new(chat_id)) - .await - .map(|msg_id| msg_id.to_u32()) - } - // --------------------------------------------- // misc prototyping functions // that might get removed later again diff --git a/deltachat-jsonrpc/src/api/types/message.rs b/deltachat-jsonrpc/src/api/types/message.rs index 0369c43e3..fd47c534d 100644 --- a/deltachat-jsonrpc/src/api/types/message.rs +++ b/deltachat-jsonrpc/src/api/types/message.rs @@ -84,9 +84,6 @@ pub struct MessageObject { dimensions_height: i32, dimensions_width: i32, - videochat_type: Option, - videochat_url: Option, - override_sender_name: Option, sender: ContactObject, @@ -239,15 +236,6 @@ impl MessageObject { dimensions_height: message.get_height(), dimensions_width: message.get_width(), - videochat_type: match message.get_videochat_type() { - Some(vct) => Some( - vct.to_u32() - .context("videochat type conversion to number failed")?, - ), - None => None, - }, - videochat_url: message.get_videochat_url(), - override_sender_name, sender, @@ -321,9 +309,6 @@ pub enum MessageViewtype { /// Message containing any file, eg. a PDF. File, - /// Message is an invitation to a videochat. - VideochatInvitation, - /// Message is a call. Call, @@ -348,7 +333,6 @@ impl From for MessageViewtype { Viewtype::Voice => MessageViewtype::Voice, Viewtype::Video => MessageViewtype::Video, Viewtype::File => MessageViewtype::File, - Viewtype::VideochatInvitation => MessageViewtype::VideochatInvitation, Viewtype::Call => MessageViewtype::Call, Viewtype::Webxdc => MessageViewtype::Webxdc, Viewtype::Vcard => MessageViewtype::Vcard, @@ -368,7 +352,6 @@ impl From for Viewtype { MessageViewtype::Voice => Viewtype::Voice, MessageViewtype::Video => Viewtype::Video, MessageViewtype::File => Viewtype::File, - MessageViewtype::VideochatInvitation => Viewtype::VideochatInvitation, MessageViewtype::Call => Viewtype::Call, MessageViewtype::Webxdc => Viewtype::Webxdc, MessageViewtype::Vcard => Viewtype::Vcard, diff --git a/deltachat-jsonrpc/src/api/types/qr.rs b/deltachat-jsonrpc/src/api/types/qr.rs index 61d8141f7..0414ec9e5 100644 --- a/deltachat-jsonrpc/src/api/types/qr.rs +++ b/deltachat-jsonrpc/src/api/types/qr.rs @@ -225,13 +225,6 @@ impl From for QrObject { auth_token, }, Qr::BackupTooNew {} => QrObject::BackupTooNew {}, - Qr::WebrtcInstance { - domain, - instance_pattern, - } => QrObject::WebrtcInstance { - domain, - instance_pattern, - }, Qr::Proxy { url, host, port } => QrObject::Proxy { url, host, port }, Qr::Addr { contact_id, draft } => { let contact_id = contact_id.to_u32(); diff --git a/deltachat-repl/src/cmdline.rs b/deltachat-repl/src/cmdline.rs index 29f11c20f..93e9cc2f4 100644 --- a/deltachat-repl/src/cmdline.rs +++ b/deltachat-repl/src/cmdline.rs @@ -210,13 +210,7 @@ async fn log_msg(context: &Context, prefix: impl AsRef, msg: &Message) { } else { "" }, - if msg.get_viewtype() == Viewtype::VideochatInvitation { - format!( - "[VIDEOCHAT-INVITATION: {}, type={}]", - msg.get_videochat_url().unwrap_or_default(), - msg.get_videochat_type().unwrap_or_default() - ) - } else if msg.get_viewtype() == Viewtype::Webxdc { + if msg.get_viewtype() == Viewtype::Webxdc { match msg.get_webxdc_info(context).await { Ok(info) => format!( "[WEBXDC: {}, icon={}, document={}, summary={}, source_code_url={}]", @@ -371,7 +365,6 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu sendhtml []\n\ sendsyncmsg\n\ sendupdate \n\ - videochat\n\ draft []\n\ devicemsg \n\ listmedia\n\ @@ -962,10 +955,6 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu let msg_id = MsgId::new(arg1.parse()?); context.send_webxdc_status_update(msg_id, arg2).await?; } - "videochat" => { - ensure!(sel_chat.is_some(), "No chat selected."); - chat::send_videochat_invitation(&context, sel_chat.as_ref().unwrap().get_id()).await?; - } "listmsgs" => { ensure!(!arg1.is_empty(), "Argument missing."); diff --git a/deltachat-repl/src/main.rs b/deltachat-repl/src/main.rs index 8b06cc558..0d80cf13e 100644 --- a/deltachat-repl/src/main.rs +++ b/deltachat-repl/src/main.rs @@ -179,7 +179,7 @@ const DB_COMMANDS: [&str; 11] = [ "housekeeping", ]; -const CHAT_COMMANDS: [&str; 39] = [ +const CHAT_COMMANDS: [&str; 38] = [ "listchats", "listarchived", "start-realtime", @@ -206,7 +206,6 @@ const CHAT_COMMANDS: [&str; 39] = [ "sendhtml", "sendsyncmsg", "sendupdate", - "videochat", "draft", "devicemsg", "listmedia", diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/const.py b/deltachat-rpc-client/src/deltachat_rpc_client/const.py index 522fd4ab9..c985bdfe1 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/const.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/const.py @@ -160,7 +160,6 @@ class ViewType(str, Enum): VOICE = "Voice" VIDEO = "Video" FILE = "File" - VIDEOCHAT_INVITATION = "VideochatInvitation" WEBXDC = "Webxdc" VCARD = "Vcard" @@ -279,11 +278,3 @@ class SocketSecurity(IntEnum): SSL = 1 STARTTLS = 2 PLAIN = 3 - - -class VideochatType(IntEnum): - """Video chat URL type.""" - - UNKNOWN = 0 - BASICWEBRTC = 1 - JITSI = 2 diff --git a/python/src/deltachat/message.py b/python/src/deltachat/message.py index ddab1069b..12813eba8 100644 --- a/python/src/deltachat/message.py +++ b/python/src/deltachat/message.py @@ -435,10 +435,6 @@ class Message: """return True if it's a video message.""" return self._view_type == const.DC_MSG_VIDEO - def is_videochat_invitation(self): - """return True if it's a videochat invitation message.""" - return self._view_type == const.DC_MSG_VIDEOCHAT_INVITATION - def is_webxdc(self): """return True if it's a Webxdc message.""" return self._view_type == const.DC_MSG_WEBXDC @@ -479,7 +475,6 @@ _view_type_mapping = { "video": const.DC_MSG_VIDEO, "file": const.DC_MSG_FILE, "sticker": const.DC_MSG_STICKER, - "videochat": const.DC_MSG_VIDEOCHAT_INVITATION, "webxdc": const.DC_MSG_WEBXDC, } diff --git a/src/chat.rs b/src/chat.rs index 7cbabf121..9a1b8fddf 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -2691,10 +2691,7 @@ impl ChatIdBlocked { } async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<()> { - if msg.viewtype == Viewtype::Text - || msg.viewtype == Viewtype::VideochatInvitation - || msg.viewtype == Viewtype::Call - { + if msg.viewtype == Viewtype::Text || msg.viewtype == Viewtype::Call { // the caller should check if the message text is empty } else if msg.viewtype.has_file() { let viewtype_orig = msg.viewtype; @@ -3165,10 +3162,6 @@ pub async fn send_edit_request(context: &Context, msg_id: MsgId, new_text: Strin ); ensure!(!original_msg.is_info(), "Cannot edit info messages"); ensure!(!original_msg.has_html(), "Cannot edit HTML messages"); - ensure!( - original_msg.viewtype != Viewtype::VideochatInvitation, - "Cannot edit videochat invitations" - ); ensure!(original_msg.viewtype != Viewtype::Call, "Cannot edit calls"); ensure!( !original_msg.text.is_empty(), // avoid complexity in UI element changes. focus is typos and rewordings @@ -3217,34 +3210,6 @@ pub(crate) async fn save_text_edit_to_db( Ok(()) } -/// Sends invitation to a videochat. -pub async fn send_videochat_invitation(context: &Context, chat_id: ChatId) -> Result { - ensure!( - !chat_id.is_special(), - "video chat invitation cannot be sent to special chat: {}", - chat_id - ); - - let instance = if let Some(instance) = context.get_config(Config::WebrtcInstance).await? { - if !instance.is_empty() { - instance - } else { - bail!("webrtc_instance is empty"); - } - } else { - bail!("webrtc_instance not set"); - }; - - let instance = Message::create_webrtc_instance(&instance, &create_id()); - - let mut msg = Message::new(Viewtype::VideochatInvitation); - msg.param.set(Param::WebrtcRoom, &instance); - msg.text = - stock_str::videochat_invite_msg_body(context, &Message::parse_webrtc_instance(&instance).1) - .await; - send_msg(context, chat_id, &mut msg).await -} - async fn donation_request_maybe(context: &Context) -> Result<()> { let secs_between_checks = 30 * 24 * 60 * 60; let now = time(); diff --git a/src/chat/chat_tests.rs b/src/chat/chat_tests.rs index e018e6de5..2fda9eef4 100644 --- a/src/chat/chat_tests.rs +++ b/src/chat/chat_tests.rs @@ -4568,17 +4568,6 @@ async fn test_cannot_send_edit_request() -> Result<()> { .is_err() ); - // Videochat invitations cannot be edited - alice - .set_config(Config::WebrtcInstance, Some("https://foo.bar")) - .await?; - let msg_id = send_videochat_invitation(alice, chat_id).await?; - assert!( - send_edit_request(alice, msg_id, "bar".to_string()) - .await - .is_err() - ); - // If not text was given initally, there is nothing to edit // (this also avoids complexity in UI element changes; focus is typos and rewordings) let mut msg = Message::new(Viewtype::File); diff --git a/src/config.rs b/src/config.rs index 511404b21..9bc13d317 100644 --- a/src/config.rs +++ b/src/config.rs @@ -346,9 +346,6 @@ pub enum Config { /// Unset, when quota falls below minimal warning threshold again. QuotaExceeding, - /// address to webrtc instance to use for videochats - WebrtcInstance, - /// Timestamp of the last time housekeeping was run LastHousekeeping, diff --git a/src/constants.rs b/src/constants.rs index 6d4595909..a3c29223f 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -60,23 +60,6 @@ pub enum MediaQuality { Worse = 1, } -/// Video chat URL type. -#[derive( - Debug, Default, Display, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql, -)] -#[repr(i8)] -pub enum VideochatType { - /// Unknown type. - #[default] - Unknown = 0, - - /// [basicWebRTC](https://github.com/cracker0dks/basicwebrtc) instance. - BasicWebrtc = 1, - - /// [Jitsi Meet](https://jitsi.org/jitsi-meet/) instance. - Jitsi = 2, -} - 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; @@ -308,16 +291,4 @@ mod tests { assert_eq!(MediaQuality::Balanced, MediaQuality::from_i32(0).unwrap()); assert_eq!(MediaQuality::Worse, MediaQuality::from_i32(1).unwrap()); } - - #[test] - fn test_videochattype_values() { - // values may be written to disk and must not change - assert_eq!(VideochatType::Unknown, VideochatType::default()); - assert_eq!(VideochatType::Unknown, VideochatType::from_i32(0).unwrap()); - assert_eq!( - VideochatType::BasicWebrtc, - VideochatType::from_i32(1).unwrap() - ); - assert_eq!(VideochatType::Jitsi, VideochatType::from_i32(2).unwrap()); - } } diff --git a/src/context.rs b/src/context.rs index fc96ec87a..57c14e01f 100644 --- a/src/context.rs +++ b/src/context.rs @@ -972,12 +972,6 @@ impl Context { res.insert("private_key_count", prv_key_cnt.to_string()); res.insert("public_key_count", pub_key_cnt.to_string()); res.insert("fingerprint", fingerprint_str); - res.insert( - "webrtc_instance", - self.get_config(Config::WebrtcInstance) - .await? - .unwrap_or_else(|| "".to_string()), - ); res.insert( "media_quality", self.get_config_int(Config::MediaQuality).await?.to_string(), diff --git a/src/message.rs b/src/message.rs index 482e87e38..5c54480e0 100644 --- a/src/message.rs +++ b/src/message.rs @@ -15,9 +15,7 @@ use crate::blob::BlobObject; use crate::chat::{Chat, ChatId, ChatIdBlocked, ChatVisibility, send_msg}; use crate::chatlist_events; use crate::config::Config; -use crate::constants::{ - Blocked, Chattype, DC_CHAT_ID_TRASH, DC_MSG_ID_LAST_SPECIAL, VideochatType, -}; +use crate::constants::{Blocked, Chattype, DC_CHAT_ID_TRASH, DC_MSG_ID_LAST_SPECIAL}; use crate::contact::{self, Contact, ContactId}; use crate::context::Context; use crate::debug_logging::set_debug_logging_xdc; @@ -1017,85 +1015,6 @@ impl Message { None } - // add room to a webrtc_instance as defined by the corresponding config-value; - // the result may still be prefixed by the type - pub(crate) fn create_webrtc_instance(instance: &str, room: &str) -> String { - let (videochat_type, mut url) = Message::parse_webrtc_instance(instance); - - // make sure, there is a scheme in the url - if !url.contains(':') { - url = format!("https://{url}"); - } - - // add/replace room - let url = if url.contains("$ROOM") { - url.replace("$ROOM", room) - } else if url.contains("$NOROOM") { - // there are some usecases where a separate room is not needed to use a service - // eg. if you let in people manually anyway, see discussion at - // . - // hacks as hiding the room behind `#` are not reliable, therefore, - // these services are supported by adding the string `$NOROOM` to the url. - url.replace("$NOROOM", "") - } else { - // if there nothing that would separate the room, add a slash as a separator; - // this way, urls can be given as "https://meet.jit.si" as well as "https://meet.jit.si/" - let maybe_slash = if url.ends_with('/') - || url.ends_with('?') - || url.ends_with('#') - || url.ends_with('=') - { - "" - } else { - "/" - }; - format!("{url}{maybe_slash}{room}") - }; - - // re-add and normalize type - match videochat_type { - VideochatType::BasicWebrtc => format!("basicwebrtc:{url}"), - VideochatType::Jitsi => format!("jitsi:{url}"), - VideochatType::Unknown => url, - } - } - - /// 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 instance: String = instance.split_whitespace().collect(); - let mut split = instance.splitn(2, ':'); - let type_str = split.next().unwrap_or_default().to_lowercase(); - let url = split.next(); - match type_str.as_str() { - "basicwebrtc" => ( - VideochatType::BasicWebrtc, - url.unwrap_or_default().to_string(), - ), - "jitsi" => (VideochatType::Jitsi, url.unwrap_or_default().to_string()), - _ => (VideochatType::Unknown, instance.to_string()), - } - } - - /// Returns videochat URL if the message is a videochat invitation. - pub fn get_videochat_url(&self) -> Option { - if self.viewtype == Viewtype::VideochatInvitation { - if let Some(instance) = self.param.get(Param::WebrtcRoom) { - return Some(Message::parse_webrtc_instance(instance).1); - } - } - None - } - - /// Returns videochat type if the message is a videochat invitation. - pub fn get_videochat_type(&self) -> Option { - if self.viewtype == Viewtype::VideochatInvitation { - if let Some(instance) = self.param.get(Param::WebrtcRoom) { - return Some(Message::parse_webrtc_instance(instance).0); - } - } - None - } - /// Sets or unsets message text. pub fn set_text(&mut self, text: String) { self.text = text; @@ -2277,9 +2196,6 @@ pub enum Viewtype { /// and retrieved via dc_msg_get_file(). File = 60, - /// Message is an invitation to a videochat. - VideochatInvitation = 70, - /// Message is an incoming or outgoing call. Call = 71, @@ -2305,7 +2221,6 @@ impl Viewtype { Viewtype::Voice => true, Viewtype::Video => true, Viewtype::File => true, - Viewtype::VideochatInvitation => false, Viewtype::Call => false, Viewtype::Webxdc => true, Viewtype::Vcard => true, diff --git a/src/message/message_tests.rs b/src/message/message_tests.rs index af3e74b98..eb53c7d7c 100644 --- a/src/message/message_tests.rs +++ b/src/message/message_tests.rs @@ -25,82 +25,6 @@ fn test_guess_msgtype_from_suffix() { ); } -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -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"); - - let (webrtc_type, url) = Message::parse_webrtc_instance("jitsi:https://j.si/foo"); - assert_eq!(webrtc_type, VideochatType::Jitsi); - assert_eq!(url, "https://j.si/foo"); -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_create_webrtc_instance() { - // webrtc_instance may come from an input field of the ui, be pretty tolerant on input - let instance = Message::create_webrtc_instance("https://meet.jit.si/", "123"); - assert_eq!(instance, "https://meet.jit.si/123"); - - let instance = Message::create_webrtc_instance("https://meet.jit.si", "456"); - assert_eq!(instance, "https://meet.jit.si/456"); - - let instance = Message::create_webrtc_instance("meet.jit.si", "789"); - assert_eq!(instance, "https://meet.jit.si/789"); - - let instance = Message::create_webrtc_instance("bla.foo?", "123"); - assert_eq!(instance, "https://bla.foo?123"); - - let instance = Message::create_webrtc_instance("jitsi:bla.foo#", "456"); - assert_eq!(instance, "jitsi:https://bla.foo#456"); - - let instance = Message::create_webrtc_instance("bla.foo#room=", "789"); - assert_eq!(instance, "https://bla.foo#room=789"); - - let instance = Message::create_webrtc_instance("https://bla.foo#room", "123"); - assert_eq!(instance, "https://bla.foo#room/123"); - - let instance = Message::create_webrtc_instance("bla.foo#room$ROOM", "123"); - assert_eq!(instance, "https://bla.foo#room123"); - - let instance = Message::create_webrtc_instance("bla.foo#room=$ROOM&after=cont", "234"); - assert_eq!(instance, "https://bla.foo#room=234&after=cont"); - - let instance = Message::create_webrtc_instance(" meet.jit .si ", "789"); - assert_eq!(instance, "https://meet.jit.si/789"); - - let instance = Message::create_webrtc_instance(" basicwebrtc: basic . stuff\n ", "12345ab"); - assert_eq!(instance, "basicwebrtc:https://basic.stuff/12345ab"); -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_create_webrtc_instance_noroom() { - // webrtc_instance may come from an input field of the ui, be pretty tolerant on input - let instance = Message::create_webrtc_instance("bla.foo$NOROOM", "123"); - assert_eq!(instance, "https://bla.foo"); - - let instance = Message::create_webrtc_instance(" bla . foo $NOROOM ", "456"); - assert_eq!(instance, "https://bla.foo"); - - let instance = Message::create_webrtc_instance(" $NOROOM bla . foo ", "789"); - assert_eq!(instance, "https://bla.foo"); - - let instance = Message::create_webrtc_instance(" bla.foo / $NOROOM ? a = b ", "123"); - assert_eq!(instance, "https://bla.foo/?a=b"); - - // $ROOM has a higher precedence - let instance = Message::create_webrtc_instance("bla.foo/?$NOROOM=$ROOM", "123"); - assert_eq!(instance, "https://bla.foo/?$NOROOM=123"); -} - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_get_width_height() { let t = TestContext::new_alice().await; @@ -648,10 +572,6 @@ fn test_viewtype_values() { assert_eq!(Viewtype::Voice, Viewtype::from_i32(41).unwrap()); assert_eq!(Viewtype::Video, Viewtype::from_i32(50).unwrap()); assert_eq!(Viewtype::File, Viewtype::from_i32(60).unwrap()); - assert_eq!( - Viewtype::VideochatInvitation, - Viewtype::from_i32(70).unwrap() - ); assert_eq!(Viewtype::Webxdc, Viewtype::from_i32(80).unwrap()); assert_eq!(Viewtype::Vcard, Viewtype::from_i32(90).unwrap()); } diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 4cee76a49..59da34031 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -1565,11 +1565,6 @@ impl MimeFactory { "Chat-Content", mail_builder::headers::raw::Raw::new("sticker").into(), )); - } else if msg.viewtype == Viewtype::VideochatInvitation { - headers.push(( - "Chat-Content", - mail_builder::headers::raw::Raw::new("videochat-invitation").into(), - )); } else if msg.viewtype == Viewtype::Call { headers.push(( "Chat-Content", diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 924280eb3..3640bab25 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -732,12 +732,10 @@ impl MimeMessage { .map(|s| s.to_string()); if let Some(part) = self.parts.first_mut() { if let Some(room) = room { - if content == "videochat-invitation" { - part.typ = Viewtype::VideochatInvitation; - } else if content == "call" { - part.typ = Viewtype::Call + if content == "call" { + part.typ = Viewtype::Call; + part.param.set(Param::WebrtcRoom, room); } - part.param.set(Param::WebrtcRoom, room); } else if let Some(accepted) = accepted { part.param.set(Param::WebrtcAccepted, accepted); } @@ -765,10 +763,7 @@ impl MimeMessage { | Viewtype::Vcard | Viewtype::File | Viewtype::Webxdc => true, - Viewtype::Unknown - | Viewtype::Text - | Viewtype::VideochatInvitation - | Viewtype::Call => false, + Viewtype::Unknown | Viewtype::Text | Viewtype::Call => false, }) { let mut parts = std::mem::take(&mut self.parts); diff --git a/src/mimeparser/mimeparser_tests.rs b/src/mimeparser/mimeparser_tests.rs index d2864d7e9..09800f53e 100644 --- a/src/mimeparser/mimeparser_tests.rs +++ b/src/mimeparser/mimeparser_tests.rs @@ -476,6 +476,10 @@ async fn test_mimeparser_with_avatars() { assert!(mimeparser.group_avatar.unwrap().is_change()); } +/// Tests that video chat invitations that are not supported anymore +/// are displayed as text messages. +/// +/// User can still click on the link manually. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_mimeparser_with_videochat() { let t = TestContext::new_alice().await; @@ -483,14 +487,8 @@ async fn test_mimeparser_with_videochat() { let raw = include_bytes!("../../test-data/message/videochat_invitation.eml"); let mimeparser = MimeMessage::from_bytes(&t, &raw[..], None).await.unwrap(); assert_eq!(mimeparser.parts.len(), 1); - assert_eq!(mimeparser.parts[0].typ, Viewtype::VideochatInvitation); - assert_eq!( - mimeparser.parts[0] - .param - .get(Param::WebrtcRoom) - .unwrap_or_default(), - "https://example.org/p2p/?roomname=6HiduoAn4xN" - ); + assert_eq!(mimeparser.parts[0].typ, Viewtype::Text); + assert_eq!(mimeparser.parts[0].param.get(Param::WebrtcRoom), None); assert!( mimeparser.parts[0] .msg diff --git a/src/qr.rs b/src/qr.rs index 553a2a924..dad90a4de 100644 --- a/src/qr.rs +++ b/src/qr.rs @@ -16,7 +16,6 @@ use crate::contact::{Contact, ContactId, Origin}; use crate::context::Context; use crate::events::EventType; use crate::key::Fingerprint; -use crate::message::Message; use crate::net::http::post_empty; use crate::net::proxy::{DEFAULT_SOCKS_PORT, ProxyConfig}; use crate::token; @@ -27,7 +26,6 @@ const IDELTACHAT_SCHEME: &str = "https://i.delta.chat/#"; const IDELTACHAT_NOSLASH_SCHEME: &str = "https://i.delta.chat#"; const DCACCOUNT_SCHEME: &str = "DCACCOUNT:"; pub(super) const DCLOGIN_SCHEME: &str = "DCLOGIN:"; -const DCWEBRTC_SCHEME: &str = "DCWEBRTC:"; const TG_SOCKS_SCHEME: &str = "https://t.me/socks"; const MAILTO_SCHEME: &str = "mailto:"; const MATMSG_SCHEME: &str = "MATMSG:"; @@ -122,15 +120,6 @@ pub enum Qr { /// The QR code is a backup, but it is too new. The user has to update its Delta Chat. BackupTooNew {}, - /// Ask the user if they want to use the given service for video chats. - WebrtcInstance { - /// Server domain name. - domain: String, - - /// URL pattern for video chat rooms. - instance_pattern: String, - }, - /// Ask the user if they want to use the given proxy. /// /// Note that HTTP(S) URLs without a path @@ -294,8 +283,6 @@ pub async fn check_qr(context: &Context, qr: &str) -> Result { decode_account(qr)? } else if starts_with_ignore_case(qr, DCLOGIN_SCHEME) { dclogin_scheme::decode_login(qr)? - } else if starts_with_ignore_case(qr, DCWEBRTC_SCHEME) { - decode_webrtc_instance(context, qr)? } else if starts_with_ignore_case(qr, TG_SOCKS_SCHEME) { decode_tg_socks_proxy(context, qr)? } else if qr.starts_with(SHADOWSOCKS_SCHEME) { @@ -573,28 +560,6 @@ fn decode_account(qr: &str) -> Result { } } -/// scheme: `DCWEBRTC:https://meet.jit.si/$ROOM` -fn decode_webrtc_instance(_context: &Context, qr: &str) -> Result { - let payload = qr - .get(DCWEBRTC_SCHEME.len()..) - .context("Invalid DCWEBRTC payload")?; - - let (_type, url) = Message::parse_webrtc_instance(payload); - let url = url::Url::parse(&url).context("Invalid WebRTC instance")?; - - if url.scheme() == "http" || url.scheme() == "https" { - Ok(Qr::WebrtcInstance { - domain: url - .host_str() - .context("can't extract WebRTC instance domain")? - .to_string(), - instance_pattern: payload.to_string(), - }) - } else { - bail!("Bad URL scheme for WebRTC instance: {:?}", url.scheme()); - } -} - /// scheme: `https://t.me/socks?server=foo&port=123` or `https://t.me/socks?server=1.2.3.4&port=123` fn decode_tg_socks_proxy(_context: &Context, qr: &str) -> Result { let url = url::Url::parse(qr).context("Invalid t.me/socks url")?; @@ -732,14 +697,6 @@ pub(crate) async fn set_account_from_qr(context: &Context, qr: &str) -> Result<( pub async fn set_config_from_qr(context: &Context, qr: &str) -> Result<()> { match check_qr(context, qr).await? { Qr::Account { .. } => set_account_from_qr(context, qr).await?, - Qr::WebrtcInstance { - domain: _, - instance_pattern, - } => { - context - .set_config_internal(Config::WebrtcInstance, Some(&instance_pattern)) - .await?; - } Qr::Proxy { url, .. } => { let old_proxy_url_value = context .get_config(Config::ProxyUrl) diff --git a/src/qr/qr_tests.rs b/src/qr/qr_tests.rs index 307cbbf5d..e0358d31e 100644 --- a/src/qr/qr_tests.rs +++ b/src/qr/qr_tests.rs @@ -712,32 +712,6 @@ async fn test_decode_account() -> Result<()> { Ok(()) } -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_decode_webrtc_instance() -> Result<()> { - let ctx = TestContext::new().await; - - let qr = check_qr(&ctx.ctx, "DCWEBRTC:basicwebrtc:https://basicurl.com/$ROOM").await?; - assert_eq!( - qr, - Qr::WebrtcInstance { - domain: "basicurl.com".to_string(), - instance_pattern: "basicwebrtc:https://basicurl.com/$ROOM".to_string() - } - ); - - // Test it again with mixcased "dcWebRTC:" uri scheme - let qr = check_qr(&ctx.ctx, "dcWebRTC:https://example.org/").await?; - assert_eq!( - qr, - Qr::WebrtcInstance { - domain: "example.org".to_string(), - instance_pattern: "https://example.org/".to_string() - } - ); - - Ok(()) -} - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_decode_tg_socks_proxy() -> Result<()> { let t = TestContext::new().await; @@ -820,34 +794,6 @@ async fn test_decode_account_bad_scheme() { assert!(res.is_err()); } -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_set_webrtc_instance_config_from_qr() -> Result<()> { - let ctx = TestContext::new().await; - - assert!(ctx.ctx.get_config(Config::WebrtcInstance).await?.is_none()); - - let res = set_config_from_qr(&ctx.ctx, "badqr:https://example.org/").await; - assert!(res.is_err()); - assert!(ctx.ctx.get_config(Config::WebrtcInstance).await?.is_none()); - - let res = set_config_from_qr(&ctx.ctx, "dcwebrtc:https://example.org/").await; - assert!(res.is_ok()); - assert_eq!( - ctx.ctx.get_config(Config::WebrtcInstance).await?.unwrap(), - "https://example.org/" - ); - - let res = - set_config_from_qr(&ctx.ctx, "DCWEBRTC:basicwebrtc:https://foo.bar/?$ROOM&test").await; - assert!(res.is_ok()); - assert_eq!( - ctx.ctx.get_config(Config::WebrtcInstance).await?.unwrap(), - "basicwebrtc:https://foo.bar/?$ROOM&test" - ); - - Ok(()) -} - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_set_proxy_config_from_qr() -> Result<()> { let t = TestContext::new().await; diff --git a/src/stock_str.rs b/src/stock_str.rs index 1ec89e373..45548c264 100644 --- a/src/stock_str.rs +++ b/src/stock_str.rs @@ -130,12 +130,6 @@ pub enum StockMessage { #[strum(props(fallback = "Failed to send message to %1$s."))] FailedSendingTo = 74, - #[strum(props(fallback = "Video chat invitation"))] - VideochatInvitation = 82, - - #[strum(props(fallback = "You are invited to a video chat, click %1$s to join."))] - VideochatInviteMsgBody = 83, - #[strum(props(fallback = "Error:\n\nā€œ%1$sā€"))] ConfigurationFailed = 84, @@ -1059,18 +1053,6 @@ pub(crate) async fn msg_ephemeral_timer_year(context: &Context, by_contact: Cont } } -/// Stock string: `Video chat invitation`. -pub(crate) async fn videochat_invitation(context: &Context) -> String { - translated(context, StockMessage::VideochatInvitation).await -} - -/// Stock string: `You are invited to a video chat, click %1$s to join.`. -pub(crate) async fn videochat_invite_msg_body(context: &Context, url: &str) -> String { - translated(context, StockMessage::VideochatInviteMsgBody) - .await - .replace1(url) -} - /// Stock string: `Error:\n\nā€œ%1$sā€`. pub(crate) async fn configuration_failed(context: &Context, details: &str) -> String { translated(context, StockMessage::ConfigurationFailed) diff --git a/src/summary.rs b/src/summary.rs index b7ae5cb4c..90ddd1e35 100644 --- a/src/summary.rs +++ b/src/summary.rs @@ -211,12 +211,6 @@ impl Message { type_file = self.get_filename(); append_text = true } - Viewtype::VideochatInvitation => { - emoji = None; - type_name = Some(stock_str::videochat_invitation(context).await); - type_file = None; - append_text = false; - } Viewtype::Webxdc => { emoji = None; type_name = None; @@ -428,13 +422,6 @@ mod tests { .unwrap(); assert_summary_texts(&msg, ctx, "šŸ“Ž foo.bar \u{2013} bla bla").await; // file name is added for files - let file = write_file_to_blobdir(&d).await; - let mut msg = Message::new(Viewtype::VideochatInvitation); - msg.set_text(some_text.clone()); - msg.set_file_and_deduplicate(&d, &file, Some("foo.bar"), None) - .unwrap(); - assert_summary_texts(&msg, ctx, "Video chat invitation").await; // text is not added for videochat invitations - let mut msg = Message::new(Viewtype::Vcard); msg.set_file_from_bytes(ctx, "foo.vcf", b"", None).unwrap(); chat_id.set_draft(ctx, Some(&mut msg)).await.unwrap(); diff --git a/src/test_utils.rs b/src/test_utils.rs index 0c6c590db..ca2d931ac 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -35,7 +35,7 @@ use crate::context::Context; use crate::events::{Event, EventEmitter, EventType, Events}; use crate::key::{self, DcKey, DcSecretKey, self_fingerprint}; use crate::log::warn; -use crate::message::{Message, MessageState, MsgId, Viewtype, update_msg_state}; +use crate::message::{Message, MessageState, MsgId, update_msg_state}; use crate::mimeparser::{MimeMessage, SystemMessage}; use crate::pgp::KeyPair; use crate::receive_imf::receive_imf; @@ -1535,7 +1535,7 @@ async fn write_msg(context: &Context, prefix: &str, msg: &Message, buf: &mut Str let msgtext = msg.get_text(); writeln!( buf, - "{}{}{}{}: {} (Contact#{}): {} {}{}{}{}{}", + "{}{}{}{}: {} (Contact#{}): {} {}{}{}{}", prefix, msg.get_id(), if msg.get_showpadlock() { "šŸ”’" } else { "" }, @@ -1563,15 +1563,6 @@ async fn write_msg(context: &Context, prefix: &str, msg: &Message, buf: &mut Str } else { "" }, - if msg.get_viewtype() == Viewtype::VideochatInvitation { - format!( - "[VIDEOCHAT-INVITATION: {}, type={}]", - msg.get_videochat_url().unwrap_or_default(), - msg.get_videochat_type().unwrap_or_default() - ) - } else { - "".to_string() - }, if msg.is_forwarded() { "[FORWARDED]" } else {