Files
LibreTunes/src/pages/album.rs
Ethan Girouard 368f673fd7
Some checks failed
Push Workflows / rustfmt (push) Successful in 11s
Push Workflows / mdbook (push) Successful in 16s
Push Workflows / mdbook-server (push) Successful in 4m20s
Push Workflows / docs (push) Successful in 5m44s
Push Workflows / clippy (push) Successful in 7m48s
Push Workflows / test (push) Successful in 11m14s
Push Workflows / leptos-test (push) Failing after 11m33s
Push Workflows / build (push) Successful in 12m53s
Push Workflows / nix-build (push) Successful in 16m54s
Push Workflows / docker-build (push) Successful in 17m40s
Rewrite error handling and display
2025-06-26 00:01:49 +00:00

106 lines
3.1 KiB
Rust

use crate::api::album::*;
use crate::components::error::*;
use crate::components::loading::*;
use crate::components::song_list::*;
use crate::models::frontend;
use leptos::either::*;
use leptos::prelude::*;
use leptos_router::hooks::use_params_map;
#[component]
pub fn AlbumPage() -> impl IntoView {
let params = use_params_map();
view! {
{move || params.with(|params| {
match params.get("id").map(|id| id.parse::<i32>()) {
Some(Ok(id)) => {
Either::Left(view! { <AlbumIdPage id /> })
},
Some(Err(e)) => {
Either::Right(view! {
<Error<String>
title="Invalid Album ID"
error=e.to_string()
/>
})
},
None => {
Either::Right(view! {
<Error<String>
title="No Album ID"
message="You must specify an album ID to view its page."
/>
})
}
}
})}
}
}
#[component]
fn AlbumIdPage(#[prop(into)] id: Signal<i32>) -> impl IntoView {
let album = Resource::new(id, get_album);
let show_songs = RwSignal::new(false);
view! {
<Transition
fallback=move || view! { <Loading /> }
>
{move || album.get().map(|album| {
match album {
Ok(Some(album)) => {
show_songs.set(true);
EitherOf3::A(view! { <AlbumInfo album /> })
},
Ok(None) => EitherOf3::B(view! {
<Error<String>
title="Album Not Found"
message=format!("Album with ID {} not found", id.get())
/>
}),
Err(error) => EitherOf3::C(error.to_component()),
}
})}
</Transition>
<Show when=show_songs>
<AlbumSongs id />
</Show>
}
}
#[component]
fn AlbumInfo(album: frontend::Album) -> impl IntoView {
view! {
<div class="flex">
<img class="w-70 h-70 p-5" src={album.image_path} alt="Album Cover" />
<div class="self-center">
<h1 class="text-4xl">{album.title}</h1>
<SongArtists artists=album.artists />
</div>
</div>
}
.into_view()
}
#[component]
fn AlbumSongs(#[prop(into)] id: Signal<i32>) -> impl IntoView {
let songs = Resource::new(id, get_songs);
view! {
<Transition
fallback= move || view! { <Loading /> }
>
{move || songs.get().map(|songs| {
match songs {
Ok(songs) => Either::Left(
view! { <SongList songs=songs /> }
),
Err(error) => Either::Right(error.to_component()),
}
})}
</Transition>
}
}