import 'package:flutter/material.dart'; import 'package:live_recorder_mobile/app/app_bootstrap_controller.dart'; import 'package:live_recorder_mobile/app/app_dependencies.dart'; import 'package:live_recorder_mobile/app/app_scope.dart'; import 'package:live_recorder_mobile/app/app_theme.dart'; import 'package:live_recorder_mobile/core/config/api_config.dart'; import 'package:live_recorder_mobile/core/persistence/app_config_storage.dart'; import 'package:live_recorder_mobile/core/widgets/app_error_card.dart'; import 'package:live_recorder_mobile/features/live_recorder/presentation/pages/backend_setup_page.dart'; import 'package:live_recorder_mobile/features/live_recorder/presentation/pages/login_page.dart'; import 'package:live_recorder_mobile/features/live_recorder/presentation/pages/mobile_shell_page.dart'; class LiveRecorderBootstrap extends StatefulWidget { const LiveRecorderBootstrap({ super.key, required this.config, }); final ApiConfig config; @override State createState() => _LiveRecorderBootstrapState(); } class _LiveRecorderBootstrapState extends State { late final AppBootstrapController _bootstrapController = AppBootstrapController( config: widget.config, configStorage: AppConfigStorage(), dependenciesFactory: (String baseUrl) => AppDependencies.create(baseUrl: baseUrl), ); @override void initState() { super.initState(); _bootstrapController.initialize(); } @override void dispose() { _bootstrapController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _bootstrapController, builder: (BuildContext context, _) { return AppScope( backendConfig: _bootstrapController, dependencies: _bootstrapController.dependencies, child: MaterialApp( debugShowCheckedModeBanner: false, title: 'LiveRecorder', theme: buildLiveRecorderTheme(), home: _BootstrapHome( bootstrapController: _bootstrapController, ), ), ); }, ); } } class _BootstrapHome extends StatelessWidget { const _BootstrapHome({ required this.bootstrapController, }); final AppBootstrapController bootstrapController; @override Widget build(BuildContext context) { if (bootstrapController.isInitializing) { return const _LoadingSplashPage(); } if (bootstrapController.initializationErrorMessage != null) { return _BootstrapErrorPage( message: bootstrapController.initializationErrorMessage!, onRetry: bootstrapController.initialize, ); } if (!bootstrapController.hasConfiguredBackend) { return BackendSetupPage( bootstrapController: bootstrapController, ); } final dependencies = bootstrapController.dependencies; if (dependencies == null) { return _BootstrapErrorPage( message: '后端配置未能正确加载,请重试', onRetry: bootstrapController.initialize, ); } return ListenableBuilder( listenable: dependencies.sessionController, builder: (BuildContext context, _) { if (dependencies.sessionController.isRestoring) { return const _LoadingSplashPage(); } if (dependencies.sessionController.isLoggedIn) { return MobileShellPage( dependencies: dependencies, ); } return LoginPage( sessionController: dependencies.sessionController, ); }, ); } } class _LoadingSplashPage extends StatelessWidget { const _LoadingSplashPage(); @override Widget build(BuildContext context) { return const Scaffold( body: Center( child: CircularProgressIndicator(), ), ); } } class _BootstrapErrorPage extends StatelessWidget { const _BootstrapErrorPage({ required this.message, required this.onRetry, }); final String message; final VoidCallback onRetry; @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Padding( padding: const EdgeInsets.all(24), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 420), child: AppErrorCard( message: message, onRetry: onRetry, ), ), ), ), ); } }