2026-01-21 13:27:55 +08:00
|
|
|
|
import 'dart:async';
|
2026-01-19 18:24:24 +08:00
|
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
2026-01-11 19:42:22 +08:00
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
|
|
|
|
import 'package:go_router/go_router.dart';
|
2026-01-18 20:21:14 +08:00
|
|
|
|
import 'package:maibu_satabot_v2/core/app/app_user_cubit.dart';
|
2026-01-21 13:27:55 +08:00
|
|
|
|
import 'package:maibu_satabot_v2/core/infrastructure/logging/app_bloc_observer.dart';
|
|
|
|
|
|
import 'package:maibu_satabot_v2/core/logging/i_logger_service.dart';
|
2026-01-18 20:21:14 +08:00
|
|
|
|
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
2026-01-11 19:42:22 +08:00
|
|
|
|
import 'package:maibu_satabot_v2/features/auth/presentation/bloc/auth_cubit.dart';
|
2026-01-18 20:21:14 +08:00
|
|
|
|
import 'package:maibu_satabot_v2/features/devices/presentation/bloc/devices_cubit.dart';
|
2026-01-11 19:42:22 +08:00
|
|
|
|
|
|
|
|
|
|
import 'core/di/injection.dart';
|
|
|
|
|
|
import 'features/auth/presentation/bloc/login_cubit.dart';
|
|
|
|
|
|
|
|
|
|
|
|
void main() async {
|
2026-01-21 13:27:55 +08:00
|
|
|
|
// 1. 使用 runZonedGuarded 捕获所有未处理的异步错误
|
|
|
|
|
|
runZonedGuarded(
|
|
|
|
|
|
() async {
|
|
|
|
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 初始化依赖注入 (这里面应包含 ILoggerService 的注册)
|
|
|
|
|
|
await init();
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 从 sl 中获取 logger 实例并初始化 Sentry
|
|
|
|
|
|
final logger = sl<ILoggerService>();
|
|
|
|
|
|
await logger.init();
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 设置全局 Bloc 观察者,自动上报 Bloc 错误
|
|
|
|
|
|
Bloc.observer = AppBlocObserver(logger);
|
|
|
|
|
|
|
|
|
|
|
|
runApp(const MyApp());
|
|
|
|
|
|
},
|
|
|
|
|
|
(error, stack) {
|
|
|
|
|
|
// 5. 捕获顶级错误并上报
|
|
|
|
|
|
sl<ILoggerService>().captureException(error, stackTrace: stack);
|
|
|
|
|
|
},
|
|
|
|
|
|
);
|
2026-01-11 19:42:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class MyApp extends StatelessWidget {
|
|
|
|
|
|
const MyApp({super.key});
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
Widget build(BuildContext context) {
|
2026-02-25 13:41:23 +08:00
|
|
|
|
// 在 runApp 之前调用 appStarted,确保 GoRouter 初始化时能获取到正确的初始状态
|
2026-01-11 19:42:22 +08:00
|
|
|
|
sl<AuthCubit>().appStarted();
|
2026-02-25 13:41:23 +08:00
|
|
|
|
|
2026-01-11 19:42:22 +08:00
|
|
|
|
return MultiBlocProvider(
|
|
|
|
|
|
providers: [
|
2026-02-25 13:41:23 +08:00
|
|
|
|
// 核心修正:在这里提供 AuthCubit
|
|
|
|
|
|
BlocProvider<AuthCubit>(create: (_) => sl<AuthCubit>()),
|
|
|
|
|
|
|
2026-01-18 20:21:14 +08:00
|
|
|
|
BlocProvider<AppUserCubit>(create: (_) => sl<AppUserCubit>()),
|
2026-01-11 19:42:22 +08:00
|
|
|
|
BlocProvider<LoginCubit>(create: (_) => sl<LoginCubit>()),
|
2026-01-18 20:21:14 +08:00
|
|
|
|
BlocProvider<DevicesCubit>(
|
2026-02-25 13:41:23 +08:00
|
|
|
|
create: (_) {
|
|
|
|
|
|
// 增加一个健壮性检查
|
|
|
|
|
|
final user = sl<AppUserCubit>().state.user;
|
|
|
|
|
|
final devicesCubit = sl<DevicesCubit>();
|
|
|
|
|
|
if (user != null) {
|
|
|
|
|
|
devicesCubit.fetchAllDevices(user.username);
|
|
|
|
|
|
}
|
|
|
|
|
|
return devicesCubit;
|
|
|
|
|
|
},
|
2026-01-18 20:21:14 +08:00
|
|
|
|
),
|
2026-01-11 19:42:22 +08:00
|
|
|
|
],
|
2026-01-18 20:21:14 +08:00
|
|
|
|
child: MaterialApp.router(
|
|
|
|
|
|
title: 'Maibu Satabot',
|
|
|
|
|
|
theme: AppTheme.lightTheme,
|
|
|
|
|
|
routerConfig: sl<GoRouter>(),
|
|
|
|
|
|
),
|
2026-01-11 19:42:22 +08:00
|
|
|
|
);
|
|
|
|
|
|
}
|
2026-01-21 13:27:55 +08:00
|
|
|
|
}
|