Compare commits
2 Commits
ef19940418
...
7ccf7f48a9
Author | SHA1 | Date |
---|---|---|
~erin | 7ccf7f48a9 | |
~erin | 09ccbe9cd4 |
|
@ -15,6 +15,8 @@ A custom configuration file can be passed as an argument, and arguments will ove
|
|||
|
||||
`s` - Stop
|
||||
|
||||
`Tab` - Swap through search sections
|
||||
|
||||
`i` - Insert mode (search)
|
||||
|
||||
`<esc>` - Return to normal mode
|
||||
|
|
119
src/main.rs
119
src/main.rs
|
@ -25,7 +25,7 @@ use paris::{error, info};
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
mod structs;
|
||||
use structs::{App, InputMode, StatefulList, Blocks, SongList};
|
||||
use structs::{App, InputMode, StatefulList, Blocks, SongList, Search, ArtistList};
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
struct Config {
|
||||
|
@ -171,10 +171,10 @@ fn run_app<B: Backend>(
|
|||
loop {
|
||||
terminal.draw(|f| ui(f, &mut app))?;
|
||||
|
||||
|
||||
let timeout = tick_rate
|
||||
.checked_sub(last_tick.elapsed())
|
||||
.unwrap_or_else(|| Duration::from_millis(1));
|
||||
|
||||
if crossterm::event::poll(timeout)? {
|
||||
if let Event::Key(key) = event::read()? {
|
||||
match app.input_mode {
|
||||
|
@ -186,19 +186,55 @@ fn run_app<B: Backend>(
|
|||
KeyCode::Char('s') => app.mpd_client.stop().unwrap(),
|
||||
KeyCode::Tab => app.switch_block(),
|
||||
KeyCode::Char('l') => {
|
||||
match app.songs.choose() {
|
||||
Some(s) => {
|
||||
match app.mpd_client.clear() {
|
||||
Ok(..) => {},
|
||||
Err(e) => error!("Could not clear queue: {}", e),
|
||||
match app.selected_block {
|
||||
Blocks::Songs => {
|
||||
match app.songs.choose() {
|
||||
Some(s) => {
|
||||
match app.mpd_client.clear() {
|
||||
Ok(..) => {},
|
||||
Err(e) => error!("Could not clear queue: {}", e),
|
||||
}
|
||||
match app.mpd_client.push(s) {
|
||||
Ok(..) => {},
|
||||
Err(e) => error!("Cannot play song! {}", e),
|
||||
}
|
||||
app.mpd_client.play().unwrap();
|
||||
},
|
||||
None => {},
|
||||
}
|
||||
match app.mpd_client.push(s) {
|
||||
Ok(..) => {},
|
||||
Err(e) => error!("Cannot play song! {}", e),
|
||||
}
|
||||
app.mpd_client.play().unwrap();
|
||||
},
|
||||
None => {},
|
||||
Blocks::Artists => {
|
||||
// match app.artists.choose() {
|
||||
// Some(s) => {
|
||||
// match app.mpd_client.clear() {
|
||||
// Ok(..) => {},
|
||||
// Err(e) => error!("Could not clear queue: {}", e),
|
||||
// }
|
||||
// match app.mpd_client.push(s) {
|
||||
// Ok(..) => {},
|
||||
// Err(e) => error!("Cannot play song! {}", e),
|
||||
// }
|
||||
// app.mpd_client.play().unwrap();
|
||||
// },
|
||||
// None => {},
|
||||
// }
|
||||
},
|
||||
Blocks::Albums => {
|
||||
// match app.albums.choose() {
|
||||
// Some(s) => {
|
||||
// match app.mpd_client.clear() {
|
||||
// Ok(..) => {},
|
||||
// Err(e) => error!("Could not clear queue: {}", e),
|
||||
// }
|
||||
// match app.mpd_client.push(s) {
|
||||
// Ok(..) => {},
|
||||
// Err(e) => error!("Cannot play song! {}", e),
|
||||
// }
|
||||
// app.mpd_client.play().unwrap();
|
||||
// },
|
||||
// None => {},
|
||||
// }
|
||||
},
|
||||
}
|
||||
},
|
||||
KeyCode::Char('h') => {
|
||||
|
@ -233,65 +269,26 @@ fn run_app<B: Backend>(
|
|||
Some(r) => r,
|
||||
None => "",
|
||||
};
|
||||
app.last_songs = match app.mpd_client.search(&Query::new().and(Term::File, last_results), (0,50)) {
|
||||
Ok(s) => {
|
||||
let mut results: Vec<(String, usize, Option<Song>)> = vec![];
|
||||
let mut x = 0;
|
||||
for i in s {
|
||||
let name = match i.title.clone() {
|
||||
Some(n) => n,
|
||||
None => "<unnamed>".to_string(),
|
||||
};
|
||||
results.push((name, x, Some(i.clone())));
|
||||
x+=1;
|
||||
}
|
||||
results
|
||||
},
|
||||
Err(e) => vec![("<no results>".to_string(), 0, None)],
|
||||
};
|
||||
app.last_songs = app.songs.mpd_search(&mut app.mpd_client, last_results.to_string(), (0,50));
|
||||
app.last_artists = app.artists.mpd_search(&mut app.mpd_client, last_results.to_string(), (0,50));
|
||||
app.artists = ArtistList::with_items(app.last_artists.clone());
|
||||
app.songs = SongList::with_items(app.last_songs.clone());
|
||||
app.input_mode = InputMode::Normal;
|
||||
}
|
||||
KeyCode::Char(c) => {
|
||||
app.input.push(c);
|
||||
let results = app.input.clone();
|
||||
app.last_songs = match app.mpd_client.search(&Query::new().and(Term::File, results), (0,50)) {
|
||||
Ok(s) => {
|
||||
let mut results: Vec<(String, usize, Option<Song>)> = vec![];
|
||||
let mut x = 0;
|
||||
for i in s {
|
||||
let name = match i.title.clone() {
|
||||
Some(n) => n,
|
||||
None => "<unnamed>".to_string(),
|
||||
};
|
||||
results.push((name, x, Some(i.clone())));
|
||||
x+=1;
|
||||
}
|
||||
results
|
||||
},
|
||||
Err(e) => vec![("<no results>".to_string(), 0, None)],
|
||||
};
|
||||
app.last_songs = app.songs.mpd_search(&mut app.mpd_client, results.to_string(), (0,50));
|
||||
app.last_artists = app.artists.mpd_search(&mut app.mpd_client, results.to_string(), (0,50));
|
||||
app.artists = ArtistList::with_items(app.last_artists.clone());
|
||||
app.songs = SongList::with_items(app.last_songs.clone());
|
||||
}
|
||||
KeyCode::Backspace => {
|
||||
app.input.pop();
|
||||
let results = app.input.clone();
|
||||
app.last_songs = match app.mpd_client.search(&Query::new().and(Term::File, results), (0,50)) {
|
||||
Ok(s) => {
|
||||
let mut results: Vec<(String, usize, Option<Song>)> = vec![];
|
||||
let mut x = 0;
|
||||
for i in s {
|
||||
let name = match i.title.clone() {
|
||||
Some(n) => n,
|
||||
None => "<unnamed>".to_string(),
|
||||
};
|
||||
results.push((name, x, Some(i.clone())));
|
||||
x+=1;
|
||||
}
|
||||
results
|
||||
},
|
||||
Err(e) => vec![("<no results>".to_string(), 0, None)],
|
||||
};
|
||||
app.last_songs = app.songs.mpd_search(&mut app.mpd_client, results.to_string(), (0,50));
|
||||
app.last_artists = app.artists.mpd_search(&mut app.mpd_client, results.to_string(), (0,50));
|
||||
app.artists = ArtistList::with_items(app.last_artists.clone());
|
||||
app.songs = SongList::with_items(app.last_songs.clone());
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -4,7 +4,14 @@ use tui::widgets::ListState;
|
|||
use paris::error;
|
||||
use std::process::exit;
|
||||
|
||||
use mpd::song::Song;
|
||||
use mpd::{song::Song, Query, Term};
|
||||
|
||||
pub trait Search {
|
||||
type Item;
|
||||
|
||||
fn mpd_search(&self, client: &mut Client, query: String, range: (u32, u32)) -> Vec<Self::Item>;
|
||||
fn fuzzy_search(&self, client: &Client, query: String, range: (u32, u32)) -> Vec<Self::Item>;
|
||||
}
|
||||
|
||||
pub trait StatefulList {
|
||||
type Item;
|
||||
|
@ -23,6 +30,34 @@ pub struct SongList {
|
|||
pub items: Vec<(String, usize, Option<Song>)>,
|
||||
}
|
||||
|
||||
impl Search for SongList {
|
||||
type Item = (String, usize, Option<Song>);
|
||||
|
||||
fn mpd_search(&self, client: &mut Client, query: String, range: (u32, u32)) -> Vec<Self::Item> {
|
||||
match client.search(&Query::new().and(Term::File, query), range) {
|
||||
Ok(s) => {
|
||||
let mut results: Vec<(String, usize, Option<Song>)> = vec![];
|
||||
let mut x = 0;
|
||||
for i in s {
|
||||
let name = match i.title.clone() {
|
||||
Some(n) => n,
|
||||
None => "<unnamed>".to_string(),
|
||||
};
|
||||
results.push((name, x, Some(i.clone())));
|
||||
x += 1;
|
||||
}
|
||||
results
|
||||
},
|
||||
Err(e) => vec![("<no results>".to_string(), 0, None)],
|
||||
}
|
||||
}
|
||||
|
||||
fn fuzzy_search(&self, client: &Client, query: String, range: (u32, u32)) -> Vec<Self::Item> {
|
||||
error!("Unimplemented!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
impl StatefulList for SongList {
|
||||
type Item = (String, usize, Option<Song>);
|
||||
type List = SongList;
|
||||
|
@ -83,6 +118,31 @@ pub struct ArtistList {
|
|||
pub items: Vec<(String, usize)>,
|
||||
}
|
||||
|
||||
impl Search for ArtistList {
|
||||
type Item = (String, usize);
|
||||
|
||||
fn mpd_search(&self, client: &mut Client, query: String, range: (u32, u32)) -> Vec<Self::Item> {
|
||||
match client.list(&Term::Tag(std::borrow::Cow::Borrowed("AlbumArtist")), &Query::new().and(Term::Any, query)) {
|
||||
Ok(s) => {
|
||||
let mut results: Vec<(String, usize)> = vec![];
|
||||
let mut x = 0;
|
||||
for i in s {
|
||||
error!("{}", i);
|
||||
results.push((i, x));
|
||||
x += 1;
|
||||
}
|
||||
results
|
||||
},
|
||||
Err(e) => vec![("<no results>".to_string(), 0)],
|
||||
}
|
||||
}
|
||||
|
||||
fn fuzzy_search(&self, client: &Client, query: String, range: (u32, u32)) -> Vec<Self::Item> {
|
||||
error!("Unimplemented!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
impl StatefulList for ArtistList {
|
||||
type Item = (String, usize);
|
||||
type List = ArtistList;
|
||||
|
|
Loading…
Reference in New Issue