modified: src/main.rs

This commit is contained in:
Michael Wain 2025-02-09 19:03:22 +03:00
parent 8edaec6b7a
commit 7e89009ab1

View File

@ -1,17 +1,17 @@
use std::io; use std::{error::Error, io};
use color_eyre::Result; use color_eyre::Result;
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind}; use crossterm::{event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEvent, KeyEventKind}, execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}};
use ratatui::{buffer::Buffer, layout::Rect, style::Stylize, symbols::border, text::{Line, Text}, widgets::{Block, Paragraph, Widget}, DefaultTerminal, Frame}; use ratatui::{buffer::Buffer, layout::Rect, prelude::{Backend, CrosstermBackend}, style::Stylize, symbols::border, text::{Line, Text}, widgets::{Block, Paragraph, Widget}, DefaultTerminal, Frame, Terminal};
use tokio::sync::mpsc::{self, Receiver, Sender, UnboundedReceiver, UnboundedSender}; use tokio::sync::mpsc::{self, Receiver, Sender, UnboundedReceiver, UnboundedSender};
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
mod util; mod util;
#[derive(Debug)] #[derive(Debug, Clone)]
enum AppState { enum AppState {
IPodWait, IPodWait,
MainScreen, MainScreen(String),
SoundCloud, SoundCloud,
Youtube, Youtube,
Preferences Preferences
@ -68,7 +68,7 @@ impl Default for App {
} }
impl App { impl App {
pub fn run(&mut self, terminal: &mut DefaultTerminal) -> io::Result<()> { pub fn run<B: Backend>(&mut self, terminal: &mut Terminal<B>) -> io::Result<()> {
while !self.token.is_cancelled() { while !self.token.is_cancelled() {
terminal.draw(|frame| self.draw(frame))?; terminal.draw(|frame| self.draw(frame))?;
self.handle_events()?; self.handle_events()?;
@ -77,7 +77,7 @@ impl App {
} }
fn draw(&self, frame: &mut Frame) { fn draw(&self, frame: &mut Frame) {
frame.render_widget(self, frame.area()); frame.render_widget(self.state.clone(), frame.area());
} }
fn handle_events(&mut self) -> io::Result<()> { fn handle_events(&mut self) -> io::Result<()> {
@ -90,7 +90,7 @@ impl App {
if let Ok(event) = self.receiver.try_recv() { if let Ok(event) = self.receiver.try_recv() {
match event { match event {
AppEvent::IPodFound(path) => { AppEvent::IPodFound(path) => {
self.state = AppState::MainScreen; self.state = AppState::MainScreen(path);
}, },
AppEvent::IPodNotFound => { AppEvent::IPodNotFound => {
let _ = self.sender.send(AppEvent::SearchIPod); let _ = self.sender.send(AppEvent::SearchIPod);
@ -110,8 +110,38 @@ impl App {
fn exit(&mut self) { fn exit(&mut self) {
self.token.cancel(); self.token.cancel();
} }
}
fn render_waiting_screen(&self, area: Rect, buf: &mut Buffer) { impl AppState {
fn render_main_screen(area: Rect, buf: &mut Buffer, path: String) {
let title = Line::from(" Lyrica ".bold());
let instructions = Line::from(vec![
" Quit ".into(),
"<Q> ".red().bold(),
]);
let block = Block::bordered()
.title(title.centered())
.title_bottom(instructions.centered())
.border_set(border::ROUNDED);
let counter_text = Text::from(
vec![
Line::from(
vec![
"Found iPod...".into(),
path.blue().bold()
]
)
]
);
Paragraph::new(counter_text)
.centered()
.block(block)
.render(area, buf);
}
fn render_waiting_screen(area: Rect, buf: &mut Buffer) {
let title = Line::from(" Lyrica ".bold()); let title = Line::from(" Lyrica ".bold());
let instructions = Line::from(vec![ let instructions = Line::from(vec![
" Quit ".into(), " Quit ".into(),
@ -139,19 +169,36 @@ impl App {
} }
} }
impl Widget for &App { impl Widget for AppState {
fn render(self, area: Rect, buf: &mut Buffer) { fn render(self, area: Rect, buf: &mut Buffer) {
match self.state { match self {
AppState::IPodWait => self.render_waiting_screen(area, buf), AppState::IPodWait => AppState::render_waiting_screen(area, buf),
AppState::MainScreen(s) => AppState::render_main_screen(area, buf, s),
_ => {} _ => {}
} }
} }
} }
#[tokio::main] #[tokio::main]
async fn main() -> io::Result<()> { async fn main() -> Result<(), Box<dyn Error>> {
let mut terminal = ratatui::init(); enable_raw_mode()?;
let app_result = App::default().run(&mut terminal); let mut stderr = io::stderr(); // This is a special case. Normally using stdout is fine
ratatui::restore(); execute!(stderr, EnterAlternateScreen, EnableMouseCapture)?;
app_result let backend = CrosstermBackend::new(stderr);
let mut terminal = Terminal::new(backend)?;
// create app and run it
let mut app = App::default();
app.run(&mut terminal);
// restore terminal
disable_raw_mode()?;
execute!(
terminal.backend_mut(),
LeaveAlternateScreen,
DisableMouseCapture
)?;
terminal.show_cursor()?;
Ok(())
} }