From 65fe73b396acd9be3f401ac4099287c5ac2153d3 Mon Sep 17 00:00:00 2001 From: Sanders Date: Fri, 27 Jun 2025 23:31:16 +0300 Subject: [PATCH] Transfer settings to user --- lib/injection_container.dart | 2 +- lib/logic/settings/settings_cubit.dart | 63 ++++++++++++++++++-------- lib/models/user.dart | 30 +++++++++--- lib/models/user.g.dart | 14 ++++-- lib/services/settings_service.dart | 34 -------------- lib/services/user_service.dart | 28 +++++++++--- 6 files changed, 98 insertions(+), 73 deletions(-) delete mode 100644 lib/services/settings_service.dart diff --git a/lib/injection_container.dart b/lib/injection_container.dart index df37dd1..49b8f82 100644 --- a/lib/injection_container.dart +++ b/lib/injection_container.dart @@ -21,7 +21,7 @@ Future initDependencies() async { await HiveService.init(); // Регистрация сервисов - getIt.registerSingleton(SettingsCubit()); // Регистрируем Cubit + getIt.registerSingleton(SettingsCubit(getIt())); // Регистрируем Cubit и передаем IUserRepository // Регистрация репозиториев getIt.registerSingleton( diff --git a/lib/logic/settings/settings_cubit.dart b/lib/logic/settings/settings_cubit.dart index 6304d70..ef516eb 100644 --- a/lib/logic/settings/settings_cubit.dart +++ b/lib/logic/settings/settings_cubit.dart @@ -1,42 +1,65 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; -import 'package:hive_ce/hive.dart'; +import 'package:budget_app/data/repositories/interfaces/iuser_repository.dart'; // Комментарий: Импортируем интерфейс репозитория пользователя +import 'package:budget_app/models/user.dart'; // Комментарий: Импортируем модель пользователя part 'settings_state.dart'; class SettingsCubit extends Cubit { - static const String _darkModeKey = 'darkMode'; - static const String _languageCodeKey = 'languageCode'; - static const String _defaultCurrencyKey = 'defaultCurrency'; // Комментарий: Новый ключ для хранения валюты по умолчанию - late final Box _settingsBox; + final IUserRepository _userRepository; // Комментарий: Зависимость от репозитория пользователя - SettingsCubit() : super(const SettingsInitial()) { - _settingsBox = Hive.box('settings'); + SettingsCubit(this._userRepository) : super(const SettingsInitial()) { // Комментарий: Принимаем репозиторий в конструкторе _loadSettings(); } - void _loadSettings() { - final isDarkMode = _settingsBox.get(_darkModeKey, defaultValue: false); - final languageCode = _settingsBox.get(_languageCodeKey, defaultValue: 'ru'); - // Комментарий: Загружаем валюту по умолчанию из Hive. Если ее нет, используем 'RUB'. - final defaultCurrency = _settingsBox.get(_defaultCurrencyKey, defaultValue: 'RUB'); - emit(state.copyWith(isDarkMode: isDarkMode, languageCode: languageCode, defaultCurrency: defaultCurrency)); + void _loadSettings() async { + // Комментарий: Получаем всех пользователей. В реальном приложении здесь будет логика получения текущего залогиненного пользователя. + final users = await _userRepository.getAll(); + User currentUser; + if (users.isEmpty) { + // Комментарий: Если пользователей нет, создаем нового с дефолтными настройками. + currentUser = User(name: 'Default User', email: 'default@example.com'); + await _userRepository.add(currentUser); + } else { + // Комментарий: Используем первого пользователя как текущего. + currentUser = users.first; + } + + emit(state.copyWith( + isDarkMode: currentUser.isDarkMode, + languageCode: currentUser.languageCode, + defaultCurrency: currentUser.defaultCurrency, + )); } Future setDarkMode(bool value) async { - await _settingsBox.put(_darkModeKey, value); - emit(state.copyWith(isDarkMode: value)); + final users = await _userRepository.getAll(); + if (users.isNotEmpty) { + final currentUser = users.first; + final updatedUser = currentUser.copyWith(isDarkMode: value); + await _userRepository.update(updatedUser); + emit(state.copyWith(isDarkMode: value)); + } } Future setLanguageCode(String code) async { - await _settingsBox.put(_languageCodeKey, code); - emit(state.copyWith(languageCode: code)); + final users = await _userRepository.getAll(); + if (users.isNotEmpty) { + final currentUser = users.first; + final updatedUser = currentUser.copyWith(languageCode: code); + await _userRepository.update(updatedUser); + emit(state.copyWith(languageCode: code)); + } } - // Комментарий: Новый метод для установки валюты по умолчанию. Future setDefaultCurrency(String currencyCode) async { - await _settingsBox.put(_defaultCurrencyKey, currencyCode); - emit(state.copyWith(defaultCurrency: currencyCode)); + final users = await _userRepository.getAll(); + if (users.isNotEmpty) { + final currentUser = users.first; + final updatedUser = currentUser.copyWith(defaultCurrency: currencyCode); + await _userRepository.update(updatedUser); + emit(state.copyWith(defaultCurrency: currencyCode)); + } } void toggleTheme() { diff --git a/lib/models/user.dart b/lib/models/user.dart index 1fbd545..ebcc600 100644 --- a/lib/models/user.dart +++ b/lib/models/user.dart @@ -22,20 +22,28 @@ class User { final String email; @HiveField(3) // Поле 3 в Hive - язык пользователя - final String language; + final String languageCode; // Переименовано с 'language' на 'languageCode' @HiveField(4) /// Дата и время последнего обновления объекта final DateTime updatedAt; + @HiveField(5) // Новое поле для режима темы (светлая/темная) + final bool isDarkMode; + + @HiveField(6) // Новое поле для валюты по умолчанию + final String defaultCurrency; + /// Конструктор пользователя /// id генерируется автоматически, если не передан User({ String? id, // Опциональный параметр - если null, сгенерируется автоматически required this.name, // Обязательный параметр required this.email, // Обязательный параметр - this.language = 'ru', // Язык по умолчанию - русский + this.languageCode = 'ru', // Язык по умолчанию - русский DateTime? updatedAt, // Добавлено поле updatedAt, теперь необязательное + this.isDarkMode = false, // По умолчанию светлая тема + this.defaultCurrency = 'RUB', // Валюта по умолчанию - RUB }) : id = id ?? IdGenerator.generateId(), // Если id не передан, генерируем новый updatedAt = updatedAt ?? DateTime.now(); // Устанавливаем текущее время по умолчанию @@ -45,8 +53,10 @@ class User { 'id': id, 'name': name, 'email': email, - 'language': language, + 'languageCode': languageCode, // Обновлено имя поля 'updatedAt': updatedAt.toIso8601String(), // Добавлено updatedAt в Map + 'isDarkMode': isDarkMode, + 'defaultCurrency': defaultCurrency, }; } @@ -56,15 +66,17 @@ class User { id: map['id'], name: map['name'], email: map['email'], - language: map['language'] ?? 'ru', // Устанавливаем русский по умолчанию, если язык не указан + languageCode: map['languageCode'] ?? 'ru', // Обновлено имя поля updatedAt: DateTime.parse(map['updatedAt']), // Добавлено updatedAt при создании из Map + isDarkMode: map['isDarkMode'] ?? false, + defaultCurrency: map['defaultCurrency'] ?? 'RUB', ); } /// Переопределяем toString для удобного отображения в логах @override String toString() { - return 'User(id: $id, name: $name, email: $email)'; + return 'User(id: $id, name: $name, email: $email, languageCode: $languageCode, isDarkMode: $isDarkMode, defaultCurrency: $defaultCurrency)'; } /// Метод для создания копии объекта с возможностью изменения полей @@ -72,14 +84,18 @@ class User { String? id, String? name, String? email, - String? language, + String? languageCode, // Обновлено имя поля + bool? isDarkMode, + String? defaultCurrency, }) { return User( id: id ?? this.id, name: name ?? this.name, email: email ?? this.email, - language: language ?? this.language, + languageCode: languageCode ?? this.languageCode, // Обновлено имя поля updatedAt: DateTime.now(), // Обновляем updatedAt при каждом копировании + isDarkMode: isDarkMode ?? this.isDarkMode, + defaultCurrency: defaultCurrency ?? this.defaultCurrency, ); } } diff --git a/lib/models/user.g.dart b/lib/models/user.g.dart index 4697b89..e1a5fe6 100644 --- a/lib/models/user.g.dart +++ b/lib/models/user.g.dart @@ -20,15 +20,17 @@ class UserAdapter extends TypeAdapter { id: fields[0] as String?, name: fields[1] as String, email: fields[2] as String, - language: fields[3] == null ? 'ru' : fields[3] as String, + languageCode: fields[3] == null ? 'ru' : fields[3] as String, updatedAt: fields[4] as DateTime?, + isDarkMode: fields[5] == null ? false : fields[5] as bool, + defaultCurrency: fields[6] == null ? 'RUB' : fields[6] as String, ); } @override void write(BinaryWriter writer, User obj) { writer - ..writeByte(5) + ..writeByte(7) ..writeByte(0) ..write(obj.id) ..writeByte(1) @@ -36,9 +38,13 @@ class UserAdapter extends TypeAdapter { ..writeByte(2) ..write(obj.email) ..writeByte(3) - ..write(obj.language) + ..write(obj.languageCode) ..writeByte(4) - ..write(obj.updatedAt); + ..write(obj.updatedAt) + ..writeByte(5) + ..write(obj.isDarkMode) + ..writeByte(6) + ..write(obj.defaultCurrency); } @override diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart deleted file mode 100644 index 9fff468..0000000 --- a/lib/services/settings_service.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:hive_ce/hive.dart'; - -class SettingsService extends ChangeNotifier { - static const String _darkModeKey = 'darkMode'; - static const String _languageCodeKey = 'languageCode'; // Новый ключ для языка - late final Box _settingsBox; - - SettingsService() { - _settingsBox = Hive.box('settings'); - } - - bool get isDarkMode => _settingsBox.get(_darkModeKey, defaultValue: false); - - Future setDarkMode(bool value) async { - await _settingsBox.put(_darkModeKey, value); - notifyListeners(); - } - - Future toggleTheme() async { - await setDarkMode(!isDarkMode); - } - - // Новый геттер для получения кода языка - String get languageCode => _settingsBox.get(_languageCodeKey, defaultValue: 'ru'); - - // Новый метод для установки кода языка - Future setLanguageCode(String code) async { - await _settingsBox.put(_languageCodeKey, code); - notifyListeners(); - } -} - - diff --git a/lib/services/user_service.dart b/lib/services/user_service.dart index bb4691c..d06f725 100644 --- a/lib/services/user_service.dart +++ b/lib/services/user_service.dart @@ -6,21 +6,22 @@ import 'package:budget_app/utils/tag_utils.dart'; import 'package:budget_app/utils/transaction_utils.dart'; import 'package:flutter/foundation.dart'; import 'package:hive_ce/hive.dart'; -import '/models/user.dart'; + import '/data/repositories/interfaces/iuser_repository.dart'; +import '/models/user.dart'; /// Сервис для управления текущим пользователем приложения /// Использует ChangeNotifier для уведомления UI об изменениях class UserService extends ChangeNotifier { // Ключ для сохранения ID текущего пользователя в настройках static const String _currentUserKey = 'currentUserId'; - + late final Box _settingsBox; // Box для хранения настроек final IUserRepository _userRepository; final ICategoryRepository _categoryRepository; final ITagRepository _tagRepository; final ITransactionRepository _transactionRepository; - + User? _currentUser; // Текущий активный пользователь /// Геттер для получения текущего пользователя @@ -30,7 +31,12 @@ class UserService extends ChangeNotifier { bool get hasCurrentUser => _currentUser != null; /// Конструктор сервиса - UserService(this._userRepository, this._categoryRepository, this._tagRepository, this._transactionRepository) { + UserService( + this._userRepository, + this._categoryRepository, + this._tagRepository, + this._transactionRepository, + ) { _settingsBox = Hive.box('settings'); _loadCurrentUser(); // Загружаем сохраненного пользователя при запуске } @@ -61,13 +67,21 @@ class UserService extends ChangeNotifier { /// Создание нового пользователя и установка его как текущего Future createAndSetUser(String name, String email) async { - final user = User(name: name, email: email, language: 'ru'); // Устанавливаем язык по умолчанию + final user = User( + name: name, + email: email, + languageCode: 'ru', + ); // Устанавливаем язык по умолчанию await _userRepository.add(user); // Добавляем начальные категории, теги и транзакции для нового пользователя - await _categoryRepository.addAll(CategoryUtils.getDefaultCategories(user.id)); + await _categoryRepository.addAll( + CategoryUtils.getDefaultCategories(user.id), + ); await _tagRepository.addAll(TagUtils.getDefaultTags(user.id)); - await _transactionRepository.addAll(TransactionUtils.getSampleTransactions(user.id)); + await _transactionRepository.addAll( + TransactionUtils.getSampleTransactions(user.id), + ); await setCurrentUser(user); }