115 lines
3.4 KiB
Dart
115 lines
3.4 KiB
Dart
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<void> main(List<String> 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<void> onWindowClose() async {
|
|
if (!PipManager.isActive) {
|
|
await saveWindowBounds();
|
|
}
|
|
exit(0);
|
|
}
|
|
}
|