Files
AutoJudge-Flutter/lib/main.dart
2025-11-13 09:14:49 +08:00

138 lines
4.0 KiB
Dart

import 'dart:io' show Platform;
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'providers/auth_provider.dart';
import 'providers/evaluation_provider.dart';
import 'providers/theme_provider.dart';
import 'services/notification_service.dart';
import 'screens/login_screen.dart';
import 'screens/home_screen.dart';
import 'widgets/loading_indicator.dart';
import 'utils/error_handler.dart';
import 'utils/app_logger.dart';
void main() async {
// Run app with global error handling
await ErrorHandler.runAppWithErrorHandling(() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize logger
final logger = AppLogger();
logger.initialize();
logger.info('Application starting...');
// Initialize notification service
final notificationService = NotificationService();
await notificationService.initialize();
runApp(MyApp(notificationService: notificationService));
});
}
class MyApp extends StatelessWidget {
final NotificationService notificationService;
const MyApp({super.key, required this.notificationService});
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ThemeProvider()),
ChangeNotifierProvider(create: (_) => AuthProvider()),
ChangeNotifierProxyProvider<AuthProvider, EvaluationProvider>(
create: (context) {
// Create initial provider without connection
// Connection will be set later when user logs in
return EvaluationProvider(
service: null,
notificationService: notificationService,
);
},
update: (context, authProvider, previous) {
// Keep the same provider instance and just update connection
if (previous != null) {
previous.setConnection(authProvider.connection);
return previous;
}
return EvaluationProvider(
service: null,
notificationService: notificationService,
);
},
),
],
child: Consumer<ThemeProvider>(
builder: (context, themeProvider, child) {
// Use MiSans font on Windows platform
final fontFamily = Platform.isWindows ? 'MiSans' : null;
return MaterialApp(
title: '自动评教系统',
debugShowCheckedModeBanner: false,
theme: themeProvider.lightTheme.copyWith(
textTheme: themeProvider.lightTheme.textTheme.apply(
fontFamily: fontFamily,
),
),
darkTheme: themeProvider.darkTheme.copyWith(
textTheme: themeProvider.darkTheme.textTheme.apply(
fontFamily: fontFamily,
),
),
themeMode: themeProvider.themeMode,
home: const AppInitializer(),
);
},
),
);
}
}
/// App initializer widget
///
/// Handles initial app setup and session restoration
class AppInitializer extends StatefulWidget {
const AppInitializer({super.key});
@override
State<AppInitializer> createState() => _AppInitializerState();
}
class _AppInitializerState extends State<AppInitializer> {
bool _isInitializing = true;
bool _hasSession = false;
@override
void initState() {
super.initState();
// Defer initialization until after the first frame
WidgetsBinding.instance.addPostFrameCallback((_) {
_initialize();
});
}
Future<void> _initialize() async {
final authProvider = Provider.of<AuthProvider>(context, listen: false);
// Try to restore session
final restored = await authProvider.restoreSession();
if (mounted) {
setState(() {
_isInitializing = false;
_hasSession = restored;
});
}
}
@override
Widget build(BuildContext context) {
if (_isInitializing) {
return const Scaffold(body: LoadingIndicator(message: '正在初始化...'));
}
return _hasSession ? const HomeScreen() : const LoginScreen();
}
}