From 02b1e3a3c132ae2e186d5ac48bb93f8e3e9b2ca2 Mon Sep 17 00:00:00 2001
From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
Date: Tue, 5 Nov 2024 09:07:26 -0300
Subject: [PATCH] assistant: Adjust the toolbar design (#20101)
This PR's most relevant change is removing the three-dot menu dropdown
from the assistant toolbar. The "Regenerate Title" button is now only
visible on hover and it appears on the far right of the title input.
Release Notes:
- N/A
---
assets/icons/refresh_title.svg | 5 +
crates/assistant/src/assistant_panel.rs | 204 +++++++++---------------
crates/ui/src/components/icon.rs | 1 +
3 files changed, 77 insertions(+), 133 deletions(-)
create mode 100644 assets/icons/refresh_title.svg
diff --git a/assets/icons/refresh_title.svg b/assets/icons/refresh_title.svg
new file mode 100644
index 0000000000..bd3657d48c
--- /dev/null
+++ b/assets/icons/refresh_title.svg
@@ -0,0 +1,5 @@
+
diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs
index 9a16b032ce..e1b3a3d978 100644
--- a/crates/assistant/src/assistant_panel.rs
+++ b/crates/assistant/src/assistant_panel.rs
@@ -441,48 +441,49 @@ impl AssistantPanel {
.map_or(false, |item| item.downcast::().is_some()),
);
let _pane = cx.view().clone();
- let right_children = h_flex()
- .gap(Spacing::Small.rems(cx))
- .child(
- IconButton::new("new-context", IconName::Plus)
- .on_click(
- cx.listener(|_, _, cx| {
+ let right_children =
+ h_flex()
+ .gap(Spacing::XSmall.rems(cx))
+ .child(
+ IconButton::new("new-context", IconName::Plus)
+ .on_click(cx.listener(|_, _, cx| {
cx.dispatch_action(NewContext.boxed_clone())
- }),
- )
- .tooltip(move |cx| {
- Tooltip::for_action_in(
- "New Context",
- &NewContext,
- &focus_handle,
- cx,
- )
- }),
- )
- .child(
- PopoverMenu::new("assistant-panel-popover-menu")
- .trigger(
- IconButton::new("menu", IconName::Menu).icon_size(IconSize::Small),
- )
- .menu(move |cx| {
- let zoom_label = if _pane.read(cx).is_zoomed() {
- "Zoom Out"
- } else {
- "Zoom In"
- };
- let focus_handle = _pane.focus_handle(cx);
- Some(ContextMenu::build(cx, move |menu, _| {
- menu.context(focus_handle.clone())
- .action("New Context", Box::new(NewContext))
- .action("History", Box::new(DeployHistory))
- .action("Prompt Library", Box::new(DeployPromptLibrary))
- .action("Configure", Box::new(ShowConfiguration))
- .action(zoom_label, Box::new(ToggleZoom))
}))
- }),
- )
- .into_any_element()
- .into();
+ .tooltip(move |cx| {
+ Tooltip::for_action_in(
+ "New Context",
+ &NewContext,
+ &focus_handle,
+ cx,
+ )
+ }),
+ )
+ .child(
+ PopoverMenu::new("assistant-panel-popover-menu")
+ .trigger(
+ IconButton::new("menu", IconName::EllipsisVertical)
+ .icon_size(IconSize::Small)
+ .tooltip(|cx| Tooltip::text("Toggle Assistant Menu", cx)),
+ )
+ .menu(move |cx| {
+ let zoom_label = if _pane.read(cx).is_zoomed() {
+ "Zoom Out"
+ } else {
+ "Zoom In"
+ };
+ let focus_handle = _pane.focus_handle(cx);
+ Some(ContextMenu::build(cx, move |menu, _| {
+ menu.context(focus_handle.clone())
+ .action("New Context", Box::new(NewContext))
+ .action("History", Box::new(DeployHistory))
+ .action("Prompt Library", Box::new(DeployPromptLibrary))
+ .action("Configure", Box::new(ShowConfiguration))
+ .action(zoom_label, Box::new(ToggleZoom))
+ }))
+ }),
+ )
+ .into_any_element()
+ .into();
(Some(left_children.into_any_element()), right_children)
});
@@ -4367,26 +4368,11 @@ impl FollowableItem for ContextEditor {
pub struct ContextEditorToolbarItem {
fs: Arc,
- workspace: WeakView,
active_context_editor: Option>,
model_summary_editor: View,
model_selector_menu_handle: PopoverMenuHandle>,
}
-fn active_editor_focus_handle(
- workspace: &WeakView,
- cx: &WindowContext<'_>,
-) -> Option {
- workspace.upgrade().and_then(|workspace| {
- Some(
- workspace
- .read(cx)
- .active_item_as::(cx)?
- .focus_handle(cx),
- )
- })
-}
-
fn render_inject_context_menu(
active_context_editor: WeakView,
cx: &mut WindowContext<'_>,
@@ -4413,7 +4399,6 @@ impl ContextEditorToolbarItem {
) -> Self {
Self {
fs: workspace.app_state().fs.clone(),
- workspace: workspace.weak_handle(),
active_context_editor: None,
model_summary_editor,
model_selector_menu_handle,
@@ -4466,16 +4451,30 @@ impl ContextEditorToolbarItem {
impl Render for ContextEditorToolbarItem {
fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement {
let left_side = h_flex()
- .pl_1()
- .gap_2()
- .flex_1()
- .min_w(rems(DEFAULT_TAB_TITLE.len() as f32))
- .when(self.active_context_editor.is_some(), |left_side| {
- left_side.child(self.model_summary_editor.clone())
- });
+ .group("chat-title-group")
+ .pl_0p5()
+ .gap_1()
+ .items_center()
+ .flex_grow()
+ .child(
+ div()
+ .w_full()
+ .when(self.active_context_editor.is_some(), |left_side| {
+ left_side.child(self.model_summary_editor.clone())
+ }),
+ )
+ .child(
+ div().visible_on_hover("chat-title-group").child(
+ IconButton::new("regenerate-context", IconName::RefreshTitle)
+ .shape(ui::IconButtonShape::Square)
+ .tooltip(|cx| Tooltip::text("Regenerate Title", cx))
+ .on_click(cx.listener(move |_, _, cx| {
+ cx.emit(ContextEditorToolbarItemEvent::RegenerateSummary)
+ })),
+ ),
+ );
let active_provider = LanguageModelRegistry::read_global(cx).active_provider();
let active_model = LanguageModelRegistry::read_global(cx).active_model();
- let weak_self = cx.view().downgrade();
let right_side = h_flex()
.gap_2()
// TODO display this in a nicer way, once we have a design for it.
@@ -4488,7 +4487,6 @@ impl Render for ContextEditorToolbarItem {
// let scan_items_remaining = cx.update_global(|db: &mut SemanticDb, cx| {
// project.and_then(|project| db.remaining_summaries(&project, cx))
// });
-
// scan_items_remaining
// .map(|remaining_items| format!("Files to scan: {}", remaining_items))
// })
@@ -4510,9 +4508,13 @@ impl Render for ContextEditorToolbarItem {
(Some(provider), Some(model)) => h_flex()
.gap_1()
.child(
- Icon::new(model.icon().unwrap_or_else(|| provider.icon()))
- .color(Color::Muted)
- .size(IconSize::XSmall),
+ Icon::new(
+ model
+ .icon()
+ .unwrap_or_else(|| provider.icon()),
+ )
+ .color(Color::Muted)
+ .size(IconSize::XSmall),
)
.child(
Label::new(model.name().0)
@@ -4538,71 +4540,7 @@ impl Render for ContextEditorToolbarItem {
)
.with_handle(self.model_selector_menu_handle.clone()),
)
- .children(self.render_remaining_tokens(cx))
- .child(
- PopoverMenu::new("context-editor-popover")
- .trigger(
- IconButton::new("context-editor-trigger", IconName::EllipsisVertical)
- .icon_size(IconSize::Small)
- .tooltip(|cx| Tooltip::text("Open Context Options", cx)),
- )
- .menu({
- let weak_self = weak_self.clone();
- move |cx| {
- let weak_self = weak_self.clone();
- Some(ContextMenu::build(cx, move |menu, cx| {
- let context = weak_self
- .update(cx, |this, cx| {
- active_editor_focus_handle(&this.workspace, cx)
- })
- .ok()
- .flatten();
- menu.when_some(context, |menu, context| menu.context(context))
- .entry("Regenerate Context Title", None, {
- let weak_self = weak_self.clone();
- move |cx| {
- weak_self
- .update(cx, |_, cx| {
- cx.emit(ContextEditorToolbarItemEvent::RegenerateSummary)
- })
- .ok();
- }
- })
- .custom_entry(
- |_| {
- h_flex()
- .w_full()
- .justify_between()
- .gap_2()
- .child(Label::new("Add Context"))
- .child(Label::new("/ command").color(Color::Muted))
- .into_any()
- },
- {
- let weak_self = weak_self.clone();
- move |cx| {
- weak_self
- .update(cx, |this, cx| {
- if let Some(editor) =
- &this.active_context_editor
- {
- editor
- .update(cx, |this, cx| {
- this.slash_menu_handle
- .toggle(cx);
- })
- .ok();
- }
- })
- .ok();
- }
- },
- )
- .action("Add Selection", QuoteSelection.boxed_clone())
- }))
- }
- }),
- );
+ .children(self.render_remaining_tokens(cx));
h_flex()
.size_full()
diff --git a/crates/ui/src/components/icon.rs b/crates/ui/src/components/icon.rs
index e11b6edf32..3aa3dc7615 100644
--- a/crates/ui/src/components/icon.rs
+++ b/crates/ui/src/components/icon.rs
@@ -234,6 +234,7 @@ pub enum IconName {
Public,
PullRequest,
Quote,
+ RefreshTitle,
Regex,
ReplNeutral,
Replace,