Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion app/src/ai/blocklist/block/view_impl/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,23 @@ pub struct WarpingIndicatorProps {
pub secondary_element: Option<Box<dyn Element>>,
}

/// Computes the fixed height of the warping-indicator footer.
///
/// The warping text occupies a single line. When a secondary element (an agent
/// tip or fallback-model explanation) is present, it renders on a second line
/// below the warping text, so the footer must reserve room for that extra line;
/// otherwise the `Clipped` wrapper — which keeps action chips from overflowing
/// narrow panes — also clips the secondary line. The extra line accounts for the
/// secondary element's font size (`monospace_font_size - 3`, see
/// `render_agent_tip` / `render_fallback_explanation`) plus its 1px top margin.
fn warping_footer_height(monospace_font_size: f32, has_secondary_element: bool) -> f32 {
let mut height = STATUS_FOOTER_VERTICAL_PADDING * 2. + monospace_font_size;
if has_secondary_element {
height += (monospace_font_size - 3.) + 1.;
}
height
}

/// Helper function to render text in the "warping..." footer.
/// Additional text that does not use the shimmering text animation can be passed in via
/// `non_shimmering_text` which is useful if you want some part of the text to constantly update
Expand All @@ -543,6 +560,10 @@ pub fn render_warping_indicator_base(
is_passive_code_diff,
secondary_element,
} = props;
// Whether a secondary element (an agent tip or fallback-model explanation)
// will be rendered on a second line below the warping text. Captured before
// `secondary_element` is consumed so the container can reserve room for it.
let has_secondary_element = secondary_element.is_some();
// Unicode code point for the Warp glyph that is embedded in the version of Roboto we bundle
// into the app. This code point MUST be rendered using Roboto (the default ui font) or else the
// glyph may not be rendered.
Expand Down Expand Up @@ -646,7 +667,10 @@ pub fn render_warping_indicator_base(
} else {
let mut container = Container::new(
ConstrainedBox::new(content)
.with_height(STATUS_FOOTER_VERTICAL_PADDING * 2. + appearance.monospace_font_size())
.with_height(warping_footer_height(
appearance.monospace_font_size(),
has_secondary_element,
))
.finish(),
)
.with_padding_right(CONTENT_HORIZONTAL_PADDING);
Expand Down
24 changes: 22 additions & 2 deletions app/src/ai/blocklist/block/view_impl/common_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use super::{
collect_visual_markdown_lightbox_collection, compute_visual_section_width,
image_tooltip_handles_for_group, inline_image_source_label,
is_supported_blocklist_image_source, lightbox_trigger_for_section, query_prefix_highlight_len,
render_scrollable_collapsible_content, text_sections_with_indices, CollapsibleElementState,
CollapsibleExpansionState, VisualMarkdownLightboxCollection,
render_scrollable_collapsible_content, text_sections_with_indices, warping_footer_height,
CollapsibleElementState, CollapsibleExpansionState, VisualMarkdownLightboxCollection,
};
use crate::ai::agent::{
AIAgentInput, AIAgentTextSection, AgentOutputImage, AgentOutputImageLayout,
Expand Down Expand Up @@ -161,6 +161,26 @@ fn render_scrollable_collapsible_content_returns_none_when_collapsed() {
);
}

#[test]
fn warping_footer_height_reserves_a_line_for_the_secondary_element() {
// Regression: the warping indicator's footer is a fixed-height, clipped
// container. When an agent tip (or fallback-model explanation) is present it
// renders on a second line, so the footer must be taller than the
// single-line case — otherwise the clip (added to keep action chips from
// overflowing narrow panes) hides the tip entirely.
let font_size = 13.;
let without_tip = warping_footer_height(font_size, false);
let with_tip = warping_footer_height(font_size, true);

assert!(
with_tip > without_tip,
"footer with a secondary element ({with_tip}) should be taller than without ({without_tip})",
);
// The extra room must cover the secondary line: its font size
// (monospace_font_size - 3) plus the 1px top margin on the tip container.
assert_eq!(with_tip - without_tip, (font_size - 3.) + 1.);
}

#[test]
fn compute_visual_section_width_rejects_non_finite_dimensions() {
assert_eq!(compute_visual_section_width(f32::INFINITY, 20., 40.), None);
Expand Down
Loading