@@ -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
146148impl 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