Add "Zed > Sign" In menu item

Nathan Sobo and Antonio Scandurra created

Co-Authored-By: Antonio Scandurra <me@as-cii.com>

Change summary

zed/src/lib.rs            | 17 ++++++++++++++---
zed/src/main.rs           |  4 ++--
zed/src/menus.rs          |  5 +++++
zed/src/rpc.rs            |  7 +++++--
zed/src/theme_selector.rs |  2 +-
zed/src/workspace.rs      |  4 ++--
6 files changed, 29 insertions(+), 10 deletions(-)

Detailed changes

zed/src/lib.rs 🔗

@@ -19,16 +19,18 @@ mod util;
 pub mod workspace;
 pub mod worktree;
 
+use crate::util::TryFutureExt;
 use channel::ChannelList;
 use gpui::{action, ModelHandle};
-pub use settings::Settings;
-
 use parking_lot::Mutex;
 use postage::watch;
 use std::sync::Arc;
 
+pub use settings::Settings;
+
 action!(About);
 action!(Quit);
+action!(Authenticate);
 
 pub struct AppState {
     pub settings_tx: Arc<Mutex<watch::Sender<Settings>>>,
@@ -40,8 +42,17 @@ pub struct AppState {
     pub channel_list: ModelHandle<ChannelList>,
 }
 
-pub fn init(cx: &mut gpui::MutableAppContext) {
+pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
     cx.add_global_action(quit);
+
+    cx.add_global_action({
+        let rpc = app_state.rpc.clone();
+        move |_: &Authenticate, cx| {
+            let rpc = rpc.clone();
+            cx.spawn(|cx| async move { rpc.authenticate_and_connect(cx).log_err().await })
+                .detach();
+        }
+    });
 }
 
 fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) {

zed/src/main.rs 🔗

@@ -39,11 +39,11 @@ fn main() {
             fs: Arc::new(RealFs),
         });
 
-        zed::init(cx);
+        zed::init(&app_state, cx);
         workspace::init(cx);
         editor::init(cx);
         file_finder::init(cx);
-        theme_selector::init(cx, &app_state);
+        theme_selector::init(&app_state, cx);
 
         cx.set_menus(menus::menus(&app_state.clone()));
 

zed/src/menus.rs 🔗

@@ -16,6 +16,11 @@ pub fn menus(state: &Arc<AppState>) -> Vec<Menu<'static>> {
                     action: Box::new(super::About),
                 },
                 MenuItem::Separator,
+                MenuItem::Action {
+                    name: "Sign In",
+                    keystroke: None,
+                    action: Box::new(super::Authenticate),
+                },
                 MenuItem::Action {
                     name: "Share",
                     keystroke: None,

zed/src/rpc.rs 🔗

@@ -124,7 +124,10 @@ impl Client {
         }
     }
 
-    pub async fn log_in_and_connect(self: &Arc<Self>, cx: AsyncAppContext) -> surf::Result<()> {
+    pub async fn authenticate_and_connect(
+        self: &Arc<Self>,
+        cx: AsyncAppContext,
+    ) -> anyhow::Result<()> {
         if self.state.read().connection_id.is_some() {
             return Ok(());
         }
@@ -161,7 +164,7 @@ impl Client {
         user_id: u64,
         conn: Conn,
         cx: AsyncAppContext,
-    ) -> surf::Result<()>
+    ) -> anyhow::Result<()>
     where
         Conn: 'static
             + futures::Sink<WebSocketMessage, Error = WebSocketError>

zed/src/theme_selector.rs 🔗

@@ -34,7 +34,7 @@ action!(Confirm);
 action!(Toggle, Arc<AppState>);
 action!(Reload, Arc<AppState>);
 
-pub fn init(cx: &mut MutableAppContext, app_state: &Arc<AppState>) {
+pub fn init(app_state: &Arc<AppState>, cx: &mut MutableAppContext) {
     cx.add_action(ThemeSelector::confirm);
     cx.add_action(ThemeSelector::select_prev);
     cx.add_action(ThemeSelector::select_next);

zed/src/workspace.rs 🔗

@@ -791,7 +791,7 @@ impl Workspace {
         let platform = cx.platform();
 
         let task = cx.spawn(|this, mut cx| async move {
-            rpc.log_in_and_connect(cx.clone()).await?;
+            rpc.authenticate_and_connect(cx.clone()).await?;
 
             let share_task = this.update(&mut cx, |this, cx| {
                 let worktree = this.worktrees.iter().next()?;
@@ -823,7 +823,7 @@ impl Workspace {
         let languages = self.languages.clone();
 
         let task = cx.spawn(|this, mut cx| async move {
-            rpc.log_in_and_connect(cx.clone()).await?;
+            rpc.authenticate_and_connect(cx.clone()).await?;
 
             let worktree_url = cx
                 .platform()