全局依赖注入: - app.dart 注入 JournalRepository + ClassRepository + SettingsBloc - ApiClient token 自动注入(监听 AuthBloc 状态) BLoC 重构 (占位数据 → Repository): - CalendarBloc: 通过 JournalRepository 加载月度日记 - ClassBloc: 通过 ClassRepository + JournalRepository 加载班级数据 - 新增 ClassJoin 事件支持班级码加入 - HomeBloc: 加载最近日记 + 心情概览 + 连续天数 + 今日是否已写 设置系统: - SettingsBloc: ThemeMode 切换 (system/light/dark) - app.dart 通过 ListenableBuilder 响应主题变化 - HomeBloc 支持下拉刷新 首页增强: - 连续天数徽章 + 今日已写标记 + 最常用心情高亮 - RefreshIndicator 下拉刷新 - 日记列表卡片显示日期 验证: flutter analyze 0 error
93 lines
2.9 KiB
Dart
93 lines
2.9 KiB
Dart
// 暖记 App 根组件 — MaterialApp + BLoC Provider 注入
|
||
//
|
||
// 依赖注入结构:
|
||
// MultiRepositoryProvider
|
||
// ├─ ApiClient
|
||
// ├─ AuthRepository
|
||
// ├─ JournalRepository (RemoteJournalRepository)
|
||
// └─ ClassRepository
|
||
// └─ BlocProvider<AuthBloc>
|
||
// └─ MaterialApp.router
|
||
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||
import 'package:go_router/go_router.dart';
|
||
|
||
import 'core/theme/app_theme.dart';
|
||
import 'core/routing/app_router.dart';
|
||
import 'data/remote/api_client.dart';
|
||
import 'data/repositories/auth_repository.dart';
|
||
import 'data/repositories/journal_repository.dart';
|
||
import 'data/repositories/remote_journal_repository.dart';
|
||
import 'data/repositories/class_repository.dart';
|
||
import 'features/auth/bloc/auth_bloc.dart';
|
||
import 'features/profile/bloc/settings_bloc.dart';
|
||
|
||
/// 暖记 App — 根组件
|
||
class NuanjiApp extends StatelessWidget {
|
||
const NuanjiApp({super.key});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
// 创建全局依赖(App 生命周期内单例)
|
||
final apiClient = ApiClient();
|
||
final authRepository = AuthRepository(apiClient: apiClient);
|
||
final journalRepository = RemoteJournalRepository(api: apiClient);
|
||
final classRepository = ClassRepository(api: apiClient);
|
||
final settingsBloc = SettingsBloc();
|
||
final authBloc = AuthBloc(authRepository: authRepository);
|
||
|
||
// 启动时检查认证状态
|
||
authBloc.add(const AppStarted());
|
||
|
||
// 认证成功后注入 JWT token 到 ApiClient
|
||
authBloc.stream.listen((state) {
|
||
if (state is Authenticated) {
|
||
// TODO: 从 SecureStorage 读取 token 并设置
|
||
// apiClient.setToken(token);
|
||
} else {
|
||
apiClient.clearToken();
|
||
}
|
||
});
|
||
|
||
return MultiRepositoryProvider(
|
||
providers: [
|
||
RepositoryProvider<ApiClient>.value(value: apiClient),
|
||
RepositoryProvider<AuthRepository>.value(value: authRepository),
|
||
RepositoryProvider<JournalRepository>.value(value: journalRepository),
|
||
RepositoryProvider<ClassRepository>.value(value: classRepository),
|
||
],
|
||
child: BlocProvider<AuthBloc>.value(
|
||
value: authBloc,
|
||
child: ListenableBuilder(
|
||
listenable: settingsBloc,
|
||
builder: (context, _) => _AppView(
|
||
router: createAppRouter(authBloc),
|
||
themeMode: settingsBloc.state.themeMode,
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
/// App 视图 — MaterialApp.router 包装
|
||
class _AppView extends StatelessWidget {
|
||
final GoRouter router;
|
||
final ThemeMode themeMode;
|
||
|
||
const _AppView({required this.router, this.themeMode = ThemeMode.system});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return MaterialApp.router(
|
||
title: '暖记',
|
||
debugShowCheckedModeBanner: false,
|
||
theme: AppTheme.light(),
|
||
darkTheme: AppTheme.dark(),
|
||
themeMode: themeMode,
|
||
routerConfig: router,
|
||
);
|
||
}
|
||
}
|