Switch to a new flow for advertising, sharing and joining worktrees
Now, when you open a local worktree, we immediately send an `OpenWorktree` message to the server, telling it the name of the folder that you've opened, and the names of all the collaborators (based on a `.zed.toml` file). The server responds with a unique id for the worktree. When starting share this local worktree, you now include this previously-assigned id in the `ShareWorktree` message. When joining a worktree, there is no longer a need to provide an access token. The access is controlled by the set of "collaborator logins" that were provided when the worktree was initially opened by the host.
This commit is contained in:
+29
-59
@@ -11,10 +11,11 @@ use crate::{
|
||||
rpc,
|
||||
settings::Settings,
|
||||
user,
|
||||
util::TryFutureExt as _,
|
||||
worktree::{File, Worktree},
|
||||
AppState, Authenticate,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use anyhow::Result;
|
||||
use gpui::{
|
||||
action,
|
||||
elements::*,
|
||||
@@ -52,12 +53,10 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||
open_paths(action, cx).detach()
|
||||
});
|
||||
cx.add_global_action(open_new);
|
||||
cx.add_global_action(join_worktree);
|
||||
cx.add_action(Workspace::save_active_item);
|
||||
cx.add_action(Workspace::debug_elements);
|
||||
cx.add_action(Workspace::open_new_file);
|
||||
cx.add_action(Workspace::share_worktree);
|
||||
cx.add_action(Workspace::join_worktree);
|
||||
cx.add_action(Workspace::toggle_sidebar_item);
|
||||
cx.add_bindings(vec![
|
||||
Binding::new("cmd-s", Save, None),
|
||||
@@ -129,14 +128,6 @@ fn open_new(action: &OpenNew, cx: &mut MutableAppContext) {
|
||||
});
|
||||
}
|
||||
|
||||
fn join_worktree(action: &JoinWorktree, cx: &mut MutableAppContext) {
|
||||
cx.add_window(window_options(), |cx| {
|
||||
let mut view = Workspace::new(action.0.as_ref(), cx);
|
||||
view.join_worktree(action, cx);
|
||||
view
|
||||
});
|
||||
}
|
||||
|
||||
fn window_options() -> WindowOptions<'static> {
|
||||
WindowOptions {
|
||||
bounds: RectF::new(vec2f(0., 0.), vec2f(1024., 768.)),
|
||||
@@ -818,67 +809,46 @@ impl Workspace {
|
||||
|
||||
fn share_worktree(&mut self, _: &ShareWorktree, cx: &mut ViewContext<Self>) {
|
||||
let rpc = self.rpc.clone();
|
||||
let platform = cx.platform();
|
||||
cx.spawn(|this, mut cx| {
|
||||
async move {
|
||||
rpc.authenticate_and_connect(&cx).await?;
|
||||
|
||||
let task = cx.spawn(|this, mut cx| async move {
|
||||
rpc.authenticate_and_connect(&cx).await?;
|
||||
let share_task = this.update(&mut cx, |this, cx| {
|
||||
let worktree = this.worktrees.iter().next()?;
|
||||
worktree.update(cx, |worktree, cx| {
|
||||
let worktree = worktree.as_local_mut()?;
|
||||
Some(worktree.share(cx))
|
||||
})
|
||||
});
|
||||
|
||||
let share_task = this.update(&mut cx, |this, cx| {
|
||||
let worktree = this.worktrees.iter().next()?;
|
||||
worktree.update(cx, |worktree, cx| {
|
||||
let worktree = worktree.as_local_mut()?;
|
||||
Some(worktree.share(cx))
|
||||
})
|
||||
});
|
||||
if let Some(share_task) = share_task {
|
||||
share_task.await?;
|
||||
}
|
||||
|
||||
if let Some(share_task) = share_task {
|
||||
let (worktree_id, access_token) = share_task.await?;
|
||||
let worktree_url = rpc::encode_worktree_url(worktree_id, &access_token);
|
||||
log::info!("wrote worktree url to clipboard: {}", worktree_url);
|
||||
platform.write_to_clipboard(ClipboardItem::new(worktree_url));
|
||||
}
|
||||
surf::Result::Ok(())
|
||||
});
|
||||
|
||||
cx.spawn(|_, _| async move {
|
||||
if let Err(e) = task.await {
|
||||
log::error!("sharing failed: {:?}", e);
|
||||
Ok(())
|
||||
}
|
||||
.log_err()
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
fn join_worktree(&mut self, _: &JoinWorktree, cx: &mut ViewContext<Self>) {
|
||||
fn join_worktree(&mut self, id: u64, cx: &mut ViewContext<Self>) {
|
||||
let rpc = self.rpc.clone();
|
||||
let languages = self.languages.clone();
|
||||
|
||||
let task = cx.spawn(|this, mut cx| async move {
|
||||
rpc.authenticate_and_connect(&cx).await?;
|
||||
cx.spawn(|this, mut cx| {
|
||||
async move {
|
||||
rpc.authenticate_and_connect(&cx).await?;
|
||||
let worktree = Worktree::open_remote(rpc.clone(), id, languages, &mut cx).await?;
|
||||
this.update(&mut cx, |workspace, cx| {
|
||||
cx.observe(&worktree, |_, _, cx| cx.notify()).detach();
|
||||
workspace.worktrees.insert(worktree);
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
let worktree_url = cx
|
||||
.platform()
|
||||
.read_from_clipboard()
|
||||
.ok_or_else(|| anyhow!("failed to read url from clipboard"))?;
|
||||
let (worktree_id, access_token) = rpc::decode_worktree_url(worktree_url.text())
|
||||
.ok_or_else(|| anyhow!("failed to decode worktree url"))?;
|
||||
log::info!("read worktree url from clipboard: {}", worktree_url.text());
|
||||
|
||||
let worktree =
|
||||
Worktree::open_remote(rpc.clone(), worktree_id, access_token, languages, &mut cx)
|
||||
.await?;
|
||||
this.update(&mut cx, |workspace, cx| {
|
||||
cx.observe(&worktree, |_, _, cx| cx.notify()).detach();
|
||||
workspace.worktrees.insert(worktree);
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
surf::Result::Ok(())
|
||||
});
|
||||
|
||||
cx.spawn(|_, _| async move {
|
||||
if let Err(e) = task.await {
|
||||
log::error!("joining failed: {}", e);
|
||||
Ok(())
|
||||
}
|
||||
.log_err()
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user