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
This commit is contained in:
Danilo Leal 2025-05-04 20:21:30 -03:00 committed by GitHub
parent 3594a52bee
commit 52da375a9d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 56 additions and 57 deletions

View file

@ -1 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-crosshair-icon lucide-crosshair"><circle cx="12" cy="12" r="10"/><line x1="22" x2="18" y1="12" y2="12"/><line x1="6" x2="2" y1="12" y2="12"/><line x1="12" x2="12" y1="6" y2="2"/><line x1="12" x2="12" y1="22" y2="18"/></svg> <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 12C9.76142 12 12 9.76142 12 7C12 4.23858 9.76142 2 7 2C4.23858 2 2 4.23858 2 7C2 9.76142 4.23858 12 7 12Z" stroke="black" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.5 7H9" stroke="black" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.5 7H2" stroke="black" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 4.5V2" stroke="black" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 11.5V9" stroke="black" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 426 B

After

Width:  |  Height:  |  Size: 720 B

Before After
Before After

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-circle-dashed-icon lucide-message-circle-dashed"><path d="M13.5 3.1c-.5 0-1-.1-1.5-.1s-1 .1-1.5.1"/><path d="M19.3 6.8a10.45 10.45 0 0 0-2.1-2.1"/><path d="M20.9 13.5c.1-.5.1-1 .1-1.5s-.1-1-.1-1.5"/><path d="M17.2 19.3a10.45 10.45 0 0 0 2.1-2.1"/><path d="M10.5 20.9c.5.1 1 .1 1.5.1s1-.1 1.5-.1"/><path d="M3.5 17.5 2 22l4.5-1.5"/><path d="M3.1 10.5c0 .5-.1 1-.1 1.5s.1 1 .1 1.5"/><path d="M6.8 4.7a10.45 10.45 0 0 0-2.1 2.1"/></svg>

Before

Width:  |  Height:  |  Size: 644 B

View file

