fix: stabilize auth and home error flows
This commit is contained in:
@@ -55,6 +55,27 @@ class CurrentHomeNotifier extends Notifier<HomeConfig?> {
|
||||
await _initApi(home);
|
||||
}
|
||||
|
||||
/// Выбрать дом как активный и сразу проверить auth-state.
|
||||
/// Если `auth/me` падает, откатываемся к предыдущему дому и auth-state.
|
||||
Future<void> select(HomeConfig home) async {
|
||||
final previousHome = state;
|
||||
final previousAuthState = ref.read(authInfoProvider);
|
||||
|
||||
try {
|
||||
await switchTo(home);
|
||||
await ref.read(authInfoProvider.notifier).load(failOnError: true);
|
||||
} catch (error) {
|
||||
await _restoreSelection(previousHome);
|
||||
ref.read(authInfoProvider.notifier).restore(previousAuthState);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> clear() async {
|
||||
await ref.read(settingsServiceProvider).setCurrentHomeId(null);
|
||||
state = null;
|
||||
}
|
||||
|
||||
/// Инициализировать API-клиент текущим домом
|
||||
Future<void> _initApi(HomeConfig home) async {
|
||||
final apiKey = await ref
|
||||
@@ -62,6 +83,18 @@ class CurrentHomeNotifier extends Notifier<HomeConfig?> {
|
||||
.requireHomeApiKey(home.id);
|
||||
ref.read(apiProvider).init(home.url, apiKey);
|
||||
}
|
||||
|
||||
Future<void> _restoreSelection(HomeConfig? home) async {
|
||||
if (home == null) {
|
||||
await clear();
|
||||
return;
|
||||
}
|
||||
|
||||
final svc = ref.read(settingsServiceProvider);
|
||||
await svc.setCurrentHomeId(home.id);
|
||||
state = home;
|
||||
await _initApi(home);
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Список домов ────────────────────────────────────────────
|
||||
@@ -798,26 +831,35 @@ class ApiKeysNotifier extends Notifier<LoadState<List<ApiKeyInfo>>> {
|
||||
|
||||
// ─── Информация об авторизации ────────────────────────────────
|
||||
|
||||
final authInfoProvider = NotifierProvider<AuthInfoNotifier, AuthInfo?>(
|
||||
() => AuthInfoNotifier(),
|
||||
);
|
||||
final authInfoProvider =
|
||||
NotifierProvider<AuthInfoNotifier, LoadState<AuthInfo?>>(
|
||||
() => AuthInfoNotifier(),
|
||||
);
|
||||
|
||||
class AuthInfoNotifier extends Notifier<AuthInfo?> {
|
||||
class AuthInfoNotifier extends Notifier<LoadState<AuthInfo?>> {
|
||||
@override
|
||||
AuthInfo? build() => null;
|
||||
LoadState<AuthInfo?> build() => const LoadState.idle(null);
|
||||
|
||||
Future<void> load({bool failOnError = false}) async {
|
||||
Future<AuthInfo?> load({bool failOnError = false}) async {
|
||||
state = LoadState.loading(state.data);
|
||||
try {
|
||||
final api = ref.read(apiProvider);
|
||||
final res = await api.getAuthMe();
|
||||
state = AuthInfo.fromApi(res.data);
|
||||
final authInfo = AuthInfo.fromApi(res.data);
|
||||
state = LoadState.data(authInfo);
|
||||
return authInfo;
|
||||
} catch (e) {
|
||||
debugPrint("Ошибка загрузки auth/me: $e");
|
||||
state = LoadState.error(null, describeLoadError(e));
|
||||
if (failOnError) rethrow;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
bool get isAdmin => state?.isAdmin == true;
|
||||
void clear() => state = const LoadState.idle(null);
|
||||
|
||||
void restore(LoadState<AuthInfo?> restoredState) => state = restoredState;
|
||||
|
||||
bool get isAdmin => state.data?.isAdmin == true;
|
||||
}
|
||||
|
||||
// ─── Геофенс: управление фоновым таском ─────────────────────
|
||||
|
||||
Reference in New Issue
Block a user