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::{
layout::{Constraint, Layout, Rect, Spacing},
symbols::merge::MergeStrategy,
widgets::{Block, Paragraph},
widgets::{Block, List, ListItem, ListState, Paragraph},
Frame, Terminal,
};
use ratatui::backend::CrosstermBackend;
#[derive(Default)]
struct App {
should_exit: bool,
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<()> {
@@ -44,11 +66,7 @@ fn main() -> io::Result<()> {
fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> io::Result<()> {
let tick_rate = Duration::from_millis(16); // ~60fps
let mut last_tick = Instant::now();
let mut app = App {
status: "Press q to quit".to_string(),
..Default::default()
};
let mut app = App::default();
while !app.should_exit {
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.)
last_tick = Instant::now();
}
}
};
Ok(())
}
fn handle_key(app: &mut App, code: KeyCode) {
match code {
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
frame.render_widget(Block::bordered().title("cj-jftui"), panes.top);
// Main
frame.render_widget(Block::bordered().title("List").merge_borders(MergeStrategy::Exact), panes.left_main);
frame.render_widget(Block::bordered().title("Details").merge_borders(MergeStrategy::Exact), panes.right_main);
// Left Main
let items: Vec<ListItem> = app
.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
frame.render_widget(