From 95bce993ad747ce323ee554a4b7a1af3338f54c4 Mon Sep 17 00:00:00 2001 From: bjoern Date: Mon, 27 Sep 2021 13:39:27 +0200 Subject: [PATCH] set message-state OutMdnRcvd on first read-receipt (#2699) in the past, group-messages were marked as "read by recipient" only when at least 50% of the group members have send a read receipt - in practise, this does happen never or much too late esp. in larger groups. setting the state OutMdnRcvd already on the first read-receipt seems to be much more intuitive and useful as you at least know one person has read the message. this is also what other messengers as telegram are doing here. moreover, this fixes a bug that did not add all read-receipts to the "Info" screen - once "enough" read-receipts were received, and the state was already set to OutMdnRcvd, subsequent read-receipts were ignored. probably because the "Info" screen did not show the read-receipts since forever - and for the second tick, the addutional read-receipts are not needed. --- src/chat.rs | 11 -------- src/message.rs | 75 +++++++++++++------------------------------------- 2 files changed, 19 insertions(+), 67 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index ad5c2fcab..e25a67363 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -2758,17 +2758,6 @@ pub async fn forward_msgs(context: &Context, msg_ids: &[MsgId], chat_id: ChatId) Ok(()) } -pub(crate) async fn get_chat_contact_cnt(context: &Context, chat_id: ChatId) -> Result { - let count = context - .sql - .count( - "SELECT COUNT(*) FROM chats_contacts WHERE chat_id=?;", - paramsv![chat_id], - ) - .await?; - Ok(count as usize) -} - pub(crate) async fn get_chat_cnt(context: &Context) -> Result { if context.sql.is_open().await { // no database, no chats - this is no error (needed eg. for information) diff --git a/src/message.rs b/src/message.rs index f17890531..3674cb969 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1487,7 +1487,6 @@ pub async fn handle_mdn( "SELECT", " m.id AS msg_id,", " c.id AS chat_id,", - " c.type AS type,", " m.state AS state", " FROM msgs m LEFT JOIN chats c ON m.chat_id=c.id", " WHERE rfc724_mid=? AND from_id=1", @@ -1498,14 +1497,13 @@ pub async fn handle_mdn( Ok(( row.get::<_, MsgId>("msg_id")?, row.get::<_, ChatId>("chat_id")?, - row.get::<_, Chattype>("type")?, row.get::<_, MessageState>("state")?, )) }, ) .await?; - let (msg_id, chat_id, chat_type, msg_state) = if let Some(res) = res { + let (msg_id, chat_id, msg_state) = if let Some(res) = res { res } else { info!( @@ -1516,63 +1514,28 @@ pub async fn handle_mdn( return Ok(None); }; - let mut read_by_all = false; + if !context + .sql + .exists( + "SELECT COUNT(*) FROM msgs_mdns WHERE msg_id=? AND contact_id=?;", + paramsv![msg_id, from_id as i32,], + ) + .await? + { + context + .sql + .execute( + "INSERT INTO msgs_mdns (msg_id, contact_id, timestamp_sent) VALUES (?, ?, ?);", + paramsv![msg_id, from_id as i32, timestamp_sent], + ) + .await?; + } + if msg_state == MessageState::OutPreparing || msg_state == MessageState::OutPending || msg_state == MessageState::OutDelivered { - let mdn_already_in_table = context - .sql - .exists( - "SELECT COUNT(*) FROM msgs_mdns WHERE msg_id=? AND contact_id=?;", - paramsv![msg_id, from_id as i32,], - ) - .await?; - - if !mdn_already_in_table { - context - .sql - .execute( - "INSERT INTO msgs_mdns (msg_id, contact_id, timestamp_sent) VALUES (?, ?, ?);", - paramsv![msg_id, from_id as i32, timestamp_sent], - ) - .await?; - } - - // Normal chat? that's quite easy. - if chat_type == Chattype::Single { - update_msg_state(context, msg_id, MessageState::OutMdnRcvd).await; - read_by_all = true; - } else { - // send event about new state - let ist_cnt = context - .sql - .count( - "SELECT COUNT(*) FROM msgs_mdns WHERE msg_id=?;", - paramsv![msg_id], - ) - .await?; - - // Groupsize: Min. MDNs - // 1 S n/a - // 2 SR 1 - // 3 SRR 2 - // 4 SRRR 2 - // 5 SRRRR 3 - // 6 SRRRRR 3 - // - // (S=Sender, R=Recipient) - - // for rounding, SELF is already included! - let soll_cnt = (chat::get_chat_contact_cnt(context, chat_id).await? + 1) / 2; - if ist_cnt >= soll_cnt { - update_msg_state(context, msg_id, MessageState::OutMdnRcvd).await; - read_by_all = true; - } // else wait for more receipts - } - } - - if read_by_all { + update_msg_state(context, msg_id, MessageState::OutMdnRcvd).await; Ok(Some((chat_id, msg_id))) } else { Ok(None)