make star button work
This commit is contained in:
parent
720b73f2a8
commit
5b0a7124a8
7 changed files with 84 additions and 3 deletions
|
@ -110,8 +110,8 @@ template $AudreyUiPlayQueueSong: Box {
|
|||
|
||||
Button {
|
||||
focusable: true;
|
||||
// TODO icon-name: bind $star_button_icon_name (template.song as <$AudreyModelSong>.starred) as <string>;
|
||||
icon-name: bind $star_button_icon_name() as <string>;
|
||||
icon-name: bind $heart_button_icon_name(template.song as <$AudreyModelSong>.starred) as <string>;
|
||||
clicked => $on_heart_button_clicked() swapped;
|
||||
|
||||
styles [
|
||||
"flat"
|
||||
|
|
|
@ -176,10 +176,11 @@ template $AudreyUiPlaybar: Adw.Bin {
|
|||
}
|
||||
|
||||
Button {
|
||||
icon-name: "heart-empty-symbolic"; // placeholder
|
||||
icon-name: bind $heart_button_icon_name(template.song as <$AudreyModelSong>.starred) as <string>;
|
||||
halign: end;
|
||||
valign: center;
|
||||
sensitive: bind template.idle-active inverted;
|
||||
clicked => $on_heart_button_clicked() swapped;
|
||||
}
|
||||
|
||||
Button {
|
||||
|
|
|
@ -94,6 +94,7 @@ template $AudreyUiWindow: Adw.ApplicationWindow {
|
|||
duration: bind template.duration;
|
||||
idle-active: bind template.idle-active;
|
||||
playlist-count: bind template.playlist-count;
|
||||
client: bind template.client;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ mod imp {
|
|||
track: Cell<i64>,
|
||||
#[property(get, set)]
|
||||
cover_art: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
starred: Cell<bool>,
|
||||
|
||||
#[property(get, set)]
|
||||
stream_url: RefCell<String>,
|
||||
|
|
|
@ -299,6 +299,16 @@ impl Client {
|
|||
pub fn stream_url(&self, id: &str) -> url::Url {
|
||||
self.url(&["rest", "stream"], &[("id", id)])
|
||||
}
|
||||
|
||||
pub async fn star(&self, id: &str) -> Result<(), Error> {
|
||||
let url = self.url(&["rest", "star"], &[("id", id)]);
|
||||
self.get_bytes(url).await.map(|_| ())
|
||||
}
|
||||
|
||||
pub async fn unstar(&self, id: &str) -> Result<(), Error> {
|
||||
let url = self.url(&["rest", "unstar"], &[("id", id)]);
|
||||
self.get_bytes(url).await.map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Client {
|
||||
|
|
|
@ -3,6 +3,7 @@ use adw::prelude::*;
|
|||
use glib::subclass::InitializingObject;
|
||||
use gtk::{gdk, gio, glib, subclass::prelude::*};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use tracing::{event, Level};
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
@ -35,6 +36,9 @@ mod imp {
|
|||
|
||||
drag_pos: Cell<(i32, i32)>,
|
||||
drag_widget: Cell<Option<gtk::ListBox>>,
|
||||
|
||||
#[property(get, set)]
|
||||
client: RefCell<Option<crate::wrappers::Client>>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -174,6 +178,37 @@ mod imp {
|
|||
self.obj()
|
||||
.set_current(playlist_pos == self.position.get() as i64);
|
||||
}
|
||||
|
||||
// FIXME: duplicated in playbar....
|
||||
#[template_callback]
|
||||
fn heart_button_icon_name(&self, starred: bool) -> &'static str {
|
||||
if starred {
|
||||
"heart-full-symbolic"
|
||||
} else {
|
||||
"heart-empty-symbolic"
|
||||
}
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
async fn on_heart_button_clicked(&self) {
|
||||
// TODO: disable button while await ongoing?? consider making star/unstar methods in
|
||||
// the model class and add a semaphore there for serialization
|
||||
// FIXME: doesn't update all if track is duplicated in the play queue
|
||||
|
||||
let song = self.obj().song().unwrap();
|
||||
let client = self.obj().client().unwrap();
|
||||
if song.starred() {
|
||||
match client.unstar(&song.id()).await {
|
||||
Ok(()) => song.set_starred(false),
|
||||
Err(err) => event!(Level::ERROR, "could not unstar song {}: {err}", song.id()),
|
||||
}
|
||||
} else {
|
||||
match client.star(&song.id()).await {
|
||||
Ok(()) => song.set_starred(true),
|
||||
Err(err) => event!(Level::ERROR, "could not star song {}: {err}", song.id()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,6 +234,7 @@ impl Song {
|
|||
self.set_song(&song);
|
||||
self.set_position(position);
|
||||
self.set_playlist_pos(window.playlist_pos());
|
||||
self.set_client(window.client().unwrap());
|
||||
|
||||
song.need_thumbnail(
|
||||
window.client().as_ref().unwrap(),
|
||||
|
|
|
@ -43,6 +43,9 @@ mod imp {
|
|||
|
||||
#[property(get, set)]
|
||||
_show_pulse_bar: Cell<bool>,
|
||||
|
||||
#[property(get, set)]
|
||||
client: RefCell<Option<crate::wrappers::Client>>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -162,6 +165,34 @@ mod imp {
|
|||
fn song_album(&self, song: Option<&Song>) -> String {
|
||||
song.map(Song::album).unwrap_or_default()
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
fn heart_button_icon_name(&self, starred: bool) -> &'static str {
|
||||
if starred {
|
||||
"heart-full-symbolic"
|
||||
} else {
|
||||
"heart-empty-symbolic"
|
||||
}
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
async fn on_heart_button_clicked(&self) {
|
||||
// TODO: disable button while await ongoing??
|
||||
|
||||
let song = self.obj().song().unwrap();
|
||||
let client = self.obj().client().unwrap();
|
||||
if song.starred() {
|
||||
match client.unstar(&song.id()).await {
|
||||
Ok(()) => song.set_starred(false),
|
||||
Err(err) => event!(Level::ERROR, "could not unstar song {}: {err}", song.id()),
|
||||
}
|
||||
} else {
|
||||
match client.star(&song.id()).await {
|
||||
Ok(()) => song.set_starred(true),
|
||||
Err(err) => event!(Level::ERROR, "could not star song {}: {err}", song.id()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Playbar {
|
||||
|
|
Loading…
Reference in a new issue