diff --git a/src/components/playlist.rs b/src/components/playlist.rs index 165ab44..b94cbf5 100644 --- a/src/components/playlist.rs +++ b/src/components/playlist.rs @@ -5,6 +5,15 @@ use crate::models::Playlist; use crate::models::Song; use crate::api::playlists::get_songs; use crate::api::songs::get_artists; +use crate::api::playlists::remove_song; + +fn total_duration(songs: ReadSignal>) -> i32 { + let mut total_duration = 0; + for song in songs.get() { + total_duration += song.duration; + } + total_duration +} fn convert_seconds(seconds: i32) -> String { let minutes = seconds / 60; @@ -17,6 +26,12 @@ fn convert_seconds(seconds: i32) -> String { format!("{}:{}", minutes, seconds_string) } +fn convert_to_text_time(seconds: i32) -> String { + let hours = seconds / 3600; + let minutes = (seconds % 3600) / 60; + format!("{} hour{}, {} minute{}", hours, if hours > 1 { "s" } else { "" }, minutes, if minutes > 1 { "s" } else { "" }) +} + #[component] pub fn Playlist(playlist: Playlist) -> impl IntoView { let (show_playlist, set_show_playlist) = create_signal(false); @@ -55,6 +70,7 @@ pub fn PlayListPopUp(playlist: Playlist, set_show_playlist: WriteSignal) - log!("Songs: {:?}", playlist_songs); log!("number of songs: {:?}", playlist_songs.clone().expect("REASON").len()); set_songs.update(|value| *value = playlist_songs.unwrap()); + } }) }); @@ -66,13 +82,13 @@ pub fn PlayListPopUp(playlist: Playlist, set_show_playlist: WriteSignal) -

{playlist.name.clone()}

-

{move || songs.get().len()}

+

{move || songs.get().len()} songs {move || convert_to_text_time(total_duration(songs))}

    { move || songs.get().iter().enumerate().map(|(index,song)| view! { - + }).collect::>() }
@@ -80,10 +96,23 @@ pub fn PlayListPopUp(playlist: Playlist, set_show_playlist: WriteSignal) - } } #[component] -pub fn PlaylistSong(song: Song) -> impl IntoView { +pub fn PlaylistSong(song: Song, playlist_id: Option, set_songs: WriteSignal>) -> impl IntoView { let (artists, set_artists) = create_signal("".to_string()); let (is_hovered, set_is_hovered) = create_signal(false); + let delete_song = move |_| { + spawn_local(async move { + let delete_result = remove_song(song.id.clone(), playlist_id).await; + if let Err(err) = delete_result { + // Handle the error here, e.g., log it or display to the user + log!("Error deleting song: {:?}", err); + } else { + log!("Song deleted successfully!"); + set_songs.update(|value| *value = value.iter().filter(|s| s.id != song.id).cloned().collect()); + } + }) + }; + create_effect(move |_| { spawn_local(async move { @@ -120,7 +149,9 @@ pub fn PlaylistSong(song: Song) -> impl IntoView { when=move || is_hovered() fallback=move || view! {

{convert_seconds(song.duration)}

} > +
+
diff --git a/style/sidebar.scss b/style/sidebar.scss index 72c04be..6174cab 100644 --- a/style/sidebar.scss +++ b/style/sidebar.scss @@ -240,11 +240,22 @@ .info { display:flex; flex-direction: row; + align-items: end; + h1 { + font-weight: bold; + font-size: 2rem; + margin-left: .5rem; + margin-right:2rem; + } + p { + color: #aaa; + } } .songs { list-style: none; padding: 0; margin: 0; + margin-top: 2rem; .song { display: flex; align-items: center; @@ -278,6 +289,19 @@ .duration { } + .delete-song { + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + } + .delete-song:hover { + transform: scale(1.1); + } + + .delete-song:active { + transform: scale(0.8); + } } } .song:first-child {