Skip to content

Commit 407288c

Browse files
Handle app lifecycle events: Pause, Resume, etc
1 parent fd6af28 commit 407288c

File tree

1 file changed

+100
-25
lines changed

1 file changed

+100
-25
lines changed

src/app.rs

Lines changed: 100 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ pub struct App {
141141
/// The details of a room we're waiting on to be joined so that we can navigate to it.
142142
/// Also includes an optional room ID to be closed once the awaited room is joined.
143143
#[rust] waiting_to_navigate_to_joined_room: Option<(BasicRoomDetails, Option<OwnedRoomId>)>,
144+
/// Track whether app state has been saved during Pause to avoid redundant saves.
145+
#[rust] state_saved_on_pause: bool,
144146
}
145147

146148
impl LiveRegister for App {
@@ -450,38 +452,111 @@ impl AppMain for App {
450452
// log!("App::handle_event(): Window geometry changed: {:?}", geom);
451453
// }
452454

453-
if let Event::Shutdown = event {
454-
let window_ref = self.ui.window(id!(main_window));
455-
if let Err(e) = persistence::save_window_state(window_ref, cx) {
456-
error!("Failed to save window state. Error: {e}");
457-
}
458-
if let Some(user_id) = current_user_id() {
459-
let app_state = self.app_state.clone();
460-
if let Err(e) = persistence::save_app_state(app_state, user_id) {
461-
error!("Failed to save app state. Error: {e}");
455+
match event {
456+
Event::Pause => {
457+
if let Some(user_id) = current_user_id() {
458+
if let Err(e) = persistence::save_app_state(self.app_state.clone(), user_id) {
459+
error!("Failed to save app state on Pause: {e}");
460+
} else {
461+
self.state_saved_on_pause = true;
462+
}
463+
}
464+
465+
if let Some(sync_service) = crate::sliding_sync::get_sync_service() {
466+
let _ = crate::sliding_sync::block_on_async_with_timeout(
467+
Some(std::time::Duration::from_secs(2)),
468+
async move { sync_service.stop().await },
469+
);
462470
}
463471
}
464-
#[cfg(feature = "tsp")] {
465-
// Save the TSP wallet state, if it exists, with a 3-second timeout.
466-
let tsp_state = std::mem::take(&mut *crate::tsp::tsp_state_ref().lock().unwrap());
467-
let res = crate::sliding_sync::block_on_async_with_timeout(
468-
Some(std::time::Duration::from_secs(3)),
469-
async move {
470-
match tsp_state.close_and_serialize().await {
471-
Ok(saved_state) => match persistence::save_tsp_state_async(saved_state).await {
472-
Ok(_) => { }
473-
Err(e) => error!("Failed to save TSP wallet state. Error: {e}"),
472+
473+
Event::Resume | Event::Foreground => {
474+
if self.state_saved_on_pause {
475+
if let Some(user_id) = current_user_id() {
476+
match crate::sliding_sync::block_on_async_with_timeout(
477+
Some(std::time::Duration::from_secs(2)),
478+
crate::persistence::load_app_state(&user_id),
479+
) {
480+
Ok(Ok(restored_state)) => {
481+
let logged_in = self.app_state.logged_in;
482+
self.app_state = restored_state;
483+
self.app_state.logged_in = logged_in;
484+
cx.action(crate::home::main_desktop_ui::MainDesktopUiAction::LoadDockFromAppState);
474485
}
475-
Err(e) => error!("Failed to close and serialize TSP wallet state. Error: {e}"),
486+
Ok(Err(e)) => error!("Failed to restore app state on Resume: {e}"),
487+
Err(_) => error!("Timeout while restoring app state on Resume"),
476488
}
477-
},
478-
);
479-
if let Err(_e) = res {
480-
error!("Failed to save TSP wallet state before app shutdown. Error: Timed Out.");
489+
self.state_saved_on_pause = false;
490+
}
491+
}
492+
493+
if let Some(sync_service) = crate::sliding_sync::get_sync_service() {
494+
let _ = crate::sliding_sync::block_on_async_with_timeout(
495+
Some(std::time::Duration::from_secs(2)),
496+
async move { sync_service.start().await },
497+
);
498+
}
499+
500+
self.ui.redraw(cx);
501+
}
502+
503+
Event::Background => {
504+
if !self.state_saved_on_pause {
505+
if let Some(user_id) = current_user_id() {
506+
if let Err(e) = persistence::save_app_state(self.app_state.clone(), user_id)
507+
{
508+
error!("Failed to save app state on Background: {e}");
509+
}
510+
}
511+
}
512+
}
513+
514+
Event::Shutdown => {
515+
let window_ref = self.ui.window(id!(main_window));
516+
if let Err(e) = persistence::save_window_state(window_ref, cx) {
517+
error!("Failed to save window state: {e}");
518+
}
519+
520+
if !self.state_saved_on_pause {
521+
if let Some(user_id) = current_user_id() {
522+
if let Err(e) = persistence::save_app_state(self.app_state.clone(), user_id)
523+
{
524+
error!("Failed to save app state: {e}");
525+
}
526+
}
527+
}
528+
529+
#[cfg(feature = "tsp")]
530+
{
531+
// Save the TSP wallet state, if it exists, with a 3-second timeout.
532+
let tsp_state =
533+
std::mem::take(&mut *crate::tsp::tsp_state_ref().lock().unwrap());
534+
let res = crate::sliding_sync::block_on_async_with_timeout(
535+
Some(std::time::Duration::from_secs(3)),
536+
async move {
537+
match tsp_state.close_and_serialize().await {
538+
Ok(saved_state) => {
539+
if let Err(e) =
540+
persistence::save_tsp_state_async(saved_state).await
541+
{
542+
error!("Failed to save TSP wallet state: {e}");
543+
}
544+
}
545+
Err(e) => {
546+
error!("Failed to close and serialize TSP wallet state: {e}")
547+
}
548+
}
549+
},
550+
);
551+
if let Err(_) = res {
552+
error!("Failed to save TSP wallet state before app shutdown: Timed Out");
553+
}
481554
}
482555
}
556+
557+
_ => {}
483558
}
484-
559+
485560
// Forward events to the MatchEvent trait implementation.
486561
self.match_event(cx, event);
487562
let scope = &mut Scope::with_data(&mut self.app_state);

0 commit comments

Comments
 (0)