Skip to content

Commit 3e32b55

Browse files
committed
Block editing appropiate item editor's field, when a filter is active.
1 parent 42ec450 commit 3e32b55

File tree

16 files changed

+236
-107
lines changed

16 files changed

+236
-107
lines changed

assets/defaults/countries.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
[
2+
{
3+
"code": "none",
4+
"name": {
5+
"pl": "Brak",
6+
"en": "None",
7+
"cs": "Žádný"
8+
}
9+
},
210
{
311
"code": "AF",
412
"name": {
910 Bytes
Loading

lib/main.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import 'package:sj_manager/repositories/country_flags.dart/local_storage_country
1616
import 'package:sj_manager/repositories/database_editing/default_items_repository.dart';
1717
import 'package:sj_manager/setup/set_up_app.dart';
1818
import 'package:sj_manager/ui/app.dart';
19-
import 'package:sj_manager/ui/app_initializer.dart';
2019
import 'package:sj_manager/ui/providers/locale_notifier.dart';
2120
import 'package:sj_manager/ui/reusable_widgets/database_item_images/hill_image/hill_image_generating_setup.dart';
2221
import 'package:sj_manager/ui/reusable_widgets/database_item_images/jumper_image/jumper_image_generating_setup.dart';

lib/models/country.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
// ignore_for_file: public_member_api_docs, sort_constructors_first
12
import 'package:json_annotation/json_annotation.dart';
3+
24
import 'package:sj_manager/json/json_types.dart';
35

46
part 'country.g.dart';
@@ -25,4 +27,14 @@ class Country {
2527
String toString() {
2628
return '$name ($code)';
2729
}
30+
31+
Country copyWith({
32+
String? code,
33+
String? name,
34+
}) {
35+
return Country(
36+
code: code ?? this.code,
37+
name: name ?? this.name,
38+
);
39+
}
2840
}

lib/repositories/country_flags.dart/local_storage_country_flags_repo.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ class LocalStorageCountryFlagsRepo implements CountryFlagsRepo {
2121
return _cache[country]!;
2222
} else {
2323
final path = '${imagesDirectory.path}/${country.code}.$imagesExtension';
24-
final imageData = FileImage(File(path));
24+
var file = File(path);
25+
if (!file.existsSync()) {
26+
file = File('${imagesDirectory.path}/none.$imagesExtension');
27+
}
28+
final imageData = FileImage(file);
2529
_cache[country] = imageData;
2630
return imageData;
2731
}

lib/setup/set_up_app.dart

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:io';
2+
13
import 'package:flutter/material.dart';
24
import 'package:flutter/services.dart';
35
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -7,12 +9,10 @@ import 'package:sj_manager/models/country.dart';
79
import 'package:sj_manager/models/hill/hill.dart';
810
import 'package:sj_manager/models/jumper/jumper.dart';
911
import 'package:sj_manager/repositories/countries/countries_repo.dart';
10-
import 'package:sj_manager/repositories/country_flags.dart/local_storage_country_flags_repo.dart';
1112
import 'package:sj_manager/repositories/database_editing/db_io_parameters_repo.dart';
1213
import 'package:sj_manager/repositories/database_editing/db_items_repository.dart';
1314
import 'package:sj_manager/ui/dialogs/loading_items_failed_dialog.dart';
1415
import 'package:sj_manager/ui/navigation/routes.dart';
15-
import 'package:sj_manager/utils/context_maybe_read.dart';
1616
import 'package:sj_manager/utils/file_system.dart';
1717

1818
class AppConfigurator {
@@ -57,15 +57,15 @@ class AppConfigurator {
5757
}
5858
if (!_context.mounted) return;
5959

60-
final flagsDir = _context.maybeRead<LocalStorageCountryFlagsRepo>()?.imagesDirectory;
61-
if (flagsDir != null) {
62-
if (!await flagsDir.exists()) {
63-
await copyAssetsDir('defaults/country_flags', flagsDir);
64-
}
60+
final flagsDir = userDataDirectory(_context.read(), 'countries/country_flags');
61+
if (!await flagsDir.exists()) {
62+
await copyAssetsDir('defaults/country_flags', flagsDir);
6563
}
6664
}
6765

6866
Future<void> loadDatabase() async {
67+
if (!_context.mounted) return;
68+
final file = _context.read<DbIoParametersRepo<Country>>().storageFile;
6969
try {
7070
await _loadCountries();
7171
} catch (e) {
@@ -74,49 +74,33 @@ class AppConfigurator {
7474
context: _context,
7575
builder: (context) => LoadingItemsFailedDialog(
7676
titleText: 'Błąd wczytywania krajów',
77-
filePath: context.read<DbIoParametersRepo<Country>>().storageFile.path,
78-
error: e,
79-
),
80-
);
81-
}
82-
83-
try {
84-
await _loadItems<MaleJumper>();
85-
} catch (e) {
86-
if (!_context.mounted) return;
87-
await showDialog(
88-
context: _context,
89-
builder: (context) => LoadingItemsFailedDialog(
90-
titleText: 'Błąd wczytywania skoczków',
91-
filePath: context.read<DbIoParametersRepo<MaleJumper>>().storageFile.path,
77+
filePath: file.path,
9278
error: e,
9379
),
9480
);
9581
}
9682

97-
try {
98-
await _loadItems<FemaleJumper>();
99-
} catch (e) {
100-
if (!_context.mounted) return;
101-
await showDialog(
102-
context: _context,
103-
builder: (context) => LoadingItemsFailedDialog(
104-
titleText: 'Błąd wczytywania skoczkiń',
105-
filePath: context.read<DbIoParametersRepo<FemaleJumper>>().storageFile.path,
106-
error: e,
107-
),
108-
);
109-
}
83+
await _tryLoadItems<MaleJumper>(dialogTitleText: 'Błąd wczytywania skoczków');
84+
await _tryLoadItems<FemaleJumper>(dialogTitleText: 'Błąd wczytywania skoczkiń');
85+
await _tryLoadItems<Hill>(dialogTitleText: 'Błąd wczytywania skoczni');
86+
}
11087

88+
Future<void> _tryLoadItems<T>({required String dialogTitleText}) async {
89+
if (!_context.mounted) return;
90+
final file = _context.read<DbIoParametersRepo<T>>().storageFile;
11191
try {
112-
await _loadItems<Hill>();
92+
await _loadItems<T>();
93+
} on PathNotFoundException {
94+
file.createSync();
95+
file.writeAsStringSync('[]');
11396
} catch (e) {
11497
if (!_context.mounted) return;
11598
await showDialog(
99+
barrierDismissible: false,
116100
context: _context,
117101
builder: (context) => LoadingItemsFailedDialog(
118-
titleText: 'Błąd wczytywania skoczni',
119-
filePath: context.read<DbIoParametersRepo<Hill>>().storageFile.path,
102+
titleText: dialogTitleText,
103+
filePath: file.path,
120104
error: e,
121105
),
122106
);
@@ -130,7 +114,8 @@ class AppConfigurator {
130114
fromJson: parameters.fromJson,
131115
);
132116
if (!_context.mounted) return;
133-
_context.read<CountriesRepo>().setCountries(countries);
117+
_context.read<CountriesRepo>().setCountries(
118+
countries.map((c) => c.copyWith(code: c.code.toLowerCase())).toList());
134119
}
135120

136121
Future<void> _loadItems<T>() async {

lib/ui/database_item_editors/fields/my_dropdown_field.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ class MyDropdownField<T> extends StatelessWidget {
1111
this.leadingIcon,
1212
this.trailingIcon,
1313
this.label,
14-
this.focusNode,
14+
this.enableSearch,
15+
this.enabled,
1516
});
1617

1718
final TextEditingController? controller;
@@ -22,11 +23,16 @@ class MyDropdownField<T> extends StatelessWidget {
2223
final Widget? label;
2324
final Widget? leadingIcon;
2425
final Widget? trailingIcon;
25-
final FocusNode? focusNode;
26+
final bool? enableSearch;
27+
final bool? enabled;
2628

2729
@override
2830
Widget build(BuildContext context) {
31+
print('dropdown build');
2932
return DropdownMenu<T>(
33+
enabled: enabled ?? true,
34+
enableSearch: enableSearch ?? true,
35+
requestFocusOnTap: false,
3036
width: width,
3137
controller: controller,
3238
initialSelection: initial,

lib/ui/database_item_editors/fields/my_numeral_text_field.dart

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:sj_manager/utils/math.dart';
88
class MyNumeralTextField extends StatelessWidget {
99
const MyNumeralTextField({
1010
super.key,
11+
this.enabled = true,
1112
required this.controller,
1213
this.buttons,
1314
required this.onChange,
@@ -21,6 +22,7 @@ class MyNumeralTextField extends StatelessWidget {
2122
this.maxDecimalPlaces,
2223
});
2324

25+
final bool enabled;
2426
final VoidCallback onChange;
2527
final TextEditingController controller;
2628
final List<TextInputFormatter> formatters;
@@ -40,6 +42,7 @@ class MyNumeralTextField extends StatelessWidget {
4042
children: [
4143
Expanded(
4244
child: TextField(
45+
enabled: enabled,
4346
controller: controller,
4447
decoration: InputDecoration(
4548
label: Text(labelText),
@@ -59,33 +62,37 @@ class MyNumeralTextField extends StatelessWidget {
5962
),
6063
...buttons ?? [],
6164
IconButton(
62-
onPressed: () {
63-
var decremented = _numberFromController - step;
64-
if (maxDecimalPlaces != null) {
65-
decremented = preparedNumber(decremented.toDouble());
66-
}
67-
controller.text = _numberInRangeEnforcer
68-
.formatEditUpdate(controller.value,
69-
controller.value.copyWith(text: decremented.toString()))
70-
.text;
71-
onChange();
72-
},
65+
onPressed: enabled
66+
? () {
67+
var decremented = _numberFromController - step;
68+
if (maxDecimalPlaces != null) {
69+
decremented = preparedNumber(decremented.toDouble());
70+
}
71+
controller.text = _numberInRangeEnforcer
72+
.formatEditUpdate(controller.value,
73+
controller.value.copyWith(text: decremented.toString()))
74+
.text;
75+
onChange();
76+
}
77+
: null,
7378
icon: const Icon(
7479
Symbols.remove,
7580
),
7681
),
7782
IconButton(
78-
onPressed: () {
79-
var incremented = _numberFromController + step;
80-
if (maxDecimalPlaces != null) {
81-
incremented = preparedNumber(incremented.toDouble());
82-
}
83-
controller.text = _numberInRangeEnforcer
84-
.formatEditUpdate(controller.value,
85-
controller.value.copyWith(text: incremented.toString()))
86-
.text;
87-
onChange();
88-
},
83+
onPressed: enabled
84+
? () {
85+
var incremented = _numberFromController + step;
86+
if (maxDecimalPlaces != null) {
87+
incremented = preparedNumber(incremented.toDouble());
88+
}
89+
controller.text = _numberInRangeEnforcer
90+
.formatEditUpdate(controller.value,
91+
controller.value.copyWith(text: incremented.toString()))
92+
.text;
93+
onChange();
94+
}
95+
: null,
8996
icon: const Icon(Symbols.add),
9097
),
9198
],

lib/ui/database_item_editors/fields/my_text_field.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ class MyTextField extends StatelessWidget {
99
this.formatters,
1010
required this.labelText,
1111
this.focusNode,
12+
this.enabled = true,
1213
});
1314

15+
final bool enabled;
1416
final VoidCallback onChange;
1517
final TextEditingController controller;
1618
final List<TextInputFormatter>? formatters;
@@ -20,6 +22,7 @@ class MyTextField extends StatelessWidget {
2022
@override
2123
Widget build(BuildContext context) {
2224
return TextField(
25+
enabled: enabled,
2326
controller: controller,
2427
decoration: InputDecoration(
2528
label: Text(labelText),

lib/ui/database_item_editors/hill_editor.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,17 @@ class HillEditor extends StatefulWidget {
2929
const HillEditor({
3030
super.key,
3131
required this.onChange,
32+
this.enableEditingDimensions = true,
33+
this.enableEditingLocality = true,
34+
this.enableEditingName = true,
35+
this.enableEditingCountry = true,
3236
});
3337

3438
final Function(Hill? current) onChange;
39+
final bool enableEditingDimensions;
40+
final bool enableEditingLocality;
41+
final bool enableEditingName;
42+
final bool enableEditingCountry;
3543

3644
@override
3745
State<HillEditor> createState() => HillEditorState();
@@ -130,6 +138,7 @@ class HillEditorState extends State<HillEditor> {
130138
children: [
131139
MyTextField(
132140
key: const Key('name'),
141+
enabled: widget.enableEditingName,
133142
focusNode: _firstFocusNode,
134143
controller: _nameController,
135144
onChange: () {
@@ -140,6 +149,7 @@ class HillEditorState extends State<HillEditor> {
140149
gap,
141150
MyTextField(
142151
key: const Key('locality'),
152+
enabled: widget.enableEditingLocality,
143153
controller: _localityController,
144154
onChange: () {
145155
widget.onChange(_constructAndCacheHill());
@@ -151,6 +161,7 @@ class HillEditorState extends State<HillEditor> {
151161
),
152162
gap,
153163
CountriesDropdown(
164+
enabled: widget.enableEditingCountry,
154165
key: _countriesDropdownKey,
155166
countriesApi: RepositoryProvider.of<CountriesRepo>(context),
156167
onSelected: (maybeCountry) {
@@ -184,6 +195,7 @@ class HillEditorState extends State<HillEditor> {
184195
),
185196
MyNumeralTextField(
186197
key: const Key('k'),
198+
enabled: widget.enableEditingDimensions,
187199
controller: _kController,
188200
onChange: () {
189201
widget.onChange(_constructAndCacheHill());
@@ -197,6 +209,7 @@ class HillEditorState extends State<HillEditor> {
197209
gap,
198210
MyNumeralTextField(
199211
key: const Key('hs'),
212+
enabled: widget.enableEditingDimensions,
200213
controller: _hsController,
201214
onChange: () {
202215
widget.onChange(_constructAndCacheHill());

0 commit comments

Comments
 (0)