From d5da2bed75de27005c3ca0ae43fe0b134a423e9e Mon Sep 17 00:00:00 2001 From: iequidoo Date: Wed, 10 Jan 2024 15:09:35 -0300 Subject: [PATCH] feat: Add ConfigSynced event Add an event for a case if a multi-device synced config value changed. Maybe the app needs to refresh smth on such an event. For uniformity it is emitted on the source device too. The value is omitted, otherwise it would be logged which might not be good for privacy. --- deltachat-ffi/deltachat.h | 12 +++++++ deltachat-ffi/src/lib.rs | 9 +++++- deltachat-jsonrpc/src/api/types/events.rs | 12 +++++++ src/config.rs | 38 +++++++++++++++++++++-- src/events/payload.rs | 10 ++++++ 5 files changed, 78 insertions(+), 3 deletions(-) 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.