mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-26 11:07:54 -06:00
fix(updates): report self-update results to the prompt and finish through the app's close path
Keeps the worker's failure visible instead of leaving the prompt installing, repaints while a check runs, and no longer calls process::exit past the unsaved-work prompt.
This commit is contained in:
@@ -28,9 +28,9 @@ pub mod native_menu;
|
||||
pub mod panels;
|
||||
mod pointer_wrap;
|
||||
pub mod prefs_live;
|
||||
pub mod updates_ui;
|
||||
pub mod state;
|
||||
pub mod theme;
|
||||
pub mod updates_ui;
|
||||
pub mod widgets;
|
||||
mod workspace_state;
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ pub(crate) struct Runtime {
|
||||
rx: Option<std::sync::mpsc::Receiver<Result<Option<craft_update::Release>, String>>>,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
checking: bool,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
update_rx: Option<std::sync::mpsc::Receiver<Result<(), String>>>,
|
||||
}
|
||||
|
||||
impl Default for Runtime {
|
||||
@@ -28,6 +30,8 @@ impl Default for Runtime {
|
||||
rx: None,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
checking: false,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
update_rx: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,7 +47,7 @@ pub(crate) fn check(app: &mut EffectcraftApp) {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
app.updates_rt.manual_window_open = true;
|
||||
app.updates_rt.status_message = Some(crate::i18n::tr("Update check is not supported in the web browser."));
|
||||
app.updates_rt.status_message = Some(crate::i18n::tr("Update check is not supported in the web browser.").to_string());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +81,10 @@ pub(crate) fn tick(app: &mut EffectcraftApp, ctx: &egui::Context) {
|
||||
start_check(app);
|
||||
}
|
||||
|
||||
if app.updates_rt.checking {
|
||||
ctx.request_repaint_after(std::time::Duration::from_millis(100));
|
||||
}
|
||||
|
||||
let mut completed = None;
|
||||
if let Some(rx) = &app.updates_rt.rx {
|
||||
if let Ok(res) = rx.try_recv() {
|
||||
@@ -89,8 +97,7 @@ pub(crate) fn tick(app: &mut EffectcraftApp, ctx: &egui::Context) {
|
||||
app.updates_rt.checking = false;
|
||||
match res {
|
||||
Ok(Some(release)) => {
|
||||
let mut prompt =
|
||||
craft_update::StartupPrompt::new(&craft_update::suite::EFFECTCRAFT, release, env!("CARGO_PKG_VERSION"));
|
||||
let mut prompt = craft_update::StartupPrompt::new(&craft_update::suite::EFFECTCRAFT, release, env!("CARGO_PKG_VERSION"));
|
||||
prompt.open = true;
|
||||
app.updates_rt.prompt = Some(prompt);
|
||||
ctx.request_repaint();
|
||||
@@ -98,8 +105,7 @@ pub(crate) fn tick(app: &mut EffectcraftApp, ctx: &egui::Context) {
|
||||
Ok(None) => {
|
||||
if app.updates_rt.manual_checked {
|
||||
app.updates_rt.manual_checked = false;
|
||||
app.updates_rt.status_message =
|
||||
Some(format!("EffectCraft {} is currently the newest version available.", env!("CARGO_PKG_VERSION")));
|
||||
app.updates_rt.status_message = Some(format!("EffectCraft {} is currently the newest version available.", env!("CARGO_PKG_VERSION")));
|
||||
app.updates_rt.manual_window_open = true;
|
||||
ctx.request_repaint();
|
||||
}
|
||||
@@ -122,68 +128,60 @@ pub(crate) fn show(app: &mut EffectcraftApp, ctx: &egui::Context) {
|
||||
{
|
||||
let mut download_url = None;
|
||||
if let Some(prompt) = &mut app.updates_rt.prompt {
|
||||
if let Some(result) = app.updates_rt.update_rx.as_ref().and_then(|rx| rx.try_recv().ok()) {
|
||||
app.updates_rt.update_rx = None;
|
||||
match result {
|
||||
// The app's close path asks about unsaved work; the restart helper relaunches once the process exits.
|
||||
Ok(()) => ctx.send_viewport_cmd(egui::ViewportCommand::Close),
|
||||
Err(e) => {
|
||||
prompt.status_message = Some(e);
|
||||
prompt.is_installing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
match prompt.show(ctx) {
|
||||
craft_update::StartupPromptResponse::Pending => {}
|
||||
craft_update::StartupPromptResponse::UpdateAndRestart => {
|
||||
prompt.is_installing = true;
|
||||
if let Some(install) = craft_update::self_update::current(&craft_update::suite::EFFECTCRAFT) {
|
||||
let mut release = prompt.release.clone();
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
app.updates_rt.update_rx = Some(rx);
|
||||
let ctx = ctx.clone();
|
||||
std::thread::spawn(move || {
|
||||
let http = match craft_update::Http::new("EffectCraft/Update") {
|
||||
Ok(h) => h,
|
||||
Err(e) => {
|
||||
log::warn!("could not initialize HTTP: {e}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
if release.assets.is_empty() {
|
||||
if let Ok(Some(full)) = craft_update::check_for_update(
|
||||
&craft_update::suite::EFFECTCRAFT,
|
||||
&http,
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
) {
|
||||
let mut run = || -> Result<(), String> {
|
||||
let http = craft_update::Http::new("EffectCraft/Update").map_err(|e| format!("could not initialize HTTP: {e}"))?;
|
||||
if release.assets.is_empty()
|
||||
&& let Some(full) = craft_update::check_for_update(&craft_update::suite::EFFECTCRAFT, &http, env!("CARGO_PKG_VERSION"))
|
||||
.map_err(|e| format!("could not fetch release assets: {e}"))?
|
||||
{
|
||||
release = full;
|
||||
}
|
||||
}
|
||||
let paths = match craft_update::Paths::for_app(&craft_update::suite::EFFECTCRAFT) {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
log::warn!("could not find paths: {e}");
|
||||
return;
|
||||
}
|
||||
let paths =
|
||||
craft_update::Paths::for_app(&craft_update::suite::EFFECTCRAFT).map_err(|e| format!("could not find paths: {e}"))?;
|
||||
let platform = craft_update::Platform::current().ok_or("unsupported platform for self update")?;
|
||||
craft_update::self_update::update(
|
||||
&craft_update::suite::EFFECTCRAFT,
|
||||
&install,
|
||||
&release,
|
||||
platform,
|
||||
&http,
|
||||
&paths,
|
||||
&craft_update::Stop::default(),
|
||||
&mut |_| {},
|
||||
&|| Ok(()),
|
||||
Some(env!("CARGO_PKG_VERSION")),
|
||||
)
|
||||
};
|
||||
let stop = craft_update::Stop::default();
|
||||
let platform = match craft_update::Platform::current() {
|
||||
Some(p) => p,
|
||||
None => {
|
||||
log::warn!("unsupported platform for self update");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let last = || Ok(());
|
||||
match craft_update::self_update::update(
|
||||
&craft_update::suite::EFFECTCRAFT,
|
||||
&install,
|
||||
&release,
|
||||
platform,
|
||||
&http,
|
||||
&paths,
|
||||
&stop,
|
||||
&mut |_| {},
|
||||
&last,
|
||||
Some(env!("CARGO_PKG_VERSION")),
|
||||
) {
|
||||
Ok(()) => {
|
||||
std::process::exit(0);
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("EffectCraft self-update failed: {e}");
|
||||
}
|
||||
let result = run();
|
||||
if let Err(e) = &result {
|
||||
log::warn!("self-update failed: {e}");
|
||||
}
|
||||
let _ = tx.send(result);
|
||||
ctx.request_repaint();
|
||||
});
|
||||
} else {
|
||||
prompt.status_message =
|
||||
Some("Cannot auto-update this installation type. Please download manually.".to_string());
|
||||
prompt.status_message = Some("Cannot auto-update this installation type. Please download manually.".to_string());
|
||||
prompt.is_installing = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user