diff --git a/CHANGELOG.md b/CHANGELOG.md index d12027d49..fa98e0fc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ - order contact lists by "last seen"; this affects `dc_get_chat_contacts()`, `dc_get_contacts()` and `dc_get_blocked_contacts()` #3562 - add `internet_access` flag to `dc_msg_get_webxdc_info()` #3516 +- `DC_EVENT_WEBXDC_INSTANCE_DELETED` is emitted when a message containing a webxdc gets deleted #3105 ### Fixes - do not emit notifications for blocked chats #3557 diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 68b3f5d10..3d785a71c 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -5724,7 +5724,15 @@ void dc_event_unref(dc_event_t* event); * @param data1 (int) msg_id * @param data2 (int) status_update_serial - must not be used by UI implementations. */ -#define DC_EVENT_WEBXDC_STATUS_UPDATE 2120 +#define DC_EVENT_WEBXDC_STATUS_UPDATE 2120 + +/** + * Message deleted which contained a webxdc instance. + * + * @param data1 (int) msg_id + */ + +#define DC_EVENT_WEBXDC_INSTANCE_DELETED 2121 /** diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index e85d93957..2f872d6e1 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -504,6 +504,7 @@ pub unsafe extern "C" fn dc_event_get_id(event: *mut dc_event_t) -> libc::c_int EventType::ConnectivityChanged => 2100, EventType::SelfavatarChanged => 2110, EventType::WebxdcStatusUpdate { .. } => 2120, + EventType::WebxdcInstanceDeleted { .. } => 2121, } } @@ -550,6 +551,7 @@ pub unsafe extern "C" fn dc_event_get_data1_int(event: *mut dc_event_t) -> libc: contact_id.to_u32() as libc::c_int } EventType::WebxdcStatusUpdate { msg_id, .. } => msg_id.to_u32() as libc::c_int, + EventType::WebxdcInstanceDeleted { msg_id, .. } => msg_id.to_u32() as libc::c_int, } } @@ -581,6 +583,7 @@ pub unsafe extern "C" fn dc_event_get_data2_int(event: *mut dc_event_t) -> libc: | EventType::ImexFileWritten(_) | EventType::MsgsNoticed(_) | EventType::ConnectivityChanged + | EventType::WebxdcInstanceDeleted { .. } | EventType::SelfavatarChanged => 0, EventType::ChatModified(_) => 0, EventType::MsgsChanged { msg_id, .. } @@ -637,6 +640,7 @@ pub unsafe extern "C" fn dc_event_get_data2_str(event: *mut dc_event_t) -> *mut | EventType::ConnectivityChanged | EventType::SelfavatarChanged | EventType::WebxdcStatusUpdate { .. } + | EventType::WebxdcInstanceDeleted { .. } | EventType::ChatEphemeralTimerModified { .. } => ptr::null_mut(), EventType::ConfigureProgress { comment, .. } => { if let Some(comment) = comment { diff --git a/deltachat-jsonrpc/src/api/events.rs b/deltachat-jsonrpc/src/api/events.rs index ad0fb5faf..61e1162c9 100644 --- a/deltachat-jsonrpc/src/api/events.rs +++ b/deltachat-jsonrpc/src/api/events.rs @@ -60,6 +60,7 @@ pub fn event_to_json_rpc_notification(event: Event) -> Value { msg_id, status_update_serial, } => (json!(msg_id), json!(status_update_serial)), + EventType::WebxdcInstanceDeleted { msg_id } => (json!(msg_id), Value::Null), }; let id: EventTypeName = event.typ.into(); @@ -102,6 +103,7 @@ pub enum EventTypeName { ConnectivityChanged, SelfavatarChanged, WebxdcStatusUpdate, + WebXdInstanceDeleted, } impl From for EventTypeName { @@ -137,6 +139,7 @@ impl From for EventTypeName { EventType::ConnectivityChanged => ConnectivityChanged, EventType::SelfavatarChanged => SelfavatarChanged, EventType::WebxdcStatusUpdate { .. } => WebxdcStatusUpdate, + EventType::WebxdcInstanceDeleted { .. } => WebXdInstanceDeleted, } } } diff --git a/deltachat-jsonrpc/typescript/generated/events.ts b/deltachat-jsonrpc/typescript/generated/events.ts index c4a5d7481..16a372a21 100644 --- a/deltachat-jsonrpc/typescript/generated/events.ts +++ b/deltachat-jsonrpc/typescript/generated/events.ts @@ -1,3 +1,3 @@ // AUTO-GENERATED by typescript-type-def -export type EventTypeName=("Info"|"SmtpConnected"|"ImapConnected"|"SmtpMessageSent"|"ImapMessageDeleted"|"ImapMessageMoved"|"NewBlobFile"|"DeletedBlobFile"|"Warning"|"Error"|"ErrorSelfNotInGroup"|"MsgsChanged"|"IncomingMsg"|"MsgsNoticed"|"MsgDelivered"|"MsgFailed"|"MsgRead"|"ChatModified"|"ChatEphemeralTimerModified"|"ContactsChanged"|"LocationChanged"|"ConfigureProgress"|"ImexProgress"|"ImexFileWritten"|"SecurejoinInviterProgress"|"SecurejoinJoinerProgress"|"ConnectivityChanged"|"SelfavatarChanged"|"WebxdcStatusUpdate"); +export type EventTypeName=("Info"|"SmtpConnected"|"ImapConnected"|"SmtpMessageSent"|"ImapMessageDeleted"|"ImapMessageMoved"|"NewBlobFile"|"DeletedBlobFile"|"Warning"|"Error"|"ErrorSelfNotInGroup"|"MsgsChanged"|"IncomingMsg"|"MsgsNoticed"|"MsgDelivered"|"MsgFailed"|"MsgRead"|"ChatModified"|"ChatEphemeralTimerModified"|"ContactsChanged"|"LocationChanged"|"ConfigureProgress"|"ImexProgress"|"ImexFileWritten"|"SecurejoinInviterProgress"|"SecurejoinJoinerProgress"|"ConnectivityChanged"|"SelfavatarChanged"|"WebxdcStatusUpdate"|"WebXdInstanceDeleted"); diff --git a/deltachat-jsonrpc/typescript/generated/types.ts b/deltachat-jsonrpc/typescript/generated/types.ts index 9f9b52f64..fa5e4e538 100644 --- a/deltachat-jsonrpc/typescript/generated/types.ts +++ b/deltachat-jsonrpc/typescript/generated/types.ts @@ -65,7 +65,6 @@ export type Viewtype=("Unknown"| "Webxdc"); export type I32=number; export type U64=number; -export type Message={"id":U32;"chatId":U32;"fromId":U32;"quotedText":(string|null);"quotedMessageId":(U32|null);"text":(string|null);"hasLocation":boolean;"hasHtml":boolean;"viewType":Viewtype;"state":U32;"timestamp":I64;"sortTimestamp":I64;"receivedTimestamp":I64;"hasDeviatingTimestamp":boolean;"subject":string;"showPadlock":boolean;"isSetupmessage":boolean;"isInfo":boolean;"isForwarded":boolean;"duration":I32;"dimensionsHeight":I32;"dimensionsWidth":I32;"videochatType":(U32|null);"videochatUrl":(string|null);"overrideSenderName":(string|null);"sender":Contact;"setupCodeBegin":(string|null);"file":(string|null);"fileMime":(string|null);"fileBytes":U64;"fileName":(string|null);}; export type WebxdcMessageInfo={ /** * The name of the app. @@ -103,4 +102,5 @@ export type WebxdcMessageInfo={ * True if full internet access should be granted to the app. */ "internetAccess":boolean;}; +export type Message={"id":U32;"chatId":U32;"fromId":U32;"quotedText":(string|null);"quotedMessageId":(U32|null);"text":(string|null);"hasLocation":boolean;"hasHtml":boolean;"viewType":Viewtype;"state":U32;"timestamp":I64;"sortTimestamp":I64;"receivedTimestamp":I64;"hasDeviatingTimestamp":boolean;"subject":string;"showPadlock":boolean;"isSetupmessage":boolean;"isInfo":boolean;"isForwarded":boolean;"duration":I32;"dimensionsHeight":I32;"dimensionsWidth":I32;"videochatType":(U32|null);"videochatUrl":(string|null);"overrideSenderName":(string|null);"sender":Contact;"setupCodeBegin":(string|null);"file":(string|null);"fileMime":(string|null);"fileBytes":U64;"fileName":(string|null);"webxdcInfo":(WebxdcMessageInfo|null);}; export type __AllTyps=[string,boolean,Record,U32,U32,null,(U32)[],U32,null,(U32|null),(Account)[],U32,Account,U32,string,(ProviderInfo|null),U32,boolean,U32,Record,U32,string,(string|null),null,U32,Record,null,U32,string,null,U32,string,Qr,U32,string,(string|null),U32,(string)[],Record,U32,null,U32,null,U32,(U32)[],U32,U32,Usize,U32,string,U32,U32,string,null,U32,(U32|null),(string|null),(U32|null),(ChatListEntry)[],U32,(ChatListEntry)[],Record,U32,U32,FullChat,U32,U32,null,U32,U32,null,U32,U32,null,U32,U32,string,U32,(U32|null),[string,string],U32,U32,null,U32,U32,U32,null,U32,U32,U32,null,U32,string,string,U32,U32,U32,U32,(U32)[],U32,U32,Message,U32,(U32)[],Record,U32,(U32)[],null,U32,U32,string,U32,U32,Contact,U32,string,(string|null),U32,U32,U32,U32,U32,U32,null,U32,U32,null,U32,(Contact)[],U32,U32,(string|null),(U32)[],U32,U32,(string|null),(Contact)[],U32,(U32)[],Record,U32,(U32|null),Viewtype,(Viewtype|null),(Viewtype|null),(U32)[],U32,U32,string,string,null,U32,U32,U32,string,U32,U32,WebxdcMessageInfo,U32,string,U32,U32]; diff --git a/src/events.rs b/src/events.rs index 17d70e294..29fb039b2 100644 --- a/src/events.rs +++ b/src/events.rs @@ -302,4 +302,9 @@ pub enum EventType { msg_id: MsgId, status_update_serial: StatusUpdateSerial, }, + + /// Inform that a message containing a webxdc instance has been deleted + WebxdcInstanceDeleted { + msg_id: MsgId, + }, } diff --git a/src/message.rs b/src/message.rs index 346ece3f5..7ff5b3667 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1236,6 +1236,11 @@ pub async fn delete_msgs(context: &Context, msg_ids: &[MsgId]) -> Result<()> { .trash(context) .await .with_context(|| format!("Unable to trash message {}", msg_id))?; + + if msg.viewtype == Viewtype::Webxdc { + context.emit_event(EventType::WebxdcInstanceDeleted { msg_id: *msg_id }); + } + context .sql .execute( diff --git a/src/webxdc.rs b/src/webxdc.rs index d812bf501..05fa96875 100644 --- a/src/webxdc.rs +++ b/src/webxdc.rs @@ -753,6 +753,7 @@ mod tests { use crate::chatlist::Chatlist; use crate::config::Config; use crate::contact::Contact; + use crate::message; use crate::receive_imf::{receive_imf, receive_imf_inner}; use crate::test_utils::TestContext; @@ -2377,4 +2378,17 @@ sth_for_the = "future""# ); Ok(()) } + + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_webxdc_delete_event() -> Result<()> { + let alice = TestContext::new_alice().await; + let chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "foo").await?; + let instance = send_webxdc_instance(&alice, chat_id).await?; + message::delete_msgs(&alice, &[instance.id]).await?; + alice + .evtracker + .get_matching(|evt| matches!(evt, EventType::WebxdcInstanceDeleted { .. })) + .await; + Ok(()) + } }