diff --git a/src/model/song.rs b/src/model/song.rs index 224bf8c..b32fe22 100644 --- a/src/model/song.rs +++ b/src/model/song.rs @@ -27,8 +27,6 @@ mod imp { #[property(get, set)] track: Cell, - #[property(get, set)] - cover_art_url: RefCell, #[property(get, set)] stream_url: RefCell, @@ -83,8 +81,7 @@ impl Song { .property("album", &song.album) .property("genre", &song.genre) .property("duration", song.duration as i64) - //.property("track", song.track) - .property("cover-art-url", api.cover_art_url(&song.id, 0).as_str()) + .property("track", song.track.map(i64::from).unwrap_or(-1)) .property("stream-url", api.stream_url(&song.id).as_str()) .build(); @@ -96,7 +93,7 @@ impl Song { .thumbnail_loading .replace(Some(glib::spawn_future_local(async move { let bytes = api - .cover_art(&id, 50) // TODO: constify thumbnail size, maybe take dpi into account etc + .cover_art(&id, Some(50)) // TODO: WidgetExt::scale_factor .await .unwrap(); let song = match song_weak.upgrade() { diff --git a/src/subsonic.rs b/src/subsonic.rs index 5b0caf5..6f6e8a0 100644 --- a/src/subsonic.rs +++ b/src/subsonic.rs @@ -153,10 +153,51 @@ impl Client { } } - async fn send_bytes(&self, request: reqwest::RequestBuilder) -> Result { + fn url(&self, path: &[&str], query: &[(&str, &str)]) -> url::Url { + let mut url = self.base_url.clone(); + url.path_segments_mut() + // literally can't fail + .unwrap_or_else(|_| unsafe { std::hint::unreachable_unchecked() }) + .extend(path); + url.query_pairs_mut().extend_pairs(query); + url + } + + async fn get( + &self, + path: &[&str], + query: &[(&str, &str)], + ) -> Result { + self.send(self.client.get(self.url(path, query))).await + } + + pub async fn ping(&self) -> Result<(), Error> { + self.get(&["rest", "ping"], &[]).await + } + + pub async fn get_random_songs(&self, size: u32) -> Result, Error> { + self.get::( + &["rest", "getRandomSongs"], + &[("size", &size.to_string())], + ) + .await + .map(|response| response.random_songs.song) + } + + pub fn cover_art_url(&self, id: &str, size: Option) -> url::Url { + match size { + None => self.url(&["rest", "getCoverArt"], &[("id", id)]), + Some(size) => self.url( + &["rest", "getCoverArt"], + &[("id", id), ("size", &size.to_string())], + ), + } + } + + pub async fn cover_art(&self, id: &str, size: Option) -> Result { let (sender, receiver) = async_channel::bounded(1); - let future = request.send(); + let future = self.client.get(self.cover_art_url(id, size)).send(); runtime().spawn(async move { async fn perform( response: Result, @@ -197,53 +238,6 @@ impl Client { .expect("could not receive cover art bytes from tokio") } - fn url(&self, path: &[&str], query: &[(&str, &str)]) -> url::Url { - let mut url = self.base_url.clone(); - url.path_segments_mut() - // literally can't fail - .unwrap_or_else(|_| unsafe { std::hint::unreachable_unchecked() }) - .extend(path); - url.query_pairs_mut().extend_pairs(query); - url - } - - async fn get( - &self, - path: &[&str], - query: &[(&str, &str)], - ) -> Result { - self.send(self.client.get(self.url(path, query))).await - } - - pub async fn ping(&self) -> Result<(), Error> { - self.get(&["rest", "ping"], &[]).await - } - - pub async fn get_random_songs(&self, size: u32) -> Result, Error> { - self.get::( - &["rest", "getRandomSongs"], - &[("size", &size.to_string())], - ) - .await - .map(|response| response.random_songs.song) - } - - pub fn cover_art_url(&self, id: &str, size: u32) -> url::Url { - if size == 0 { - self.url(&["rest", "getCoverArt"], &[("id", id)]) - } else { - self.url( - &["rest", "getCoverArt"], - &[("id", id), ("size", &size.to_string())], - ) - } - } - - pub async fn cover_art(&self, id: &str, size: u32) -> Result { - self.send_bytes(self.client.get(self.cover_art_url(id, size))) - .await - } - pub fn stream_url(&self, id: &str) -> url::Url { self.url(&["rest", "stream"], &[("id", id)]) } diff --git a/src/ui/window.rs b/src/ui/window.rs index d42900d..0b93b3b 100644 --- a/src/ui/window.rs +++ b/src/ui/window.rs @@ -482,7 +482,7 @@ mod imp { .replace(Some(glib::spawn_future_local(async move { let api = window.imp().api.borrow().as_ref().unwrap().clone(); let bytes = api - .cover_art(&song_id, 0) // 0: full size + .cover_art(&song_id, None) // full size .await .expect("could not load cover art for song {song_id}");