use std::path::Path;
use crate::glyphs;
use crate::render::context::RenderContext;
use ratatui::buffer::Buffer;
use ratatui::layout::Rect;
use ratatui::style::{Modifier, Style};
use ratatui::text::{Line, Span};
use ratatui::widgets::{Clear, Paragraph, Widget};
pub fn render(area: Rect, buf: &mut Buffer, app: &crate::App, ctx: &RenderContext) {
Clear.render(area, buf);
if area.width < 12 || area.height < 3 {
return;
}
let (phase, path, size) = match app.load_shown() {
Some((phase, _, path, size)) => (phase, path.map(Path::to_path_buf), size),
_ => ("Loading", None, 0),
};
let phase = app.loading_phase(phase);
let phase = phase.as_ref();
let g = glyphs::get();
let frame = app.throbber_frame as usize % g.spinner.len();
let phase_line = if app.awaiting_open_confirmation() {
Line::from("")
} else {
Line::from(vec![
Span::styled(
format!("{} ", g.spinner[frame]),
Style::default().fg(ctx.throbber),
),
Span::styled(
glyphs::fit(
&format!("{phase}{}", g.ellipsis),
(area.width as usize).saturating_sub(3),
),
Style::default()
.fg(ctx.text_primary)
.add_modifier(Modifier::BOLD),
),
])
};
let mut lines = vec![phase_line, Line::from("")];
if let Some(path) = path.as_ref() {
let name = path
.file_name()
.map(|n| n.to_string_lossy().into_owned())
.unwrap_or_else(|| crate::home::display_path(path));
lines.push(Line::from(Span::styled(
glyphs::fit(&name, area.width as usize),
Style::default().fg(ctx.text_primary),
)));
let mut detail = crate::home::display_path(path);
if size > 0 {
detail = format!("{detail} {}", crate::numfmt::bytes(size));
}
lines.push(Line::from(Span::styled(
glyphs::fit_start(&detail, area.width as usize),
Style::default().fg(ctx.text_secondary),
)));
}
let top = area
.y
.saturating_add(area.height.saturating_sub(lines.len() as u16) / 2)
.saturating_sub(1)
.max(area.y);
let height = (lines.len() as u16).min(area.height.saturating_sub(top - area.y));
let body = Rect {
x: area.x,
y: top,
width: area.width,
height,
};
Paragraph::new(lines).centered().render(body, buf);
}
#[cfg(test)]
mod tests;