modified: src/main.rs
This commit is contained in:
parent
8edaec6b7a
commit
7e89009ab1
81
src/main.rs
81
src/main.rs
@ -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(())
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user