WIP

Max Brunsfeld created

Change summary

server/src/tests.rs | 31 +++++++++++++++++++----------
zed/src/channel.rs  | 48 ++++++++++++++++++++++++++++++++++++++--------
zed/src/rpc.rs      | 14 +++++++-----
3 files changed, 67 insertions(+), 26 deletions(-)

Detailed changes

server/src/tests.rs 🔗

@@ -14,6 +14,7 @@ use sqlx::{
 };
 use std::{path::Path, sync::Arc};
 use zed::{
+    channel::{ChannelDetails, ChannelList},
     editor::Editor,
     fs::{FakeFs, Fs as _},
     language::LanguageRegistry,
@@ -514,17 +515,25 @@ async fn test_basic_chat(mut cx_a: TestAppContext, cx_b: TestAppContext) {
     .await
     .unwrap();
 
-    // let channels_a = client_a.get_channels().await;
-    // assert_eq!(channels_a.len(), 1);
-    // assert_eq!(channels_a[0].read(&cx_a).name(), "test-channel");
-
-    // assert_eq!(
-    //     db.get_recent_channel_messages(channel_id, 50)
-    //         .await
-    //         .unwrap()[0]
-    //         .body,
-    //     "first message!"
-    // );
+    let channels_a = ChannelList::new(client_a, &mut cx_a.to_async())
+        .await
+        .unwrap();
+    let channels_b = ChannelList::new(client_b, &mut cx_b.to_async())
+        .await
+        .unwrap();
+    channels_a.read_with(&cx_a, |list, _| {
+        assert_eq!(
+            list.available_channels(),
+            &[ChannelDetails {
+                id: channel_id.to_proto(),
+                name: "test-channel".to_string()
+            }]
+        )
+    });
+
+    let channel_a = channels_a.read_with(&cx_a, |this, cx| {
+        this.get_channel(channel_id.to_proto(), &cx).unwrap()
+    });
 }
 
 struct TestServer {

zed/src/channel.rs 🔗

@@ -1,11 +1,14 @@
 use crate::rpc::{self, Client};
-use anyhow::Result;
-use gpui::{Entity, ModelContext, WeakModelHandle};
+use anyhow::{Context, Result};
+use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, WeakModelHandle};
 use std::{
     collections::{HashMap, VecDeque},
     sync::Arc,
 };
-use zrpc::{proto::ChannelMessageSent, TypedEnvelope};
+use zrpc::{
+    proto::{self, ChannelMessageSent},
+    TypedEnvelope,
+};
 
 pub struct ChannelList {
     available_channels: Vec<ChannelDetails>,
@@ -13,10 +16,12 @@ pub struct ChannelList {
     rpc: Arc<Client>,
 }
 
+#[derive(Debug, PartialEq)]
 pub struct ChannelDetails {
-    id: u64,
-    name: String,
+    pub id: u64,
+    pub name: String,
 }
+
 pub struct Channel {
     details: ChannelDetails,
     first_message_id: Option<u64>,
@@ -35,12 +40,28 @@ impl Entity for ChannelList {
 }
 
 impl ChannelList {
-    fn new(rpc: Arc<rpc::Client>) -> Self {
-        Self {
-            available_channels: Default::default(),
+    pub async fn new(rpc: Arc<rpc::Client>, cx: &mut AsyncAppContext) -> Result<ModelHandle<Self>> {
+        let response = rpc
+            .request(proto::GetChannels {})
+            .await
+            .context("failed to fetch available channels")?;
+
+        Ok(cx.add_model(|_| Self {
+            available_channels: response.channels.into_iter().map(Into::into).collect(),
             channels: Default::default(),
             rpc,
-        }
+        }))
+    }
+
+    pub fn available_channels(&self) -> &[ChannelDetails] {
+        &self.available_channels
+    }
+
+    pub fn get_channel(&self, id: u64, cx: &AppContext) -> Option<ModelHandle<Channel>> {
+        self.channels
+            .get(&id)
+            .cloned()
+            .and_then(|handle| handle.upgrade(cx))
     }
 }
 
@@ -70,3 +91,12 @@ impl Channel {
         Ok(())
     }
 }
+
+impl From<proto::Channel> for ChannelDetails {
+    fn from(message: proto::Channel) -> Self {
+        Self {
+            id: message.id,
+            name: message.name,
+        }
+    }
+}

zed/src/rpc.rs 🔗

@@ -46,12 +46,14 @@ pub struct Subscription {
 impl Drop for Subscription {
     fn drop(&mut self) {
         if let Some(client) = self.client.upgrade() {
-            client
-                .state
-                .write()
-                .model_handlers
-                .remove(&self.id)
-                .unwrap();
+            drop(
+                client
+                    .state
+                    .write()
+                    .model_handlers
+                    .remove(&self.id)
+                    .unwrap(),
+            );
         }
     }
 }