diff --git a/lib/model/entry/extensions/metadata_edition.dart b/lib/model/entry/extensions/metadata_edition.dart index 29d1d447d..1a75e9fd3 100644 --- a/lib/model/entry/extensions/metadata_edition.dart +++ b/lib/model/entry/extensions/metadata_edition.dart @@ -23,6 +23,9 @@ import 'package:latlong2/latlong.dart'; import 'package:xml/xml.dart'; extension ExtraAvesEntryMetadataEdition on AvesEntry { + static final _iso6709LatitudeFormatter = NumberFormat('00.0000', asciiLocale); + static final _iso6709LongitudeFormatter = NumberFormat('000.0000', asciiLocale); + Future> editDate(DateModifier userModifier) async { final dataTypes = {}; @@ -122,9 +125,8 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry { if (latLng != null && latLng != removalLocation) { final latitude = latLng.latitude; final longitude = latLng.longitude; - const locale = asciiLocale; - final isoLat = '${latitude >= 0 ? '+' : '-'}${NumberFormat('00.0000', locale).format(latitude.abs())}'; - final isoLon = '${longitude >= 0 ? '+' : '-'}${NumberFormat('000.0000', locale).format(longitude.abs())}'; + final isoLat = '${latitude >= 0 ? '+' : '-'}${_iso6709LatitudeFormatter.format(latitude.abs())}'; + final isoLon = '${longitude >= 0 ? '+' : '-'}${_iso6709LongitudeFormatter.format(longitude.abs())}'; iso6709String = '$isoLat$isoLon/'; } mp4Fields[MetadataField.mp4GpsCoordinates] = iso6709String; diff --git a/lib/model/entry/extensions/props.dart b/lib/model/entry/extensions/props.dart index b231b5616..88d8b5b1a 100644 --- a/lib/model/entry/extensions/props.dart +++ b/lib/model/entry/extensions/props.dart @@ -53,9 +53,9 @@ extension ExtraAvesEntryProps on AvesEntry { // text String getResolutionText(String locale) { - final numberFormat = NumberFormat('0', locale); - final ws = numberFormat.format(width); - final hs = numberFormat.format(height); + final dimensionFormatter = NumberFormat('0', locale); + final ws = dimensionFormatter.format(width); + final hs = dimensionFormatter.format(height); return isRotated ? '$hs${AText.resolutionSeparator}$ws' : '$ws${AText.resolutionSeparator}$hs'; } diff --git a/lib/model/filters/date.dart b/lib/model/filters/date.dart index 4749fcd4d..3e5f1560f 100644 --- a/lib/model/filters/date.dart +++ b/lib/model/filters/date.dart @@ -100,8 +100,7 @@ class DateFilter extends CollectionFilter { @override String getLabel(BuildContext context) { - final l10n = context.l10n; - final locale = l10n.localeName; + final locale = context.locale; switch (level) { case DateLevel.y: return DateFormat.y(locale).format(_effectiveDate); @@ -113,7 +112,7 @@ class DateFilter extends CollectionFilter { if (date != null) { return DateFormat.MMMd(locale).format(_effectiveDate); } else { - return l10n.filterOnThisDayLabel; + return context.l10n.filterOnThisDayLabel; } case DateLevel.m: return DateFormat.MMMM(locale).format(_effectiveDate); diff --git a/lib/model/settings/enums/coordinate_format.dart b/lib/model/settings/enums/coordinate_format.dart index cf90b4936..bf3a5b6ec 100644 --- a/lib/model/settings/enums/coordinate_format.dart +++ b/lib/model/settings/enums/coordinate_format.dart @@ -55,11 +55,10 @@ extension ExtraCoordinateFormat on CoordinateFormat { } static List _toDecimal(AppLocalizations l10n, LatLng latLng) { - final locale = l10n.localeName; - final formatter = NumberFormat('0.000000°', locale); + final coordinateFormatter = NumberFormat('0.000000°', l10n.localeName); return [ - formatter.format(latLng.latitude), - formatter.format(latLng.longitude), + coordinateFormatter.format(latLng.latitude), + coordinateFormatter.format(latLng.longitude), ]; } } diff --git a/lib/utils/file_utils.dart b/lib/utils/file_utils.dart index 5ed77aaf5..4f3f0b745 100644 --- a/lib/utils/file_utils.dart +++ b/lib/utils/file_utils.dart @@ -8,9 +8,9 @@ const tera = giga * kilo; String formatFileSize(String locale, int size, {int round = 2}) { if (size < kilo) return '$size B'; - final formatter = NumberFormat('0${round > 0 ? '.${'0' * round}' : ''}', locale); - if (size < mega) return '${formatter.format(size / kilo)} KB'; - if (size < giga) return '${formatter.format(size / mega)} MB'; - if (size < tera) return '${formatter.format(size / giga)} GB'; - return '${formatter.format(size / tera)} TB'; + final compactFormatter = NumberFormat('0${round > 0 ? '.${'0' * round}' : ''}', locale); + if (size < mega) return '${compactFormatter.format(size / kilo)} KB'; + if (size < giga) return '${compactFormatter.format(size / mega)} MB'; + if (size < tera) return '${compactFormatter.format(size / giga)} GB'; + return '${compactFormatter.format(size / tera)} TB'; } diff --git a/lib/widgets/about/app_ref.dart b/lib/widgets/about/app_ref.dart index 8e7c2fb1c..8443d1597 100644 --- a/lib/widgets/about/app_ref.dart +++ b/lib/widgets/about/app_ref.dart @@ -31,7 +31,7 @@ class AppReference extends StatelessWidget { } Widget _buildAvesLine(BuildContext context) { - final locale = context.l10n.localeName; + final locale = context.locale; final textScaler = MediaQuery.textScalerOf(context); return Row( mainAxisSize: MainAxisSize.min, diff --git a/lib/widgets/about/bug_report.dart b/lib/widgets/about/bug_report.dart index bda875f29..cb5dd48ff 100644 --- a/lib/widgets/about/bug_report.dart +++ b/lib/widgets/about/bug_report.dart @@ -122,9 +122,6 @@ class _BugReportState extends State with FeedbackMixin { } Widget _buildStep(int step, String text, String buttonText, VoidCallback onPressed) { - final locale = context.l10n.localeName; - final numberFormat = NumberFormat.decimalPattern(locale); - final isMonochrome = settings.themeColorMode == AvesThemeColorMode.monochrome; return Padding( padding: const EdgeInsets.symmetric(vertical: 4), @@ -139,7 +136,7 @@ class _BugReportState extends State with FeedbackMixin { )), shape: BoxShape.circle, ), - child: Text(numberFormat.format(step)), + child: Text(NumberFormat('0', context.locale).format(step)), ), const SizedBox(width: 8), Expanded(child: Text(text)), diff --git a/lib/widgets/about/data_usage.dart b/lib/widgets/about/data_usage.dart index b811a28f5..39a523762 100644 --- a/lib/widgets/about/data_usage.dart +++ b/lib/widgets/about/data_usage.dart @@ -137,7 +137,7 @@ class DataUsageDonut extends StatelessWidget { @override Widget build(BuildContext context) { final l10n = context.l10n; - final locale = l10n.localeName; + final locale = context.locale; return AvesDonut( title: Text(title), diff --git a/lib/widgets/collection/collection_grid.dart b/lib/widgets/collection/collection_grid.dart index 02c2c11f5..08832097a 100644 --- a/lib/widgets/collection/collection_grid.dart +++ b/lib/widgets/collection/collection_grid.dart @@ -673,7 +673,7 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> with Widge final newest = firstKey.date; final oldest = lastKey.date; if (newest != null && oldest != null) { - final locale = context.l10n.localeName; + final locale = context.locale; final dateFormat = (newest.difference(oldest).inHumanDays).abs() > 365 ? DateFormat.y(locale) : DateFormat.MMM(locale); String? lastLabel; sectionLayouts.forEach((section) { diff --git a/lib/widgets/collection/draggable_thumb_label.dart b/lib/widgets/collection/draggable_thumb_label.dart index 5dc38ace4..a48a6dadb 100644 --- a/lib/widgets/collection/draggable_thumb_label.dart +++ b/lib/widgets/collection/draggable_thumb_label.dart @@ -55,7 +55,7 @@ class CollectionDraggableThumbLabel extends StatelessWidget { ]; case EntrySortFactor.size: return [ - if (entry.sizeBytes != null) formatFileSize(context.l10n.localeName, entry.sizeBytes!, round: 0), + if (entry.sizeBytes != null) formatFileSize(context.locale, entry.sizeBytes!, round: 0), ]; } }, diff --git a/lib/widgets/collection/grid/headers/date.dart b/lib/widgets/collection/grid/headers/date.dart index a772a0712..2dd51383b 100644 --- a/lib/widgets/collection/grid/headers/date.dart +++ b/lib/widgets/collection/grid/headers/date.dart @@ -40,7 +40,8 @@ class DaySectionHeader extends StatelessWidget { if (date == null) return l10n.sectionUnknown; if (date.isToday) return l10n.dateToday; if (date.isYesterday) return l10n.dateYesterday; - final locale = l10n.localeName; + + final locale = context.locale; if (date.isThisYear) return '${DateFormat.MMMMd(locale).format(date)} (${DateFormat.E(locale).format(date)})'; return '${DateFormat.yMMMMd(locale).format(date)} (${DateFormat.E(locale).format(date)})'; } @@ -69,7 +70,8 @@ class MonthSectionHeader extends StatelessWidget { final l10n = context.l10n; if (date == null) return l10n.sectionUnknown; if (date.isThisMonth) return l10n.dateThisMonth; - final locale = l10n.localeName; + + final locale = context.locale; final localized = date.isThisYear ? DateFormat.MMMM(locale).format(date) : DateFormat.yMMMM(locale).format(date); return '${localized.substring(0, 1).toUpperCase()}${localized.substring(1)}'; } diff --git a/lib/widgets/collection/grid/list_details.dart b/lib/widgets/collection/grid/list_details.dart index 8b3c9790e..898cc9285 100644 --- a/lib/widgets/collection/grid/list_details.dart +++ b/lib/widgets/collection/grid/list_details.dart @@ -75,7 +75,7 @@ class EntryListDetails extends StatelessWidget { } Widget _buildDateRow(BuildContext context, TextStyle style) { - final locale = context.l10n.localeName; + final locale = context.locale; final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final date = entry.bestDate; final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable; diff --git a/lib/widgets/collection/grid/list_details_theme.dart b/lib/widgets/collection/grid/list_details_theme.dart index 41da131a3..bc93023c2 100644 --- a/lib/widgets/collection/grid/list_details_theme.dart +++ b/lib/widgets/collection/grid/list_details_theme.dart @@ -24,8 +24,6 @@ class EntryListDetailsTheme extends StatelessWidget { Widget build(BuildContext context) { return ProxyProvider( update: (context, mq, previous) { - final locale = context.l10n.localeName; - final use24hour = mq.alwaysUse24HourFormat; final textScaler = mq.textScaler; @@ -50,7 +48,7 @@ class EntryListDetailsTheme extends StatelessWidget { final captionLineHeightParagraph = RenderParagraph( TextSpan( - text: formatDateTime(DateTime.now(), locale, use24hour), + text: formatDateTime(DateTime.now(), context.locale, use24hour), style: captionStyle, ), textDirection: TextDirection.ltr, diff --git a/lib/widgets/common/action_mixins/feedback.dart b/lib/widgets/common/action_mixins/feedback.dart index a478780b9..ad348f983 100644 --- a/lib/widgets/common/action_mixins/feedback.dart +++ b/lib/widgets/common/action_mixins/feedback.dart @@ -218,8 +218,7 @@ class _ReportOverlayState extends State> with SingleTickerPr @override Widget build(BuildContext context) { - final locale = context.l10n.localeName; - final percentFormat = NumberFormat.percentPattern(locale); + final percentFormatter = NumberFormat.percentPattern(context.locale); final theme = Theme.of(context); final colorScheme = theme.colorScheme; @@ -265,7 +264,7 @@ class _ReportOverlayState extends State> with SingleTickerPr animation: animate, center: total != null ? Text( - percentFormat.format(percent), + percentFormatter.format(percent), style: const TextStyle(fontSize: fontSize), ) : null, @@ -353,8 +352,7 @@ class _FeedbackMessageState extends State<_FeedbackMessage> with SingleTickerPro @override Widget build(BuildContext context) { - final locale = context.l10n.localeName; - final numberFormat = NumberFormat('0', locale); + final durationFormatter = NumberFormat('0', context.locale); final textScaler = MediaQuery.textScalerOf(context); final theme = Theme.of(context); @@ -393,7 +391,7 @@ class _FeedbackMessageState extends State<_FeedbackMessage> with SingleTickerPro // because we cannot use the app context theme here foreground: widget.progressColor, center: ChangeHighlightText( - numberFormat.format((remainingDurationMillis / 1000).ceil()), + durationFormatter.format((remainingDurationMillis / 1000).ceil()), style: contentTextStyle.copyWith( shadows: [ Shadow( diff --git a/lib/widgets/common/action_mixins/size_aware.dart b/lib/widgets/common/action_mixins/size_aware.dart index d8a7c32c5..0510ea069 100644 --- a/lib/widgets/common/action_mixins/size_aware.dart +++ b/lib/widgets/common/action_mixins/size_aware.dart @@ -77,13 +77,12 @@ mixin SizeAwareMixin { await showDialog( context: context, builder: (context) { - final l10n = context.l10n; - final locale = l10n.localeName; + final locale = context.locale; final neededSize = formatFileSize(locale, needed); final freeSize = formatFileSize(locale, free); final volume = destinationVolume.getDescription(context); return AvesDialog( - content: Text(l10n.notEnoughSpaceDialogMessage(neededSize, freeSize, volume)), + content: Text(context.l10n.notEnoughSpaceDialogMessage(neededSize, freeSize, volume)), actions: const [OkButton()], ); }, diff --git a/lib/widgets/common/basic/wheel.dart b/lib/widgets/common/basic/wheel.dart index 8570b2415..668f12f87 100644 --- a/lib/widgets/common/basic/wheel.dart +++ b/lib/widgets/common/basic/wheel.dart @@ -8,6 +8,7 @@ class WheelSelector extends StatefulWidget { final List values; final TextStyle textStyle; final TextAlign textAlign; + final String Function(T v) format; const WheelSelector({ super.key, @@ -15,6 +16,7 @@ class WheelSelector extends StatefulWidget { required this.values, required this.textStyle, required this.textAlign, + required this.format, }); @override @@ -117,7 +119,7 @@ class _WheelSelectorState extends State> { .map((i) => SizedBox.fromSize( size: itemSize, child: Text( - '$i', + widget.format(i), textAlign: widget.textAlign, style: widget.textStyle, ), diff --git a/lib/widgets/common/extensions/build_context.dart b/lib/widgets/common/extensions/build_context.dart index 7a5585e74..ba027341d 100644 --- a/lib/widgets/common/extensions/build_context.dart +++ b/lib/widgets/common/extensions/build_context.dart @@ -7,7 +7,9 @@ extension ExtraContext on BuildContext { AppLocalizations get l10n => AppLocalizations.of(this)!; - bool get isArabic => l10n.localeName.startsWith('ar'); + String get locale => l10n.localeName; + + bool get isArabic => locale.startsWith('ar'); bool get isRtl => Directionality.of(this) == TextDirection.rtl; diff --git a/lib/widgets/common/grid/draggable_thumb_label.dart b/lib/widgets/common/grid/draggable_thumb_label.dart index eb516f34c..06455979e 100644 --- a/lib/widgets/common/grid/draggable_thumb_label.dart +++ b/lib/widgets/common/grid/draggable_thumb_label.dart @@ -62,15 +62,13 @@ class DraggableThumbLabel extends StatelessWidget { } static String formatMonthThumbLabel(BuildContext context, DateTime? date) { - final l10n = context.l10n; - if (date == null) return l10n.sectionUnknown; - return DateFormat.yMMM(l10n.localeName).format(date); + if (date == null) return context.l10n.sectionUnknown; + return DateFormat.yMMM(context.locale).format(date); } static String formatDayThumbLabel(BuildContext context, DateTime? date) { - final l10n = context.l10n; - if (date == null) return l10n.sectionUnknown; - return formatDay(date, l10n.localeName); + if (date == null) return context.l10n.sectionUnknown; + return formatDay(date, context.locale); } } diff --git a/lib/widgets/common/identity/highlight_title.dart b/lib/widgets/common/identity/highlight_title.dart index 53ad36e0a..76647e1cf 100644 --- a/lib/widgets/common/identity/highlight_title.dart +++ b/lib/widgets/common/identity/highlight_title.dart @@ -41,7 +41,7 @@ class HighlightTitle extends StatelessWidget { final style = TextStyle( shadows: shadows(context), fontSize: fontSize, - letterSpacing: canHaveLetterSpacing(context.l10n.localeName) ? 1 : 0, + letterSpacing: canHaveLetterSpacing(context.locale) ? 1 : 0, fontFeatures: const [FontFeature.enable('smcp')], ); diff --git a/lib/widgets/common/map/geo_map.dart b/lib/widgets/common/map/geo_map.dart index ee9bec0aa..9c9ee0285 100644 --- a/lib/widgets/common/map/geo_map.dart +++ b/lib/widgets/common/map/geo_map.dart @@ -146,7 +146,7 @@ class _GeoMapState extends State { selector: (context, s) => s.mapStyle, builder: (context, mapStyle, child) { final isHeavy = ExtraEntryMapStyle.isHeavy(mapStyle); - final locale = context.l10n.localeName; + final locale = context.locale; Widget _buildMarkerWidget(MarkerKey key) => ImageMarker( key: key, count: key.count, @@ -484,7 +484,7 @@ class _GeoMapState extends State { } else { markerEntry = geoEntry.entry!; } - final locale = context.l10n.localeName; + final locale = context.locale; final markerLocation = LatLng(geoEntry.latitude!, geoEntry.longitude!); Widget markerBuilder(BuildContext context) => ImageMarker( count: geoEntry.pointsSize, diff --git a/lib/widgets/dialogs/duration_dialog.dart b/lib/widgets/dialogs/duration_dialog.dart index bd547686f..ad742c4cb 100644 --- a/lib/widgets/dialogs/duration_dialog.dart +++ b/lib/widgets/dialogs/duration_dialog.dart @@ -5,6 +5,7 @@ import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/providers/media_query_data_provider.dart'; import 'package:aves/widgets/dialogs/aves_dialog.dart'; import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; class DurationDialog extends StatefulWidget { final int initialSeconds; @@ -41,7 +42,10 @@ class _DurationDialogState extends State { return MediaQueryDataProvider( child: Builder(builder: (context) { final l10n = context.l10n; + final timeComponentFormatter = NumberFormat('0', context.locale); + const textStyle = TextStyle(fontSize: 34); + const digitsAlign = TextAlign.right; return AvesDialog( scrollableContent: [ @@ -53,9 +57,9 @@ class _DurationDialogState extends State { children: [ TableRow( children: [ - Center(child: Text(context.l10n.durationDialogMinutes)), + Center(child: Text(l10n.durationDialogMinutes)), const SizedBox(width: 16), - Center(child: Text(context.l10n.durationDialogSeconds)), + Center(child: Text(l10n.durationDialogSeconds)), ], ), TableRow( @@ -66,7 +70,8 @@ class _DurationDialogState extends State { valueNotifier: _minutes, values: List.generate(minutesInHour, (i) => i), textStyle: textStyle, - textAlign: TextAlign.end, + textAlign: digitsAlign, + format: timeComponentFormatter.format, ), ), const Padding( @@ -82,7 +87,8 @@ class _DurationDialogState extends State { valueNotifier: _seconds, values: List.generate(secondsInMinute, (i) => i), textStyle: textStyle, - textAlign: TextAlign.end, + textAlign: digitsAlign, + format: timeComponentFormatter.format, ), ), ], diff --git a/lib/widgets/dialogs/entry_editors/edit_date_dialog.dart b/lib/widgets/dialogs/entry_editors/edit_date_dialog.dart index 28cd80e5c..a9e157784 100644 --- a/lib/widgets/dialogs/entry_editors/edit_date_dialog.dart +++ b/lib/widgets/dialogs/entry_editors/edit_date_dialog.dart @@ -18,6 +18,7 @@ import 'package:aves/widgets/dialogs/item_picker.dart'; import 'package:aves/widgets/dialogs/pick_dialogs/item_pick_page.dart'; import 'package:aves_model/aves_model.dart'; import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; class EditEntryDateDialog extends StatefulWidget { @@ -147,19 +148,17 @@ class _EditEntryDateDialogState extends State { } Widget _buildSetCustomContent(BuildContext context) { - final l10n = context.l10n; - final locale = l10n.localeName; final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); return Padding( padding: const EdgeInsetsDirectional.only(start: 16, end: 8), child: Row( children: [ - Expanded(child: Text(formatDateTime(_customDateTime, locale, use24hour))), + Expanded(child: Text(formatDateTime(_customDateTime, context.locale, use24hour))), IconButton( icon: const Icon(AIcons.edit), onPressed: _editDate, - tooltip: l10n.changeTooltip, + tooltip: context.l10n.changeTooltip, ), ], ), @@ -181,15 +180,13 @@ class _EditEntryDateDialogState extends State { } Widget _buildCopyItemContent(BuildContext context) { - final l10n = context.l10n; - final locale = l10n.localeName; final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); return Padding( padding: const EdgeInsetsDirectional.only(start: 16, end: 8), child: Row( children: [ - Expanded(child: Text(formatDateTime(copyItemDate, locale, use24hour))), + Expanded(child: Text(formatDateTime(copyItemDate, context.locale, use24hour))), const SizedBox(width: 8), ItemPicker( extent: 48, @@ -202,7 +199,12 @@ class _EditEntryDateDialogState extends State { } Widget _buildShiftContent(BuildContext context) { + final l10n = context.l10n; + final timeComponentFormatter = NumberFormat('0', context.locale); + const textStyle = TextStyle(fontSize: 34); + const digitsAlign = TextAlign.right; + return Center( child: Table( textDirection: timeComponentsDirection, @@ -210,9 +212,9 @@ class _EditEntryDateDialogState extends State { TableRow( children: [ const SizedBox(), - Center(child: Text(context.l10n.durationDialogHours)), + Center(child: Text(l10n.durationDialogHours)), const SizedBox(width: 16), - Center(child: Text(context.l10n.durationDialogMinutes)), + Center(child: Text(l10n.durationDialogMinutes)), ], ), TableRow( @@ -222,6 +224,7 @@ class _EditEntryDateDialogState extends State { values: const ['+', '-'], textStyle: textStyle, textAlign: TextAlign.center, + format: (v) => v, ), Align( alignment: Alignment.centerRight, @@ -229,7 +232,8 @@ class _EditEntryDateDialogState extends State { valueNotifier: _shiftHour, values: List.generate(hoursInDay, (i) => i), textStyle: textStyle, - textAlign: TextAlign.end, + textAlign: digitsAlign, + format: timeComponentFormatter.format, ), ), const Padding( @@ -245,7 +249,8 @@ class _EditEntryDateDialogState extends State { valueNotifier: _shiftMinute, values: List.generate(minutesInHour, (i) => i), textStyle: textStyle, - textAlign: TextAlign.end, + textAlign: digitsAlign, + format: timeComponentFormatter.format, ), ), ], diff --git a/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart b/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart index ca73fa477..39e98aae9 100644 --- a/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart +++ b/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart @@ -48,7 +48,7 @@ class _EditEntryLocationDialogState extends State { final TextEditingController _latitudeController = TextEditingController(), _longitudeController = TextEditingController(); final ValueNotifier _isValidNotifier = ValueNotifier(false); - NumberFormat get coordinateFormatter => NumberFormat('0.000000', context.l10n.localeName); + NumberFormat get coordinateFormatter => NumberFormat('0.000000', context.locale); @override void initState() { diff --git a/lib/widgets/dialogs/entry_editors/rename_entry_set_page.dart b/lib/widgets/dialogs/entry_editors/rename_entry_set_page.dart index ea944f59f..b46652c4c 100644 --- a/lib/widgets/dialogs/entry_editors/rename_entry_set_page.dart +++ b/lib/widgets/dialogs/entry_editors/rename_entry_set_page.dart @@ -54,7 +54,7 @@ class _RenameEntrySetPageState extends State { _patternTextController.addListener(_onUserPatternChanged); WidgetsBinding.instance.addPostFrameCallback((_) { - locale = context.l10n.localeName; + locale = context.locale; _onUserPatternChanged(); }); } diff --git a/lib/widgets/editor/transform/control_panel.dart b/lib/widgets/editor/transform/control_panel.dart index 47a5f41ae..5438de4a5 100644 --- a/lib/widgets/editor/transform/control_panel.dart +++ b/lib/widgets/editor/transform/control_panel.dart @@ -156,6 +156,7 @@ class RotationControlPanel extends StatelessWidget { @override Widget build(BuildContext context) { final controller = context.watch(); + final angleFormatter = NumberFormat('0.0°', context.locale); return Row( children: [ @@ -172,7 +173,7 @@ class RotationControlPanel extends StatelessWidget { divisions: 18, onChangeStart: (v) => controller.activity = TransformActivity.straighten, onChangeEnd: (v) => controller.activity = TransformActivity.none, - label: NumberFormat('0.0°', context.l10n.localeName).format(transformation.straightenDegrees), + label: angleFormatter.format(transformation.straightenDegrees), onChanged: (v) => controller.straightenDegrees = v, ); }, diff --git a/lib/widgets/filter_grids/common/covered_filter_chip.dart b/lib/widgets/filter_grids/common/covered_filter_chip.dart index 6e9e86395..c16ed1fb8 100644 --- a/lib/widgets/filter_grids/common/covered_filter_chip.dart +++ b/lib/widgets/filter_grids/common/covered_filter_chip.dart @@ -171,8 +171,7 @@ class CoveredFilterChip extends StatelessWidget { Color _detailColor(BuildContext context) => Theme.of(context).colorScheme.onSurfaceVariant; Widget _buildDetails(BuildContext context, CollectionSource source, T filter) { - final locale = context.l10n.localeName; - final numberFormat = NumberFormat.decimalPattern(locale); + final countFormatter = NumberFormat.decimalPattern(context.locale); final padding = min(8.0, extent / 16); final iconSize = detailIconSize(extent); @@ -211,7 +210,7 @@ class CoveredFilterChip extends StatelessWidget { ), ), Text( - locked ? AText.valueNotAvailable : numberFormat.format(source.count(filter)), + locked ? AText.valueNotAvailable : countFormatter.format(source.count(filter)), style: TextStyle( color: _detailColor(context), fontSize: fontSize, diff --git a/lib/widgets/filter_grids/common/draggable_thumb_label.dart b/lib/widgets/filter_grids/common/draggable_thumb_label.dart index ab0f9941f..fa06daddc 100644 --- a/lib/widgets/filter_grids/common/draggable_thumb_label.dart +++ b/lib/widgets/filter_grids/common/draggable_thumb_label.dart @@ -36,9 +36,8 @@ class FilterDraggableThumbLabel extends StatelessWid context.l10n.itemCount(context.read().count(filterGridItem.filter)), ]; case ChipSortFactor.size: - final locale = context.l10n.localeName; return [ - formatFileSize(locale, context.read().size(filterGridItem.filter)), + formatFileSize(context.locale, context.read().size(filterGridItem.filter)), ]; } }, diff --git a/lib/widgets/filter_grids/common/list_details.dart b/lib/widgets/filter_grids/common/list_details.dart index 955ff70fb..1124afaac 100644 --- a/lib/widgets/filter_grids/common/list_details.dart +++ b/lib/widgets/filter_grids/common/list_details.dart @@ -84,10 +84,9 @@ class FilterListDetails extends StatelessWidget { } Widget _buildDateRow(BuildContext context, FilterListDetailsThemeData detailsTheme, bool hasTitleLeading) { - final locale = context.l10n.localeName; final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final date = entry?.bestDate; - final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable; + final dateText = date != null ? formatDateTime(date, context.locale, use24hour) : AText.valueNotAvailable; Widget leading = const Icon(AIcons.date); if (hasTitleLeading) { @@ -143,8 +142,6 @@ class FilterListDetails extends StatelessWidget { child: Center(child: leading ?? const SizedBox()), ); - final l10n = context.l10n; - final locale = l10n.localeName; final source = context.read(); return IconTheme.merge( @@ -154,7 +151,7 @@ class FilterListDetails extends StatelessWidget { leading, const SizedBox(width: 8), Text( - '${l10n.itemCount(source.count(filter))} • ${formatFileSize(locale, source.size(filter))}', + '${context.l10n.itemCount(source.count(filter))} • ${formatFileSize(context.locale, source.size(filter))}', style: detailsTheme.captionStyle, softWrap: false, overflow: TextOverflow.fade, diff --git a/lib/widgets/filter_grids/common/list_details_theme.dart b/lib/widgets/filter_grids/common/list_details_theme.dart index d5af3e26d..b828d16cb 100644 --- a/lib/widgets/filter_grids/common/list_details_theme.dart +++ b/lib/widgets/filter_grids/common/list_details_theme.dart @@ -28,8 +28,6 @@ class FilterListDetailsTheme extends StatelessWidget { Widget build(BuildContext context) { return ProxyProvider( update: (context, mq, previous) { - final locale = context.l10n.localeName; - final use24hour = mq.alwaysUse24HourFormat; final textScaler = mq.textScaler; @@ -54,7 +52,7 @@ class FilterListDetailsTheme extends StatelessWidget { titleLineHeightParagraph.dispose(); final captionLineHeightParagraph = RenderParagraph( - TextSpan(text: formatDateTime(DateTime.now(), locale, use24hour), style: captionStyle), + TextSpan(text: formatDateTime(DateTime.now(), context.locale, use24hour), style: captionStyle), textDirection: TextDirection.ltr, textScaler: textScaler, )..layout(const BoxConstraints(), parentUsesSize: true); diff --git a/lib/widgets/map/date_row.dart b/lib/widgets/map/date_row.dart index e663afcb0..d83e71573 100644 --- a/lib/widgets/map/date_row.dart +++ b/lib/widgets/map/date_row.dart @@ -16,11 +16,10 @@ class MapDateRow extends StatelessWidget { @override Widget build(BuildContext context) { - final locale = context.l10n.localeName; final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final date = entry?.bestDate; - final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable; + final dateText = date != null ? formatDateTime(date, context.locale, use24hour) : AText.valueNotAvailable; return Text.rich( TextSpan( children: [ diff --git a/lib/widgets/navigation/drawer/app_drawer.dart b/lib/widgets/navigation/drawer/app_drawer.dart index c04705690..8ecb4d440 100644 --- a/lib/widgets/navigation/drawer/app_drawer.dart +++ b/lib/widgets/navigation/drawer/app_drawer.dart @@ -112,7 +112,6 @@ class _AppDrawerState extends State { Widget _buildHeader(BuildContext context) { final l10n = context.l10n; - final locale = l10n.localeName; Future goTo(String routeName, WidgetBuilder pageBuilder) async { Navigator.maybeOf(context)?.pop(); @@ -153,7 +152,7 @@ class _AppDrawerState extends State { color: Colors.white, fontSize: 38, fontWeight: FontWeight.w300, - letterSpacing: canHaveLetterSpacing(locale) ? 1 : 0, + letterSpacing: canHaveLetterSpacing(context.locale) ? 1 : 0, fontFeatures: const [FontFeature.enable('smcp')], ), ), @@ -295,7 +294,7 @@ class _AppDrawerState extends State { return CollectionNavTile( leading: const DrawerFilterIcon(filter: filter), title: const DrawerFilterTitle(filter: filter), - trailing: Text(formatFileSize(context.l10n.localeName, trashSize, round: 0)), + trailing: Text(formatFileSize(context.locale, trashSize, round: 0)), filter: filter, isSelected: () => currentCollection?.filters.contains(filter) ?? false, ); diff --git a/lib/widgets/navigation/tv_rail.dart b/lib/widgets/navigation/tv_rail.dart index ee75292a1..a55c2cb84 100644 --- a/lib/widgets/navigation/tv_rail.dart +++ b/lib/widgets/navigation/tv_rail.dart @@ -91,9 +91,6 @@ class _TvRailState extends State { @override Widget build(BuildContext context) { - final l10n = context.l10n; - final locale = l10n.localeName; - final navEntries = _getNavEntries(context); return DirectionalSafeArea( end: false, @@ -107,12 +104,12 @@ class _TvRailState extends State { logo, const SizedBox(width: 16), Text( - l10n.appName, + context.l10n.appName, style: TextStyle( color: Colors.white, fontSize: 32, fontWeight: FontWeight.w300, - letterSpacing: canHaveLetterSpacing(locale) ? 1 : 0, + letterSpacing: canHaveLetterSpacing(context.locale) ? 1 : 0, fontFeatures: const [FontFeature.enable('smcp')], ), ), diff --git a/lib/widgets/stats/date/histogram.dart b/lib/widgets/stats/date/histogram.dart index 93db96de7..4ad68866a 100644 --- a/lib/widgets/stats/date/histogram.dart +++ b/lib/widgets/stats/date/histogram.dart @@ -223,7 +223,7 @@ class _HistogramState extends State with AutomaticKeepAliveClientMixi )..setAttribute(charts.rendererIdKey, 'customPoint'), ]; - final locale = context.l10n.localeName; + final locale = context.locale; final timeAxisSpec = _firstDate != null && _lastDate != null ? TimeAxisSpec.forLevel( locale: locale, @@ -232,7 +232,7 @@ class _HistogramState extends State with AutomaticKeepAliveClientMixi last: _lastDate!, ) : null; - final measureFormat = NumberFormat.decimalPattern(locale); + final tickFormatter = NumberFormat.decimalPattern(locale); final domainAxis = charts.DateTimeAxisSpec( renderSpec: charts.SmallTickRendererSpec( @@ -254,7 +254,7 @@ class _HistogramState extends State with AutomaticKeepAliveClientMixi ), tickFormatterSpec: charts.BasicNumericTickFormatterSpec((v) { // localize and hide 0 - return (v == null || v == 0) ? '' : measureFormat.format(v); + return (v == null || v == 0) ? '' : tickFormatter.format(v); }), ), defaultRenderer: charts.LineRendererConfig( @@ -304,8 +304,7 @@ class _HistogramState extends State with AutomaticKeepAliveClientMixi } Widget _buildSelectionRow() { - final locale = context.l10n.localeName; - final numberFormat = NumberFormat.decimalPattern(locale); + final countFormatter = NumberFormat.decimalPattern(context.locale); return ValueListenableBuilder<_EntryByDate?>( valueListenable: _selection, @@ -326,7 +325,7 @@ class _HistogramState extends State with AutomaticKeepAliveClientMixi ), const Spacer(), Text( - numberFormat.format(count), + countFormatter.format(count), style: TextStyle( color: Theme.of(context).colorScheme.onSurfaceVariant, ), diff --git a/lib/widgets/stats/filter_table.dart b/lib/widgets/stats/filter_table.dart index 7e0673940..a450fa1fb 100644 --- a/lib/widgets/stats/filter_table.dart +++ b/lib/widgets/stats/filter_table.dart @@ -35,8 +35,7 @@ class FilterTable extends StatelessWidget { @override Widget build(BuildContext context) { - final locale = context.l10n.localeName; - final numberFormat = NumberFormat.decimalPattern(locale); + final countFormatter = NumberFormat.decimalPattern(context.locale); final animate = context.select((v) => v.accessibilityAnimations.animate); final sortedEntries = entryCountMap.entries.toList(); @@ -104,7 +103,7 @@ class FilterTable extends StatelessWidget { }, ), Text( - numberFormat.format(count), + countFormatter.format(count), style: TextStyle( color: colorScheme.onSurfaceVariant, ), diff --git a/lib/widgets/stats/mime_donut.dart b/lib/widgets/stats/mime_donut.dart index 4e0fdc4a5..83a173fda 100644 --- a/lib/widgets/stats/mime_donut.dart +++ b/lib/widgets/stats/mime_donut.dart @@ -24,8 +24,7 @@ class MimeDonut extends StatelessWidget { @override Widget build(BuildContext context) { - final locale = context.l10n.localeName; - final numberFormat = NumberFormat.decimalPattern(locale); + final countFormatter = NumberFormat.decimalPattern(context.locale); String formatKey(d) => MimeUtils.displayType(d.key); return AvesDonut( @@ -33,7 +32,7 @@ class MimeDonut extends StatelessWidget { byTypes: byMimeTypes, animationDuration: animationDuration, formatKey: formatKey, - formatValue: numberFormat.format, + formatValue: countFormatter.format, colorize: (context, d) { final colors = context.read(); return colors.fromString(formatKey(d)); diff --git a/lib/widgets/stats/percent_text.dart b/lib/widgets/stats/percent_text.dart index 7bc62038c..ed7247bc4 100644 --- a/lib/widgets/stats/percent_text.dart +++ b/lib/widgets/stats/percent_text.dart @@ -16,13 +16,12 @@ class LinearPercentIndicatorText extends StatelessWidget { @override Widget build(BuildContext context) { - final locale = context.l10n.localeName; - final percentFormat = NumberFormat.percentPattern(locale); + final percentFormatter = NumberFormat.percentPattern(context.locale); return OutlinedText( textSpans: [ TextSpan( - text: percentFormat.format(percent), + text: percentFormatter.format(percent), style: TextStyle( shadows: Theme.of(context).isDark ? AStyles.embossShadows : null, ), diff --git a/lib/widgets/stats/stats_page.dart b/lib/widgets/stats/stats_page.dart index 07d6596cd..3bfaa0e85 100644 --- a/lib/widgets/stats/stats_page.dart +++ b/lib/widgets/stats/stats_page.dart @@ -168,7 +168,7 @@ class _StatsPageState extends State with FeedbackMixin, VaultAwareMix const Icon(AIcons.size), const SizedBox(width: 16), Expanded( - child: Text(formatFileSize(l10n.localeName, _totalSizeBytes)), + child: Text(formatFileSize(context.locale, _totalSizeBytes)), ), ], ), diff --git a/lib/widgets/viewer/info/basic_section.dart b/lib/widgets/viewer/info/basic_section.dart index 123891051..42080956b 100644 --- a/lib/widgets/viewer/info/basic_section.dart +++ b/lib/widgets/viewer/info/basic_section.dart @@ -299,7 +299,7 @@ class _BasicInfoState extends State<_BasicInfo> { Widget build(BuildContext context) { final l10n = context.l10n; final infoUnknown = l10n.viewerInfoUnknown; - final locale = l10n.localeName; + final locale = context.locale; final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); // TODO TLAD line break on all characters for the following fields when this is fixed: https://github.com/flutter/flutter/issues/61081 @@ -383,10 +383,9 @@ class _BasicInfoState extends State<_BasicInfo> { // guess whether this is a photo, according to file type final isPhoto = [MimeTypes.heic, MimeTypes.heif, MimeTypes.jpeg, MimeTypes.tiff].contains(entry.mimeType) || entry.isRaw; if (isPhoto) { - final numberFormat = NumberFormat('0', locale); final megaPixels = (entry.width * entry.height / 1000000).round(); if (megaPixels > 0) { - s += ' • ${numberFormat.format(megaPixels)} MP'; + s += ' • ${NumberFormat('0', locale).format(megaPixels)} MP'; } } diff --git a/lib/widgets/viewer/overlay/details/date.dart b/lib/widgets/viewer/overlay/details/date.dart index af2425fc5..7c762f028 100644 --- a/lib/widgets/viewer/overlay/details/date.dart +++ b/lib/widgets/viewer/overlay/details/date.dart @@ -21,7 +21,7 @@ class OverlayDateRow extends StatelessWidget { @override Widget build(BuildContext context) { - final locale = context.l10n.localeName; + final locale = context.locale; final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final date = entry.bestDate; diff --git a/lib/widgets/viewer/overlay/details/shooting.dart b/lib/widgets/viewer/overlay/details/shooting.dart index 94ea6f260..770d04e9c 100644 --- a/lib/widgets/viewer/overlay/details/shooting.dart +++ b/lib/widgets/viewer/overlay/details/shooting.dart @@ -17,7 +17,7 @@ class OverlayShootingRow extends StatelessWidget { @override Widget build(BuildContext context) { - final locale = context.l10n.localeName; + final locale = context.locale; final aperture = details.aperture; final apertureText = aperture != null ? 'ƒ/${NumberFormat('0.0', locale).format(aperture)}' : AText.valueNotAvailable; diff --git a/plugins/aves_map/lib/src/marker/image.dart b/plugins/aves_map/lib/src/marker/image.dart index 8ead5d7a2..7b776e0d9 100644 --- a/plugins/aves_map/lib/src/marker/image.dart +++ b/plugins/aves_map/lib/src/marker/image.dart @@ -9,7 +9,7 @@ import 'package:latlong2/latlong.dart'; class ImageMarker extends StatelessWidget { final int? count; - final intl.NumberFormat numberFormat; + final intl.NumberFormat countFormatter; final bool drawArrow; final Widget Function(double extent) buildThumbnailImage; @@ -28,7 +28,7 @@ class ImageMarker extends StatelessWidget { required String locale, this.drawArrow = true, required this.buildThumbnailImage, - }) : numberFormat = intl.NumberFormat.decimalPattern(locale); + }) : countFormatter = intl.NumberFormat.decimalPattern(locale); @override Widget build(BuildContext context) { @@ -110,7 +110,7 @@ class ImageMarker extends StatelessWidget { ), ), child: Text( - numberFormat.format(count), + countFormatter.format(count), style: TextStyle( fontSize: 12, color: theme.colorScheme.onPrimary,