Files
BudgetApp/lib/logic/sms/sms_cubit.dart
T
Sanders 8b75299d41 Refactors data repositories for single-user mode
This commit refactors the data repositories to remove user-specific filtering. It simplifies the data access logic by retrieving all data from the Hive boxes and removing the need to filter by `userId` in the repository methods.

This change makes the app function in single-user mode and removes the need to manage multiple user contexts within the data layer.

Specifically:
- Removes `userId` parameter from repository methods.
- Updates the setting repository to use fixed keys.
- Removes user ID filtering from queries.
- Removes user ID parameters from Cubits and Blocs
- Updates initial data creation
2025-07-12 21:54:00 +03:00

123 lines
5.8 KiB
Dart

import 'package:budget_app/logic/sms/sms_state.dart';
import 'package:budget_app/models/sms_message.dart';
import 'package:budget_app/models/transaction_record.dart';
import 'package:budget_app/services/sms_service.dart';
import 'package:budget_app/logic/user/user_cubit.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:budget_app/data/repositories/interfaces/isms_message_repository.dart';
/// Cubit для управления состоянием SMS.
///
/// Отвечает за загрузку SMS сообщений и обработку разрешений.
class SmsCubit extends Cubit<SmsState> {
final SmsService _smsService;
final ISmsMessageRepository _smsRepository;
final UserCubit _userCubit;
SmsCubit(
this._smsService,
this._smsRepository,
this._userCubit
) : super(SmsInitial());
/// Загружает последние 10 SMS сообщений.
///
/// Перед загрузкой запрашивает необходимые разрешения.
/// В случае успеха, переходит в состояние [SmsLoaded].
/// В случае отказа в разрешениях, переходит в состояние [SmsPermissionDenied].
/// В случае ошибки, переходит в состояние [SmsError].
Future<void> loadLastMessages() async {
emit(SmsLoading());
try {
final hasPermissions = await _smsService.requestPermissions();
if (hasPermissions) {
final messages = await _smsService.getLastSmsMessages(10);
emit(SmsLoaded(messages));
} else {
emit(SmsPermissionDenied());
}
} catch (e) {
emit(SmsError(e.toString()));
}
}
// Комментарий: Метод для загрузки и сохранения SMS-сообщений.
Future<void> loadSmsMessages() async {
// Комментарий: Устанавливаем состояние загрузки, чтобы UI мог отобразить индикатор.
emit(SmsLoading());
try {
// Комментарий: Запрашиваем разрешение на чтение SMS.
final hasPermissions = await _smsService.requestPermissions();
if (hasPermissions) {
// Комментарий: Получаем текущего пользователя из состояния UserCubit.
final userState = _userCubit.state;
if (userState is UserLoaded) {
final user = userState.user;
// Комментарий: Получаем все SMS-сообщения с момента последней синхронизации.
final messages = await _smsService.getSmsMessagesSince(user!.lastSmsSyncTime);
// Комментарий: Сохраняем новые сообщения через репозиторий и создаем транзакции.
await _smsRepository.addAll(messages);
for (final message in messages) {
// Комментарий: Пытаемся создать транзакцию из SMS.
_createTransactionFromSms(message);
}
// Комментарий: Устанавливаем состояние успешной загрузки.
emit(SmsLoaded(messages));
} else {
emit(SmsError("User not loaded"));
}
} else {
// Комментарий: Если разрешение не получено, устанавливаем состояние "в доступе отказано".
emit(SmsPermissionDenied());
}
} catch (e) {
// Комментарий: В случае ошибки устанавливаем состояние ошибки и передаем сообщение.
emit(SmsError(e.toString()));
}
}
// Комментарий: Метод для создания транзакции из SMS-сообщения.
Future<void> _createTransactionFromSms(SmsMessage sms) async {
// Комментарий: Здесь будет логика для парсинга SMS и создания транзакции.
// Пример простой логики парсинга (нужно будет доработать под реальные SMS).
final body = sms.body?.toLowerCase() ?? '';
double? amount;
TransactionRecord? type;
// Комментарий: Поиск суммы в сообщении.
final amountRegex = RegExp(r'(\d+(\.\d{1,2})?)');
final match = amountRegex.firstMatch(body);
if (match != null) {
amount = double.tryParse(match.group(1)!);
}
// TODO
// Комментарий: Определение типа транзакции (доход/расход).
// if (body.contains('покупка') || body.contains('списание')) {
// type = Transaction.expense;
// } else if (body.contains('зачисление') || body.contains('пополнение')) {
// type = TransactionType.income;
// }
// if (amount != null && type != null) {
// // Комментарий: Создаем новую транзакцию.
// final transaction = TransactionRecord(
// amount: amount,
// type: type,
// date: sms.date ?? DateTime.now(),
// description: sms.body, // Описание берем из тела SMS
// // Комментарий: Здесь можно добавить логику для определения категории и тегов.
// );
// // Комментарий: Добавляем событие AddTransaction в TransactionBloc.
// _transactionBloc.add(AddTransaction(transaction));
// // Комментарий: Сохраняем ID транзакции в SMS-сообщении.
// await _smsRepository.update(
// sms.copyWith(transactionId: transaction.id)
// );
// }
}
}