Added List

This commit is contained in:
2026-02-13 20:24:27 -06:00
parent 13039965ba
commit 664e9e944a

View File

@@ -11,15 +11,37 @@ use crossterm::{
use ratatui::{ use ratatui::{
layout::{Constraint, Layout, Rect, Spacing}, layout::{Constraint, Layout, Rect, Spacing},
symbols::merge::MergeStrategy, symbols::merge::MergeStrategy,
widgets::{Block, Paragraph}, widgets::{Block, List, ListItem, ListState, Paragraph},
Frame, Terminal, Frame, Terminal,
}; };
use ratatui::backend::CrosstermBackend; use ratatui::backend::CrosstermBackend;
#[derive(Default)]
struct App { struct App {
should_exit: bool, should_exit: bool,
status: String, status: String,
items: Vec<String>,
selected: usize,
}
impl Default for App {
fn default() -> Self {
Self {
should_exit: false,
status: "Press q to quit".to_string(),
items: vec![
"Shows".into(),
"Movies".into(),
"Music".into(),
"Playlists".into(),
"Collections".into(),
"Continue Watching".into(),
"Recently Added".into(),
"Downloads".into(),
"Settings".into(),
],
selected: 0,
}
}
} }
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
@@ -44,11 +66,7 @@ fn main() -> io::Result<()> {
fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> io::Result<()> { fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> io::Result<()> {
let tick_rate = Duration::from_millis(16); // ~60fps let tick_rate = Duration::from_millis(16); // ~60fps
let mut last_tick = Instant::now(); let mut last_tick = Instant::now();
let mut app = App::default();
let mut app = App {
status: "Press q to quit".to_string(),
..Default::default()
};
while !app.should_exit { while !app.should_exit {
terminal.draw(|f| ui(f, &app))?; terminal.draw(|f| ui(f, &app))?;
@@ -66,15 +84,28 @@ fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> io::Result<
// tick-based updates go here later (smooth nav, download polling, etc.) // tick-based updates go here later (smooth nav, download polling, etc.)
last_tick = Instant::now(); last_tick = Instant::now();
} }
} };
Ok(()) Ok(())
} }
fn handle_key(app: &mut App, code: KeyCode) { fn handle_key(app: &mut App, code: KeyCode) {
match code { match code {
KeyCode::Char('q') => app.should_exit = true, KeyCode::Char('q') => app.should_exit = true,
KeyCode::Char('h') => app.status = "hi".to_string(),
KeyCode::Up | KeyCode::Char('k') => {
if app.selected > 0 {
app.selected -= 1;
}
app.status = format!("Selected: {}", app.items[app.selected]);
}
KeyCode::Down | KeyCode::Char('j') => {
if app.selected + 1 < app.items.len() {
app.selected += 1;
}
app.status = format!("Selected: {}", app.items[app.selected]);
}
_ => {} _ => {}
} }
} }
@@ -86,9 +117,29 @@ fn ui(frame: &mut Frame, app: &App) {
// Top // Top
frame.render_widget(Block::bordered().title("cj-jftui"), panes.top); frame.render_widget(Block::bordered().title("cj-jftui"), panes.top);
// Main // Left Main
frame.render_widget(Block::bordered().title("List").merge_borders(MergeStrategy::Exact), panes.left_main); let items: Vec<ListItem> = app
frame.render_widget(Block::bordered().title("Details").merge_borders(MergeStrategy::Exact), panes.right_main); .items
.iter()
.map(|s| ListItem::new(s.as_str()))
.collect();
let list = List::new(items)
.block(Block::bordered().title("List").merge_borders(MergeStrategy::Exact))
.highlight_symbol("> ");
let mut state = ListState::default();
state.select(Some(app.selected));
frame.render_stateful_widget(list, panes.left_main, &mut state);
//Right Main
let detail = format!("Details for:\n\n{}", app.items[app.selected]);
frame.render_widget(
Paragraph::new(detail)
.block(Block::bordered().title("Details").merge_borders(MergeStrategy::Exact)),
panes.right_main,
);
// Bottom // Bottom
frame.render_widget( frame.render_widget(