diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 427b846a9..811cda456 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -6206,6 +6206,18 @@ void dc_event_unref(dc_event_t* event); #define DC_EVENT_SELFAVATAR_CHANGED 2110 +/** + * A multi-device synced config value changed. Maybe the app needs to refresh smth. For uniformity + * this is emitted on the source device too. The value isn't reported, otherwise it would be logged + * which might not be good for privacy. You can get the new value with + * `dc_get_config(context, data2)`. + * + * @param data1 0 + * @param data2 (char*) Configuration key. + */ +#define DC_EVENT_CONFIG_SYNCED 2111 + + /** * webxdc status update received. * To get the received status update, use dc_get_webxdc_status_updates() with diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 06c55bc84..ac0fc05fa 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -556,6 +556,7 @@ pub unsafe extern "C" fn dc_event_get_id(event: *mut dc_event_t) -> libc::c_int EventType::SecurejoinJoinerProgress { .. } => 2061, EventType::ConnectivityChanged => 2100, EventType::SelfavatarChanged => 2110, + EventType::ConfigSynced { .. } => 2111, EventType::WebxdcStatusUpdate { .. } => 2120, EventType::WebxdcInstanceDeleted { .. } => 2121, } @@ -583,6 +584,7 @@ pub unsafe extern "C" fn dc_event_get_data1_int(event: *mut dc_event_t) -> libc: | EventType::Error(_) | EventType::ConnectivityChanged | EventType::SelfavatarChanged + | EventType::ConfigSynced { .. } | EventType::IncomingMsgBunch { .. } | EventType::ErrorSelfNotInGroup(_) => 0, EventType::MsgsChanged { chat_id, .. } @@ -643,7 +645,8 @@ pub unsafe extern "C" fn dc_event_get_data2_int(event: *mut dc_event_t) -> libc: | EventType::ConnectivityChanged | EventType::WebxdcInstanceDeleted { .. } | EventType::IncomingMsgBunch { .. } - | EventType::SelfavatarChanged => 0, + | EventType::SelfavatarChanged + | EventType::ConfigSynced { .. } => 0, EventType::ChatModified(_) => 0, EventType::MsgsChanged { msg_id, .. } | EventType::ReactionsChanged { msg_id, .. } @@ -722,6 +725,10 @@ pub unsafe extern "C" fn dc_event_get_data2_str(event: *mut dc_event_t) -> *mut .to_c_string() .unwrap_or_default() .into_raw(), + EventType::ConfigSynced { key } => { + let data2 = key.to_string().to_c_string().unwrap_or_default(); + data2.into_raw() + } } } diff --git a/deltachat-jsonrpc/src/api/types/events.rs b/deltachat-jsonrpc/src/api/types/events.rs index dd03358bc..b3a9e04c8 100644 --- a/deltachat-jsonrpc/src/api/types/events.rs +++ b/deltachat-jsonrpc/src/api/types/events.rs @@ -288,8 +288,17 @@ pub enum EventType { /// getConnectivityHtml() for details. ConnectivityChanged, + /// Deprecated by `ConfigSynced`. SelfavatarChanged, + /// A multi-device synced config value changed. Maybe the app needs to refresh smth. For + /// uniformity this is emitted on the source device too. The value isn't here, otherwise it + /// would be logged which might not be good for privacy. + ConfigSynced { + /// Configuration key. + key: String, + }, + #[serde(rename_all = "camelCase")] WebxdcStatusUpdate { msg_id: u32, @@ -396,6 +405,9 @@ impl From for EventType { }, CoreEventType::ConnectivityChanged => ConnectivityChanged, CoreEventType::SelfavatarChanged => SelfavatarChanged, + CoreEventType::ConfigSynced { key } => ConfigSynced { + key: key.to_string(), + }, CoreEventType::WebxdcStatusUpdate { msg_id, status_update_serial, diff --git a/src/config.rs b/src/config.rs index c2bcd42fc..0594939e3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -564,6 +564,7 @@ impl Context { if sync != Sync { return Ok(()); } + self.emit_event(EventType::ConfigSynced { key }); let Some(val) = value else { return Ok(()); }; @@ -866,10 +867,43 @@ mod tests { // Reset to default. Test that it's not synced because defaults may differ across client // versions. alice0.set_config(Config::MdnsEnabled, None).await?; - assert!(alice0.get_config_bool(Config::MdnsEnabled).await?); + assert_eq!(alice0.get_config_bool(Config::MdnsEnabled).await?, true); + alice0 + .evtracker + .get_matching(|e| { + matches!( + e, + EventType::ConfigSynced { + key: Config::MdnsEnabled + } + ) + }) + .await; alice0.set_config_bool(Config::MdnsEnabled, false).await?; + alice0 + .evtracker + .get_matching(|e| { + matches!( + e, + EventType::ConfigSynced { + key: Config::MdnsEnabled + } + ) + }) + .await; sync(&alice0, &alice1).await; - assert!(!alice1.get_config_bool(Config::MdnsEnabled).await?); + assert_eq!(alice1.get_config_bool(Config::MdnsEnabled).await?, false); + alice1 + .evtracker + .get_matching(|e| { + matches!( + e, + EventType::ConfigSynced { + key: Config::MdnsEnabled + } + ) + }) + .await; let show_emails = alice0.get_config_bool(Config::ShowEmails).await?; alice0 diff --git a/src/events/payload.rs b/src/events/payload.rs index ea9e43698..d2cf3f476 100644 --- a/src/events/payload.rs +++ b/src/events/payload.rs @@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize}; use std::path::PathBuf; use crate::chat::ChatId; +use crate::config::Config; use crate::contact::ContactId; use crate::ephemeral::Timer as EphemeralTimer; use crate::message::MsgId; @@ -261,8 +262,17 @@ pub enum EventType { ConnectivityChanged, /// The user's avatar changed. + /// Deprecated by `ConfigSynced`. SelfavatarChanged, + /// A multi-device synced config value changed. Maybe the app needs to refresh smth. For + /// uniformity this is emitted on the source device too. The value isn't here, otherwise it + /// would be logged which might not be good for privacy. + ConfigSynced { + /// Configuration key. + key: Config, + }, + /// Webxdc status update received. WebxdcStatusUpdate { /// Message ID.