From b238851a5666233afa89db00df4d94c5e1ebe70f Mon Sep 17 00:00:00 2001 From: 140bpmdubstep Date: Mon, 2 Nov 2020 12:26:42 +0400 Subject: [PATCH] Playback implementation, closes #21 and closes #19 --- src/bc_core/album_parsing.rs | 8 +-- src/bc_core/queue.rs | 15 ++++-- src/bop_interfaces/listbox.rs | 11 ++-- src/bop_interfaces/statebar.rs | 4 +- src/bop_interfaces/tui.rs | 95 ++++++++++++++++++++++++++++------ src/main.rs | 4 +- 6 files changed, 104 insertions(+), 33 deletions(-) diff --git a/src/bc_core/album_parsing.rs b/src/bc_core/album_parsing.rs index 51a2442..1460d3d 100644 --- a/src/bc_core/album_parsing.rs +++ b/src/bc_core/album_parsing.rs @@ -35,18 +35,20 @@ pub fn get_album(url: &str) -> Option { file.write_all(json.as_bytes()).unwrap(); */ + log::info!("{}", json); + let data: Album = serde_json::from_str(&json).unwrap(); Some(data) } pub fn parse(html_code: &str) -> Option { - let start = "var TralbumData = {"; - let stop = "};"; + let start = "data-tralbum=\"{"; + let stop = "}\""; let album_data = &html_code[html_code.find(start)? + start.len() - 1..]; let album_data = &album_data[..=album_data.find(stop)?]; - let album_data_json = fix_json(album_data); + let album_data_json = fix_json(&album_data.replace(""", "\"")); Some(album_data_json) } diff --git a/src/bc_core/queue.rs b/src/bc_core/queue.rs index 3750906..1dafa60 100644 --- a/src/bc_core/queue.rs +++ b/src/bc_core/queue.rs @@ -1,3 +1,6 @@ +use core::fmt; +use std::{fmt::Display, time::Duration}; + use super::album_parsing; #[derive(Clone)] @@ -7,7 +10,7 @@ pub struct QueuedTrack { pub album: String, pub audio_url: String, pub album_url: String, - pub duration: f64, + pub duration: Duration, } impl Default for QueuedTrack { @@ -18,11 +21,17 @@ impl Default for QueuedTrack { audio_url: String::new(), album: String::new(), album_url: String::new(), - duration: 0.0, + duration: Duration::from_secs(0), } } } +impl Display for QueuedTrack { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} - {}", self.artist, self.title) + } +} + pub struct Queue<'a> { pub queue: Vec, pub shuffle: bool, @@ -98,7 +107,7 @@ impl<'a> Queue<'a> { // TODO: switch to normal error-handling and not this garbage that panic... audio_url: album_track.file.unwrap().mp3128, album_url: album_url.mp3128, - duration: album_track.duration.unwrap_or(0.0), + duration: Duration::from_secs_f64(album_track.duration.unwrap_or(0.0)), }; self.queue.push(pushed_track.clone()); } diff --git a/src/bop_interfaces/listbox.rs b/src/bop_interfaces/listbox.rs index e8c1b34..71635cc 100644 --- a/src/bop_interfaces/listbox.rs +++ b/src/bop_interfaces/listbox.rs @@ -7,16 +7,18 @@ pub struct ListBox { pub position: usize, pub screen: Screen, pub focused: bool, + pub description: String, } impl ListBox { - pub fn new(w: u16, h: u16, focused: bool) -> Self { + pub fn new>(w: u16, h: u16, focused: bool, description: S) -> Self { Self { display: Vec::new(), page: 0, position: 0, screen: Screen::new_empty(w as u32, h as u32), focused, + description: description.into() } } @@ -58,11 +60,8 @@ impl ListBox { self.screen.clear(); } - pub fn get_selected_item(&mut self, pos: usize) -> String { - self.display[(pos + (self.page * self.screen.get_height() as usize)) - .checked_sub(1) - .unwrap_or(0)] - .clone() + pub fn get_selected_idx(&mut self) -> usize { + self.position + (self.page * self.screen.get_height() as usize) } pub fn remove(&mut self, value: String) { diff --git a/src/bop_interfaces/statebar.rs b/src/bop_interfaces/statebar.rs index 615def6..1581884 100644 --- a/src/bop_interfaces/statebar.rs +++ b/src/bop_interfaces/statebar.rs @@ -19,7 +19,7 @@ impl StateBar { Self { header_text: BASE_HEADER.to_string(), - bottom_text: String::from("Loading..."), + bottom_text: String::from("Nothing playing..."), error: false, screen: Screen::new(cols.into(), 2), y: (rows as u32) - 2, @@ -33,7 +33,7 @@ impl StateBar { pub fn information(&mut self, item: &T) { self.error = false; - self.header_text = item.to_string(); + self.header_text = format!("{}{}", BASE_HEADER, item.to_string()); } pub fn draw(&mut self) -> &Screen { diff --git a/src/bop_interfaces/tui.rs b/src/bop_interfaces/tui.rs index 7ddf9c1..19d6e1e 100644 --- a/src/bop_interfaces/tui.rs +++ b/src/bop_interfaces/tui.rs @@ -1,6 +1,11 @@ -use std::time::Duration; +use std::{ + sync::{Arc, Mutex}, + time::Duration, +}; + +use crate::bc_core::{playback::Player, queue::Queue}; -use super::{listbox::ListBox, tui_structs::State, statebar::StateBar}; +use super::{listbox::ListBox, statebar::StateBar, tui_structs::State}; use console_engine::{ crossterm::{ event::{self, read}, @@ -11,20 +16,20 @@ use console_engine::{ const LIST_TAGS: usize = 0; const LIST_DISCOVER: usize = 1; -const LIST_QUEUE: usize = 3; - +const LIST_QUEUE: usize = 2; -fn setup_focus_at(id: usize, lbx: &mut Vec) { +fn setup_focus_at(id: usize, lbx: &mut Vec, bar: &mut StateBar) { for list in lbx.iter_mut() { list.focused = false; } lbx[id].focused = true; + bar.information(&lbx[id].description); } fn get_focus_at(lbx: &mut Vec) -> usize { for (id, list) in lbx.iter_mut().enumerate() { if list.focused { - return id + return id; } } 0 @@ -41,13 +46,22 @@ pub fn loadinterface(_args: Vec) -> Result<(), Box) -> Result<(), Box) -> Result<(), Box) -> Result<(), Box listboxes.len() - 1 { - setup_focus_at(LIST_TAGS, &mut listboxes); + setup_focus_at(LIST_TAGS, &mut listboxes, &mut bar); } else { - setup_focus_at(switch, &mut listboxes); + setup_focus_at(switch, &mut listboxes, &mut bar); } } if engine.is_key_pressed(KeyCode::F(1)) { - debug_overlay =! debug_overlay; + debug_overlay = !debug_overlay; } - match engine.get_resize() { Some((width, height)) => { for list in listboxes.iter_mut() { @@ -137,6 +177,27 @@ pub fn loadinterface(_args: Vec) -> Result<(), Box {} } + + // TODO: change this + match player.clone().try_lock().unwrap().get_time() { + Some(time) => { + if time + >= queue + .get_current_track() + .ok_or_else(|| { + bar.error(&"Queue is empty!".to_string()); + }) + .unwrap() + .duration + { + queue.next().unwrap(); + } + } + + None => { + // TODO: Loading + } + } } Ok(()) } diff --git a/src/main.rs b/src/main.rs index fd3d993..308d6aa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,11 +34,11 @@ fn main() -> Result<(), Box> { } match args[1].as_str() { - "cli" => tui::loadinterface(args)?, + "tui" => tui::loadinterface(args)?, _ => { eprintln!("error: Invalid arguments supplyed. Exiting"); println!("Allowed options:"); - println!("cli - TUI player mode"); + println!("tui - TUI player mode"); } } Ok(())