use ratatui::Frame;
use ratatui::layout::Rect;
use ratatui::style::Style;
use ratatui::text::{Line, Span};
use ratatui::widgets::{Clear, Paragraph};
use crate::app::App;
use crate::ui::theme;
pub fn draw(frame: &mut Frame, app: &App, screen: Rect) {
let progress = match app.fim_progress.lock() {
Ok(g) => g.clone(),
Err(p) => p.into_inner().clone(),
};
let Some(p) = progress else {
return;
};
let t = theme::cur();
let w = 52u16.min(screen.width);
let h = 4u16.min(screen.height);
let x = screen.x + (screen.width.saturating_sub(w)) / 2;
let y = screen.y.saturating_add(screen.height.saturating_sub(h + 2));
let area = Rect {
x,
y,
width: w,
height: h,
};
frame.render_widget(Clear, area);
let block = crate::ui::design_tokens::modal_panel("Downloading local model (one-time)");
let inner = block.inner(area);
frame.render_widget(block, area);
if inner.width < 4 || inner.height < 2 {
return;
}
let fmt_bytes = |b: u64| -> String {
if b >= 1 << 30 {
format!("{:.1} GB", b as f64 / (1u64 << 30) as f64)
} else {
format!("{:.0} MB", b as f64 / (1u64 << 20) as f64)
}
};
let status = match p.total {
Some(total) => format!(
" {} · {} / {}",
p.label,
fmt_bytes(p.received),
fmt_bytes(total)
),
None => format!(" {} · {}", p.label, fmt_bytes(p.received)),
};
frame.render_widget(
Paragraph::new(Line::from(Span::styled(
status,
Style::default().fg(t.comment),
))),
Rect::new(inner.x, inner.y, inner.width, 1),
);
let bar_w = inner.width as usize;
let filled = match p.total {
Some(total) if total > 0 => ((p.received as u128 * bar_w as u128) / total as u128) as usize,
_ => bar_w.saturating_sub(1),
};
let bar: String =
"█".repeat(filled.min(bar_w)) + &"░".repeat(bar_w.saturating_sub(filled.min(bar_w)));
frame.render_widget(
Paragraph::new(Line::from(Span::styled(
bar,
Style::default().fg(t.cyan).bg(t.bg2),
))),
Rect::new(inner.x, inner.y + 1, inner.width, 1),
);
}