From d2f38228fb6229b7e64f8e03b42c7b459738bdd1 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Wed, 13 Aug 2025 20:45:58 +0200 Subject: [PATCH] Improvements in handling localized values in the UI --- lib/widgets/dashboard/calendar.dart | 13 +++++++------ lib/widgets/measurements/charts.dart | 9 +++++++-- lib/widgets/measurements/entries.dart | 5 +++-- lib/widgets/measurements/forms.dart | 17 ++++++++++++++--- lib/widgets/weight/weight_overview.dart | 4 +++- .../measurement_entries_screen_test.dart | 2 +- 6 files changed, 35 insertions(+), 15 deletions(-) diff --git a/lib/widgets/dashboard/calendar.dart b/lib/widgets/dashboard/calendar.dart index 2069d243..76621fad 100644 --- a/lib/widgets/dashboard/calendar.dart +++ b/lib/widgets/dashboard/calendar.dart @@ -17,6 +17,7 @@ */ import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:table_calendar/table_calendar.dart'; import 'package:wger/helpers/consts.dart'; @@ -85,9 +86,10 @@ class _DashboardCalendarWidgetState extends State } void loadEvents() async { + final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + // Process weight entries - final BodyWeightProvider weightProvider = - Provider.of(context, listen: false); + final weightProvider = context.read(); for (final entry in weightProvider.items) { final date = DateFormatLists.format(entry.date); @@ -96,12 +98,11 @@ class _DashboardCalendarWidgetState extends State } // Add events to lists - _events[date]!.add(Event(EventType.weight, '${entry.weight} kg')); + _events[date]!.add(Event(EventType.weight, '${numberFormat.format(entry.weight)} kg')); } // Process measurements - final MeasurementProvider measurementProvider = - Provider.of(context, listen: false); + final measurementProvider = context.read(); for (final category in measurementProvider.categories) { for (final entry in category.entries) { final date = DateFormatLists.format(entry.date); @@ -112,7 +113,7 @@ class _DashboardCalendarWidgetState extends State _events[date]!.add(Event( EventType.measurement, - '${category.name}: ${entry.value} ${category.unit}', + '${category.name}: ${numberFormat.format(entry.value)} ${category.unit}', )); } } diff --git a/lib/widgets/measurements/charts.dart b/lib/widgets/measurements/charts.dart index 62ee1d4a..704c3da6 100644 --- a/lib/widgets/measurements/charts.dart +++ b/lib/widgets/measurements/charts.dart @@ -78,13 +78,16 @@ class _MeasurementChartWidgetFlState extends State { touchTooltipData: LineTouchTooltipData( getTooltipColor: (touchedSpot) => Theme.of(context).colorScheme.primaryContainer, getTooltipItems: (touchedSpots) { + final numberFormat = + NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + return touchedSpots.map((touchedSpot) { final DateTime date = DateTime.fromMillisecondsSinceEpoch(touchedSpot.x.toInt()); final dateStr = DateFormat.Md(Localizations.localeOf(context).languageCode).format(date); return LineTooltipItem( - '$dateStr: ${touchedSpot.y.toStringAsFixed(1)} ${widget._unit}', + '$dateStr: ${numberFormat.format(touchedSpot.y)} ${widget._unit}', TextStyle(color: touchedSpot.bar.color), ); }).toList(); @@ -94,6 +97,8 @@ class _MeasurementChartWidgetFlState extends State { } LineChartData mainData() { + final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + return LineChartData( lineTouchData: tooltipData(), gridData: FlGridData( @@ -158,7 +163,7 @@ class _MeasurementChartWidgetFlState extends State { return const Text(''); } - return Text('${value.toStringAsFixed(1)} ${widget._unit}'); + return Text('${numberFormat.format(value)} ${widget._unit}'); }, ), ), diff --git a/lib/widgets/measurements/entries.dart b/lib/widgets/measurements/entries.dart index 2efa8858..8fe2e3a8 100644 --- a/lib/widgets/measurements/entries.dart +++ b/lib/widgets/measurements/entries.dart @@ -37,6 +37,8 @@ class EntriesList extends StatelessWidget { @override Widget build(BuildContext context) { final plan = Provider.of(context, listen: false).currentPlan; + final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + final provider = Provider.of(context, listen: false); final entriesAll = _category.entries.map((e) => MeasurementChartEntry(e.value, e.date)).toList(); @@ -58,11 +60,10 @@ class EntriesList extends StatelessWidget { itemCount: _category.entries.length, itemBuilder: (context, index) { final currentEntry = _category.entries[index]; - final provider = Provider.of(context, listen: false); return Card( child: ListTile( - title: Text('${currentEntry.value} ${_category.unit}'), + title: Text('${numberFormat.format(currentEntry.value)} ${_category.unit}'), subtitle: Text( DateFormat.yMd(Localizations.localeOf(context).languageCode) .format(currentEntry.date), diff --git a/lib/widgets/measurements/forms.dart b/lib/widgets/measurements/forms.dart index d82759fa..e547dc2d 100644 --- a/lib/widgets/measurements/forms.dart +++ b/lib/widgets/measurements/forms.dart @@ -159,7 +159,7 @@ class MeasurementEntryForm extends StatelessWidget { } _dateController.text = dateToYYYYMMDD(_entryData['date'])!; - _valueController.text = _entryData['value']!.toString(); + _valueController.text = ''; _notesController.text = _entryData['notes']!; } @@ -172,12 +172,23 @@ class MeasurementEntryForm extends StatelessWidget { final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); + // If the value is not empty, format it + if (_valueController.text.isEmpty && _entryData['value'] != null && _entryData['value'] != '') { + _valueController.text = numberFormat.format(_entryData['value']); + } + return Form( key: _form, child: Column( children: [ TextFormField( - decoration: InputDecoration(labelText: AppLocalizations.of(context).date), + decoration: InputDecoration( + labelText: AppLocalizations.of(context).date, + suffixIcon: const Icon( + Icons.calendar_today, + key: Key('calendarIcon'), + ), + ), readOnly: true, // Hide text cursor controller: _dateController, @@ -202,7 +213,7 @@ class MeasurementEntryForm extends StatelessWidget { }, ); - _dateController.text = dateToYYYYMMDD(pickedDate)!; + _dateController.text = pickedDate == null ? '' : dateToYYYYMMDD(pickedDate)!; }, onSaved: (newValue) { _entryData['date'] = DateTime.parse(newValue!); diff --git a/lib/widgets/weight/weight_overview.dart b/lib/widgets/weight/weight_overview.dart index 9d47d9ae..a60e04b5 100644 --- a/lib/widgets/weight/weight_overview.dart +++ b/lib/widgets/weight/weight_overview.dart @@ -37,6 +37,7 @@ class WeightOverview extends StatelessWidget { @override Widget build(BuildContext context) { final profile = context.read().profile; + final numberFormat = NumberFormat.decimalPattern(Localizations.localeOf(context).toString()); final plan = Provider.of(context, listen: false).currentPlan; final entriesAll = _provider.items.map((e) => MeasurementChartEntry(e.weight, e.date)).toList(); @@ -78,7 +79,8 @@ class WeightOverview extends StatelessWidget { final currentEntry = _provider.items[index]; return Card( child: ListTile( - title: Text('${currentEntry.weight} ${weightUnit(profile.isMetric, context)}'), + title: Text( + '${numberFormat.format(currentEntry.weight)} ${weightUnit(profile.isMetric, context)}'), subtitle: Text( DateFormat.yMd( Localizations.localeOf(context).languageCode, diff --git a/test/measurements/measurement_entries_screen_test.dart b/test/measurements/measurement_entries_screen_test.dart index 85862dd5..5a1cb3ae 100644 --- a/test/measurements/measurement_entries_screen_test.dart +++ b/test/measurements/measurement_entries_screen_test.dart @@ -82,7 +82,7 @@ void main() { expect(find.text('body fat'), findsOneWidget); // Entries - expect(find.text('15.0 %'), findsNWidgets(1)); + expect(find.text('15 %'), findsNWidgets(1)); }); testWidgets('Tests the localization of dates - EN', (WidgetTester tester) async {