use ratatui::prelude::*;
use ratatui::widgets::Paragraph;
use crate::app::App;
use super::widgets::{panel_block, truncate_with_ellipsis};
pub(crate) const MAX_ENTRIES: usize = 4;
pub fn render(frame: &mut Frame, app: &App, area: Rect) {
let theme = &app.theme;
let entries = &app.gallery.entries;
let count = entries.len().min(MAX_ENTRIES);
let hint = if entries.is_empty() {
None
} else {
Some(format!("{count} recent"))
};
let block = panel_block(theme, "Recent", false, hint.as_deref());
let inner = block.inner(area);
frame.render_widget(block, area);
if inner.width == 0 || inner.height == 0 {
return;
}
if entries.is_empty() {
let empty = Paragraph::new("No images yet — press Enter to generate.")
.style(theme.dim())
.alignment(Alignment::Left);
frame.render_widget(empty, inner);
return;
}
let width = inner.width as usize;
let lines: Vec<Line> = entries
.iter()
.take(count.min(inner.height as usize))
.enumerate()
.map(|(i, entry)| build_line(theme, entry, i, width))
.collect();
let paragraph = Paragraph::new(lines);
frame.render_widget(paragraph, inner);
}
fn build_line<'a>(
theme: &crate::ui::theme::Theme,
entry: &'a crate::app::GalleryEntry,
index: usize,
width: usize,
) -> Line<'a> {
let name = entry.filename();
let model = entry.metadata.model.as_str();
let diff = diff_label(index);
let chrome = 2 + diff.len() + 4;
let body_width = width.saturating_sub(chrome);
let name_width = body_width.saturating_mul(3) / 5; let model_width = body_width.saturating_sub(name_width);
let name_cell = truncate_with_ellipsis(&name, name_width);
let model_cell = truncate_with_ellipsis(model, model_width);
let mut spans = Vec::with_capacity(6);
spans.push(Span::styled("● ", Style::default().fg(theme.accent)));
spans.push(Span::styled(
format!("{:<w$}", name_cell, w = name_width),
theme.param_value(),
));
spans.push(Span::raw(" "));
spans.push(Span::styled(
format!("{:<w$}", model_cell, w = model_width),
theme.dim(),
));
spans.push(Span::raw(" "));
spans.push(Span::styled(diff, theme.dim()));
Line::from(spans)
}
fn diff_label(index: usize) -> &'static str {
match index {
0 => "latest",
1 => "-1",
2 => "-2",
3 => "-3",
_ => "-n",
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn diff_labels_cover_first_four() {
assert_eq!(diff_label(0), "latest");
assert_eq!(diff_label(1), "-1");
assert_eq!(diff_label(3), "-3");
assert_eq!(diff_label(5), "-n");
}
}