Skip to content

Commit d2cff8a

Browse files
Merge branch 'develop'
2 parents 97ac79b + 225dcab commit d2cff8a

File tree

95 files changed

+1969
-1324
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+1969
-1324
lines changed

android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ android {
6060
applicationId "com.monekin.app"
6161
// You can update the following values to match your application needs.
6262
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
63-
minSdkVersion 19
63+
minSdkVersion 21
6464
targetSdkVersion flutter.targetSdkVersion
6565
versionCode flutterVersionCode.toInteger()
6666
versionName flutterVersionName

lib/app/accounts/account_form.dart

Lines changed: 233 additions & 249 deletions
Large diffs are not rendered by default.

lib/app/accounts/account_selector.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ import 'package:flutter/material.dart';
44
import 'package:flutter/services.dart';
55
import 'package:monekin/core/database/app_db.dart';
66
import 'package:monekin/core/database/services/account/account_service.dart';
7+
import 'package:monekin/core/extensions/color.extensions.dart';
78
import 'package:monekin/core/models/account/account.dart';
89
import 'package:monekin/core/models/supported-icon/icon_displayer.dart';
910
import 'package:monekin/core/presentation/app_colors.dart';
11+
import 'package:monekin/core/presentation/theme.dart';
1012
import 'package:monekin/core/presentation/widgets/bottomSheetFooter.dart';
1113
import 'package:monekin/core/presentation/widgets/modal_container.dart';
12-
import 'package:monekin/core/utils/color_utils.dart';
1314
import 'package:monekin/i18n/translations.g.dart';
1415

1516
import '../../core/presentation/widgets/icon_displayer_widgets.dart';
@@ -237,7 +238,7 @@ class _AccountSelectorState extends State<AccountSelector> {
237238
padding: widget.params.iconPadding,
238239
isOutline: selectedAccounts == null,
239240
secondaryColor: AppColors.of(context).background.darken(
240-
Theme.of(context).brightness == Brightness.dark ? 0.6 : 0.1,
241+
isAppInDarkBrightness(context) ? 0.6 : 0.1,
241242
),
242243
mainColor: AppColors.of(context).onBackground,
243244
onTap: () {

lib/app/accounts/details/account_details.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import 'package:monekin/core/database/services/account/account_service.dart';
99
import 'package:monekin/core/database/services/exchange-rate/exchange_rate_service.dart';
1010
import 'package:monekin/core/database/services/transaction/transaction_service.dart';
1111
import 'package:monekin/core/models/account/account.dart';
12-
import 'package:monekin/core/models/transaction/transaction_status.dart';
12+
import 'package:monekin/core/models/transaction/transaction_status.enum.dart';
1313
import 'package:monekin/core/presentation/app_colors.dart';
1414
import 'package:monekin/core/presentation/widgets/bottomSheetFooter.dart';
1515
import 'package:monekin/core/presentation/widgets/card_with_header.dart';
16-
import 'package:monekin/core/presentation/widgets/date_form_field/date_form_field.dart';
16+
import 'package:monekin/core/presentation/widgets/form_fields/date_form_field.dart';
1717
import 'package:monekin/core/presentation/widgets/inline_info_card.dart';
1818
import 'package:monekin/core/presentation/widgets/modal_container.dart';
1919
import 'package:monekin/core/presentation/widgets/monekin_quick_actions_buttons.dart';

lib/app/accounts/details/account_details_actions.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import 'package:monekin/app/accounts/details/account_details.dart';
55
import 'package:monekin/app/transactions/form/transaction_form.page.dart';
66
import 'package:monekin/core/database/services/account/account_service.dart';
77
import 'package:monekin/core/models/account/account.dart';
8-
import 'package:monekin/core/models/transaction/transaction.dart';
98
import 'package:monekin/core/presentation/widgets/confirm_dialog.dart';
109
import 'package:monekin/core/routes/route_utils.dart';
1110
import 'package:monekin/core/utils/list_tile_action_item.dart';
1211
import 'package:monekin/i18n/translations.g.dart';
1312

13+
import '../../../core/models/transaction/transaction_type.enum.dart';
14+
1415
abstract class AccountDetailsActions {
1516
static List<ListTileActionItem> getAccountDetailsActions(
1617
BuildContext context, {

lib/app/budgets/budget_form_page.dart

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import 'package:monekin/core/database/services/currency/currency_service.dart';
99
import 'package:monekin/core/models/budget/budget.dart';
1010
import 'package:monekin/core/models/category/category.dart';
1111
import 'package:monekin/core/models/date-utils/periodicity.dart';
12-
import 'package:monekin/core/presentation/widgets/date_form_field/date_field.dart';
13-
import 'package:monekin/core/presentation/widgets/date_form_field/date_form_field.dart';
12+
import 'package:monekin/core/presentation/widgets/form_fields/date_field.dart';
13+
import 'package:monekin/core/presentation/widgets/form_fields/date_form_field.dart';
1414
import 'package:monekin/core/presentation/widgets/icon_displayer_widgets.dart';
1515
import 'package:monekin/core/utils/text_field_utils.dart';
16+
import 'package:monekin/core/utils/uuid.dart';
1617
import 'package:monekin/i18n/translations.g.dart';
17-
import 'package:uuid/uuid.dart';
1818

1919
import '../../core/models/account/account.dart';
2020
import '../../core/presentation/widgets/persistent_footer_button.dart';
@@ -48,28 +48,6 @@ class _BudgetFormPageState extends State<BudgetFormPage> {
4848
DateTime startDate = DateTime.now();
4949
DateTime? endDate;
5050

51-
Widget selector({
52-
required String title,
53-
required String? inputValue,
54-
required Function onClick,
55-
}) {
56-
return TextFormField(
57-
controller: TextEditingController(text: inputValue ?? ''),
58-
readOnly: true,
59-
onTap: () => onClick(),
60-
validator: (value) {
61-
if (inputValue == null) {
62-
return 'Please, specify at least one item here';
63-
}
64-
65-
return null;
66-
},
67-
decoration: InputDecoration(
68-
labelText: title,
69-
suffixIcon: const Icon(Icons.arrow_drop_down),
70-
));
71-
}
72-
7351
submitForm() {
7452
final t = Translations.of(context);
7553

@@ -92,7 +70,7 @@ class _BudgetFormPageState extends State<BudgetFormPage> {
9270
final Budget toPush;
9371

9472
toPush = Budget(
95-
id: isEditMode ? widget.budgetToEdit!.id : const Uuid().v4(),
73+
id: isEditMode ? widget.budgetToEdit!.id : generateUUID(),
9674
name: nameController.text,
9775
limitAmount: valueToNumber!,
9876
intervalPeriod: intervalPeriod,

lib/app/budgets/components/budget_card.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import 'package:monekin/core/presentation/widgets/number_ui_formatters/currency_
1010
import 'package:monekin/core/presentation/widgets/skeleton.dart';
1111
import 'package:monekin/core/presentation/widgets/tappable.dart';
1212
import 'package:monekin/core/routes/route_utils.dart';
13-
import 'package:monekin/core/utils/color_utils.dart';
13+
import 'package:monekin/core/extensions/color.extensions.dart';
1414
import 'package:monekin/i18n/translations.g.dart';
1515

1616
class BudgetCard extends StatelessWidget {

lib/app/budgets/components/budget_evolution_chart.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import 'package:flutter/material.dart';
66
import 'package:intl/intl.dart';
77
import 'package:monekin/app/stats/widgets/fund_evolution_line_chart.dart';
88
import 'package:monekin/core/models/budget/budget.dart';
9-
import 'package:monekin/core/utils/color_utils.dart';
109
import 'package:monekin/i18n/translations.g.dart';
1110

1211
import '../../../core/presentation/app_colors.dart';
@@ -85,7 +84,7 @@ class BudgetEvolutionChart extends StatelessWidget {
8584
]),
8685
lineTouchData: LineTouchData(
8786
touchTooltipData: LineTouchTooltipData(
88-
tooltipBgColor: AppColors.of(context).background,
87+
getTooltipColor: (spot) => AppColors.of(context).background,
8988
tooltipHorizontalAlignment: FLHorizontalAlignment.right,
9089
tooltipMargin: -10,
9190
getTooltipItems: (touchedSpots) {

lib/app/categories/categories_list.dart

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import 'package:monekin/app/categories/category_selector.dart';
33
import 'package:monekin/app/categories/form/category_form.dart';
44
import 'package:monekin/app/categories/subcategory_selector.dart';
55
import 'package:monekin/core/database/services/category/category_service.dart';
6+
import 'package:monekin/core/extensions/color.extensions.dart';
67
import 'package:monekin/core/models/category/category.dart';
8+
import 'package:monekin/core/presentation/theme.dart';
79
import 'package:monekin/core/presentation/widgets/icon_displayer_widgets.dart';
810
import 'package:monekin/core/presentation/widgets/persistent_footer_button.dart';
911
import 'package:monekin/core/routes/route_utils.dart';
10-
import 'package:monekin/core/utils/color_utils.dart';
1112
import 'package:monekin/i18n/translations.g.dart';
1213

1314
import '../../core/presentation/app_colors.dart';
@@ -231,18 +232,15 @@ class _CategoriesListState extends State<CategoriesList> {
231232
),
232233
TabBar(
233234
labelColor:
234-
Theme.of(context).brightness == Brightness.light &&
235-
widget.mode.isModal
235+
isAppInLightBrightness(context) && widget.mode.isModal
236236
? AppColors.of(context).primary
237237
: null,
238238
unselectedLabelColor:
239-
Theme.of(context).brightness == Brightness.light &&
240-
widget.mode.isModal
239+
isAppInLightBrightness(context) && widget.mode.isModal
241240
? AppColors.of(context).onBackground.lighten(0.3)
242241
: null,
243242
indicatorColor:
244-
Theme.of(context).brightness == Brightness.light &&
245-
widget.mode.isModal
243+
isAppInLightBrightness(context) && widget.mode.isModal
246244
? AppColors.of(context).primary
247245
: null,
248246
tabs: [

lib/app/categories/category_selector.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import 'package:flutter/material.dart';
22
import 'package:flutter/services.dart';
3+
import 'package:monekin/core/extensions/color.extensions.dart';
34
import 'package:monekin/core/models/category/category.dart';
45
import 'package:monekin/core/models/supported-icon/icon_displayer.dart';
56
import 'package:monekin/core/presentation/app_colors.dart';
6-
import 'package:monekin/core/utils/color_utils.dart';
7+
import 'package:monekin/core/presentation/theme.dart';
78
import 'package:monekin/i18n/translations.g.dart';
89

910
import '../../core/presentation/widgets/icon_displayer_widgets.dart';
@@ -91,9 +92,10 @@ class _CategorySelectorState extends State<CategorySelector> {
9192
icon: Icons.select_all,
9293
size: widget.params.iconSize,
9394
padding: widget.params.iconPadding,
95+
borderRadius: 99999,
9496
isOutline: selectedCategories == null,
9597
secondaryColor: AppColors.of(context).background.darken(
96-
Theme.of(context).brightness == Brightness.dark ? 0.6 : 0.1,
98+
isAppInDarkBrightness(context) ? 0.6 : 0.1,
9799
),
98100
mainColor: AppColors.of(context).onBackground,
99101
onTap: () {

lib/app/categories/form/category_form.dart

Lines changed: 48 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import 'package:drift/drift.dart' as drift;
22
import 'package:flutter/material.dart';
33
import 'package:monekin/app/categories/form/category_form_functions.dart';
4+
import 'package:monekin/app/categories/form/icon_and_color_selector.dart';
45
import 'package:monekin/core/database/app_db.dart';
56
import 'package:monekin/core/database/services/category/category_service.dart';
7+
import 'package:monekin/core/extensions/color.extensions.dart';
8+
import 'package:monekin/core/extensions/lists.extensions.dart';
69
import 'package:monekin/core/models/category/category.dart';
710
import 'package:monekin/core/models/supported-icon/icon_displayer.dart';
811
import 'package:monekin/core/models/supported-icon/supported_icon.dart';
9-
import 'package:monekin/core/presentation/widgets/color_picker.dart';
10-
import 'package:monekin/core/presentation/widgets/icon_selector_modal.dart';
12+
import 'package:monekin/core/presentation/widgets/color_picker/color_picker.dart';
1113
import 'package:monekin/core/presentation/widgets/persistent_footer_button.dart';
12-
import 'package:monekin/core/services/supported_icon/supported_icon_service.dart';
13-
import 'package:monekin/core/utils/color_utils.dart';
1414
import 'package:monekin/core/utils/constants.dart';
1515
import 'package:monekin/core/utils/text_field_utils.dart';
16+
import 'package:monekin/core/utils/uuid.dart';
1617
import 'package:monekin/i18n/translations.g.dart';
17-
import 'package:uuid/uuid.dart';
1818

1919
class CategoryFormPage extends StatefulWidget {
2020
const CategoryFormPage({super.key, this.categoryUUID});
@@ -33,9 +33,8 @@ class _CategoryFormPageState extends State<CategoryFormPage> {
3333

3434
final TextEditingController _nameController = TextEditingController();
3535

36-
SupportedIcon _icon = SupportedIconService.instance.defaultSupportedIcon;
37-
38-
String _color = '000000';
36+
SupportedIcon _icon = Category.unkown().icon;
37+
String _color = defaultColorPickerOptions.randomItem();
3938
CategoryType _type = CategoryType.E;
4039

4140
@override
@@ -109,7 +108,7 @@ class _CategoryFormPageState extends State<CategoryFormPage> {
109108

110109
await CategoryService.instance
111110
.insertCategory(CategoryInDB(
112-
id: const Uuid().v4(),
111+
id: generateUUID(),
113112
name: _nameController.text,
114113
iconId: _icon.id,
115114
displayOrder: 10,
@@ -211,59 +210,45 @@ class _CategoryFormPageState extends State<CategoryFormPage> {
211210
crossAxisAlignment: CrossAxisAlignment.start,
212211
mainAxisSize: MainAxisSize.min,
213212
children: [
214-
Row(
215-
crossAxisAlignment: CrossAxisAlignment.start,
216-
children: [
217-
IconDisplayer(
218-
mainColor: ColorHex.get(_color).lighten(
219-
Theme.of(context).brightness ==
220-
Brightness.dark
221-
? 0.8
222-
: 0),
223-
secondaryColor: ColorHex.get(_color).lighten(
224-
Theme.of(context).brightness ==
225-
Brightness.dark
226-
? 0
227-
: 0.8),
228-
supportedIcon: _icon,
229-
size: 48,
230-
isOutline: true,
231-
outlineWidth: 1,
232-
padding: 6,
233-
borderRadius: 4,
234-
onTap: () {
235-
showIconSelectorModal(
236-
context,
237-
IconSelectorModal(
238-
preselectedIconID: _icon.id,
239-
subtitle: t
240-
.icon_selector.select_category_icon,
241-
onIconSelected: (selectedIcon) {
242-
setState(() {
243-
_icon = selectedIcon;
244-
});
245-
},
246-
),
247-
);
248-
},
213+
IconAndColorSelector(
214+
iconSelectorModalSubtitle:
215+
t.icon_selector.select_category_icon,
216+
iconDisplayer: IconDisplayer.fromCategory(
217+
context,
218+
category: Category.fromDB(
219+
Category.unkown().copyWith(
220+
iconId: _icon.id,
221+
color: drift.Value(_color)),
222+
null,
249223
),
250-
const SizedBox(width: 10),
251-
Expanded(
252-
child: TextFormField(
253-
controller: _nameController,
254-
maxLength: maxLabelLenghtForDisplayNames,
255-
decoration: InputDecoration(
256-
labelText: '${t.categories.name} *',
257-
hintText: 'Ex.: Food',
258-
),
259-
validator: (value) =>
260-
fieldValidator(value, isRequired: true),
261-
autovalidateMode:
262-
AutovalidateMode.onUserInteraction,
263-
textInputAction: TextInputAction.next,
264-
),
265-
)
266-
],
224+
isOutline: true,
225+
size: 48,
226+
padding: 6,
227+
),
228+
onDataChange: ((data) {
229+
setState(() {
230+
_icon = data.icon;
231+
_color = data.color.toHex();
232+
});
233+
}),
234+
data: (
235+
color: ColorHex.get(_color),
236+
icon: _icon,
237+
),
238+
),
239+
const SizedBox(height: 20),
240+
TextFormField(
241+
controller: _nameController,
242+
maxLength: maxLabelLenghtForDisplayNames,
243+
decoration: InputDecoration(
244+
labelText: '${t.categories.name} *',
245+
hintText: 'Ex.: Food',
246+
),
247+
validator: (value) =>
248+
fieldValidator(value, isRequired: true),
249+
autovalidateMode:
250+
AutovalidateMode.onUserInteraction,
251+
textInputAction: TextInputAction.next,
267252
),
268253
const SizedBox(height: 14),
269254
DropdownButtonFormField<CategoryType>(
@@ -293,22 +278,11 @@ class _CategoryFormPageState extends State<CategoryFormPage> {
293278
});
294279
},
295280
),
296-
const SizedBox(height: 24),
297-
Text(t.icon_selector.color)
281+
const SizedBox(height: 16),
298282
],
299283
),
300284
),
301285
),
302-
ColorPicker(
303-
colorOptions: colorOptions,
304-
selectedColor: _color,
305-
onColorSelected: (selectedColor) {
306-
setState(() {
307-
_color = selectedColor;
308-
});
309-
},
310-
),
311-
const SizedBox(height: 6),
312286
if (widget.categoryUUID != null) ...[
313287
Padding(
314288
padding: const EdgeInsets.symmetric(
@@ -415,7 +389,7 @@ class _CategoryFormPageState extends State<CategoryFormPage> {
415389
color: _color, onSubmit: (name, icon) {
416390
CategoryService.instance.insertCategory(
417391
CategoryInDB(
418-
id: const Uuid().v4(),
392+
id: generateUUID(),
419393
displayOrder: 10,
420394
name: name,
421395
iconId: icon.id,

0 commit comments

Comments
 (0)