Files
jinzhi/lib/app/app.dart
T
2026-08-24 19:07:31 +08:00

95 lines
3.3 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import '../common/router/app_router.dart';
import '../common/lifecycle/refresh_coordinator.dart';
import '../common/push/device_push_registrar.dart';
import '../common/push/umeng_push_service.dart';
import '../common/theme/jinzhi_theme.dart';
import '../common/theme/spacing.dart';
import '../common/theme/theme_controller.dart';
import '../features/ads/application/ad_config_foreground_refresher.dart';
import '../features/settings/application/update_foreground_service.dart';
import '../common/router/deep_link_service.dart';
import '../common/services/device_header_service.dart';
class JinzhiApp extends ConsumerStatefulWidget {
const JinzhiApp({super.key});
@override
ConsumerState<JinzhiApp> createState() => _JinzhiAppState();
}
class _JinzhiAppState extends ConsumerState<JinzhiApp>
with WidgetsBindingObserver {
late final DevicePushRegistrar _pushRegistrar;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_pushRegistrar = DevicePushRegistrar(ref.read)..start();
UmengPushService.configureNotificationOpen(DeepLinkService.handle);
WidgetsBinding.instance.addPostFrameCallback((_) {
// 首次 iOS 启动在欢迎页点击进入后才注册 APNs,确保系统弹窗不被启动页
// 或其他 Overlay 吞掉;后续启动和 Android 保持原有自动初始化。
if (!DeviceHeaderService.to.iosStartupRequired) {
unawaited(UmengPushService.startIfAllowed());
}
});
}
@override
void dispose() {
unawaited(_pushRegistrar.stop());
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
unawaited(_pushRegistrar.refresh());
unawaited(ref.read(adConfigForegroundRefresherProvider).refresh());
final context = rootNavigatorKey.currentContext;
if (context != null) {
unawaited(UpdateForegroundService.check(context, ref));
}
}
}
@override
Widget build(BuildContext context) {
// Keep the app-wide foreground refresh coordinator alive. Features opt in
// by registering only while their screen is visible.
ref.watch(refreshCoordinatorProvider);
final router = ref.watch(routerProvider);
final mode = ref.watch(themeModeControllerProvider);
// DM Sans 作主字体(拉丁/数字),中文走系统级联(iOS 苹方 / Android 厂商
// 中文字体)——主流做法,不显式点名、不内置字体。
final dmSansFamily = GoogleFonts.dmSans().fontFamily;
final textTheme = ShadTextTheme(family: dmSansFamily);
return ShadApp.router(
title: '金值',
themeMode: mode,
theme: ShadThemeData(
brightness: Brightness.light,
colorScheme: jinzhiLightScheme,
textTheme: textTheme,
radius: BorderRadius.circular(Spacing.radiusBase),
),
darkTheme: ShadThemeData(
brightness: Brightness.dark,
colorScheme: jinzhiDarkScheme,
textTheme: textTheme,
radius: BorderRadius.circular(Spacing.radiusBase),
),
routerConfig: router,
);
}
}