diff --git a/frontend/src/api.rs b/frontend/src/api.rs index 8c83c24..fbf4982 100644 --- a/frontend/src/api.rs +++ b/frontend/src/api.rs @@ -98,6 +98,11 @@ pub async fn delete_user(id: i32) -> Result<(), ApiError> { delete(&format!("{BASE}/auth/users/{id}")).await } +// --- Lyrics --- +pub async fn get_lyrics(artist: &str, title: &str) -> Result { + get_json(&format!("{BASE}/lyrics?artist={artist}&title={title}")).await +} + // --- Status --- pub async fn get_status() -> Result { get_json(&format!("{BASE}/status")).await @@ -108,7 +113,11 @@ pub async fn search_artist(query: &str, limit: u32) -> Result, get_json(&format!("{BASE}/search/artist?q={query}&limit={limit}")).await } -pub async fn search_album(query: &str, artist: Option<&str>, limit: u32) -> Result, ApiError> { +pub async fn search_album( + query: &str, + artist: Option<&str>, + limit: u32, +) -> Result, ApiError> { let mut url = format!("{BASE}/search/album?q={query}&limit={limit}"); if let Some(a) = artist { url.push_str(&format!("&artist={a}")); @@ -116,7 +125,11 @@ pub async fn search_album(query: &str, artist: Option<&str>, limit: u32) -> Resu get_json(&url).await } -pub async fn search_track(query: &str, artist: Option<&str>, limit: u32) -> Result, ApiError> { +pub async fn search_track( + query: &str, + artist: Option<&str>, + limit: u32, +) -> Result, ApiError> { let mut url = format!("{BASE}/search/track?q={query}&limit={limit}"); if let Some(a) = artist { url.push_str(&format!("&artist={a}")); @@ -158,7 +171,11 @@ pub async fn add_artist(name: &str, mbid: Option<&str>) -> Result) -> Result { +pub async fn add_album( + artist: &str, + album: &str, + mbid: Option<&str>, +) -> Result { let body = match mbid { Some(m) => format!(r#"{{"artist":"{artist}","album":"{album}","mbid":"{m}"}}"#), None => format!(r#"{{"artist":"{artist}","album":"{album}"}}"#), diff --git a/frontend/src/pages/album.rs b/frontend/src/pages/album.rs index b0754ab..d7980fa 100644 --- a/frontend/src/pages/album.rs +++ b/frontend/src/pages/album.rs @@ -1,8 +1,9 @@ +use std::collections::HashMap; use yew::prelude::*; use crate::api; use crate::components::status_badge::StatusBadge; -use crate::types::MbAlbumDetail; +use crate::types::{LyricsResult, MbAlbumDetail}; #[derive(Properties, PartialEq)] pub struct Props { @@ -14,6 +15,8 @@ pub fn album_page(props: &Props) -> Html { let detail = use_state(|| None::); let error = use_state(|| None::); let mbid = props.mbid.clone(); + let lyrics_cache: UseStateHandle> = use_state(HashMap::new); + let active_lyrics = use_state(|| None::); { let detail = detail.clone(); @@ -37,7 +40,6 @@ pub fn album_page(props: &Props) -> Html { return html! {

{ "Loading album from MusicBrainz..." }

}; }; - // Format duration from ms let fmt_duration = |ms: u64| -> String { let secs = ms / 1000; let mins = secs / 60; @@ -45,11 +47,22 @@ pub fn album_page(props: &Props) -> Html { format!("{mins}:{remaining:02}") }; + let cover_url = format!("https://coverartarchive.org/release/{}/front-250", d.mbid); + html! {
-