mirror of
https://github.com/chatmail/core.git
synced 2026-05-03 05:16:28 +03:00
add dc_skip_device_msg() and belonging tests
This commit is contained in:
@@ -1135,6 +1135,44 @@ uint32_t dc_add_device_msg (dc_context_t* context, dc_msg_t* m
|
|||||||
uint32_t dc_add_device_msg_once (dc_context_t* context, const char* label, dc_msg_t* msg);
|
uint32_t dc_add_device_msg_once (dc_context_t* context, const char* label, dc_msg_t* msg);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip a device-message permanently.
|
||||||
|
* Subsequent calls to dc_add_device_msg_once() with the same label
|
||||||
|
* won't add the device-message then.
|
||||||
|
* This might be handy if you want to add
|
||||||
|
* eg. different messages for first-install and updates.
|
||||||
|
*
|
||||||
|
* @memberof dc_context_t
|
||||||
|
* @param context The context as created by dc_context_new().
|
||||||
|
* @param label A unique name for the message to skip.
|
||||||
|
* The label is typically not displayed to the user and
|
||||||
|
* must be created from the characters `A-Z`, `a-z`, `0-9`, `_` or `-`.
|
||||||
|
* If a message with that label already exist,
|
||||||
|
* nothing happens.
|
||||||
|
* @return None.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ~~~
|
||||||
|
* dc_msg_t* welcome_msg = dc_msg_new(DC_MSG_TEXT);
|
||||||
|
* dc_msg_set_text(welcome_msg, "great that you give this app a try!");
|
||||||
|
*
|
||||||
|
* dc_msg_t* changelog_msg = dc_msg_new(DC_MSG_TEXT);
|
||||||
|
* dc_msg_set_text(changelog_msg, "we have added 3 new emojis :)");
|
||||||
|
*
|
||||||
|
* if (dc_add_device_msg_once(context, "welcome", welcome_msg)) {
|
||||||
|
* // do not add the changelog on a new installations -
|
||||||
|
* // not now and not when this code is executed again
|
||||||
|
* dc_skip_device_msg(context, "update-123");
|
||||||
|
* } else {
|
||||||
|
* // welcome message was not added now, this is an oder installation,
|
||||||
|
* // add a changelog
|
||||||
|
* dc_add_device_msg_once(context, "update-123", changelog_msg);
|
||||||
|
* }
|
||||||
|
* ~~~
|
||||||
|
*/
|
||||||
|
void dc_skip_device_msg (dc_context_t* context, const char* label);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get draft for a chat, if any.
|
* Get draft for a chat, if any.
|
||||||
* See dc_set_draft() for more details about drafts.
|
* See dc_set_draft() for more details about drafts.
|
||||||
|
|||||||
@@ -849,6 +849,24 @@ pub unsafe extern "C" fn dc_add_device_msg_once(
|
|||||||
.unwrap_or(0)
|
.unwrap_or(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_skip_device_msg(
|
||||||
|
context: *mut dc_context_t,
|
||||||
|
label: *const libc::c_char,
|
||||||
|
) {
|
||||||
|
if context.is_null() || label.is_null() {
|
||||||
|
eprintln!("ignoring careless call to dc_skip_device_msg()");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let ffi_context = &mut *context;
|
||||||
|
ffi_context
|
||||||
|
.with_inner(|ctx| {
|
||||||
|
chat::skip_device_msg(ctx, &to_string_lossy(label))
|
||||||
|
.unwrap_or_log_default(ctx, "Failed to skip device message")
|
||||||
|
})
|
||||||
|
.unwrap_or(())
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_get_draft(context: *mut dc_context_t, chat_id: u32) -> *mut dc_msg_t {
|
pub unsafe extern "C" fn dc_get_draft(context: *mut dc_context_t, chat_id: u32) -> *mut dc_msg_t {
|
||||||
if context.is_null() {
|
if context.is_null() {
|
||||||
|
|||||||
45
src/chat.rs
45
src/chat.rs
@@ -1974,6 +1974,7 @@ fn add_device_msg_maybe_labelled(
|
|||||||
|
|
||||||
// if the device message is labeled and was ever added, do nothing
|
// if the device message is labeled and was ever added, do nothing
|
||||||
if let Some(label) = label {
|
if let Some(label) = label {
|
||||||
|
ensure!(!label.is_empty(), "cannot add empty label");
|
||||||
if let Ok(()) = context.sql.query_row(
|
if let Ok(()) = context.sql.query_row(
|
||||||
"SELECT label FROM devmsglabels WHERE label=?",
|
"SELECT label FROM devmsglabels WHERE label=?",
|
||||||
params![label],
|
params![label],
|
||||||
@@ -2009,10 +2010,7 @@ fn add_device_msg_maybe_labelled(
|
|||||||
let msg_id = MsgId::new(row_id);
|
let msg_id = MsgId::new(row_id);
|
||||||
|
|
||||||
if let Some(label) = label {
|
if let Some(label) = label {
|
||||||
context.sql.execute(
|
skip_device_msg(context, label)?;
|
||||||
"INSERT INTO devmsglabels (label, msg_id) VALUES (?, ?);",
|
|
||||||
params![label, msg_id],
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !msg_id.is_unset() {
|
if !msg_id.is_unset() {
|
||||||
@@ -2022,6 +2020,25 @@ fn add_device_msg_maybe_labelled(
|
|||||||
Ok(msg_id)
|
Ok(msg_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn skip_device_msg(context: &Context, label: &str) -> Result<(), Error> {
|
||||||
|
ensure!(!label.is_empty(), "cannot skip empty label");
|
||||||
|
if let Ok(()) = context.sql.query_row(
|
||||||
|
"SELECT label FROM devmsglabels WHERE label=?",
|
||||||
|
params![label],
|
||||||
|
|_| Ok(()),
|
||||||
|
) {
|
||||||
|
info!(context, "device-message {} already added", label);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
context.sql.execute(
|
||||||
|
"INSERT INTO devmsglabels (label) VALUES (?);",
|
||||||
|
params![label],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_info_msg(context: &Context, chat_id: u32, text: impl AsRef<str>) {
|
pub fn add_info_msg(context: &Context, chat_id: u32, text: impl AsRef<str>) {
|
||||||
let rfc724_mid = dc_create_outgoing_rfc724_mid(None, "@device");
|
let rfc724_mid = dc_create_outgoing_rfc724_mid(None, "@device");
|
||||||
|
|
||||||
@@ -2214,6 +2231,26 @@ mod tests {
|
|||||||
assert!(msg2_id.as_ref().unwrap().is_unset());
|
assert!(msg2_id.as_ref().unwrap().is_unset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_skip_device_msg() {
|
||||||
|
let t = test_context(Some(Box::new(logging_cb)));
|
||||||
|
let res = skip_device_msg(&t.ctx, "");
|
||||||
|
assert!(res.is_err());
|
||||||
|
let res = skip_device_msg(&t.ctx, "some-label");
|
||||||
|
assert!(res.is_ok());
|
||||||
|
|
||||||
|
let mut msg = Message::new(Viewtype::Text);
|
||||||
|
msg.text = Some("message text".to_string());
|
||||||
|
|
||||||
|
let msg_id = add_device_msg_once(&t.ctx, "some-label", &mut msg);
|
||||||
|
assert!(msg_id.is_ok());
|
||||||
|
assert!(msg_id.as_ref().unwrap().is_unset());
|
||||||
|
|
||||||
|
let msg_id = add_device_msg_once(&t.ctx, "unused-label", &mut msg);
|
||||||
|
assert!(msg_id.is_ok());
|
||||||
|
assert!(!msg_id.as_ref().unwrap().is_unset());
|
||||||
|
}
|
||||||
|
|
||||||
fn chatlist_len(ctx: &Context, listflags: usize) -> usize {
|
fn chatlist_len(ctx: &Context, listflags: usize) -> usize {
|
||||||
Chatlist::try_load(ctx, listflags, None, None)
|
Chatlist::try_load(ctx, listflags, None, None)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|||||||
@@ -815,7 +815,7 @@ fn open(
|
|||||||
// records in the devmsglabels are kept when the message is deleted.
|
// records in the devmsglabels are kept when the message is deleted.
|
||||||
// so, msg_id may or may not exist.
|
// so, msg_id may or may not exist.
|
||||||
sql.execute(
|
sql.execute(
|
||||||
"CREATE TABLE devmsglabels (id INTEGER PRIMARY KEY AUTOINCREMENT, label TEXT, msg_id INTEGER);",
|
"CREATE TABLE devmsglabels (id INTEGER PRIMARY KEY AUTOINCREMENT, label TEXT, msg_id INTEGER DEFAULT 0);",
|
||||||
NO_PARAMS,
|
NO_PARAMS,
|
||||||
)?;
|
)?;
|
||||||
sql.execute(
|
sql.execute(
|
||||||
|
|||||||
Reference in New Issue
Block a user