Formatting
parent
bfbc791a7b
commit
98884cac19
103
src/main.rs
103
src/main.rs
|
@ -4,30 +4,29 @@ use crossterm::{
|
|||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||
};
|
||||
use std::{
|
||||
error::Error,
|
||||
io,
|
||||
env,
|
||||
fs,
|
||||
error::Error,
|
||||
fs, io,
|
||||
path::PathBuf,
|
||||
time::{Duration, Instant},
|
||||
process::exit,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use tui::{
|
||||
backend::{Backend, CrosstermBackend},
|
||||
layout::{Alignment, Constraint, Direction, Layout},
|
||||
style::{Color, Modifier, Style},
|
||||
text::{Span, Spans},
|
||||
widgets::{Block, Paragraph, Wrap, BorderType, Borders, Gauge, List, ListItem, ListState},
|
||||
widgets::{Block, BorderType, Borders, Gauge, List, ListItem, ListState, Paragraph, Wrap},
|
||||
Frame, Terminal,
|
||||
};
|
||||
|
||||
use paris::{info, error};
|
||||
use clap::{Parser, Subcommand, ValueEnum};
|
||||
use paris::{error, info};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use toml::Table;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
mod structs;
|
||||
use structs::{App, StatefulList, InputMode};
|
||||
use structs::{App, InputMode, StatefulList};
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
struct Config {
|
||||
|
@ -64,12 +63,10 @@ enum Commands {
|
|||
Pause,
|
||||
}
|
||||
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
// Parse arguments
|
||||
let args = Args::parse();
|
||||
|
||||
|
||||
let mut default_config = dirs::config_dir().unwrap();
|
||||
default_config.push("xenmotif");
|
||||
default_config.push("config.toml");
|
||||
|
@ -95,7 +92,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
|
||||
info!("Created new config file at {}", &default_config.display());
|
||||
exit(0);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
let config: Config = match toml::from_str(&config_contents) {
|
||||
|
@ -103,7 +100,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
Err(e) => {
|
||||
error!("Couldn't parse config file! {}", e);
|
||||
exit(1);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
let port = match args.port {
|
||||
|
@ -126,16 +123,16 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
Some(Commands::Stop) => {
|
||||
app.mpd_client.stop().unwrap();
|
||||
exit(0);
|
||||
},
|
||||
}
|
||||
Some(Commands::Play) => {
|
||||
app.mpd_client.play().unwrap();
|
||||
exit(0);
|
||||
},
|
||||
}
|
||||
Some(Commands::Pause) => {
|
||||
app.mpd_client.pause(true).unwrap();
|
||||
exit(0);
|
||||
}
|
||||
None => {},
|
||||
None => {}
|
||||
}
|
||||
|
||||
// setup terminal
|
||||
|
@ -166,7 +163,11 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App, tick_rate: Duration) -> io::Result<()> {
|
||||
fn run_app<B: Backend>(
|
||||
terminal: &mut Terminal<B>,
|
||||
mut app: App,
|
||||
tick_rate: Duration,
|
||||
) -> io::Result<()> {
|
||||
let mut last_tick = Instant::now();
|
||||
loop {
|
||||
terminal.draw(|f| ui(f, &mut app))?;
|
||||
|
@ -190,16 +191,16 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App, tick_rate: Dura
|
|||
InputMode::Editing => match key.code {
|
||||
KeyCode::Enter => {
|
||||
app.messages.push(app.input.drain(..).collect());
|
||||
},
|
||||
}
|
||||
KeyCode::Char(c) => {
|
||||
app.input.push(c);
|
||||
},
|
||||
}
|
||||
KeyCode::Backspace => {
|
||||
app.input.pop();
|
||||
},
|
||||
}
|
||||
KeyCode::Esc => {
|
||||
app.input_mode = InputMode::Normal;
|
||||
},
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
|
@ -308,7 +309,7 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
|
|||
let duration = match song.duration {
|
||||
Some(s) => {
|
||||
let minutes = s.num_minutes();
|
||||
let seconds = s.num_seconds() - minutes*60;
|
||||
let seconds = s.num_seconds() - minutes * 60;
|
||||
|
||||
let s_seconds;
|
||||
if seconds < 10 {
|
||||
|
@ -317,13 +318,13 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
|
|||
s_seconds = format!("{}", seconds);
|
||||
}
|
||||
format!("{}:{}", minutes, s_seconds)
|
||||
},
|
||||
}
|
||||
None => "none".to_string(),
|
||||
};
|
||||
let elapsed = match mpd_status.time {
|
||||
Some(t) => {
|
||||
let minutes = t.0.num_minutes();
|
||||
let seconds = t.0.num_seconds() - minutes*60;
|
||||
let seconds = t.0.num_seconds() - minutes * 60;
|
||||
|
||||
let s_seconds;
|
||||
if seconds < 10 {
|
||||
|
@ -332,27 +333,34 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
|
|||
s_seconds = format!("{}", seconds);
|
||||
}
|
||||
format!("{}:{}", minutes, s_seconds)
|
||||
},
|
||||
}
|
||||
None => "none".to_string(),
|
||||
};
|
||||
info.push(Spans::from(Span::styled(format!("({}/{})", elapsed, duration), Style::default())));
|
||||
info.push(Spans::from(Span::styled(
|
||||
format!("({}/{})", elapsed, duration),
|
||||
Style::default(),
|
||||
)));
|
||||
info
|
||||
},
|
||||
None => vec![Spans::from(Span::styled("Not Playing", Style::default().fg(Color::Red)))],
|
||||
}
|
||||
None => vec![Spans::from(Span::styled(
|
||||
"Not Playing",
|
||||
Style::default().fg(Color::Red),
|
||||
))],
|
||||
};
|
||||
|
||||
let song = Paragraph::new(song_text).block(
|
||||
Block::default()
|
||||
.title(vec![
|
||||
Span::styled("──┤ ", Style::default().fg(Color::White)),
|
||||
Span::raw(title),
|
||||
Span::styled(" ├──", Style::default().fg(Color::White)),
|
||||
])
|
||||
.title_alignment(Alignment::Center)
|
||||
)
|
||||
let song = Paragraph::new(song_text)
|
||||
.block(
|
||||
Block::default()
|
||||
.title(vec![
|
||||
Span::styled("──┤ ", Style::default().fg(Color::White)),
|
||||
Span::raw(title),
|
||||
Span::styled(" ├──", Style::default().fg(Color::White)),
|
||||
])
|
||||
.title_alignment(Alignment::Center),
|
||||
)
|
||||
.style(Style::default())
|
||||
.alignment(Alignment::Center)
|
||||
.wrap(Wrap { trim: true } );
|
||||
.wrap(Wrap { trim: true });
|
||||
f.render_widget(song, song_search[0]);
|
||||
|
||||
// Search
|
||||
|
@ -361,17 +369,14 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
|
|||
InputMode::Normal => Style::default(),
|
||||
InputMode::Editing => Style::default().fg(Color::Yellow),
|
||||
})
|
||||
.block(Block::default().borders(Borders::ALL).title("Search"));
|
||||
.block(Block::default().borders(Borders::ALL).title("Search"));
|
||||
f.render_widget(input, song_search[1]);
|
||||
match app.input_mode {
|
||||
InputMode::Normal =>
|
||||
{}
|
||||
InputMode::Editing => {
|
||||
f.set_cursor(
|
||||
song_search[1].x + app.input.len() as u16 + 1,
|
||||
song_search[1].y + 1,
|
||||
)
|
||||
}
|
||||
InputMode::Normal => {}
|
||||
InputMode::Editing => f.set_cursor(
|
||||
song_search[1].x + app.input.len() as u16 + 1,
|
||||
song_search[1].y + 1,
|
||||
),
|
||||
}
|
||||
|
||||
// Sort & View
|
||||
|
@ -420,10 +425,8 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
|
|||
let total = t.1.num_seconds() as f64;
|
||||
let result = played / total;
|
||||
result * 100.0
|
||||
},
|
||||
None => {
|
||||
0.0
|
||||
},
|
||||
}
|
||||
None => 0.0,
|
||||
};
|
||||
let timeline = Gauge::default()
|
||||
.block(Block::default().borders(Borders::NONE))
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
use mpd::Client;
|
||||
use tui::{
|
||||
widgets::{ListState},
|
||||
};
|
||||
use tui::widgets::ListState;
|
||||
|
||||
use paris::error;
|
||||
use std::process::exit;
|
||||
|
@ -68,9 +66,7 @@ pub struct App<'a> {
|
|||
impl<'a> App<'a> {
|
||||
pub fn new(port: u16, host: String) -> App<'a> {
|
||||
let client = match Client::connect(format!("{}:{}", host, port)) {
|
||||
Ok(conn) => {
|
||||
conn
|
||||
},
|
||||
Ok(conn) => conn,
|
||||
Err(e) => {
|
||||
error!("Could not connect to MPD daemon: {}", e);
|
||||
exit(1);
|
||||
|
@ -91,4 +87,3 @@ pub enum InputMode {
|
|||
Normal,
|
||||
Editing,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue