branches: Add a modal branch list. (#2697)

Piotr Osiewicz created

Extract branch list into a separate vcs_menu crate akin to
recent_projects. Add current bind for a modal branch to branch popover's
tooltip.

Z-2555

Release Notes:
- N/A

Change summary

Cargo.lock                                   | 14 ++++++++
Cargo.toml                                   |  1 
assets/keymaps/default.json                  |  1 
assets/keymaps/textmate.json                 |  1 
crates/collab_ui/Cargo.toml                  |  1 
crates/collab_ui/src/collab_titlebar_item.rs |  9 +---
crates/collab_ui/src/collab_ui.rs            |  3 -
crates/vcs_menu/Cargo.toml                   | 16 +++++++++
crates/vcs_menu/src/lib.rs                   | 36 ++++++++++++++++++++-
9 files changed, 71 insertions(+), 11 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -1491,6 +1491,7 @@ dependencies = [
  "theme",
  "theme_selector",
  "util",
+ "vcs_menu",
  "workspace",
  "zed-actions",
 ]
@@ -8377,6 +8378,19 @@ version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
 
+[[package]]
+name = "vcs_menu"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "fuzzy",
+ "gpui",
+ "picker",
+ "theme",
+ "util",
+ "workspace",
+]
+
 [[package]]
 name = "version_check"
 version = "0.9.4"

Cargo.toml 🔗

@@ -64,6 +64,7 @@ members = [
     "crates/theme_selector",
     "crates/util",
     "crates/vim",
+    "crates/vcs_menu",
     "crates/workspace",
     "crates/welcome",
     "crates/xtask",

assets/keymaps/default.json 🔗

@@ -39,6 +39,7 @@
       "cmd-shift-n": "workspace::NewWindow",
       "cmd-o": "workspace::Open",
       "alt-cmd-o": "projects::OpenRecent",
+      "alt-cmd-b": "branches::OpenRecent",
       "ctrl-~": "workspace::NewTerminal",
       "ctrl-`": "terminal_panel::ToggleFocus",
       "shift-escape": "workspace::ToggleZoom"

assets/keymaps/textmate.json 🔗

@@ -2,6 +2,7 @@
   {
     "bindings": {
       "cmd-shift-o": "projects::OpenRecent",
+      "cmd-shift-b": "branches::OpenRecent",
       "cmd-alt-tab": "project_panel::ToggleFocus"
     }
   },

crates/collab_ui/Cargo.toml 🔗

@@ -39,6 +39,7 @@ recent_projects = {path = "../recent_projects"}
 settings = { path = "../settings" }
 theme = { path = "../theme" }
 theme_selector = { path = "../theme_selector" }
+vcs_menu = { path = "../vcs_menu" }
 util = { path = "../util" }
 workspace = { path = "../workspace" }
 zed-actions = {path = "../zed-actions"}

crates/collab_ui/src/collab_titlebar_item.rs 🔗

@@ -1,8 +1,5 @@
 use crate::{
-    branch_list::{build_branch_list, BranchList},
-    contact_notification::ContactNotification,
-    contacts_popover,
-    face_pile::FacePile,
+    contact_notification::ContactNotification, contacts_popover, face_pile::FacePile,
     toggle_deafen, toggle_mute, toggle_screen_sharing, LeaveCall, ToggleDeafen, ToggleMute,
     ToggleScreenSharing,
 };
@@ -27,6 +24,7 @@ use recent_projects::{build_recent_projects, RecentProjects};
 use std::{ops::Range, sync::Arc};
 use theme::{AvatarStyle, Theme};
 use util::ResultExt;
+use vcs_menu::{build_branch_list, BranchList, OpenRecent as ToggleVcsMenu};
 use workspace::{FollowNextCollaborator, Workspace, WORKSPACE_DB};
 
 const MAX_PROJECT_NAME_LENGTH: usize = 40;
@@ -37,7 +35,6 @@ actions!(
     [
         ToggleContactsMenu,
         ToggleUserMenu,
-        ToggleVcsMenu,
         ToggleProjectMenu,
         SwitchBranch,
         ShareProject,
@@ -286,7 +283,7 @@ impl CollabTitlebarItem {
                                             .with_tooltip::<BranchPopoverTooltip>(
                                                 0,
                                                 "Recent branches".into(),
-                                                None,
+                                                Some(Box::new(ToggleVcsMenu)),
                                                 theme.tooltip.clone(),
                                                 cx,
                                             )

crates/collab_ui/src/collab_ui.rs 🔗

@@ -1,4 +1,3 @@
-mod branch_list;
 mod collab_titlebar_item;
 mod contact_finder;
 mod contact_list;
@@ -29,7 +28,7 @@ actions!(
 );
 
 pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
-    branch_list::init(cx);
+    vcs_menu::init(cx);
     collab_titlebar_item::init(cx);
     contact_list::init(cx);
     contact_finder::init(cx);

crates/vcs_menu/Cargo.toml 🔗

@@ -0,0 +1,16 @@
+[package]
+name = "vcs_menu"
+version = "0.1.0"
+edition = "2021"
+publish = false
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+fuzzy = {path = "../fuzzy"}
+gpui = {path = "../gpui"}
+picker = {path = "../picker"}
+util = {path = "../util"}
+theme = {path = "../theme"}
+workspace = {path = "../workspace"}
+
+anyhow.workspace = true

crates/collab_ui/src/branch_list.rs → crates/vcs_menu/src/lib.rs 🔗

@@ -1,15 +1,17 @@
-use anyhow::{anyhow, bail};
+use anyhow::{anyhow, bail, Result};
 use fuzzy::{StringMatch, StringMatchCandidate};
-use gpui::{elements::*, AppContext, MouseState, Task, ViewContext, ViewHandle};
+use gpui::{actions, elements::*, AppContext, MouseState, Task, ViewContext, ViewHandle};
 use picker::{Picker, PickerDelegate, PickerEvent};
 use std::{ops::Not, sync::Arc};
 use util::ResultExt;
 use workspace::{Toast, Workspace};
 
+actions!(branches, [OpenRecent]);
+
 pub fn init(cx: &mut AppContext) {
     Picker::<BranchListDelegate>::init(cx);
+    cx.add_async_action(toggle);
 }
-
 pub type BranchList = Picker<BranchListDelegate>;
 
 pub fn build_branch_list(
@@ -28,6 +30,34 @@ pub fn build_branch_list(
     .with_theme(|theme| theme.picker.clone())
 }
 
+fn toggle(
+    _: &mut Workspace,
+    _: &OpenRecent,
+    cx: &mut ViewContext<Workspace>,
+) -> Option<Task<Result<()>>> {
+    Some(cx.spawn(|workspace, mut cx| async move {
+        workspace.update(&mut cx, |workspace, cx| {
+            workspace.toggle_modal(cx, |_, cx| {
+                let workspace = cx.handle();
+                cx.add_view(|cx| {
+                    Picker::new(
+                        BranchListDelegate {
+                            matches: vec![],
+                            workspace,
+                            selected_index: 0,
+                            last_query: String::default(),
+                        },
+                        cx,
+                    )
+                    .with_theme(|theme| theme.picker.clone())
+                    .with_max_size(800., 1200.)
+                })
+            });
+        })?;
+        Ok(())
+    }))
+}
+
 pub struct BranchListDelegate {
     matches: Vec<StringMatch>,
     workspace: ViewHandle<Workspace>,