From df01bafbd139417c9b645ec2951573c82868a142 Mon Sep 17 00:00:00 2001
From: Aidan Westphal
Date: Tue, 22 Oct 2024 03:32:55 +0000
Subject: [PATCH 01/11] Album Page Component
---
src/app.rs | 2 ++
src/models.rs | 22 +++++++++++++++++--
src/pages.rs | 3 ++-
src/pages/album.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++
src/playbar.rs | 2 +-
src/songdata.rs | 3 ++-
6 files changed, 81 insertions(+), 5 deletions(-)
create mode 100644 src/pages/album.rs
diff --git a/src/app.rs b/src/app.rs
index ed9fd1b..ed8b252 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -7,6 +7,7 @@ use leptos_meta::*;
use leptos_router::*;
use crate::pages::login::*;
use crate::pages::signup::*;
+use crate::pages::album::*;
use crate::error_template::{AppError, ErrorTemplate};
@@ -42,6 +43,7 @@ pub fn App() -> impl IntoView {
+
diff --git a/src/models.rs b/src/models.rs
index b96c8d2..b2534dc 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -1,13 +1,15 @@
use std::time::SystemTime;
+use leptos::{server, ServerFnError};
use time::Date;
use serde::{Deserialize, Serialize};
+use crate::songdata::SongData;
use cfg_if::cfg_if;
cfg_if! {
if #[cfg(feature = "ssr")] {
use diesel::prelude::*;
- use crate::database::PgPooledConn;
+ use crate::database::*;
use std::error::Error;
}
}
@@ -499,7 +501,7 @@ impl Album {
Ok(())
}
- /// Get songs by this artist from the database
+ /// Get songs by this album from the database
///
/// The `id` field of this album must be present (Some) to get songs
///
@@ -528,6 +530,22 @@ impl Album {
}
}
+#[server(endpoint = "get_album")]
+pub async fn get_album(a_id: i32) -> Result,ServerFnError> {
+ use crate::schema::songs::dsl::*;
+ use crate::schema::song_artists::dsl::*;
+
+ let conn = get_db_conn();
+
+ let songs = songs
+ .inner_join(song_artists)
+ .filter(album_id.eq(a_id))
+ .select(songs::all_columns())
+ .load(conn)?;
+
+ Ok(songs.into())
+}
+
/// Model for a song
#[cfg_attr(feature = "ssr", derive(Queryable, Selectable, Insertable))]
#[cfg_attr(feature = "ssr", diesel(table_name = crate::schema::songs))]
diff --git a/src/pages.rs b/src/pages.rs
index 40f63fd..c1e787a 100644
--- a/src/pages.rs
+++ b/src/pages.rs
@@ -1,2 +1,3 @@
pub mod login;
-pub mod signup;
\ No newline at end of file
+pub mod signup;
+pub mod album;
\ No newline at end of file
diff --git a/src/pages/album.rs b/src/pages/album.rs
new file mode 100644
index 0000000..bbe3f35
--- /dev/null
+++ b/src/pages/album.rs
@@ -0,0 +1,54 @@
+use leptos::leptos_dom::*;
+use leptos::*;
+use leptos_icons::*;
+use leptos_router::*;
+use crate::models::*;
+use crate::components::song_list::*;
+
+
+#[derive(Params, PartialEq)]
+struct AlbumParams {
+ id: i32
+}
+
+#[component]
+pub fn AlbumPage() -> impl IntoView {
+ let params = use_params::();
+
+ let id = move || {params.with(|params| {
+ params.as_ref()
+ .map(|params| params.id)
+ .map_err(|e| e.clone())
+ })
+ };
+
+ let song_list = create_resource(
+ id,
+ |value| async move {
+ match value {
+ Ok(v) => {get_album(v).await},
+ Err(e) => {Err(ServerFnError::Request("Invalid album!".into()))},
+ }
+ },
+ );
+
+ view! {
+ "Loading..."
}
+ >
+ {move || {
+ song_list.with( |song_list| {
+ match song_list {
+ Some(Ok(s)) => {
+ view! { }.into_view()
+ },
+ Some(Err(e)) => {
+ view! { "Error loading albums"
}.into_view()
+ },
+ None => {view! { }.into_view()}
+ }
+ })
+ }}
+
+ }
+}
\ No newline at end of file
diff --git a/src/playbar.rs b/src/playbar.rs
index d113b7a..c14e9f7 100644
--- a/src/playbar.rs
+++ b/src/playbar.rs
@@ -444,7 +444,7 @@ fn QueueToggle(status: RwSignal) -> impl IntoView {
toggle_queue(status);
log!("queue button pressed, queue status: {:?}", status.with_untracked(|status| status.queue_open));
};
-
+
// We use this to prevent the buttons from being focused when clicked
// If buttons were focused on clicks, then pressing space bar to play/pause would "click" the button
// and trigger unwanted behavior
diff --git a/src/songdata.rs b/src/songdata.rs
index 36e5679..1da9e69 100644
--- a/src/songdata.rs
+++ b/src/songdata.rs
@@ -1,12 +1,13 @@
use crate::models::{Album, Artist, Song};
use crate::components::dashboard_tile::DashboardTile;
+use serde::{Serialize, Deserialize};
use time::Date;
/// Holds information about a song
///
/// Intended to be used in the front-end, as it includes artist and album objects, rather than just their ids.
-#[derive(Clone)]
+#[derive(Clone, Serialize, Deserialize)]
pub struct SongData {
/// Song id
pub id: i32,
From fe1b76e6e40d9a42902e2a4839fa31aa72190b39 Mon Sep 17 00:00:00 2001
From: Aidan Westphal
Date: Fri, 25 Oct 2024 21:23:21 +0000
Subject: [PATCH 02/11] API Endpoints for Album Queries
---
src/api/album.rs | 37 ++++++++++++++++++++++++++++
src/api/mod.rs | 1 +
src/app.rs | 4 +--
src/models.rs | 34 ++++++++++++++-----------
src/pages.rs | 2 +-
src/pages/{album.rs => albumpage.rs} | 7 +++---
6 files changed, 65 insertions(+), 20 deletions(-)
create mode 100644 src/api/album.rs
rename src/pages/{album.rs => albumpage.rs} (92%)
diff --git a/src/api/album.rs b/src/api/album.rs
new file mode 100644
index 0000000..82f62c9
--- /dev/null
+++ b/src/api/album.rs
@@ -0,0 +1,37 @@
+use leptos::*;
+use crate::models::Album;
+use crate::models::Song;
+use crate::songdata::SongData;
+
+use cfg_if::cfg_if;
+
+cfg_if! {
+ if #[cfg(feature = "ssr")] {
+ use leptos::server_fn::error::NoCustomError;
+ use crate::database::get_db_conn;
+ }
+}
+
+#[server(endpoint = "album/get")]
+pub async fn get_album(id: Option) -> Result {
+ let db_con = &mut get_db_conn();
+ let album = Album::get_album(id,db_con)
+ .map_err(|e| ServerFnError::::ServerError(format!("Error getting album: {}", e)))?;
+ Ok(album)
+}
+
+#[server(endpoint = "album/get_songs")]
+pub async fn get_songs(album: Option) -> Result, ServerFnError> {
+ let db_con = &mut get_db_conn();
+ let songs = album.get_songs(db_con)
+ .map_err(|e| ServerFnError::::ServerError(format!("Error getting album: {}", e)))?;
+ Ok(songs)
+}
+
+// #[server(endpoint = "album/get_song_list")]
+// pub async fn get_song_list(album: Option) -> Result, ServerFnError> {
+// songs = get_songs(album)?;
+
+// let mut song_data_list = Vec::new();
+// // TODO: NEEDS SONG DATA QUERIES
+// }
diff --git a/src/api/mod.rs b/src/api/mod.rs
index c287a07..e9ee6c9 100644
--- a/src/api/mod.rs
+++ b/src/api/mod.rs
@@ -1,3 +1,4 @@
pub mod history;
pub mod profile;
pub mod songs;
+pub mod album;
diff --git a/src/app.rs b/src/app.rs
index ed8b252..689e9cd 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -7,7 +7,7 @@ use leptos_meta::*;
use leptos_router::*;
use crate::pages::login::*;
use crate::pages::signup::*;
-use crate::pages::album::*;
+use crate::pages::albumpage::*;
use crate::error_template::{AppError, ErrorTemplate};
@@ -43,7 +43,7 @@ pub fn App() -> impl IntoView {
-
+ //
diff --git a/src/models.rs b/src/models.rs
index b2534dc..e1a8a63 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -528,22 +528,28 @@ impl Album {
Ok(my_songs)
}
-}
-#[server(endpoint = "get_album")]
-pub async fn get_album(a_id: i32) -> Result,ServerFnError> {
- use crate::schema::songs::dsl::*;
- use crate::schema::song_artists::dsl::*;
-
- let conn = get_db_conn();
-
- let songs = songs
- .inner_join(song_artists)
- .filter(album_id.eq(a_id))
- .select(songs::all_columns())
- .load(conn)?;
+ /// Obtain an album from its albumid
+ /// # Arguments
+ ///
+ /// * `album_id` - The id of the album to select
+ /// * `conn` - A mutable reference to a database connection
+ ///
+ /// # Returns
+ ///
+ /// * `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::*;
+ use crate::database::get_db_conn;
- Ok(songs.into())
+ let album = albums
+ .find(album_id)
+ .first(conn)?;
+
+ Ok(album)
+ }
}
/// Model for a song
diff --git a/src/pages.rs b/src/pages.rs
index c1e787a..057a60a 100644
--- a/src/pages.rs
+++ b/src/pages.rs
@@ -1,3 +1,3 @@
pub mod login;
pub mod signup;
-pub mod album;
\ No newline at end of file
+pub mod albumpage;
\ No newline at end of file
diff --git a/src/pages/album.rs b/src/pages/albumpage.rs
similarity index 92%
rename from src/pages/album.rs
rename to src/pages/albumpage.rs
index bbe3f35..915d9f4 100644
--- a/src/pages/album.rs
+++ b/src/pages/albumpage.rs
@@ -1,6 +1,5 @@
use leptos::leptos_dom::*;
use leptos::*;
-use leptos_icons::*;
use leptos_router::*;
use crate::models::*;
use crate::components::song_list::*;
@@ -11,6 +10,7 @@ struct AlbumParams {
id: i32
}
+/*
#[component]
pub fn AlbumPage() -> impl IntoView {
let params = use_params::();
@@ -43,7 +43,7 @@ pub fn AlbumPage() -> impl IntoView {
view! { }.into_view()
},
Some(Err(e)) => {
- view! { "Error loading albums"
}.into_view()
+ view! { "Error loading albums: :e"
}.into_view()
},
None => {view! { }.into_view()}
}
@@ -51,4 +51,5 @@ pub fn AlbumPage() -> impl IntoView {
}}
}
-}
\ No newline at end of file
+}
+*/
From ff24f68eede077b71c712531eb24af17b4ae756e Mon Sep 17 00:00:00 2001
From: Aidan Westphal
Date: Sat, 26 Oct 2024 03:53:03 +0000
Subject: [PATCH 03/11] A very big SQL Query
---
src/models.rs | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/src/models.rs b/src/models.rs
index e1a8a63..441e7fa 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -550,6 +550,123 @@ impl Album {
Ok(album)
}
+
+ /// Obtain an album from its albumid
+ /// # Arguments
+ ///
+ /// * `album_id` - The id of the album to select
+ /// * `conn` - A mutable reference to a database connection
+ ///
+ /// # Returns
+ ///
+ /// * `Result>` - A result indicating success with the desired album, or an error
+ ///
+ #[cfg(feature = "ssr")]
+ pub fn get_song_data(album_id: i32, conn: &mut PgPooledConn) -> Result> {
+ use crate::schema::albums::dsl::*;
+ use crate::database::get_db_conn;
+
+ "
+ WITH R1 AS(
+ SELECT
+ id AS album_id,
+ title AS album_title,
+ release_date AS album_release_date,
+ image_path AS album_image_path
+ FROM albums WHERE [ALBUM_ID] = id
+ ),
+ R2 AS(
+ SELECT
+ id,
+ title,
+ track,
+ duration,
+ release_date,
+ storage_path AS song_path,
+ image_path,
+ r.album_id,
+ album_title,
+ album_release_date,
+ album_image_path
+ FROM
+ R1 r LEFT JOIN songs s ON r.album_id = s.album_id
+ ),
+ R7 AS(
+ SELECT
+ song_id,
+ artist_id,
+ name AS artist_name
+ FROM
+ song_artists sa LEFT JOIN artists a ON sa.artist_id = a.id
+ ),
+ R3 AS(
+ SELECT
+ s.song_id,
+ artist_name,
+ artist_id
+ FROM
+ (SELECT id AS song_id FROM R2) s LEFT JOIN R7 a ON s.song_id = a.song_id
+ ),
+ R4 AS(
+ SELECT
+ id,
+ title,
+ track,
+ duration,
+ release_date,
+ song_path,
+ image_path,
+ r.album_id,
+ album_title,
+ album_release_date,
+ album_image_path,
+ artist_id,
+ artist_name
+ FROM
+ R2 r LEFT JOIN R3 a ON r.id = a.song_id
+ ),
+ R5 AS(
+ SELECT
+ r.id,
+ count(sl.user_id) <> 0 AS liked
+ FROM
+ R4 r LEFT JOIN song_likes sl ON sl.user_id = [USER_ID] AND r.id = sl.song_id
+ GROUP BY
+ r.id
+ ),
+ R6 AS(
+ SELECT
+ r.id,
+ count(sd.user_id) <> 0 AS disliked
+ FROM
+ R4 r LEFT JOIN song_dislikes sd ON sd.user_id = [USER_ID] AND r.id = sd.song_id
+ GROUP BY
+ r.id
+ )
+ SELECT
+ r.id,
+ title,
+ track,
+ duration,
+ release_date,
+ song_path,
+ image_path,
+ r.album_id,
+ album_title,
+ album_release_date,
+ album_image_path,
+ artist_id,
+ artist_name,
+ liked,
+ disliked
+ FROM R4 r
+ LEFT JOIN R5 likes ON likes.id = r.id
+ LEFT JOIN R6 dislikes ON dislikes.id = r.id
+ ;
+ "
+
+ Ok(album)
+ }
}
/// Model for a song
From 7a1ffaad475ed0e3df348504e537e3ebcd1edb09 Mon Sep 17 00:00:00 2001
From: Aidan Westphal
Date: Fri, 8 Nov 2024 22:16:46 +0000
Subject: [PATCH 04/11] Finished Query for Song Data from Album
---
src/api/album.rs | 36 +++++------
src/models.rs | 156 ++++++++++++++++-------------------------------
2 files changed, 72 insertions(+), 120 deletions(-)
diff --git a/src/api/album.rs b/src/api/album.rs
index 82f62c9..8d62d95 100644
--- a/src/api/album.rs
+++ b/src/api/album.rs
@@ -9,29 +9,29 @@ cfg_if! {
if #[cfg(feature = "ssr")] {
use leptos::server_fn::error::NoCustomError;
use crate::database::get_db_conn;
+ use crate::auth::get_user;
}
}
-#[server(endpoint = "album/get")]
-pub async fn get_album(id: Option) -> Result {
- let db_con = &mut get_db_conn();
- let album = Album::get_album(id,db_con)
- .map_err(|e| ServerFnError::::ServerError(format!("Error getting album: {}", e)))?;
- Ok(album)
-}
+// #[server(endpoint = "album/get")]
+// pub async fn get_album(id: Option) -> Result {
+// let db_con = &mut get_db_conn();
+// let album = Album::get_album(id,db_con)
+// .map_err(|e| ServerFnError::::ServerError(format!("Error getting album: {}", e)))?;
+// Ok(album)
+// }
-#[server(endpoint = "album/get_songs")]
-pub async fn get_songs(album: Option) -> Result, ServerFnError> {
- let db_con = &mut get_db_conn();
- let songs = album.get_songs(db_con)
- .map_err(|e| ServerFnError::::ServerError(format!("Error getting album: {}", e)))?;
- Ok(songs)
-}
+// #[server(endpoint = "album/get_songs")]
+// pub async fn get_songs(album: Option) -> Result, ServerFnError> {
+// let db_con = &mut get_db_conn();
+// let songs = album.get_songs(db_con)
+// .map_err(|e| ServerFnError::::ServerError(format!("Error getting album: {}", e)))?;
+// Ok(songs)
+// }
// #[server(endpoint = "album/get_song_list")]
-// pub async fn get_song_list(album: Option) -> Result, ServerFnError> {
-// songs = get_songs(album)?;
-
-// let mut song_data_list = Vec::new();
+// pub async fn get_song_data(album: Option) -> Result, ServerFnError> {
+// let user = get_user().await?;
+// let db_con = &mut get_db_conn();
// // TODO: NEEDS SONG DATA QUERIES
// }
diff --git a/src/models.rs b/src/models.rs
index 441e7fa..46475f9 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -540,7 +540,7 @@ 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> {
+ pub fn get_album(album_id: i32, user_id: i32, conn: &mut PgPooledConn) -> Result> {
use crate::schema::albums::dsl::*;
use crate::database::get_db_conn;
@@ -562,110 +562,62 @@ impl Album {
/// * `Result>` - A result indicating success with the desired album, or an error
///
#[cfg(feature = "ssr")]
- pub fn get_song_data(album_id: i32, conn: &mut PgPooledConn) -> Result> {
- use crate::schema::albums::dsl::*;
+ pub fn get_song_data(album_id: i32, user_like_dislike_id: i32, conn: &mut PgPooledConn) -> Result, Box> {
+ use crate::schema::*;
use crate::database::get_db_conn;
+ use std::collections::HashMap;
- "
- WITH R1 AS(
- SELECT
- id AS album_id,
- title AS album_title,
- release_date AS album_release_date,
- image_path AS album_image_path
- FROM albums WHERE [ALBUM_ID] = id
- ),
- R2 AS(
- SELECT
- id,
- title,
- track,
- duration,
- release_date,
- storage_path AS song_path,
- image_path,
- r.album_id,
- album_title,
- album_release_date,
- album_image_path
- FROM
- R1 r LEFT JOIN songs s ON r.album_id = s.album_id
- ),
- R7 AS(
- SELECT
- song_id,
- artist_id,
- name AS artist_name
- FROM
- song_artists sa LEFT JOIN artists a ON sa.artist_id = a.id
- ),
- R3 AS(
- SELECT
- s.song_id,
- artist_name,
- artist_id
- FROM
- (SELECT id AS song_id FROM R2) s LEFT JOIN R7 a ON s.song_id = a.song_id
- ),
- R4 AS(
- SELECT
- id,
- title,
- track,
- duration,
- release_date,
- song_path,
- image_path,
- r.album_id,
- album_title,
- album_release_date,
- album_image_path,
- artist_id,
- artist_name
- FROM
- R2 r LEFT JOIN R3 a ON r.id = a.song_id
- ),
- R5 AS(
- SELECT
- r.id,
- count(sl.user_id) <> 0 AS liked
- FROM
- R4 r LEFT JOIN song_likes sl ON sl.user_id = [USER_ID] AND r.id = sl.song_id
- GROUP BY
- r.id
- ),
- R6 AS(
- SELECT
- r.id,
- count(sd.user_id) <> 0 AS disliked
- FROM
- R4 r LEFT JOIN song_dislikes sd ON sd.user_id = [USER_ID] AND r.id = sd.song_id
- GROUP BY
- r.id
- )
- SELECT
- r.id,
- title,
- track,
- duration,
- release_date,
- song_path,
- image_path,
- r.album_id,
- album_title,
- album_release_date,
- album_image_path,
- artist_id,
- artist_name,
- liked,
- disliked
- FROM R4 r
- LEFT JOIN R5 likes ON likes.id = r.id
- LEFT JOIN R6 dislikes ON dislikes.id = r.id
- ;
- "
+ let songs: Vec<(Album, Option, Option, Option<(i32, i32)>, Option<(i32, i32)>)> =
+ albums::table
+ .find(album_id)
+ .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)))
+ .left_join(song_likes::table.on(songs::id.eq(song_likes::song_id).and(song_likes::user_id.eq(user_like_dislike_id))))
+ .left_join(song_dislikes::table.on(songs::id.eq(song_dislikes::song_id).and(song_dislikes::user_id.eq(user_like_dislike_id))))
+ .select((
+ albums::all_columns,
+ songs::all_columns.nullable(),
+ artists::all_columns.nullable(),
+ song_likes::all_columns.nullable(),
+ song_dislikes::all_columns.nullable()
+ ))
+ .load(conn)?;
- Ok(album)
+ let mut album_songs: HashMap = HashMap::with_capacity(songs.len());
+
+ for (album, song, artist, like, dislike) in songs {
+ if let Some(song) = song {
+ let like_dislike = match (like, dislike) {
+ (Some(_), Some(_)) => Some((true, true)),
+ (Some(_), None) => Some((true, false)),
+ (None, Some(_)) => Some((false, true)),
+ _ => None,
+ };
+
+ let image_path = song.image_path.unwrap_or(
+ album.image_path.clone().unwrap_or("/assets/images/placeholders/MusicPlaceholder.svg".to_string()));
+
+ let songdata = SongData {
+ id: song.id.unwrap(),
+ title: song.title,
+ artists: artist.map(|artist| vec![artist]).unwrap_or_default(),
+ album: Some(album),
+ track: song.track,
+ duration: song.duration,
+ release_date: song.release_date,
+ song_path: song.storage_path,
+ image_path: image_path,
+ like_dislike: like_dislike,
+ };
+
+ album_songs.insert(song.id.unwrap(), songdata);
+ }
+ }
+
+ // Sort the songs by date
+ let mut songdata: Vec = album_songs.into_values().collect();
+ songdata.sort_by(|a, b| b.track.cmp(&a.track));
+ Ok(songdata)
}
}
From 568f6ada0e4d4dc92ecfa4584f224f4f92728778 Mon Sep 17 00:00:00 2001
From: Aidan Westphal
Date: Tue, 12 Nov 2024 21:44:30 +0000
Subject: [PATCH 05/11] Working Albums Page (BETA)
---
src/api/album.rs | 37 ++++++++++++++++---------------------
src/app.rs | 2 +-
src/models.rs | 2 +-
src/pages/albumpage.rs | 10 +++++-----
4 files changed, 23 insertions(+), 28 deletions(-)
diff --git a/src/api/album.rs b/src/api/album.rs
index 8d62d95..33a5299 100644
--- a/src/api/album.rs
+++ b/src/api/album.rs
@@ -13,25 +13,20 @@ cfg_if! {
}
}
-// #[server(endpoint = "album/get")]
-// pub async fn get_album(id: Option) -> Result {
-// let db_con = &mut get_db_conn();
-// let album = Album::get_album(id,db_con)
-// .map_err(|e| ServerFnError::::ServerError(format!("Error getting album: {}", e)))?;
-// Ok(album)
-// }
+#[server(endpoint = "album/get")]
+pub async fn get_album(id: i32) -> Result {
+ let db_con = &mut get_db_conn();
+ let album = Album::get_album(id,db_con)
+ .map_err(|e| ServerFnError::::ServerError(format!("Error getting album: {}", e)))?;
+ Ok(album)
+}
-// #[server(endpoint = "album/get_songs")]
-// pub async fn get_songs(album: Option) -> Result, ServerFnError> {
-// let db_con = &mut get_db_conn();
-// let songs = album.get_songs(db_con)
-// .map_err(|e| ServerFnError::::ServerError(format!("Error getting album: {}", e)))?;
-// Ok(songs)
-// }
-
-// #[server(endpoint = "album/get_song_list")]
-// pub async fn get_song_data(album: Option) -> Result, ServerFnError> {
-// let user = get_user().await?;
-// let db_con = &mut get_db_conn();
-// // TODO: NEEDS SONG DATA QUERIES
-// }
+#[server(endpoint = "album/get_songs")]
+pub async fn get_songs(id: i32) -> Result, ServerFnError> {
+ let user = get_user().await?;
+ let db_con = &mut get_db_conn();
+ // TODO: NEEDS SONG DATA QUERIES
+ let songdata = Album::get_song_data(id,user.id.unwrap(),db_con)
+ .map_err(|e| ServerFnError::::ServerError(format!("Error getting song data: {}", e)))?;
+ Ok(songdata)
+}
\ No newline at end of file
diff --git a/src/app.rs b/src/app.rs
index 689e9cd..e3e9226 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -43,7 +43,7 @@ pub fn App() -> impl IntoView {
- //
+
diff --git a/src/models.rs b/src/models.rs
index 46475f9..ed28ba6 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -540,7 +540,7 @@ impl Album {
/// * `Result>` - A result indicating success with the desired album, or an error
///
#[cfg(feature = "ssr")]
- pub fn get_album(album_id: i32, user_id: i32, conn: &mut PgPooledConn) -> Result> {
+ pub fn get_album(album_id: i32, conn: &mut PgPooledConn) -> Result> {
use crate::schema::albums::dsl::*;
use crate::database::get_db_conn;
diff --git a/src/pages/albumpage.rs b/src/pages/albumpage.rs
index 915d9f4..392cc9b 100644
--- a/src/pages/albumpage.rs
+++ b/src/pages/albumpage.rs
@@ -3,6 +3,7 @@ use leptos::*;
use leptos_router::*;
use crate::models::*;
use crate::components::song_list::*;
+use crate::api::album::*;
#[derive(Params, PartialEq)]
@@ -10,7 +11,6 @@ struct AlbumParams {
id: i32
}
-/*
#[component]
pub fn AlbumPage() -> impl IntoView {
let params = use_params::();
@@ -26,8 +26,8 @@ pub fn AlbumPage() -> impl IntoView {
id,
|value| async move {
match value {
- Ok(v) => {get_album(v).await},
- Err(e) => {Err(ServerFnError::Request("Invalid album!".into()))},
+ Ok(v) => {get_songs(v).await},
+ Err(e) => {Err(ServerFnError::Request(format!("Error getting song data: {}", e).into()))},
}
},
);
@@ -40,7 +40,7 @@ pub fn AlbumPage() -> impl IntoView {
song_list.with( |song_list| {
match song_list {
Some(Ok(s)) => {
- view! { }.into_view()
+ view! { }.into_view()
},
Some(Err(e)) => {
view! { "Error loading albums: :e"
}.into_view()
@@ -52,4 +52,4 @@ pub fn AlbumPage() -> impl IntoView {
}
}
-*/
+
From 3b6035dd7180eef9bfbead01543678efeab06f92 Mon Sep 17 00:00:00 2001
From: Aidan Westphal
Date: Wed, 20 Nov 2024 02:12:09 +0000
Subject: [PATCH 06/11] Album pages for users not signed in
---
src/api/album.rs | 6 ++--
src/models.rs | 64 ++++++++++++++++++++++++++++--------------
src/pages/albumpage.rs | 2 +-
3 files changed, 47 insertions(+), 25 deletions(-)
diff --git a/src/api/album.rs b/src/api/album.rs
index 33a5299..ff1f6cf 100644
--- a/src/api/album.rs
+++ b/src/api/album.rs
@@ -1,6 +1,5 @@
use leptos::*;
use crate::models::Album;
-use crate::models::Song;
use crate::songdata::SongData;
use cfg_if::cfg_if;
@@ -23,10 +22,11 @@ pub async fn get_album(id: i32) -> Result {
#[server(endpoint = "album/get_songs")]
pub async fn get_songs(id: i32) -> Result, ServerFnError> {
- let user = get_user().await?;
+ use crate::auth::get_logged_in_user;
+ let user = get_logged_in_user().await?;
let db_con = &mut get_db_conn();
// TODO: NEEDS SONG DATA QUERIES
- let songdata = Album::get_song_data(id,user.id.unwrap(),db_con)
+ let songdata = Album::get_song_data(id,user,db_con)
.map_err(|e| ServerFnError::::ServerError(format!("Error getting song data: {}", e)))?;
Ok(songdata)
}
\ No newline at end of file
diff --git a/src/models.rs b/src/models.rs
index 4a34b86..08dd956 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -561,30 +561,52 @@ impl Album {
/// * `Result>` - A result indicating success with the desired album, or an error
///
#[cfg(feature = "ssr")]
- pub fn get_song_data(album_id: i32, user_like_dislike_id: i32, conn: &mut PgPooledConn) -> Result, Box> {
+ pub fn get_song_data(album_id: i32, user_like_dislike: Option, conn: &mut PgPooledConn) -> Result, Box> {
use crate::schema::*;
use crate::database::get_db_conn;
use std::collections::HashMap;
-
- let songs: Vec<(Album, Option, Option, Option<(i32, i32)>, Option<(i32, i32)>)> =
- albums::table
- .find(album_id)
- .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)))
- .left_join(song_likes::table.on(songs::id.eq(song_likes::song_id).and(song_likes::user_id.eq(user_like_dislike_id))))
- .left_join(song_dislikes::table.on(songs::id.eq(song_dislikes::song_id).and(song_dislikes::user_id.eq(user_like_dislike_id))))
- .select((
- albums::all_columns,
- songs::all_columns.nullable(),
- artists::all_columns.nullable(),
- song_likes::all_columns.nullable(),
- song_dislikes::all_columns.nullable()
- ))
- .load(conn)?;
-
- let mut album_songs: HashMap = HashMap::with_capacity(songs.len());
- for (album, song, artist, like, dislike) in songs {
+ let song_list = if let Some(user_like_dislike) = user_like_dislike {
+ let user_like_dislike_id = user_like_dislike.id.unwrap();
+ let song_list: Vec<(Album, Option, Option, Option<(i32, i32)>, Option<(i32, i32)>)> =
+ albums::table
+ .find(album_id)
+ .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)))
+ .left_join(song_likes::table.on(songs::id.eq(song_likes::song_id).and(song_likes::user_id.eq(user_like_dislike_id))))
+ .left_join(song_dislikes::table.on(songs::id.eq(song_dislikes::song_id).and(song_dislikes::user_id.eq(user_like_dislike_id))))
+ .select((
+ albums::all_columns,
+ songs::all_columns.nullable(),
+ artists::all_columns.nullable(),
+ song_likes::all_columns.nullable(),
+ song_dislikes::all_columns.nullable()
+ ))
+ .order(songs::track.asc())
+ .load(conn)?;
+ song_list
+ } else {
+ let song_list: Vec<(Album, Option, Option)> =
+ albums::table
+ .find(album_id)
+ .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,
+ songs::all_columns.nullable(),
+ artists::all_columns.nullable()
+ ))
+ .order(songs::track.asc())
+ .load(conn)?;
+
+ let song_list: Vec<(Album, Option, Option, Option<(i32, i32)>, Option<(i32, i32)>)> =
+ song_list.into_iter().map( |(album, song, artist)| (album, song, artist, None, None) ).collect();
+ song_list
+ };
+
+ let mut album_songs: HashMap = HashMap::with_capacity(song_list.len());
+
+ for (album, song, artist, like, dislike) in song_list {
if let Some(song) = song {
let like_dislike = match (like, dislike) {
(Some(_), Some(_)) => Some((true, true)),
@@ -612,7 +634,7 @@ impl Album {
album_songs.insert(song.id.unwrap(), songdata);
}
}
-
+
// Sort the songs by date
let mut songdata: Vec = album_songs.into_values().collect();
songdata.sort_by(|a, b| b.track.cmp(&a.track));
diff --git a/src/pages/albumpage.rs b/src/pages/albumpage.rs
index 392cc9b..162f870 100644
--- a/src/pages/albumpage.rs
+++ b/src/pages/albumpage.rs
@@ -43,7 +43,7 @@ pub fn AlbumPage() -> impl IntoView {
view! { }.into_view()
},
Some(Err(e)) => {
- view! { "Error loading albums: :e"
}.into_view()
+ view! { {format!("Error loading albums: : {}",e)}
}.into_view()
},
None => {view! { }.into_view()}
}
From dd14aa0b4d742fd4e397bf177455c809a372eb3d Mon Sep 17 00:00:00 2001
From: Aidan Westphal
Date: Wed, 20 Nov 2024 04:43:53 +0000
Subject: [PATCH 07/11] 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()
From 21a17a8eb52ca3594099dabebc2e7f74b2680c74 Mon Sep 17 00:00:00 2001
From: Aidan Westphal
Date: Fri, 22 Nov 2024 21:34:21 +0000
Subject: [PATCH 08/11] Album Page Styling
---
src/components/album_info.rs | 14 +++----
src/pages/albumpage.rs | 74 +++++++++++++++++++-----------------
style/album_page.scss | 67 ++++++++++++++++++++++++++++++++
style/main.scss | 1 +
style/theme.scss | 3 +-
5 files changed, 115 insertions(+), 44 deletions(-)
create mode 100644 style/album_page.scss
diff --git a/src/components/album_info.rs b/src/components/album_info.rs
index b44a1f5..03b2950 100644
--- a/src/components/album_info.rs
+++ b/src/components/album_info.rs
@@ -5,17 +5,15 @@ use crate::albumdata::AlbumData;
#[component]
pub fn AlbumInfo(albumdata: AlbumData) -> impl IntoView {
view! {
-
-
-

-
-
-
{albumdata.title}
-
+
+

+
+
{albumdata.title}
+
{
albumdata.artists.iter().map(|artist| {
view! {
-
{artist.name.clone()}
+
{artist.name.clone()}
}
}).collect::
>()
}
diff --git a/src/pages/albumpage.rs b/src/pages/albumpage.rs
index 62c4ed1..47332ac 100644
--- a/src/pages/albumpage.rs
+++ b/src/pages/albumpage.rs
@@ -44,41 +44,45 @@ pub fn AlbumPage() -> impl IntoView {
);
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..." }
- >
- {move || {
- song_list.with( |song_list| {
- match song_list {
- Some(Ok(s)) => {
- view! { }
- },
- Some(Err(e)) => {
- view! { {format!("Error loading albums: : {}",e)}
}.into_view()
- },
- None => {view! { }.into_view()}
- }
- })
- }}
-
+
+
+
+
"Loading..." }
+ >
+ {move || {
+ song_list.with( |song_list| {
+ match song_list {
+ Some(Ok(s)) => {
+ view! { }
+ },
+ Some(Err(e)) => {
+ view! { {format!("Error loading albums: : {}",e)}
}.into_view()
+ },
+ None => {view! { }.into_view()}
+ }
+ })
+ }}
+
+
}
}
diff --git a/style/album_page.scss b/style/album_page.scss
new file mode 100644
index 0000000..55b306b
--- /dev/null
+++ b/style/album_page.scss
@@ -0,0 +1,67 @@
+@import 'theme.scss';
+
+
+
+.album-page-container {
+ width: 90vw;
+
+ .album-header {
+ height: 40vh;
+ width: 65vw;
+ margin: auto;
+
+
+ padding:20px;
+
+ background-image: linear-gradient($accent-color, $background-color);
+ border-radius: 15px;
+
+ .album-info {
+ width: 100%;
+ height: 100%;
+ }
+ }
+}
+
+.album-info {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: space-around;
+
+ .album-image {
+ max-width: 80%;
+ max-height: 80%;
+ box-shadow: 10px 10px 50px -10px $background-color;
+ }
+
+ .album-body {
+ display: flex;
+ flex-flow: column nowrap;
+ justify-content: center;
+
+ .album-title {
+ color: $text-controls-color;
+ font-size: 40px;
+ font-weight: bold;
+ margin:15px;
+ text-align: center;
+ }
+
+ .album-artists {
+ display: flex;
+ flex-flow: row wrap;
+ justify-content: space-around;
+ align-content: space-around;
+ margin:15px;
+
+ color: $text-controls-color;
+ font-size: 20px;
+
+ .album-artist {
+ margin: 5px;
+ text-align: center;
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/style/main.scss b/style/main.scss
index a19abe7..e2be23c 100644
--- a/style/main.scss
+++ b/style/main.scss
@@ -15,6 +15,7 @@
@import 'song_list.scss';
@import 'profile.scss';
@import 'loading.scss';
+@import 'album_page.scss';
body {
font-family: sans-serif;
diff --git a/style/theme.scss b/style/theme.scss
index b0cea43..0569ca6 100644
--- a/style/theme.scss
+++ b/style/theme.scss
@@ -10,10 +10,11 @@ $controls-click-color: #909090;
$play-bar-background-color: #212121;
$play-grad-start: #0a0533;
$play-grad-end: $accent-color;
+$border-color: #7851ed;
$queue-background-color: $play-bar-background-color;
$auth-inputs: #796dd4;
$auth-containers: white;
$dashboard-tile-size: 200px;
-$playbar-size: 75px;
+$playbar-size: 75px;
\ No newline at end of file
From 45eb7191f0800778bbf7fdde86083ee2ee5059bb Mon Sep 17 00:00:00 2001
From: Aidan Westphal
Date: Fri, 22 Nov 2024 21:47:24 +0000
Subject: [PATCH 09/11] Bugfix and small changes to styling
---
src/models.rs | 55 ++++++++++++++++++++++++-------------------
style/album_page.scss | 1 +
2 files changed, 32 insertions(+), 24 deletions(-)
diff --git a/src/models.rs b/src/models.rs
index 71c4180..15a97b4 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -638,30 +638,37 @@ impl Album {
for (album, song, artist, like, dislike) in song_list {
if let Some(song) = song {
- let like_dislike = match (like, dislike) {
- (Some(_), Some(_)) => Some((true, true)),
- (Some(_), None) => Some((true, false)),
- (None, Some(_)) => Some((false, true)),
- _ => None,
- };
-
- let image_path = song.image_path.unwrap_or(
- album.image_path.clone().unwrap_or("/assets/images/placeholders/MusicPlaceholder.svg".to_string()));
-
- let songdata = SongData {
- id: song.id.unwrap(),
- title: song.title,
- artists: artist.map(|artist| vec![artist]).unwrap_or_default(),
- album: Some(album),
- track: song.track,
- duration: song.duration,
- release_date: song.release_date,
- song_path: song.storage_path,
- image_path: image_path,
- like_dislike: like_dislike,
- };
-
- album_songs.insert(song.id.unwrap(), songdata);
+ if let Some(stored_songdata) = album_songs.get_mut(&song.id.unwrap()) {
+ // If the song is already in the map, update the artists
+ if let Some(artist) = artist {
+ stored_songdata.artists.push(artist);
+ }
+ } else {
+ let like_dislike = match (like, dislike) {
+ (Some(_), Some(_)) => Some((true, true)),
+ (Some(_), None) => Some((true, false)),
+ (None, Some(_)) => Some((false, true)),
+ _ => None,
+ };
+
+ let image_path = song.image_path.unwrap_or(
+ album.image_path.clone().unwrap_or("/assets/images/placeholders/MusicPlaceholder.svg".to_string()));
+
+ let songdata = SongData {
+ id: song.id.unwrap(),
+ title: song.title,
+ artists: artist.map(|artist| vec![artist]).unwrap_or_default(),
+ album: Some(album),
+ track: song.track,
+ duration: song.duration,
+ release_date: song.release_date,
+ song_path: song.storage_path,
+ image_path: image_path,
+ like_dislike: like_dislike,
+ };
+
+ album_songs.insert(song.id.unwrap(), songdata);
+ }
}
}
diff --git a/style/album_page.scss b/style/album_page.scss
index 55b306b..d00439e 100644
--- a/style/album_page.scss
+++ b/style/album_page.scss
@@ -60,6 +60,7 @@
.album-artist {
margin: 5px;
text-align: center;
+ text-decoration: underline;
}
}
}
From e5ce0eab76722b679664cdb38bbeaa17a397011d Mon Sep 17 00:00:00 2001
From: Aidan Westphal
Date: Fri, 22 Nov 2024 21:55:59 +0000
Subject: [PATCH 10/11] Fix Build Warnings
---
src/albumdata.rs | 1 -
src/api/album.rs | 4 ++--
src/models.rs | 7 ++-----
src/pages/albumpage.rs | 1 -
4 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/src/albumdata.rs b/src/albumdata.rs
index a621a8c..f1481ae 100644
--- a/src/albumdata.rs
+++ b/src/albumdata.rs
@@ -1,6 +1,5 @@
use crate::models::Artist;
use crate::components::dashboard_tile::DashboardTile;
-use crate::components::album_info::AlbumInfo;
use serde::{Serialize, Deserialize};
use chrono::NaiveDate;
diff --git a/src/api/album.rs b/src/api/album.rs
index 0bf9390..5c4d55e 100644
--- a/src/api/album.rs
+++ b/src/api/album.rs
@@ -1,5 +1,4 @@
use leptos::*;
-use crate::models::Album;
use crate::albumdata::AlbumData;
use crate::songdata::SongData;
@@ -9,12 +8,12 @@ cfg_if! {
if #[cfg(feature = "ssr")] {
use leptos::server_fn::error::NoCustomError;
use crate::database::get_db_conn;
- use crate::auth::get_user;
}
}
#[server(endpoint = "album/get")]
pub async fn get_album(id: i32) -> Result {
+ use crate::models::Album;
let db_con = &mut get_db_conn();
let album = Album::get_album_data(id,db_con)
.map_err(|e| ServerFnError::::ServerError(format!("Error getting album: {}", e)))?;
@@ -23,6 +22,7 @@ pub async fn get_album(id: i32) -> Result {
#[server(endpoint = "album/get_songs")]
pub async fn get_songs(id: i32) -> Result, ServerFnError> {
+ use crate::models::Album;
use crate::auth::get_logged_in_user;
let user = get_logged_in_user().await?;
let db_con = &mut get_db_conn();
diff --git a/src/models.rs b/src/models.rs
index 15a97b4..40fd7f9 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -1,8 +1,5 @@
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;
@@ -11,6 +8,8 @@ cfg_if! {
use diesel::prelude::*;
use crate::database::*;
use std::error::Error;
+ use crate::songdata::SongData;
+ use crate::albumdata::AlbumData;
}
}
@@ -542,7 +541,6 @@ impl Album {
#[cfg(feature = "ssr")]
pub fn get_album_data(album_id: i32, conn: &mut PgPooledConn) -> Result> {
use crate::schema::*;
- use crate::database::get_db_conn;
let album: Vec<(Album, std::option::Option)> = albums::table
.find(album_id)
@@ -593,7 +591,6 @@ impl Album {
#[cfg(feature = "ssr")]
pub fn get_song_data(album_id: i32, user_like_dislike: Option, conn: &mut PgPooledConn) -> Result, Box> {
use crate::schema::*;
- use crate::database::get_db_conn;
use std::collections::HashMap;
let song_list = if let Some(user_like_dislike) = user_like_dislike {
diff --git a/src/pages/albumpage.rs b/src/pages/albumpage.rs
index 47332ac..f65d71e 100644
--- a/src/pages/albumpage.rs
+++ b/src/pages/albumpage.rs
@@ -1,7 +1,6 @@
use leptos::leptos_dom::*;
use leptos::*;
use leptos_router::*;
-use crate::{albumdata, models::*};
use crate::components::song_list::*;
use crate::api::album::*;
use crate::components::album_info::*;
From 954cc0edce63f3baea8f6efae42fe52efc9af190 Mon Sep 17 00:00:00 2001
From: Aidan Westphal
Date: Fri, 22 Nov 2024 22:13:43 +0000
Subject: [PATCH 11/11] Artist links and styling
---
src/components/album_info.rs | 2 +-
style/album_page.scss | 16 ++++++++++++++--
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/components/album_info.rs b/src/components/album_info.rs
index 03b2950..182cc75 100644
--- a/src/components/album_info.rs
+++ b/src/components/album_info.rs
@@ -13,7 +13,7 @@ pub fn AlbumInfo(albumdata: AlbumData) -> impl IntoView {
{
albumdata.artists.iter().map(|artist| {
view! {
- {artist.name.clone()}
+ {artist.name.clone()}
}
}).collect::>()
}
diff --git a/style/album_page.scss b/style/album_page.scss
index d00439e..b63e906 100644
--- a/style/album_page.scss
+++ b/style/album_page.scss
@@ -1,7 +1,5 @@
@import 'theme.scss';
-
-
.album-page-container {
width: 90vw;
@@ -65,4 +63,18 @@
}
}
+ a {
+ color: $text-controls-color;
+ }
+ a:visited {
+ color: $text-controls-color;
+ }
+ a:hover {
+ color: $controls-hover-color;
+ }
+
+ a:active {
+ color: $controls-click-color;
+ }
+
}
\ No newline at end of file