mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
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.
This commit is contained in:
11
src/chat.rs
11
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<usize> {
|
||||
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<usize> {
|
||||
if context.sql.is_open().await {
|
||||
// no database, no chats - this is no error (needed eg. for information)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user