thread view: Add ability to expand message editor and fix scroll (#34766)
Release Notes: - N/A
This commit is contained in:
parent
88af35fe47
commit
56fd950d94
3 changed files with 135 additions and 51 deletions
|
@ -45,7 +45,8 @@ use ::acp_thread::{
|
|||
use crate::acp::completion_provider::{ContextPickerCompletionProvider, MentionSet};
|
||||
use crate::acp::message_history::MessageHistory;
|
||||
use crate::agent_diff::AgentDiff;
|
||||
use crate::{AgentDiffPane, Follow, KeepAll, OpenAgentDiff, RejectAll};
|
||||
use crate::message_editor::{MAX_EDITOR_LINES, MIN_EDITOR_LINES};
|
||||
use crate::{AgentDiffPane, ExpandMessageEditor, Follow, KeepAll, OpenAgentDiff, RejectAll};
|
||||
|
||||
const RESPONSE_PADDING_X: Pixels = px(19.);
|
||||
|
||||
|
@ -65,6 +66,7 @@ pub struct AcpThreadView {
|
|||
expanded_tool_calls: HashSet<ToolCallId>,
|
||||
expanded_thinking_blocks: HashSet<(usize, usize)>,
|
||||
edits_expanded: bool,
|
||||
editor_is_expanded: bool,
|
||||
message_history: Rc<RefCell<MessageHistory<acp::SendUserMessageParams>>>,
|
||||
}
|
||||
|
||||
|
@ -94,6 +96,8 @@ impl AcpThreadView {
|
|||
workspace: WeakEntity<Workspace>,
|
||||
project: Entity<Project>,
|
||||
message_history: Rc<RefCell<MessageHistory<acp::SendUserMessageParams>>>,
|
||||
min_lines: usize,
|
||||
max_lines: Option<usize>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
|
@ -113,8 +117,8 @@ impl AcpThreadView {
|
|||
|
||||
let mut editor = Editor::new(
|
||||
editor::EditorMode::AutoHeight {
|
||||
min_lines: 4,
|
||||
max_lines: None,
|
||||
min_lines,
|
||||
max_lines: max_lines,
|
||||
},
|
||||
buffer,
|
||||
None,
|
||||
|
@ -182,6 +186,7 @@ impl AcpThreadView {
|
|||
expanded_tool_calls: HashSet::default(),
|
||||
expanded_thinking_blocks: HashSet::default(),
|
||||
edits_expanded: false,
|
||||
editor_is_expanded: false,
|
||||
message_history,
|
||||
}
|
||||
}
|
||||
|
@ -321,6 +326,35 @@ impl AcpThreadView {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn expand_message_editor(
|
||||
&mut self,
|
||||
_: &ExpandMessageEditor,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.set_editor_is_expanded(!self.editor_is_expanded, cx);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn set_editor_is_expanded(&mut self, is_expanded: bool, cx: &mut Context<Self>) {
|
||||
self.editor_is_expanded = is_expanded;
|
||||
self.message_editor.update(cx, |editor, _| {
|
||||
if self.editor_is_expanded {
|
||||
editor.set_mode(EditorMode::Full {
|
||||
scale_ui_elements_with_buffer_font_size: false,
|
||||
show_active_line_background: false,
|
||||
sized_by_content: false,
|
||||
})
|
||||
} else {
|
||||
editor.set_mode(EditorMode::AutoHeight {
|
||||
min_lines: MIN_EDITOR_LINES,
|
||||
max_lines: Some(MAX_EDITOR_LINES),
|
||||
})
|
||||
}
|
||||
});
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn chat(&mut self, _: &Chat, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.last_error.take();
|
||||
|
||||
|
@ -381,6 +415,7 @@ impl AcpThreadView {
|
|||
|
||||
let mention_set = self.mention_set.clone();
|
||||
|
||||
self.set_editor_is_expanded(false, cx);
|
||||
self.message_editor.update(cx, |editor, cx| {
|
||||
editor.clear(window, cx);
|
||||
editor.remove_creases(mention_set.lock().drain(), cx)
|
||||
|
@ -1793,34 +1828,96 @@ impl AcpThreadView {
|
|||
))
|
||||
}
|
||||
|
||||
fn render_message_editor(&mut self, cx: &mut Context<Self>) -> AnyElement {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let font_size = TextSize::Small
|
||||
.rems(cx)
|
||||
.to_pixels(settings.agent_font_size(cx));
|
||||
let line_height = settings.buffer_line_height.value() * font_size;
|
||||
|
||||
let text_style = TextStyle {
|
||||
color: cx.theme().colors().text,
|
||||
font_family: settings.buffer_font.family.clone(),
|
||||
font_fallbacks: settings.buffer_font.fallbacks.clone(),
|
||||
font_features: settings.buffer_font.features.clone(),
|
||||
font_size: font_size.into(),
|
||||
line_height: line_height.into(),
|
||||
..Default::default()
|
||||
fn render_message_editor(&mut self, window: &mut Window, cx: &mut Context<Self>) -> AnyElement {
|
||||
let focus_handle = self.message_editor.focus_handle(cx);
|
||||
let editor_bg_color = cx.theme().colors().editor_background;
|
||||
let (expand_icon, expand_tooltip) = if self.editor_is_expanded {
|
||||
(IconName::Minimize, "Minimize Message Editor")
|
||||
} else {
|
||||
(IconName::Maximize, "Expand Message Editor")
|
||||
};
|
||||
|
||||
EditorElement::new(
|
||||
&self.message_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().colors().editor_background,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.into_any()
|
||||
v_flex()
|
||||
.on_action(cx.listener(Self::expand_message_editor))
|
||||
.p_2()
|
||||
.gap_2()
|
||||
.border_t_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.bg(editor_bg_color)
|
||||
.when(self.editor_is_expanded, |this| {
|
||||
this.h(vh(0.8, window)).size_full().justify_between()
|
||||
})
|
||||
.child(
|
||||
v_flex()
|
||||
.relative()
|
||||
.size_full()
|
||||
.pt_1()
|
||||
.pr_2p5()
|
||||
.child(div().flex_1().child({
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let font_size = TextSize::Small
|
||||
.rems(cx)
|
||||
.to_pixels(settings.agent_font_size(cx));
|
||||
let line_height = settings.buffer_line_height.value() * font_size;
|
||||
|
||||
let text_style = TextStyle {
|
||||
color: cx.theme().colors().text,
|
||||
font_family: settings.buffer_font.family.clone(),
|
||||
font_fallbacks: settings.buffer_font.fallbacks.clone(),
|
||||
font_features: settings.buffer_font.features.clone(),
|
||||
font_size: font_size.into(),
|
||||
line_height: line_height.into(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
EditorElement::new(
|
||||
&self.message_editor,
|
||||
EditorStyle {
|
||||
background: editor_bg_color,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}))
|
||||
.child(
|
||||
h_flex()
|
||||
.absolute()
|
||||
.top_0()
|
||||
.right_0()
|
||||
.opacity(0.5)
|
||||
.hover(|this| this.opacity(1.0))
|
||||
.child(
|
||||
IconButton::new("toggle-height", expand_icon)
|
||||
.icon_size(IconSize::XSmall)
|
||||
.icon_color(Color::Muted)
|
||||
.tooltip({
|
||||
let focus_handle = focus_handle.clone();
|
||||
move |window, cx| {
|
||||
Tooltip::for_action_in(
|
||||
expand_tooltip,
|
||||
&ExpandMessageEditor,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
})
|
||||
.on_click(cx.listener(|_, _, window, cx| {
|
||||
window.dispatch_action(Box::new(ExpandMessageEditor), cx);
|
||||
})),
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.flex_none()
|
||||
.justify_between()
|
||||
.child(self.render_follow_toggle(cx))
|
||||
.child(self.render_send_button(cx)),
|
||||
)
|
||||
.into_any()
|
||||
}
|
||||
|
||||
fn render_send_button(&self, cx: &mut Context<Self>) -> AnyElement {
|
||||
|
@ -2132,7 +2229,6 @@ impl Render for AcpThreadView {
|
|||
.px(RESPONSE_PADDING_X)
|
||||
.opacity(0.4)
|
||||
.hover(|style| style.opacity(1.))
|
||||
.gap_1()
|
||||
.flex_wrap()
|
||||
.justify_end()
|
||||
.child(open_as_markdown)
|
||||
|
@ -2166,22 +2262,7 @@ impl Render for AcpThreadView {
|
|||
),
|
||||
)
|
||||
})
|
||||
.child(
|
||||
v_flex()
|
||||
.p_2()
|
||||
.pt_3()
|
||||
.gap_1()
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.border_t_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.child(self.render_message_editor(cx))
|
||||
.child(
|
||||
h_flex()
|
||||
.justify_between()
|
||||
.child(self.render_follow_toggle(cx))
|
||||
.child(self.render_send_button(cx)),
|
||||
),
|
||||
)
|
||||
.child(self.render_message_editor(window, cx))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::NewExternalAgentThread;
|
||||
use crate::agent_diff::AgentDiffThread;
|
||||
use crate::message_editor::{MAX_EDITOR_LINES, MIN_EDITOR_LINES};
|
||||
use crate::{
|
||||
AddContextServer, AgentDiffPane, ContinueThread, ContinueWithBurnMode,
|
||||
DeleteRecentlyOpenThread, ExpandMessageEditor, Follow, InlineAssistant, NewTextThread,
|
||||
|
@ -960,6 +961,8 @@ impl AgentPanel {
|
|||
workspace.clone(),
|
||||
project,
|
||||
message_history,
|
||||
MIN_EDITOR_LINES,
|
||||
Some(MAX_EDITOR_LINES),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
|
|
|
@ -65,6 +65,9 @@ use agent::{
|
|||
thread_store::{TextThreadStore, ThreadStore},
|
||||
};
|
||||
|
||||
pub const MIN_EDITOR_LINES: usize = 4;
|
||||
pub const MAX_EDITOR_LINES: usize = 8;
|
||||
|
||||
#[derive(RegisterComponent)]
|
||||
pub struct MessageEditor {
|
||||
thread: Entity<Thread>,
|
||||
|
@ -88,9 +91,6 @@ pub struct MessageEditor {
|
|||
_subscriptions: Vec<Subscription>,
|
||||
}
|
||||
|
||||
const MIN_EDITOR_LINES: usize = 4;
|
||||
const MAX_EDITOR_LINES: usize = 8;
|
||||
|
||||
pub(crate) fn create_editor(
|
||||
workspace: WeakEntity<Workspace>,
|
||||
context_store: WeakEntity<ContextStore>,
|
||||
|
@ -711,11 +711,11 @@ impl MessageEditor {
|
|||
cx.listener(|this, _: &RejectAll, window, cx| this.handle_reject_all(window, cx)),
|
||||
)
|
||||
.capture_action(cx.listener(Self::paste))
|
||||
.gap_2()
|
||||
.p_2()
|
||||
.bg(editor_bg_color)
|
||||
.gap_2()
|
||||
.border_t_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.bg(editor_bg_color)
|
||||
.child(
|
||||
h_flex()
|
||||
.justify_between()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue