Thread view scrollbar (#35655)
This also adds a convenient `Scrollbar:auto_hide` function so that we don't have to handle that at the callsite. Release Notes: - N/A --------- Co-authored-by: David Kleingeld <davidsk@zed.dev>
This commit is contained in:
parent
3c602fecbf
commit
33f198fef1
5 changed files with 238 additions and 233 deletions
|
@ -21,10 +21,10 @@ use editor::{
|
|||
use file_icons::FileIcons;
|
||||
use gpui::{
|
||||
Action, Animation, AnimationExt, App, BorderStyle, EdgesRefinement, Empty, Entity, EntityId,
|
||||
FocusHandle, Focusable, Hsla, Length, ListOffset, ListState, PlatformDisplay, SharedString,
|
||||
StyleRefinement, Subscription, Task, TextStyle, TextStyleRefinement, Transformation,
|
||||
UnderlineStyle, WeakEntity, Window, WindowHandle, div, linear_color_stop, linear_gradient,
|
||||
list, percentage, point, prelude::*, pulsating_between,
|
||||
FocusHandle, Focusable, Hsla, Length, ListOffset, ListState, MouseButton, PlatformDisplay,
|
||||
SharedString, Stateful, StyleRefinement, Subscription, Task, TextStyle, TextStyleRefinement,
|
||||
Transformation, UnderlineStyle, WeakEntity, Window, WindowHandle, div, linear_color_stop,
|
||||
linear_gradient, list, percentage, point, prelude::*, pulsating_between,
|
||||
};
|
||||
use language::language_settings::SoftWrap;
|
||||
use language::{Buffer, Language};
|
||||
|
@ -34,7 +34,9 @@ use project::Project;
|
|||
use settings::Settings as _;
|
||||
use text::{Anchor, BufferSnapshot};
|
||||
use theme::ThemeSettings;
|
||||
use ui::{Disclosure, Divider, DividerColor, KeyBinding, Tooltip, prelude::*};
|
||||
use ui::{
|
||||
Disclosure, Divider, DividerColor, KeyBinding, Scrollbar, ScrollbarState, Tooltip, prelude::*,
|
||||
};
|
||||
use util::ResultExt;
|
||||
use workspace::{CollaboratorId, Workspace};
|
||||
use zed_actions::agent::{Chat, NextHistoryMessage, PreviousHistoryMessage};
|
||||
|
@ -69,6 +71,7 @@ pub struct AcpThreadView {
|
|||
notification_subscriptions: HashMap<WindowHandle<AgentNotification>, Vec<Subscription>>,
|
||||
last_error: Option<Entity<Markdown>>,
|
||||
list_state: ListState,
|
||||
scrollbar_state: ScrollbarState,
|
||||
auth_task: Option<Task<()>>,
|
||||
expanded_tool_calls: HashSet<acp::ToolCallId>,
|
||||
expanded_thinking_blocks: HashSet<(usize, usize)>,
|
||||
|
@ -187,7 +190,8 @@ impl AcpThreadView {
|
|||
notifications: Vec::new(),
|
||||
notification_subscriptions: HashMap::default(),
|
||||
diff_editors: Default::default(),
|
||||
list_state: list_state,
|
||||
list_state: list_state.clone(),
|
||||
scrollbar_state: ScrollbarState::new(list_state).parent_entity(&cx.entity()),
|
||||
last_error: None,
|
||||
auth_task: None,
|
||||
expanded_tool_calls: HashSet::default(),
|
||||
|
@ -2479,6 +2483,39 @@ impl AcpThreadView {
|
|||
.child(open_as_markdown)
|
||||
.child(scroll_to_top)
|
||||
}
|
||||
|
||||
fn render_vertical_scrollbar(&self, cx: &mut Context<Self>) -> Stateful<Div> {
|
||||
div()
|
||||
.id("acp-thread-scrollbar")
|
||||
.occlude()
|
||||
.on_mouse_move(cx.listener(|_, _, _, cx| {
|
||||
cx.notify();
|
||||
cx.stop_propagation()
|
||||
}))
|
||||
.on_hover(|_, _, cx| {
|
||||
cx.stop_propagation();
|
||||
})
|
||||
.on_any_mouse_down(|_, _, cx| {
|
||||
cx.stop_propagation();
|
||||
})
|
||||
.on_mouse_up(
|
||||
MouseButton::Left,
|
||||
cx.listener(|_, _, _, cx| {
|
||||
cx.stop_propagation();
|
||||
}),
|
||||
)
|
||||
.on_scroll_wheel(cx.listener(|_, _, _, cx| {
|
||||
cx.notify();
|
||||
}))
|
||||
.h_full()
|
||||
.absolute()
|
||||
.right_1()
|
||||
.top_1()
|
||||
.bottom_0()
|
||||
.w(px(12.))
|
||||
.cursor_default()
|
||||
.children(Scrollbar::vertical(self.scrollbar_state.clone()).map(|s| s.auto_hide(cx)))
|
||||
}
|
||||
}
|
||||
|
||||
impl Focusable for AcpThreadView {
|
||||
|
@ -2553,6 +2590,7 @@ impl Render for AcpThreadView {
|
|||
.flex_grow()
|
||||
.into_any(),
|
||||
)
|
||||
.child(self.render_vertical_scrollbar(cx))
|
||||
.children(match thread_clone.read(cx).status() {
|
||||
ThreadStatus::Idle | ThreadStatus::WaitingForToolConfirmation => {
|
||||
None
|
||||
|
|
|
@ -69,8 +69,6 @@ pub struct ActiveThread {
|
|||
messages: Vec<MessageId>,
|
||||
list_state: ListState,
|
||||
scrollbar_state: ScrollbarState,
|
||||
show_scrollbar: bool,
|
||||
hide_scrollbar_task: Option<Task<()>>,
|
||||
rendered_messages_by_id: HashMap<MessageId, RenderedMessage>,
|
||||
rendered_tool_uses: HashMap<LanguageModelToolUseId, RenderedToolUse>,
|
||||
editing_message: Option<(MessageId, EditingMessageState)>,
|
||||
|
@ -805,9 +803,7 @@ impl ActiveThread {
|
|||
expanded_thinking_segments: HashMap::default(),
|
||||
expanded_code_blocks: HashMap::default(),
|
||||
list_state: list_state.clone(),
|
||||
scrollbar_state: ScrollbarState::new(list_state),
|
||||
show_scrollbar: false,
|
||||
hide_scrollbar_task: None,
|
||||
scrollbar_state: ScrollbarState::new(list_state).parent_entity(&cx.entity()),
|
||||
editing_message: None,
|
||||
last_error: None,
|
||||
copied_code_block_ids: HashSet::default(),
|
||||
|
@ -3502,60 +3498,37 @@ impl ActiveThread {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_vertical_scrollbar(&self, cx: &mut Context<Self>) -> Option<Stateful<Div>> {
|
||||
if !self.show_scrollbar && !self.scrollbar_state.is_dragging() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(
|
||||
div()
|
||||
.occlude()
|
||||
.id("active-thread-scrollbar")
|
||||
.on_mouse_move(cx.listener(|_, _, _, cx| {
|
||||
cx.notify();
|
||||
cx.stop_propagation()
|
||||
}))
|
||||
.on_hover(|_, _, cx| {
|
||||
fn render_vertical_scrollbar(&self, cx: &mut Context<Self>) -> Stateful<Div> {
|
||||
div()
|
||||
.occlude()
|
||||
.id("active-thread-scrollbar")
|
||||
.on_mouse_move(cx.listener(|_, _, _, cx| {
|
||||
cx.notify();
|
||||
cx.stop_propagation()
|
||||
}))
|
||||
.on_hover(|_, _, cx| {
|
||||
cx.stop_propagation();
|
||||
})
|
||||
.on_any_mouse_down(|_, _, cx| {
|
||||
cx.stop_propagation();
|
||||
})
|
||||
.on_mouse_up(
|
||||
MouseButton::Left,
|
||||
cx.listener(|_, _, _, cx| {
|
||||
cx.stop_propagation();
|
||||
})
|
||||
.on_any_mouse_down(|_, _, cx| {
|
||||
cx.stop_propagation();
|
||||
})
|
||||
.on_mouse_up(
|
||||
MouseButton::Left,
|
||||
cx.listener(|_, _, _, cx| {
|
||||
cx.stop_propagation();
|
||||
}),
|
||||
)
|
||||
.on_scroll_wheel(cx.listener(|_, _, _, cx| {
|
||||
cx.notify();
|
||||
}))
|
||||
.h_full()
|
||||
.absolute()
|
||||
.right_1()
|
||||
.top_1()
|
||||
.bottom_0()
|
||||
.w(px(12.))
|
||||
.cursor_default()
|
||||
.children(Scrollbar::vertical(self.scrollbar_state.clone())),
|
||||
)
|
||||
}
|
||||
|
||||
fn hide_scrollbar_later(&mut self, cx: &mut Context<Self>) {
|
||||
const SCROLLBAR_SHOW_INTERVAL: Duration = Duration::from_secs(1);
|
||||
self.hide_scrollbar_task = Some(cx.spawn(async move |thread, cx| {
|
||||
cx.background_executor()
|
||||
.timer(SCROLLBAR_SHOW_INTERVAL)
|
||||
.await;
|
||||
thread
|
||||
.update(cx, |thread, cx| {
|
||||
if !thread.scrollbar_state.is_dragging() {
|
||||
thread.show_scrollbar = false;
|
||||
cx.notify();
|
||||
}
|
||||
})
|
||||
.log_err();
|
||||
}))
|
||||
}),
|
||||
)
|
||||
.on_scroll_wheel(cx.listener(|_, _, _, cx| {
|
||||
cx.notify();
|
||||
}))
|
||||
.h_full()
|
||||
.absolute()
|
||||
.right_1()
|
||||
.top_1()
|
||||
.bottom_0()
|
||||
.w(px(12.))
|
||||
.cursor_default()
|
||||
.children(Scrollbar::vertical(self.scrollbar_state.clone()).map(|s| s.auto_hide(cx)))
|
||||
}
|
||||
|
||||
pub fn is_codeblock_expanded(&self, message_id: MessageId, ix: usize) -> bool {
|
||||
|
@ -3596,26 +3569,8 @@ impl Render for ActiveThread {
|
|||
.size_full()
|
||||
.relative()
|
||||
.bg(cx.theme().colors().panel_background)
|
||||
.on_mouse_move(cx.listener(|this, _, _, cx| {
|
||||
this.show_scrollbar = true;
|
||||
this.hide_scrollbar_later(cx);
|
||||
cx.notify();
|
||||
}))
|
||||
.on_scroll_wheel(cx.listener(|this, _, _, cx| {
|
||||
this.show_scrollbar = true;
|
||||
this.hide_scrollbar_later(cx);
|
||||
cx.notify();
|
||||
}))
|
||||
.on_mouse_up(
|
||||
MouseButton::Left,
|
||||
cx.listener(|this, _, _, cx| {
|
||||
this.hide_scrollbar_later(cx);
|
||||
}),
|
||||
)
|
||||
.child(list(self.list_state.clone(), cx.processor(Self::render_message)).flex_grow())
|
||||
.when_some(self.render_vertical_scrollbar(cx), |this, scrollbar| {
|
||||
this.child(scrollbar)
|
||||
})
|
||||
.child(self.render_vertical_scrollbar(cx))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue