From 547a811acfb7e3e41db13335bb93882c27f0bd66 Mon Sep 17 00:00:00 2001 From: Reinout Meliesie Date: Wed, 5 Feb 2025 13:51:22 +0100 Subject: [PATCH] Make loading of poster images async --- src/main.rs | 2 +- src/ui/collatable_container/collated_grid.rs | 51 ++++++++++---------- src/ui/collatable_container/mod.rs | 18 +++---- src/ui/mod.rs | 11 +++-- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/main.rs b/src/main.rs index 768cbde..93c57fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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| { diff --git a/src/ui/collatable_container/collated_grid.rs b/src/ui/collatable_container/collated_grid.rs index 9d9bb8b..a50a624 100644 --- a/src/ui/collatable_container/collated_grid.rs +++ b/src/ui/collatable_container/collated_grid.rs @@ -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 , 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 , sorting : FilmsSorting ) { - let widgets = films . iter () - . map (create_film_entry) - . collect :: < Vec <_> > () ; + pub async fn set_films ( & self , films : Vec , 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 , 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 , sorting : SeriesSorting ) { - let widgets = series . iter () - . map (create_series_entry) - . collect :: < Vec <_> > () ; + pub async fn set_series ( & self , series : Vec , 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 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 ) diff --git a/src/ui/collatable_container/mod.rs b/src/ui/collatable_container/mod.rs index 50d3c45..69c0eec 100644 --- a/src/ui/collatable_container/mod.rs +++ b/src/ui/collatable_container/mod.rs @@ -63,9 +63,8 @@ pub struct CollatableSeriesContainer { } impl CollatableFilmsContainer { - pub fn new ( films : Vec ) -> 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 ) { - self . collated_grid . set_films ( films , FilmsSorting :: default () ) ; + pub async fn set_films ( & self , films : Vec ) { + self . collated_grid . set_films ( films , FilmsSorting :: default () ) . await ; } } impl CollatableSeriesContainer { - pub fn new ( series : Vec ) -> 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 ) { - self . collated_grid . set_series ( series , SeriesSorting :: default () ) ; + pub async fn set_series ( & self , series : Vec ) { + self . collated_grid . set_series ( series , SeriesSorting :: default () ) . await ; } } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 13951b6..f6390ba 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -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 ; } }