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,