Adds category management feature
Adds the ability to manage categories in the settings page. This includes: - Registers CategoryCubit in the dependency injection container. - Introduces a new CategoryListPage for editing categories. - Adds translations for category management related text. - Adds unselected icon color to the theme. - Updates the date format in the transaction dialog.
This commit is contained in:
@@ -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.
|
||||
-
|
||||
@@ -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<void> initDependencies() async {
|
||||
);
|
||||
|
||||
getIt.registerFactory<SmsCubit>(() => SmsCubit(getIt()));
|
||||
getIt.registerFactory<CategoryCubit>(
|
||||
() => CategoryCubit(getIt()),
|
||||
); // Регистрируем CategoryCubit с зависимостью от UserService
|
||||
}
|
||||
|
||||
+6
-1
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
@@ -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 => 'Поиск по анлгийскому наименованию';
|
||||
}
|
||||
|
||||
+6
-1
@@ -37,5 +37,10 @@
|
||||
"save": "Сохранить",
|
||||
"tag": "Тег",
|
||||
"smsPageTitle": "SMS Сообщения",
|
||||
"smsPermissionDenied": "Необходимо разрешение на чтение SMS"
|
||||
"smsPermissionDenied": "Необходимо разрешение на чтение SMS",
|
||||
"editCategories": "Редактировать категории",
|
||||
"editCategoriesDescription": "Добавляйте, редактируйте или удаляйте категории",
|
||||
"color": "Цвет",
|
||||
"chooseIcon": "Выберите иконку",
|
||||
"chooseIconHint": "Поиск по анлгийскому наименованию"
|
||||
}
|
||||
|
||||
@@ -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<List<Category>> {
|
||||
final UserService _userService; // Добавляем зависимость от UserService
|
||||
final Box<Category> _categoryBox; // Используем Box<Category> для типизации
|
||||
|
||||
CategoryCubit(this._userService) // Принимаем UserService через конструктор
|
||||
: _categoryBox = Hive.box<Category>('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();
|
||||
}
|
||||
}
|
||||
@@ -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<CategoryEditPage> {
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
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),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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<CategoryCubit>()
|
||||
..loadCategories(), // Получаем CategoryCubit из GetIt
|
||||
child: BlocBuilder<CategoryCubit, List<Category>>(
|
||||
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<CategoryCubit>().updateCategory(
|
||||
updatedCategory,
|
||||
); // Обновляем категорию по ее id
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.delete),
|
||||
onPressed: () {
|
||||
context.read<CategoryCubit>().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<CategoryCubit>().addCategory(newCategory);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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<HomePage> {
|
||||
],
|
||||
currentIndex: _selectedIndex,
|
||||
selectedItemColor: Theme.of(context).colorScheme.primary,
|
||||
unselectedItemColor: Theme.of(context).extension<CustomColors>()?.unselectedIcon,
|
||||
onTap: _onItemTapped,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -38,7 +38,7 @@ class _AddTransactionDialogState extends State<AddTransactionDialog> {
|
||||
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<AddTransactionDialog> {
|
||||
pickedTime.minute,
|
||||
);
|
||||
// Комментарий: Обновляем текстовое поле с отформатированной датой и временем.
|
||||
_dateController.text = DateFormat.yMd().add_Hm().format(_selectedDateTime);
|
||||
_dateController.text = DateFormat('dd-MM-yyyy').add_Hm().format(_selectedDateTime);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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(),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -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]!, // Светло-серый для невыбранных иконок
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -9,12 +9,14 @@ class CustomColors extends ThemeExtension<CustomColors> {
|
||||
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<CustomColors> {
|
||||
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<CustomColors> {
|
||||
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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+240
@@ -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:
|
||||
|
||||
@@ -48,6 +48,8 @@ dependencies:
|
||||
sdk: flutter
|
||||
intl: ^0.20.2
|
||||
bloc:
|
||||
flutter_colorpicker: ^1.1.0
|
||||
flutter_iconpicker: ^4.0.1
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
Reference in New Issue
Block a user