From fdaf2a27bf3f492b76f24500d40589faa727945a Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Mon, 7 Apr 2025 18:09:38 -0300 Subject: [PATCH] agent: Adjust the thread generation design (#28193) This PR simplifies the button to send a new message as well as the "generation" display design. Release Notes: - N/A --------- Co-authored-by: Bennet Bo Fenner --- Cargo.lock | 1 - assets/icons/send.svg | 4 + assets/icons/stop_filled.svg | 3 + crates/agent/Cargo.toml | 1 - crates/agent/src/message_editor.rs | 210 +++++++++-------------------- crates/icons/src/icons.rs | 2 + 6 files changed, 76 insertions(+), 145 deletions(-) create mode 100644 assets/icons/send.svg create mode 100644 assets/icons/stop_filled.svg diff --git a/Cargo.lock b/Cargo.lock index 4e974c303f..479dfa500f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -119,7 +119,6 @@ dependencies = [ "ui_input", "util", "uuid", - "vim_mode_setting", "workspace", "workspace-hack", "zed_actions", diff --git a/assets/icons/send.svg b/assets/icons/send.svg new file mode 100644 index 0000000000..0d6ad36341 --- /dev/null +++ b/assets/icons/send.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/stop_filled.svg b/assets/icons/stop_filled.svg new file mode 100644 index 0000000000..caf40d197e --- /dev/null +++ b/assets/icons/stop_filled.svg @@ -0,0 +1,3 @@ + + + diff --git a/crates/agent/Cargo.toml b/crates/agent/Cargo.toml index 3da0f395ff..f72fc60203 100644 --- a/crates/agent/Cargo.toml +++ b/crates/agent/Cargo.toml @@ -84,7 +84,6 @@ ui.workspace = true ui_input.workspace = true util.workspace = true uuid.workspace = true -vim_mode_setting.workspace = true workspace.workspace = true zed_actions.workspace = true workspace-hack.workspace = true diff --git a/crates/agent/src/message_editor.rs b/crates/agent/src/message_editor.rs index 9f3324b3c5..6ef2cb30c5 100644 --- a/crates/agent/src/message_editor.rs +++ b/crates/agent/src/message_editor.rs @@ -8,7 +8,7 @@ use file_icons::FileIcons; use fs::Fs; use gpui::{ Animation, AnimationExt, App, DismissEvent, Entity, Focusable, Subscription, TextStyle, - WeakEntity, linear_color_stop, linear_gradient, point, + WeakEntity, linear_color_stop, linear_gradient, point, pulsating_between, }; use language::Buffer; use language_model::{ConfiguredModel, LanguageModelRegistry}; @@ -18,12 +18,8 @@ use project::Project; use settings::Settings; use std::time::Duration; use theme::ThemeSettings; -use ui::{ - ButtonLike, Disclosure, KeyBinding, PlatformStyle, PopoverMenu, PopoverMenuHandle, Tooltip, - prelude::*, -}; +use ui::{Disclosure, KeyBinding, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*}; use util::ResultExt as _; -use vim_mode_setting::VimModeSetting; use workspace::Workspace; use crate::assistant_model_selector::AssistantModelSelector; @@ -355,24 +351,6 @@ impl Render for MessageEditor { let total_token_usage = thread.total_token_usage(cx); let is_model_selected = self.is_model_selected(cx); let is_editor_empty = self.is_editor_empty(cx); - let needs_confirmation = - thread.has_pending_tool_uses() && thread.tools_needing_confirmation().next().is_some(); - - let submit_label_color = if is_editor_empty { - Color::Muted - } else { - Color::Default - }; - - let vim_mode_enabled = VimModeSetting::get_global(cx).0; - let platform = PlatformStyle::platform(); - let linux = platform == PlatformStyle::Linux; - let windows = platform == PlatformStyle::Windows; - let button_width = if linux || windows || vim_mode_enabled { - px(82.) - } else { - px(64.) - }; let action_log = self.thread.read(cx).action_log(); let changed_buffers = action_log.read(cx).changed_buffers(cx); @@ -420,70 +398,6 @@ impl Render for MessageEditor { ), ) }) - .when(is_generating, |parent| { - let focus_handle = self.editor.focus_handle(cx).clone(); - parent.child( - h_flex().py_3().w_full().justify_center().child( - h_flex() - .flex_none() - .pl_2() - .pr_1() - .py_1() - .bg(editor_bg_color) - .border_1() - .border_color(cx.theme().colors().border_variant) - .rounded_lg() - .shadow_md() - .gap_1() - .child( - Icon::new(IconName::ArrowCircle) - .size(IconSize::XSmall) - .color(Color::Muted) - .with_animation( - "arrow-circle", - Animation::new(Duration::from_secs(2)).repeat(), - |icon, delta| { - icon.transform(gpui::Transformation::rotate( - gpui::percentage(delta), - )) - }, - ), - ) - .child({ - - - Label::new(if needs_confirmation { - "Waiting for confirmation…" - } else { - "Generating…" - }) - .size(LabelSize::XSmall) - .color(Color::Muted) - }) - .child(ui::Divider::vertical()) - .child( - Button::new("cancel-generation", "Cancel") - .label_size(LabelSize::XSmall) - .key_binding( - KeyBinding::for_action_in( - &editor::actions::Cancel, - &focus_handle, - window, - cx, - ) - .map(|kb| kb.size(rems_from_px(10.))), - ) - .on_click(move |_event, window, cx| { - focus_handle.dispatch_action( - &editor::actions::Cancel, - window, - cx, - ); - }), - ), - ), - ) - }) .when(changed_buffers_count > 0, |parent| { parent.child( v_flex() @@ -734,7 +648,6 @@ impl Render for MessageEditor { ..Default::default() }, ).into_any() - }) .child( PopoverMenu::new("inline-context-picker") @@ -742,7 +655,6 @@ impl Render for MessageEditor { inline_context_picker.update(cx, |this, cx| { this.init(window, cx); }); - Some(inline_context_picker.clone()) }) .attach(gpui::Corner::TopLeft) @@ -759,60 +671,72 @@ impl Render for MessageEditor { .justify_between() .child(h_flex().gap_2().child(self.profile_selector.clone())) .child( - h_flex().gap_1().child(self.model_selector.clone()).child( - ButtonLike::new("submit-message") - .width(button_width.into()) - .style(ButtonStyle::Filled) - .disabled( - is_editor_empty - || !is_model_selected - || is_generating - || self.waiting_for_summaries_to_send - ) - .child( - h_flex() - .w_full() - .justify_between() - .child( - Label::new("Submit") - .size(LabelSize::Small) - .color(submit_label_color), - ) - .children( - KeyBinding::for_action_in( - &Chat, - &focus_handle, - window, - cx, + h_flex().gap_1().child(self.model_selector.clone()) + .map(|parent| { + if is_generating { + parent.child( + IconButton::new("stop-generation", IconName::StopFilled) + .icon_color(Color::Error) + .style(ButtonStyle::Tinted(ui::TintColor::Error)) + .tooltip(move |window, cx| { + Tooltip::for_action( + "Stop Generation", + &editor::actions::Cancel, + window, + cx, + ) + }) + .on_click(move |_event, window, cx| { + focus_handle.dispatch_action( + &editor::actions::Cancel, + window, + cx, + ); + }) + .with_animation( + "pulsating-label", + Animation::new(Duration::from_secs(2)) + .repeat() + .with_easing(pulsating_between(0.4, 1.0)), + |icon_button, delta| icon_button.alpha(delta), + ), + ) + } else { + parent.child( + IconButton::new("send-message", IconName::Send) + .icon_color(Color::Accent) + .style(ButtonStyle::Filled) + .disabled( + is_editor_empty + || !is_model_selected + || self.waiting_for_summaries_to_send ) - .map(|binding| { - binding - .when(vim_mode_enabled, |kb| { - kb.size(rems_from_px(12.)) - }) - .into_any_element() - }), - ), - ) - .on_click(move |_event, window, cx| { - focus_handle.dispatch_action(&Chat, window, cx); - }) - .when(is_editor_empty, |button| { - button.tooltip(Tooltip::text( - "Type a message to submit", - )) - }) - .when(is_generating, |button| { - button.tooltip(Tooltip::text( - "Cancel to submit a new message", - )) - }) - .when(!is_model_selected, |button| { - button.tooltip(Tooltip::text( - "Select a model to continue", - )) - }), - ), + .on_click(move |_event, window, cx| { + focus_handle.dispatch_action(&Chat, window, cx); + }) + .when(!is_editor_empty && is_model_selected, |button| { + button.tooltip(move |window, cx| { + Tooltip::for_action( + "Send", + &Chat, + window, + cx, + ) + }) + }) + .when(is_editor_empty, |button| { + button.tooltip(Tooltip::text( + "Type a message to submit", + )) + }) + .when(!is_model_selected, |button| { + button.tooltip(Tooltip::text( + "Select a model to continue", + )) + }) + ) + } + }) ), ), ) diff --git a/crates/icons/src/icons.rs b/crates/icons/src/icons.rs index 4dab811fd6..62e92f2d22 100644 --- a/crates/icons/src/icons.rs +++ b/crates/icons/src/icons.rs @@ -191,6 +191,7 @@ pub enum IconName { SearchCode, SearchSelection, SelectAll, + Send, Server, Settings, SettingsAlt, @@ -212,6 +213,7 @@ pub enum IconName { Star, StarFilled, Stop, + StopFilled, Strikethrough, Supermaven, SupermavenDisabled,