@@ -46,6 +46,8 @@ 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_use_labels: HashMap<LanguageModelToolUseId, Entity<Markdown>>,
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<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| {
+ 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| {
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<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()
.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)
+ })
}
}