Detailed changes
@@ -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();
}
}
@@ -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,
@@ -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);
+ }
+}
@@ -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()
@@ -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();