import 'package:cipher_guard_sdk/cipher_guard_sdk.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:im_app/core/foundation/device_info.dart'; import 'package:im_app/core/services/app_initializer.dart'; import 'package:im_app/core/services/encryption_manager.dart'; import 'package:im_app/app/di/network_provider.dart'; // ── 认证 ────────────────────────────────────────────────────────────────────── /// 登录状态管理 /// /// 同时继承 [ChangeNotifier],作为 go_router [GoRouter.refreshListenable] 使用, /// 登录 / 退出时 go_router 自动重新执行 redirect,无需手动触发。 /// /// ## 当前状态 /// /// Demo 实现,无持久化。storage_sdk 就绪后替换为: /// - `build`:从安全存储读取 token,有则视为已登录 /// - `login` / `logout`:同步更新安全存储 class AuthNotifier extends ChangeNotifier { bool _isLoggedIn = false; int? _currentUid; bool get isLoggedIn => _isLoggedIn; /// 登录用户的 UID,登录成功后由 LoginViewModel 写入 int? get currentUid => _currentUid; /// E2E EncryptionManager — 由外部注入(见 LoginViewModel) EncryptionManager? _encryptionManager; NetworksSdkApi? _api; void setEncryptionDeps(EncryptionManager encMgr, NetworksSdkApi api) { _encryptionManager = encMgr; _api = api; } void login({required int uid}) { _isLoggedIn = true; _currentUid = uid; notifyListeners(); // E2E setup: 对齐 iOS AppCoordinator.onLogin → EncryptionManager.setup() if (_encryptionManager != null && _api != null) { _encryptionManager!.setup(_api!); } } void logout() { _isLoggedIn = false; _currentUid = null; // E2E teardown: 清除所有加密密钥 _encryptionManager?.clearKeys(); notifyListeners(); } } /// 登录状态 Provider /// /// 自动注入 EncryptionManager + API client,login() 后自动触发 E2E setup。 final authNotifierProvider = Provider((ref) { final auth = AuthNotifier(); auth.setEncryptionDeps( ref.read(encryptionManagerProvider), ref.read(networkSdkApiProvider), ); return auth; }); // ── E2E 加密 ──────────────────────────────────────────────────────────────── /// CipherGuardSdkApi 单例 — 对齐老项目加密引擎 final cipherSdkProvider = Provider((ref) { return CipherGuardSdkApi(); }); /// EncryptionManager 单例 — per-chat key chain + API integration /// /// 登录后调用 `encMgr.setup(api)` 启动 E2E,退出时调用 `encMgr.clearKeys()`。 /// 对齐 iOS EncryptionManager + 老项目 EncryptionMgr。 final encryptionManagerProvider = Provider((ref) { return EncryptionManager(cipherSdk: ref.read(cipherSdkProvider)); }); // ── 主题 ────────────────────────────────────────────────────────────────────── /// 主题模式 Notifier — 控制应用全局亮 / 暗主题 /// /// 启动时从持久化存储读取上次保存的主题模式,无则默认跟随系统。 /// 切换时先更新内存状态,再写入持久化存储。 /// /// ## storage_sdk 接入步骤 /// /// 1. 在 `build()` 解开 TODO:读取存储值作为初始模式 /// 2. 在 `setMode()` 解开 TODO:每次切换后写入存储 /// 3. 若存储接口是异步的,将 `Notifier` 改为 /// `AsyncNotifier`,`build()` 改为 `Future` class ThemeModeNotifier extends Notifier { @override ThemeMode build() { // TODO: storage_sdk 就绪后从持久化读取初始值: // final saved = ref.read(themeStorageProvider).readThemeMode(); // return saved ?? ThemeMode.system; return ThemeMode.system; } void setMode(ThemeMode mode) { state = mode; // TODO: storage_sdk 就绪后写入持久化: // ref.read(themeStorageProvider).saveThemeMode(mode); } } /// 主题模式 Provider /// /// ## Setting 页切换(只需一行) /// /// ```dart /// ref.read(themeModeProvider.notifier).setMode(ThemeMode.system); /// ref.read(themeModeProvider.notifier).setMode(ThemeMode.light); /// ref.read(themeModeProvider.notifier).setMode(ThemeMode.dark); /// ``` /// /// ## 持久化(storage_sdk TODO) /// /// 读取和写入的 TODO 均在 [ThemeModeNotifier] 内,接入 storage_sdk 后解开即可。 final themeModeProvider = NotifierProvider( ThemeModeNotifier.new, ); // ── 启动初始化 ──────────────────────────────────────────────────────────────── /// AppInitializer Provider /// /// 集中声明所有启动初始化任务,app.dart 只需一行 `.run()`。 /// /// ## 任务分类规则 /// /// 问自己:「这个任务不完成,用户能正常看到首页吗?」 /// - **不能** → 放 critical(谨慎,每多一个都拖慢启动) /// - **能** → 放 deferred(绝大多数情况) /// /// ## 当前任务清单 /// /// | 阶段 | 任务 | 说明 | /// |---|---|---| /// | Critical | NetworkMonitor | 后续 HTTP、WebSocket 都依赖网络状态 | /// | Deferred | (待扩展) | 推送注册、登录态恢复、缓存预热等 | final appInitializerProvider = Provider((ref) { return AppInitializer( onLog: (message, {tag}) { // ignore: avoid_print print('[${tag ?? 'AppInit'}] $message'); }, critical: [ // 网络监听必须最先就绪(后续 HTTP、WebSocket 都依赖它) InitTask( name: 'NetworkMonitor', task: () => ref.read(networkMonitorProvider).initialize(), ), // 预取设备 ID / 设备名,platformHeaders 同步读取 InitTask( name: 'DeviceInfo', task: DeviceInfo.init, ), ], deferred: [ // TODO: 推送注册 // InitTask( // name: 'PushNotification', // task: () => ref.read(pushServiceProvider).register(), // ), // // TODO: 登录态恢复(从安全存储读取 token → 自动登录) // InitTask( // name: 'AuthRestore', // task: () => ref.read(authRestoreUseCaseProvider).execute(), // ), // // TODO: 缓存预热 // InitTask( // name: 'CacheWarmup', // task: () => ref.read(cacheServiceProvider).warmup(), // ), ], ); });