agent: Hide the scrollbar if there's no mouse movement (#28129)
Release Notes: - agent: The scrollbar now automatically hides if there's no mouse movement on the thread list. --------- Co-authored-by: Agus Zubiaga <agus@zed.dev> Co-authored-by: Agus Zubiaga <hi@aguz.me>
This commit is contained in:
parent
02e4267bc6
commit
b8d05bb641
1 changed files with 76 additions and 31 deletions
|
@ -46,6 +46,8 @@ pub struct ActiveThread {
|
||||||
messages: Vec<MessageId>,
|
messages: Vec<MessageId>,
|
||||||
list_state: ListState,
|
list_state: ListState,
|
||||||
scrollbar_state: ScrollbarState,
|
scrollbar_state: ScrollbarState,
|
||||||
|
show_scrollbar: bool,
|
||||||
|
hide_scrollbar_task: Option<Task<()>>,
|
||||||
rendered_messages_by_id: HashMap<MessageId, RenderedMessage>,
|
rendered_messages_by_id: HashMap<MessageId, RenderedMessage>,
|
||||||
rendered_tool_use_labels: HashMap<LanguageModelToolUseId, Entity<Markdown>>,
|
rendered_tool_use_labels: HashMap<LanguageModelToolUseId, Entity<Markdown>>,
|
||||||
editing_message: Option<(MessageId, EditMessageState)>,
|
editing_message: Option<(MessageId, EditMessageState)>,
|
||||||
|
@ -377,6 +379,8 @@ impl ActiveThread {
|
||||||
expanded_thinking_segments: HashMap::default(),
|
expanded_thinking_segments: HashMap::default(),
|
||||||
list_state: list_state.clone(),
|
list_state: list_state.clone(),
|
||||||
scrollbar_state: ScrollbarState::new(list_state),
|
scrollbar_state: ScrollbarState::new(list_state),
|
||||||
|
show_scrollbar: false,
|
||||||
|
hide_scrollbar_task: None,
|
||||||
editing_message: None,
|
editing_message: None,
|
||||||
last_error: None,
|
last_error: None,
|
||||||
notifications: Vec::new(),
|
notifications: Vec::new(),
|
||||||
|
@ -2197,37 +2201,60 @@ impl ActiveThread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_vertical_scrollbar(&self, cx: &mut Context<Self>) -> Stateful<Div> {
|
fn render_vertical_scrollbar(&self, cx: &mut Context<Self>) -> Option<Stateful<Div>> {
|
||||||
div()
|
if !self.show_scrollbar && !self.scrollbar_state.is_dragging() {
|
||||||
.occlude()
|
return None;
|
||||||
.id("active-thread-scrollbar")
|
}
|
||||||
.on_mouse_move(cx.listener(|_, _, _, cx| {
|
|
||||||
cx.notify();
|
Some(
|
||||||
cx.stop_propagation()
|
div()
|
||||||
}))
|
.occlude()
|
||||||
.on_hover(|_, _, cx| {
|
.id("active-thread-scrollbar")
|
||||||
cx.stop_propagation();
|
.on_mouse_move(cx.listener(|_, _, _, cx| {
|
||||||
})
|
cx.notify();
|
||||||
.on_any_mouse_down(|_, _, cx| {
|
cx.stop_propagation()
|
||||||
cx.stop_propagation();
|
}))
|
||||||
})
|
.on_hover(|_, _, cx| {
|
||||||
.on_mouse_up(
|
|
||||||
MouseButton::Left,
|
|
||||||
cx.listener(|_, _, _, cx| {
|
|
||||||
cx.stop_propagation();
|
cx.stop_propagation();
|
||||||
}),
|
})
|
||||||
)
|
.on_any_mouse_down(|_, _, cx| {
|
||||||
.on_scroll_wheel(cx.listener(|_, _, _, cx| {
|
cx.stop_propagation();
|
||||||
cx.notify();
|
})
|
||||||
}))
|
.on_mouse_up(
|
||||||
.h_full()
|
MouseButton::Left,
|
||||||
.absolute()
|
cx.listener(|_, _, _, cx| {
|
||||||
.right_1()
|
cx.stop_propagation();
|
||||||
.top_1()
|
}),
|
||||||
.bottom_0()
|
)
|
||||||
.w(px(12.))
|
.on_scroll_wheel(cx.listener(|_, _, _, cx| {
|
||||||
.cursor_default()
|
cx.notify();
|
||||||
.children(Scrollbar::vertical(self.scrollbar_state.clone()))
|
}))
|
||||||
|
.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();
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2236,8 +2263,26 @@ impl Render for ActiveThread {
|
||||||
v_flex()
|
v_flex()
|
||||||
.size_full()
|
.size_full()
|
||||||
.relative()
|
.relative()
|
||||||
|
.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()).flex_grow())
|
.child(list(self.list_state.clone()).flex_grow())
|
||||||
.child(self.render_vertical_scrollbar(cx))
|
.when_some(self.render_vertical_scrollbar(cx), |this, scrollbar| {
|
||||||
|
this.child(scrollbar)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue