diff --git a/CHANGELOG.md b/CHANGELOG.md index 91d5b5c..0720e68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ you can now disable the primary manifest's entries. * GUI: On startup, Ludusavi will check if a new version is available and notify you. This happens at most once per 7 days. + * GUI: When left open, + Ludusavi will automatically check for manifest updates once every 24 hours. + Previously, this check only occurred when the app started. * Fixed: * CLI: Some commands would fail with relative path arguments. * Changed: diff --git a/src/gui/app.rs b/src/gui/app.rs index bb9df81..6a6662f 100644 --- a/src/gui/app.rs +++ b/src/gui/app.rs @@ -20,8 +20,8 @@ use crate::{ lang::TRANSLATOR, prelude::{app_dir, get_threads_from_env, initialize_rayon, Error, Finality, StrictPath, SyncDirection}, resource::{ - cache::Cache, - config::{Config, CustomGame, CustomGameKind, Root}, + cache::{self, Cache}, + config::{self, Config, CustomGame, CustomGameKind, Root}, manifest::Manifest, ResourceFile, SaveableResourceFile, }, @@ -66,6 +66,7 @@ pub enum SaveKind { #[derive(Default)] pub struct App { + flags: Flags, config: Config, manifest: Manifest, cache: Cache, @@ -1125,6 +1126,16 @@ impl App { self.switch_screen(Screen::CustomGames) } + fn update_manifest(config: config::ManifestConfig, cache: cache::Manifests, force: bool) -> Command { + Command::perform( + async move { tokio::task::spawn_blocking(move || Manifest::update(config, cache, force)).await }, + |join| match join { + Ok(x) => Message::ManifestUpdated(x), + Err(_) => Message::Ignore, + }, + ) + } + fn open_url(url: String) -> Command { let url2 = url.clone(); Command::perform(async { opener::open(url) }, move |res| match res { @@ -1249,8 +1260,6 @@ impl Application for App { } } - let manifest_config = config.manifest.clone(); - let manifest_cache = cache.manifests.clone(); let text_histories = TextHistories::new(&config); log::debug!("Config on startup: {config:?}"); @@ -1260,14 +1269,10 @@ impl Application for App { iced::font::load(std::borrow::Cow::Borrowed(crate::gui::font::ICONS_DATA)).map(|_| Message::Ignore), ]; if flags.update_manifest { - commands.push(Command::perform( - async move { - tokio::task::spawn_blocking(move || Manifest::update(manifest_config, manifest_cache, false)).await - }, - |join| match join { - Ok(x) => Message::ManifestUpdated(x), - Err(_) => Message::Ignore, - }, + commands.push(Self::update_manifest( + config.manifest.clone(), + cache.manifests.clone(), + false, )); } @@ -1288,6 +1293,7 @@ impl Application for App { modal, updating_manifest: flags.update_manifest, text_histories, + flags, ..Self::default() }, Command::batch(commands), @@ -1361,20 +1367,13 @@ impl Application for App { Command::none() } - Message::UpdateManifest => { + Message::UpdateManifest { force } => { + if self.updating_manifest { + return Command::none(); + } + self.updating_manifest = true; - let manifest_config = self.config.manifest.clone(); - let manifest_cache = self.cache.manifests.clone(); - Command::perform( - async move { - tokio::task::spawn_blocking(move || Manifest::update(manifest_config, manifest_cache, true)) - .await - }, - |join| match join { - Ok(x) => Message::ManifestUpdated(x), - Err(_) => Message::Ignore, - }, - ) + Self::update_manifest(self.config.manifest.clone(), self.cache.manifests.clone(), force) } Message::ManifestUpdated(updates) => { self.updating_manifest = false; @@ -2674,6 +2673,12 @@ impl Application for App { subscriptions.push(iced::time::every(Duration::from_millis(200)).map(|_| Message::Save)); } + if self.flags.update_manifest { + subscriptions.push( + iced::time::every(Duration::from_secs(60 * 60 * 24)).map(|_| Message::UpdateManifest { force: false }), + ); + } + if self.exiting { subscriptions.push(iced::time::every(Duration::from_millis(50)).map(|_| Message::Exit { user: false })); } diff --git a/src/gui/common.rs b/src/gui/common.rs index 968828d..6a248cc 100644 --- a/src/gui/common.rs +++ b/src/gui/common.rs @@ -108,7 +108,9 @@ pub enum Message { PruneNotifications, AppReleaseToggle(bool), AppReleaseChecked(Result), - UpdateManifest, + UpdateManifest { + force: bool, + }, ManifestUpdated(Vec, Error>>), Backup(BackupPhase), Restore(RestorePhase), diff --git a/src/gui/screen.rs b/src/gui/screen.rs index bda28ab..5893819 100644 --- a/src/gui/screen.rs +++ b/src/gui/screen.rs @@ -507,7 +507,10 @@ pub fn other<'a>( Row::new() .align_items(iced::Alignment::Center) .push(text(TRANSLATOR.manifest_label()).width(100)) - .push(button::refresh(Message::UpdateManifest, updating_manifest)), + .push(button::refresh( + Message::UpdateManifest { force: true }, + updating_manifest, + )), ) .push(editor::manifest(config, cache, histories, modifiers).padding([10, 0, 0, 0])), ) diff --git a/src/resource/config.rs b/src/resource/config.rs index a38ecc4..cc2eb8f 100644 --- a/src/resource/config.rs +++ b/src/resource/config.rs @@ -75,12 +75,12 @@ pub struct ManifestConfig { } impl ManifestConfig { - pub fn secondary_manifest_urls(&self) -> Vec<&str> { + pub fn secondary_manifest_urls(&self, force: bool) -> Vec<&str> { self.secondary .iter() .filter_map(|x| match x { SecondaryManifestConfig::Local { .. } => None, - SecondaryManifestConfig::Remote { url, .. } => Some(url.as_str()), + SecondaryManifestConfig::Remote { url, enable } => (*enable || force).then_some(url.as_str()), }) .collect() } diff --git a/src/resource/manifest.rs b/src/resource/manifest.rs index a2107b4..7a0afd2 100644 --- a/src/resource/manifest.rs +++ b/src/resource/manifest.rs @@ -391,9 +391,11 @@ impl Manifest { ) -> Vec, Error>> { let mut out = vec![]; - out.push(Self::update_one(&config.url, &cache, force, true)); + if config.enable || force { + out.push(Self::update_one(&config.url, &cache, force, true)); + } - for secondary in config.secondary_manifest_urls() { + for secondary in config.secondary_manifest_urls(force) { out.push(Self::update_one(secondary, &cache, force, false)); }