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 { async {
let data_manager = DataManager :: new () . await ? ; let data_manager = DataManager :: new () . await ? ;
let collection = data_manager . get_collection_overview () . await ; let collection = data_manager . get_collection_overview () . await ;
ui . render_collection_overview (collection) ; ui . render_collection_overview (collection) . await ;
Ok (()) Ok (())
} , } ,
|error| { |error| {

View file

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

View file

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

View file

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