mirror of
https://github.com/Dangoware/dango-music-player.git
synced 2025-04-19 10:02:53 -05:00
Added proper functionality to the Queue. still missing the remove from queue function.
This commit is contained in:
parent
04ecd0e9d5
commit
87965ef6da
7 changed files with 174 additions and 56 deletions
|
@ -32,7 +32,7 @@ pub enum ControllerError {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move this to a different location to be used elsewhere
|
// TODO: move this to a different location to be used elsewhere
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum PlayerLocation {
|
pub enum PlayerLocation {
|
||||||
Test,
|
Test,
|
||||||
|
@ -73,6 +73,7 @@ pub enum PlayerCommand {
|
||||||
Play,
|
Play,
|
||||||
Enqueue(usize),
|
Enqueue(usize),
|
||||||
SetVolume(f64),
|
SetVolume(f64),
|
||||||
|
PlayNow(Uuid, PlayerLocation),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
@ -81,39 +82,45 @@ pub enum PlayerResponse {
|
||||||
NowPlaying(Song)
|
NowPlaying(Song)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, PartialOrd, Clone)]
|
||||||
pub enum LibraryCommand {
|
pub enum LibraryCommand {
|
||||||
Song(Uuid),
|
Song(Uuid),
|
||||||
AllSongs,
|
AllSongs,
|
||||||
GetLibrary,
|
GetLibrary,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum LibraryResponse {
|
pub enum LibraryResponse {
|
||||||
Song(Song),
|
Song(Song),
|
||||||
AllSongs(Vec<Song>),
|
AllSongs(Vec<Song>),
|
||||||
Library(MusicLibrary),
|
Library(MusicLibrary),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, PartialOrd, Clone)]
|
||||||
enum InnerLibraryCommand {
|
enum InnerLibraryCommand {
|
||||||
Song(Uuid),
|
Song(Uuid),
|
||||||
AllSongs,
|
AllSongs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
enum InnerLibraryResponse<'a> {
|
enum InnerLibraryResponse<'a> {
|
||||||
Song(&'a Song),
|
Song(&'a Song, usize),
|
||||||
AllSongs(&'a Vec<Song>),
|
AllSongs(&'a Vec<Song>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum QueueCommand {
|
pub enum QueueCommand {
|
||||||
Append(QueueItem<QueueSong, QueueAlbum>),
|
Append(QueueItem<QueueSong, QueueAlbum>, bool),
|
||||||
Next,
|
Next,
|
||||||
Prev,
|
Prev,
|
||||||
GetIndex(usize),
|
GetIndex(usize),
|
||||||
NowPlaying,
|
NowPlaying,
|
||||||
Get
|
Get,
|
||||||
|
Clear
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum QueueResponse {
|
pub enum QueueResponse {
|
||||||
Ok,
|
Ok,
|
||||||
Item(QueueItem<QueueSong, QueueAlbum>),
|
Item(QueueItem<QueueSong, QueueAlbum>),
|
||||||
|
@ -208,12 +215,14 @@ impl<'c, P: Player + Send + Sync> Controller<'c, P> {
|
||||||
let player = Arc::new(RwLock::new(P::new().unwrap()));
|
let player = Arc::new(RwLock::new(P::new().unwrap()));
|
||||||
|
|
||||||
let _player = player.clone();
|
let _player = player.clone();
|
||||||
|
let _inner_lib_mail = inner_lib_mail.0.clone();
|
||||||
scope
|
scope
|
||||||
.spawn(async move {
|
.spawn(async move {
|
||||||
Controller::<P>::player_command_loop(
|
Controller::<P>::player_command_loop(
|
||||||
_player,
|
_player,
|
||||||
player_mail.1,
|
player_mail.1,
|
||||||
queue_mail.0,
|
queue_mail.0,
|
||||||
|
_inner_lib_mail
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -256,6 +265,7 @@ impl<'c, P: Player + Send + Sync> Controller<'c, P> {
|
||||||
player: Arc<RwLock<P>>,
|
player: Arc<RwLock<P>>,
|
||||||
player_mail: MailMan<PlayerResponse, PlayerCommand>,
|
player_mail: MailMan<PlayerResponse, PlayerCommand>,
|
||||||
queue_mail: MailMan<QueueCommand, QueueResponse>,
|
queue_mail: MailMan<QueueCommand, QueueResponse>,
|
||||||
|
inner_lib_mail: MailMan<InnerLibraryCommand, InnerLibraryResponse<'c>>
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
while true {
|
while true {
|
||||||
|
@ -294,6 +304,39 @@ impl<'c, P: Player + Send + Sync> Controller<'c, P> {
|
||||||
};
|
};
|
||||||
player.write().unwrap().enqueue_next(uri).unwrap();
|
player.write().unwrap().enqueue_next(uri).unwrap();
|
||||||
let QueueItemType::Single(np_song) = item.item else { panic!("This is temporary, handle queueItemTypes at some point")};
|
let QueueItemType::Single(np_song) = item.item else { panic!("This is temporary, handle queueItemTypes at some point")};
|
||||||
|
|
||||||
|
// Append next song in library
|
||||||
|
inner_lib_mail.send(InnerLibraryCommand::AllSongs).await.unwrap();
|
||||||
|
|
||||||
|
let InnerLibraryResponse::AllSongs(songs) = inner_lib_mail.recv().await.unwrap() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
inner_lib_mail.send(InnerLibraryCommand::Song(np_song.song.uuid.clone())).await.unwrap();
|
||||||
|
let InnerLibraryResponse::Song(_, i) = inner_lib_mail.recv().await.unwrap() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
if let Some(song) = songs.get(i + 49) {
|
||||||
|
queue_mail.send(
|
||||||
|
QueueCommand::Append(
|
||||||
|
QueueItem::from_item_type(
|
||||||
|
QueueItemType::Single(
|
||||||
|
QueueSong {
|
||||||
|
song: song.clone(),
|
||||||
|
location: np_song.location
|
||||||
|
}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
).await
|
||||||
|
.unwrap();
|
||||||
|
let QueueResponse::Ok = queue_mail.recv().await.unwrap() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
println!("Library Empty");
|
||||||
|
}
|
||||||
|
|
||||||
player_mail.send(PlayerResponse::NowPlaying(np_song.song.clone())).await.unwrap();
|
player_mail.send(PlayerResponse::NowPlaying(np_song.song.clone())).await.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,7 +349,7 @@ impl<'c, P: Player + Send + Sync> Controller<'c, P> {
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
};
|
};
|
||||||
let QueueItemType::Single(np_song) = item.item else { panic!("This is temporary, handle queueItemTypes at some point")};
|
let QueueItemType::Single(np_song) = item.item else { panic!("This is temporary, handle queueItemTypes at some point")};
|
||||||
player_mail.send(PlayerResponse::NowPlaying(np_song.song.clone())).await.unwrap();;
|
player_mail.send(PlayerResponse::NowPlaying(np_song.song.clone())).await.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PlayerCommand::Enqueue(index) => {
|
PlayerCommand::Enqueue(index) => {
|
||||||
|
@ -328,6 +371,46 @@ impl<'c, P: Player + Send + Sync> Controller<'c, P> {
|
||||||
player_mail.send(PlayerResponse::Empty).await.unwrap();
|
player_mail.send(PlayerResponse::Empty).await.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PlayerCommand::PlayNow(uuid, location) => {
|
||||||
|
// TODO: This assumes the uuid doesn't point to an album. we've been over this.
|
||||||
|
inner_lib_mail.send(InnerLibraryCommand::Song(uuid)).await.unwrap();
|
||||||
|
let InnerLibraryResponse::Song(song, index) = inner_lib_mail.recv().await.unwrap() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
queue_mail.send(QueueCommand::Clear).await.unwrap();
|
||||||
|
let QueueResponse::Ok = queue_mail.recv().await.unwrap() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
queue_mail.send(QueueCommand::Append(QueueItem::from_item_type(QueueItemType::Single(QueueSong { song: song.clone(), location: location })), true)).await.unwrap();
|
||||||
|
let QueueResponse::Ok = queue_mail.recv().await.unwrap() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
player.write().unwrap().enqueue_next(song.primary_uri().unwrap().0).unwrap();
|
||||||
|
|
||||||
|
// how grab all the songs in a certain subset of the library, I reckon?
|
||||||
|
// ...
|
||||||
|
// let's just pretend I figured that out already
|
||||||
|
|
||||||
|
inner_lib_mail.send(InnerLibraryCommand::AllSongs).await.unwrap();
|
||||||
|
let InnerLibraryResponse::AllSongs(songs) = inner_lib_mail.recv().await.unwrap() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
for i in index+1..(index+50) {
|
||||||
|
if let Some(song) = songs.get(i) {
|
||||||
|
queue_mail.send(QueueCommand::Append(QueueItem::from_item_type(QueueItemType::Single(QueueSong { song: song.clone(), location })), false)).await.unwrap();
|
||||||
|
let QueueResponse::Ok = queue_mail.recv().await.unwrap() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
println!("End of Library");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ^ This be my solution for now ^
|
||||||
|
player_mail.send(PlayerResponse::NowPlaying(song.clone())).await.unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(());
|
return Err(());
|
||||||
|
@ -347,7 +430,7 @@ impl<'c, P: Player + Send + Sync> Controller<'c, P> {
|
||||||
.send(InnerLibraryCommand::Song(uuid))
|
.send(InnerLibraryCommand::Song(uuid))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let InnerLibraryResponse::Song(song) = inner_lib_mail.recv().await.unwrap() else {
|
let InnerLibraryResponse::Song(song, i) = inner_lib_mail.recv().await.unwrap() else {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
};
|
};
|
||||||
lib_mail.send(LibraryResponse::Song(song.clone())).await.unwrap();
|
lib_mail.send(LibraryResponse::Song(song.clone())).await.unwrap();
|
||||||
|
@ -377,9 +460,9 @@ impl<'c, P: Player + Send + Sync> Controller<'c, P> {
|
||||||
while true {
|
while true {
|
||||||
match lib_mail.recv().await.unwrap() {
|
match lib_mail.recv().await.unwrap() {
|
||||||
InnerLibraryCommand::Song(uuid) => {
|
InnerLibraryCommand::Song(uuid) => {
|
||||||
let song: &'c Song = library.query_uuid(&uuid).unwrap().0;
|
let (song, i): (&'c Song, usize) = library.query_uuid(&uuid).unwrap();
|
||||||
lib_mail
|
lib_mail
|
||||||
.send(InnerLibraryResponse::Song(song))
|
.send(InnerLibraryResponse::Song(song, i))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -408,9 +491,9 @@ impl<'c, P: Player + Send + Sync> Controller<'c, P> {
|
||||||
) {
|
) {
|
||||||
while true {
|
while true {
|
||||||
match queue_mail.recv().await.unwrap() {
|
match queue_mail.recv().await.unwrap() {
|
||||||
QueueCommand::Append(item) => {
|
QueueCommand::Append(item, by_human) => {
|
||||||
match item.item {
|
match item.item {
|
||||||
QueueItemType::Single(song) => queue.add_item(song, true),
|
QueueItemType::Single(song) => queue.add_item(song, by_human),
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
queue_mail
|
queue_mail
|
||||||
|
@ -446,6 +529,10 @@ impl<'c, P: Player + Send + Sync> Controller<'c, P> {
|
||||||
QueueCommand::Get => {
|
QueueCommand::Get => {
|
||||||
queue_mail.send(QueueResponse::GetAll(queue.items.clone())).await.unwrap();
|
queue_mail.send(QueueResponse::GetAll(queue.items.clone())).await.unwrap();
|
||||||
}
|
}
|
||||||
|
QueueCommand::Clear => {
|
||||||
|
queue.clear();
|
||||||
|
queue_mail.send(QueueResponse::Ok).await.unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,6 @@ impl<
|
||||||
self.items.get_mut(i).expect("There should be an item at index {i}").state = QueueState::NoState;
|
self.items.get_mut(i).expect("There should be an item at index {i}").state = QueueState::NoState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if by_human {
|
if by_human {
|
||||||
self.items.insert(
|
self.items.insert(
|
||||||
i + if empty { 0 } else { 1 },
|
i + if empty { 0 } else { 1 },
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
use dmp_core::music_controller::{controller::{ControllerHandle, LibraryResponse, PlayerLocation, QueueResponse}, queue::QueueSong};
|
use dmp_core::music_controller::{controller::{ControllerHandle, LibraryResponse, PlayerCommand, PlayerLocation, PlayerResponse, QueueResponse}, queue::QueueSong};
|
||||||
use kushi::QueueItem;
|
use kushi::QueueItem;
|
||||||
use tauri::{AppHandle, Emitter, State, Wry};
|
use tauri::{AppHandle, Emitter, State, Wry};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use crate::wrappers::_Song;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
@ -11,10 +13,22 @@ pub async fn add_song_to_queue(app: AppHandle<Wry>, ctrl_handle: State<'_, Contr
|
||||||
let LibraryResponse::Song(song) = ctrl_handle.lib_mail.recv().await.unwrap() else {
|
let LibraryResponse::Song(song) = ctrl_handle.lib_mail.recv().await.unwrap() else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
ctrl_handle.queue_mail.send(dmp_core::music_controller::controller::QueueCommand::Append(QueueItem::from_item_type(kushi::QueueItemType::Single(QueueSong { song, location })))).await.unwrap();
|
ctrl_handle.queue_mail.send(dmp_core::music_controller::controller::QueueCommand::Append(QueueItem::from_item_type(kushi::QueueItemType::Single(QueueSong { song, location })), true)).await.unwrap();
|
||||||
let QueueResponse::Ok = ctrl_handle.queue_mail.recv().await.unwrap() else {
|
let QueueResponse::Ok = ctrl_handle.queue_mail.recv().await.unwrap() else {
|
||||||
panic!()
|
panic!()
|
||||||
};
|
};
|
||||||
app.emit("queue_updated", ()).unwrap();
|
app.emit("queue_updated", ()).unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn play_now(app: AppHandle<Wry>, ctrl_handle: State<'_, ControllerHandle>, uuid: Uuid, location: PlayerLocation) -> Result<(), String> {
|
||||||
|
ctrl_handle.player_mail.send(PlayerCommand::PlayNow(uuid, location)).await.unwrap();
|
||||||
|
let PlayerResponse::NowPlaying(song) = ctrl_handle.player_mail.recv().await.unwrap() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
app.emit("queue_updated", ()).unwrap();
|
||||||
|
app.emit("now_playing_change", _Song::from(&song)).unwrap();
|
||||||
|
app.emit("playing", ()).unwrap();
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
use std::{fs, path::PathBuf, str::FromStr, thread::spawn};
|
use std::{fs, path::PathBuf, str::FromStr, thread::spawn};
|
||||||
|
|
||||||
use commands::add_song_to_queue;
|
use commands::{add_song_to_queue, play_now};
|
||||||
use crossbeam::channel::{unbounded, Receiver, Sender};
|
use crossbeam::channel::{unbounded, Receiver, Sender};
|
||||||
use dmp_core::{config::{Config, ConfigLibrary}, music_controller::controller::{Controller, ControllerHandle, LibraryResponse}, music_player::gstreamer::GStreamer, music_storage::library::{AlbumArt, MusicLibrary}};
|
use dmp_core::{config::{Config, ConfigLibrary}, music_controller::controller::{Controller, ControllerHandle, LibraryResponse}, music_player::gstreamer::GStreamer, music_storage::library::{AlbumArt, MusicLibrary}};
|
||||||
use tauri::{http::Response, Manager, State, Url, WebviewWindowBuilder, Wry};
|
use tauri::{http::Response, Emitter, Manager, State, Url, WebviewWindowBuilder, Wry};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::wrappers::{get_library, play, pause, prev, set_volume, get_song, next, get_queue};
|
use crate::wrappers::{get_library, play, pause, prev, set_volume, get_song, next, get_queue};
|
||||||
|
@ -73,6 +73,7 @@ pub fn run() {
|
||||||
lib_already_created,
|
lib_already_created,
|
||||||
get_queue,
|
get_queue,
|
||||||
add_song_to_queue,
|
add_song_to_queue,
|
||||||
|
play_now,
|
||||||
]).manage(ConfigRx(rx))
|
]).manage(ConfigRx(rx))
|
||||||
.manage(LibRx(lib_rx))
|
.manage(LibRx(lib_rx))
|
||||||
.manage(HandleTx(handle_tx))
|
.manage(HandleTx(handle_tx))
|
||||||
|
@ -96,8 +97,6 @@ pub fn run() {
|
||||||
let LibraryResponse::Song(song) = controller.lib_mail.recv().await.unwrap() else { unreachable!() };
|
let LibraryResponse::Song(song) = controller.lib_mail.recv().await.unwrap() else { unreachable!() };
|
||||||
song.album_art(0).unwrap_or_else(|_| None).unwrap_or(DEFAULT_IMAGE.to_vec())
|
song.album_art(0).unwrap_or_else(|_| None).unwrap_or(DEFAULT_IMAGE.to_vec())
|
||||||
})};
|
})};
|
||||||
|
|
||||||
|
|
||||||
res.respond(
|
res.respond(
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.header("Origin", "*")
|
.header("Origin", "*")
|
||||||
|
@ -124,7 +123,6 @@ struct ConfigRx(Sender<Config>);
|
||||||
|
|
||||||
struct LibRx(Sender<Option<PathBuf>>);
|
struct LibRx(Sender<Option<PathBuf>>);
|
||||||
struct HandleTx(Receiver<ControllerHandle>);
|
struct HandleTx(Receiver<ControllerHandle>);
|
||||||
struct DefaultImage<'a>(&'a [u8]);
|
|
||||||
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
@ -196,6 +194,7 @@ async fn create_library(
|
||||||
|
|
||||||
lib_rx.inner().0.send(Some(path)).unwrap();
|
lib_rx.inner().0.send(Some(path)).unwrap();
|
||||||
app.manage(handle_tx.inner().0.recv().unwrap());
|
app.manage(handle_tx.inner().0.recv().unwrap());
|
||||||
|
app.emit("library_loaded", ()).unwrap();
|
||||||
|
|
||||||
window.close().unwrap();
|
window.close().unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -206,5 +205,6 @@ async fn create_library(
|
||||||
println!("lib already created");
|
println!("lib already created");
|
||||||
lib_rx.inner().0.send(None).unwrap();
|
lib_rx.inner().0.send(None).unwrap();
|
||||||
app.manage(handle_tx.inner().0.recv().unwrap());
|
app.manage(handle_tx.inner().0.recv().unwrap());
|
||||||
|
app.emit("library_loaded", ()).unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,15 +21,17 @@ pub async fn play(app: AppHandle<Wry>, ctrl_handle: State<'_, ControllerHandle>)
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
app.emit("playing", ()).unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn pause(ctrl_handle: State<'_, ControllerHandle>) -> Result<(), String> {
|
pub async fn pause(app: AppHandle<Wry>, ctrl_handle: State<'_, ControllerHandle>) -> Result<(), String> {
|
||||||
ctrl_handle.player_mail.send(dmp_core::music_controller::controller::PlayerCommand::Pause).await.unwrap();
|
ctrl_handle.player_mail.send(dmp_core::music_controller::controller::PlayerCommand::Pause).await.unwrap();
|
||||||
let PlayerResponse::Empty = ctrl_handle.player_mail.recv().await.unwrap() else {
|
let PlayerResponse::Empty = ctrl_handle.player_mail.recv().await.unwrap() else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
app.emit("paused", ()).unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +60,7 @@ pub async fn next(app: AppHandle<Wry>, ctrl_handle: State<'_, ControllerHandle>)
|
||||||
println!("next");
|
println!("next");
|
||||||
app.emit("now_playing_change", _Song::from(&song)).unwrap();
|
app.emit("now_playing_change", _Song::from(&song)).unwrap();
|
||||||
app.emit("queue_updated", ()).unwrap();
|
app.emit("queue_updated", ()).unwrap();
|
||||||
|
app.emit("playing", ()).unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
59
src/App.tsx
59
src/App.tsx
|
@ -12,6 +12,7 @@ const appWindow = getCurrentWebviewWindow();
|
||||||
function App() {
|
function App() {
|
||||||
const library = useState<JSX.Element[]>([]);
|
const library = useState<JSX.Element[]>([]);
|
||||||
const [queue, setQueue] = useState<JSX.Element[]>([]);
|
const [queue, setQueue] = useState<JSX.Element[]>([]);
|
||||||
|
const [playing, setPlaying] = useState(false);
|
||||||
|
|
||||||
const [nowPlaying, setNowPlaying] = useState<JSX.Element>(
|
const [nowPlaying, setNowPlaying] = useState<JSX.Element>(
|
||||||
<NowPlaying
|
<NowPlaying
|
||||||
|
@ -51,6 +52,19 @@ function App() {
|
||||||
return () => { unlisten.then((f) => f()) }
|
return () => { unlisten.then((f) => f()) }
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const unlisten = appWindow.listen<any>("playing", (_) => {
|
||||||
|
setPlaying(true)
|
||||||
|
})
|
||||||
|
return () => { unlisten.then((f) => f()) }
|
||||||
|
}, []);
|
||||||
|
useEffect(() => {
|
||||||
|
const unlisten = appWindow.listen<any>("paused", (_) => {
|
||||||
|
setPlaying(false)
|
||||||
|
})
|
||||||
|
return () => { unlisten.then((f) => f()) }
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getConfig();
|
getConfig();
|
||||||
}, [])
|
}, [])
|
||||||
|
@ -60,7 +74,7 @@ function App() {
|
||||||
<div className="leftSide">
|
<div className="leftSide">
|
||||||
<PlaylistHead />
|
<PlaylistHead />
|
||||||
<MainView lib_ref={ library } />
|
<MainView lib_ref={ library } />
|
||||||
<PlayBar />
|
<PlayBar playing={ playing } setPlaying={ setPlaying } />
|
||||||
</div>
|
</div>
|
||||||
<div className="rightSide">
|
<div className="rightSide">
|
||||||
{ nowPlaying }
|
{ nowPlaying }
|
||||||
|
@ -110,14 +124,10 @@ interface MainViewProps {
|
||||||
function MainView({ lib_ref }: MainViewProps) {
|
function MainView({ lib_ref }: MainViewProps) {
|
||||||
const [library, setLibrary] = lib_ref;
|
const [library, setLibrary] = lib_ref;
|
||||||
|
|
||||||
return (
|
useEffect(() => {
|
||||||
<div className="mainView">
|
const unlisten = appWindow.listen<any>("library_loaded", (_) => {
|
||||||
main view
|
|
||||||
<button onClick={ (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
invoke('get_library').then((lib) => {
|
invoke('get_library').then((lib) => {
|
||||||
setLibrary([...(lib as any[]).map((song) => {
|
setLibrary([...(lib as any[]).map((song, i) => {
|
||||||
console.log(song);
|
console.log(song);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -131,7 +141,14 @@ function MainView({ lib_ref }: MainViewProps) {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})])
|
})])
|
||||||
})} }>get library</button>
|
})
|
||||||
|
})
|
||||||
|
return () => { unlisten.then((f) => f()) }
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mainView">
|
||||||
|
<h1>Library</h1>
|
||||||
<div>{ library }</div>
|
<div>{ library }</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -162,16 +179,19 @@ function Song(props: SongProps) {
|
||||||
invoke('add_song_to_queue', { uuid: props.uuid, location: 'Library' }).then(() => {} )
|
invoke('add_song_to_queue', { uuid: props.uuid, location: 'Library' }).then(() => {} )
|
||||||
}}
|
}}
|
||||||
>Add to Queue</button>
|
>Add to Queue</button>
|
||||||
|
<button onClick={() => {
|
||||||
|
invoke("play_now", { uuid: props.uuid, location: 'Library' }).then(() => {})
|
||||||
|
}}>Play Now</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function PlayBar() {
|
interface PlayBarProps {
|
||||||
let [playing, setPlaying] = useState('play');
|
playing: boolean,
|
||||||
|
setPlaying: React.Dispatch<React.SetStateAction<boolean>>
|
||||||
|
}
|
||||||
|
function PlayBar({ playing, setPlaying }: PlayBarProps) {
|
||||||
return (
|
return (
|
||||||
<section id="playBar" className="playBar">
|
<section id="playBar" className="playBar">
|
||||||
<div className="topHalf">
|
<div className="topHalf">
|
||||||
|
@ -181,14 +201,9 @@ function PlayBar() {
|
||||||
</div>
|
</div>
|
||||||
<button onClick={ () => invoke('prev').then(() => {}) }>prev</button>
|
<button onClick={ () => invoke('prev').then(() => {}) }>prev</button>
|
||||||
<button onClick={ (_) => {
|
<button onClick={ (_) => {
|
||||||
if (playing == 'play') {
|
setPlaying( playing ? false : true );
|
||||||
setPlaying('pause')
|
invoke( playing ? 'pause' : 'play' ).then(() => {})
|
||||||
invoke('play').then(() => {})
|
}}>{ playing ? 'pause' : 'play' }</button>
|
||||||
} else {
|
|
||||||
setPlaying('play')
|
|
||||||
invoke('pause').then(() => {})
|
|
||||||
}
|
|
||||||
}}>{ playing }</button>
|
|
||||||
<button onClick={ () => invoke('next').then(() => {}) }>next</button>
|
<button onClick={ () => invoke('next').then(() => {}) }>next</button>
|
||||||
<input type="range" name="volume" id="volumeSlider" onChange={ (volume) => {
|
<input type="range" name="volume" id="volumeSlider" onChange={ (volume) => {
|
||||||
invoke('set_volume', { volume: volume.target.value }).then(() => {})
|
invoke('set_volume', { volume: volume.target.value }).then(() => {})
|
||||||
|
|
Loading…
Reference in a new issue