Initial commit
This commit is contained in:
+127
@@ -0,0 +1,127 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart'
|
||||
show defaultTargetPlatform, TargetPlatform;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:forui/forui.dart';
|
||||
|
||||
import 'features/update/update_dialog.dart';
|
||||
import 'providers/appearance_provider.dart';
|
||||
import 'providers/di_providers.dart';
|
||||
import 'providers/server_sync_provider.dart';
|
||||
import 'providers/sm_account_provider.dart';
|
||||
import 'providers/update_provider.dart';
|
||||
import 'router/app_router.dart' show appRouterProvider, rootNavigatorKey;
|
||||
import 'shared/theme/app_scroll_behavior.dart';
|
||||
import 'shared/theme/app_theme.dart';
|
||||
import 'shared/utils/app_logger.dart';
|
||||
|
||||
class SmPlayerApp extends ConsumerStatefulWidget {
|
||||
const SmPlayerApp({super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<SmPlayerApp> createState() => _SmPlayerAppState();
|
||||
}
|
||||
|
||||
class _SmPlayerAppState extends ConsumerState<SmPlayerApp> {
|
||||
bool _updateDialogShown = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
try {
|
||||
final queue = await ref.read(traktSyncQueueProvider.future);
|
||||
await queue.drain();
|
||||
} catch (e) {
|
||||
AppLogger.debug('Trakt', 'startup drain skipped', e);
|
||||
}
|
||||
unawaited(ref.read(updateProvider.notifier).silentCheck());
|
||||
unawaited(_autoSyncPull());
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _autoSyncPull() async {
|
||||
try {
|
||||
final account = await ref.read(smAccountProvider.future);
|
||||
if (!account.hasVip) return;
|
||||
final outcome = await ref.read(serverSyncProvider.notifier).pull();
|
||||
if (outcome.isError) {
|
||||
AppLogger.debug('CloudSync', 'auto-pull failed: ${outcome.message}');
|
||||
}
|
||||
} catch (e) {
|
||||
AppLogger.debug('CloudSync', 'auto-pull skipped', e);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final router = ref.watch(appRouterProvider);
|
||||
final appearance = ref.watch(appearanceProvider);
|
||||
final flutterMode = appearance.maybeWhen(
|
||||
data: (d) => d.themeMode,
|
||||
orElse: () => ThemeMode.system,
|
||||
);
|
||||
|
||||
return MaterialApp.router(
|
||||
title: 'smPlayer',
|
||||
debugShowCheckedModeBanner: false,
|
||||
locale: const Locale('zh', 'CN'),
|
||||
supportedLocales: const [Locale('zh', 'CN'), Locale('en')],
|
||||
localizationsDelegates: const [
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
],
|
||||
theme: AppTheme.light(),
|
||||
darkTheme: AppTheme.dark(),
|
||||
themeMode: flutterMode,
|
||||
scrollBehavior: const AppScrollBehavior(),
|
||||
routerConfig: router,
|
||||
builder: (context, child) {
|
||||
final zinc = Theme.of(context).brightness == Brightness.dark
|
||||
? FThemes.zinc.dark
|
||||
: FThemes.zinc.light;
|
||||
return FTheme(
|
||||
data: _isTouchPlatform ? zinc.touch : zinc.desktop,
|
||||
child: FToaster(
|
||||
child: Consumer(
|
||||
builder: (context, ref, _) {
|
||||
ref.listen<UpdateState>(updateProvider, (previous, next) {
|
||||
if (_updateDialogShown ||
|
||||
next.status != UpdateStatus.available ||
|
||||
!next.silent) {
|
||||
return;
|
||||
}
|
||||
_updateDialogShown = true;
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!mounted) return;
|
||||
final navContext = rootNavigatorKey.currentContext;
|
||||
if (navContext == null) return;
|
||||
showFDialog(
|
||||
context: navContext,
|
||||
builder: (_, _, _) => const UpdateDialog(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
return child ?? const SizedBox();
|
||||
},
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool get _isTouchPlatform => switch (defaultTargetPlatform) {
|
||||
TargetPlatform.android ||
|
||||
TargetPlatform.iOS ||
|
||||
TargetPlatform.fuchsia => true,
|
||||
_ => false,
|
||||
};
|
||||
Reference in New Issue
Block a user