import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:media_kit/media_kit.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:window_manager/window_manager.dart'; import 'app.dart'; import 'core/infra/deep_link/deep_link_service.dart'; import 'features/player/services/pip_manager.dart'; import 'providers/appearance_provider.dart'; import 'shared/utils/window_bounds.dart'; const _kMinW = 960.0; const _kMinH = 640.0; Future main(List args) async { WidgetsFlutterBinding.ensureInitialized(); MediaKit.ensureInitialized(); _installErrorNoiseFilters(); if (Platform.isAndroid) { SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); SystemChrome.setSystemUIOverlayStyle( const SystemUiOverlayStyle( statusBarColor: Colors.transparent, systemNavigationBarColor: Colors.transparent, systemNavigationBarDividerColor: Colors.transparent, ), ); } if (Platform.isWindows || Platform.isMacOS) { await windowManager.ensureInitialized(); final prefs = await SharedPreferences.getInstance(); final savedW = prefs.getDouble(kWinWidthKey); final savedH = prefs.getDouble(kWinHeightKey); final savedX = prefs.getDouble(kWinXKey); final savedY = prefs.getDouble(kWinYKey); final hasSize = savedW != null && savedH != null; final size = hasSize ? Size( savedW.clamp(_kMinW, double.infinity), savedH.clamp(_kMinH, double.infinity), ) : const Size(1280, 720); final opts = WindowOptions( size: size, minimumSize: const Size(_kMinW, _kMinH), center: !hasSize, title: 'smPlayer', titleBarStyle: TitleBarStyle.hidden, ); await windowManager.waitUntilReadyToShow(opts, () async { if (hasSize && savedX != null && savedY != null) { await windowManager.setPosition(Offset(savedX, savedY)); } if (Platform.isMacOS || Platform.isWindows) { await windowManager.setTitleBarStyle( TitleBarStyle.hidden, windowButtonVisibility: false, ); } await windowManager.show(); await windowManager.focus(); }); windowManager.addListener(_MainWindowListener()); } await DeepLinkService.instance.init(); var initialLocation = startupPagePath(StartupPage.home); try { final prefs = await SharedPreferences.getInstance(); initialLocation = startupPagePath( parseStartupPage(prefs.getString(kStartupPageKey)), ); } catch (_) {} runApp( ProviderScope( retry: (_, _) => null, overrides: [initialLocationProvider.overrideWithValue(initialLocation)], child: const SmPlayerApp(), ), ); } void _installErrorNoiseFilters() { final original = FlutterError.onError; FlutterError.onError = (details) { final msg = details.exceptionAsString(); if (msg.contains('KeyDownEvent is dispatched, but the state shows')) { return; } if (details.exception is HttpException && (details.library ?? '').contains('image resource')) { return; } original?.call(details); }; } class _MainWindowListener extends WindowListener { @override Future onWindowClose() async { if (!PipManager.isActive) { await saveWindowBounds(); } exit(0); } }