Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
Nathan Sobo 2021-08-24 09:29:14 -06:00
parent 39ad7f6a60
commit 2701abde11
2 changed files with 68 additions and 44 deletions

View File

@ -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"))

View File

@ -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);
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);
}
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<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>,