From 336687eccf830f8071c7d3fa754f1f14330741e0 Mon Sep 17 00:00:00 2001 From: Arseni Date: Mon, 8 Dec 2025 19:50:02 +0300 Subject: [PATCH 1/3] Account state now survives reload before redirecting to login --- frontend/pshared/lib/provider/account.dart | 19 +++++++++++++++++ frontend/pweb/lib/pages/loaders/account.dart | 22 ++++++++++++++------ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/frontend/pshared/lib/provider/account.dart b/frontend/pshared/lib/provider/account.dart index 9413913..b6e458c 100644 --- a/frontend/pshared/lib/provider/account.dart +++ b/frontend/pshared/lib/provider/account.dart @@ -27,6 +27,7 @@ class AccountProvider extends ChangeNotifier { Resource get resource => _resource; late LocaleProvider _localeProvider; PendingLogin? _pendingLogin; + bool _restoreAttempted = false; Account? get account => _resource.data; PendingLogin? get pendingLogin => _pendingLogin; @@ -34,6 +35,7 @@ class AccountProvider extends ChangeNotifier { bool get isLoading => _resource.isLoading; Object? get error => _resource.error; bool get isReady => (!isLoading) && (account != null); + bool get restoreAttempted => _restoreAttempted; Account? currentUser() { final acc = account; @@ -67,6 +69,7 @@ class AccountProvider extends ChangeNotifier { required String password, required String locale, }) async { + _restoreAttempted = true; _setResource(_resource.copyWith(isLoading: true, error: null)); try { final outcome = await AccountService.login(LoginData.build( @@ -95,6 +98,7 @@ class AccountProvider extends ChangeNotifier { void completePendingLogin(Account account) { _pendingLogin = null; + _restoreAttempted = true; _setResource(Resource(data: account, isLoading: false, error: null)); _pickupLocale(account.locale); } @@ -102,6 +106,7 @@ class AccountProvider extends ChangeNotifier { Future isAuthorizationStored() async => AuthorizationService.isAuthorizationStored(); Future restore() async { + _restoreAttempted = true; _setResource(_resource.copyWith(isLoading: true, error: null)); try { final acc = await AccountService.restore(); @@ -140,6 +145,7 @@ class AccountProvider extends ChangeNotifier { } Future logout() async { + _restoreAttempted = true; _setResource(_resource.copyWith(isLoading: true, error: null)); try { await AccountService.logout(); @@ -220,4 +226,17 @@ class AccountProvider extends ChangeNotifier { rethrow; } } + + Future restoreIfPossible() async { + if (_restoreAttempted) return; + _restoreAttempted = true; + final hasAuth = await AuthorizationService.isAuthorizationStored(); + if (!hasAuth) { + _setResource(Resource(data: null, isLoading: false, error: null)); + return; + } + try { + await restore(); + } catch (_) {} + } } diff --git a/frontend/pweb/lib/pages/loaders/account.dart b/frontend/pweb/lib/pages/loaders/account.dart index d891e1c..ccd1bab 100644 --- a/frontend/pweb/lib/pages/loaders/account.dart +++ b/frontend/pweb/lib/pages/loaders/account.dart @@ -17,14 +17,24 @@ class AccountLoader extends StatelessWidget { @override Widget build(BuildContext context) => Consumer(builder: (context, provider, _) { + if (provider.account != null) return child; + + if (!provider.restoreAttempted) { + WidgetsBinding.instance.addPostFrameCallback((_) => provider.restoreIfPossible()); + return const Center(child: CircularProgressIndicator()); + } + if (provider.isLoading) return const Center(child: CircularProgressIndicator()); if (provider.error != null) { - postNotifyUserOfErrorX( - context: context, - errorSituation: AppLocalizations.of(context)!.errorLogin, - exception: provider.error!, - ); - navigateAndReplace(context, Pages.login); + WidgetsBinding.instance.addPostFrameCallback((_) { + postNotifyUserOfErrorX( + context: context, + errorSituation: AppLocalizations.of(context)!.errorLogin, + exception: provider.error!, + ); + navigateAndReplace(context, Pages.login); + }); + return const Center(child: CircularProgressIndicator()); } if (provider.account == null) { WidgetsBinding.instance.addPostFrameCallback((_) => navigateAndReplace(context, Pages.login)); -- 2.49.1 From b16c2950947198825944f70716f6fcbc42b9db58 Mon Sep 17 00:00:00 2001 From: Arseni Date: Tue, 9 Dec 2025 21:10:31 +0300 Subject: [PATCH 2/3] Account recovery is triggered once via a memoized Future, and errors are not swallowed inside the provider --- frontend/pshared/lib/provider/account.dart | 23 ++++++-------------- frontend/pweb/lib/pages/loaders/account.dart | 11 ++++++++++ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/frontend/pshared/lib/provider/account.dart b/frontend/pshared/lib/provider/account.dart index b6e458c..644907c 100644 --- a/frontend/pshared/lib/provider/account.dart +++ b/frontend/pshared/lib/provider/account.dart @@ -27,7 +27,7 @@ class AccountProvider extends ChangeNotifier { Resource get resource => _resource; late LocaleProvider _localeProvider; PendingLogin? _pendingLogin; - bool _restoreAttempted = false; + Future? _restoreFuture; Account? get account => _resource.data; PendingLogin? get pendingLogin => _pendingLogin; @@ -35,7 +35,7 @@ class AccountProvider extends ChangeNotifier { bool get isLoading => _resource.isLoading; Object? get error => _resource.error; bool get isReady => (!isLoading) && (account != null); - bool get restoreAttempted => _restoreAttempted; + Future? get restoreFuture => _restoreFuture; Account? currentUser() { final acc = account; @@ -69,7 +69,6 @@ class AccountProvider extends ChangeNotifier { required String password, required String locale, }) async { - _restoreAttempted = true; _setResource(_resource.copyWith(isLoading: true, error: null)); try { final outcome = await AccountService.login(LoginData.build( @@ -98,7 +97,6 @@ class AccountProvider extends ChangeNotifier { void completePendingLogin(Account account) { _pendingLogin = null; - _restoreAttempted = true; _setResource(Resource(data: account, isLoading: false, error: null)); _pickupLocale(account.locale); } @@ -106,7 +104,6 @@ class AccountProvider extends ChangeNotifier { Future isAuthorizationStored() async => AuthorizationService.isAuthorizationStored(); Future restore() async { - _restoreAttempted = true; _setResource(_resource.copyWith(isLoading: true, error: null)); try { final acc = await AccountService.restore(); @@ -145,7 +142,6 @@ class AccountProvider extends ChangeNotifier { } Future logout() async { - _restoreAttempted = true; _setResource(_resource.copyWith(isLoading: true, error: null)); try { await AccountService.logout(); @@ -227,16 +223,11 @@ class AccountProvider extends ChangeNotifier { } } - Future restoreIfPossible() async { - if (_restoreAttempted) return; - _restoreAttempted = true; - final hasAuth = await AuthorizationService.isAuthorizationStored(); - if (!hasAuth) { - _setResource(Resource(data: null, isLoading: false, error: null)); - return; - } - try { + Future restoreIfPossible() { + return _restoreFuture ??= () async { + final hasAuth = await AuthorizationService.isAuthorizationStored(); + if (!hasAuth) return; await restore(); - } catch (_) {} + }(); } } diff --git a/frontend/pweb/lib/pages/loaders/account.dart b/frontend/pweb/lib/pages/loaders/account.dart index ccd1bab..a2f1668 100644 --- a/frontend/pweb/lib/pages/loaders/account.dart +++ b/frontend/pweb/lib/pages/loaders/account.dart @@ -36,6 +36,17 @@ class AccountLoader extends StatelessWidget { }); return const Center(child: CircularProgressIndicator()); } + + if (provider.restoreFuture == null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + provider.restoreIfPossible().catchError((error, stack) { + debugPrint('Account restore failed: $error'); + }); + }); + return const Center(child: CircularProgressIndicator()); + } + + if (provider.isLoading) return const Center(child: CircularProgressIndicator()); if (provider.account == null) { WidgetsBinding.instance.addPostFrameCallback((_) => navigateAndReplace(context, Pages.login)); return const Center(child: CircularProgressIndicator()); -- 2.49.1 From dfbf36bf04fd4f454050d857a5cd609b15112f75 Mon Sep 17 00:00:00 2001 From: Arseni Date: Tue, 9 Dec 2025 21:16:29 +0300 Subject: [PATCH 3/3] Fixes for build --- .gitignore | 3 ++- frontend/pweb/lib/pages/loaders/account.dart | 10 ++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index e663d96..ae95915 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ devtools_options.yaml untranslated.txt generate_protos.sh update_dep.sh -.vscode/ \ No newline at end of file +.vscode/ +GeneratedPluginRegistrant.swift \ No newline at end of file diff --git a/frontend/pweb/lib/pages/loaders/account.dart b/frontend/pweb/lib/pages/loaders/account.dart index a2f1668..14200d9 100644 --- a/frontend/pweb/lib/pages/loaders/account.dart +++ b/frontend/pweb/lib/pages/loaders/account.dart @@ -17,14 +17,12 @@ class AccountLoader extends StatelessWidget { @override Widget build(BuildContext context) => Consumer(builder: (context, provider, _) { - if (provider.account != null) return child; - - if (!provider.restoreAttempted) { - WidgetsBinding.instance.addPostFrameCallback((_) => provider.restoreIfPossible()); - return const Center(child: CircularProgressIndicator()); + if (provider.account != null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + }); + return child; } - if (provider.isLoading) return const Center(child: CircularProgressIndicator()); if (provider.error != null) { WidgetsBinding.instance.addPostFrameCallback((_) { postNotifyUserOfErrorX( -- 2.49.1