Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I928162008cb1ba02e1aa0e7aa971e8326a6a6964
97 lines
2.7 KiB
Rust
97 lines
2.7 KiB
Rust
use ratatui::{
|
|
Frame,
|
|
layout::{Constraint, Rect},
|
|
style::{Color, Modifier, Style},
|
|
text::Span,
|
|
widgets::{Block, Borders, Cell, Row, Table},
|
|
};
|
|
|
|
use super::{format_duration, format_size, media_type_color};
|
|
use crate::app::AppState;
|
|
|
|
pub fn render(f: &mut Frame, state: &AppState, area: Rect) {
|
|
let header =
|
|
Row::new(vec!["", "Title / Name", "Type", "Duration", "Year", "Size"])
|
|
.style(
|
|
Style::default()
|
|
.fg(Color::Yellow)
|
|
.add_modifier(Modifier::BOLD),
|
|
);
|
|
|
|
let rows: Vec<Row> = state
|
|
.media_list
|
|
.iter()
|
|
.enumerate()
|
|
.map(|(i, item)| {
|
|
let is_cursor = Some(i) == state.selected_index;
|
|
let is_selected = state.selected_items.contains(&item.id);
|
|
|
|
let style = if is_cursor {
|
|
Style::default().fg(Color::Black).bg(Color::Cyan)
|
|
} else if is_selected {
|
|
Style::default().fg(Color::Black).bg(Color::Green)
|
|
} else {
|
|
Style::default()
|
|
};
|
|
|
|
// Selection marker
|
|
let marker = if is_selected { "[*]" } else { "[ ]" };
|
|
let marker_style = if is_selected {
|
|
Style::default()
|
|
.fg(Color::Green)
|
|
.add_modifier(Modifier::BOLD)
|
|
} else {
|
|
Style::default().fg(Color::DarkGray)
|
|
};
|
|
|
|
let display_name =
|
|
item.title.as_deref().unwrap_or(&item.file_name).to_string();
|
|
|
|
let type_color = media_type_color(&item.media_type);
|
|
let type_cell = Cell::from(Span::styled(
|
|
item.media_type.clone(),
|
|
Style::default().fg(type_color),
|
|
));
|
|
|
|
let duration = item
|
|
.duration_secs
|
|
.map_or_else(|| "-".to_string(), format_duration);
|
|
|
|
let year = item.year.map_or_else(|| "-".to_string(), |y| y.to_string());
|
|
|
|
Row::new(vec![
|
|
Cell::from(Span::styled(marker, marker_style)),
|
|
Cell::from(display_name),
|
|
type_cell,
|
|
Cell::from(duration),
|
|
Cell::from(year),
|
|
Cell::from(format_size(item.file_size)),
|
|
])
|
|
.style(style)
|
|
})
|
|
.collect();
|
|
|
|
let page = (state.page_offset / state.page_size) + 1;
|
|
let item_count = state.media_list.len();
|
|
let selected_count = state.selected_items.len();
|
|
let title = if selected_count > 0 {
|
|
format!(
|
|
" Library (page {page}, {item_count} items, {selected_count} selected) "
|
|
)
|
|
} else {
|
|
format!(" Library (page {page}, {item_count} items) ")
|
|
};
|
|
|
|
let table = Table::new(rows, [
|
|
Constraint::Length(3), // Selection marker
|
|
Constraint::Percentage(33), // Title
|
|
Constraint::Percentage(18), // Type
|
|
Constraint::Percentage(13), // Duration
|
|
Constraint::Percentage(8), // Year
|
|
Constraint::Percentage(18), // Size
|
|
])
|
|
.header(header)
|
|
.block(Block::default().borders(Borders::ALL).title(title));
|
|
|
|
f.render_widget(table, area);
|
|
}
|