From 4c8e6ef4958aac495bcafaa6a0afe63a53c61933 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sat, 10 Oct 2020 00:32:45 +0200 Subject: [PATCH 1/2] use combined index (state, hidden, chat_id) to speed up marknoticed_chat() --- src/chat.rs | 14 ++++++++------ src/sql.rs | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 9fcafe206..e0fd01a1f 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1745,11 +1745,12 @@ pub async fn get_chat_msgs( } 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? { @@ -1760,10 +1761,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/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![], From c2b222e6a5c05df02e153cabe6ac20c92bbf7b65 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sat, 10 Oct 2020 00:34:28 +0200 Subject: [PATCH 2/2] emit DC_EVENT_MSGS_NOTICED when a chat was answered on another device --- deltachat-ffi/deltachat.h | 3 ++- src/chat.rs | 21 +++++++++++++++++++++ src/dc_receive_imf.rs | 5 +++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 152349a97..d8004cb8d 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -4558,7 +4558,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 e0fd01a1f..f36d9064b 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1744,6 +1744,27 @@ 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 diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 6315b9691..4989e96a9 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -845,6 +845,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;