hosted projects (#8627)

- **Allow joining a hosted project**

You can't yet do anything in a hosted project, but you can join it and
look how empty it is.

Release Notes:

- N/A
This commit is contained in:
Conrad Irwin 2024-03-04 19:17:40 -07:00 committed by GitHub
parent 4167c66b86
commit 27c5343707
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 519 additions and 232 deletions

View file

@ -11,7 +11,7 @@ mod project_tests;
use anyhow::{anyhow, bail, Context as _, Result};
use async_trait::async_trait;
use client::{proto, Client, Collaborator, TypedEnvelope, UserStore};
use client::{proto, Client, Collaborator, HostedProjectId, TypedEnvelope, UserStore};
use clock::ReplicaId;
use collections::{hash_map, BTreeMap, HashMap, HashSet, VecDeque};
use copilot::Copilot;
@ -167,6 +167,7 @@ pub struct Project {
prettiers_per_worktree: HashMap<WorktreeId, HashSet<Option<PathBuf>>>,
prettier_instances: HashMap<PathBuf, PrettierInstance>,
tasks: Model<Inventory>,
hosted_project_id: Option<HostedProjectId>,
}
pub enum LanguageServerToQuery {
@ -605,6 +606,7 @@ impl Project {
prettiers_per_worktree: HashMap::default(),
prettier_instances: HashMap::default(),
tasks,
hosted_project_id: None,
}
})
}
@ -615,17 +617,30 @@ impl Project {
user_store: Model<UserStore>,
languages: Arc<LanguageRegistry>,
fs: Arc<dyn Fs>,
role: proto::ChannelRole,
mut cx: AsyncAppContext,
cx: AsyncAppContext,
) -> Result<Model<Self>> {
client.authenticate_and_connect(true, &cx).await?;
let subscription = client.subscribe_to_entity(remote_id)?;
let response = client
.request_envelope(proto::JoinProject {
project_id: remote_id,
})
.await?;
Self::from_join_project_response(response, None, client, user_store, languages, fs, cx)
.await
}
async fn from_join_project_response(
response: TypedEnvelope<proto::JoinProjectResponse>,
hosted_project_id: Option<HostedProjectId>,
client: Arc<Client>,
user_store: Model<UserStore>,
languages: Arc<LanguageRegistry>,
fs: Arc<dyn Fs>,
mut cx: AsyncAppContext,
) -> Result<Model<Self>> {
let remote_id = response.payload.project_id;
let role = response.payload.role();
let subscription = client.subscribe_to_entity(remote_id)?;
let this = cx.new_model(|cx| {
let replica_id = response.payload.replica_id as ReplicaId;
let tasks = Inventory::new(cx);
@ -714,6 +729,7 @@ impl Project {
prettiers_per_worktree: HashMap::default(),
prettier_instances: HashMap::default(),
tasks,
hosted_project_id,
};
this.set_role(role, cx);
for worktree in worktrees {
@ -742,6 +758,31 @@ impl Project {
Ok(this)
}
pub async fn hosted(
hosted_project_id: HostedProjectId,
user_store: Model<UserStore>,
client: Arc<Client>,
languages: Arc<LanguageRegistry>,
fs: Arc<dyn Fs>,
cx: AsyncAppContext,
) -> Result<Model<Self>> {
let response = client
.request_envelope(proto::JoinHostedProject {
id: hosted_project_id.0,
})
.await?;
Self::from_join_project_response(
response,
Some(hosted_project_id),
client,
user_store,
languages,
fs,
cx,
)
.await
}
fn release(&mut self, cx: &mut AppContext) {
match &self.client_state {
ProjectClientState::Local => {}
@ -987,6 +1028,10 @@ impl Project {
}
}
pub fn hosted_project_id(&self) -> Option<HostedProjectId> {
self.hosted_project_id
}
pub fn replica_id(&self) -> ReplicaId {
match self.client_state {
ProjectClientState::Remote { replica_id, .. } => replica_id,