git_ui: Feature flag repo selector (#23470)

Nate Butler created

Fixes an issue where the repo selector showed for all users, not just
those in the git_ui feature flag.

This was meant to be included in the `git_ui` feature flag.

Release Notes:

- N/A

Change summary

Cargo.lock                        |  2 +
crates/git_ui/Cargo.toml          |  2 +
crates/git_ui/src/git_ui.rs       | 13 ++++++++++++
crates/title_bar/src/title_bar.rs | 34 ++++++++++++++++++++++++++++++--
crates/zed/src/zed.rs             | 10 --------
5 files changed, 49 insertions(+), 12 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -5242,6 +5242,7 @@ dependencies = [
  "collections",
  "db",
  "editor",
+ "feature_flags",
  "futures 0.3.31",
  "git",
  "gpui",
@@ -5253,6 +5254,7 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "settings",
+ "smol",
  "theme",
  "ui",
  "util",

crates/git_ui/Cargo.toml 🔗

@@ -32,6 +32,8 @@ ui.workspace = true
 util.workspace = true
 workspace.workspace = true
 picker.workspace = true
+feature_flags.workspace = true
+smol.workspace = true
 
 [target.'cfg(windows)'.dependencies]
 windows.workspace = true

crates/git_ui/src/git_ui.rs 🔗

@@ -1,4 +1,6 @@
 use ::settings::Settings;
+use feature_flags::WaitForFlag;
+use futures::{select_biased, FutureExt};
 use git::status::FileStatus;
 use git_panel_settings::GitPanelSettings;
 use gpui::{AppContext, Hsla};
@@ -12,6 +14,17 @@ pub fn init(cx: &mut AppContext) {
     GitPanelSettings::register(cx);
 }
 
+// TODO: Remove this before launching Git UI
+pub async fn git_ui_enabled(flag: WaitForFlag) -> bool {
+    let mut git_ui_feature_flag = flag.fuse();
+    let mut timeout = FutureExt::fuse(smol::Timer::after(std::time::Duration::from_secs(5)));
+
+    select_biased! {
+        is_git_ui_enabled = git_ui_feature_flag => is_git_ui_enabled,
+        _ = timeout => false,
+    }
+}
+
 const ADDED_COLOR: Hsla = Hsla {
     h: 142. / 360.,
     s: 0.68,

crates/title_bar/src/title_bar.rs 🔗

@@ -108,6 +108,7 @@ pub struct TitleBar {
     should_move: bool,
     application_menu: Option<View<ApplicationMenu>>,
     _subscriptions: Vec<Subscription>,
+    git_ui_enabled: bool,
 }
 
 impl Render for TitleBar {
@@ -289,7 +290,7 @@ impl TitleBar {
         subscriptions.push(cx.observe_window_activation(Self::window_activation_changed));
         subscriptions.push(cx.observe(&user_store, |_, _, cx| cx.notify()));
 
-        Self {
+        let title_bar = Self {
             platform_style,
             content: div().id(id.into()),
             children: SmallVec::new(),
@@ -301,7 +302,29 @@ impl TitleBar {
             user_store,
             client,
             _subscriptions: subscriptions,
-        }
+            git_ui_enabled: false,
+        };
+
+        title_bar.check_git_ui_enabled(cx);
+
+        title_bar
+    }
+
+    fn check_git_ui_enabled(&self, cx: &mut ViewContext<Self>) {
+        let git_ui_feature_flag = cx.wait_for_flag::<feature_flags::GitUiFeatureFlag>();
+
+        let weak_self = cx.view().downgrade();
+        cx.spawn(|_, mut cx| async move {
+            let enabled = git_ui::git_ui_enabled(git_ui_feature_flag).await;
+            if let Some(this) = weak_self.upgrade() {
+                this.update(&mut cx, |this, cx| {
+                    this.git_ui_enabled = enabled;
+                    cx.notify();
+                })
+                .ok();
+            }
+        })
+        .detach();
     }
 
     #[cfg(not(target_os = "windows"))]
@@ -484,9 +507,14 @@ impl TitleBar {
         &self,
         cx: &mut ViewContext<Self>,
     ) -> Option<impl IntoElement> {
-        // TODO what to render if no active repository?
+        if !self.git_ui_enabled {
+            return None;
+        }
+
         let active_repository = self.project.read(cx).active_repository(cx)?;
         let display_name = active_repository.display_name(self.project.read(cx), cx);
+
+        // TODO: what to render if no active repository?
         Some(RepositorySelectorPopoverMenu::new(
             self.repository_selector.clone(),
             ButtonLike::new("active-repository")

crates/zed/src/zed.rs 🔗

@@ -389,16 +389,8 @@ fn initialize_panels(prompt_builder: Arc<PromptBuilder>, cx: &mut ViewContext<Wo
             workspace.add_panel(notification_panel, cx);
         })?;
 
-        let git_ui_enabled = {
-            let mut git_ui_feature_flag = git_ui_feature_flag.fuse();
-            let mut timeout =
-                FutureExt::fuse(smol::Timer::after(std::time::Duration::from_secs(5)));
+        let git_ui_enabled = git_ui::git_ui_enabled(git_ui_feature_flag).await;
 
-            select_biased! {
-                is_git_ui_enabled = git_ui_feature_flag => is_git_ui_enabled,
-                _ = timeout => false,
-            }
-        };
         let git_panel = if git_ui_enabled {
             Some(git_ui::git_panel::GitPanel::load(workspace_handle.clone(), cx.clone()).await?)
         } else {