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,