From fe21785f2d0bbe17707ff6b7e8e334ecefdce3a6 Mon Sep 17 00:00:00 2001 From: Ethan Girouard Date: Fri, 15 Nov 2024 15:33:05 -0500 Subject: [PATCH] Implement SongList like/dislike functionality --- src/components/song_list.rs | 47 ++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/components/song_list.rs b/src/components/song_list.rs index e0c46d7..442b9d5 100644 --- a/src/components/song_list.rs +++ b/src/components/song_list.rs @@ -1,6 +1,8 @@ use leptos::*; +use leptos::logging::*; use leptos_icons::*; +use crate::api::songs::*; use crate::songdata::SongData; use crate::models::{Album, Artist}; @@ -70,7 +72,7 @@ pub fn SongListItem(song: SongData, song_playing: MaybeSignal, extra: O - + {format!("{}:{:02}", song.duration / 60, song.duration % 60)} {extra.map(|extra| view! { @@ -135,7 +137,12 @@ fn SongAlbum(album: Option) -> impl IntoView { /// Display like and dislike buttons for a song, and indicate if the song is liked or disliked #[component] -fn SongLikeDislike(liked: RwSignal, disliked: RwSignal) -> impl IntoView { +fn SongLikeDislike( + #[prop(into)] + song_id: MaybeSignal, + liked: RwSignal, + disliked: RwSignal) -> impl IntoView +{ let like_icon = Signal::derive(move || { if liked.get() { icondata::TbThumbUpFilled @@ -168,14 +175,48 @@ fn SongLikeDislike(liked: RwSignal, disliked: RwSignal) -> impl Into } }); + // If an error occurs, check the like/dislike status again to ensure consistency + let check_like_dislike = move || { + spawn_local(async move { + match get_like_dislike_song(song_id.get_untracked()).await { + Ok((like, dislike)) => { + liked.set(like); + disliked.set(dislike); + }, + Err(_) => {} + } + }); + }; + let toggle_like = move |_| { - liked.set(!liked.get_untracked()); + let new_liked = !liked.get_untracked(); + liked.set(new_liked); disliked.set(disliked.get_untracked() && !liked.get_untracked()); + + spawn_local(async move { + match set_like_song(song_id.get_untracked(), new_liked).await { + Ok(_) => {}, + Err(e) => { + error!("Error setting like: {}", e); + check_like_dislike(); + } + } + }); }; let toggle_dislike = move |_| { disliked.set(!disliked.get_untracked()); liked.set(liked.get_untracked() && !disliked.get_untracked()); + + spawn_local(async move { + match set_dislike_song(song_id.get_untracked(), disliked.get_untracked()).await { + Ok(_) => {}, + Err(e) => { + error!("Error setting dislike: {}", e); + check_like_dislike(); + } + } + }); }; view! {