import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'app.dart'; import 'core/config/app_config.dart'; import 'core/services/error_logger.dart'; import 'core/updater/update_service.dart'; import 'core/updater/models/update_config.dart'; import 'features/notifications/presentation/providers/notification_providers.dart'; void main() { runZonedGuarded( () async { WidgetsFlutterBinding.ensureInitialized(); // Catch all Flutter framework errors (rendering, gestures, etc.) FlutterError.onError = (details) { FlutterError.presentError(details); ErrorLogger.instance.log({ 'timestamp': DateTime.now().toIso8601String(), 'source': 'FlutterError', 'message': details.exceptionAsString(), 'library': details.library ?? 'unknown', }); }; // Catch errors in the platform dispatcher (e.g. platform channels) PlatformDispatcher.instance.onError = (error, stack) { if (kDebugMode) debugPrint('[PlatformError] $error'); ErrorLogger.instance.log({ 'timestamp': DateTime.now().toIso8601String(), 'source': 'PlatformDispatcher', 'message': error.toString(), }); return true; // handled — prevent crash }; await Hive.initFlutter(); await ErrorLogger.instance.init(); // Initialize local notifications final localNotifications = FlutterLocalNotificationsPlugin(); const androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const initSettings = InitializationSettings(android: androidInit); await localNotifications.initialize(initSettings); // Initialize app update service final config = AppConfig.production(); UpdateService().initialize( UpdateConfig.selfHosted( apiBaseUrl: config.apiBaseUrl, enabled: true, checkIntervalSeconds: 86400, // 24小时 ), ); runApp( ProviderScope( overrides: [ localNotificationsPluginProvider .overrideWithValue(localNotifications), ], child: const IT0App(), ), ); }, // Catch ALL remaining unhandled async errors (the final safety net) (error, stack) { if (kDebugMode) debugPrint('[ZoneError] $error\n$stack'); ErrorLogger.instance.log({ 'timestamp': DateTime.now().toIso8601String(), 'source': 'runZonedGuarded', 'message': error.toString(), }); }, ); }