AlbumData Query, API Endpoint, and Integration into AlbumPage
Some checks failed
Some checks failed
This commit is contained in:
parent
3b6035dd71
commit
dd14aa0b4d
@ -1,11 +1,15 @@
|
||||
use crate::models::Artist;
|
||||
use crate::components::dashboard_tile::DashboardTile;
|
||||
use crate::components::album_info::AlbumInfo;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
use chrono::NaiveDate;
|
||||
|
||||
/// Holds information about an album
|
||||
///
|
||||
/// Intended to be used in the front-end
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct AlbumData {
|
||||
/// Album id
|
||||
pub id: i32,
|
||||
|
@ -1,5 +1,6 @@
|
||||
use leptos::*;
|
||||
use crate::models::Album;
|
||||
use crate::albumdata::AlbumData;
|
||||
use crate::songdata::SongData;
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
@ -13,9 +14,9 @@ cfg_if! {
|
||||
}
|
||||
|
||||
#[server(endpoint = "album/get")]
|
||||
pub async fn get_album(id: i32) -> Result<Album, ServerFnError> {
|
||||
pub async fn get_album(id: i32) -> Result<AlbumData, ServerFnError> {
|
||||
let db_con = &mut get_db_conn();
|
||||
let album = Album::get_album(id,db_con)
|
||||
let album = Album::get_album_data(id,db_con)
|
||||
.map_err(|e| ServerFnError::<NoCustomError>::ServerError(format!("Error getting album: {}", e)))?;
|
||||
Ok(album)
|
||||
}
|
||||
|
@ -8,3 +8,4 @@ pub mod upload;
|
||||
pub mod song_list;
|
||||
pub mod loading;
|
||||
pub mod error;
|
||||
pub mod album_info;
|
27
src/components/album_info.rs
Normal file
27
src/components/album_info.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use leptos::leptos_dom::*;
|
||||
use leptos::*;
|
||||
use crate::albumdata::AlbumData;
|
||||
|
||||
#[component]
|
||||
pub fn AlbumInfo(albumdata: AlbumData) -> impl IntoView {
|
||||
view! {
|
||||
<div>
|
||||
<div>
|
||||
<img src={albumdata.image_path} alt="dashboard-tile" />
|
||||
</div>
|
||||
<div>
|
||||
<p>{albumdata.title}</p>
|
||||
<div>
|
||||
{
|
||||
albumdata.artists.iter().map(|artist| {
|
||||
view! {
|
||||
<p>{artist.name.clone()}</p>
|
||||
}
|
||||
}).collect::<Vec<_>>()
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}.into_view()
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ use chrono::{NaiveDate, NaiveDateTime};
|
||||
use leptos::{server, ServerFnError};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::songdata::SongData;
|
||||
use crate::albumdata::AlbumData;
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
@ -539,15 +540,44 @@ impl Album {
|
||||
/// * `Result<Album, Box<dyn Error>>` - A result indicating success with the desired album, or an error
|
||||
///
|
||||
#[cfg(feature = "ssr")]
|
||||
pub fn get_album(album_id: i32, conn: &mut PgPooledConn) -> Result<Album, Box<dyn Error>> {
|
||||
use crate::schema::albums::dsl::*;
|
||||
pub fn get_album_data(album_id: i32, conn: &mut PgPooledConn) -> Result<AlbumData, Box<dyn Error>> {
|
||||
use crate::schema::*;
|
||||
use crate::database::get_db_conn;
|
||||
|
||||
let album = albums
|
||||
let album: Vec<(Album, std::option::Option<Artist>)> = albums::table
|
||||
.find(album_id)
|
||||
.first(conn)?;
|
||||
.left_join(songs::table.on(albums::id.nullable().eq(songs::album_id)))
|
||||
.left_join(song_artists::table.inner_join(artists::table).on(songs::id.eq(song_artists::song_id)))
|
||||
.select((
|
||||
albums::all_columns,
|
||||
artists::all_columns.nullable()
|
||||
))
|
||||
.distinct()
|
||||
.load(conn)?;
|
||||
|
||||
Ok(album)
|
||||
let mut artist_list: Vec<Artist> = Vec::new();
|
||||
|
||||
for (_, artist) in album {
|
||||
if let Some(artist) = artist {
|
||||
artist_list.push(artist);
|
||||
}
|
||||
}
|
||||
// Get info of album
|
||||
let albuminfo = albums::table
|
||||
.filter(albums::id.eq(album_id))
|
||||
.first::<Album>(conn)?;
|
||||
|
||||
let img = albuminfo.image_path.unwrap_or("/assets/images/placeholders/MusicPlaceholder.svg".to_string());
|
||||
|
||||
let albumdata = AlbumData {
|
||||
id: albuminfo.id.unwrap(),
|
||||
title: albuminfo.title,
|
||||
artists: artist_list,
|
||||
release_date: albuminfo.release_date,
|
||||
image_path: img
|
||||
};
|
||||
|
||||
Ok(albumdata)
|
||||
}
|
||||
|
||||
/// Obtain an album from its albumid
|
||||
|
@ -1,9 +1,10 @@
|
||||
use leptos::leptos_dom::*;
|
||||
use leptos::*;
|
||||
use leptos_router::*;
|
||||
use crate::models::*;
|
||||
use crate::{albumdata, models::*};
|
||||
use crate::components::song_list::*;
|
||||
use crate::api::album::*;
|
||||
use crate::components::album_info::*;
|
||||
|
||||
|
||||
#[derive(Params, PartialEq)]
|
||||
@ -32,7 +33,35 @@ pub fn AlbumPage() -> impl IntoView {
|
||||
},
|
||||
);
|
||||
|
||||
let albumdata = create_resource(
|
||||
id,
|
||||
|value| async move {
|
||||
match value {
|
||||
Ok(v) => {get_album(v).await},
|
||||
Err(e) => {Err(ServerFnError::Request(format!("Error getting song data: {}", e).into()))},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
view! {
|
||||
<Suspense
|
||||
fallback=move || view! { <p>"Loading..."</p> }
|
||||
>
|
||||
{move || {
|
||||
albumdata.with( |albumdata| {
|
||||
match albumdata {
|
||||
Some(Ok(s)) => {
|
||||
view! { <AlbumInfo albumdata=(*s).clone()/> }
|
||||
},
|
||||
Some(Err(e)) => {
|
||||
view! { <div>{format!("Error loading albums: : {}",e)}</div> }.into_view()
|
||||
},
|
||||
None => {view! { }.into_view()}
|
||||
}
|
||||
})
|
||||
}}
|
||||
</Suspense>
|
||||
|
||||
<Suspense
|
||||
fallback=move || view! { <p>"Loading..."</p> }
|
||||
>
|
||||
@ -40,7 +69,7 @@ pub fn AlbumPage() -> impl IntoView {
|
||||
song_list.with( |song_list| {
|
||||
match song_list {
|
||||
Some(Ok(s)) => {
|
||||
view! { <SongList songs=(*s).clone().into()/> }.into_view()
|
||||
view! { <SongList songs=(*s).clone()/> }
|
||||
},
|
||||
Some(Err(e)) => {
|
||||
view! { <div>{format!("Error loading albums: : {}",e)}</div> }.into_view()
|
||||
|
Loading…
x
Reference in New Issue
Block a user