Files
sm-emby-share/lib/main.dart
T

115 lines
3.4 KiB
Dart
Raw Normal View History

2026-07-14 11:11:36 +08:00
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);
}
}