diff --git a/zed/src/channel.rs b/zed/src/channel.rs index f65320ae7f..37459a1215 100644 --- a/zed/src/channel.rs +++ b/zed/src/channel.rs @@ -5,8 +5,9 @@ use crate::{ use anyhow::{anyhow, Context, Result}; use gpui::{ sum_tree::{self, Bias, SumTree}, - Entity, ModelContext, ModelHandle, MutableAppContext, WeakModelHandle, + Entity, ModelContext, ModelHandle, MutableAppContext, Task, WeakModelHandle, }; +use postage::prelude::Stream; use std::{ collections::{hash_map, HashMap}, ops::Range, @@ -21,6 +22,7 @@ pub struct ChannelList { available_channels: Option>, channels: HashMap>, rpc: Arc, + _task: Task>, } #[derive(Clone, Debug, PartialEq)] @@ -74,27 +76,42 @@ impl Entity for ChannelList { impl ChannelList { pub fn new(rpc: Arc, cx: &mut ModelContext) -> Self { - cx.spawn(|this, mut cx| { + let _task = cx.spawn(|this, mut cx| { let rpc = rpc.clone(); async move { - let response = rpc - .request(proto::GetChannels {}) - .await - .context("failed to fetch available channels")?; - this.update(&mut cx, |this, cx| { - this.available_channels = - Some(response.channels.into_iter().map(Into::into).collect()); - cx.notify(); - }); - Ok(()) + let mut user_id = rpc.user_id(); + loop { + let available_channels = if user_id.recv().await.unwrap().is_some() { + Some( + rpc.request(proto::GetChannels {}) + .await + .context("failed to fetch available channels")? + .channels + .into_iter() + .map(Into::into) + .collect(), + ) + } else { + None + }; + + this.update(&mut cx, |this, cx| { + if available_channels.is_none() { + this.channels.clear(); + } + this.available_channels = available_channels; + cx.notify(); + }); + } } .log_err() - }) - .detach(); + }); + Self { available_channels: None, channels: Default::default(), rpc, + _task, } } @@ -223,8 +240,7 @@ impl Channel { } fn current_user_id(&self) -> Result { - self - .rpc + self.rpc .user_id() .borrow() .ok_or_else(|| anyhow!("not logged in")) diff --git a/zed/src/chat_panel.rs b/zed/src/chat_panel.rs index de4d183d5a..d722d5add9 100644 --- a/zed/src/chat_panel.rs +++ b/zed/src/chat_panel.rs @@ -5,8 +5,8 @@ use crate::{ Settings, }; use gpui::{ - action, elements::*, Entity, ModelHandle, MutableAppContext, RenderContext, Subscription, View, - ViewContext, ViewHandle, + action, elements::*, keymap::Binding, Entity, ModelHandle, MutableAppContext, RenderContext, + Subscription, View, ViewContext, ViewHandle, }; use postage::watch; @@ -24,6 +24,8 @@ action!(Send); pub fn init(cx: &mut MutableAppContext) { cx.add_action(ChatPanel::send); + + cx.add_bindings(vec![Binding::new("enter", Send, Some("ChatPanel"))]); } impl ChatPanel { @@ -41,44 +43,50 @@ impl ChatPanel { settings, }; - this.assign_active_channel(cx); + this.init_active_channel(cx); cx.observe(&this.channel_list, |this, _, cx| { - this.assign_active_channel(cx); + this.init_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()) - .map(|details| details.id) - { - return list.get_channel(channel_id, cx); + fn init_active_channel(&mut self, cx: &mut ViewContext) { + if self.active_channel.is_none() { + let channel = self.channel_list.update(cx, |list, cx| { + if let Some(channel_id) = list + .available_channels() + .and_then(|channels| channels.first()) + .map(|details| details.id) + { + return list.get_channel(channel_id, cx); + } + None + }); + if let Some(channel) = channel { + self.set_active_channel(channel, cx); } - None - }); - if let Some(channel) = channel { - if self.active_channel.as_ref().map(|e| &e.0) != Some(&channel) { - let subscription = cx.subscribe(&channel, Self::channel_did_change); - self.messages = ListState::new( - channel - .read(cx) - .messages() - .cursor::<(), ()>() - .map(|m| self.render_message(m)) - .collect(), - ); - self.active_channel = Some((channel, subscription)); - } - } else { + } else if self.channel_list.read(cx).available_channels().is_none() { self.active_channel = None; } } + fn set_active_channel(&mut self, channel: ModelHandle, cx: &mut ViewContext) { + if self.active_channel.as_ref().map(|e| &e.0) != Some(&channel) { + let subscription = cx.subscribe(&channel, Self::channel_did_change); + self.messages = ListState::new( + channel + .read(cx) + .messages() + .cursor::<(), ()>() + .map(|m| self.render_message(m)) + .collect(), + ); + self.active_channel = Some((channel, subscription)); + } + } + fn channel_did_change( &mut self, _: ModelHandle,