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;
|
||||
|
||||
Image {
|
||||
icon-name: "media-optical-cd";
|
||||
paintable: bind template.cover_art;
|
||||
pixel-size: 160;
|
||||
halign: center;
|
||||
hexpand: false;
|
||||
|
|
|
@ -93,7 +93,6 @@ gridview.albums child image {
|
|||
|
||||
.album-carousel listview row image {
|
||||
border-radius: 3px;
|
||||
background-color: oklch(0 0 0);
|
||||
}
|
||||
|
||||
.album-carousel .labels {
|
||||
|
|
|
@ -157,7 +157,7 @@ mod imp {
|
|||
pub fn on_bind(&self, item: >k::ListItem, _factory: >k::SignalListItemFactory) {
|
||||
let child: super::Album = item.child().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]
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
use crate::model;
|
||||
use adw::gdk;
|
||||
use adw::{prelude::*, subclass::prelude::*};
|
||||
use glib::subclass::InitializingObject;
|
||||
use std::cell::RefCell;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use tokio::sync::Semaphore;
|
||||
use tracing::{event, Level};
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
@ -12,6 +15,11 @@ mod imp {
|
|||
pub struct Album {
|
||||
#[property(get, set, nullable)]
|
||||
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]
|
||||
|
@ -37,6 +45,9 @@ mod imp {
|
|||
impl BinImpl for Album {}
|
||||
}
|
||||
|
||||
// only fetch 10 thumbnails at a time
|
||||
static SEM: Semaphore = Semaphore::const_new(10);
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct Album(ObjectSubclass<imp::Album>)
|
||||
@extends adw::Bin, gtk::Widget,
|
||||
|
@ -44,11 +55,37 @@ glib::wrapper! {
|
|||
}
|
||||
|
||||
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));
|
||||
|
||||
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) {
|
||||
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