Skip to content

Commit

Permalink
fix: Emit MsgsChanged if the number of unnoticed archived chats could…
Browse files Browse the repository at this point in the history
… decrease (#5768)

Follow-up to 3cf7874 "Emit DC_EVENT_MSGS_CHANGED for
DC_CHAT_ID_ARCHIVED_LINK when the number of archived chats with unread messages increases (#3940)".

In general we don't want to make an extra db query to know if a noticied chat is
archived. Emitting events should be cheap, better to allow false-positive `MsgsChanged` events.
  • Loading branch information
iequidoo committed Jul 22, 2024
1 parent 5815d8f commit c596ee0
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 45 deletions.
69 changes: 44 additions & 25 deletions src/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3268,35 +3268,25 @@ pub async fn marknoticed_chat(context: &Context, chat_id: ChatId) -> Result<()>
context.emit_event(EventType::MsgsNoticed(chat_id_in_archive));
chatlist_events::emit_chatlist_item_changed(context, chat_id_in_archive);
}
chatlist_events::emit_chatlist_item_changed(context, DC_CHAT_ID_ARCHIVED_LINK);
} else {
let exists = context
.sql
.exists(
"SELECT COUNT(*) FROM msgs WHERE state=? AND hidden=0 AND chat_id=?;",
(MessageState::InFresh, chat_id),
)
.await?;
if !exists {
return Ok(());
}

context
.sql
.execute(
"UPDATE msgs
SET state=?
WHERE state=?
AND hidden=0
AND chat_id=?;",
(MessageState::InNoticed, MessageState::InFresh, chat_id),
)
.await?;
} else if context
.sql
.execute(
"UPDATE msgs
SET state=?
WHERE state=?
AND hidden=0
AND chat_id=?;",
(MessageState::InNoticed, MessageState::InFresh, chat_id),
)
.await?
== 0
{
return Ok(());
}

context.emit_event(EventType::MsgsNoticed(chat_id));
chatlist_events::emit_chatlist_item_changed(context, chat_id);

context.on_archived_chats_maybe_noticed();
Ok(())
}

Expand Down Expand Up @@ -3359,6 +3349,7 @@ pub(crate) async fn mark_old_messages_as_noticed(
context,
"Marking chats as noticed because there are newer outgoing messages: {changed_chats:?}."
);
context.on_archived_chats_maybe_noticed();
}

for c in changed_chats {
Expand Down Expand Up @@ -4697,6 +4688,14 @@ impl Context {
SyncAction::SetContacts(addrs) => set_contacts_by_addrs(self, chat_id, addrs).await,
}
}

/// Emits the appropriate `MsgsChanged` event. Should be called if the number of unnoticed
/// archived chats could decrease. In general we don't want to make an extra db query to know if
/// a noticied chat is archived. Emitting events should be cheap, a false-positive `MsgsChanged`
/// is ok.
pub(crate) fn on_archived_chats_maybe_noticed(&self) {
self.emit_msgs_changed(DC_CHAT_ID_ARCHIVED_LINK, MsgId::new(0));
}
}