@ -9,7 +9,7 @@ use language_model_selector::{
}; };
use settings::update_settings_file; use settings::update_settings_file;
use std::sync::Arc; use std::sync::Arc;
use ui::{ButtonLike, PopoverMenuHandle, Tooltip, prelude::*}; use ui::{PopoverMenuHandle, Tooltip, prelude::*};
#[derive(Clone)] #[derive(Clone)]
pub enum ModelType { pub enum ModelType {
@ -110,23 +110,13 @@ impl Render for AssistantModelSelector {
LanguageModelSelectorPopoverMenu::new( LanguageModelSelectorPopoverMenu::new(
self.selector.clone(), self.selector.clone(),
ButtonLike::new("active-model") Button::new("active-model", model_name)
.style(ButtonStyle::Subtle) .label_size(LabelSize::Small)
.child( .color(Color::Muted)
h_flex() .icon(IconName::ChevronDown)
.gap_0p5() .icon_size(IconSize::XSmall)
.child( .icon_position(IconPosition::End)
Label::new(model_name) .icon_color(Color::Muted),
.size(LabelSize::Small)
.color(Color::Muted)
.ml_1(),
)
.child(
Icon::new(IconName::ChevronDown)
.color(Color::Muted)
.size(IconSize::XSmall),
),
),
move |window, cx| { move |window, cx| {
Tooltip::for_action_in( Tooltip::for_action_in(
"Change Model", "Change Model",

View file

@ -200,7 +200,8 @@ impl MessageEditor {
model_selector, model_selector,
edits_expanded: false, edits_expanded: false,
editor_is_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, last_estimated_token_count: None,
update_token_count_task: None, update_token_count_task: None,
_subscriptions: subscriptions, _subscriptions: subscriptions,
@ -463,6 +464,7 @@ impl MessageEditor {
workspace.is_being_followed(CollaboratorId::Agent) workspace.is_being_followed(CollaboratorId::Agent)
}) })
.unwrap_or(false); .unwrap_or(false);
IconButton::new("follow-agent", IconName::Crosshair) IconButton::new("follow-agent", IconName::Crosshair)
.icon_size(IconSize::Small) .icon_size(IconSize::Small)
.icon_color(Color::Muted) .icon_color(Color::Muted)
@ -638,7 +640,7 @@ impl MessageEditor {
h_flex() h_flex()
.gap_1() .gap_1()
.child(self.render_follow_toggle(cx)) .child(self.render_follow_toggle(cx))
.child(self.profile_selector.clone()), .children(self.render_max_mode_toggle(cx)),
) )
.child( .child(
h_flex() 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()) .child(self.model_selector.clone())
.map({ .map({
let focus_handle = focus_handle.clone(); let focus_handle = focus_handle.clone();

View file

@ -4,21 +4,20 @@ use assistant_settings::{
AgentProfile, AgentProfileId, AssistantSettings, GroupedAgentProfiles, builtin_profiles, AgentProfile, AgentProfileId, AssistantSettings, GroupedAgentProfiles, builtin_profiles,
}; };
use fs::Fs; use fs::Fs;
use gpui::{Action, Entity, Subscription, WeakEntity, prelude::*}; use gpui::{Action, Entity, FocusHandle, Subscription, WeakEntity, prelude::*};
use language_model::LanguageModelRegistry; use language_model::LanguageModelRegistry;
use settings::{Settings as _, SettingsStore, update_settings_file}; use settings::{Settings as _, SettingsStore, update_settings_file};
use ui::{ use ui::{ContextMenu, ContextMenuEntry, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*};
ButtonLike, ContextMenu, ContextMenuEntry, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*,
};
use util::ResultExt as _; use util::ResultExt as _;
use crate::{ManageProfiles, ThreadStore}; use crate::{ManageProfiles, ThreadStore, ToggleProfileSelector};
pub struct ProfileSelector { pub struct ProfileSelector {
profiles: GroupedAgentProfiles, profiles: GroupedAgentProfiles,
fs: Arc<dyn Fs>, fs: Arc<dyn Fs>,
thread_store: WeakEntity<ThreadStore>, thread_store: WeakEntity<ThreadStore>,
menu_handle: PopoverMenuHandle<ContextMenu>, menu_handle: PopoverMenuHandle<ContextMenu>,
focus_handle: FocusHandle,
_subscriptions: Vec<Subscription>, _subscriptions: Vec<Subscription>,
} }
@ -26,6 +25,7 @@ impl ProfileSelector {
pub fn new( pub fn new(
fs: Arc<dyn Fs>, fs: Arc<dyn Fs>,
thread_store: WeakEntity<ThreadStore>, thread_store: WeakEntity<ThreadStore>,
focus_handle: FocusHandle,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> Self { ) -> Self {
let settings_subscription = cx.observe_global::<SettingsStore>(move |this, cx| { let settings_subscription = cx.observe_global::<SettingsStore>(move |this, cx| {
@ -37,6 +37,7 @@ impl ProfileSelector {
fs, fs,
thread_store, thread_store,
menu_handle: PopoverMenuHandle::default(), menu_handle: PopoverMenuHandle::default(),
focus_handle,
_subscriptions: vec![settings_subscription], _subscriptions: vec![settings_subscription],
} }
} }
@ -143,39 +144,41 @@ impl Render for ProfileSelector {
.map_or(false, |default| default.model.supports_tools()); .map_or(false, |default| default.model.supports_tools());
let this = cx.entity().clone(); 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") PopoverMenu::new("profile-selector")
.menu(move |window, cx| { .trigger_with_tooltip(trigger_button, {
Some(this.update(cx, |this, cx| this.build_context_menu(window, cx))) let focus_handle = focus_handle.clone();
}) move |window, cx| {
.trigger(if supports_tools { Tooltip::for_action_in(
ButtonLike::new("profile-selector-button").child( "Toggle Profile Menu",
h_flex() &ToggleProfileSelector,
.gap_1() &focus_handle,
.child( window,
Label::new(selected_profile) cx,
.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),
),
) )
.tooltip(Tooltip::text("The current model does not support tools.")) }
}) })
.anchor(gpui::Corner::BottomRight) .anchor(gpui::Corner::BottomRight)
.with_handle(self.menu_handle.clone()) .with_handle(self.menu_handle.clone())
.menu(move |window, cx| {
Some(this.update(cx, |this, cx| this.build_context_menu(window, cx)))
})
} }
} }

View file

@ -160,7 +160,6 @@ pub enum IconName {
Maximize, Maximize,
Menu, Menu,
MenuAlt, MenuAlt,
MessageBubbleDashed,
MessageBubbles, MessageBubbles,
Mic, Mic,
MicMute, MicMute,