diff --git a/GEMINI.md b/GEMINI.md deleted file mode 100644 index 93a84bf..0000000 --- a/GEMINI.md +++ /dev/null @@ -1,28 +0,0 @@ -# Project: Budget App - -## General Instructions: - -- Это проект на Flutter используй только его -- Комментируй в коде каждое изменение, которое ты делаешь, что бы мне было понятно и я учился на этом. -- Комментарии и твои ответы должны быть на русском языке -- When generating new Flutter code, please follow the existing coding style. -- Цветовая палитра черно-белая -- Все настройки цветов выноси в тему -- Все элементы должны разбиваться на мелкие и иметь логичную структуру по попкам -- Весь текст должен иметь локализацию чрезе flutter_localizations. Смотри папку l10n -- Разработка ведется под windows, ты можешь исопльзовать его консольные команды - -## Coding Style: - -- Interface names should be prefixed with `I` (e.g., `IUserService`). -- Private class members should be prefixed with an underscore (`_`). -- Учитывай, что в проекте используется bloc cubit архитектура - -## Role -- You are a Flutter assistant that helps users write more efficient and optimizable Flutter code. -- You specialize in identifying patterns that enable Flutter Compiler to automatically apply optimizations, reducing unnecessary re-renders and improving application performance. - -## Follow these guidelines in all code you produce and suggest -- Prefer composition and small components: Break down UI into small, reusable components rather than writing large monolithic components. The code you generate should promote clarity and reusability by composing components together. -- Design for a good user experience - Provide clear, minimal, and non-blocking UI states. When data is loading, show lightweight placeholders (e.g., skeleton screens) rather than intrusive spinners everywhere. Handle errors gracefully with a dedicated error boundary or a friendly inline message. Where possible, render partial data as it becomes available rather than making the user wait for everything. Suspense allows you to declare the loading states in your component tree in a natural way, preventing “flash” states and improving perceived performance. -- \ No newline at end of file diff --git a/lib/injection_container.dart b/lib/injection_container.dart index 5b31d6d..609ce7f 100644 --- a/lib/injection_container.dart +++ b/lib/injection_container.dart @@ -10,6 +10,7 @@ import 'data/repositories/interfaces/itag_repository.dart'; import 'data/repositories/interfaces/itransaction_repository.dart'; import 'data/repositories/interfaces/iuser_repository.dart'; import 'logic/auth/auth_bloc.dart'; +import 'logic/category/category_cubit.dart'; import 'logic/settings/settings_cubit.dart'; // Импортируем SettingsCubit import 'logic/sms/sms_cubit.dart'; import 'logic/transaction/transaction_bloc.dart'; @@ -56,4 +57,7 @@ Future initDependencies() async { ); getIt.registerFactory(() => SmsCubit(getIt())); + getIt.registerFactory( + () => CategoryCubit(getIt()), + ); // Регистрируем CategoryCubit с зависимостью от UserService } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index f93bb20..102cbe9 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -37,5 +37,10 @@ "save": "Save", "tag": "Tag", "smsPageTitle": "SMS Messages", - "smsPermissionDenied": "SMS permission is required" + "smsPermissionDenied": "SMS permission is required", + "editCategories": "Edit Categories", + "editCategoriesDescription": "Add, edit, or delete categories", + "color": "Color", + "chooseIcon": "Pick icon", + "chooseIconHint": "Search" } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 1ee694e..fd0cd48 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -325,6 +325,36 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'SMS permission is required'** String get smsPermissionDenied; + + /// No description provided for @editCategories. + /// + /// In en, this message translates to: + /// **'Edit Categories'** + String get editCategories; + + /// No description provided for @editCategoriesDescription. + /// + /// In en, this message translates to: + /// **'Add, edit, or delete categories'** + String get editCategoriesDescription; + + /// No description provided for @color. + /// + /// In en, this message translates to: + /// **'Color'** + String get color; + + /// No description provided for @chooseIcon. + /// + /// In en, this message translates to: + /// **'Pick icon'** + String get chooseIcon; + + /// No description provided for @chooseIconHint. + /// + /// In en, this message translates to: + /// **'Search'** + String get chooseIconHint; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index db805ed..5daa938 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -123,4 +123,19 @@ class AppLocalizationsEn extends AppLocalizations { @override String get smsPermissionDenied => 'SMS permission is required'; + + @override + String get editCategories => 'Edit Categories'; + + @override + String get editCategoriesDescription => 'Add, edit, or delete categories'; + + @override + String get color => 'Color'; + + @override + String get chooseIcon => 'Pick icon'; + + @override + String get chooseIconHint => 'Search'; } diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 20be8f3..5928c23 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -124,4 +124,20 @@ class AppLocalizationsRu extends AppLocalizations { @override String get smsPermissionDenied => 'Необходимо разрешение на чтение SMS'; + + @override + String get editCategories => 'Редактировать категории'; + + @override + String get editCategoriesDescription => + 'Добавляйте, редактируйте или удаляйте категории'; + + @override + String get color => 'Цвет'; + + @override + String get chooseIcon => 'Выберите иконку'; + + @override + String get chooseIconHint => 'Поиск по анлгийскому наименованию'; } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index 730eecb..72f7f47 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -37,5 +37,10 @@ "save": "Сохранить", "tag": "Тег", "smsPageTitle": "SMS Сообщения", - "smsPermissionDenied": "Необходимо разрешение на чтение SMS" + "smsPermissionDenied": "Необходимо разрешение на чтение SMS", + "editCategories": "Редактировать категории", + "editCategoriesDescription": "Добавляйте, редактируйте или удаляйте категории", + "color": "Цвет", + "chooseIcon": "Выберите иконку", + "chooseIconHint": "Поиск по анлгийскому наименованию" } diff --git a/lib/logic/category/category_cubit.dart b/lib/logic/category/category_cubit.dart new file mode 100644 index 0000000..dc3b9c9 --- /dev/null +++ b/lib/logic/category/category_cubit.dart @@ -0,0 +1,49 @@ + +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:budget_app/models/category.dart'; +import 'package:hive_ce/hive.dart'; +import 'package:budget_app/services/user_service.dart'; // Импортируем UserService + +class CategoryCubit extends Cubit> { + final UserService _userService; // Добавляем зависимость от UserService + final Box _categoryBox; // Используем Box для типизации + + CategoryCubit(this._userService) // Принимаем UserService через конструктор + : _categoryBox = Hive.box('categories'), + super([]); + + // Загружает категории, фильтруя их по userId текущего пользователя + void loadCategories() { + final currentUserId = _userService.currentUser?.id; + if (currentUserId != null) { + final userCategories = _categoryBox.values + .where((category) => category.userId == currentUserId) + .toList(); + emit(List.from(userCategories)); + } else { + emit([]); // Если пользователя нет, список категорий пуст + } + } + + // Добавляет новую категорию, присваивая ей userId текущего пользователя + void addCategory(Category category) { + final currentUserId = _userService.currentUser?.id; + if (currentUserId != null) { + final newCategory = category.copyWith(userId: currentUserId); // Присваиваем userId + _categoryBox.put(newCategory.id, newCategory); + loadCategories(); + } + } + + // Обновляет существующую категорию + void updateCategory(Category category) { + _categoryBox.put(category.id, category); + loadCategories(); + } + + // Удаляет категорию по ее id + void deleteCategory(String id) { + _categoryBox.delete(id); + loadCategories(); + } +} diff --git a/lib/pages/category/category_edit_page.dart b/lib/pages/category/category_edit_page.dart new file mode 100644 index 0000000..ec66b29 --- /dev/null +++ b/lib/pages/category/category_edit_page.dart @@ -0,0 +1,167 @@ +import 'package:budget_app/l10n/app_localizations.dart'; +import 'package:budget_app/models/category.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_colorpicker/flutter_colorpicker.dart'; +import 'package:flutter_iconpicker/Models/configuration.dart'; +import 'package:flutter_iconpicker/flutter_iconpicker.dart'; + +class CategoryEditPage extends StatefulWidget { + final Category? category; + final Function(String, Color, IconData) onSave; + + const CategoryEditPage({super.key, this.category, required this.onSave}); + + @override + _CategoryEditPageState createState() => _CategoryEditPageState(); +} + +class _CategoryEditPageState extends State { + final _formKey = GlobalKey(); + late String _name; + late Color _color; + late IconData _icon; + + @override + void initState() { + super.initState(); + _name = widget.category?.name ?? ''; + _color = widget.category?.color ?? Colors.blue; + _icon = widget.category?.icon ?? Icons.ac_unit; + } + + @override + Widget build(BuildContext context) { + final localizations = AppLocalizations.of(context)!; + return Scaffold( + appBar: AppBar( + title: Text( + widget.category == null + ? localizations.addTransactionButton + : localizations.editCategories, + ), + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: Column( + children: [ + TextFormField( + initialValue: _name, + decoration: InputDecoration( + labelText: localizations.nameFieldLabel, + ), + validator: (value) { + if (value == null || value.isEmpty) { + return localizations.nameFieldEmptyError; + } + return null; + }, + onSaved: (value) { + _name = value!; + }, + ), + const SizedBox(height: 20), + Row( + children: [ + Text(localizations.color), + const SizedBox(width: 10), + GestureDetector( + onTap: () { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text(localizations.color), + content: SingleChildScrollView( + child: ColorPicker( + pickerColor: _color, + onColorChanged: (color) { + setState(() { + _color = color; + }); + }, + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text(localizations.save), + ), + ], + ), + ); + }, + child: CircleAvatar(backgroundColor: _color), + ), + ], + ), + const SizedBox(height: 20), + Row( + children: [ + Text(localizations.tag), + const SizedBox(width: 10), + GestureDetector( + onTap: () async { + final icon = await showIconPicker( + context, + configuration: SinglePickerConfiguration( + adaptiveDialog: true, + showTooltips: true, + showSearchBar: true, + preSelected: IconPickerIcon( + name: '', + data: _icon, + pack: IconPack.material, + ), + title: Text( + localizations.chooseIcon, + textScaler: const TextScaler.linear(1.25), + ), + searchHintText: localizations.chooseIconHint, + iconPickerShape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + ), + //iconPackModes: IconNotifier.starterPacks, + searchComparator: + (String search, IconPickerIcon icon) => + search.toLowerCase().contains( + icon.name + .replaceAll('_', ' ') + .toLowerCase(), + ) || + icon.name.toLowerCase().contains( + search.toLowerCase(), + ), + ), + ); + + if (icon != null) { + setState(() { + _icon = icon.data; + }); + } + }, + child: Icon(_icon), + ), + ], + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + _formKey.currentState!.save(); + widget.onSave(_name, _color, _icon); + Navigator.pop(context); + } + }, + child: Text(localizations.save), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/category/category_list_page.dart b/lib/pages/category/category_list_page.dart new file mode 100644 index 0000000..713ab11 --- /dev/null +++ b/lib/pages/category/category_list_page.dart @@ -0,0 +1,100 @@ +import 'package:budget_app/l10n/app_localizations.dart'; +import 'package:budget_app/logic/category/category_cubit.dart'; +import 'package:budget_app/models/category.dart'; +import 'package:budget_app/pages/category/category_edit_page.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:get_it/get_it.dart'; // Импортируем GetIt + +class CategoryListPage extends StatelessWidget { + const CategoryListPage({super.key}); + + @override + Widget build(BuildContext context) { + final localizations = AppLocalizations.of(context)!; + return Scaffold( + appBar: AppBar(title: Text(localizations.editCategories)), + body: BlocProvider( + create: (context) => + GetIt.instance() + ..loadCategories(), // Получаем CategoryCubit из GetIt + child: BlocBuilder>( + builder: (context, categories) { + return ListView.builder( + itemCount: categories.length, + itemBuilder: (context, index) { + final category = categories[index]; + return ListTile( + leading: CircleAvatar( + backgroundColor: category.color, + child: Icon(category.icon, color: Colors.white), + ), + title: Text(category.name), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + icon: const Icon(Icons.edit), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => CategoryEditPage( + category: category, + onSave: (name, color, icon) { + final updatedCategory = category.copyWith( + name: name, + color: color, + icon: icon, + ); + context.read().updateCategory( + updatedCategory, + ); // Обновляем категорию по ее id + }, + ), + ), + ); + }, + ), + IconButton( + icon: const Icon(Icons.delete), + onPressed: () { + context.read().deleteCategory( + category.id, + ); // Удаляем категорию по ее id + }, + ), + ], + ), + ); + }, + ); + }, + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => CategoryEditPage( + onSave: (name, color, icon) { + final newCategory = Category( + name: name, + color: color, + icon: icon, + isIncome: false, // по умолчанию false + userId: 'default_user', + // userId будет установлен в CategoryCubit + ); + context.read().addCategory(newCategory); + }, + ), + ), + ); + }, + child: const Icon(Icons.add), + ), + ); + } +} diff --git a/lib/pages/home/home_page.dart b/lib/pages/home/home_page.dart index 5e42076..7629910 100644 --- a/lib/pages/home/home_page.dart +++ b/lib/pages/home/home_page.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:get_it/get_it.dart'; +import '../../theme/custom_colors.dart'; import '/l10n/app_localizations.dart'; import '../../logic/auth/auth_bloc.dart'; @@ -101,6 +102,7 @@ class _HomePageState extends State { ], currentIndex: _selectedIndex, selectedItemColor: Theme.of(context).colorScheme.primary, + unselectedItemColor: Theme.of(context).extension()?.unselectedIcon, onTap: _onItemTapped, ), ); diff --git a/lib/pages/home/widgets/add_transaction_dialog.dart b/lib/pages/home/widgets/add_transaction_dialog.dart index 215d623..fbe8d48 100644 --- a/lib/pages/home/widgets/add_transaction_dialog.dart +++ b/lib/pages/home/widgets/add_transaction_dialog.dart @@ -38,7 +38,7 @@ class _AddTransactionDialogState extends State { void initState() { super.initState(); // Комментарий: Устанавливаем начальное значение с датой и временем. - _dateController.text = DateFormat.yMd().add_Hm().format(_selectedDateTime); + _dateController.text = DateFormat('dd-MM-yyyy').add_Hm().format(_selectedDateTime); } @override @@ -78,7 +78,7 @@ class _AddTransactionDialogState extends State { pickedTime.minute, ); // Комментарий: Обновляем текстовое поле с отформатированной датой и временем. - _dateController.text = DateFormat.yMd().add_Hm().format(_selectedDateTime); + _dateController.text = DateFormat('dd-MM-yyyy').add_Hm().format(_selectedDateTime); }); } diff --git a/lib/pages/settings_page.dart b/lib/pages/settings_page.dart index 0875888..7ae27ab 100644 --- a/lib/pages/settings_page.dart +++ b/lib/pages/settings_page.dart @@ -1,3 +1,4 @@ +import 'package:budget_app/pages/category/category_list_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '/l10n/app_localizations.dart'; @@ -97,6 +98,20 @@ class SettingsPage extends StatelessWidget { ), ), const Divider(), + // Комментарий: ListTile для перехода на страницу редактирования категорий. + ListTile( + title: Text(localizations.editCategories), + subtitle: Text(localizations.editCategoriesDescription), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const CategoryListPage(), + ), + ); + }, + ), + const Divider(), ], ), ); diff --git a/lib/theme/app_theme.dart b/lib/theme/app_theme.dart index ec3775f..e60c95b 100644 --- a/lib/theme/app_theme.dart +++ b/lib/theme/app_theme.dart @@ -50,6 +50,7 @@ class AppTheme { expense: Colors.grey[600]!, // Серый для расходов divider: Colors.grey[300]!, // Светло-серый для разделителей accent: Colors.black, // Черный для акцентов + unselectedIcon: Colors.grey[500]!, // Серый для невыбранных иконок ), ], ); @@ -103,6 +104,7 @@ class AppTheme { expense: Colors.grey[500]!, // Серый для расходов divider: Colors.grey[700]!, // Темно-серый для разделителей accent: Colors.white, // Белый для акцентов + unselectedIcon: Colors.grey[400]!, // Светло-серый для невыбранных иконок ), ], ); diff --git a/lib/theme/custom_colors.dart b/lib/theme/custom_colors.dart index ffa1a9e..edb1005 100644 --- a/lib/theme/custom_colors.dart +++ b/lib/theme/custom_colors.dart @@ -9,12 +9,14 @@ class CustomColors extends ThemeExtension { required this.expense, this.divider, // Добавлен цвет для разделителей this.accent, // Добавлен цвет для акцентов + this.unselectedIcon, // Цвет для невыбранных иконок }); final Color? income; final Color? expense; final Color? divider; final Color? accent; + final Color? unselectedIcon; // Цвет для невыбранных иконок @override CustomColors copyWith({ @@ -22,12 +24,14 @@ class CustomColors extends ThemeExtension { Color? expense, Color? divider, Color? accent, + Color? unselectedIcon, }) { return CustomColors( income: income ?? this.income, expense: expense ?? this.expense, divider: divider ?? this.divider, accent: accent ?? this.accent, + unselectedIcon: unselectedIcon ?? this.unselectedIcon, ); } @@ -41,6 +45,7 @@ class CustomColors extends ThemeExtension { expense: Color.lerp(expense, other.expense, t), divider: Color.lerp(divider, other.divider, t), accent: Color.lerp(accent, other.accent, t), + unselectedIcon: Color.lerp(unselectedIcon, other.unselectedIcon, t), ); } } diff --git a/pubspec.lock b/pubspec.lock index aa74e64..a67c496 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -33,6 +33,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.1" + archive: + dependency: transitive + description: + name: archive + sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d + url: "https://pub.dev" + source: hosted + version: "3.6.1" args: dependency: transitive description: @@ -145,6 +153,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.4" + chunked_stream: + dependency: transitive + description: + name: chunked_stream + sha256: b2fde5f81d780f0c1699b8347cae2e413412ae947fc6e64727cc48c6bb54c95c + url: "https://pub.dev" + source: hosted + version: "1.4.2" + circular_buffer: + dependency: transitive + description: + name: circular_buffer + sha256: b3a315fef3fee7fe58879643fc8ce21c7c2449d01c1a8a396dc9e24687f335c4 + url: "https://pub.dev" + source: hosted + version: "0.12.0" clock: dependency: transitive description: @@ -185,6 +209,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.6" + csv: + dependency: transitive + description: + name: csv + sha256: c6aa2679b2a18cb57652920f674488d89712efaf4d3fdf2e537215b35fc19d6c + url: "https://pub.dev" + source: hosted + version: "6.0.0" cupertino_icons: dependency: "direct main" description: @@ -193,6 +225,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" + dart_console: + dependency: transitive + description: + name: dart_console + sha256: "03c23e1f9cc3ac02b608f834808003e6510a5b292a0449f43dfac1c78bd8ee85" + url: "https://pub.dev" + source: hosted + version: "4.1.2" dart_style: dependency: transitive description: @@ -201,6 +241,38 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.0" + dcli: + dependency: transitive + description: + name: dcli + sha256: "881e88bbad0ada4e3a085a0b55e05afa8e4199392c0c45ac18e3dedc37305b9b" + url: "https://pub.dev" + source: hosted + version: "6.1.2" + dcli_common: + dependency: transitive + description: + name: dcli_common + sha256: f8f77bea6a6d7e4ec2dc24cb4f274fc582938057c2cba44ed0650195ecfcd3ad + url: "https://pub.dev" + source: hosted + version: "6.1.2" + dcli_core: + dependency: transitive + description: + name: dcli_core + sha256: "29fb4833aa950900936646190b30315db511a853273b9fe31d360e5f72c7560b" + url: "https://pub.dev" + source: hosted + version: "6.1.2" + dcli_terminal: + dependency: transitive + description: + name: dcli_terminal + sha256: fb50860855c6b2841aed5bcfb315fa83d1401e109691b6585773a24c149dc4b0 + url: "https://pub.dev" + source: hosted + version: "6.1.2" equatable: dependency: "direct main" description: @@ -254,6 +326,22 @@ packages: url: "https://pub.dev" source: hosted version: "9.1.1" + flutter_colorpicker: + dependency: "direct main" + description: + name: flutter_colorpicker + sha256: "969de5f6f9e2a570ac660fb7b501551451ea2a1ab9e2097e89475f60e07816ea" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + flutter_iconpicker: + dependency: "direct main" + description: + name: flutter_iconpicker + sha256: d53b35bcb73325fcfdd36931769a8e7ff33b38e3b7c39b518a226fd0a5f3dc29 + url: "https://pub.dev" + source: hosted + version: "4.0.1" flutter_lints: dependency: "direct dev" description: @@ -272,6 +360,14 @@ packages: description: flutter source: sdk version: "0.0.0" + font_awesome_flutter: + dependency: transitive + description: + name: font_awesome_flutter + sha256: d3a89184101baec7f4600d58840a764d2ef760fe1c5a20ef9e6b0e9b24a07a3a + url: "https://pub.dev" + source: hosted + version: "10.8.0" frontend_server_client: dependency: transitive description: @@ -280,6 +376,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" + functional_data: + dependency: transitive + description: + name: functional_data + sha256: "76d17dc707c40e552014f5a49c0afcc3f1e3f05e800cd6b7872940bfe41a5039" + url: "https://pub.dev" + source: hosted + version: "1.2.0" get_it: dependency: "direct main" description: @@ -296,6 +400,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" + globbing: + dependency: transitive + description: + name: globbing + sha256: "4f89cfaf6fa74c9c1740a96259da06bd45411ede56744e28017cc534a12b6e2d" + url: "https://pub.dev" + source: hosted + version: "1.0.0" graphs: dependency: transitive description: @@ -352,6 +464,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" + ini: + dependency: transitive + description: + name: ini + sha256: "12a76c53591ffdf86d1265be3f986888a6dfeb34a85957774bc65912d989a173" + url: "https://pub.dev" + source: hosted + version: "2.1.0" intl: dependency: "direct main" description: @@ -384,6 +504,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.2" + json2yaml: + dependency: transitive + description: + name: json2yaml + sha256: da94630fbc56079426fdd167ae58373286f603371075b69bf46d848d63ba3e51 + url: "https://pub.dev" + source: hosted + version: "3.0.1" json_annotation: dependency: transitive description: @@ -424,6 +552,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.1.1" + lists: + dependency: transitive + description: + name: lists + sha256: "4ca5c19ae4350de036a7e996cdd1ee39c93ac0a2b840f4915459b7d0a7d4ab27" + url: "https://pub.dev" + source: hosted + version: "1.0.1" logger: dependency: "direct main" description: @@ -472,6 +608,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + native_synchronization_temp: + dependency: transitive + description: + name: native_synchronization_temp + sha256: f9ad36a5054c606db10e3dc0c9c352e6d0d56d08621af5c470abf9fa41da40fa + url: "https://pub.dev" + source: hosted + version: "0.7.1" nested: dependency: transitive description: @@ -568,6 +712,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + posix: + dependency: transitive + description: + name: posix + sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" + url: "https://pub.dev" + source: hosted + version: "6.0.3" provider: dependency: transitive description: @@ -584,6 +736,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + pubspec_lock: + dependency: transitive + description: + name: pubspec_lock + sha256: ed5fc1ecd0cdc0e14475a091afcb2c4cbb00e74cebff17635e9abbec18d76cc4 + url: "https://pub.dev" + source: hosted + version: "3.0.2" + pubspec_manager: + dependency: transitive + description: + name: pubspec_manager + sha256: "4000db36057ddc9c95f1c56fd209ce54b1e7c621280f52e159a83342b1e33d62" + url: "https://pub.dev" + source: hosted + version: "1.0.2" pubspec_parse: dependency: transitive description: @@ -592,6 +760,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" + scope: + dependency: transitive + description: + name: scope + sha256: "0b056e5b64ca16a2db9e1eb35cf7fd05a9e99a6b15140f82bfa651d081e4819b" + url: "https://pub.dev" + source: hosted + version: "5.1.0" + scrollview_observer: + dependency: transitive + description: + name: scrollview_observer + sha256: "174d4efe7b79459a07662175c4db42c9862dcf78d3978e6e9c2d6c0d8137f4ca" + url: "https://pub.dev" + source: hosted + version: "1.26.1" + settings_yaml: + dependency: transitive + description: + name: settings_yaml + sha256: "31c389f57d21518866ff36ec08cb15bf5c28aa6d324c09ba34a5547474f2b603" + url: "https://pub.dev" + source: hosted + version: "8.3.0" shelf: dependency: transitive description: @@ -677,6 +869,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" + strings: + dependency: transitive + description: + name: strings + sha256: "052836499f03897d3860a603b330c1ea3c8a14177b21f34b15a1295f36024aae" + url: "https://pub.dev" + source: hosted + version: "3.1.2" + sum_types: + dependency: transitive + description: + name: sum_types + sha256: c0a0fad9a518d011987e1d9f27fc336194294e55dafdc3699363e52aa5776e09 + url: "https://pub.dev" + source: hosted + version: "0.3.5" + system_info2: + dependency: transitive + description: + name: system_info2 + sha256: "65206bbef475217008b5827374767550a5420ce70a04d2d7e94d1d2253f3efc9" + url: "https://pub.dev" + source: hosted + version: "4.0.0" term_glyph: dependency: transitive description: @@ -709,6 +925,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + unicode: + dependency: transitive + description: + name: unicode + sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1" + url: "https://pub.dev" + source: hosted + version: "0.3.1" uuid: dependency: "direct main" description: @@ -717,6 +941,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.5.1" + validators2: + dependency: transitive + description: + name: validators2 + sha256: "5c63054b2f47b6a3f39e0d0e3f5d38829db4545250144a34c9e1585466de4814" + url: "https://pub.dev" + source: hosted + version: "5.0.0" vector_math: dependency: transitive description: @@ -765,6 +997,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" + win32: + dependency: transitive + description: + name: win32 + sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" + url: "https://pub.dev" + source: hosted + version: "5.14.0" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b8ac46d..082c402 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -48,6 +48,8 @@ dependencies: sdk: flutter intl: ^0.20.2 bloc: + flutter_colorpicker: ^1.1.0 + flutter_iconpicker: ^4.0.1 dev_dependencies: