diff --git a/crates/agent/src/active_thread.rs b/crates/agent/src/active_thread.rs index fc1a3f3a1c..496fd67352 100644 --- a/crates/agent/src/active_thread.rs +++ b/crates/agent/src/active_thread.rs @@ -46,6 +46,8 @@ pub struct ActiveThread { messages: Vec, list_state: ListState, scrollbar_state: ScrollbarState, + show_scrollbar: bool, + hide_scrollbar_task: Option>, rendered_messages_by_id: HashMap, rendered_tool_use_labels: HashMap>, editing_message: Option<(MessageId, EditMessageState)>, @@ -377,6 +379,8 @@ impl ActiveThread { expanded_thinking_segments: HashMap::default(), list_state: list_state.clone(), scrollbar_state: ScrollbarState::new(list_state), + show_scrollbar: false, + hide_scrollbar_task: None, editing_message: None, last_error: None, notifications: Vec::new(), @@ -2197,37 +2201,60 @@ impl ActiveThread { } } - fn render_vertical_scrollbar(&self, cx: &mut Context) -> Stateful
{ - 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| { + fn render_vertical_scrollbar(&self, cx: &mut Context) -> Option> { + 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| { 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())) + }) + .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) { + 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() .size_full() .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(self.render_vertical_scrollbar(cx)) + .when_some(self.render_vertical_scrollbar(cx), |this, scrollbar| { + this.child(scrollbar) + }) } }