added a delete playlist song

This commit is contained in:
Danny Zou 2024-04-19 11:04:15 -04:00
parent f56e13eaa9
commit 1377743aba
2 changed files with 58 additions and 3 deletions

View File

@ -5,6 +5,15 @@ use crate::models::Playlist;
use crate::models::Song; use crate::models::Song;
use crate::api::playlists::get_songs; use crate::api::playlists::get_songs;
use crate::api::songs::get_artists; use crate::api::songs::get_artists;
use crate::api::playlists::remove_song;
fn total_duration(songs: ReadSignal<Vec<Song>>) -> i32 {
let mut total_duration = 0;
for song in songs.get() {
total_duration += song.duration;
}
total_duration
}
fn convert_seconds(seconds: i32) -> String { fn convert_seconds(seconds: i32) -> String {
let minutes = seconds / 60; let minutes = seconds / 60;
@ -17,6 +26,12 @@ fn convert_seconds(seconds: i32) -> String {
format!("{}:{}", minutes, seconds_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] #[component]
pub fn Playlist(playlist: Playlist) -> impl IntoView { pub fn Playlist(playlist: Playlist) -> impl IntoView {
let (show_playlist, set_show_playlist) = create_signal(false); let (show_playlist, set_show_playlist) = create_signal(false);
@ -55,6 +70,7 @@ pub fn PlayListPopUp(playlist: Playlist, set_show_playlist: WriteSignal<bool>) -
log!("Songs: {:?}", playlist_songs); log!("Songs: {:?}", playlist_songs);
log!("number of songs: {:?}", playlist_songs.clone().expect("REASON").len()); log!("number of songs: {:?}", playlist_songs.clone().expect("REASON").len());
set_songs.update(|value| *value = playlist_songs.unwrap()); set_songs.update(|value| *value = playlist_songs.unwrap());
} }
}) })
}); });
@ -66,13 +82,13 @@ pub fn PlayListPopUp(playlist: Playlist, set_show_playlist: WriteSignal<bool>) -
</div> </div>
<div class="info"> <div class="info">
<h1>{playlist.name.clone()}</h1> <h1>{playlist.name.clone()}</h1>
<h1>{move || songs.get().len()}</h1> <p>{move || songs.get().len()} songs {move || convert_to_text_time(total_duration(songs))}</p>
</div> </div>
<ul class="songs"> <ul class="songs">
{ {
move || songs.get().iter().enumerate().map(|(index,song)| view! { move || songs.get().iter().enumerate().map(|(index,song)| view! {
<PlaylistSong song=song.clone() /> <PlaylistSong song=song.clone() playlist_id=playlist.id.clone() set_songs=set_songs />
}).collect::<Vec<_>>() }).collect::<Vec<_>>()
} }
</ul> </ul>
@ -80,10 +96,23 @@ pub fn PlayListPopUp(playlist: Playlist, set_show_playlist: WriteSignal<bool>) -
} }
} }
#[component] #[component]
pub fn PlaylistSong(song: Song) -> impl IntoView { pub fn PlaylistSong(song: Song, playlist_id: Option<i32>, set_songs: WriteSignal<Vec<Song>>) -> impl IntoView {
let (artists, set_artists) = create_signal("".to_string()); let (artists, set_artists) = create_signal("".to_string());
let (is_hovered, set_is_hovered) = create_signal(false); 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 |_| { create_effect(move |_| {
spawn_local(async move { spawn_local(async move {
@ -120,7 +149,9 @@ pub fn PlaylistSong(song: Song) -> impl IntoView {
when=move || is_hovered() when=move || is_hovered()
fallback=move || view! {<p class="duration">{convert_seconds(song.duration)}</p>} fallback=move || view! {<p class="duration">{convert_seconds(song.duration)}</p>}
> >
<div class="delete-song" on:click=delete_song>
<Icon icon=icondata::FaTrashCanRegular /> <Icon icon=icondata::FaTrashCanRegular />
</div>
</Show> </Show>
</div> </div>
</div> </div>

View File

@ -240,11 +240,22 @@
.info { .info {
display:flex; display:flex;
flex-direction: row; flex-direction: row;
align-items: end;
h1 {
font-weight: bold;
font-size: 2rem;
margin-left: .5rem;
margin-right:2rem;
}
p {
color: #aaa;
}
} }
.songs { .songs {
list-style: none; list-style: none;
padding: 0; padding: 0;
margin: 0; margin: 0;
margin-top: 2rem;
.song { .song {
display: flex; display: flex;
align-items: center; align-items: center;
@ -278,6 +289,19 @@
.duration { .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 { .song:first-child {