agent: Add animation in the edit file tool card until a diff is assigned (#29773)

This PR prevents this edit card from being shown expanded but empty,
like this:

<img width="590" alt="Screenshot 2025-05-01 at 7 38 47 PM"
src="https://github.com/user-attachments/assets/147d3d73-05b9-4493-8145-0ee915f12cd9"
/>

Now, we will show an animation until it has a diff computed.


https://github.com/user-attachments/assets/52900cdf-ee3d-4c3b-88c7-c53377543bcf

Release Notes:

- N/A

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This commit is contained in:
Max Brunsfeld 2025-05-02 05:48:40 -07:00 committed by GitHub
parent 33011f2eaf
commit 225deb6785
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -7,7 +7,8 @@ use assistant_tool::{ActionLog, AnyToolCard, Tool, ToolCard, ToolResult, ToolUse
use buffer_diff::{BufferDiff, BufferDiffSnapshot};
use editor::{Editor, EditorMode, MultiBuffer, PathKey};
use gpui::{
AnyWindowHandle, App, AppContext, AsyncApp, Context, Entity, EntityId, Task, WeakEntity,
Animation, AnimationExt, AnyWindowHandle, App, AppContext, AsyncApp, Context, Entity, EntityId,
Task, WeakEntity, pulsating_between,
};
use language::{
Anchor, Buffer, Capability, LanguageRegistry, LineEnding, OffsetRangeExt, Rope, TextBuffer,
@ -20,6 +21,7 @@ use serde::{Deserialize, Serialize};
use std::{
path::{Path, PathBuf},
sync::Arc,
time::Duration,
};
use ui::{Disclosure, Tooltip, Window, prelude::*};
use util::ResultExt;
@ -323,6 +325,10 @@ impl EditFileToolCard {
}
}
pub fn has_diff(&self) -> bool {
self.total_lines.is_some()
}
pub fn set_diff(
&mut self,
path: Arc<Path>,
@ -463,9 +469,8 @@ impl ToolCard for EditFileToolCard {
.rounded_t_md()
.when(!failed, |header| header.bg(codeblock_header_bg))
.child(path_label_button)
.map(|container| {
if failed {
container.child(
.when(failed, |header| {
header.child(
h_flex()
.gap_1()
.child(
@ -487,8 +492,9 @@ impl ToolCard for EditFileToolCard {
)),
),
)
} else {
container.child(
})
.when(!failed && self.has_diff(), |header| {
header.child(
Disclosure::new(
("edit-file-disclosure", self.editor_unique_id),
self.preview_expanded,
@ -501,7 +507,6 @@ impl ToolCard for EditFileToolCard {
},
)),
)
}
});
let (editor, editor_line_height) = self.editor.update(cx, |editor, cx| {
@ -538,6 +543,50 @@ impl ToolCard for EditFileToolCard {
const DEFAULT_COLLAPSED_LINES: u32 = 10;
let is_collapsible = self.total_lines.unwrap_or(0) > DEFAULT_COLLAPSED_LINES;
let waiting_for_diff = {
let styles = [
("w_4_5", (0.1, 0.85), 2000),
("w_1_4", (0.2, 0.75), 2200),
("w_2_4", (0.15, 0.64), 1900),
("w_3_5", (0.25, 0.72), 2300),
("w_2_5", (0.3, 0.56), 1800),
];
let mut container = v_flex()
.p_3()
.gap_1p5()
.border_t_1()
.border_color(border_color)
.bg(cx.theme().colors().editor_background);
for (width_method, pulse_range, duration_ms) in styles.iter() {
let (min_opacity, max_opacity) = *pulse_range;
let placeholder = match *width_method {
"w_4_5" => div().w_3_4(),
"w_1_4" => div().w_1_4(),
"w_2_4" => div().w_2_4(),
"w_3_5" => div().w_3_5(),
"w_2_5" => div().w_2_5(),
_ => div().w_1_2(),
}
.id("loading_div")
.h_2()
.rounded_full()
.bg(cx.theme().colors().element_active)
.with_animation(
"loading_pulsate",
Animation::new(Duration::from_millis(*duration_ms))
.repeat()
.with_easing(pulsating_between(min_opacity, max_opacity)),
|label, delta| label.opacity(delta),
);
container = container.child(placeholder);
}
container
};
v_flex()
.mb_2()
.border_1()
@ -573,7 +622,12 @@ impl ToolCard for EditFileToolCard {
),
)
})
.when(!failed && self.preview_expanded, |card| {
.when(!self.has_diff() && !failed, |card| {
card.child(waiting_for_diff)
})
.when(
!failed && self.preview_expanded && self.has_diff(),
|card| {
card.child(
v_flex()
.relative()
@ -604,7 +658,9 @@ impl ToolCard for EditFileToolCard {
.border_t_1()
.border_color(border_color)
.bg(cx.theme().colors().editor_background)
.hover(|style| style.bg(cx.theme().colors().element_hover.opacity(0.1)))
.hover(|style| {
style.bg(cx.theme().colors().element_hover.opacity(0.1))
})
.child(
Icon::new(full_height_icon)
.size(IconSize::Small)
@ -616,7 +672,8 @@ impl ToolCard for EditFileToolCard {
})),
)
})
})
},
)
}
}