Fix channel messages test

Mikayla created

Change summary

crates/channel/src/channel_chat.rs                | 14 +++++
crates/channel/src/channel_store.rs               | 10 ++++
crates/channel/src/channel_store/channel_index.rs | 20 +++++++-
crates/collab/src/tests/channel_message_tests.rs  | 38 +++++++++++-----
crates/collab_ui/src/chat_panel.rs                | 14 +++++
5 files changed, 77 insertions(+), 19 deletions(-)

Detailed changes

crates/channel/src/channel_chat.rs 🔗

@@ -1,4 +1,4 @@
-use crate::{Channel, ChannelStore};
+use crate::{Channel, ChannelId, ChannelStore};
 use anyhow::{anyhow, Result};
 use client::{
     proto,
@@ -57,6 +57,10 @@ pub enum ChannelChatEvent {
         old_range: Range<usize>,
         new_count: usize,
     },
+    NewMessage {
+        channel_id: ChannelId,
+        message_id: u64,
+    },
 }
 
 pub fn init(client: &Arc<Client>) {
@@ -338,10 +342,15 @@ impl ChannelChat {
             .payload
             .message
             .ok_or_else(|| anyhow!("empty message"))?;
+        let message_id = message.id;
 
         let message = ChannelMessage::from_proto(message, &user_store, &mut cx).await?;
         this.update(&mut cx, |this, cx| {
-            this.insert_messages(SumTree::from_item(message, &()), cx)
+            this.insert_messages(SumTree::from_item(message, &()), cx);
+            cx.emit(ChannelChatEvent::NewMessage {
+                channel_id: this.channel.id,
+                message_id,
+            })
         });
 
         Ok(())
@@ -413,6 +422,7 @@ impl ChannelChat {
                 old_range: start_ix..end_ix,
                 new_count,
             });
+
             cx.notify();
         }
     }

crates/channel/src/channel_store.rs 🔗

@@ -234,6 +234,16 @@ impl ChannelStore {
         cx.notify();
     }
 
+    pub fn new_message(
+        &mut self,
+        channel_id: ChannelId,
+        message_id: u64,
+        cx: &mut ModelContext<Self>,
+    ) {
+        self.channel_index.new_message(channel_id, message_id);
+        cx.notify();
+    }
+
     pub fn acknowledge_message_id(
         &mut self,
         channel_id: ChannelId,

crates/channel/src/channel_store/channel_index.rs 🔗

@@ -71,6 +71,10 @@ impl ChannelIndex {
     pub fn note_changed(&mut self, channel_id: ChannelId, epoch: u64, version: &clock::Global) {
         insert_note_changed(&mut self.channels_by_id, channel_id, epoch, version);
     }
+
+    pub fn new_message(&mut self, channel_id: ChannelId, message_id: u64) {
+        insert_new_message(&mut self.channels_by_id, channel_id, message_id)
+    }
 }
 
 impl Deref for ChannelIndex {
@@ -114,10 +118,7 @@ impl<'a> ChannelPathsInsertGuard<'a> {
     }
 
     pub fn new_messages(&mut self, channel_id: ChannelId, message_id: u64) {
-        if let Some(channel) = self.channels_by_id.get_mut(&channel_id) {
-            let unseen_message_id = Arc::make_mut(channel).unseen_message_id.get_or_insert(0);
-            *unseen_message_id = message_id.max(*unseen_message_id);
-        }
+        insert_new_message(&mut self.channels_by_id, channel_id, message_id)
     }
 
     pub fn insert(&mut self, channel_proto: proto::Channel) {
@@ -224,3 +225,14 @@ fn insert_note_changed(
         }
     }
 }
+
+fn insert_new_message(
+    channels_by_id: &mut BTreeMap<ChannelId, Arc<Channel>>,
+    channel_id: u64,
+    message_id: u64,
+) {
+    if let Some(channel) = channels_by_id.get_mut(&channel_id) {
+        let unseen_message_id = Arc::make_mut(channel).unseen_message_id.get_or_insert(0);
+        *unseen_message_id = message_id.max(*unseen_message_id);
+    }
+}

crates/collab/src/tests/channel_message_tests.rs 🔗

@@ -246,15 +246,6 @@ async fn test_channel_message_changes(
         )
         .await;
 
-    let other_channel_id = server
-        .make_channel(
-            "other-channel",
-            None,
-            (&client_a, cx_a),
-            &mut [(&client_b, cx_b)],
-        )
-        .await;
-
     // Client A sends a message, client B should see that there is a new message.
     let channel_chat_a = client_a
         .channel_store()
@@ -324,16 +315,39 @@ async fn test_channel_message_changes(
 
     assert!(!b_has_messages);
 
-    // Closing the chat should re-enable change tracking
-    todo!();
+    // Sending a message while the chat is closed should change the flag.
+    chat_panel_b.update(cx_b, |chat_panel, cx| {
+        chat_panel.set_active(false, cx);
+    });
+
+    // Sending a message while the chat is open should not change the flag.
+    channel_chat_a
+        .update(cx_a, |c, cx| c.send_message("three".into(), cx).unwrap())
+        .await
+        .unwrap();
 
     deterministic.run_until_parked();
 
+    let b_has_messages = cx_b.read_with(|cx| {
+        client_b
+            .channel_store()
+            .read(cx)
+            .has_new_messages(channel_id)
+            .unwrap()
+    });
+
+    assert!(b_has_messages);
+
+    // Closing the chat should re-enable change tracking
+    cx_b.update(|_| drop(chat_panel_b));
+
     channel_chat_a
-        .update(cx_a, |c, cx| c.send_message("three".into(), cx).unwrap())
+        .update(cx_a, |c, cx| c.send_message("four".into(), cx).unwrap())
         .await
         .unwrap();
 
+    deterministic.run_until_parked();
+
     let b_has_messages = cx_b.read_with(|cx| {
         client_b
             .channel_store()

crates/collab_ui/src/chat_panel.rs 🔗

@@ -273,7 +273,19 @@ impl ChatPanel {
                 new_count,
             } => {
                 self.message_list.splice(old_range.clone(), *new_count);
-                self.acknowledge_last_message(cx);
+                if self.active {
+                    self.acknowledge_last_message(cx);
+                }
+            }
+            ChannelChatEvent::NewMessage {
+                channel_id,
+                message_id,
+            } => {
+                if !self.active {
+                    self.channel_store.update(cx, |store, cx| {
+                        store.new_message(*channel_id, *message_id, cx)
+                    })
+                }
             }
         }
         cx.notify();