carousel album covers
This commit is contained in:
parent
afa27dbb6a
commit
abfd5ab568
4 changed files with 41 additions and 5 deletions
|
@ -12,7 +12,7 @@ template $AudreyUiAlbumCarouselAlbum: Adw.Bin {
|
||||||
spacing: 6;
|
spacing: 6;
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
icon-name: "media-optical-cd";
|
paintable: bind template.cover_art;
|
||||||
pixel-size: 160;
|
pixel-size: 160;
|
||||||
halign: center;
|
halign: center;
|
||||||
hexpand: false;
|
hexpand: false;
|
||||||
|
|
|
@ -93,7 +93,6 @@ gridview.albums child image {
|
||||||
|
|
||||||
.album-carousel listview row image {
|
.album-carousel listview row image {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background-color: oklch(0 0 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.album-carousel .labels {
|
.album-carousel .labels {
|
||||||
|
|
|
@ -157,7 +157,7 @@ mod imp {
|
||||||
pub fn on_bind(&self, item: >k::ListItem, _factory: >k::SignalListItemFactory) {
|
pub fn on_bind(&self, item: >k::ListItem, _factory: >k::SignalListItemFactory) {
|
||||||
let child: super::Album = item.child().and_downcast().unwrap();
|
let child: super::Album = item.child().and_downcast().unwrap();
|
||||||
let album: model::Album = item.item().and_downcast().unwrap();
|
let album: model::Album = item.item().and_downcast().unwrap();
|
||||||
child.bind(&album);
|
child.bind(self.client.borrow().as_ref().unwrap(), &album);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
use crate::model;
|
use crate::model;
|
||||||
|
use adw::gdk;
|
||||||
use adw::{prelude::*, subclass::prelude::*};
|
use adw::{prelude::*, subclass::prelude::*};
|
||||||
use glib::subclass::InitializingObject;
|
use glib::subclass::InitializingObject;
|
||||||
use std::cell::RefCell;
|
use std::cell::{Cell, RefCell};
|
||||||
|
use tokio::sync::Semaphore;
|
||||||
|
use tracing::{event, Level};
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -12,6 +15,11 @@ mod imp {
|
||||||
pub struct Album {
|
pub struct Album {
|
||||||
#[property(get, set, nullable)]
|
#[property(get, set, nullable)]
|
||||||
item: RefCell<Option<model::Album>>,
|
item: RefCell<Option<model::Album>>,
|
||||||
|
|
||||||
|
#[property(get, set, nullable)]
|
||||||
|
cover_art: RefCell<Option<gdk::Paintable>>,
|
||||||
|
|
||||||
|
pub cover_art_loading: Cell<Option<glib::JoinHandle<()>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -37,6 +45,9 @@ mod imp {
|
||||||
impl BinImpl for Album {}
|
impl BinImpl for Album {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only fetch 10 thumbnails at a time
|
||||||
|
static SEM: Semaphore = Semaphore::const_new(10);
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct Album(ObjectSubclass<imp::Album>)
|
pub struct Album(ObjectSubclass<imp::Album>)
|
||||||
@extends adw::Bin, gtk::Widget,
|
@extends adw::Bin, gtk::Widget,
|
||||||
|
@ -44,11 +55,37 @@ glib::wrapper! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Album {
|
impl Album {
|
||||||
pub fn bind(&self, album: &model::Album) {
|
pub fn bind(&self, client: &crate::wrappers::Client, album: &model::Album) {
|
||||||
self.set_item(Some(album));
|
self.set_item(Some(album));
|
||||||
|
|
||||||
|
let client = client.clone();
|
||||||
|
let id = album.id();
|
||||||
|
let this = self.downgrade();
|
||||||
|
let scale_factor = self.scale_factor() as u32;
|
||||||
|
let handle = glib::spawn_future_local(async move {
|
||||||
|
let _permit = SEM.acquire().await.unwrap();
|
||||||
|
|
||||||
|
// see pixel-size in album_carousel_album.blp
|
||||||
|
let pixbuf = match client.cover_art(&id, Some(160 * scale_factor)).await {
|
||||||
|
Ok(image) => audrey::util::image_to_pixbuf(image),
|
||||||
|
Err(err) => {
|
||||||
|
event!(Level::ERROR, "could not fetch cover for album {id}: {err}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let this = this.upgrade().unwrap();
|
||||||
|
this.set_cover_art(Some(gdk::Texture::for_pixbuf(&pixbuf)));
|
||||||
|
});
|
||||||
|
|
||||||
|
self.imp().cover_art_loading.replace(Some(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unbind(&self) {
|
pub fn unbind(&self) {
|
||||||
self.set_item(None::<model::Album>);
|
self.set_item(None::<model::Album>);
|
||||||
|
if let Some(handle) = self.imp().cover_art_loading.take() {
|
||||||
|
handle.abort();
|
||||||
|
}
|
||||||
|
self.set_cover_art(None::<gdk::Paintable>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue