Acknowledge channel notes and chat changes when views are active
Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
parent
af09861f5c
commit
61e0289014
19 changed files with 478 additions and 209 deletions
|
@ -1,6 +1,6 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use call::report_call_event_for_channel;
|
||||
use channel::{Channel, ChannelBuffer, ChannelBufferEvent, ChannelId};
|
||||
use channel::{Channel, ChannelBuffer, ChannelBufferEvent, ChannelId, ChannelStore};
|
||||
use client::{
|
||||
proto::{self, PeerId},
|
||||
Collaborator, ParticipantIndex,
|
||||
|
@ -36,6 +36,7 @@ pub fn init(cx: &mut AppContext) {
|
|||
pub struct ChannelView {
|
||||
pub editor: ViewHandle<Editor>,
|
||||
project: ModelHandle<Project>,
|
||||
channel_store: ModelHandle<ChannelStore>,
|
||||
channel_buffer: ModelHandle<ChannelBuffer>,
|
||||
remote_id: Option<ViewId>,
|
||||
_editor_event_subscription: Subscription,
|
||||
|
@ -94,7 +95,13 @@ impl ChannelView {
|
|||
pane.update(&mut cx, |pane, cx| {
|
||||
pane.items_of_type::<Self>()
|
||||
.find(|channel_view| channel_view.read(cx).channel_buffer == channel_buffer)
|
||||
.unwrap_or_else(|| cx.add_view(|cx| Self::new(project, channel_buffer, cx)))
|
||||
.unwrap_or_else(|| {
|
||||
cx.add_view(|cx| {
|
||||
let mut this = Self::new(project, channel_store, channel_buffer, cx);
|
||||
this.acknowledge_buffer_version(cx);
|
||||
this
|
||||
})
|
||||
})
|
||||
})
|
||||
.ok_or_else(|| anyhow!("pane was dropped"))
|
||||
})
|
||||
|
@ -102,6 +109,7 @@ impl ChannelView {
|
|||
|
||||
pub fn new(
|
||||
project: ModelHandle<Project>,
|
||||
channel_store: ModelHandle<ChannelStore>,
|
||||
channel_buffer: ModelHandle<ChannelBuffer>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
|
@ -121,6 +129,7 @@ impl ChannelView {
|
|||
Self {
|
||||
editor,
|
||||
project,
|
||||
channel_store,
|
||||
channel_buffer,
|
||||
remote_id: None,
|
||||
_editor_event_subscription,
|
||||
|
@ -137,13 +146,44 @@ impl ChannelView {
|
|||
event: &ChannelBufferEvent,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
if let ChannelBufferEvent::Disconnected = event {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
match event {
|
||||
ChannelBufferEvent::Disconnected => self.editor.update(cx, |editor, cx| {
|
||||
editor.set_read_only(true);
|
||||
cx.notify();
|
||||
})
|
||||
}),
|
||||
ChannelBufferEvent::BufferEdited => {
|
||||
if cx.is_self_focused() || self.editor.is_focused(cx) {
|
||||
self.acknowledge_buffer_version(cx);
|
||||
} else {
|
||||
self.channel_store.update(cx, |store, cx| {
|
||||
let channel_buffer = self.channel_buffer.read(cx);
|
||||
store.notes_changed(
|
||||
channel_buffer.channel().id,
|
||||
channel_buffer.epoch(),
|
||||
&channel_buffer.buffer().read(cx).version(),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn acknowledge_buffer_version(&mut self, cx: &mut ViewContext<'_, '_, ChannelView>) {
|
||||
self.channel_store.update(cx, |store, cx| {
|
||||
let channel_buffer = self.channel_buffer.read(cx);
|
||||
store.acknowledge_notes_version(
|
||||
channel_buffer.channel().id,
|
||||
channel_buffer.epoch(),
|
||||
&channel_buffer.buffer().read(cx).version(),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
self.channel_buffer.update(cx, |buffer, cx| {
|
||||
buffer.acknowledge_buffer_version(cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for ChannelView {
|
||||
|
@ -161,6 +201,7 @@ impl View for ChannelView {
|
|||
|
||||
fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||
if cx.is_self_focused() {
|
||||
self.acknowledge_buffer_version(cx);
|
||||
cx.focus(self.editor.as_any())
|
||||
}
|
||||
}
|
||||
|
@ -200,6 +241,7 @@ impl Item for ChannelView {
|
|||
fn clone_on_split(&self, _: WorkspaceId, cx: &mut ViewContext<Self>) -> Option<Self> {
|
||||
Some(Self::new(
|
||||
self.project.clone(),
|
||||
self.channel_store.clone(),
|
||||
self.channel_buffer.clone(),
|
||||
cx,
|
||||
))
|
||||
|
|
|
@ -42,6 +42,7 @@ pub struct ChatPanel {
|
|||
local_timezone: UtcOffset,
|
||||
fs: Arc<dyn Fs>,
|
||||
width: Option<f32>,
|
||||
active: bool,
|
||||
pending_serialization: Task<Option<()>>,
|
||||
subscriptions: Vec<gpui::Subscription>,
|
||||
workspace: WeakViewHandle<Workspace>,
|
||||
|
@ -138,6 +139,7 @@ impl ChatPanel {
|
|||
has_focus: false,
|
||||
subscriptions: Vec::new(),
|
||||
workspace: workspace_handle,
|
||||
active: false,
|
||||
width: None,
|
||||
};
|
||||
|
||||
|
@ -154,9 +156,9 @@ impl ChatPanel {
|
|||
}),
|
||||
);
|
||||
|
||||
this.init_active_channel(cx);
|
||||
this.update_channel_count(cx);
|
||||
cx.observe(&this.channel_store, |this, _, cx| {
|
||||
this.init_active_channel(cx);
|
||||
this.update_channel_count(cx)
|
||||
})
|
||||
.detach();
|
||||
|
||||
|
@ -225,10 +227,8 @@ impl ChatPanel {
|
|||
);
|
||||
}
|
||||
|
||||
fn init_active_channel(&mut self, cx: &mut ViewContext<Self>) {
|
||||
fn update_channel_count(&mut self, cx: &mut ViewContext<Self>) {
|
||||
let channel_count = self.channel_store.read(cx).channel_count();
|
||||
self.message_list.reset(0);
|
||||
self.active_chat = None;
|
||||
self.channel_select.update(cx, |select, cx| {
|
||||
select.set_item_count(channel_count, cx);
|
||||
});
|
||||
|
@ -247,6 +247,7 @@ impl ChatPanel {
|
|||
}
|
||||
let subscription = cx.subscribe(&chat, Self::channel_did_change);
|
||||
self.active_chat = Some((chat, subscription));
|
||||
self.acknowledge_last_message(cx);
|
||||
self.channel_select.update(cx, |select, cx| {
|
||||
if let Some(ix) = self.channel_store.read(cx).index_of_channel(id) {
|
||||
select.set_selected_index(ix, cx);
|
||||
|
@ -268,11 +269,22 @@ impl ChatPanel {
|
|||
new_count,
|
||||
} => {
|
||||
self.message_list.splice(old_range.clone(), *new_count);
|
||||
self.acknowledge_last_message(cx);
|
||||
}
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn acknowledge_last_message(&mut self, cx: &mut ViewContext<'_, '_, ChatPanel>) {
|
||||
if self.active {
|
||||
if let Some((chat, _)) = &self.active_chat {
|
||||
chat.update(cx, |chat, cx| {
|
||||
chat.acknowledge_last_message(cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render_channel(&self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
||||
let theme = theme::current(cx);
|
||||
Flex::column()
|
||||
|
@ -627,8 +639,12 @@ impl Panel for ChatPanel {
|
|||
}
|
||||
|
||||
fn set_active(&mut self, active: bool, cx: &mut ViewContext<Self>) {
|
||||
if active && !is_chat_feature_enabled(cx) {
|
||||
cx.emit(Event::Dismissed);
|
||||
self.active = active;
|
||||
if active {
|
||||
self.acknowledge_last_message(cx);
|
||||
if !is_chat_feature_enabled(cx) {
|
||||
cx.emit(Event::Dismissed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1821,7 +1821,7 @@ impl CollabPanel {
|
|||
channel.name.clone(),
|
||||
theme
|
||||
.channel_name
|
||||
.in_state(channel.has_new_messages)
|
||||
.in_state(channel.unseen_message_id.is_some())
|
||||
.text
|
||||
.clone(),
|
||||
)
|
||||
|
@ -1880,7 +1880,7 @@ impl CollabPanel {
|
|||
let participants =
|
||||
self.channel_store.read(cx).channel_participants(channel_id);
|
||||
if participants.is_empty() {
|
||||
if channel.has_note_changed {
|
||||
if channel.unseen_note_version.is_some() {
|
||||
Svg::new("icons/terminal.svg")
|
||||
.with_color(theme.channel_note_active_color)
|
||||
.constrained()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue