diff --git a/CHANGELOG.md b/CHANGELOG.md index edd957fea..f931fecbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Unreleased + +### API Changes +- add `DC_EVENT_CHAT_LIST_CHANGED` event + +### Changes +- add chatlist changed event + ## 1.68.0 ### Fixes diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 23e849f86..7357a2008 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -5301,6 +5301,14 @@ void dc_event_unref(dc_event_t* event); */ #define DC_EVENT_CHAT_EPHEMERAL_TIMER_MODIFIED 2021 +/** + * Chatlist changed and ui should reload it (reordering, entry added or removed) + * + * This event is fired when the ordering or contents of the chatlist change, + * for changes in individual chat list items listen to `IncomingMsg`, `MsgsNoticed`, `MsgDelivered`, `MsgFailed`, `MsgRead` and `ChatModified` + */ +#define DC_EVENT_CHAT_LIST_CHANGED 2025 + /** * Contact(s) created, renamed, verified, blocked or deleted. diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 3c5ad5447..cb8749a7a 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -440,6 +440,7 @@ pub unsafe extern "C" fn dc_event_get_data1_int(event: *mut dc_event_t) -> libc: | EventType::Error(_) | EventType::ConnectivityChanged | EventType::SelfavatarChanged + | EventType::ChatListChanged | EventType::ErrorSelfNotInGroup(_) => 0, EventType::MsgsChanged { chat_id, .. } | EventType::IncomingMsg { chat_id, .. } @@ -491,7 +492,8 @@ pub unsafe extern "C" fn dc_event_get_data2_int(event: *mut dc_event_t) -> libc: | EventType::MsgsNoticed(_) | EventType::ConnectivityChanged | EventType::SelfavatarChanged - | EventType::ChatModified(_) => 0, + | EventType::ChatModified(_) + | EventType::ChatListChanged => 0, EventType::MsgsChanged { msg_id, .. } | EventType::IncomingMsg { msg_id, .. } | EventType::MsgDelivered { msg_id, .. } @@ -534,6 +536,7 @@ pub unsafe extern "C" fn dc_event_get_data2_str(event: *mut dc_event_t) -> *mut | EventType::MsgFailed { .. } | EventType::MsgRead { .. } | EventType::ChatModified(_) + | EventType::ChatListChanged | EventType::ContactsChanged(_) | EventType::LocationChanged(_) | EventType::ImexProgress(_) diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index 0b538f19d..407518629 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -96,6 +96,7 @@ async fn reset_tables(context: &Context, bits: i32) { chat_id: ChatId::new(0), msg_id: MsgId::new(0), }); + context.emit_event(EventType::ChatListChanged); } async fn poke_eml_file(context: &Context, filename: impl AsRef) -> Result<()> { @@ -167,6 +168,7 @@ async fn poke_spec(context: &Context, spec: Option<&str>) -> bool { chat_id: ChatId::new(0), msg_id: MsgId::new(0), }); + context.emit_event(EventType::ChatListChanged); } true } diff --git a/examples/repl/main.rs b/examples/repl/main.rs index 21ac12d0d..97e8b4c43 100644 --- a/examples/repl/main.rs +++ b/examples/repl/main.rs @@ -114,6 +114,12 @@ fn receive_event(event: EventType) { yellow.paint(format!("Received CHAT_MODIFIED({})", chat)) ); } + EventType::ChatListChanged(chat) => { + info!( + "{}", + yellow.paint("Received CHAT_LIST_CHANGED") + ); + } _ => { info!("Received {:?}", event); } diff --git a/src/chat.rs b/src/chat.rs index 351e3f21d..c44d506d3 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -211,6 +211,7 @@ impl ChatId { chat_id: ChatId::new(0), msg_id: MsgId::new(0), }); + context.emit_event(EventType::ChatListChanged); Ok(chat_id) } @@ -301,10 +302,12 @@ impl ChatId { Chattype::Group => { info!(context, "Can't block groups yet, deleting the chat"); self.delete(context).await?; + context.emit_event(EventType::ChatListChanged); } Chattype::Mailinglist => { if self.set_blocked(context, Blocked::Yes).await? { context.emit_event(EventType::ChatModified(self)); + context.emit_event(EventType::ChatListChanged); } } } @@ -345,6 +348,7 @@ impl ChatId { if self.set_blocked(context, Blocked::Not).await? { context.emit_event(EventType::ChatModified(self)); + context.emit_event(EventType::ChatListChanged); } Ok(()) @@ -489,6 +493,7 @@ impl ChatId { msg_id: MsgId::new(0), chat_id: ChatId::new(0), }); + context.emit_event(EventType::ChatListChanged); Ok(()) } @@ -546,6 +551,7 @@ impl ChatId { msg_id: MsgId::new(0), chat_id: ChatId::new(0), }); + context.emit_event(EventType::ChatListChanged); job::kill_action(context, Action::Housekeeping).await?; let j = job::Job::new(Action::Housekeeping, 0, Params::new(), 10); @@ -1992,7 +1998,8 @@ pub async fn get_chat_msgs( context.emit_event(EventType::MsgsChanged { msg_id: MsgId::new(0), chat_id: ChatId::new(0), - }) + }); + context.emit_event(EventType::ChatListChanged); } } } @@ -2292,6 +2299,7 @@ pub async fn create_group_chat( msg_id: MsgId::new(0), chat_id: ChatId::new(0), }); + context.emit_event(EventType::ChatListChanged); if protect == ProtectionStatus::Protected { // this part is to stay compatible to verified groups, @@ -2349,6 +2357,7 @@ pub async fn create_broadcast_list(context: &Context) -> Result { msg_id: MsgId::new(0), chat_id: ChatId::new(0), }); + context.emit_event(EventType::ChatListChanged); Ok(chat_id) } diff --git a/src/config.rs b/src/config.rs index a0cd9d76b..40fbdc872 100644 --- a/src/config.rs +++ b/src/config.rs @@ -314,6 +314,7 @@ impl Context { msg_id: MsgId::new(0), chat_id: ChatId::new(0), }); + self.emit_event(EventType::ChatListChanged); ret } Config::Displayname => { diff --git a/src/contact.rs b/src/contact.rs index 8d53c4214..51160f8c3 100644 --- a/src/contact.rs +++ b/src/contact.rs @@ -252,12 +252,16 @@ impl Contact { /// Block the given contact. pub async fn block(context: &Context, id: u32) -> Result<()> { - set_block_contact(context, id, true).await + set_block_contact(context, id, true).await?; + context.emit_event(EventType::ChatListChanged); + Ok(()) } /// Unblock the given contact. pub async fn unblock(context: &Context, id: u32) -> Result<()> { - set_block_contact(context, id, false).await + set_block_contact(context, id, false).await?; + context.emit_event(EventType::ChatListChanged); + Ok(()) } /// Add a single contact as a result of an _explicit_ user action. diff --git a/src/ephemeral.rs b/src/ephemeral.rs index f071093bf..ea604d753 100644 --- a/src/ephemeral.rs +++ b/src/ephemeral.rs @@ -422,6 +422,7 @@ pub async fn schedule_ephemeral_task(context: &Context) { chat_id: ChatId::new(0), msg_id: MsgId::new(0), }); + context1.emit_event(EventType::ChatListChanged); }); *context.ephemeral_task.write().await = Some(ephemeral_task); } else { @@ -430,6 +431,7 @@ pub async fn schedule_ephemeral_task(context: &Context) { chat_id: ChatId::new(0), msg_id: MsgId::new(0), }); + context.emit_event(EventType::ChatListChanged); } } } diff --git a/src/events.rs b/src/events.rs index c700b065a..eda4b1af4 100644 --- a/src/events.rs +++ b/src/events.rs @@ -248,6 +248,13 @@ pub enum EventType { timer: EphemeralTimer, }, + // Chatlist changed and ui should reload it (reordering, entry added or removed) + // + // This event is fired when the ordering or contents of the chatlist change, + // for changes in individual chat list items listen to `IncomingMsg`, `MsgsNoticed`, `MsgDelivered`, `MsgFailed`, `MsgRead` and `ChatModified` + #[strum(props(id = "2025"))] + ChatListChanged, + /// Contact(s) created, renamed, blocked or deleted. /// /// @param data1 (int) If set, this is the contact_id of an added contact that should be selected. diff --git a/src/message.rs b/src/message.rs index 41f1cc002..6cf7fe4c4 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1295,6 +1295,7 @@ pub async fn delete_msgs(context: &Context, msg_ids: &[MsgId]) -> Result<()> { chat_id: ChatId::new(0), msg_id: MsgId::new(0), }); + context.emit_event(EventType::ChatListChanged); job::kill_action(context, Action::Housekeeping).await?; job::add( context, diff --git a/src/test_utils.rs b/src/test_utils.rs index 525e42587..90cdfaf45 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -695,6 +695,10 @@ fn receive_event(event: &Event) { "{}", green.paint(format!("Received CHAT_MODIFIED({})", chat)) ), + EventType::ChatListChanged => format!( + "{}", + green.paint("Received CHAT_LIST_CHANGED()") + ), _ => format!("Received {:?}", event), }; let context_names = CONTEXT_NAMES.read().unwrap();