#[cfg(test)]
Expand Down Expand Up @@ -5868,7 +5867,27 @@ mod tests {
assert_eq!(DC_CHAT_ID_ARCHIVED_LINK.get_fresh_msg_cnt(&t).await?, 2);

// mark one of the archived+muted chats as noticed: check that the archive-link counter is changed as well
t.evtracker.clear_events();
marknoticed_chat(&t, claire_chat_id).await?;
let ev = t
.evtracker
.get_matching(|ev| {
matches!(
ev,
EventType::MsgsChanged {
chat_id: DC_CHAT_ID_ARCHIVED_LINK,
..
}
)
})
.await;
assert_eq!(
ev,
EventType::MsgsChanged {
chat_id: DC_CHAT_ID_ARCHIVED_LINK,
msg_id: MsgId::new(0),
}
);
assert_eq!(bob_chat_id.get_fresh_msg_cnt(&t).await?, 2);
assert_eq!(claire_chat_id.get_fresh_msg_cnt(&t).await?, 0);
assert_eq!(DC_CHAT_ID_ARCHIVED_LINK.get_fresh_msg_cnt(&t).await?, 1);
Expand Down
3 changes: 3 additions & 0 deletions src/imap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,9 @@ impl Session {
set_modseq(context, folder, highest_modseq)
.await
.with_context(|| format!("failed to set MODSEQ for folder {folder}"))?;
if !updated_chat_ids.is_empty() {
context.on_archived_chats_maybe_noticed();
}
for updated_chat_id in updated_chat_ids {
context.emit_event(EventType::MsgsNoticed(updated_chat_id));
chatlist_events::emit_chatlist_item_changed(context, updated_chat_id);
Expand Down
53 changes: 33 additions & 20 deletions src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
use tokio::{fs, io};

use crate::blob::BlobObject;
use crate::chat::{Chat, ChatId, ChatIdBlocked};
use crate::chat::{Chat, ChatId, ChatIdBlocked, ChatVisibility};
use crate::chatlist_events;
use crate::config::Config;
use crate::constants::{
Expand Down Expand Up @@ -1664,6 +1664,7 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> Result<()>
m.param AS param,
m.from_id AS from_id,
m.rfc724_mid AS rfc724_mid,
c.archived AS archived,
c.blocked AS blocked
FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id
WHERE m.id IN ({}) AND m.chat_id>9",
Expand All @@ -1677,42 +1678,49 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> Result<()>
let param: Params = row.get::<_, String>("param")?.parse().unwrap_or_default();
let from_id: ContactId = row.get("from_id")?;
let rfc724_mid: String = row.get("rfc724_mid")?;
let visibility: ChatVisibility = row.get("archived")?;
let blocked: Option<Blocked> = row.get("blocked")?;
let ephemeral_timer: EphemeralTimer = row.get("ephemeral_timer")?;
Ok((
id,
chat_id,
state,
param,
from_id,
rfc724_mid,
blocked.unwrap_or_default(),
(
id,
chat_id,
state,
param,
from_id,
rfc724_mid,
visibility,
blocked.unwrap_or_default(),
),
ephemeral_timer,
))
},
|rows| rows.collect::<Result<Vec<_>, _>>().map_err(Into::into),
)
.await?;

if msgs.iter().any(
|(_id, _chat_id, _state, _param, _from_id, _rfc724_mid, _blocked, ephemeral_timer)| {
*ephemeral_timer != EphemeralTimer::Disabled
},
) {
if msgs
.iter()
.any(|(_, ephemeral_timer)| *ephemeral_timer != EphemeralTimer::Disabled)
{
start_ephemeral_timers_msgids(context, &msg_ids)
.await
.context("failed to start ephemeral timers")?;
}

let mut updated_chat_ids = BTreeSet::new();
let mut archived_chats_maybe_noticed = false;
for (
id,
curr_chat_id,
curr_state,
curr_param,
curr_from_id,
curr_rfc724_mid,
curr_blocked,
(
id,
curr_chat_id,
curr_state,
curr_param,
curr_from_id,
curr_rfc724_mid,
curr_visibility,
curr_blocked,
),
_curr_ephemeral_timer,
) in msgs
{
Expand Down Expand Up @@ -1750,12 +1758,17 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> Result<()>
}
updated_chat_ids.insert(curr_chat_id);
}
archived_chats_maybe_noticed |=
curr_state == MessageState::InFresh && curr_visibility == ChatVisibility::Archived;
}

for updated_chat_id in updated_chat_ids {
context.emit_event(EventType::MsgsNoticed(updated_chat_id));
chatlist_events::emit_chatlist_item_changed(context, updated_chat_id);
}
if archived_chats_maybe_noticed {
context.on_archived_chats_maybe_noticed();
}

Ok(())
}
Expand Down

0 comments on commit c596ee0

Please sign in to comment.