From dd14aa0b4d742fd4e397bf177455c809a372eb3d Mon Sep 17 00:00:00 2001
From: Aidan Westphal
Date: Wed, 20 Nov 2024 04:43:53 +0000
Subject: [PATCH] AlbumData Query, API Endpoint, and Integration into AlbumPage
---
src/albumdata.rs | 6 +++++-
src/api/album.rs | 5 +++--
src/components.rs | 1 +
src/components/album_info.rs | 27 ++++++++++++++++++++++++
src/models.rs | 40 +++++++++++++++++++++++++++++++-----
src/pages/albumpage.rs | 33 +++++++++++++++++++++++++++--
6 files changed, 102 insertions(+), 10 deletions(-)
create mode 100644 src/components/album_info.rs
diff --git a/src/albumdata.rs b/src/albumdata.rs
index 2b86b25..a621a8c 100644
--- a/src/albumdata.rs
+++ b/src/albumdata.rs
@@ -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,
@@ -36,4 +40,4 @@ impl DashboardTile for AlbumData {
fn description(&self) -> Option {
Some(format!("Album • {}", Artist::display_list(&self.artists)))
}
-}
+}
\ No newline at end of file
diff --git a/src/api/album.rs b/src/api/album.rs
index ff1f6cf..0bf9390 100644
--- a/src/api/album.rs
+++ b/src/api/album.rs
@@ -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 {
+pub async fn get_album(id: i32) -> Result {
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::::ServerError(format!("Error getting album: {}", e)))?;
Ok(album)
}
diff --git a/src/components.rs b/src/components.rs
index 2624877..de281a7 100644
--- a/src/components.rs
+++ b/src/components.rs
@@ -8,3 +8,4 @@ pub mod upload;
pub mod song_list;
pub mod loading;
pub mod error;
+pub mod album_info;
\ No newline at end of file
diff --git a/src/components/album_info.rs b/src/components/album_info.rs
new file mode 100644
index 0000000..b44a1f5
--- /dev/null
+++ b/src/components/album_info.rs
@@ -0,0 +1,27 @@
+use leptos::leptos_dom::*;
+use leptos::*;
+use crate::albumdata::AlbumData;
+
+#[component]
+pub fn AlbumInfo(albumdata: AlbumData) -> impl IntoView {
+ view! {
+
+
+

+
+
+
{albumdata.title}
+
+ {
+ albumdata.artists.iter().map(|artist| {
+ view! {
+
{artist.name.clone()}
+ }
+ }).collect::
>()
+ }
+
+
+
+ }.into_view()
+}
+
diff --git a/src/models.rs b/src/models.rs
index 08dd956..71c4180 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -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>` - 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> {
- use crate::schema::albums::dsl::*;
+ pub fn get_album_data(album_id: i32, conn: &mut PgPooledConn) -> Result> {
+ use crate::schema::*;
use crate::database::get_db_conn;
- let album = albums
+ let album: Vec<(Album, std::option::Option)> = 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 = 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::(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
diff --git a/src/pages/albumpage.rs b/src/pages/albumpage.rs
index 162f870..62c4ed1 100644
--- a/src/pages/albumpage.rs
+++ b/src/pages/albumpage.rs
@@ -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! {
+ "Loading..."
}
+ >
+ {move || {
+ albumdata.with( |albumdata| {
+ match albumdata {
+ Some(Ok(s)) => {
+ view! { }
+ },
+ Some(Err(e)) => {
+ view! { {format!("Error loading albums: : {}",e)}
}.into_view()
+ },
+ None => {view! { }.into_view()}
+ }
+ })
+ }}
+
+
"Loading..." }
>
@@ -40,7 +69,7 @@ pub fn AlbumPage() -> impl IntoView {
song_list.with( |song_list| {
match song_list {
Some(Ok(s)) => {
- view! { }.into_view()
+ view! { }
},
Some(Err(e)) => {
view! { {format!("Error loading albums: : {}",e)}
}.into_view()