• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wger-project / flutter / 14928647242

09 May 2025 12:12PM UTC coverage: 52.971% (-3.4%) from 56.402%
14928647242

Pull #813

github

rolandgeider
Recreate generated files
Pull Request #813: Improve error handling and logging

108 of 309 new or added lines in 14 files covered. (34.95%)

1 existing line in 1 file now uncovered.

5152 of 9726 relevant lines covered (52.97%)

1.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.43
/lib/widgets/weight/forms.dart
1
/*
2
 * This file is part of wger Workout Manager <https://github.com/wger-project>.
3
 * Copyright (C) 2020, 2021 wger Team
4
 *
5
 * wger Workout Manager is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU Affero General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * wger Workout Manager is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU Affero General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Affero General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18

19
import 'package:flutter/material.dart';
20
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
21
import 'package:provider/provider.dart';
22
import 'package:wger/helpers/consts.dart';
23
import 'package:wger/helpers/json.dart';
24
import 'package:wger/l10n/generated/app_localizations.dart';
25
import 'package:wger/models/body_weight/weight_entry.dart';
26
import 'package:wger/providers/body_weight.dart';
27

28
class WeightForm extends StatelessWidget {
29
  final _form = GlobalKey<FormState>();
30
  final dateController = TextEditingController();
31
  final weightController = TextEditingController();
32

33
  late final WeightEntry _weightEntry;
34

35
  WeightForm([WeightEntry? weightEntry]) {
2✔
36
    _weightEntry = weightEntry ?? WeightEntry(date: DateTime.now());
6✔
37
    weightController.text = _weightEntry.weight == 0 ? '' : _weightEntry.weight.toString();
13✔
38
    dateController.text = dateToYYYYMMDD(_weightEntry.date)!;
10✔
39
  }
40

41
  @override
2✔
42
  Widget build(BuildContext context) {
43
    return Form(
2✔
44
      key: _form,
2✔
45
      child: Column(
2✔
46
        children: [
2✔
47
          // Weight date
48
          TextFormField(
2✔
49
            key: const Key('dateInput'),
50
            // Stop keyboard from appearing
51
            readOnly: true,
52
            decoration: InputDecoration(
2✔
53
              labelText: AppLocalizations.of(context).date,
4✔
54
              suffixIcon: const Icon(
55
                Icons.calendar_today,
56
                key: Key('calendarIcon'),
57
              ),
58
            ),
59
            enableInteractiveSelection: false,
60
            controller: dateController,
2✔
61
            onTap: () async {
×
62
              final pickedDate = await showDatePicker(
×
63
                context: context,
64
                initialDate: _weightEntry.date,
×
65
                firstDate: DateTime(DateTime.now().year - 10),
×
66
                lastDate: DateTime.now(),
×
67
                selectableDayPredicate: (day) {
×
68
                  // Always allow the current initial date
69
                  if (day == _weightEntry.date) {
×
70
                    return true;
71
                  }
72

73
                  // if the date is known, don't allow it
74
                  return Provider.of<BodyWeightProvider>(context, listen: false).findByDate(day) ==
×
75
                      null;
76
                },
77
              );
78

79
              if (pickedDate != null) {
80
                dateController.text = dateToYYYYMMDD(pickedDate)!;
×
81
              }
82
            },
83
            onSaved: (newValue) {
×
84
              _weightEntry.date = DateTime.parse(newValue!);
×
85
            },
86
          ),
87

88
          // Weight
89
          TextFormField(
2✔
90
            key: const Key('weightInput'),
91
            decoration: InputDecoration(
2✔
92
              labelText: AppLocalizations.of(context).weight,
4✔
93
              prefix: Row(
2✔
94
                mainAxisSize: MainAxisSize.min,
95
                children: [
2✔
96
                  IconButton(
2✔
97
                    key: const Key('quickMinus'),
98
                    icon: const FaIcon(FontAwesomeIcons.circleMinus),
99
                    onPressed: () {
1✔
100
                      try {
101
                        final num newValue = num.parse(weightController.text) - 1;
4✔
102
                        weightController.text = newValue.toString();
3✔
103
                      } on FormatException {}
1✔
104
                    },
105
                  ),
106
                  IconButton(
2✔
107
                    key: const Key('quickMinusSmall'),
108
                    icon: const FaIcon(FontAwesomeIcons.minus),
109
                    onPressed: () {
1✔
110
                      try {
111
                        final num newValue = num.parse(weightController.text) - 0.1;
4✔
112
                        weightController.text = newValue.toStringAsFixed(1);
3✔
113
                      } on FormatException {}
1✔
114
                    },
115
                  ),
116
                ],
117
              ),
118
              suffix: Row(
2✔
119
                mainAxisSize: MainAxisSize.min,
120
                children: [
2✔
121
                  IconButton(
2✔
122
                    key: const Key('quickPlusSmall'),
123
                    icon: const FaIcon(FontAwesomeIcons.plus),
124
                    onPressed: () {
1✔
125
                      try {
126
                        final num newValue = num.parse(weightController.text) + 0.1;
4✔
127
                        weightController.text = newValue.toStringAsFixed(1);
3✔
128
                      } on FormatException {}
1✔
129
                    },
130
                  ),
131
                  IconButton(
2✔
132
                    key: const Key('quickPlus'),
133
                    icon: const FaIcon(FontAwesomeIcons.circlePlus),
134
                    onPressed: () {
1✔
135
                      try {
136
                        final num newValue = num.parse(weightController.text) + 1;
4✔
137
                        weightController.text = newValue.toString();
3✔
138
                      } on FormatException {}
1✔
139
                    },
140
                  ),
141
                ],
142
              ),
143
            ),
144
            controller: weightController,
2✔
145
            keyboardType: TextInputType.number,
146
            onSaved: (newValue) {
×
147
              _weightEntry.weight = double.parse(newValue!);
×
148
            },
149
            validator: (value) {
×
150
              if (value!.isEmpty) {
×
151
                return AppLocalizations.of(context).enterValue;
×
152
              }
153
              try {
154
                double.parse(value);
×
155
              } catch (error) {
156
                return AppLocalizations.of(context).enterValidNumber;
×
157
              }
158
              return null;
159
            },
160
          ),
161
          ElevatedButton(
2✔
162
            key: const Key(SUBMIT_BUTTON_KEY_NAME),
163
            child: Text(AppLocalizations.of(context).save),
6✔
164
            onPressed: () async {
×
165
              // Validate and save the current values to the weightEntry
166
              final isValid = _form.currentState!.validate();
×
167
              if (!isValid) {
168
                return;
169
              }
170
              _form.currentState!.save();
×
171

172
              // Save the entry on the server
NEW
173
              final provider = Provider.of<BodyWeightProvider>(context, listen: false);
×
NEW
174
              _weightEntry.id == null
×
NEW
175
                  ? await provider.addEntry(_weightEntry)
×
NEW
176
                  : await provider.editEntry(_weightEntry);
×
177

178
              if (context.mounted) {
×
179
                Navigator.of(context).pop();
×
180
              }
181
            },
182
          ),
183
        ],
184
      ),
185
    );
186
  }
187
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc