diff --git a/Cargo.lock b/Cargo.lock index e47da8e..df419a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -384,6 +384,7 @@ dependencies = [ "tokio", "tokio-stream", "tonic", + "tracing", ] [[package]] diff --git a/audio-player/src/player_engine.rs b/audio-player/src/player_engine.rs index 0a23823..9dec317 100644 --- a/audio-player/src/player_engine.rs +++ b/audio-player/src/player_engine.rs @@ -1,11 +1,11 @@ use flume::Sender; use std::path::Path; use std::sync::atomic::AtomicU64; -use std::thread; + use std::time::Duration; use std::{fs::File, sync::atomic::Ordering}; use symphonia::core::probe::Hint; -use tracing::{debug, warn}; +use tracing::{warn}; use url::Url; use crate::decoder::{MediaInfo, SymphoniaDecoder}; diff --git a/cbd-tui/Cargo.toml b/cbd-tui/Cargo.toml index 51b5994..1524e3a 100644 --- a/cbd-tui/Cargo.toml +++ b/cbd-tui/Cargo.toml @@ -15,3 +15,4 @@ tokio-stream = "0.1" tonic = "0.9" notify-rust = "4.8.0" serde = "1.0.164" +tracing = "0.1.37" diff --git a/cbd-tui/src/app/library.rs b/cbd-tui/src/app/library.rs index 6ac6c38..28a0e33 100644 --- a/cbd-tui/src/app/library.rs +++ b/cbd-tui/src/app/library.rs @@ -11,6 +11,7 @@ use ratatui::{ }, Frame, }; +use tracing::error; use crabidy_core::proto::crabidy::LibraryNode; @@ -57,15 +58,21 @@ impl Library { } pub fn ascend(&mut self) { if let Some(parent) = self.parent.as_ref() { - self.tx.send(MessageFromUi::GetLibraryNode(parent.clone())); + if let Err(err) = self.tx.send(MessageFromUi::GetLibraryNode(parent.clone())) { + error!("Send error: {}", err); + } } } pub fn dive(&mut self) { if let Some(idx) = self.list_state.selected() { let item = &self.list[idx]; if let UiItemKind::Node = item.kind { - self.tx - .send(MessageFromUi::GetLibraryNode(item.uuid.clone())); + if let Err(err) = self + .tx + .send(MessageFromUi::GetLibraryNode(item.uuid.clone())) + { + error!("Send error: {}", err); + } } } } @@ -73,7 +80,7 @@ impl Library { if let Some(items) = self.get_selected() { match self.tx.send(MessageFromUi::AppendTracks(items)) { Ok(_) => self.remove_marks(), - Err(_) => { /* FIXME: warn */ } + Err(err) => error!("Send error: {}", err), } } } @@ -81,7 +88,7 @@ impl Library { if let Some(items) = self.get_selected() { match self.tx.send(MessageFromUi::QueueTracks(items)) { Ok(_) => self.remove_marks(), - Err(_) => { /* FIXME: warn */ } + Err(err) => error!("Send error: {}", err), } } } @@ -89,7 +96,7 @@ impl Library { if let Some(items) = self.get_selected() { match self.tx.send(MessageFromUi::ReplaceQueue(items)) { Ok(_) => self.remove_marks(), - Err(_) => { /* FIXME: warn */ } + Err(err) => error!("Send error: {}", err), } } } @@ -97,7 +104,7 @@ impl Library { if let Some(items) = self.get_selected() { match self.tx.send(MessageFromUi::InsertTracks(items, pos)) { Ok(_) => self.remove_marks(), - Err(_) => { /* FIXME: warn */ } + Err(err) => error!("Send error: {}", err), } } } diff --git a/cbd-tui/src/app/mod.rs b/cbd-tui/src/app/mod.rs index 9cacc05..3749609 100644 --- a/cbd-tui/src/app/mod.rs +++ b/cbd-tui/src/app/mod.rs @@ -117,7 +117,7 @@ impl App { let main = Layout::default() .direction(Direction::Horizontal) .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()) - .split(f.size()); + .split(full_screen); self.library.render(f, main[0], library_focused); diff --git a/cbd-tui/src/app/now_playing.rs b/cbd-tui/src/app/now_playing.rs index 0617071..ad2d682 100644 --- a/cbd-tui/src/app/now_playing.rs +++ b/cbd-tui/src/app/now_playing.rs @@ -47,10 +47,14 @@ impl NowPlaying { } pub fn update_track(&mut self, active: Option) { if let Some(track) = &active { + let body = if let Some(ref album) = track.album { + format!("{} by {} ({})", track.title, track.artist, album.title) + } else { + format!("{} by {}", track.title, track.artist) + }; Notification::new() - .summary("Crabidy playing") - // FIXME: album - .body(&format!("{} by {}", track.title, track.artist)) + .summary("Playing") + .body(&body) .show() .unwrap(); } @@ -118,7 +122,7 @@ impl NowPlaying { f.render_widget(media_info_p, now_playing_layout[0]); - if let (Some(position), Some(duration), Some(track)) = + if let (Some(position), Some(duration), Some(_track)) = (self.position, self.duration, &self.track) { let pos = position.as_secs(); diff --git a/cbd-tui/src/app/queue.rs b/cbd-tui/src/app/queue.rs index dbf602a..5cf1ecd 100644 --- a/cbd-tui/src/app/queue.rs +++ b/cbd-tui/src/app/queue.rs @@ -9,6 +9,7 @@ use ratatui::{ }, Frame, }; +use tracing::error; use crabidy_core::proto::crabidy::Queue as QueueData; @@ -33,20 +34,28 @@ impl Queue { } } pub fn play_next(&self) { - self.tx.send(MessageFromUi::NextTrack); + if let Err(err) = self.tx.send(MessageFromUi::NextTrack) { + error!("Send error: {}", err); + } } pub fn play_prev(&self) { - self.tx.send(MessageFromUi::PrevTrack); + if let Err(err) = self.tx.send(MessageFromUi::PrevTrack) { + error!("Send error: {}", err); + } } pub fn play_selected(&self) { if let Some(pos) = self.selected() { - self.tx.send(MessageFromUi::SetCurrentTrack(pos)); + if let Err(err) = self.tx.send(MessageFromUi::SetCurrentTrack(pos)) { + error!("Send error: {}", err); + } } } pub fn remove_track(&mut self) { if let Some(pos) = self.selected() { // FIXME: mark multiple tracks on queue and remove them - self.tx.send(MessageFromUi::RemoveTracks(vec![pos])); + if let Err(err) = self.tx.send(MessageFromUi::RemoveTracks(vec![pos])) { + error!("Send error: {}", err); + } } } pub fn update_position(&mut self, pos: usize) { @@ -57,10 +66,9 @@ impl Queue { self.list = queue .tracks .iter() - .enumerate() - .map(|(i, t)| UiItem { - uuid: t.uuid.clone(), - title: format!("{} - {}", t.artist, t.title), + .map(|track| UiItem { + uuid: track.uuid.clone(), + title: format!("{} - {}", track.artist, track.title), kind: UiItemKind::Track, marked: false, is_queable: false, diff --git a/cbd-tui/src/main.rs b/cbd-tui/src/main.rs index c51577b..a7dec07 100644 --- a/cbd-tui/src/main.rs +++ b/cbd-tui/src/main.rs @@ -36,6 +36,7 @@ use ratatui::{backend::CrosstermBackend, Terminal}; use tokio::{fs, select, signal, task}; use tokio_stream::StreamExt; use tonic::{transport::Channel, Request, Status, Streaming}; +use tracing::error; use app::{App, MessageFromUi, MessageToUi, StatefulList, UiFocus}; use config::Config; @@ -44,6 +45,7 @@ use rpc::RpcClient; static CONFIG: OnceLock = OnceLock::new(); #[tokio::main] +// FIXME: use anyhow, thiserror async fn main() -> Result<(), Box> { let config = CONFIG.get_or_init(|| crabidy_core::init_config("cbd-tui.toml")); @@ -51,12 +53,12 @@ async fn main() -> Result<(), Box> { let (tx, ui_rx): (Sender, Receiver) = flume::unbounded(); // FIXME: unwrap - tokio::spawn(async move { orchestrate(config, (tx, rx)).await.unwrap() }); + tokio::spawn(async move { orchestrate(config, (tx, rx)).await.unwrap() }).await?; tokio::task::spawn_blocking(|| { run_ui(ui_tx, ui_rx); }) - .await; + .await?; Ok(()) } @@ -68,14 +70,16 @@ async fn orchestrate<'a>( let mut rpc_client = rpc::RpcClient::connect(&config.server.address).await?; if let Some(root_node) = rpc_client.get_library_node("node:/").await? { - tx.send(MessageToUi::ReplaceLibraryNode(root_node.clone())); + tx.send(MessageToUi::ReplaceLibraryNode(root_node.clone()))?; } let init_data = rpc_client.init().await?; tx.send_async(MessageToUi::Init(init_data)).await?; loop { - poll(&mut rpc_client, &rx, &tx).await.ok(); + if let Err(err) = poll(&mut rpc_client, &rx, &tx).await { + error!("Poll error: {}", err); + } } } @@ -89,7 +93,7 @@ async fn poll( match msg { MessageFromUi::GetLibraryNode(uuid) => { if let Some(node) = rpc_client.get_library_node(&uuid).await? { - tx.send(MessageToUi::ReplaceLibraryNode(node.clone())); + tx.send(MessageToUi::ReplaceLibraryNode(node.clone()))?; } }, MessageFromUi::AppendTracks(uuids) => { @@ -211,7 +215,7 @@ fn run_ui(tx: Sender, rx: Receiver) { } } - terminal.draw(|f| app.render(f)); + terminal.draw(|f| app.render(f)).unwrap(); let timeout = tick_rate .checked_sub(last_tick.elapsed()) @@ -226,25 +230,39 @@ fn run_ui(tx: Sender, rx: Receiver) { } (_, KeyModifiers::NONE, KeyCode::Tab) => app.cycle_active(), (_, KeyModifiers::NONE, KeyCode::Char(' ')) => { - tx.send(MessageFromUi::TogglePlay); + if let Err(err) = tx.send(MessageFromUi::TogglePlay) { + error!("Send error: {}", err); + } } (_, KeyModifiers::NONE, KeyCode::Char('r')) => { - tx.send(MessageFromUi::RestartTrack); + if let Err(err) = tx.send(MessageFromUi::RestartTrack) { + error!("Send error: {}", err); + } } (_, KeyModifiers::SHIFT, KeyCode::Char('J')) => { - tx.send(MessageFromUi::ChangeVolume(-0.1)); + if let Err(err) = tx.send(MessageFromUi::ChangeVolume(-0.1)) { + error!("Send error: {}", err); + } } (_, KeyModifiers::SHIFT, KeyCode::Char('K')) => { - tx.send(MessageFromUi::ChangeVolume(0.1)); + if let Err(err) = tx.send(MessageFromUi::ChangeVolume(0.1)) { + error!("Send error: {}", err); + } } (_, KeyModifiers::NONE, KeyCode::Char('m')) => { - tx.send(MessageFromUi::ToggleMute); + if let Err(err) = tx.send(MessageFromUi::ToggleMute) { + error!("Send error: {}", err); + } } (_, KeyModifiers::NONE, KeyCode::Char('z')) => { - tx.send(MessageFromUi::ToggleShuffle); + if let Err(err) = tx.send(MessageFromUi::ToggleShuffle) { + error!("Send error: {}", err); + } } (_, KeyModifiers::NONE, KeyCode::Char('x')) => { - tx.send(MessageFromUi::ToggleRepeat); + if let Err(err) = tx.send(MessageFromUi::ToggleRepeat) { + error!("Send error: {}", err); + } } (_, KeyModifiers::CONTROL, KeyCode::Char('n')) => { app.queue.play_next(); diff --git a/cbd-tui/src/rpc.rs b/cbd-tui/src/rpc.rs index fca0353..834de99 100644 --- a/cbd-tui/src/rpc.rs +++ b/cbd-tui/src/rpc.rs @@ -72,9 +72,7 @@ impl RpcClient { } pub async fn reconnect_update_stream(&mut self) { - let update_stream = Self::get_update_stream(&mut self.client).await; - // FIXME: apparently mem::replace doesn't do anything here - mem::replace(&mut self.update_stream, update_stream); + self.update_stream = Self::get_update_stream(&mut self.client).await; } pub async fn init(&mut self) -> Result> { diff --git a/crabidy-core/src/lib.rs b/crabidy-core/src/lib.rs index 92d6697..bbb7a95 100644 --- a/crabidy-core/src/lib.rs +++ b/crabidy-core/src/lib.rs @@ -73,7 +73,7 @@ where if let Some(config_dir) = dirs::config_dir() { let dir = Path::new(&config_dir).join("crabidy"); if !dir.is_dir() { - create_dir_all(&dir); + create_dir_all(&dir).expect("Could not create crabidy directory in config dir"); } let config_file_path = dir.join(config_file_name); if !config_file_path.is_file() {