User quit handling, playlist extending
This commit is contained in:
parent
85ae8d1624
commit
35184a76b9
6 changed files with 67 additions and 6 deletions
|
@ -8,6 +8,8 @@ use crate::utils::Error;
|
|||
#[derive(Deserialize)]
|
||||
pub struct Settings {
|
||||
pub subsonic: Subsonic,
|
||||
#[serde(default = "default_controls")]
|
||||
pub controls: Controls,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
@ -20,6 +22,15 @@ pub struct Subsonic {
|
|||
pub random_limit: i32,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Controls {
|
||||
pub quit: char,
|
||||
}
|
||||
|
||||
fn default_controls() -> Controls {
|
||||
Controls { quit: 'q' }
|
||||
}
|
||||
|
||||
fn default_random_limit() -> i32 {
|
||||
10
|
||||
}
|
||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -1,7 +1,11 @@
|
|||
use std::ops::Deref;
|
||||
use std::process::exit;
|
||||
|
||||
use std::sync::mpsc::{channel, Receiver};
|
||||
|
||||
use player::errors::PlayerError;
|
||||
use ssonic::response::PlayQueue;
|
||||
|
||||
mod audio;
|
||||
mod config;
|
||||
mod player;
|
||||
|
@ -22,6 +26,7 @@ fn init() -> Result<Receiver<utils::Error>, utils::Error> {
|
|||
api_event_chan,
|
||||
error_in.clone(),
|
||||
player_events_out,
|
||||
player_events_in,
|
||||
)?;
|
||||
Ok(error_out)
|
||||
}
|
||||
|
@ -36,8 +41,20 @@ fn main() {
|
|||
Ok(err_chan) => err_chan,
|
||||
};
|
||||
match err_chan.recv() {
|
||||
Err(_) => exit(0),
|
||||
Err(_) => {
|
||||
utils::restore();
|
||||
exit(0)
|
||||
}
|
||||
Ok(err) => {
|
||||
if let Some(e) = err.downcast_ref::<PlayerError>() {
|
||||
match e {
|
||||
PlayerError::UserQuit => {
|
||||
utils::restore();
|
||||
exit(0)
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
utils::restore();
|
||||
eprintln!("{}", err);
|
||||
exit(1)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#[derive(Debug)]
|
||||
pub enum PlayerError {
|
||||
PlaylistEmpty,
|
||||
UserQuit,
|
||||
}
|
||||
|
||||
impl std::error::Error for PlayerError {}
|
||||
|
@ -9,6 +10,7 @@ impl std::fmt::Display for PlayerError {
|
|||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::PlaylistEmpty => write!(f, "Playlist empty"),
|
||||
Self::UserQuit => write!(f, "User quit signalled"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use crate::{
|
|||
|
||||
pub enum PlayerEvent {
|
||||
AddSongList(Vec<Song>),
|
||||
UserQuit,
|
||||
}
|
||||
|
||||
pub struct Player {
|
||||
|
@ -26,6 +27,7 @@ pub struct Player {
|
|||
api_chan: Sender<APIEvent>,
|
||||
error_chan: Sender<Error>,
|
||||
player_chan: Receiver<PlayerEvent>,
|
||||
player_chan_in: Sender<PlayerEvent>,
|
||||
playlist: playlist::Playlist,
|
||||
}
|
||||
|
||||
|
@ -35,6 +37,7 @@ pub fn init(
|
|||
api_chan: Sender<APIEvent>,
|
||||
error_chan: Sender<Error>,
|
||||
player_chan: Receiver<PlayerEvent>,
|
||||
player_chan_in: Sender<PlayerEvent>,
|
||||
) -> Result<(), Error> {
|
||||
let terminal = ratatui::init();
|
||||
thread::spawn(move || {
|
||||
|
@ -45,6 +48,7 @@ pub fn init(
|
|||
api_chan,
|
||||
error_chan: error_chan.clone(),
|
||||
player_chan,
|
||||
player_chan_in,
|
||||
playlist: playlist::Playlist::new(),
|
||||
};
|
||||
match player.begin() {
|
||||
|
@ -59,6 +63,6 @@ pub fn init(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
mod errors;
|
||||
pub mod errors;
|
||||
mod player;
|
||||
mod playlist;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use std::{thread, time::Duration};
|
||||
use std::{sync::mpsc::TryRecvError, time::Duration};
|
||||
|
||||
use crossterm::event::{poll, read, Event, KeyCode};
|
||||
|
||||
use crate::{ssonic::APIEvent, utils::Error};
|
||||
|
||||
use super::Player;
|
||||
use super::{errors::PlayerError, Player, PlayerEvent};
|
||||
|
||||
impl Player {
|
||||
pub fn begin(&mut self) -> Result<(), Error> {
|
||||
|
@ -22,15 +24,36 @@ impl Player {
|
|||
self.handle_events()?;
|
||||
self.handle_inputs()?;
|
||||
self.update()?;
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_events(&mut self) -> Result<(), Error> {
|
||||
loop {
|
||||
let e = match self.player_chan.try_recv() {
|
||||
Err(err) if err == TryRecvError::Empty => break,
|
||||
Err(err) => return Err(Box::new(err)),
|
||||
Ok(x) => x,
|
||||
};
|
||||
match e {
|
||||
PlayerEvent::UserQuit => return Err(Box::new(PlayerError::UserQuit)),
|
||||
PlayerEvent::AddSongList(list) => self.playlist.append(list),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_inputs(&mut self) -> Result<(), Error> {
|
||||
if poll(Duration::from_millis(100))? {
|
||||
match read()? {
|
||||
Event::Key(e) => {
|
||||
if e.code == KeyCode::Char(self.settings.controls.quit) {
|
||||
self.player_chan_in.send(PlayerEvent::UserQuit)?
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::{borrow::BorrowMut, collections::VecDeque};
|
||||
|
||||
use crate::{ssonic::response::Song, utils::Error};
|
||||
|
||||
|
@ -16,6 +16,10 @@ impl Playlist {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn append(&mut self, list: Vec<Song>) {
|
||||
self.song_list.append(VecDeque::from(list).borrow_mut());
|
||||
}
|
||||
|
||||
pub fn new() -> Playlist {
|
||||
Playlist {
|
||||
song_list: VecDeque::new(),
|
||||
|
|
Loading…
Reference in a new issue