diff --git a/gpui/src/elements/list.rs b/gpui/src/elements/list.rs index d6101a5951..2e692f4a99 100644 --- a/gpui/src/elements/list.rs +++ b/gpui/src/elements/list.rs @@ -219,7 +219,7 @@ impl StateInner { let start_ix = cursor.sum_start().0; cursor.seek(&Height(self.scroll_top + height), Bias::Left, &()); let end_ix = cursor.sum_start().0; - start_ix..end_ix + 1 + start_ix..self.elements.len().min(end_ix + 1) } fn scroll( diff --git a/zed/src/channel.rs b/zed/src/channel.rs index efb51eb239..148d541f03 100644 --- a/zed/src/channel.rs +++ b/zed/src/channel.rs @@ -183,6 +183,7 @@ impl Channel { }) }) .detach(); + cx.notify(); Ok(()) } diff --git a/zed/src/chat_panel.rs b/zed/src/chat_panel.rs index 86a7762fac..dfb4e545be 100644 --- a/zed/src/chat_panel.rs +++ b/zed/src/chat_panel.rs @@ -1,31 +1,33 @@ -use super::{ - channel::{Channel, ChannelList}, - Settings, -}; -use gpui::{elements::*, Entity, ModelHandle, RenderContext, View, ViewContext}; -use postage::watch; +use super::channel::{Channel, ChannelList}; +use gpui::{elements::*, Entity, ModelHandle, RenderContext, Subscription, View, ViewContext}; pub struct ChatPanel { channel_list: ModelHandle, - active_channel: Option>, - // active_channel_subscription: Subscription, + active_channel: Option<(ModelHandle, Subscription)>, messages: ListState, } pub enum Event {} impl ChatPanel { - pub fn new( - channel_list: ModelHandle, - settings: watch::Receiver, - cx: &mut ViewContext, - ) -> Self { + pub fn new(channel_list: ModelHandle, cx: &mut ViewContext) -> Self { let mut this = Self { channel_list, messages: ListState::new(Vec::new()), active_channel: None, }; - let channel = this.channel_list.update(cx, |list, cx| { + + this.assign_active_channel(cx); + cx.observe(&this.channel_list, |this, _, cx| { + this.assign_active_channel(cx); + }) + .detach(); + + this + } + + pub fn assign_active_channel(&mut self, cx: &mut ViewContext) { + let channel = self.channel_list.update(cx, |list, cx| { if let Some(channel_id) = list .available_channels() .and_then(|channels| channels.first()) @@ -36,13 +38,17 @@ impl ChatPanel { None }); if let Some(channel) = channel { - this.set_active_channel(channel); + if self.active_channel.as_ref().map(|e| &e.0) != Some(&channel) { + let subscription = cx.observe(&channel, Self::channel_did_change); + self.active_channel = Some((channel, subscription)); + } + } else { + self.active_channel = None; } - this } - pub fn set_active_channel(&mut self, channel: ModelHandle) { - // + fn channel_did_change(&mut self, _: ModelHandle, cx: &mut ViewContext) { + cx.notify(); } } @@ -55,7 +61,7 @@ impl View for ChatPanel { "ChatPanel" } - fn render(&self, cx: &RenderContext) -> gpui::ElementBox { + fn render(&self, _: &RenderContext) -> gpui::ElementBox { List::new(self.messages.clone()).boxed() } } diff --git a/zed/src/workspace.rs b/zed/src/workspace.rs index 28ed2701d1..b6843fdc0b 100644 --- a/zed/src/workspace.rs +++ b/zed/src/workspace.rs @@ -374,14 +374,8 @@ impl Workspace { let mut right_sidebar = Sidebar::new(Side::Right); right_sidebar.add_item( "icons/comment-16.svg", - cx.add_view(|cx| { - ChatPanel::new( - app_state.channel_list.clone(), - app_state.settings.clone(), - cx, - ) - }) - .into(), + cx.add_view(|cx| ChatPanel::new(app_state.channel_list.clone(), cx)) + .into(), ); right_sidebar.add_item("icons/user-16.svg", cx.add_view(|_| ProjectBrowser).into());