@@ -5,16 +5,16 @@ use assistant_tool::ToolWorkingSet;
use collections::HashMap;
use gpui::{
list, percentage, AbsoluteLength, Animation, AnimationExt, AnyElement, AppContext,
- DefiniteLength, EdgesRefinement, Empty, Length, ListAlignment, ListOffset, ListState, Model,
- StyleRefinement, Subscription, TextStyleRefinement, Transformation, UnderlineStyle, View,
- WeakView,
+ DefiniteLength, EdgesRefinement, Empty, FocusHandle, Length, ListAlignment, ListOffset,
+ ListState, Model, StyleRefinement, Subscription, TextStyleRefinement, Transformation,
+ UnderlineStyle, View, WeakView,
};
use language::LanguageRegistry;
use language_model::Role;
use markdown::{Markdown, MarkdownStyle};
use settings::Settings as _;
use theme::ThemeSettings;
-use ui::prelude::*;
+use ui::{prelude::*, ButtonLike, KeyBinding};
use workspace::Workspace;
use crate::thread::{MessageId, Thread, ThreadError, ThreadEvent};
@@ -29,6 +29,7 @@ pub struct ActiveThread {
list_state: ListState,
rendered_messages_by_id: HashMap<MessageId, View<Markdown>>,
last_error: Option<ThreadError>,
+ focus_handle: FocusHandle,
_subscriptions: Vec<Subscription>,
}
@@ -38,6 +39,7 @@ impl ActiveThread {
workspace: WeakView<Workspace>,
language_registry: Arc<LanguageRegistry>,
tools: Arc<ToolWorkingSet>,
+ focus_handle: FocusHandle,
cx: &mut ViewContext<Self>,
) -> Self {
let subscriptions = vec![
@@ -60,6 +62,7 @@ impl ActiveThread {
}
}),
last_error: None,
+ focus_handle,
_subscriptions: subscriptions,
};
@@ -345,6 +348,8 @@ impl Render for ActiveThread {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
let is_streaming_completion = self.thread.read(cx).is_streaming();
+ let focus_handle = self.focus_handle.clone();
+
v_flex()
.size_full()
.child(list(self.list_state.clone()).flex_grow())
@@ -363,7 +368,23 @@ impl Render for ActiveThread {
.rounded_md()
.bg(cx.theme().colors().elevated_surface_background)
.child(Label::new("Generating…").size(LabelSize::Small))
- .child(Label::new("esc to cancel").size(LabelSize::Small)),
+ .child(
+ ButtonLike::new("cancel-generation")
+ .style(ButtonStyle::Filled)
+ .child(Label::new("Cancel").size(LabelSize::Small))
+ .children(
+ KeyBinding::for_action_in(
+ &editor::actions::Cancel,
+ &self.focus_handle,
+ cx,
+ )
+ .map(|binding| binding.into_any_element()),
+ )
+ .on_click(move |_event, cx| {
+ focus_handle
+ .dispatch_action(&editor::actions::Cancel, cx);
+ }),
+ ),
)
}),
)
@@ -100,6 +100,16 @@ impl AssistantPanel {
let workspace = workspace.weak_handle();
let weak_self = cx.view().downgrade();
+ let message_editor = cx.new_view(|cx| {
+ MessageEditor::new(
+ fs.clone(),
+ workspace.clone(),
+ thread_store.downgrade(),
+ thread.clone(),
+ cx,
+ )
+ });
+
Self {
active_view: ActiveView::Thread,
workspace: workspace.clone(),
@@ -109,21 +119,14 @@ impl AssistantPanel {
thread: cx.new_view(|cx| {
ActiveThread::new(
thread.clone(),
- workspace.clone(),
+ workspace,
language_registry,
tools.clone(),
+ message_editor.focus_handle(cx),
cx,
)
}),
- message_editor: cx.new_view(|cx| {
- MessageEditor::new(
- fs.clone(),
- workspace,
- thread_store.downgrade(),
- thread.clone(),
- cx,
- )
- }),
+ message_editor,
tools,
local_timezone: UtcOffset::from_whole_seconds(
chrono::Local::now().offset().local_minus_utc(),
@@ -160,6 +163,7 @@ impl AssistantPanel {
self.workspace.clone(),
self.language_registry.clone(),
self.tools.clone(),
+ self.focus_handle(cx),
cx,
)
});
@@ -196,6 +200,7 @@ impl AssistantPanel {
self.workspace.clone(),
self.language_registry.clone(),
self.tools.clone(),
+ self.focus_handle(cx),
cx,
)
});