import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:mnemo_cards_web_v2/di/user_scope/user_scope.dart'; import 'package:yx_scope_flutter/yx_scope_flutter.dart'; import 'package:yx_state_flutter/yx_state_flutter.dart'; import 'di/app_scope/app_scope_container.dart'; import 'di/app_scope/app_scope_holder.dart'; import 'domain/state/theme_state_manager.dart'; import 'main.dart' show scaffoldMessengerKey; import 'presentation/theme/app_theme.dart'; import 'package:mnemo_cards_common/mnemo_cards_common.dart'; /// Main application widget /// /// Wraps the entire app in ScopeProviders for AppScope and UserScope class App extends StatelessWidget { const App({ required this.appScopeHolder, super.key, }); final AppScopeHolder appScopeHolder; @override Widget build(BuildContext context) { return ScopeProvider( holder: appScopeHolder, child: ScopeBuilder.withPlaceholder( builder: (context, appScope) { return _AppInitializer(appScope: appScope); }, placeholder: const _LoadingScreen(message: 'Initializing...'), ), ); } } /// Initializes the app and handles auto-login class _AppInitializer extends StatefulWidget { const _AppInitializer({required this.appScope}); final AppScopeContainer appScope; @override State<_AppInitializer> createState() => _AppInitializerState(); } class _AppInitializerState extends State<_AppInitializer> { bool _isInitialized = false; @override void initState() { super.initState(); _initialize(); } @override void didUpdateWidget(_AppInitializer oldWidget) { super.didUpdateWidget(oldWidget); // Rebuild when UserScope changes if (mounted) { setState(() {}); } } Future _initialize() async { try { log('Starting app initialization...', name: 'App'); // Try auto-login first with timeout log('Attempting auto-login...', name: 'App'); UserDto? user; try { user = await widget.appScope.authService.autoLogin().timeout( const Duration(seconds: 3), onTimeout: () { log('Auto-login timed out, continuing as guest', name: 'App'); return null; }, ); } catch (e) { log('Auto-login failed with error, continuing as guest', error: e, name: 'App'); user = null; } if (widget.appScope.userScopeHolder.scope == null) { log('Creating UserScope...', name: 'App'); await widget.appScope.userScopeHolder.create(); } if (user != null) { log('Auto-login successful, creating UserScope', name: 'App'); // Create UserScope only for authenticated users widget.appScope.userScopeHolder.scope!.userStateManager.setUser(user); log('UserScope created and user set', name: 'App'); } else { log('No saved session, starting as guest without UserScope', name: 'App'); } log('Setting _isInitialized = true', name: 'App'); setState(() { _isInitialized = true; }); log('App initialization completed', name: 'App'); } catch (e) { log('Error during initialization', error: e, name: 'App'); // Continue as guest even if auto-login fails log('Continuing as guest after error', name: 'App'); setState(() { _isInitialized = true; }); } } @override Widget build(BuildContext context) { log('_AppInitializer build called, _isInitialized: $_isInitialized', name: 'App'); if (!_isInitialized) { log('Showing loading screen', name: 'App'); return const _LoadingScreen(message: 'Loading...'); } log('Building main app', name: 'App'); return StateBuilder( stateReadable: widget.appScope.themeManager, builder: (context, themeState, _) { log('StateBuilder builder called with themeState: ${themeState.mode}', name: 'App'); return _buildAppWithUserScope(themeState); }, ); } Widget _buildAppWithUserScope(ThemeState themeState) { Widget app = MaterialApp.router( title: 'Mnemo Cards', routerConfig: widget.appScope.router, theme: AppTheme.light, darkTheme: AppTheme.dark, themeMode: themeState.mode, scaffoldMessengerKey: scaffoldMessengerKey, debugShowCheckedModeBanner: false, ); // Wrap with UserScope provider only if UserScope exists if (widget.appScope.userScopeHolder.scope != null) { return ScopeProvider( holder: widget.appScope.userScopeHolder, child: app, ); } // For guest users, return app without UserScope provider return app; } } /// Экран загрузки class _LoadingScreen extends StatelessWidget { const _LoadingScreen({required this.message}); final String message; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const CircularProgressIndicator(), const SizedBox(height: 24), Text( message, style: const TextStyle(fontSize: 18), ), ], ), ), ), ); } }