Start work on displaying channels and invites in collab panel
This commit is contained in:
parent
003a711dea
commit
7954b02819
8 changed files with 412 additions and 70 deletions
|
@ -6,18 +6,19 @@ use rpc::{proto, TypedEnvelope};
|
|||
use std::sync::Arc;
|
||||
|
||||
pub struct ChannelStore {
|
||||
channels: Vec<Channel>,
|
||||
channel_invitations: Vec<Channel>,
|
||||
channels: Vec<Arc<Channel>>,
|
||||
channel_invitations: Vec<Arc<Channel>>,
|
||||
client: Arc<Client>,
|
||||
user_store: ModelHandle<UserStore>,
|
||||
_rpc_subscription: Subscription,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Channel {
|
||||
pub id: u64,
|
||||
pub name: String,
|
||||
pub parent_id: Option<u64>,
|
||||
pub depth: usize,
|
||||
}
|
||||
|
||||
impl Entity for ChannelStore {
|
||||
|
@ -41,11 +42,11 @@ impl ChannelStore {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn channels(&self) -> &[Channel] {
|
||||
pub fn channels(&self) -> &[Arc<Channel>] {
|
||||
&self.channels
|
||||
}
|
||||
|
||||
pub fn channel_invitations(&self) -> &[Channel] {
|
||||
pub fn channel_invitations(&self) -> &[Arc<Channel>] {
|
||||
&self.channel_invitations
|
||||
}
|
||||
|
||||
|
@ -97,6 +98,10 @@ impl ChannelStore {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_channel_invite_pending(&self, channel: &Arc<Channel>) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn remove_member(
|
||||
&self,
|
||||
channel_id: u64,
|
||||
|
@ -124,66 +129,74 @@ impl ChannelStore {
|
|||
_: Arc<Client>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<()> {
|
||||
let payload = message.payload;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.channels
|
||||
.retain(|channel| !payload.remove_channels.contains(&channel.id));
|
||||
this.channel_invitations
|
||||
.retain(|channel| !payload.remove_channel_invitations.contains(&channel.id));
|
||||
this.update_channels(message.payload, cx);
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
for channel in payload.channel_invitations {
|
||||
if let Some(existing_channel) = this
|
||||
.channel_invitations
|
||||
.iter_mut()
|
||||
.find(|c| c.id == channel.id)
|
||||
{
|
||||
existing_channel.name = channel.name;
|
||||
continue;
|
||||
pub(crate) fn update_channels(
|
||||
&mut self,
|
||||
payload: proto::UpdateChannels,
|
||||
cx: &mut ModelContext<ChannelStore>,
|
||||
) {
|
||||
self.channels
|
||||
.retain(|channel| !payload.remove_channels.contains(&channel.id));
|
||||
self.channel_invitations
|
||||
.retain(|channel| !payload.remove_channel_invitations.contains(&channel.id));
|
||||
|
||||
for channel in payload.channel_invitations {
|
||||
if let Some(existing_channel) = self
|
||||
.channel_invitations
|
||||
.iter_mut()
|
||||
.find(|c| c.id == channel.id)
|
||||
{
|
||||
Arc::make_mut(existing_channel).name = channel.name;
|
||||
continue;
|
||||
}
|
||||
|
||||
self.channel_invitations.insert(
|
||||
0,
|
||||
Arc::new(Channel {
|
||||
id: channel.id,
|
||||
name: channel.name,
|
||||
parent_id: None,
|
||||
depth: 0,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
for channel in payload.channels {
|
||||
if let Some(existing_channel) = self.channels.iter_mut().find(|c| c.id == channel.id) {
|
||||
Arc::make_mut(existing_channel).name = channel.name;
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(parent_id) = channel.parent_id {
|
||||
if let Some(ix) = self.channels.iter().position(|c| c.id == parent_id) {
|
||||
let depth = self.channels[ix].depth + 1;
|
||||
self.channels.insert(
|
||||
ix + 1,
|
||||
Arc::new(Channel {
|
||||
id: channel.id,
|
||||
name: channel.name,
|
||||
parent_id: Some(parent_id),
|
||||
depth,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
this.channel_invitations.insert(
|
||||
} else {
|
||||
self.channels.insert(
|
||||
0,
|
||||
Channel {
|
||||
Arc::new(Channel {
|
||||
id: channel.id,
|
||||
name: channel.name,
|
||||
parent_id: None,
|
||||
},
|
||||
depth: 0,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
for channel in payload.channels {
|
||||
if let Some(existing_channel) =
|
||||
this.channels.iter_mut().find(|c| c.id == channel.id)
|
||||
{
|
||||
existing_channel.name = channel.name;
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(parent_id) = channel.parent_id {
|
||||
if let Some(ix) = this.channels.iter().position(|c| c.id == parent_id) {
|
||||
this.channels.insert(
|
||||
ix + 1,
|
||||
Channel {
|
||||
id: channel.id,
|
||||
name: channel.name,
|
||||
parent_id: Some(parent_id),
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.channels.insert(
|
||||
0,
|
||||
Channel {
|
||||
id: channel.id,
|
||||
name: channel.name,
|
||||
parent_id: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
|
95
crates/client/src/channel_store_tests.rs
Normal file
95
crates/client/src/channel_store_tests.rs
Normal file
|
@ -0,0 +1,95 @@
|
|||
use util::http::FakeHttpClient;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[gpui::test]
|
||||
fn test_update_channels(cx: &mut AppContext) {
|
||||
let http = FakeHttpClient::with_404_response();
|
||||
let client = Client::new(http.clone(), cx);
|
||||
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http, cx));
|
||||
|
||||
let channel_store = cx.add_model(|cx| ChannelStore::new(client, user_store, cx));
|
||||
|
||||
update_channels(
|
||||
&channel_store,
|
||||
proto::UpdateChannels {
|
||||
channels: vec![
|
||||
proto::Channel {
|
||||
id: 1,
|
||||
name: "b".to_string(),
|
||||
parent_id: None,
|
||||
},
|
||||
proto::Channel {
|
||||
id: 2,
|
||||
name: "a".to_string(),
|
||||
parent_id: None,
|
||||
},
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
cx,
|
||||
);
|
||||
assert_channels(
|
||||
&channel_store,
|
||||
&[
|
||||
//
|
||||
(0, "a"),
|
||||
(0, "b"),
|
||||
],
|
||||
cx,
|
||||
);
|
||||
|
||||
update_channels(
|
||||
&channel_store,
|
||||
proto::UpdateChannels {
|
||||
channels: vec![
|
||||
proto::Channel {
|
||||
id: 3,
|
||||
name: "x".to_string(),
|
||||
parent_id: Some(1),
|
||||
},
|
||||
proto::Channel {
|
||||
id: 4,
|
||||
name: "y".to_string(),
|
||||
parent_id: Some(2),
|
||||
},
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
cx,
|
||||
);
|
||||
assert_channels(
|
||||
&channel_store,
|
||||
&[
|
||||
//
|
||||
(0, "a"),
|
||||
(1, "y"),
|
||||
(0, "b"),
|
||||
(1, "x"),
|
||||
],
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
fn update_channels(
|
||||
channel_store: &ModelHandle<ChannelStore>,
|
||||
message: proto::UpdateChannels,
|
||||
cx: &mut AppContext,
|
||||
) {
|
||||
channel_store.update(cx, |store, cx| store.update_channels(message, cx));
|
||||
}
|
||||
|
||||
fn assert_channels(
|
||||
channel_store: &ModelHandle<ChannelStore>,
|
||||
expected_channels: &[(usize, &str)],
|
||||
cx: &AppContext,
|
||||
) {
|
||||
channel_store.read_with(cx, |store, _| {
|
||||
let actual = store
|
||||
.channels()
|
||||
.iter()
|
||||
.map(|c| (c.depth, c.name.as_str()))
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(actual, expected_channels);
|
||||
});
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub mod test;
|
||||
|
||||
#[cfg(test)]
|
||||
mod channel_store_tests;
|
||||
|
||||
pub mod channel_store;
|
||||
pub mod telemetry;
|
||||
pub mod user;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue