@@ -3,9 +3,9 @@ import 'package:flutter/material.dart';
3
3
import 'package:provider/provider.dart' ;
4
4
5
5
class BadgeScanSettingsWidget extends StatefulWidget {
6
- final Function (BadgeScanMode mode, List <String > names) onSave;
6
+ final Function (BadgeScanMode mode, List <String > names)? onSave;
7
7
8
- const BadgeScanSettingsWidget ({super .key, required this .onSave});
8
+ const BadgeScanSettingsWidget ({super .key, this .onSave});
9
9
10
10
@override
11
11
State <BadgeScanSettingsWidget > createState () =>
@@ -21,9 +21,6 @@ class _BadgeScanSettingsWidgetState extends State<BadgeScanSettingsWidget> {
21
21
super .initState ();
22
22
final provider = Provider .of <BadgeScanProvider >(context, listen: false );
23
23
_mode = provider.mode;
24
- for (var name in provider.badgeNames) {
25
- _controllers.add (TextEditingController (text: name));
26
- }
27
24
}
28
25
29
26
void _addBadgeName () {
@@ -38,7 +35,7 @@ class _BadgeScanSettingsWidgetState extends State<BadgeScanSettingsWidget> {
38
35
});
39
36
}
40
37
41
- void _onSave () {
38
+ Future < void > _onSave () async {
42
39
final updatedNames = _controllers
43
40
.map ((c) => c.text.trim ())
44
41
.where ((name) => name.isNotEmpty)
@@ -52,82 +49,98 @@ class _BadgeScanSettingsWidgetState extends State<BadgeScanSettingsWidget> {
52
49
const SnackBar (content: Text ('Scan settings saved successfully' )),
53
50
);
54
51
55
- widget.onSave (_mode, updatedNames);
56
- Navigator .pop (context);
57
- }
58
-
59
- @override
60
- void dispose () {
61
- for (var c in _controllers) {
62
- c.dispose ();
63
- }
64
- super .dispose ();
52
+ widget.onSave? .call (_mode, updatedNames);
53
+ if (mounted) Navigator .pop (context);
65
54
}
66
55
67
56
@override
68
57
Widget build (BuildContext context) {
69
- return Scaffold (
70
- appBar: AppBar (
71
- title: const Text ('Badge Scan Settings' ),
72
- actions: [
73
- IconButton (
74
- icon: const Icon (Icons .save),
75
- onPressed: _onSave,
76
- ),
77
- ],
78
- ),
79
- body: Column (
80
- children: [
81
- RadioListTile <BadgeScanMode >(
82
- title: const Text ('Connect to any badge' ),
83
- value: BadgeScanMode .any,
84
- groupValue: _mode,
85
- onChanged: (val) => setState (() => _mode = val! ),
86
- ),
87
- RadioListTile <BadgeScanMode >(
88
- title: const Text ('Connect to badges with the following names' ),
89
- value: BadgeScanMode .specific,
90
- groupValue: _mode,
91
- onChanged: (val) => setState (() => _mode = val! ),
58
+ return Consumer <BadgeScanProvider >(
59
+ builder: (context, provider, child) {
60
+ if (! provider.isLoaded) {
61
+ return const Scaffold (
62
+ body: Center (child: CircularProgressIndicator ()),
63
+ );
64
+ }
65
+
66
+ if (_controllers.isEmpty) {
67
+ // Initialize controllers only after provider is loaded
68
+ for (var name in provider.badgeNames) {
69
+ _controllers.add (TextEditingController (text: name));
70
+ }
71
+ }
72
+
73
+ return Scaffold (
74
+ appBar: AppBar (
75
+ title: const Text ('Badge Scan Settings' ),
76
+ actions: [
77
+ IconButton (
78
+ icon: const Icon (Icons .save),
79
+ onPressed: _onSave,
80
+ ),
81
+ ],
92
82
),
93
- if (_mode == BadgeScanMode .specific)
94
- Expanded (
95
- child: ListView .builder (
96
- itemCount: _controllers.length,
97
- itemBuilder: (context, index) {
98
- return Row (
99
- children: [
100
- Expanded (
101
- child: Padding (
102
- padding: const EdgeInsets .symmetric (horizontal: 12.0 ),
103
- child: TextField (
104
- controller: _controllers[index],
105
- decoration: const InputDecoration (
106
- labelText: 'Badge Name' ,
107
- ),
108
- ),
109
- ),
110
- ),
111
- IconButton (
112
- icon: const Icon (Icons .remove_circle_outline),
113
- onPressed: () => _removeBadgeName (index),
114
- ),
115
- ],
116
- );
117
- },
83
+ body: Column (
84
+ children: [
85
+ RadioListTile <BadgeScanMode >(
86
+ title: const Text ('Connect to any badge' ),
87
+ value: BadgeScanMode .any,
88
+ groupValue: _mode,
89
+ onChanged: (val) => setState (() => _mode = val! ),
118
90
),
119
- ),
120
- if (_mode == BadgeScanMode .specific)
121
- Padding (
122
- padding: const EdgeInsets .all (12.0 ),
123
- child: ElevatedButton .icon (
124
- onPressed: _addBadgeName,
125
- icon: const Icon (Icons .add),
126
- label: const Text ("Add more" ),
91
+ RadioListTile <BadgeScanMode >(
92
+ title: const Text ('Connect to badges with the following names' ),
93
+ value: BadgeScanMode .specific,
94
+ groupValue: _mode,
95
+ onChanged: (val) => setState (() => _mode = val! ),
127
96
),
128
- ),
129
- ],
130
- ),
97
+ if (_mode == BadgeScanMode .specific)
98
+ Expanded (
99
+ child: ListView .builder (
100
+ itemCount: _controllers.length,
101
+ itemBuilder: (context, index) {
102
+ return Row (
103
+ children: [
104
+ Expanded (
105
+ child: Padding (
106
+ padding:
107
+ const EdgeInsets .symmetric (horizontal: 12.0 ),
108
+ child: TextField (
109
+ controller: _controllers[index],
110
+ decoration: const InputDecoration (
111
+ labelText: 'Badge Name' ,
112
+ ),
113
+ ),
114
+ ),
115
+ ),
116
+ IconButton (
117
+ icon: const Icon (Icons .remove_circle_outline),
118
+ onPressed: () => _removeBadgeName (index),
119
+ ),
120
+ ],
121
+ );
122
+ },
123
+ ),
124
+ ),
125
+ if (_mode == BadgeScanMode .specific)
126
+ Padding (
127
+ padding: const EdgeInsets .all (12.0 ),
128
+ child: ElevatedButton .icon (
129
+ onPressed: _addBadgeName,
130
+ icon: const Icon (Icons .add),
131
+ label: const Text ("Add more" ),
132
+ ),
133
+ ),
134
+ ],
135
+ ),
136
+ );
137
+ },
131
138
);
132
139
}
140
+
141
+ @override
142
+ void dispose () {
143
+ for (var c in _controllers) c.dispose ();
144
+ super .dispose ();
145
+ }
133
146
}
0 commit comments