From 78daa33c81b6a21866b67734220aaec58c406b26 Mon Sep 17 00:00:00 2001 From: qxbthree Date: Thu, 23 Jan 2025 04:11:53 +0800 Subject: [PATCH 1/4] improve error message --- src/action.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/action.rs b/src/action.rs index 4b6ea55..d52a525 100644 --- a/src/action.rs +++ b/src/action.rs @@ -73,25 +73,29 @@ impl<'de> Deserialize<'de> for Action { if let Some(captures) = forward_re.captures(a) { match captures[1].parse::() { Ok(offset) => return Ok(Action::Forward(offset)), - Err(_) => return Err(de::Error::custom("Invalid forward offset format")) + Err(_) => return Err(de::Error::custom("Invalid forward() offset format")) } } - Err(de::Error::custom("Invalid forward format")) + Err(de::Error::custom("Invalid forward() format")) }, a if backward_re.is_match(a) => { if let Some(captures) = backward_re.captures(a) { match captures[1].parse::() { Ok(offset) => return Ok(Action::Backward(offset)), - Err(_) => return Err(de::Error::custom("Invalid backward offset format")) + Err(_) => return Err(de::Error::custom("Invalid backward() offset format")) } } - Err(de::Error::custom("Invalid backward format")) + Err(de::Error::custom("Invalid backward() format")) }, - _ => Err(serde::de::Error::custom(format!("Unknown action: {}", action_str))) + // Error if forward() / backward() has no value inside + "forward()" => Err(de::Error::custom(format!("Invalid forward() format, needs value inside"))), + "backward()" => Err(de::Error::custom(format!("Invalid backward() format, needs value inside"))), + + _ => Err(de::Error::custom(format!("Unknown action: {}", action_str))) } } } From 31496ff65f6a5981b1d0f032851f36a1f2828bbb Mon Sep 17 00:00:00 2001 From: qxbthree Date: Thu, 23 Jan 2025 04:18:23 +0800 Subject: [PATCH 2/4] immediately redraw on forward, backward actions --- src/action.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/action.rs b/src/action.rs index d52a525..26faa07 100644 --- a/src/action.rs +++ b/src/action.rs @@ -132,8 +132,14 @@ impl Action { } }, - Action::Forward(offset) => if_player!(&fum.player, |player: &Player| player.seek_forwards(&Duration::from_millis(*offset))), - Action::Backward(offset) => if_player!(&fum.player, |player: &Player| player.seek_backwards(&Duration::from_millis(*offset))) + Action::Forward(offset) => if_player!(&fum.player, |player: &Player| { + fum.redraw = true; + player.seek_forwards(&Duration::from_millis(*offset)) + }), + Action::Backward(offset) => if_player!(&fum.player, |player: &Player| { + fum.redraw = true; + player.seek_backwards(&Duration::from_millis(*offset)) + }) } Ok(()) From ed949f1cb4cd41da4f4da13174f9c0bd398a62b5 Mon Sep 17 00:00:00 2001 From: qxbthree Date: Thu, 23 Jan 2025 04:41:26 +0800 Subject: [PATCH 3/4] add new meta: track_id --- src/meta.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/meta.rs b/src/meta.rs index 97aba1b..4346dc6 100644 --- a/src/meta.rs +++ b/src/meta.rs @@ -2,7 +2,7 @@ use std::{fs, io::{self, Cursor}, str::FromStr, time::Duration}; use base64::{prelude::BASE64_STANDARD, Engine}; use image::ImageReader; -use mpris::{Metadata, MetadataValue, PlaybackStatus, Player, PlayerFinder}; +use mpris::{Metadata, MetadataValue, PlaybackStatus, Player, PlayerFinder, TrackID}; use ratatui_image::{picker::Picker, protocol::StatefulProtocol}; use reqwest::{header::RANGE, Url}; @@ -17,6 +17,7 @@ pub struct CoverArt { #[derive(Clone)] pub struct Meta<'a> { pub metadata: Metadata, + pub track_id: Option, pub title: String, pub artists: Vec, pub album: String, @@ -32,6 +33,7 @@ impl<'a> Default for Meta<'a> { fn default() -> Self { Self { metadata: Metadata::default(), + track_id: None, title: "No Music".to_string(), artists: vec!["Artist".to_string()], album: "Album".to_string(), @@ -48,6 +50,7 @@ impl<'a> Default for Meta<'a> { impl<'a> Meta<'a> { pub fn fetch(player: &Player, picker: &Picker, current: Option<&Self>) -> FumResult { let metadata = Meta::get_metadata(player)?; + let track_id = Meta::get_trackid(&metadata)?; let title = Meta::get_title(&metadata)?; let artists = Meta::get_artists(&metadata)?; let album = Meta::get_album(&metadata)?; @@ -71,6 +74,7 @@ impl<'a> Meta<'a> { Ok(Self { metadata, + track_id: Some(track_id), title, artists, album, @@ -124,6 +128,13 @@ impl<'a> Meta<'a> { Ok(metadata) } + pub fn get_trackid(metadata: &Metadata) -> FumResult { + let trackid = metadata.track_id() + .ok_or("Failed to get track_id")?; + + Ok(trackid) + } + pub fn get_title(metadata: &Metadata) -> FumResult { let title = metadata .title() From 8ca9d4cd7453623347b9055ad4b54e84560b325a Mon Sep 17 00:00:00 2001 From: qxbthree Date: Thu, 23 Jan 2025 04:41:46 +0800 Subject: [PATCH 4/4] -1 values for forward() & backward() --- src/action.rs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/action.rs b/src/action.rs index 26faa07..bb6efb7 100644 --- a/src/action.rs +++ b/src/action.rs @@ -35,8 +35,8 @@ pub enum Action { LoopTrack, LoopCycle, - Forward(u64), - Backward(u64), + Forward(i64), + Backward(i64), } impl<'de> Deserialize<'de> for Action { @@ -46,8 +46,8 @@ impl<'de> Deserialize<'de> for Action { { let action_str: &str = Deserialize::deserialize(deserializer)?; - let forward_re = Regex::new(r"forward\((\d+)\)").unwrap(); - let backward_re = Regex::new(r"backward\((\d+)\)").unwrap(); + let forward_re = Regex::new(r"forward\((-?\d+)\)").unwrap(); + let backward_re = Regex::new(r"backward\((-?\d+)\)").unwrap(); match action_str { "quit()" => Ok(Action::Quit), @@ -71,7 +71,7 @@ impl<'de> Deserialize<'de> for Action { a if forward_re.is_match(a) => { if let Some(captures) = forward_re.captures(a) { - match captures[1].parse::() { + match captures[1].parse::() { Ok(offset) => return Ok(Action::Forward(offset)), Err(_) => return Err(de::Error::custom("Invalid forward() offset format")) } @@ -82,7 +82,7 @@ impl<'de> Deserialize<'de> for Action { a if backward_re.is_match(a) => { if let Some(captures) = backward_re.captures(a) { - match captures[1].parse::() { + match captures[1].parse::() { Ok(offset) => return Ok(Action::Backward(offset)), Err(_) => return Err(de::Error::custom("Invalid backward() offset format")) } @@ -134,11 +134,27 @@ impl Action { Action::Forward(offset) => if_player!(&fum.player, |player: &Player| { fum.redraw = true; - player.seek_forwards(&Duration::from_millis(*offset)) + + if let Some(track_id) = &fum.meta.track_id { + match offset { + -1 => return player.set_position(track_id.clone(), &fum.meta.length), + _ => return player.seek_forwards(&Duration::from_millis(*offset as u64)) + } + } + + unreachable!() }), Action::Backward(offset) => if_player!(&fum.player, |player: &Player| { fum.redraw = true; - player.seek_backwards(&Duration::from_millis(*offset)) + + if let Some(track_id) = &fum.meta.track_id { + match offset { + -1 => return player.set_position(track_id.clone(), &Duration::from_secs(0)), + _ => return player.seek_backwards(&Duration::from_millis(*offset as u64)) + } + } + + unreachable!() }) }