From 763b13e7003f17a3ca1a9abb370cb40adb25ae9b Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Sun, 22 Oct 2023 18:00:02 +0200 Subject: [PATCH] Avoid duplicate acks for messages with mentions --- crates/channel/src/channel_chat.rs | 21 ++++++------ crates/collab_ui/src/chat_panel.rs | 54 +++++++++++++++++------------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/crates/channel/src/channel_chat.rs b/crates/channel/src/channel_chat.rs index b6212d378f..ca344c409f 100644 --- a/crates/channel/src/channel_chat.rs +++ b/crates/channel/src/channel_chat.rs @@ -21,6 +21,7 @@ use util::{post_inc, ResultExt as _, TryFutureExt}; pub struct ChannelChat { channel: Arc, messages: SumTree, + acknowledged_message_ids: HashSet, channel_store: ModelHandle, loaded_all_messages: bool, last_acknowledged_id: Option, @@ -117,6 +118,7 @@ impl ChannelChat { rpc: client, outgoing_messages_lock: Default::default(), messages: Default::default(), + acknowledged_message_ids: Default::default(), loaded_all_messages, next_pending_message_id: 0, last_acknowledged_id: None, @@ -370,16 +372,15 @@ impl ChannelChat { cursor.item().unwrap() } - pub fn rendered_message(&self, id: ChannelMessageId) { - let ChannelMessageId::Saved(id) = id else { - return; - }; - self.rpc - .send(proto::AckChannelMessage { - channel_id: self.channel.id, - message_id: id, - }) - .ok(); + pub fn acknowledge_message(&mut self, id: u64) { + if self.acknowledged_message_ids.insert(id) { + self.rpc + .send(proto::AckChannelMessage { + channel_id: self.channel.id, + message_id: id, + }) + .ok(); + } } pub fn messages_in_range(&self, range: Range) -> impl Iterator { diff --git a/crates/collab_ui/src/chat_panel.rs b/crates/collab_ui/src/chat_panel.rs index 30134eb5cd..b68a244437 100644 --- a/crates/collab_ui/src/chat_panel.rs +++ b/crates/collab_ui/src/chat_panel.rs @@ -346,32 +346,38 @@ impl ChatPanel { } fn render_message(&mut self, ix: usize, cx: &mut ViewContext) -> AnyElement { - let (message, is_continuation, is_last, is_admin) = { - let active_chat = self.active_chat.as_ref().unwrap().0.read(cx); - let is_admin = self - .channel_store - .read(cx) - .is_user_admin(active_chat.channel().id); - let last_message = active_chat.message(ix.saturating_sub(1)); - let this_message = active_chat.message(ix); - let is_continuation = last_message.id != this_message.id - && this_message.sender.id == last_message.sender.id; + let (message, is_continuation, is_last, is_admin) = self + .active_chat + .as_ref() + .unwrap() + .0 + .update(cx, |active_chat, cx| { + let is_admin = self + .channel_store + .read(cx) + .is_user_admin(active_chat.channel().id); + let last_message = active_chat.message(ix.saturating_sub(1)); + let this_message = active_chat.message(ix).clone(); + let is_continuation = last_message.id != this_message.id + && this_message.sender.id == last_message.sender.id; - if this_message - .mentions - .iter() - .any(|(_, user_id)| Some(*user_id) == self.client.user_id()) - { - active_chat.rendered_message(this_message.id); - } + if let ChannelMessageId::Saved(id) = this_message.id { + if this_message + .mentions + .iter() + .any(|(_, user_id)| Some(*user_id) == self.client.user_id()) + { + active_chat.acknowledge_message(id); + } + } - ( - this_message.clone(), - is_continuation, - active_chat.message_count() == ix + 1, - is_admin, - ) - }; + ( + this_message, + is_continuation, + active_chat.message_count() == ix + 1, + is_admin, + ) + }); let is_pending = message.is_pending(); let theme = theme::current(cx);