Template
Core 基础设施:Flavor 三包体系、Drift+SQLCipher 加密数据库 7 拦截器 Dio 网络栈、CrashReporter 崩溃日志、Sealed Failure 错误体系 5 色板主题系统、Auth 认证骨架(Clean Architecture)、Dev Panel、Mock Adapter 通过验证:flutter analyze(0 errors)、flutter test(全绿)、staging APK 74.8MB
61 lines
1.8 KiB
Dart
61 lines
1.8 KiB
Dart
import 'dart:async';
|
||
|
||
import 'package:flutter/foundation.dart' show ValueNotifier;
|
||
import 'package:sunny_mochi/core/observability/talker_setup.dart';
|
||
import 'package:sunny_mochi/core/storage/secure_storage.dart'
|
||
show secureStorageProvider;
|
||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||
|
||
part 'auth_status_provider.g.dart';
|
||
|
||
/// 同步可读的登录态门面 — 给 GoRouter `redirect` 用。
|
||
///
|
||
/// 三态语义:
|
||
/// - `null` → 启动期未知(异步 storage 还没读完,redirect 应不动)
|
||
/// - `true` → 已登录
|
||
/// - `false` → 未登录(redirect 把非 /login 的访问跳 /login)
|
||
class AuthStatusController {
|
||
AuthStatusController() : _notifier = ValueNotifier<bool?>(null);
|
||
|
||
final ValueNotifier<bool?> _notifier;
|
||
|
||
ValueNotifier<bool?> get listenable => _notifier;
|
||
|
||
bool? get value => _notifier.value;
|
||
|
||
void markLoggedIn() {
|
||
appTalker.info('[AuthStatus] markLoggedIn');
|
||
_notifier.value = true;
|
||
}
|
||
|
||
void markLoggedOut() {
|
||
appTalker.info('[AuthStatus] markLoggedOut');
|
||
_notifier.value = false;
|
||
}
|
||
|
||
void dispose() => _notifier.dispose();
|
||
}
|
||
|
||
@Riverpod(keepAlive: true)
|
||
AuthStatusController authStatus(Ref ref) {
|
||
final controller = AuthStatusController();
|
||
unawaited(_bootstrap(ref, controller));
|
||
ref.onDispose(controller.dispose);
|
||
return controller;
|
||
}
|
||
|
||
Future<void> _bootstrap(Ref ref, AuthStatusController controller) async {
|
||
try {
|
||
final token = await ref.read(secureStorageProvider).getToken();
|
||
final loggedIn = token != null && token.isNotEmpty;
|
||
if (loggedIn) {
|
||
controller.markLoggedIn();
|
||
} else {
|
||
controller.markLoggedOut();
|
||
}
|
||
} on Object catch (e, st) {
|
||
appTalker.warning('[AuthStatus] bootstrap 异常 → 视为未登录', e, st);
|
||
controller.markLoggedOut();
|
||
}
|
||
}
|