This commit is contained in:
Lucy 2025-09-30 21:47:30 +02:00
parent 35c3f4c423
commit 0bff250ecf

View file

@ -1,19 +1,19 @@
use crate::{downloader, wget_list};
use crossterm::{ use crossterm::{
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode}, event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
execute, execute,
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode}, terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
}; };
use std::{error::Error, io}; use std::{error::Error, io, time::Duration};
use tui::{ use tui::{
Terminal, Terminal,
backend::CrosstermBackend, backend::CrosstermBackend,
layout::{Constraint, Direction, Layout}, layout::{Constraint, Direction, Layout},
style::{Color, Modifier, Style}, style::{Color, Modifier, Style},
widgets::{Block, Borders, List, ListItem}, widgets::{Block, Borders, Gauge, List, ListItem, Paragraph},
}; };
pub fn tui_menu() -> Result<(), Box<dyn Error>> { pub fn tui_menu() -> Result<(), Box<dyn Error>> {
// Setup terminal
enable_raw_mode()?; enable_raw_mode()?;
let mut stdout = io::stdout(); let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
@ -28,8 +28,14 @@ pub fn tui_menu() -> Result<(), Box<dyn Error>> {
let size = f.size(); let size = f.size();
let chunks = Layout::default() let chunks = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.margin(5) .margin(2)
.constraints([Constraint::Length(menu_items.len() as u16)].as_ref()) .constraints(
[
Constraint::Length(menu_items.len() as u16),
Constraint::Min(1),
]
.as_ref(),
)
.split(size); .split(size);
let items: Vec<ListItem> = menu_items let items: Vec<ListItem> = menu_items
@ -53,47 +59,46 @@ pub fn tui_menu() -> Result<(), Box<dyn Error>> {
.borders(Borders::ALL), .borders(Borders::ALL),
); );
f.render_widget(list, chunks[0]); f.render_widget(list, chunks[0]);
let status = Paragraph::new("Use ↑↓ to navigate, Enter to select.")
.block(Block::default().borders(Borders::ALL).title("Status"));
f.render_widget(status, chunks[1]);
})?; })?;
// Handle input if event::poll(Duration::from_millis(100))? {
if let Event::Key(key) = event::read()? { if let Event::Key(key) = event::read()? {
match key.code { match key.code {
KeyCode::Up => { KeyCode::Up => {
if selected > 0 { if selected > 0 {
selected -= 1; selected -= 1
}
} }
} KeyCode::Down => {
KeyCode::Down => { if selected < menu_items.len() - 1 {
if selected < menu_items.len() - 1 { selected += 1
selected += 1; }
} }
} KeyCode::Enter => match selected {
KeyCode::Enter => {
match selected {
0 => { 0 => {
// Start downloader
disable_raw_mode()?; disable_raw_mode()?;
execute!( execute!(
terminal.backend_mut(), terminal.backend_mut(),
LeaveAlternateScreen, LeaveAlternateScreen,
DisableMouseCapture DisableMouseCapture
)?; )?;
super::start_downloader()?; // call your downloader function run_downloader_ui(&mut terminal)?; // Added &mut here
return Ok(()); return Ok(());
} }
1 => { 1 => break,
break; // Exit
}
_ => {} _ => {}
} },
KeyCode::Esc => break,
_ => {}
} }
KeyCode::Esc => break,
_ => {}
} }
} }
} }
// Restore terminal
disable_raw_mode()?; disable_raw_mode()?;
execute!( execute!(
terminal.backend_mut(), terminal.backend_mut(),
@ -102,3 +107,62 @@ pub fn tui_menu() -> Result<(), Box<dyn Error>> {
)?; )?;
Ok(()) Ok(())
} }
fn run_downloader_ui(
terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
) -> Result<(), Box<dyn Error>> {
// Dynamically get the download list
let wget_string = wget_list::get_wget_list()?;
let files: Vec<String> = wget_string.lines().map(|s| s.to_string()).collect();
let mut progress: Vec<f64> = vec![0.0; files.len()];
// Example: simulate progress
for (i, _file) in files.iter().enumerate() {
for p in 0..=100 {
progress[i] = p as f64;
terminal.draw(|f| {
let size = f.size();
let chunks = Layout::default()
.direction(Direction::Vertical)
.margin(2)
.constraints(
files
.iter()
.map(|_| Constraint::Length(3))
.collect::<Vec<_>>(),
)
.split(size);
for (idx, &prog) in progress.iter().enumerate() {
let gauge = Gauge::default()
.block(
Block::default()
.title(files[idx].as_str())
.borders(Borders::ALL),
) // Changed to .as_str()
.gauge_style(Style::default().fg(Color::Green).bg(Color::Black))
.percent(prog as u16);
f.render_widget(gauge, chunks[idx]);
}
})?;
std::thread::sleep(Duration::from_millis(20)); // simulate download
}
}
terminal.draw(|f| {
let size = f.size();
let paragraph = Paragraph::new("Download completed! Press any key to return.")
.block(Block::default().borders(Borders::ALL).title("Status"));
f.render_widget(paragraph, size);
})?;
loop {
if let Event::Key(_) = event::read()? {
break;
}
}
Ok(())
}