started work on playlist ui

This commit is contained in:
2024-04-17 19:50:27 -04:00
parent ac02fb9bd6
commit c66e04643c
4 changed files with 78 additions and 5 deletions

View File

@ -71,3 +71,31 @@ pub async fn get_playlists() -> Result<Vec<Playlist>, ServerFnError> {
Ok(results)
}
/// Add a song to a playlist
///
/// # Arguments
///
/// * `playlist_id` - The id of the playlist
/// * `song_id` - The id of the song
///
/// # Returns
///
/// * `Result<(), ServerFnError>` - An empty result if successful, or an error
///
#[server(endpoint = "playlists/add-song")]
pub async fn add_song(new_playlist_id: Option<i32>, new_song_id: Option<i32>) -> Result<(), ServerFnError> {
use crate::schema::playlist_songs::dsl::*;
use leptos::server_fn::error::NoCustomError;
let other_playlist_id = new_playlist_id.ok_or(ServerFnError::<NoCustomError>::ServerError("Playlist id must be present (Some) to add song".to_string()))?;
let other_song_id = new_song_id.ok_or(ServerFnError::<NoCustomError>::ServerError("Song id must be present (Some) to add song".to_string()))?;
let db_con = &mut get_db_conn();
diesel::insert_into(playlist_songs)
.values((playlist_id.eq(other_playlist_id), song_id.eq(other_song_id)))
.execute(db_con)
.map_err(|e| ServerFnError::<NoCustomError>::ServerError(format!("Error adding song to playlist: {}", e)))?;
Ok(())
}

View File

@ -3,6 +3,7 @@ use leptos::*;
use leptos_icons::*;
use crate::api::playlists::create_playlist;
use crate::api::playlists::get_playlists;
use crate::models::Playlist;
#[component]
pub fn Sidebar(setter: WriteSignal<bool>, active: ReadSignal<bool>) -> impl IntoView {
@ -66,10 +67,8 @@ pub fn Bottom() -> impl IntoView {
<CreatePlayList opened=create_playlist_open closer=set_create_playlist_open/>
<ul class="playlists">
{
move || playlists.get().iter().map(|playlist| view! {
<div class="playlist">
<h1 class="name">{playlist.name.clone()}</h1>
</div>
move || playlists.get().iter().enumerate().map(|(index,playlist)| view! {
<Playlist playlist=playlist.clone() />
}).collect::<Vec<_>>()
}
</ul>
@ -116,4 +115,20 @@ pub fn CreatePlayList(opened: ReadSignal<bool>,closer: WriteSignal<bool>) -> imp
</form>
</div>
}
}
#[component]
pub fn Playlist(playlist: Playlist) -> impl IntoView {
let (show_playlist, set_show_playlist) = create_signal(false);
view! {
<div class="playlist" on:click=move|_| set_show_playlist.update(|value| *value=true) >
<h1 class="name">{playlist.name.clone()}</h1>
<div class="playlist-container" style={move || if show_playlist() {"display: flex"} else {"display: none"}}>
<div class="close-button" on:click=move |_| set_show_playlist.update(|value| *value = false)>
<Icon icon=icondata::IoCloseSharp />
</div>
<h1>{playlist.name.clone()}</h1>
</div>
</div>
}
}

View File

@ -320,7 +320,6 @@ impl Playlist {
#[cfg(feature = "ssr")]
pub fn create_playlist(new_playlist: Playlist, conn: &mut PgPooledConn) -> Result<(), Box<dyn Error>> {
use crate::schema::playlists::dsl::*;
use crate::models::Playlist;
let new_playlist = Playlist {
..new_playlist

View File

@ -178,6 +178,37 @@
margin-top: 0.5rem;
color: white;
}
.playlist-container {
background-color: red;
width: 10rem;
height: 10rem;
position: fixed;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
.close-button {
position: absolute;
top: 5px;
right: 5px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
border-radius: 50%;
font-size: 1.6rem;
transition: all 0.3s;
}
.close-button:hover {
transform: scale(1.1);
background-color: rgba(255, 255, 255, 0.1);
}
.close-button:active {
transform: scale(0.8);
}
}
}
.playlist:hover {
background-color: #adadad36;