fix: stabilize auth and home error flows

This commit is contained in:
Artem Kokos
2026-04-27 23:11:45 +07:00
parent c2d7ce5bdc
commit eed04e9122
5 changed files with 247 additions and 41 deletions

View File

@@ -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;
}
// ─── Геофенс: управление фоновым таском ─────────────────────