Implement like/dislike using SongData instead of PlayStatus

This commit is contained in:
Ethan Girouard 2024-07-28 22:42:04 -04:00
parent e5a6e8f44e
commit afbcc65457
Signed by: eta357
GPG Key ID: 7BCDC36DFD11C146
2 changed files with 78 additions and 34 deletions

View File

@ -1,5 +1,7 @@
use crate::models::Artist; use crate::models::Artist;
use crate::playstatus::PlayStatus; use crate::playstatus::PlayStatus;
use crate::songdata::SongData;
use crate::api::songs;
use leptos::ev::MouseEvent; use leptos::ev::MouseEvent;
use leptos::html::{Audio, Div}; use leptos::html::{Audio, Div};
use leptos::leptos_dom::*; use leptos::leptos_dom::*;
@ -283,53 +285,101 @@ fn MediaInfo(status: RwSignal<PlayStatus>) -> impl IntoView {
fn LikeDislike(status: RwSignal<PlayStatus>) -> impl IntoView { fn LikeDislike(status: RwSignal<PlayStatus>) -> impl IntoView {
let like_icon = Signal::derive(move || { let like_icon = Signal::derive(move || {
status.with(|status| { status.with(|status| {
if status.liked { match status.queue.front() {
icondata::TbThumbUpFilled Some(SongData { like_dislike: Some((true, _)), .. }) => icondata::TbThumbUpFilled,
} else { _ => icondata::TbThumbUp,
icondata::TbThumbUp
} }
}) })
}); });
let dislike_icon = Signal::derive(move || { let dislike_icon = Signal::derive(move || {
status.with(|status| { status.with(|status| {
if status.disliked { match status.queue.front() {
icondata::TbThumbDownFilled Some(SongData { like_dislike: Some((_, true)), .. }) => icondata::TbThumbDownFilled,
} else { _ => icondata::TbThumbDown,
icondata::TbThumbDown
} }
}) })
}); });
let toggle_like = move |_| { let toggle_like = move |_| {
status.update(|status| { status.update(|status| {
if status.queue.is_empty() { match status.queue.front_mut() {
Some(SongData { id, like_dislike: Some((liked, disliked)), .. }) => {
*liked = !*liked;
if *liked {
*disliked = false;
}
let id = *id;
let liked = *liked;
spawn_local(async move {
if let Err(e) = songs::set_like_song(id, liked).await {
error!("Error liking song: {:?}", e);
}
});
},
Some(SongData { id, like_dislike, .. }) => {
// This arm should only be reached if like_dislike is None
// In this case, the buttons will show up not filled, indicating that the song is not
// liked or disliked. Therefore, clicking the like button should like the song.
*like_dislike = Some((true, false));
let id = *id;
spawn_local(async move {
if let Err(e) = songs::set_like_song(id, true).await {
error!("Error liking song: {:?}", e);
}
});
},
_ => {
log!("Unable to like song: No song in queue");
return; return;
} }
status.liked = !status.liked;
if status.liked {
status.disliked = false;
} }
// TODO call the API to like the song
}); });
}; };
let toggle_dislike = move |_| { let toggle_dislike = move |_| {
log!("Dislike button pressed");
status.update(|status| { status.update(|status| {
if status.queue.is_empty() { match status.queue.front_mut() {
Some(SongData { id, like_dislike: Some((liked, disliked)), .. }) => {
*disliked = !*disliked;
if *disliked {
*liked = false;
}
let id = *id;
let disliked = *disliked;
spawn_local(async move {
if let Err(e) = songs::set_dislike_song(id, disliked).await {
error!("Error disliking song: {:?}", e);
}
});
},
Some(SongData { id, like_dislike, .. }) => {
// This arm should only be reached if like_dislike is None
// In this case, the buttons will show up not filled, indicating that the song is not
// liked or disliked. Therefore, clicking the dislike button should dislike the song.
*like_dislike = Some((false, true));
let id = *id;
spawn_local(async move {
if let Err(e) = songs::set_dislike_song(id, true).await {
error!("Error disliking song: {:?}", e);
}
});
},
_ => {
log!("Unable to dislike song: No song in queue");
return; return;
} }
status.disliked = !status.disliked;
if status.disliked {
status.liked = false;
} }
// TODO call the API to dislike the song
}); });
}; };

View File

@ -17,10 +17,6 @@ pub struct PlayStatus {
pub history: VecDeque<SongData>, pub history: VecDeque<SongData>,
/// A queue of songs that have yet to be played, ordered from next up to last /// A queue of songs that have yet to be played, ordered from next up to last
pub queue: VecDeque<SongData>, pub queue: VecDeque<SongData>,
/// Whether the current playing song is liked
pub liked: bool,
/// Whether the current playing song is disliked
pub disliked: bool,
} }
impl PlayStatus { impl PlayStatus {
@ -63,8 +59,6 @@ impl Default for PlayStatus {
audio_player: None, audio_player: None,
history: VecDeque::new(), history: VecDeque::new(),
queue: VecDeque::new(), queue: VecDeque::new(),
liked: false,
disliked: false,
} }
} }
} }