Make loading of poster images async

This commit is contained in:
Reinout Meliesie 2025-02-05 13:51:22 +01:00
parent bc1661b8d9
commit 547a811acf
Signed by: zedfrigg
GPG key ID: 3AFCC06481308BC6
4 changed files with 41 additions and 41 deletions

View file

@ -45,7 +45,7 @@ fn show_window ( app : & Application ) {
async {
let data_manager = DataManager :: new () . await ? ;
let collection = data_manager . get_collection_overview () . await ;
ui . render_collection_overview (collection) ;
ui . render_collection_overview (collection) . await ;
Ok (())
} ,
|error| {

View file

@ -4,10 +4,11 @@ use {
Align :: * ,
Orientation :: * ,
gdk :: * ,
gio :: * ,
pango :: { * , Weight :: * } ,
prelude :: * ,
} ,
std :: { cell :: * , iter :: * , path :: Path } ,
std :: { cell :: * , iter :: * , path :: { Path , PathBuf } } ,
} ;
use crate :: ui :: { collatable_container :: * , component :: * } ;
@ -24,7 +25,7 @@ pub struct CollatedSeriesGrid {
}
impl CollatedFilmsGrid {
pub fn new ( films : Vec <FilmOverview> , sorting : FilmsSorting ) -> Self {
pub fn new () -> Self {
let grid_widget = flow_box ! (
@ orientation : Horizontal ;
@ homogeneous : true ;
@ -32,16 +33,14 @@ impl CollatedFilmsGrid {
) ;
let film_widget_pairs = RefCell :: new ( vec ! () ) ;
let component = Self { film_widget_pairs , grid_widget } ;
component . set_films ( films , sorting ) ;
component
Self { film_widget_pairs , grid_widget }
}
pub fn set_films ( & self , films : Vec <FilmOverview> , sorting : FilmsSorting ) {
let widgets = films . iter ()
. map (create_film_entry)
. collect :: < Vec <_> > () ;
pub async fn set_films ( & self , films : Vec <FilmOverview> , sorting : FilmsSorting ) {
let mut widgets = Vec :: new () ;
for film in films . as_slice () {
widgets . push ( create_film_entry (film) . await ) ;
}
* self . film_widget_pairs . borrow_mut () = zip ( films , widgets )
. collect () ;
@ -77,7 +76,7 @@ impl CollatedFilmsGrid {
}
}
impl CollatedSeriesGrid {
pub fn new ( series : Vec <SeriesOverview> , sorting : SeriesSorting ) -> Self {
pub fn new () -> Self {
let grid_widget = flow_box ! (
@ orientation : Horizontal ;
@ homogeneous : true ;
@ -85,16 +84,14 @@ impl CollatedSeriesGrid {
) ;
let series_widget_pairs = RefCell :: new ( vec ! () ) ;
let component = Self { series_widget_pairs , grid_widget } ;
component . set_series ( series, sorting ) ;
component
Self { series_widget_pairs , grid_widget }
}
pub fn set_series ( & self , series : Vec <SeriesOverview> , sorting : SeriesSorting ) {
let widgets = series . iter ()
. map (create_series_entry)
. collect :: < Vec <_> > () ;
pub async fn set_series ( & self , series : Vec <SeriesOverview> , sorting : SeriesSorting ) {
let mut widgets = Vec :: new () ;
for series in series . as_slice () {
widgets . push ( create_series_entry (series) . await ) ;
}
* self . series_widget_pairs . borrow_mut () = zip ( series , widgets )
. collect () ;
@ -135,24 +132,24 @@ impl Component <FlowBox> for CollatedSeriesGrid {
fn get_widget ( & self ) -> & FlowBox { & self . grid_widget }
}
pub fn create_film_entry ( film : & FilmOverview ) -> Box {
pub async fn create_film_entry ( film : & FilmOverview ) -> Box {
create_collection_item (
film . name . as_str () ,
film . original_name . as_deref () ,
film . poster_file_path . as_deref () ,
& create_film_details (film) ,
)
) . await
}
pub fn create_series_entry ( series : & SeriesOverview ) -> Box {
pub async fn create_series_entry ( series : & SeriesOverview ) -> Box {
create_collection_item (
series . name . as_str () ,
series . original_name . as_deref () ,
series . poster_file_path . as_deref () ,
& create_series_details (series) ,
)
) . await
}
fn create_collection_item (
async fn create_collection_item (
name : & str ,
original_name : Option < & str > ,
poster_file_path : Option < & Path > ,
@ -165,7 +162,11 @@ fn create_collection_item (
. build () ;
if let Some (poster_file_path) = poster_file_path {
let poster_texture = Texture :: from_filename (poster_file_path) . unwrap () ;
let poster_file_path = PathBuf :: from (poster_file_path) ; // God forbid `Path` would work with `clone ! ()`
let poster_texture = spawn_blocking ( move ||
Texture :: from_filename (poster_file_path) . unwrap ()
) . await . unwrap () ;
container . append (
& Image :: builder ()
. paintable ( & poster_texture )

View file

@ -63,9 +63,8 @@ pub struct CollatableSeriesContainer {
}
impl CollatableFilmsContainer {
pub fn new ( films : Vec <FilmOverview> ) -> Self {
let collated_grid = leak (
CollatedFilmsGrid :: new ( films , FilmsSorting :: default () ) ) ;
pub fn new () -> Self {
let collated_grid = leak ( CollatedFilmsGrid :: new () ) ;
let film_collation_menu = FilmCollationMenu :: new ( |sorting|
collated_grid . set_sorting (sorting) ) ;
@ -81,14 +80,13 @@ impl CollatableFilmsContainer {
Self { collated_grid , widget }
}
pub fn set_films ( & self , films : Vec <FilmOverview> ) {
self . collated_grid . set_films ( films , FilmsSorting :: default () ) ;
pub async fn set_films ( & self , films : Vec <FilmOverview> ) {
self . collated_grid . set_films ( films , FilmsSorting :: default () ) . await ;
}
}
impl CollatableSeriesContainer {
pub fn new ( series : Vec <SeriesOverview> ) -> Self {
let collated_grid = leak (
CollatedSeriesGrid :: new ( series , SeriesSorting :: default () ) ) ;
pub fn new () -> Self {
let collated_grid = leak ( CollatedSeriesGrid :: new () ) ;
let series_collation_menu = SeriesCollationMenu :: new ( |sorting| {
collated_grid . set_sorting (sorting) ;
} ) ;
@ -105,8 +103,8 @@ impl CollatableSeriesContainer {
Self { collated_grid , widget }
}
pub fn set_series ( & self , series : Vec <SeriesOverview> ) {
self . collated_grid . set_series ( series , SeriesSorting :: default () ) ;
pub async fn set_series ( & self , series : Vec <SeriesOverview> ) {
self . collated_grid . set_series ( series , SeriesSorting :: default () ) . await ;
}
}

View file

@ -30,8 +30,8 @@ pub struct UI {
impl UI {
pub fn new ( application : & Application ) -> UI {
let films_component = CollatableFilmsContainer :: new ( vec ! () ) ;
let series_component = CollatableSeriesContainer :: new ( vec ! () ) ;
let films_component = CollatableFilmsContainer :: new () ;
let series_component = CollatableSeriesContainer :: new () ;
let switch_component = CollectionViewStack :: new (
& films_component , & series_component ) ;
let header_bar = ApplicationHeaderBar :: new ( & switch_component ) ;
@ -53,8 +53,9 @@ impl UI {
pub fn close_window ( & self ) { self . window . close () }
pub fn render_collection_overview ( & self , collection : CollectionOverview ) {
self . films_component . set_films ( collection . films ) ;
self . series_component . set_series ( collection . series ) ;
pub async fn render_collection_overview ( & self , collection : CollectionOverview ) {
// TODO: Find a way to await these futures concurrently
self . films_component . set_films ( collection . films ) . await ;
self . series_component . set_series ( collection . series ) . await ;
}
}