import 'dart:developer' as developer; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:pshared/models/auth/state.dart'; import 'package:pshared/provider/account.dart'; import 'package:pweb/app/router/pages.dart'; import 'package:pweb/controllers/auth/account_loader.dart'; import 'package:pweb/utils/error/snackbar.dart'; import 'package:pweb/models/account/account_loader.dart'; import 'package:pweb/generated/i18n/app_localizations.dart'; class AccountLoader extends StatefulWidget { final Widget child; const AccountLoader({super.key, required this.child}); @override State createState() => _AccountLoaderState(); } class _AccountLoaderState extends State { late final AccountLoaderController _controller; @override void initState() { super.initState(); _controller = AccountLoaderController() ..addListener(_handleControllerAction); WidgetsBinding.instance.addPostFrameCallback((_) { if (!mounted) return; Provider.of(context, listen: false).restoreIfPossible(); }); } void _handleControllerAction() { final action = _controller.consumeAction(); if (action == null) return; void goToLogin() { if (!mounted) return; navigateAndReplace(context, Pages.login); } switch (action) { case AccountLoaderAction.showErrorAndGoToLogin: final error = _controller.error ?? Exception('Authorization failed'); assert(() { developer.log( 'AccountLoader action=showErrorAndGoToLogin', name: 'pweb.auth.redirect', error: error, ); developer.debugger( message: 'AccountLoader: redirecting to login due to auth error', ); return true; }()); WidgetsBinding.instance.addPostFrameCallback((_) { if (!mounted) return; postNotifyUserOfErrorX( context: context, errorSituation: AppLocalizations.of(context)!.errorLogin, exception: error, ); goToLogin(); }); break; case AccountLoaderAction.goToLogin: assert(() { developer.log( 'AccountLoader action=goToLogin', name: 'pweb.auth.redirect', ); developer.debugger( message: 'AccountLoader: redirecting to login due to empty auth state', ); return true; }()); WidgetsBinding.instance.addPostFrameCallback((_) => goToLogin()); break; } } @override void dispose() { _controller.removeListener(_handleControllerAction); _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Consumer( builder: (context, provider, _) { _controller.update(provider); if (provider.authState == AuthState.ready && provider.account != null) { return widget.child; } return const Center(child: CircularProgressIndicator()); }, ); } }