git: Make repo selector wider (#26149)

Conrad Irwin created

…m_item()

Closes #ISSUE

Release Notes:

- git: Fixed repository selector being too narrow

Change summary

crates/git_ui/src/repository_selector.rs | 25 +++++++++++++++++++------
crates/picker/src/picker.rs              | 10 ++++++++++
2 files changed, 29 insertions(+), 6 deletions(-)

Detailed changes

crates/git_ui/src/repository_selector.rs 🔗

@@ -2,6 +2,7 @@ use gpui::{
     AnyElement, App, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, Subscription,
     Task, WeakEntity,
 };
+use itertools::Itertools;
 use picker::{Picker, PickerDelegate};
 use project::{
     git::{GitStore, Repository},
@@ -19,22 +20,35 @@ pub struct RepositorySelector {
 }
 
 impl RepositorySelector {
-    pub fn new(project: Entity<Project>, window: &mut Window, cx: &mut Context<Self>) -> Self {
-        let git_store = project.read(cx).git_store().clone();
+    pub fn new(
+        project_handle: Entity<Project>,
+        window: &mut Window,
+        cx: &mut Context<Self>,
+    ) -> Self {
+        let project = project_handle.read(cx);
+        let git_store = project.git_store().clone();
         let all_repositories = git_store.read(cx).all_repositories();
         let filtered_repositories = all_repositories.clone();
+
+        let widest_item_ix = all_repositories.iter().position_max_by(|a, b| {
+            a.read(cx)
+                .display_name(project, cx)
+                .len()
+                .cmp(&b.read(cx).display_name(project, cx).len())
+        });
+
         let delegate = RepositorySelectorDelegate {
-            project: project.downgrade(),
+            project: project_handle.downgrade(),
             repository_selector: cx.entity().downgrade(),
-            repository_entries: all_repositories,
+            repository_entries: all_repositories.clone(),
             filtered_repositories,
             selected_index: 0,
         };
 
         let picker = cx.new(|cx| {
             Picker::nonsearchable_uniform_list(delegate, window, cx)
+                .widest_item(widest_item_ix)
                 .max_height(Some(rems(20.).into()))
-                .width(rems(15.))
         });
 
         let _subscriptions =
@@ -186,7 +200,6 @@ impl PickerDelegate for RepositorySelectorDelegate {
         let project = self.project.upgrade()?;
         let repo_info = self.filtered_repositories.get(ix)?;
         let display_name = repo_info.read(cx).display_name(project.read(cx), cx);
-        // TODO: Implement repository item rendering
         Some(
             ListItem::new(ix)
                 .inset(true)

crates/picker/src/picker.rs 🔗

@@ -48,6 +48,7 @@ pub struct Picker<D: PickerDelegate> {
     pending_update_matches: Option<PendingUpdateMatches>,
     confirm_on_update: Option<bool>,
     width: Option<Length>,
+    widest_item: Option<usize>,
     max_height: Option<Length>,
     focus_handle: FocusHandle,
     /// An external control to display a scrollbar in the `Picker`.
@@ -283,6 +284,7 @@ impl<D: PickerDelegate> Picker<D> {
             pending_update_matches: None,
             confirm_on_update: None,
             width: None,
+            widest_item: None,
             max_height: Some(rems(18.).into()),
             focus_handle,
             show_scrollbar: false,
@@ -332,6 +334,11 @@ impl<D: PickerDelegate> Picker<D> {
         self
     }
 
+    pub fn widest_item(mut self, ix: Option<usize>) -> Self {
+        self.widest_item = ix;
+        self
+    }
+
     pub fn max_height(mut self, max_height: Option<gpui::Length>) -> Self {
         self.max_height = max_height;
         self
@@ -690,6 +697,9 @@ impl<D: PickerDelegate> Picker<D> {
                 },
             )
             .with_sizing_behavior(sizing_behavior)
+            .when_some(self.widest_item, |el, widest_item| {
+                el.with_width_from_item(Some(widest_item))
+            })
             .flex_grow()
             .py_1()
             .track_scroll(scroll_handle.clone())