diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index af0d3142b..a520e3c13 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -4615,7 +4615,8 @@ void dc_event_unref(dc_event_t* event); * Messages were marked noticed or seen. * The ui may update badge counters or stop showing a chatlist-item with a bold font. * - * This event is emitted eg. when calling dc_markseen_msgs(), dc_marknoticed_chat() or dc_marknoticed_contact(). + * This event is emitted eg. when calling dc_markseen_msgs(), dc_marknoticed_chat() or dc_marknoticed_contact() + * or when a chat is answered on another device. * Do not try to derive the state of an item from just the fact you received the event; * use eg. dc_msg_get_state() or dc_get_fresh_msg_cnt() for this purpose. * diff --git a/src/chat.rs b/src/chat.rs index 43b40286b..42f5e585b 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1687,12 +1687,34 @@ pub async fn get_chat_msgs( } } +pub(crate) async fn marknoticed_chat_if_older_than( + context: &Context, + chat_id: ChatId, + timestamp: i64, +) -> Result<(), Error> { + if let Some(chat_timestamp) = context + .sql + .query_get_value( + context, + "SELECT MAX(timestamp) FROM msgs WHERE chat_id=?", + paramsv![chat_id], + ) + .await + { + if timestamp > chat_timestamp { + marknoticed_chat(context, chat_id).await?; + } + } + Ok(()) +} + pub async fn marknoticed_chat(context: &Context, chat_id: ChatId) -> Result<(), Error> { + // "WHERE" below uses the index `(state, hidden, chat_id)`, see get_fresh_msg_cnt() for reasoning if !context .sql .exists( - "SELECT id FROM msgs WHERE chat_id=? AND state=?;", - paramsv![chat_id, MessageState::InFresh], + "SELECT id FROM msgs WHERE state=? AND hidden=0 AND chat_id=?;", + paramsv![MessageState::InFresh, chat_id], ) .await? { @@ -1703,10 +1725,11 @@ pub async fn marknoticed_chat(context: &Context, chat_id: ChatId) -> Result<(), .sql .execute( "UPDATE msgs - SET state=13 - WHERE chat_id=? - AND state=10;", - paramsv![chat_id], + SET state=? + WHERE state=? + AND hidden=0 + AND chat_id=?;", + paramsv![MessageState::InNoticed, MessageState::InFresh, chat_id], ) .await?; diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index d71954055..fc092bf39 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -868,6 +868,11 @@ async fn add_parts( "Message has {} parts and is assigned to chat #{}.", icnt, chat_id, ); + // new outgoing message from another device marks the chat as noticed. + if !incoming && !*hidden && !chat_id.is_special() { + chat::marknoticed_chat_if_older_than(context, chat_id, sort_timestamp).await?; + } + // check event to send if chat_id.is_trash() || *hidden { *create_event_to_send = None; diff --git a/src/sql.rs b/src/sql.rs index 8a3f47b9a..98fc7d21e 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -1360,7 +1360,7 @@ CREATE INDEX devmsglabels_index1 ON devmsglabels (label); } if dbversion < 68 { info!(context, "[migration] v68"); - // the index is used to speed up get_fresh_msg_cnt(), see comment there for more details + // the index is used to speed up get_fresh_msg_cnt() (see comment there for more details) and marknoticed_chat() sql.execute( "CREATE INDEX IF NOT EXISTS msgs_index7 ON msgs (state, hidden, chat_id);", paramsv![],