From 84bbf29882fc7310d719ace56a7171776ec2dcdc Mon Sep 17 00:00:00 2001 From: LynithDev <61880709+LynithDev@users.noreply.github.com> Date: Mon, 14 Sep 2026 21:03:34 +0200 Subject: [PATCH] fix: mod updates applying after launch and not before --- .../src/components/package_update_popup.rs | 7 +- packages/oneclient_app/src/hooks/actions.rs | 84 ++++--------------- packages/oneclient_app/src/notifications.rs | 22 +++-- 3 files changed, 34 insertions(+), 79 deletions(-) diff --git a/packages/oneclient_app/src/components/package_update_popup.rs b/packages/oneclient_app/src/components/package_update_popup.rs index ce6b2e21..89907681 100644 --- a/packages/oneclient_app/src/components/package_update_popup.rs +++ b/packages/oneclient_app/src/components/package_update_popup.rs @@ -247,15 +247,14 @@ fn content( } let answers = choices.read(); + let mut chosen = Vec::new(); for update in &all { match answers .get(&row_key(update)) .copied() .unwrap_or_default() { - RowChoice::Update => { - proceed_dispatch.apply_package_update(update.clone()); - } + RowChoice::Update => chosen.push(update.clone()), RowChoice::Skip => {} RowChoice::SkipVersion => proceed_dispatch .skip_package_update( @@ -264,7 +263,7 @@ fn content( ), } } - proceed_dispatch.close_package_updates(); + proceed_dispatch.proceed_package_updates(chosen); }) .child(Icon::new(IconType::DownloadCloud02).size(15.)) .text("Proceed"), diff --git a/packages/oneclient_app/src/hooks/actions.rs b/packages/oneclient_app/src/hooks/actions.rs index d27e8d98..1fc88734 100644 --- a/packages/oneclient_app/src/hooks/actions.rs +++ b/packages/oneclient_app/src/hooks/actions.rs @@ -846,6 +846,12 @@ impl Actions { }); } + pub fn proceed_package_updates(&self, chosen: Vec) { + self.with_engine(move |state| { + state.notifications.proceed_package_updates(chosen) + }); + } + pub fn close_package_updates(&self) { self.with_engine(|state| state.notifications.close_package_updates()); } @@ -1536,7 +1542,10 @@ impl Actions { else { return; }; - self.prompt_package_updates(group).await; + let chosen = self.prompt_package_updates(group).await; + if !chosen.is_empty() { + self.apply_updates_for_launch(state, &chosen).await; + } } } } @@ -1619,6 +1628,8 @@ impl Actions { .finish_grouped_as_actions(&mut app.inbox, session_id, spec); }); + super::invalidate_cluster_queries().await; + if applied > 0 { super::invalidate_cluster_queries().await; } @@ -1664,7 +1675,10 @@ impl Actions { let _ = wait.await; } - async fn prompt_package_updates(&self, group: PackageUpdateGroup) { + async fn prompt_package_updates( + &self, + group: PackageUpdateGroup, + ) -> Vec { let (done, wait) = tokio::sync::oneshot::channel(); self.with_engine(move |state| { @@ -1672,71 +1686,7 @@ impl Actions { state.center_open = false; }); - let _ = wait.await; - } - - pub fn apply_package_update(&self, update: oneclient_core::BrowserPackageUpdate) { - let actions = self.clone(); - spawn_forever(async move { - let Ok(state) = launcher::state() else { return }; - let events = state.services.events.clone(); - - let session = oneclient_events::GroupedProgressSession::start( - &events, - format!("Updating {}", update.display_name), - ); - let child = session.child( - update.display_name.clone(), - 1, - oneclient_events::TaskCategory::Packages, - ); - - let result = oneclient_core::apply_browser_package_update( - &update, - Some(&child), - &state.services.content(), - ) - .await; - - child.finish(); - let session_id = session.detach(); - - let spec = match &result { - Ok(_) => NotificationSpec { - title: "Updated".to_string(), - body: format!( - "{} is now on {}", - update.display_name, update.latest_version_name - ), - level: Level::Info, - icon: Some(IconType::DownloadCloud02), - progress: None, - actions: Vec::new(), - }, - Err(err) => NotificationSpec { - title: "Update failed".to_string(), - body: err.to_string(), - level: Level::Error, - icon: None, - progress: None, - actions: Vec::new(), - }, - }; - - actions.with_engine(|app| { - app.notifications - .finish_grouped_as_actions(&mut app.inbox, session_id, Some(spec)); - }); - - // A failed update stays in the list so the user can retry - if result.is_ok() { - actions.with_engine(|app| { - app.notifications - .resolve_package_update(update.cluster_id, &update.hash); - }); - super::invalidate_cluster_queries().await; - } - }); + wait.await.unwrap_or_default() } /// The package stays marked out of date only the modal stops asking and diff --git a/packages/oneclient_app/src/notifications.rs b/packages/oneclient_app/src/notifications.rs index c5ab97e5..bcd34267 100644 --- a/packages/oneclient_app/src/notifications.rs +++ b/packages/oneclient_app/src/notifications.rs @@ -225,7 +225,7 @@ pub struct NotificationState { /// Resumes the launch that opened the update modal /// Held here not by the launch task /// because every way the modal can end goes through this state - package_updates_done: Option>, + package_updates_done: Option>>, optional_mods_done: Option>, } @@ -388,7 +388,7 @@ impl NotificationState { pub fn open_package_updates( &mut self, groups: Vec, - done: Option>, + done: Option>>, ) { let groups: Vec = groups .into_iter() @@ -397,19 +397,25 @@ impl NotificationState { if groups.is_empty() { if let Some(done) = done { - let _ = done.send(()); + let _ = done.send(Vec::new()); } return; } // A second modal would strand the first launch so release the old continuation first - self.finish_package_updates(); + self.finish_package_updates(Vec::new()); self.package_updates = Some(groups); self.package_updates_done = done; } pub fn close_package_updates(&mut self) { - self.finish_package_updates(); + self.finish_package_updates(Vec::new()); + } + + /// The launch applies these itself so the game starts on the versions the + /// player just picked rather than racing them + pub fn proceed_package_updates(&mut self, chosen: Vec) { + self.finish_package_updates(chosen); } /// Applying and skipping are both answers either drops the row and can close the modal @@ -426,16 +432,16 @@ impl NotificationState { groups.retain(|group| !group.packages.is_empty()); if groups.is_empty() { - self.finish_package_updates(); + self.finish_package_updates(Vec::new()); } } /// Safe to call when nothing is open so every exit path can call it unconditionally - fn finish_package_updates(&mut self) { + fn finish_package_updates(&mut self, chosen: Vec) { self.package_updates = None; if let Some(done) = self.package_updates_done.take() { // A send failure means the launch task is gone nothing left to resume - let _ = done.send(()); + let _ = done.send(chosen); } }