@@ -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<Vec<ChannelDetails>>,
channels: HashMap<u64, WeakModelHandle<Channel>>,
rpc: Arc<Client>,
+ _task: Task<Option<()>>,
}
#[derive(Clone, Debug, PartialEq)]
@@ -74,27 +76,42 @@ impl Entity for ChannelList {
impl ChannelList {
pub fn new(rpc: Arc<rpc::Client>, cx: &mut ModelContext<Self>) -> 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<u64> {
- self
- .rpc
+ self.rpc
.user_id()
.borrow()
.ok_or_else(|| anyhow!("not logged in"))
@@ -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<Self>) {
- 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 {
- 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 init_active_channel(&mut self, cx: &mut ViewContext<Self>) {
+ 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);
}
- } else {
+ } else if self.channel_list.read(cx).available_channels().is_none() {
self.active_channel = None;
}
}
+ fn set_active_channel(&mut self, channel: ModelHandle<Channel>, cx: &mut ViewContext<Self>) {
+ 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<Channel>,