diff --git a/crates/agent_ui/src/conversation_view.rs b/crates/agent_ui/src/conversation_view.rs index 7c9acfdf27d5b750afe4b8817af7f657f5fcdecc..e2b02d814be7950afd061ac9778be6587527e016 100644 --- a/crates/agent_ui/src/conversation_view.rs +++ b/crates/agent_ui/src/conversation_view.rs @@ -54,8 +54,8 @@ use theme_settings::AgentFontSize; use ui::{ Callout, CircularProgress, CommonAnimationExt, ContextMenu, ContextMenuEntry, CopyButton, DecoratedIcon, DiffStat, Disclosure, Divider, DividerColor, IconDecoration, IconDecorationKind, - KeyBinding, PopoverMenu, PopoverMenuHandle, SpinnerLabel, TintColor, Tooltip, WithScrollbar, - prelude::*, right_click_menu, + KeyBinding, PopoverMenu, PopoverMenuHandle, TintColor, Tooltip, WithScrollbar, prelude::*, + right_click_menu, }; use util::{ResultExt, size::format_file_size, time::duration_alt_display}; use util::{debug_panic, defer}; diff --git a/crates/agent_ui/src/conversation_view/thread_view.rs b/crates/agent_ui/src/conversation_view/thread_view.rs index 27ebadade8047db5f2b4de63c5c3731708d9af59..63df627cade5b96f47cbc338914780c23934e56d 100644 --- a/crates/agent_ui/src/conversation_view/thread_view.rs +++ b/crates/agent_ui/src/conversation_view/thread_view.rs @@ -14,7 +14,7 @@ use gpui::{Corner, List}; use heapless::Vec as ArrayVec; use language_model::{LanguageModelEffortLevel, Speed}; use settings::update_settings_file; -use ui::{ButtonLike, SplitButton, SplitButtonStyle, Tab}; +use ui::{ButtonLike, SpinnerLabel, SpinnerVariant, SplitButton, SplitButtonStyle, Tab}; use workspace::SERIALIZATION_THROTTLE_TIME; use super::*; @@ -164,6 +164,46 @@ impl ThreadFeedbackState { } } +struct GeneratingSpinner { + variant: SpinnerVariant, +} + +impl GeneratingSpinner { + fn new(variant: SpinnerVariant) -> Self { + Self { variant } + } +} + +impl Render for GeneratingSpinner { + fn render(&mut self, _window: &mut Window, _cx: &mut Context) -> impl IntoElement { + SpinnerLabel::with_variant(self.variant).size(LabelSize::Small) + } +} + +#[derive(IntoElement)] +struct GeneratingSpinnerElement { + variant: SpinnerVariant, +} + +impl GeneratingSpinnerElement { + fn new(variant: SpinnerVariant) -> Self { + Self { variant } + } +} + +impl RenderOnce for GeneratingSpinnerElement { + fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement { + let id = match self.variant { + SpinnerVariant::Dots => "generating-spinner-view", + SpinnerVariant::Sand => "confirmation-spinner-view", + _ => "spinner-view", + }; + window.with_id(id, |window| { + window.use_state(cx, |_, _| GeneratingSpinner::new(self.variant)) + }) + } +} + pub enum AcpThreadViewEvent { FirstSendRequested { content: Vec }, MessageSentOrQueued, @@ -4275,10 +4315,10 @@ impl Render for TokenUsageTooltip { } impl ThreadView { - pub(crate) fn render_entries(&mut self, cx: &mut Context) -> List { + fn render_entries(&mut self, cx: &mut Context) -> List { list( self.list_state.clone(), - cx.processor(|this, index: usize, window, cx| { + cx.processor(move |this, index: usize, window, cx| { let entries = this.thread.read(cx).entries(); if let Some(entry) = entries.get(index) { this.render_entry(index, entries.len(), entry, window, cx) @@ -5193,7 +5233,8 @@ impl ThreadView { this.child( h_flex() .w_2() - .child(SpinnerLabel::sand().size(LabelSize::Small)), + .justify_center() + .child(GeneratingSpinnerElement::new(SpinnerVariant::Sand)), ) .child( div().min_w(rems(8.)).child( @@ -5205,7 +5246,12 @@ impl ThreadView { } else if is_blocked_on_terminal_command { this } else { - this.child(SpinnerLabel::new().size(LabelSize::Small)) + this.child( + h_flex() + .w_2() + .justify_center() + .child(GeneratingSpinnerElement::new(SpinnerVariant::Dots)), + ) } }) .when_some(elapsed_label, |this, elapsed| {