diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 62b7a5363..506d40764 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -1039,8 +1039,12 @@ int dc_get_msg_cnt (dc_context_t* context, uint32_t ch /** - * Get the number of _fresh_ messages in a chat. Typically used to implement - * a badge with a number in the chatlist. + * Get the number of _fresh_ messages in a chat. + * Typically used to implement a badge with a number in the chatlist. + * + * If the specified chat is muted, + * the UI should show the badge counter "less obtrusive", + * eg. using "gray" instead of "red" color. * * @memberof dc_context_t * @param context The context object as returned from dc_context_new(). @@ -1067,11 +1071,20 @@ int dc_get_fresh_msg_cnt (dc_context_t* context, uint32_t ch */ int dc_estimate_deletion_cnt (dc_context_t* context, int from_server, int64_t seconds); + /** * Returns the message IDs of all _fresh_ messages of any chat. - * Typically used for implementing notification summaries. + * Typically used for implementing notification summaries + * or badge counters eg. on the app-icon. * The list is already sorted and starts with the most recent fresh message. * + * Messages belonging to muted chats are not returned, + * as they should not be notified + * and also a badge counters should not include messages of muted chats. + * + * To get the number of fresh messages for a single chat, muted or not, + * use dc_get_fresh_msg_cnt(). + * * @memberof dc_context_t * @param context The context object as returned from dc_context_new(). * @return Array of message IDs, must be dc_array_unref()'d when no longer used. @@ -1426,13 +1439,21 @@ int dc_set_chat_profile_image (dc_context_t* context, uint32_t ch /** * Set mute duration of a chat. * - * The UI can then call dc_chat_is_muted() when receiving a new message to decide whether it should trigger an notification. + * The UI can then call dc_chat_is_muted() when receiving a new message + * to decide whether it should trigger an notification. + * + * Muted chats should not sound or vibrate + * and should not show a visual notification in the system area. + * Moreover, muted chats should be excluded from global badge counter + * (dc_get_fresh_msgs() skips muted chats therefore) + * and the in-app, per-chat badge counter should use a less obtrusive color. * * Sends out #DC_EVENT_CHAT_MODIFIED. * * @memberof dc_context_t * @param chat_id The chat ID to set the mute duration. - * @param duration The duration (0 for no mute, -1 for forever mute, everything else is is the relative mute duration from now in seconds) + * @param duration The duration (0 for no mute, -1 for forever mute, + * everything else is is the relative mute duration from now in seconds) * @param context The context object. * @return 1=success, 0=error */ diff --git a/src/context.rs b/src/context.rs index d137785d3..f6dec7c9c 100644 --- a/src/context.rs +++ b/src/context.rs @@ -17,11 +17,11 @@ use crate::chat::{get_chat_cnt, ChatId}; use crate::config::Config; use crate::constants::DC_VERSION_STR; use crate::contact::Contact; -use crate::dc_tools::duration_to_str; +use crate::dc_tools::{duration_to_str, time}; use crate::events::{Event, EventEmitter, EventType, Events}; use crate::key::{DcKey, SignedPublicKey}; use crate::login_param::LoginParam; -use crate::message::{self, MsgId}; +use crate::message::{self, MessageState, MsgId}; use crate::scheduler::Scheduler; use crate::securejoin::Bob; use crate::sql::Sql; @@ -425,8 +425,13 @@ impl Context { res } + /// Get a list of fresh, unmuted messages in any chat but deaddrop. + /// + /// The list starts with the most recent message + /// and is typically used to show notifications. + /// Moreover, the number of returned messages + /// can be used for a badge counter on the app icon. pub async fn get_fresh_msgs(&self) -> Vec { - let show_deaddrop: i32 = 0; self.sql .query_map( concat!( @@ -438,12 +443,13 @@ impl Context { " ON m.chat_id=c.id", " WHERE m.state=?", " AND m.hidden=0", - " AND m.chat_id>?", + " AND m.chat_id>9", " AND ct.blocked=0", - " AND (c.blocked=0 OR c.blocked=?)", + " AND c.blocked=0", + " AND NOT(c.muted_until=-1 OR (c.muted_until>0 AND c.muted_until(0), |rows| { let mut ret = Vec::new();