diff --git a/src/main.rs b/src/main.rs index 1b3e89c..1cf0673 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,8 +22,8 @@ use std::error::Error; async fn main() -> Result<(), Box> { let settings = settings::Settings::new()?; settings::Settings::write_config_if_missing(); - let usersinfo = sync::run_sync(&settings).unwrap(); - sync::download_images(&settings,&usersinfo).await; + let usersinfo = sync::run_sync(&settings,&mut None).unwrap(); + sync::download_images(&settings,&usersinfo,&mut None).await; Ok(()) } diff --git a/src/steamgriddb/downloader.rs b/src/steamgriddb/downloader.rs index e7fec18..12a10a2 100644 --- a/src/steamgriddb/downloader.rs +++ b/src/steamgriddb/downloader.rs @@ -5,6 +5,7 @@ use std::{collections::HashMap, path::Path}; use futures::{stream, StreamExt}; use serde::{Deserialize, Serialize}; +use tokio::sync::watch::Sender; use std::error::Error; use steamgriddb_api::query_parameters::{GridDimentions, Nsfw}; // 0.3.1 @@ -14,6 +15,7 @@ use steamgriddb_api::Client; use crate::settings::Settings; use crate::steam::{get_shortcuts_for_user, get_users_images, SteamUsersInfo}; use crate::steamgriddb::ImageType; +use crate::sync::SyncProgress; use super::CachedSearch; @@ -23,6 +25,7 @@ pub async fn download_images_for_users<'b>( settings: &Settings, users: &[SteamUsersInfo], download_animated: bool, + sender:&mut Option> ) { let auth_key = &settings.steamgrid_db.auth_key; if let Some(auth_key) = auth_key { @@ -32,6 +35,9 @@ pub async fn download_images_for_users<'b>( let search = CachedSearch::new(&client); let search = &search; let client = &client; + if let Some(sender) = sender{ + let _ = sender.send(SyncProgress::FindingImages); + } let to_downloads = stream::iter(users) .map(|user| { let shortcut_info = get_shortcuts_for_user(user); @@ -54,9 +60,12 @@ pub async fn download_images_for_users<'b>( .collect::>>() .await; let to_downloads = to_downloads.iter().flatten().collect::>(); + let total = to_downloads.len(); if !to_downloads.is_empty() { + if let Some(sender) = sender{ + let _ = sender.send(SyncProgress::DownloadingImages { to_download: total }); + } search.save(); - stream::iter(to_downloads) .map(|to_download| async move { if let Err(e) = download_to_download(to_download).await { @@ -73,7 +82,7 @@ pub async fn download_images_for_users<'b>( } } else { println!("Steamgrid DB Auth Key not found, please add one as described here: https://github.com/PhilipK/steam_shortcuts_sync#configuration"); - } + } } #[derive(Serialize, Deserialize, Debug, Clone)] diff --git a/src/sync/mod.rs b/src/sync/mod.rs index da9fd68..230e452 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -4,4 +4,6 @@ mod synchronization; pub use synchronization::run_sync; pub use synchronization::download_images; -pub use synchronization::get_platform_shortcuts; \ No newline at end of file +pub use synchronization::get_platform_shortcuts; + +pub use synchronization::SyncProgress; \ No newline at end of file diff --git a/src/sync/synchronization.rs b/src/sync/synchronization.rs index f8a997e..7d54be7 100644 --- a/src/sync/synchronization.rs +++ b/src/sync/synchronization.rs @@ -1,4 +1,5 @@ use steam_shortcuts_util::{shortcut::ShortcutOwned, shortcuts_to_bytes}; +use tokio::sync::watch::Sender; use crate::{ egs::EpicPlatform, @@ -11,7 +12,7 @@ use crate::{ Collection, ShortcutInfo, SteamUsersInfo, }, steamgriddb::{download_images_for_users, ImageType}, - uplay::Uplay, + uplay::Uplay, }; #[cfg(target_family = "unix")] @@ -24,7 +25,25 @@ use std::{fs::File, io::Write, path::Path}; const BOILR_TAG: &str = "boilr"; -pub fn run_sync(settings: &Settings) -> Result, String> { + +pub enum SyncProgress{ + NotStarted, + Starting, + FoundGames{ + games_found:usize + }, + FindingImages, + DownloadingImages{ + to_download:usize, + }, + Done +} + + +pub fn run_sync(settings: &Settings, sender: &mut Option>) -> Result, String> { + if let Some(sender) = &sender{ + let _ = sender.send(SyncProgress::Starting); + } let mut userinfo_shortcuts = get_shortcuts_paths(&settings.steam) .map_err(|e| format!("Getting shortcut paths failed: {e}"))?; @@ -34,6 +53,9 @@ pub fn run_sync(settings: &Settings) -> Result, String> { .flat_map(|s| s.1.clone()) .filter(|s| !settings.blacklisted_games.contains(&s.app_id)) .collect(); + if let Some(sender) = &sender{ + let _ = sender.send(SyncProgress::FoundGames { games_found: all_shortcuts.len() }); + } for shortcut in &all_shortcuts { println!("Appid: {} name: {}", shortcut.app_id, shortcut.app_name); } @@ -69,18 +91,18 @@ pub fn run_sync(settings: &Settings) -> Result, String> { let duration = start_time.elapsed(); println!("Finished synchronizing games in: {:?}", duration); - } + } Ok(userinfo_shortcuts) } -pub async fn download_images(settings: &Settings, userinfo_shortcuts: &Vec) { +pub async fn download_images(settings: &Settings, userinfo_shortcuts: &Vec,sender: &mut Option>) { if settings.steamgrid_db.enabled { if settings.steamgrid_db.prefer_animated { println!("downloading animated images"); - download_images_for_users(settings, userinfo_shortcuts, true).await; + download_images_for_users(settings, userinfo_shortcuts, true,sender).await; } - download_images_for_users(settings, userinfo_shortcuts, false).await; + download_images_for_users(settings, userinfo_shortcuts, false,sender).await; } } diff --git a/src/ui/uiapp.rs b/src/ui/uiapp.rs index afd2e32..0f5be90 100644 --- a/src/ui/uiapp.rs +++ b/src/ui/uiapp.rs @@ -1,11 +1,11 @@ -use eframe::{egui, epi::{self, IconData},}; -use egui::{ScrollArea, TextureHandle, Stroke, Rounding, Image, ImageButton}; +use eframe::{egui, epi::{self},}; +use egui::{ScrollArea, TextureHandle, Stroke, Rounding, ImageButton}; use futures::executor::block_on; use steam_shortcuts_util::shortcut::ShortcutOwned; -use std::error::Error; -use tokio::runtime::Runtime; +use std::{error::Error}; +use tokio::{runtime::Runtime, sync::watch::{Receiver, self}}; -use crate::{settings::Settings, sync::{download_images, self}, sync::run_sync}; +use crate::{settings::Settings, sync::{download_images, self, SyncProgress}, sync::run_sync}; use super::{ui_images::{get_import_image, get_logo, get_logo_icon}, ui_colors::{TEXT_COLOR, BACKGROUND_COLOR, BG_STROKE_COLOR, ORANGE, PURLPLE, LIGHT_ORANGE}}; @@ -22,9 +22,12 @@ struct MyEguiApp { settings: Settings, rt: Runtime, ui_images: UiImages, - games_to_sync:Option)>> + games_to_sync:Option)>>, + status_reciever: Receiver, } + + impl MyEguiApp { pub fn new() -> Self { let runtime = Runtime::new().unwrap(); @@ -34,17 +37,24 @@ impl MyEguiApp { rt: runtime, games_to_sync:None, ui_images: UiImages::default(), + status_reciever: watch::channel(SyncProgress::NotStarted).1, } } - pub fn run_sync(&self) { - let settings = self.settings.clone(); - self.rt.spawn_blocking(move || { - + pub fn run_sync(&mut self) { + let (sender,mut reciever ) = watch::channel(SyncProgress::NotStarted); + let settings = self.settings.clone(); + self.status_reciever = reciever; + self.rt.spawn_blocking(move || { + MyEguiApp::save_settings_to_file(&settings); //TODO get status back to ui - let usersinfo = run_sync(&settings).unwrap(); - let task = download_images(&settings, &usersinfo); + let mut some_sender =Some(sender); + let usersinfo = run_sync(&settings,&mut some_sender).unwrap(); + let task = download_images(&settings, &usersinfo,&mut some_sender); block_on(task); + if let Some(sender) = some_sender{ + let _ = sender.send(SyncProgress::Done); + } }); } @@ -93,6 +103,28 @@ impl epi::App for MyEguiApp { egui::TopBottomPanel::new(egui::panel::TopBottomSide::Bottom, "Bottom Panel") .show(ctx,|ui|{ + { + let status = &*self.status_reciever.borrow(); + match status{ + SyncProgress::NotStarted => {}, + SyncProgress::Starting => { + ui.label("Starting Import"); + }, + SyncProgress::FoundGames { games_found } => { + ui.label(format!("Found {} games to import",games_found)); + }, + SyncProgress::FindingImages => { + ui.label(format!("Searching for images")); + }, + SyncProgress::DownloadingImages { to_download } => { + ui.label(format!("Downloading {} images ",to_download)); + }, + SyncProgress::Done =>{ + ui.label(format!("Done importing games")); + }, + }; + } + let texture = self.get_import_image(ui); let size = texture.size_vec2(); let image_button = ImageButton::new(texture, size);