WIP

Antonio Scandurra created

Change summary

Cargo.lock                             |  1 
crates/collab/src/integration_tests.rs | 36 +++++++++++++++++++++++++++
crates/collab/src/rpc/store.rs         | 14 ++++++++++
crates/room/Cargo.toml                 |  1 
crates/room/src/participant.rs         | 14 ++++++---
crates/room/src/room.rs                | 27 ++++++++++++++++----
6 files changed, 80 insertions(+), 13 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -4459,7 +4459,6 @@ dependencies = [
  "client",
  "gpui",
  "project",
- "workspace",
 ]
 
 [[package]]

crates/collab/src/integration_tests.rs 🔗

@@ -60,6 +60,42 @@ fn init_logger() {
     }
 }
 
+#[gpui::test(iterations = 10)]
+async fn test_share_project_in_room(
+    deterministic: Arc<Deterministic>,
+    cx_a: &mut TestAppContext,
+    cx_b: &mut TestAppContext,
+) {
+    deterministic.forbid_parking();
+    let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await;
+    let client_a = server.create_client(cx_a, "user_a").await;
+    let client_b = server.create_client(cx_b, "user_b").await;
+    server
+        .make_contacts(vec![(&client_a, cx_a), (&client_b, cx_b)])
+        .await;
+
+    client_a
+        .fs
+        .insert_tree(
+            "/a",
+            json!({
+                ".gitignore": "ignored-dir",
+                "a.txt": "a-contents",
+                "b.txt": "b-contents",
+                "ignored-dir": {
+                    "c.txt": "",
+                    "d.txt": "",
+                }
+            }),
+        )
+        .await;
+
+    let (project_a, worktree_id) = client_a.build_local_project("/a", cx_a).await;
+    let project_id = project_a.update(cx_a, |project, cx| project.share(cx)).await.unwrap();
+
+
+}
+
 #[gpui::test(iterations = 10)]
 async fn test_share_project(
     deterministic: Arc<Deterministic>,

crates/collab/src/rpc/store.rs 🔗

@@ -7,10 +7,13 @@ use std::{mem, path::PathBuf, str, time::Duration};
 use time::OffsetDateTime;
 use tracing::instrument;
 
+pub type RoomId = u64;
+
 #[derive(Default, Serialize)]
 pub struct Store {
     connections: BTreeMap<ConnectionId, ConnectionState>,
     connections_by_user_id: BTreeMap<UserId, HashSet<ConnectionId>>,
+    rooms: BTreeMap<RoomId, Room>,
     projects: BTreeMap<ProjectId, Project>,
     #[serde(skip)]
     channels: BTreeMap<ChannelId, Channel>,
@@ -25,6 +28,17 @@ struct ConnectionState {
     channels: HashSet<ChannelId>,
 }
 
+#[derive(Serialize)]
+struct Room {
+    participants: HashMap<ConnectionId, Participant>,
+}
+
+#[derive(Serialize)]
+struct Participant {
+    user_id: UserId,
+    shared_projects: HashSet<ProjectId>,
+}
+
 #[derive(Serialize)]
 pub struct Project {
     pub online: bool,

crates/room/Cargo.toml 🔗

@@ -19,7 +19,6 @@ anyhow = "1.0.38"
 client = { path = "../client" }
 gpui = { path = "../gpui" }
 project = { path = "../project" }
-workspace = { path = "../workspace" }
 
 [dev-dependencies]
 client = { path = "../client", features = ["test-support"] }

crates/room/src/participant.rs 🔗

@@ -1,15 +1,19 @@
 use client::User;
-use gpui::{ModelHandle, ViewHandle};
+use gpui::ModelHandle;
 use project::Project;
-use workspace::Workspace;
+
+pub enum Location {
+    Project { project_id: usize },
+    External,
+}
 
 pub struct LocalParticipant {
     user: User,
-    workspaces: Vec<ViewHandle<Workspace>>,
+    projects: Vec<ModelHandle<Project>>,
 }
 
 pub struct RemoteParticipant {
     user: User,
-    workspaces: Vec<ViewHandle<Workspace>>,
-    active_workspace_id: usize,
+    projects: Vec<ModelHandle<Project>>,
+    location: Location,
 }

crates/room/src/room.rs 🔗

@@ -1,19 +1,27 @@
 mod participant;
 
 use anyhow::Result;
-use client::Client;
-use gpui::ModelHandle;
+use client::{Client, PeerId};
+use gpui::{Entity, ModelHandle};
 use participant::{LocalParticipant, RemoteParticipant};
 use project::Project;
-use std::sync::Arc;
+use std::{collections::HashMap, sync::Arc};
+
+pub enum Event {
+    PeerChangedActiveProject,
+}
 
 pub struct Room {
     id: u64,
     local_participant: LocalParticipant,
-    remote_participants: Vec<RemoteParticipant>,
+    remote_participants: HashMap<PeerId, RemoteParticipant>,
     client: Arc<Client>,
 }
 
+impl Entity for Room {
+    type Event = Event;
+}
+
 impl Room {
     pub async fn create(client: Arc<Client>) -> Result<u64> {
         todo!()
@@ -27,11 +35,18 @@ impl Room {
         todo!()
     }
 
-    pub async fn share(&mut self) -> Result<()> {
+    pub async fn share_project(&mut self, project: ModelHandle<Project>) -> Result<()> {
+        todo!()
+    }
+
+    pub async fn unshare_project(&mut self, project: ModelHandle<Project>) -> Result<()> {
         todo!()
     }
 
-    pub async fn unshare(&mut self) -> Result<()> {
+    pub async fn set_active_project(
+        &mut self,
+        project: Option<&ModelHandle<Project>>,
+    ) -> Result<()> {
         todo!()
     }