diff --git a/.gitignore b/.gitignore index f28f2a1..10d9a4e 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,4 @@ Cargo.lock .cargo test-config -.txt \ No newline at end of file +*.txt \ No newline at end of file diff --git a/dmp-core/src/music_controller/connections.rs b/dmp-core/src/music_controller/connections.rs index 18d364d..ed09ff0 100644 --- a/dmp-core/src/music_controller/connections.rs +++ b/dmp-core/src/music_controller/connections.rs @@ -1,5 +1,5 @@ #![allow(while_true)] -use std::{sync::Arc, thread::sleep, time::{Duration, SystemTime, UNIX_EPOCH}}; +use std::{sync::{atomic::{AtomicBool, Ordering}, Arc}, thread::sleep, time::{Duration, SystemTime, UNIX_EPOCH}}; use chrono::TimeDelta; use crossbeam::{scope, select}; @@ -34,6 +34,10 @@ pub(super) struct ControllerConnections { pub inner: ConnectionsInput } + +static DC_ACTIVE: AtomicBool = AtomicBool::new(false); +static LB_ACTIVE: AtomicBool = AtomicBool::new(false); + impl Controller { pub(super) fn handle_connections( config: Arc>, @@ -48,6 +52,7 @@ impl Controller { let (dc_song_rx, dc_song_tx) = bounded::(1); let (lb_song_rx, lb_song_tx) = bounded::(1); let (lb_eos_rx, lb_eos_tx) = bounded::<()>(1); + scope(|s| { s.builder().name("Notifications Sorter".to_string()).spawn(|_| { use ConnectionsNotification::*; @@ -55,14 +60,14 @@ impl Controller { match notifications_tx.recv().unwrap() { Playback { position, duration } => {} StateChange(state) => { - dc_state_rx.send(state.clone()).unwrap(); + if DC_ACTIVE.load(Ordering::Relaxed) { dc_state_rx.send(state.clone()).unwrap(); } } SongChange(song) => { - dc_song_rx.send(song.clone()).unwrap(); - lb_song_rx.send(song).unwrap(); + if DC_ACTIVE.load(Ordering::Relaxed) { dc_song_rx.send(song.clone()).unwrap(); } + if LB_ACTIVE.load(Ordering::Relaxed) { lb_song_rx.send(song).unwrap(); } } EOS => { - lb_eos_rx.send(()).unwrap(); + if LB_ACTIVE.load(Ordering::Relaxed) { lb_eos_rx.send(()).unwrap(); } } } } @@ -84,73 +89,73 @@ impl Controller { fn discord_rpc(client_id: u64, song_tx: Receiver, state_tx: Receiver) { // TODO: Handle seeking position change and pause - std::thread::spawn(move || { - let mut client = discord_presence::Client::with_error_config(client_id, Duration::from_secs(5), None); - client.start(); - while !Client::is_ready() { sleep(Duration::from_millis(100)); } - println!("discord connected"); + let mut client = discord_presence::Client::with_error_config(client_id, Duration::from_secs(5), None); + client.start(); + while !Client::is_ready() { sleep(Duration::from_millis(100)); } + println!("discord connected"); - let mut state = "Started".to_string(); - let mut song: Option = None; - let mut now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards?").as_secs(); + let mut state = "Started".to_string(); + let mut song: Option = None; + let mut now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards?").as_secs(); + DC_ACTIVE.store(true, Ordering::Relaxed); - while true { - let state = &mut state; - let song = &mut song; - select! { - recv(state_tx) -> res => { - if let Ok(state_) = res { - *state = match state_ { - PrismState::Playing => "Playing", - PrismState::Paused => "Paused", - PrismState::Stopped => "Stopped", - _ => "I'm Scared, Boss" - }.to_string(); - } - }, - recv(song_tx) -> res => { - if let Ok(song_) = res { - *song = Some(song_); - now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards?").as_secs(); - } - }, - default(Duration::from_millis(99)) => () - } + while true { + let state = &mut state; + let song = &mut song; + select! { + recv(state_tx) -> res => { + if let Ok(state_) = res { + *state = match state_ { + PrismState::Playing => "Playing", + PrismState::Paused => "Paused", + PrismState::Stopped => "Stopped", + _ => "I'm Scared, Boss" + }.to_string(); + } + }, + recv(song_tx) -> res => { + if let Ok(song_) = res { + *song = Some(song_); + now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards?").as_secs(); + } + }, + default(Duration::from_millis(99)) => () + } - client.set_activity(|activity| { - let a = activity.state( - song.as_ref().map_or(String::new(), |s| format!( - "{}{}{}", - s.get_tag(&Tag::Artist).map_or(String::new(), |album| album.clone()), - if s.get_tag(&Tag::Album).is_some() && s.get_tag(&Tag::Artist).is_some() { " - " } else { "" }, - s.get_tag(&Tag::Album).map_or(String::new(), |album| album.clone()) - ) + client.set_activity(|activity| { + let a = activity.state( + song.as_ref().map_or(String::new(), |s| format!( + "{}{}{}", + s.get_tag(&Tag::Artist).map_or(String::new(), |album| album.clone()), + if s.get_tag(&Tag::Album).is_some() && s.get_tag(&Tag::Artist).is_some() { " - " } else { "" }, + s.get_tag(&Tag::Album).map_or(String::new(), |album| album.clone()) ) - )._type(discord_presence::models::ActivityType::Listening) - .details( - if let Some(song) = song { - song.get_tag(&Tag::Title).map_or(String::from("Unknown Title"), |title| title.clone()) - } else { - String::new() - } - ); - if let Some(s) = song { - if state.as_str() == "Playing" { - a.timestamps(|timestamps| { - timestamps.start(now) - .end(now + s.duration.as_secs()) - }) - } else { - a - } + ) + )._type(discord_presence::models::ActivityType::Listening) + .details( + if let Some(song) = song { + song.get_tag(&Tag::Title).map_or(String::from("Unknown Title"), |title| title.clone()) + } else { + String::new() + } + ); + if let Some(s) = song { + if state.as_str() == "Playing" { + a.timestamps(|timestamps| { + timestamps.start(now) + .end(now + s.duration.as_secs()) + }) } else { a - }.assets(|a| { - a.large_text(state.clone()) - }).instance(true) - }).unwrap(); - } - }); + } + } else { + a + }.assets(|a| { + a.large_text(state.clone()) + }).instance(true) + }).unwrap(); + } + DC_ACTIVE.store(false, Ordering::Relaxed); } fn listenbrainz_scrobble(token: &str, song_tx: Receiver, eos_tx: Receiver<()>) { @@ -161,25 +166,48 @@ impl Controller { } let mut song: Option = None; + LB_ACTIVE.store(true, Ordering::Relaxed); + while true { let song = &mut song; let client = &client; select! { recv(song_tx) -> res => { if let Ok(_song) = res { - client.playing_now(_song.get_tag(&Tag::Artist).map_or("", |tag| tag.as_str()), _song.get_tag(&Tag::Title).map_or("", |tag| tag.as_str()), None).unwrap(); + let artist = if let Some(tag) = _song.get_tag(&Tag::Artist) { + tag.as_str() + } else { + continue + }; + let title = if let Some(tag) = _song.get_tag(&Tag::Title) { + tag.as_str() + } else { + continue + }; + client.playing_now(artist, title, None).unwrap(); *song = Some(_song); println!("Song Listening") } }, recv(eos_tx) -> _ => { if let Some(song) = song { - client.listen(song.get_tag(&Tag::Artist).map_or("", |tag| tag.as_str()), song.get_tag(&Tag::Title).map_or("", |tag| tag.as_str()), None).unwrap(); + let artist = if let Some(tag) = song.get_tag(&Tag::Artist) { + tag.as_str() + } else { + continue + }; + let title = if let Some(tag) = song.get_tag(&Tag::Title) { + tag.as_str() + } else { + continue + }; + client.listen(artist, title, None).unwrap(); println!("Song Scrobbled"); } } } } + LB_ACTIVE.store(false, Ordering::Relaxed); } } diff --git a/dmp-core/src/music_controller/controller.rs b/dmp-core/src/music_controller/controller.rs index 3079c05..9fa2ac7 100644 --- a/dmp-core/src/music_controller/controller.rs +++ b/dmp-core/src/music_controller/controller.rs @@ -656,6 +656,7 @@ impl Controller { if let Ok(song) = res { notify_next_song.send(song.clone()).unwrap(); notify_connections.send(ConnectionsNotification::SongChange(song)).unwrap(); + notify_connections.send(ConnectionsNotification::EOS).unwrap(); } } std::thread::sleep(Duration::from_millis(100)); diff --git a/src/App.tsx b/src/App.tsx index 555c283..86ad12b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -294,8 +294,8 @@ function PlayBar({ playing, setPlaying }: PlayBarProps) { const pos_ = Array.isArray(info.position) ? info.position![0] : 0; const dur_ = Array.isArray(info.duration) ? info.duration![0] : 0; - setPosition(dur_); - setDuration(pos_); + setPosition(pos_); + setDuration(dur_); let progress = ((dur_/pos_) * 100); setSeekBarSize(progress) }) @@ -332,10 +332,11 @@ function PlayBar({ playing, setPlaying }: PlayBarProps) { invoke('set_volume', { volume: volume.target.value }).then(() => {}) }} />

- { Math.floor(+position / 60).toString().padStart(2, "0") }: - { (+position % 60).toString().padStart(2, "0") }/ { Math.floor(+duration / 60).toString().padStart(2, "0") }: - { (+duration % 60).toString().padStart(2, "0") } + { (+duration % 60).toString().padStart(2, "0") }/ + { Math.floor(+position / 60).toString().padStart(2, "0") }: + { (+position % 60).toString().padStart(2, "0") } +