From 52da375a9d35ed61e952353481954884cf0be921 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Sun, 4 May 2025 20:21:30 -0300 Subject: [PATCH] agent: Add design adjustments to message editor (#29891) - Removed unused `MessageBubbleDashed` icon - Polished `Crosshair` icon SVG - Added dropdown toggle keybinding to the profile selector tooltip - Repositioned buttons at the message editor footer - Updated buttons to use `Button` instead of `ButtonLike` Release Notes: - N/A --- assets/icons/crosshair.svg | 8 ++- assets/icons/message_bubble_dashed.svg | 1 - crates/agent/src/assistant_model_selector.rs | 26 +++----- crates/agent/src/message_editor.rs | 8 ++- crates/agent/src/profile_selector.rs | 69 ++++++++++---------- crates/icons/src/icons.rs | 1 - 6 files changed, 56 insertions(+), 57 deletions(-) delete mode 100644 assets/icons/message_bubble_dashed.svg diff --git a/assets/icons/crosshair.svg b/assets/icons/crosshair.svg index cd8c40ed03..006c6362aa 100644 --- a/assets/icons/crosshair.svg +++ b/assets/icons/crosshair.svg @@ -1 +1,7 @@ - + + + + + + + diff --git a/assets/icons/message_bubble_dashed.svg b/assets/icons/message_bubble_dashed.svg deleted file mode 100644 index 02d44c7362..0000000000 --- a/assets/icons/message_bubble_dashed.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crates/agent/src/assistant_model_selector.rs b/crates/agent/src/assistant_model_selector.rs index 47bb62be9c..67c701bb0d 100644 --- a/crates/agent/src/assistant_model_selector.rs +++ b/crates/agent/src/assistant_model_selector.rs @@ -9,7 +9,7 @@ use language_model_selector::{ }; use settings::update_settings_file; use std::sync::Arc; -use ui::{ButtonLike, PopoverMenuHandle, Tooltip, prelude::*}; +use ui::{PopoverMenuHandle, Tooltip, prelude::*}; #[derive(Clone)] pub enum ModelType { @@ -110,23 +110,13 @@ impl Render for AssistantModelSelector { LanguageModelSelectorPopoverMenu::new( self.selector.clone(), - ButtonLike::new("active-model") - .style(ButtonStyle::Subtle) - .child( - h_flex() - .gap_0p5() - .child( - Label::new(model_name) - .size(LabelSize::Small) - .color(Color::Muted) - .ml_1(), - ) - .child( - Icon::new(IconName::ChevronDown) - .color(Color::Muted) - .size(IconSize::XSmall), - ), - ), + Button::new("active-model", model_name) + .label_size(LabelSize::Small) + .color(Color::Muted) + .icon(IconName::ChevronDown) + .icon_size(IconSize::XSmall) + .icon_position(IconPosition::End) + .icon_color(Color::Muted), move |window, cx| { Tooltip::for_action_in( "Change Model", diff --git a/crates/agent/src/message_editor.rs b/crates/agent/src/message_editor.rs index 2ac2d9f92d..2f173e3cce 100644 --- a/crates/agent/src/message_editor.rs +++ b/crates/agent/src/message_editor.rs @@ -200,7 +200,8 @@ impl MessageEditor { model_selector, edits_expanded: false, editor_is_expanded: false, - profile_selector: cx.new(|cx| ProfileSelector::new(fs, thread_store, cx)), + profile_selector: cx + .new(|cx| ProfileSelector::new(fs, thread_store, editor.focus_handle(cx), cx)), last_estimated_token_count: None, update_token_count_task: None, _subscriptions: subscriptions, @@ -463,6 +464,7 @@ impl MessageEditor { workspace.is_being_followed(CollaboratorId::Agent) }) .unwrap_or(false); + IconButton::new("follow-agent", IconName::Crosshair) .icon_size(IconSize::Small) .icon_color(Color::Muted) @@ -638,7 +640,7 @@ impl MessageEditor { h_flex() .gap_1() .child(self.render_follow_toggle(cx)) - .child(self.profile_selector.clone()), + .children(self.render_max_mode_toggle(cx)), ) .child( h_flex() @@ -662,7 +664,7 @@ impl MessageEditor { }), ) }) - .children(self.render_max_mode_toggle(cx)) + .child(self.profile_selector.clone()) .child(self.model_selector.clone()) .map({ let focus_handle = focus_handle.clone(); diff --git a/crates/agent/src/profile_selector.rs b/crates/agent/src/profile_selector.rs index db08e93577..38ec7ff0c8 100644 --- a/crates/agent/src/profile_selector.rs +++ b/crates/agent/src/profile_selector.rs @@ -4,21 +4,20 @@ use assistant_settings::{ AgentProfile, AgentProfileId, AssistantSettings, GroupedAgentProfiles, builtin_profiles, }; use fs::Fs; -use gpui::{Action, Entity, Subscription, WeakEntity, prelude::*}; +use gpui::{Action, Entity, FocusHandle, Subscription, WeakEntity, prelude::*}; use language_model::LanguageModelRegistry; use settings::{Settings as _, SettingsStore, update_settings_file}; -use ui::{ - ButtonLike, ContextMenu, ContextMenuEntry, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*, -}; +use ui::{ContextMenu, ContextMenuEntry, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*}; use util::ResultExt as _; -use crate::{ManageProfiles, ThreadStore}; +use crate::{ManageProfiles, ThreadStore, ToggleProfileSelector}; pub struct ProfileSelector { profiles: GroupedAgentProfiles, fs: Arc, thread_store: WeakEntity, menu_handle: PopoverMenuHandle, + focus_handle: FocusHandle, _subscriptions: Vec, } @@ -26,6 +25,7 @@ impl ProfileSelector { pub fn new( fs: Arc, thread_store: WeakEntity, + focus_handle: FocusHandle, cx: &mut Context, ) -> Self { let settings_subscription = cx.observe_global::(move |this, cx| { @@ -37,6 +37,7 @@ impl ProfileSelector { fs, thread_store, menu_handle: PopoverMenuHandle::default(), + focus_handle, _subscriptions: vec![settings_subscription], } } @@ -143,39 +144,41 @@ impl Render for ProfileSelector { .map_or(false, |default| default.model.supports_tools()); let this = cx.entity().clone(); + let focus_handle = self.focus_handle.clone(); + + let trigger_button = if supports_tools { + Button::new("profile-selector-model", selected_profile) + .label_size(LabelSize::Small) + .color(Color::Muted) + .icon(IconName::ChevronDown) + .icon_size(IconSize::XSmall) + .icon_position(IconPosition::End) + .icon_color(Color::Muted) + } else { + Button::new("tools-not-supported-button", "No Tools") + .disabled(true) + .label_size(LabelSize::Small) + .color(Color::Muted) + .tooltip(Tooltip::text("The current model does not support tools.")) + }; PopoverMenu::new("profile-selector") - .menu(move |window, cx| { - Some(this.update(cx, |this, cx| this.build_context_menu(window, cx))) - }) - .trigger(if supports_tools { - ButtonLike::new("profile-selector-button").child( - h_flex() - .gap_1() - .child( - Label::new(selected_profile) - .size(LabelSize::Small) - .color(Color::Muted), - ) - .child( - Icon::new(IconName::ChevronDown) - .size(IconSize::XSmall) - .color(Color::Muted), - ), - ) - } else { - ButtonLike::new("tools-not-supported-button") - .disabled(true) - .child( - h_flex().gap_1().child( - Label::new("No Tools") - .size(LabelSize::Small) - .color(Color::Muted), - ), + .trigger_with_tooltip(trigger_button, { + let focus_handle = focus_handle.clone(); + move |window, cx| { + Tooltip::for_action_in( + "Toggle Profile Menu", + &ToggleProfileSelector, + &focus_handle, + window, + cx, ) - .tooltip(Tooltip::text("The current model does not support tools.")) + } }) .anchor(gpui::Corner::BottomRight) .with_handle(self.menu_handle.clone()) + .menu(move |window, cx| { + Some(this.update(cx, |this, cx| this.build_context_menu(window, cx))) + }) } } diff --git a/crates/icons/src/icons.rs b/crates/icons/src/icons.rs index 79d5637ea2..bdb371b0b2 100644 --- a/crates/icons/src/icons.rs +++ b/crates/icons/src/icons.rs @@ -160,7 +160,6 @@ pub enum IconName { Maximize, Menu, MenuAlt, - MessageBubbleDashed, MessageBubbles, Mic, MicMute,