mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-31 21:48:20 -06:00
Picks up the fix that keeps the close request pending while the app holds unsaved work, the executable-name check in the Windows update helper, and the zip 9 / dirs-free build. Part of tracking issue storytold/craft-libs#319
126 lines
4.5 KiB
Rust
126 lines
4.5 KiB
Rust
//! Software updates, background check at startup, and startup prompt modal.
|
|
|
|
use crate::EffectcraftApp;
|
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
use craft_update::updater::{Action, Status, Updater};
|
|
|
|
pub(crate) struct Runtime {
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
updater: Updater,
|
|
/// The desktop app turns the check at start on; tests and the web build leave it off.
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
startup_check: bool,
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
check_requested: bool,
|
|
pub(crate) manual_window_open: bool,
|
|
pub(crate) status_message: Option<String>,
|
|
}
|
|
|
|
impl Default for Runtime {
|
|
fn default() -> Self {
|
|
Self {
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
updater: Updater::new(&craft_update::suite::EFFECTCRAFT, env!("CARGO_PKG_VERSION")),
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
startup_check: false,
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
check_requested: false,
|
|
manual_window_open: false,
|
|
status_message: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl EffectcraftApp {
|
|
/// Whether the app asks for a newer release when it starts (off until the desktop app turns it on).
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
pub fn set_startup_update_check(&mut self, on: bool) {
|
|
self.updates_rt.startup_check = on;
|
|
}
|
|
}
|
|
|
|
pub(crate) fn check(app: &mut EffectcraftApp) {
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
{
|
|
app.updates_rt.check_requested = true;
|
|
}
|
|
#[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.").to_string());
|
|
}
|
|
}
|
|
|
|
pub(crate) fn tick(app: &mut EffectcraftApp, ctx: &egui::Context) {
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
{
|
|
let rt = &mut app.updates_rt;
|
|
if std::mem::take(&mut rt.check_requested) {
|
|
rt.updater.check_now(ctx);
|
|
} else if rt.startup_check {
|
|
rt.updater.check_at_start(ctx);
|
|
}
|
|
rt.updater.tick(ctx);
|
|
}
|
|
#[cfg(target_arch = "wasm32")]
|
|
let _ = (app, ctx);
|
|
}
|
|
|
|
pub(crate) fn show(app: &mut EffectcraftApp, ctx: &egui::Context) {
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
{
|
|
// The restart helper is scheduled before the app closes, so no update starts over unsaved work.
|
|
let clean = !app.session.is_dirty();
|
|
match app.updates_rt.updater.show_if(ctx, clean) {
|
|
Action::OpenUrl(url) => ctx.open_url(egui::OpenUrl::new_tab(url)),
|
|
Action::Close => ctx.send_viewport_cmd(egui::ViewportCommand::Close),
|
|
Action::None => {}
|
|
}
|
|
// The window answers Help ▸ Check for Updates, so it follows the updater's status.
|
|
let rt = &mut app.updates_rt;
|
|
(rt.manual_window_open, rt.status_message) = match rt.updater.status() {
|
|
Status::Idle => (false, None),
|
|
Status::Checking => (true, None),
|
|
Status::UpToDate => (
|
|
true,
|
|
Some(crate::i18n::tr("EffectCraft {version} is currently the newest version available.").replace("{version}", env!("CARGO_PKG_VERSION"))),
|
|
),
|
|
Status::Failed(e) => (true, Some(crate::i18n::tr("Could not check for updates:\n{error}").replace("{error}", e))),
|
|
};
|
|
}
|
|
|
|
if app.updates_rt.manual_window_open {
|
|
let mut open = true;
|
|
let mut close = false;
|
|
egui::Window::new(crate::i18n::tr("Check for Updates"))
|
|
.open(&mut open)
|
|
.resizable(false)
|
|
.collapsible(false)
|
|
.anchor(egui::Align2::CENTER_CENTER, egui::vec2(0.0, 0.0))
|
|
.show(ctx, |ui| {
|
|
if let Some(msg) = &app.updates_rt.status_message {
|
|
ui.label(msg);
|
|
} else {
|
|
ui.label(crate::i18n::tr("Checking for updates…"));
|
|
}
|
|
ui.add_space(8.0);
|
|
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
|
if ui.button(crate::i18n::tr("Close")).clicked() {
|
|
close = true;
|
|
}
|
|
});
|
|
});
|
|
if !open || close {
|
|
app.updates_rt.manual_window_open = false;
|
|
app.updates_rt.status_message = None;
|
|
}
|
|
}
|
|
|
|
// Closing the window dismisses the outcome it showed.
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
if !app.updates_rt.manual_window_open {
|
|
app.updates_rt.updater.dismiss_status();
|
|
}
|
|
}
|