use crate::app::{App, SortCriteria};
use crate::ui::{Component, centered_rect, get_border_type};
use ratatui::style::{Color, Style};
use ratatui::{
Frame,
layout::{Constraint, Direction, Layout, Margin, Rect},
text::Text,
widgets::{Block, Borders, List, ListItem, Paragraph},
};
use ratatui_image::{StatefulImage, picker::Picker};
pub struct LibraryView;
impl Component for LibraryView {
fn render(&self, f: &mut Frame, area: Rect, app: &mut App, _picker: &mut Picker) {
let area = centered_rect(80, 80, area);
let layout = Layout::default()
.direction(Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(area);
let border_type = get_border_type(&app.config);
let mut list_items = Vec::new();
for book in &app.library_books {
let is_current = book.path == app.book_path;
let prefix = if is_current { "▶ " } else { " " };
let display_title = if book.title.is_empty() {
"Unknown Title"
} else {
&book.title
};
let content = format!("{}{}", prefix, display_title);
let mut text = Text::from(content);
if is_current {
text = text.style(Style::default().fg(Color::Green));
}
list_items.push(ListItem::new(text));
}
let sort_text = match app.sort_criteria {
SortCriteria::Recent => "Recent",
SortCriteria::Title => "Title",
SortCriteria::Author => "Author",
};
let list = List::new(list_items)
.block(
Block::default()
.borders(Borders::ALL)
.border_type(border_type)
.title(format!(" Library (Sort: {}) ", sort_text)),
)
.highlight_style(Style::default().bg(Color::DarkGray))
.highlight_symbol("> ");
f.render_stateful_widget(list, layout[0], &mut app.library_state);
let cover_block = Block::default()
.borders(Borders::ALL)
.border_type(border_type);
let cover_area = layout[1];
f.render_widget(cover_block.clone(), cover_area);
if let Some(ref mut protocol) = app.library_cover_protocol {
f.render_stateful_widget(
StatefulImage::default(),
cover_area.inner(Margin {
vertical: 1,
horizontal: 1,
}),
protocol,
);
} else {
f.render_widget(
Paragraph::new("No cover available"),
cover_area.inner(Margin {
vertical: 1,
horizontal: 1,
}),
);
}
}
}