eframe web: Store app state to local storage when leaving site (#2927)

This commit is contained in:
Emil Ernerfeldt 2023-04-18 20:26:02 +02:00 committed by GitHub
parent 438f6eafc8
commit 0f9e1a3526
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 15 deletions

View File

@ -299,21 +299,23 @@ impl AppRunner {
.unwrap() .unwrap()
} }
pub fn auto_save(&mut self) { pub fn auto_save_if_needed(&mut self) {
let now = now_sec(); let time_since_last_save = now_sec() - self.last_save_time;
let time_since_last_save = now - self.last_save_time;
if time_since_last_save > self.app.auto_save_interval().as_secs_f64() { if time_since_last_save > self.app.auto_save_interval().as_secs_f64() {
if self.app.persist_egui_memory() { self.save();
save_memory(&self.egui_ctx);
}
if let Some(storage) = self.frame.storage_mut() {
self.app.save(storage);
}
self.last_save_time = now;
} }
} }
pub fn save(&mut self) {
if self.app.persist_egui_memory() {
save_memory(&self.egui_ctx);
}
if let Some(storage) = self.frame.storage_mut() {
self.app.save(storage);
}
self.last_save_time = now_sec();
}
pub fn canvas_id(&self) -> &str { pub fn canvas_id(&self) -> &str {
self.painter.canvas_id() self.painter.canvas_id()
} }

View File

@ -21,7 +21,7 @@ pub fn paint_and_schedule(
runner_lock runner_lock
.needs_repaint .needs_repaint
.repaint_after(repaint_after.as_secs_f64()); .repaint_after(repaint_after.as_secs_f64());
runner_lock.auto_save(); runner_lock.auto_save_if_needed();
} }
Ok(IsDestroyed(is_destroyed)) Ok(IsDestroyed(is_destroyed))
@ -54,13 +54,17 @@ pub fn install_document_events(runner_container: &mut AppRunnerContainer) -> Res
{ {
// Avoid sticky modifier keys on alt-tab: // Avoid sticky modifier keys on alt-tab:
let clear_modifiers = ["blur", "focus"]; for event_name in ["blur", "focus"] {
for event_name in clear_modifiers {
let closure = let closure =
move |_event: web_sys::MouseEvent, move |_event: web_sys::MouseEvent,
mut runner_lock: egui::mutex::MutexGuard<'_, AppRunner>| { mut runner_lock: egui::mutex::MutexGuard<'_, AppRunner>| {
let has_focus = event_name == "focus"; let has_focus = event_name == "focus";
if !has_focus {
// We lost focus - good idea to save
runner_lock.save();
}
runner_lock.input.on_web_page_focus_change(has_focus); runner_lock.input.on_web_page_focus_change(has_focus);
runner_lock.egui_ctx().request_repaint(); runner_lock.egui_ctx().request_repaint();
// tracing::debug!("{event_name:?}"); // tracing::debug!("{event_name:?}");
@ -208,6 +212,15 @@ pub fn install_document_events(runner_container: &mut AppRunnerContainer) -> Res
pub fn install_window_events(runner_container: &mut AppRunnerContainer) -> Result<(), JsValue> { pub fn install_window_events(runner_container: &mut AppRunnerContainer) -> Result<(), JsValue> {
let window = web_sys::window().unwrap(); let window = web_sys::window().unwrap();
// Save-on-close
runner_container.add_event_listener(
&window,
"onbeforeunload",
|_: web_sys::Event, mut runner_lock| {
runner_lock.save();
},
)?;
for event_name in &["load", "pagehide", "pageshow", "resize"] { for event_name in &["load", "pagehide", "pageshow", "resize"] {
runner_container.add_event_listener( runner_container.add_event_listener(
&window, &window,