import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:media_kit/media_kit.dart'; import 'services/audio_service.dart'; import 'services/playback_service.dart'; import 'services/app_lifecycle_service.dart'; import 'services/webdav_service.dart'; import 'pages/home_page.dart'; import 'pages/player_page.dart'; import 'pages/playlist_page.dart'; import 'widgets/global_mini_player.dart'; final GlobalKey navigatorKey = GlobalKey(); // ═══════════════════════════════════════════════════ // main: 只做 runApp,不做任何初始化 // ═══════════════════════════════════════════════════ void main() { WidgetsFlutterBinding.ensureInitialized(); runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => AudioService()), ChangeNotifierProvider(create: (_) => AppLifecycleService()), ], child: const QTPlayerApp(), ), ); } // ═══════════════════════════════════════════════════ // RouteManager - 路由状态 // ═══════════════════════════════════════════════════ class RouteManager extends ChangeNotifier { static final RouteManager _instance = RouteManager._internal(); factory RouteManager() => _instance; RouteManager._internal(); String _currentRoute = '/'; String get currentRoute => _currentRoute; bool get showMiniPlayer => _currentRoute != '/player' && _currentRoute != '/playlist'; void updateRoute(String route) { if (_currentRoute != route) { _currentRoute = route; debugPrint('📌 路由更新: $route'); notifyListeners(); } } } // ═══════════════════════════════════════════════════ // MiniPlayerNavigatorObserver - 路由监听 // ═══════════════════════════════════════════════════ class MiniPlayerNavigatorObserver extends NavigatorObserver { void _updateRoute(Route? route) { final name = route?.settings.name ?? '/'; RouteManager().updateRoute(name); } @override void didPush(Route route, Route? previousRoute) { _updateRoute(route); } @override void didPop(Route route, Route? previousRoute) { _updateRoute(previousRoute); } @override void didReplace({Route? newRoute, Route? oldRoute}) { _updateRoute(newRoute); } } // ═══════════════════════════════════════════════════ // QTPlayerApp - 主应用 // ═══════════════════════════════════════════════════ class QTPlayerApp extends StatefulWidget { const QTPlayerApp({super.key}); @override State createState() => _QTPlayerAppState(); } class _QTPlayerAppState extends State { @override void initState() { super.initState(); // 首帧完成后才开始初始化 WidgetsBinding.instance.addPostFrameCallback((_) { debugPrint('🖼️ Flutter 首帧已完成'); _initializeServices(); }); } @override Widget build(BuildContext context) { debugPrint('🎨 QTPlayerApp.build()'); return MaterialApp( title: '清听', theme: ThemeData( brightness: Brightness.dark, primaryColor: const Color(0xFF7C9A9E), colorScheme: const ColorScheme.dark( primary: Color(0xFF7C9A9E), secondary: Color(0xFFB8D4D0), surface: Color(0xFF1A1F1E), onSurface: Colors.white, ), useMaterial3: true, ), navigatorKey: navigatorKey, navigatorObservers: [MiniPlayerNavigatorObserver()], routes: { '/': (context) => const HomePage(), '/player': (context) => const PlayerPage(), '/playlist': (context) => const PlaylistPage(), }, builder: (context, child) { return Stack( fit: StackFit.expand, children: [ if (child != null) child, AnimatedBuilder( animation: RouteManager(), builder: (context, _) { if (!RouteManager().showMiniPlayer) { return const SizedBox.shrink(); } return const Align( alignment: Alignment.bottomCenter, child: GlobalMiniPlayer(), ); }, ), ], ); }, ); } } // ═══════════════════════════════════════════════════ // 后台初始化 - 在首帧完成后执行 // ═══════════════════════════════════════════════════ void _initializeServices() async { final lifecycle = AppLifecycleService(); try { lifecycle.updateStatus(AppStatus.mediaKitInitializing); MediaKit.ensureInitialized(); lifecycle.updateStatus(AppStatus.mediaKitReady); lifecycle.updateStatus(AppStatus.playerInitializing); PlaybackService().init(); lifecycle.updateStatus(AppStatus.playerReady); lifecycle.updateStatus(AppStatus.webdavChecking); final hasCred = await WebDAVService.instance.loadCredentials(); if (hasCred) { lifecycle.updateStatus(AppStatus.webdavReady); } else { lifecycle.updateStatus(AppStatus.webdavMissing); } lifecycle.updateStatus(AppStatus.fullReady); debugPrint('✅ 应用完全就绪'); } catch (e) { debugPrint('❌ 初始化错误: $e'); lifecycle.updateStatus(AppStatus.error); } }