Files
BudgetApp/lib/logic/auth/auth_bloc.dart
T
Sanders 85daede4a9 Implements authentication flow with user registration
This commit implements a complete authentication flow, including user registration.

- Introduces an `AuthRegisterRequested` event to handle user registration.
- Persists the user ID in settings upon successful authentication.
- Modifies `AuthBloc` to load the user based on the stored ID, improving app launch persistence.
- Refactors `UserCubit` to only manage the user state and removes authentication logic.
- Removes `UserCubit` initialization from `main.dart` and triggers `AuthStarted` to initiate the authentication process.
2025-07-12 22:40:31 +03:00

96 lines
3.6 KiB
Dart

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:budget_app/models/user.dart';
import 'package:budget_app/logic/user/user_cubit.dart';
import 'package:budget_app/injection_container.dart' as di;
import 'package:budget_app/data/repositories/interfaces/iglobal_settings_repository.dart';
import 'package:budget_app/data/repositories/interfaces/iuser_repository.dart';
part 'auth_event.dart';
part 'auth_state.dart';
class AuthBloc extends Bloc<AuthEvent, AuthState> {
final UserCubit _userCubit;
final IGlobalSettingsRepository _settingsRepository;
final IUserRepository _userRepository;
AuthBloc({
required UserCubit userCubit,
required IGlobalSettingsRepository settingsRepository,
required IUserRepository userRepository,
}) : _userCubit = userCubit,
_settingsRepository = settingsRepository,
_userRepository = userRepository,
super(AuthInitial()) {
on<AuthStarted>(_onAuthStarted);
on<AuthLoggedIn>(_onAuthLoggedIn);
on<AuthLoggedOut>(_onAuthLoggedOut);
on<AuthRegisterRequested>(_onAuthRegisterRequested);
}
void _onAuthStarted(AuthStarted event, Emitter<AuthState> emit) async {
try {
final userId = await _settingsRepository.getCurrentUserId();
if (userId != null) {
final user = await _userRepository.getById(userId);
if (user != null) {
// Пользователь найден, инициализируем зависимости и аутентифицируем
await di.initUserSpecificDependencies(user.id);
_userCubit.setUser(user);
emit(AuthAuthenticated(user: user));
} else {
// ID есть, а пользователя нет (ошибка) -> сбрасываем
await _settingsRepository.setCurrentUserId(null);
emit(AuthUnauthenticated());
}
} else {
// ID не найден, пользователь не аутентифицирован
emit(AuthUnauthenticated());
}
} catch (e) {
emit(AuthError(e.toString()));
}
}
void _onAuthLoggedIn(AuthLoggedIn event, Emitter<AuthState> emit) async {
// Инициализируем зависимости для вошедшего пользователя.
await di.initUserSpecificDependencies(event.user.id);
_userCubit.setUser(event.user);
await _settingsRepository.setCurrentUserId(event.user.id);
emit(AuthAuthenticated(user: event.user));
}
void _onAuthLoggedOut(AuthLoggedOut event, Emitter<AuthState> emit) async {
// Сбрасываем пользовательские зависимости.
await di.resetUserSpecificDependencies();
await _settingsRepository.setCurrentUserId(null);
_userCubit.logout();
emit(AuthUnauthenticated());
}
Future<void> _onAuthRegisterRequested(
AuthRegisterRequested event, Emitter<AuthState> emit) async {
emit(AuthLoading());
try {
// 1. Создаем пользователя
final user = User(name: event.name, email: event.email);
await _userRepository.add(user);
// 2. Инициализируем его зависимости
await di.initUserSpecificDependencies(user.id);
// 3. Создаем начальные данные (теперь это сработает)
await _userCubit.createInitialData(user.id);
// 4. Сохраняем и устанавливаем пользователя
await _settingsRepository.setCurrentUserId(user.id);
_userCubit.setUser(user);
emit(AuthAuthenticated(user: user));
} catch (e) {
emit(AuthError(e.toString()));
}
}
}