move queue into its own file, and optimize it
This commit is contained in:
parent
32a3c60471
commit
9c30356a3e
22
src/app.rs
22
src/app.rs
|
|
@ -3,8 +3,9 @@ use std::time::Duration;
|
||||||
use crate::browser::FileBrowser;
|
use crate::browser::FileBrowser;
|
||||||
use crate::connection::Connection;
|
use crate::connection::Connection;
|
||||||
use crate::list::ContentList;
|
use crate::list::ContentList;
|
||||||
|
use crate::queue::Queue;
|
||||||
use crate::ui::InputMode;
|
use crate::ui::InputMode;
|
||||||
use mpd::Client;
|
use mpd::{Client, Song};
|
||||||
|
|
||||||
// Application result type
|
// Application result type
|
||||||
pub type AppResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
pub type AppResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||||
|
|
@ -16,7 +17,7 @@ pub struct App {
|
||||||
pub running: bool,
|
pub running: bool,
|
||||||
pub conn: Connection,
|
pub conn: Connection,
|
||||||
pub browser: FileBrowser, // Directory browser
|
pub browser: FileBrowser, // Directory browser
|
||||||
pub queue_list: ContentList<String>, // Stores the current playing queue
|
pub queue_list: Queue, // Stores the current playing queue
|
||||||
pub pl_list: ContentList<String>, // Stores list of playlists
|
pub pl_list: ContentList<String>, // Stores list of playlists
|
||||||
pub selected_tab: SelectedTab, // Used to switch between tabs
|
pub selected_tab: SelectedTab, // Used to switch between tabs
|
||||||
|
|
||||||
|
|
@ -33,6 +34,8 @@ pub struct App {
|
||||||
pub append_list: ContentList<String>,
|
pub append_list: ContentList<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum SelectedTab {
|
pub enum SelectedTab {
|
||||||
DirectoryBrowser,
|
DirectoryBrowser,
|
||||||
|
|
@ -43,7 +46,7 @@ pub enum SelectedTab {
|
||||||
impl App {
|
impl App {
|
||||||
pub fn builder(addrs: &str) -> AppResult<Self> {
|
pub fn builder(addrs: &str) -> AppResult<Self> {
|
||||||
let mut conn = Connection::new(addrs).unwrap();
|
let mut conn = Connection::new(addrs).unwrap();
|
||||||
let mut queue_list = ContentList::new();
|
let mut queue_list = Queue::new();
|
||||||
let mut pl_list = ContentList::new();
|
let mut pl_list = ContentList::new();
|
||||||
pl_list.list = Self::get_playlist(&mut conn.conn)?;
|
pl_list.list = Self::get_playlist(&mut conn.conn)?;
|
||||||
|
|
||||||
|
|
@ -78,7 +81,7 @@ impl App {
|
||||||
self.running = false;
|
self.running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_queue(conn: &mut Connection, vec: &mut Vec<String>) {
|
pub fn get_queue(conn: &mut Connection, vec: &mut Vec<Song>) {
|
||||||
// conn.conn.queue().unwrap().into_iter().for_each(|x| {
|
// conn.conn.queue().unwrap().into_iter().for_each(|x| {
|
||||||
// if let Some(title) = x.title {
|
// if let Some(title) = x.title {
|
||||||
// if let Some(artist) = x.artist {
|
// if let Some(artist) = x.artist {
|
||||||
|
|
@ -91,7 +94,8 @@ impl App {
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
conn.conn.queue().unwrap().into_iter().for_each(|x| {
|
conn.conn.queue().unwrap().into_iter().for_each(|x| {
|
||||||
vec.push(x.file);
|
// vec.push(x.title.unwrap());
|
||||||
|
vec.push(x);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,7 +128,7 @@ impl App {
|
||||||
|
|
||||||
let mut status = false;
|
let mut status = false;
|
||||||
for (i, song) in self.queue_list.list.clone().iter().enumerate() {
|
for (i, song) in self.queue_list.list.clone().iter().enumerate() {
|
||||||
if song.contains(file) {
|
if song.file.contains(file) {
|
||||||
self.conn.conn.delete(i as u32).unwrap();
|
self.conn.conn.delete(i as u32).unwrap();
|
||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
|
|
@ -150,11 +154,11 @@ impl App {
|
||||||
.queue_list
|
.queue_list
|
||||||
.list
|
.list
|
||||||
.get(self.queue_list.index)
|
.get(self.queue_list.index)
|
||||||
.unwrap()
|
.unwrap().file
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
for (i, song) in self.queue_list.list.clone().iter().enumerate() {
|
for (i, song) in self.queue_list.list.clone().iter().enumerate() {
|
||||||
if song.contains(&file) {
|
if song.file.contains(&file) {
|
||||||
self.conn.conn.delete(i as u32).unwrap();
|
self.conn.conn.delete(i as u32).unwrap();
|
||||||
if self.queue_list.index == self.queue_list.list.len() - 1
|
if self.queue_list.index == self.queue_list.list.len() - 1
|
||||||
&& self.queue_list.index != 0
|
&& self.queue_list.index != 0
|
||||||
|
|
@ -203,7 +207,7 @@ impl App {
|
||||||
// .get(0)
|
// .get(0)
|
||||||
// .unwrap()
|
// .unwrap()
|
||||||
// .clone();
|
// .clone();
|
||||||
let index = self.queue_list.list.iter().position(|x| x.contains(path));
|
let index = self.queue_list.list.iter().position(|x| x.file.contains(path));
|
||||||
|
|
||||||
if index.is_some() {
|
if index.is_some() {
|
||||||
self.conn.conn.switch(index.unwrap() as u32)?;
|
self.conn.conn.switch(index.unwrap() as u32)?;
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,13 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
|
||||||
.queue_list
|
.queue_list
|
||||||
.list
|
.list
|
||||||
.iter()
|
.iter()
|
||||||
.map(|f| f.as_str())
|
.map(|f| f.file.as_str())
|
||||||
.collect::<Vec<&str>>();
|
.collect::<Vec<&str>>();
|
||||||
let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list);
|
let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list);
|
||||||
let res = res.iter().map(|(x, _)| *x).collect::<Vec<&str>>();
|
let res = res.iter().map(|(x, _)| *x).collect::<Vec<&str>>();
|
||||||
|
|
||||||
for (i, item) in app.queue_list.list.iter().enumerate() {
|
for (i, item) in app.queue_list.list.iter().enumerate() {
|
||||||
if item.contains(res.get(0).unwrap()) {
|
if item.file.contains(res.get(0).unwrap()) {
|
||||||
app.queue_list.index = i;
|
app.queue_list.index = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -162,7 +162,7 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
|
||||||
match app.selected_tab {
|
match app.selected_tab {
|
||||||
SelectedTab::Queue => {
|
SelectedTab::Queue => {
|
||||||
s_index = app.queue_list.index;
|
s_index = app.queue_list.index;
|
||||||
let short_path = app.queue_list.list.get(s_index).unwrap().to_string();
|
let short_path = &app.queue_list.list.get(s_index).unwrap().file;
|
||||||
|
|
||||||
if let Some(full_path) = app.conn.get_full_path(&short_path) {
|
if let Some(full_path) = app.conn.get_full_path(&short_path) {
|
||||||
let song = app.conn.get_song_with_only_filename(&full_path);
|
let song = app.conn.get_song_with_only_filename(&full_path);
|
||||||
|
|
|
||||||
|
|
@ -24,3 +24,6 @@ pub mod handler;
|
||||||
|
|
||||||
/// Application
|
/// Application
|
||||||
pub mod app;
|
pub mod app;
|
||||||
|
|
||||||
|
/// The Queue structure
|
||||||
|
pub mod queue;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
use mpd::Song;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Queue {
|
||||||
|
pub list: Vec<Song>,
|
||||||
|
pub index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Queue {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Queue {
|
||||||
|
list: Vec::new(),
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go to next item in list
|
||||||
|
pub fn next(&mut self) {
|
||||||
|
let len = self.list.len();
|
||||||
|
if len != 0 {
|
||||||
|
if self.index < len - 1 {
|
||||||
|
self.index += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Go to previous item in list
|
||||||
|
pub fn prev(&mut self) {
|
||||||
|
if self.index != 0 {
|
||||||
|
self.index -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset_index(&mut self) {
|
||||||
|
self.index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/ui.rs
60
src/ui.rs
|
|
@ -1,7 +1,6 @@
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::app::{App, SelectedTab};
|
use crate::app::{App, SelectedTab};
|
||||||
use mpd::Song;
|
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
widgets::{block::Title, *},
|
widgets::{block::Title, *},
|
||||||
|
|
@ -77,28 +76,22 @@ fn draw_directory_browser(frame: &mut Frame, app: &mut App, size: Rect) {
|
||||||
|
|
||||||
let mut status: bool = false;
|
let mut status: bool = false;
|
||||||
for sn in app.queue_list.list.iter() {
|
for sn in app.queue_list.list.iter() {
|
||||||
if sn.contains(s) {
|
if sn.file.contains(s) {
|
||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let row = Row::new(vec![
|
||||||
|
Cell::from(artist),
|
||||||
|
Cell::from(track.green()),
|
||||||
|
Cell::from(title),
|
||||||
|
Cell::from(album.cyan()),
|
||||||
|
Cell::from(time.to_string().magenta()),
|
||||||
|
]);
|
||||||
|
|
||||||
if status {
|
if status {
|
||||||
let row = Row::new(vec![
|
|
||||||
Cell::from(artist),
|
|
||||||
Cell::from(track.green()),
|
|
||||||
Cell::from(title),
|
|
||||||
Cell::from(album),
|
|
||||||
Cell::from(time.to_string().magenta()),
|
|
||||||
]);
|
|
||||||
row.magenta().bold()
|
row.magenta().bold()
|
||||||
} else {
|
} else {
|
||||||
let row = Row::new(vec![
|
|
||||||
Cell::from(artist),
|
|
||||||
Cell::from(track.green()),
|
|
||||||
Cell::from(title),
|
|
||||||
Cell::from(album),
|
|
||||||
Cell::from(time.to_string().magenta()),
|
|
||||||
]);
|
|
||||||
row
|
row
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -153,17 +146,8 @@ fn draw_directory_browser(frame: &mut Frame, app: &mut App, size: Rect) {
|
||||||
|
|
||||||
/// draws playing queue
|
/// draws playing queue
|
||||||
fn draw_queue(frame: &mut Frame, app: &mut App, size: Rect) {
|
fn draw_queue(frame: &mut Frame, app: &mut App, size: Rect) {
|
||||||
let rows = app.queue_list.list.iter().map(|s| {
|
let rows = app.queue_list.list.iter().map(|song| {
|
||||||
// metadata
|
// metadata
|
||||||
let song = app
|
|
||||||
.conn
|
|
||||||
.conn
|
|
||||||
.lsinfo(&Song {
|
|
||||||
file: app.conn.get_full_path(&s).unwrap_or_default(),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.unwrap_or_default();
|
|
||||||
let song = song.get(0).unwrap();
|
|
||||||
let title = song.clone().title.unwrap_or_else(|| song.clone().file);
|
let title = song.clone().title.unwrap_or_else(|| song.clone().file);
|
||||||
let artist = song.clone().artist.unwrap_or_default().cyan();
|
let artist = song.clone().artist.unwrap_or_default().cyan();
|
||||||
let album = song
|
let album = song
|
||||||
|
|
@ -184,23 +168,17 @@ fn draw_queue(frame: &mut Frame, app: &mut App, size: Rect) {
|
||||||
|
|
||||||
let time = App::format_time(song.clone().duration.unwrap_or_else(|| Duration::new(0, 0)));
|
let time = App::format_time(song.clone().duration.unwrap_or_else(|| Duration::new(0, 0)));
|
||||||
|
|
||||||
if s.contains(&app.conn.current_song.file) {
|
let row = Row::new(vec![
|
||||||
let row = Row::new(vec![
|
Cell::from(artist),
|
||||||
Cell::from(artist),
|
Cell::from(track.green()),
|
||||||
Cell::from(track.green()),
|
Cell::from(title),
|
||||||
Cell::from(title),
|
Cell::from(album.cyan()),
|
||||||
Cell::from(album),
|
Cell::from(time.to_string().magenta()),
|
||||||
Cell::from(time.to_string().magenta()),
|
]);
|
||||||
]);
|
|
||||||
|
if song.file.contains(&app.conn.current_song.file) {
|
||||||
row.magenta().bold()
|
row.magenta().bold()
|
||||||
} else {
|
} else {
|
||||||
let row = Row::new(vec![
|
|
||||||
Cell::from(artist),
|
|
||||||
Cell::from(track.green()),
|
|
||||||
Cell::from(title),
|
|
||||||
Cell::from(album),
|
|
||||||
Cell::from(time.to_string().magenta()),
|
|
||||||
]);
|
|
||||||
row
|
row
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Reference in New Issue