134 lines
5.3 KiB
Dart
134 lines
5.3 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:bloc/bloc.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:logger/logger.dart';
|
|
|
|
import '/data/repositories/interfaces/icategory_repository.dart';
|
|
import '/data/repositories/interfaces/iglobal_settings_repository.dart';
|
|
import '/data/repositories/interfaces/itag_repository.dart';
|
|
import '/data/repositories/interfaces/itransaction_repository.dart';
|
|
import '/data/repositories/interfaces/iuser_repository.dart';
|
|
import '/models/user.dart';
|
|
import '/utils/category_utils.dart';
|
|
import '/utils/tag_utils.dart';
|
|
import '/utils/transaction_utils.dart';
|
|
|
|
part 'user_state.dart';
|
|
|
|
/// Cubit для управления состоянием пользователя.
|
|
/// Больше не управляет процессом входа, а только хранит состояние пользователя.
|
|
class UserCubit extends Cubit<UserState> {
|
|
final IGlobalSettingsRepository _settingsRepository;
|
|
final IUserRepository _userRepository;
|
|
// Эти репозитории теперь могут быть null и устанавливаются после входа пользователя.
|
|
ICategoryRepository? _categoryRepository;
|
|
ITagRepository? _tagRepository;
|
|
ITransactionRepository? _transactionRepository;
|
|
final Logger _logger = Logger(
|
|
printer: PrettyPrinter(
|
|
methodCount: 2, // Number of method calls to be displayed
|
|
errorMethodCount: 8, // Number of method calls if stacktrace is provided
|
|
lineLength: 120, // Width of the output
|
|
colors: true, // Colorful log messages
|
|
printEmojis: true, // Print an emoji for each log message
|
|
// Should each log print contain a timestamp
|
|
dateTimeFormat: DateTimeFormat.onlyTimeAndSinceStart,
|
|
),
|
|
);
|
|
|
|
UserCubit({
|
|
required IGlobalSettingsRepository settingsRepository,
|
|
required IUserRepository userRepository,
|
|
// Репозитории сделаны опциональными в конструкторе.
|
|
ICategoryRepository? categoryRepository,
|
|
ITagRepository? tagRepository,
|
|
ITransactionRepository? transactionRepository,
|
|
}) : _settingsRepository = settingsRepository,
|
|
_userRepository = userRepository,
|
|
_categoryRepository = categoryRepository,
|
|
_tagRepository = tagRepository,
|
|
_transactionRepository = transactionRepository,
|
|
super(UserInitial());
|
|
|
|
// Сеттеры для внедрения зависимостей после аутентификации.
|
|
set categoryRepository(ICategoryRepository? repo) => _categoryRepository = repo;
|
|
set tagRepository(ITagRepository? repo) => _tagRepository = repo;
|
|
set transactionRepository(ITransactionRepository? repo) =>
|
|
_transactionRepository = repo;
|
|
|
|
Future<void> createInitialData(String userId) async {
|
|
// Проверяем, что репозитории были установлены, прежде чем их использовать.
|
|
if (_categoryRepository == null ||
|
|
_tagRepository == null ||
|
|
_transactionRepository == null) {
|
|
_logger.w('User-specific repositories are not initialized. Skipping initial data creation.');
|
|
return;
|
|
}
|
|
try {
|
|
// Разбиваем создание данных на этапы
|
|
emit(UserLoading(progress: 0.7, message: 'Создание категорий...'));
|
|
// Используем '!', так как мы уже проверили на null.
|
|
await _categoryRepository!.addAll(
|
|
CategoryUtils.getDefaultCategories(),
|
|
);
|
|
|
|
emit(UserLoading(progress: 0.8, message: 'Создание тегов...'));
|
|
await _tagRepository!.addAll(TagUtils.getDefaultTags());
|
|
|
|
emit(UserLoading(progress: 0.9, message: 'Создание транзакций...'));
|
|
await _transactionRepository!.addAll(
|
|
TransactionUtils.getSampleTransactions(),
|
|
);
|
|
} catch (e, stack) {
|
|
|
|
_logger.e(
|
|
'Error creating initial data for user: $userId',
|
|
error: e,
|
|
stackTrace: stack,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Устанавливает текущего пользователя (прямая установка без загрузки)
|
|
void setUser(User user) {
|
|
emit(UserLoaded(user));
|
|
}
|
|
|
|
/// Выход из системы
|
|
Future<void> logout() async {
|
|
emit(UserLoading());
|
|
try {
|
|
await _settingsRepository.setCurrentUserId(null);
|
|
emit(UserLoaded(null));
|
|
} catch (e, stack) {
|
|
_logger.e('Error during logout', error: e, stackTrace: stack);
|
|
emit(UserError('Ошибка выхода из системы: ${e.toString()}'));
|
|
}
|
|
}
|
|
|
|
/// Возвращает всех пользователей
|
|
Future<List<User>> getAllUsers() async {
|
|
try {
|
|
return await _userRepository.getAll();
|
|
} catch (e, stack) {
|
|
_logger.e('Error getting all users', error: e, stackTrace: stack);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/// Обновляет данные пользователя
|
|
Future<void> updateUser(User updatedUser) async {
|
|
try {
|
|
if (state is UserLoaded) {
|
|
await _userRepository.update(updatedUser);
|
|
emit(UserLoaded(updatedUser));
|
|
_logger.i('User data updated successfully');
|
|
}
|
|
} catch (e, stack) {
|
|
_logger.e('Error updating user', error: e, stackTrace: stack);
|
|
throw Exception('Ошибка обновления пользователя');
|
|
}
|
|
}
|
|
}
|