format review

This commit is contained in:
Thibault Deckers 2024-05-20 15:20:13 +02:00
parent ff16651ce1
commit f10abcd670
41 changed files with 108 additions and 117 deletions

View file

@ -23,6 +23,9 @@ import 'package:latlong2/latlong.dart';
import 'package:xml/xml.dart'; import 'package:xml/xml.dart';
extension ExtraAvesEntryMetadataEdition on AvesEntry { extension ExtraAvesEntryMetadataEdition on AvesEntry {
static final _iso6709LatitudeFormatter = NumberFormat('00.0000', asciiLocale);
static final _iso6709LongitudeFormatter = NumberFormat('000.0000', asciiLocale);
Future<Set<EntryDataType>> editDate(DateModifier userModifier) async { Future<Set<EntryDataType>> editDate(DateModifier userModifier) async {
final dataTypes = <EntryDataType>{}; final dataTypes = <EntryDataType>{};
@ -122,9 +125,8 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
if (latLng != null && latLng != removalLocation) { if (latLng != null && latLng != removalLocation) {
final latitude = latLng.latitude; final latitude = latLng.latitude;
final longitude = latLng.longitude; final longitude = latLng.longitude;
const locale = asciiLocale; final isoLat = '${latitude >= 0 ? '+' : '-'}${_iso6709LatitudeFormatter.format(latitude.abs())}';
final isoLat = '${latitude >= 0 ? '+' : '-'}${NumberFormat('00.0000', locale).format(latitude.abs())}'; final isoLon = '${longitude >= 0 ? '+' : '-'}${_iso6709LongitudeFormatter.format(longitude.abs())}';
final isoLon = '${longitude >= 0 ? '+' : '-'}${NumberFormat('000.0000', locale).format(longitude.abs())}';
iso6709String = '$isoLat$isoLon/'; iso6709String = '$isoLat$isoLon/';
} }
mp4Fields[MetadataField.mp4GpsCoordinates] = iso6709String; mp4Fields[MetadataField.mp4GpsCoordinates] = iso6709String;

View file

@ -53,9 +53,9 @@ extension ExtraAvesEntryProps on AvesEntry {
// text // text
String getResolutionText(String locale) { String getResolutionText(String locale) {
final numberFormat = NumberFormat('0', locale); final dimensionFormatter = NumberFormat('0', locale);
final ws = numberFormat.format(width); final ws = dimensionFormatter.format(width);
final hs = numberFormat.format(height); final hs = dimensionFormatter.format(height);
return isRotated ? '$hs${AText.resolutionSeparator}$ws' : '$ws${AText.resolutionSeparator}$hs'; return isRotated ? '$hs${AText.resolutionSeparator}$ws' : '$ws${AText.resolutionSeparator}$hs';
} }

View file

@ -100,8 +100,7 @@ class DateFilter extends CollectionFilter {
@override @override
String getLabel(BuildContext context) { String getLabel(BuildContext context) {
final l10n = context.l10n; final locale = context.locale;
final locale = l10n.localeName;
switch (level) { switch (level) {
case DateLevel.y: case DateLevel.y:
return DateFormat.y(locale).format(_effectiveDate); return DateFormat.y(locale).format(_effectiveDate);
@ -113,7 +112,7 @@ class DateFilter extends CollectionFilter {
if (date != null) { if (date != null) {
return DateFormat.MMMd(locale).format(_effectiveDate); return DateFormat.MMMd(locale).format(_effectiveDate);
} else { } else {
return l10n.filterOnThisDayLabel; return context.l10n.filterOnThisDayLabel;
} }
case DateLevel.m: case DateLevel.m:
return DateFormat.MMMM(locale).format(_effectiveDate); return DateFormat.MMMM(locale).format(_effectiveDate);

View file

@ -55,11 +55,10 @@ extension ExtraCoordinateFormat on CoordinateFormat {
} }
static List<String> _toDecimal(AppLocalizations l10n, LatLng latLng) { static List<String> _toDecimal(AppLocalizations l10n, LatLng latLng) {
final locale = l10n.localeName; final coordinateFormatter = NumberFormat('0.000000°', l10n.localeName);
final formatter = NumberFormat('0.000000°', locale);
return [ return [
formatter.format(latLng.latitude), coordinateFormatter.format(latLng.latitude),
formatter.format(latLng.longitude), coordinateFormatter.format(latLng.longitude),
]; ];
} }
} }

View file

@ -8,9 +8,9 @@ const tera = giga * kilo;
String formatFileSize(String locale, int size, {int round = 2}) { String formatFileSize(String locale, int size, {int round = 2}) {
if (size < kilo) return '$size B'; if (size < kilo) return '$size B';
final formatter = NumberFormat('0${round > 0 ? '.${'0' * round}' : ''}', locale); final compactFormatter = NumberFormat('0${round > 0 ? '.${'0' * round}' : ''}', locale);
if (size < mega) return '${formatter.format(size / kilo)} KB'; if (size < mega) return '${compactFormatter.format(size / kilo)} KB';
if (size < giga) return '${formatter.format(size / mega)} MB'; if (size < giga) return '${compactFormatter.format(size / mega)} MB';
if (size < tera) return '${formatter.format(size / giga)} GB'; if (size < tera) return '${compactFormatter.format(size / giga)} GB';
return '${formatter.format(size / tera)} TB'; return '${compactFormatter.format(size / tera)} TB';
} }

View file

@ -31,7 +31,7 @@ class AppReference extends StatelessWidget {
} }
Widget _buildAvesLine(BuildContext context) { Widget _buildAvesLine(BuildContext context) {
final locale = context.l10n.localeName; final locale = context.locale;
final textScaler = MediaQuery.textScalerOf(context); final textScaler = MediaQuery.textScalerOf(context);
return Row( return Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,

View file

@ -122,9 +122,6 @@ class _BugReportState extends State<BugReport> with FeedbackMixin {
} }
Widget _buildStep(int step, String text, String buttonText, VoidCallback onPressed) { 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; final isMonochrome = settings.themeColorMode == AvesThemeColorMode.monochrome;
return Padding( return Padding(
padding: const EdgeInsets.symmetric(vertical: 4), padding: const EdgeInsets.symmetric(vertical: 4),
@ -139,7 +136,7 @@ class _BugReportState extends State<BugReport> with FeedbackMixin {
)), )),
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: Text(numberFormat.format(step)), child: Text(NumberFormat('0', context.locale).format(step)),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
Expanded(child: Text(text)), Expanded(child: Text(text)),

View file

@ -137,7 +137,7 @@ class DataUsageDonut extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = context.l10n; final l10n = context.l10n;
final locale = l10n.localeName; final locale = context.locale;
return AvesDonut( return AvesDonut(
title: Text(title), title: Text(title),

View file

@ -673,7 +673,7 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> with Widge
final newest = firstKey.date; final newest = firstKey.date;
final oldest = lastKey.date; final oldest = lastKey.date;
if (newest != null && oldest != null) { 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); final dateFormat = (newest.difference(oldest).inHumanDays).abs() > 365 ? DateFormat.y(locale) : DateFormat.MMM(locale);
String? lastLabel; String? lastLabel;
sectionLayouts.forEach((section) { sectionLayouts.forEach((section) {

View file

@ -55,7 +55,7 @@ class CollectionDraggableThumbLabel extends StatelessWidget {
]; ];
case EntrySortFactor.size: case EntrySortFactor.size:
return [ return [
if (entry.sizeBytes != null) formatFileSize(context.l10n.localeName, entry.sizeBytes!, round: 0), if (entry.sizeBytes != null) formatFileSize(context.locale, entry.sizeBytes!, round: 0),
]; ];
} }
}, },

View file

@ -40,7 +40,8 @@ class DaySectionHeader<T> extends StatelessWidget {
if (date == null) return l10n.sectionUnknown; if (date == null) return l10n.sectionUnknown;
if (date.isToday) return l10n.dateToday; if (date.isToday) return l10n.dateToday;
if (date.isYesterday) return l10n.dateYesterday; 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)})'; 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)})'; return '${DateFormat.yMMMMd(locale).format(date)} (${DateFormat.E(locale).format(date)})';
} }
@ -69,7 +70,8 @@ class MonthSectionHeader<T> extends StatelessWidget {
final l10n = context.l10n; final l10n = context.l10n;
if (date == null) return l10n.sectionUnknown; if (date == null) return l10n.sectionUnknown;
if (date.isThisMonth) return l10n.dateThisMonth; 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); final localized = date.isThisYear ? DateFormat.MMMM(locale).format(date) : DateFormat.yMMMM(locale).format(date);
return '${localized.substring(0, 1).toUpperCase()}${localized.substring(1)}'; return '${localized.substring(0, 1).toUpperCase()}${localized.substring(1)}';
} }

View file

@ -75,7 +75,7 @@ class EntryListDetails extends StatelessWidget {
} }
Widget _buildDateRow(BuildContext context, TextStyle style) { Widget _buildDateRow(BuildContext context, TextStyle style) {
final locale = context.l10n.localeName; final locale = context.locale;
final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final use24hour = MediaQuery.alwaysUse24HourFormatOf(context);
final date = entry.bestDate; final date = entry.bestDate;
final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable; final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable;

View file

@ -24,8 +24,6 @@ class EntryListDetailsTheme extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ProxyProvider<MediaQueryData, EntryListDetailsThemeData>( return ProxyProvider<MediaQueryData, EntryListDetailsThemeData>(
update: (context, mq, previous) { update: (context, mq, previous) {
final locale = context.l10n.localeName;
final use24hour = mq.alwaysUse24HourFormat; final use24hour = mq.alwaysUse24HourFormat;
final textScaler = mq.textScaler; final textScaler = mq.textScaler;
@ -50,7 +48,7 @@ class EntryListDetailsTheme extends StatelessWidget {
final captionLineHeightParagraph = RenderParagraph( final captionLineHeightParagraph = RenderParagraph(
TextSpan( TextSpan(
text: formatDateTime(DateTime.now(), locale, use24hour), text: formatDateTime(DateTime.now(), context.locale, use24hour),
style: captionStyle, style: captionStyle,
), ),
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,

View file

@ -218,8 +218,7 @@ class _ReportOverlayState<T> extends State<ReportOverlay<T>> with SingleTickerPr
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final locale = context.l10n.localeName; final percentFormatter = NumberFormat.percentPattern(context.locale);
final percentFormat = NumberFormat.percentPattern(locale);
final theme = Theme.of(context); final theme = Theme.of(context);
final colorScheme = theme.colorScheme; final colorScheme = theme.colorScheme;
@ -265,7 +264,7 @@ class _ReportOverlayState<T> extends State<ReportOverlay<T>> with SingleTickerPr
animation: animate, animation: animate,
center: total != null center: total != null
? Text( ? Text(
percentFormat.format(percent), percentFormatter.format(percent),
style: const TextStyle(fontSize: fontSize), style: const TextStyle(fontSize: fontSize),
) )
: null, : null,
@ -353,8 +352,7 @@ class _FeedbackMessageState extends State<_FeedbackMessage> with SingleTickerPro
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final locale = context.l10n.localeName; final durationFormatter = NumberFormat('0', context.locale);
final numberFormat = NumberFormat('0', locale);
final textScaler = MediaQuery.textScalerOf(context); final textScaler = MediaQuery.textScalerOf(context);
final theme = Theme.of(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 // because we cannot use the app context theme here
foreground: widget.progressColor, foreground: widget.progressColor,
center: ChangeHighlightText( center: ChangeHighlightText(
numberFormat.format((remainingDurationMillis / 1000).ceil()), durationFormatter.format((remainingDurationMillis / 1000).ceil()),
style: contentTextStyle.copyWith( style: contentTextStyle.copyWith(
shadows: [ shadows: [
Shadow( Shadow(

View file

@ -77,13 +77,12 @@ mixin SizeAwareMixin {
await showDialog( await showDialog(
context: context, context: context,
builder: (context) { builder: (context) {
final l10n = context.l10n; final locale = context.locale;
final locale = l10n.localeName;
final neededSize = formatFileSize(locale, needed); final neededSize = formatFileSize(locale, needed);
final freeSize = formatFileSize(locale, free); final freeSize = formatFileSize(locale, free);
final volume = destinationVolume.getDescription(context); final volume = destinationVolume.getDescription(context);
return AvesDialog( return AvesDialog(
content: Text(l10n.notEnoughSpaceDialogMessage(neededSize, freeSize, volume)), content: Text(context.l10n.notEnoughSpaceDialogMessage(neededSize, freeSize, volume)),
actions: const [OkButton()], actions: const [OkButton()],
); );
}, },

View file

@ -8,6 +8,7 @@ class WheelSelector<T> extends StatefulWidget {
final List<T> values; final List<T> values;
final TextStyle textStyle; final TextStyle textStyle;
final TextAlign textAlign; final TextAlign textAlign;
final String Function(T v) format;
const WheelSelector({ const WheelSelector({
super.key, super.key,
@ -15,6 +16,7 @@ class WheelSelector<T> extends StatefulWidget {
required this.values, required this.values,
required this.textStyle, required this.textStyle,
required this.textAlign, required this.textAlign,
required this.format,
}); });
@override @override
@ -117,7 +119,7 @@ class _WheelSelectorState<T> extends State<WheelSelector<T>> {
.map((i) => SizedBox.fromSize( .map((i) => SizedBox.fromSize(
size: itemSize, size: itemSize,
child: Text( child: Text(
'$i', widget.format(i),
textAlign: widget.textAlign, textAlign: widget.textAlign,
style: widget.textStyle, style: widget.textStyle,
), ),

View file

@ -7,7 +7,9 @@ extension ExtraContext on BuildContext {
AppLocalizations get l10n => AppLocalizations.of(this)!; 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; bool get isRtl => Directionality.of(this) == TextDirection.rtl;

View file

@ -62,15 +62,13 @@ class DraggableThumbLabel<T> extends StatelessWidget {
} }
static String formatMonthThumbLabel(BuildContext context, DateTime? date) { static String formatMonthThumbLabel(BuildContext context, DateTime? date) {
final l10n = context.l10n; if (date == null) return context.l10n.sectionUnknown;
if (date == null) return l10n.sectionUnknown; return DateFormat.yMMM(context.locale).format(date);
return DateFormat.yMMM(l10n.localeName).format(date);
} }
static String formatDayThumbLabel(BuildContext context, DateTime? date) { static String formatDayThumbLabel(BuildContext context, DateTime? date) {
final l10n = context.l10n; if (date == null) return context.l10n.sectionUnknown;
if (date == null) return l10n.sectionUnknown; return formatDay(date, context.locale);
return formatDay(date, l10n.localeName);
} }
} }

View file

@ -41,7 +41,7 @@ class HighlightTitle extends StatelessWidget {
final style = TextStyle( final style = TextStyle(
shadows: shadows(context), shadows: shadows(context),
fontSize: fontSize, fontSize: fontSize,
letterSpacing: canHaveLetterSpacing(context.l10n.localeName) ? 1 : 0, letterSpacing: canHaveLetterSpacing(context.locale) ? 1 : 0,
fontFeatures: const [FontFeature.enable('smcp')], fontFeatures: const [FontFeature.enable('smcp')],
); );

View file

@ -146,7 +146,7 @@ class _GeoMapState extends State<GeoMap> {
selector: (context, s) => s.mapStyle, selector: (context, s) => s.mapStyle,
builder: (context, mapStyle, child) { builder: (context, mapStyle, child) {
final isHeavy = ExtraEntryMapStyle.isHeavy(mapStyle); final isHeavy = ExtraEntryMapStyle.isHeavy(mapStyle);
final locale = context.l10n.localeName; final locale = context.locale;
Widget _buildMarkerWidget(MarkerKey<AvesEntry> key) => ImageMarker( Widget _buildMarkerWidget(MarkerKey<AvesEntry> key) => ImageMarker(
key: key, key: key,
count: key.count, count: key.count,
@ -484,7 +484,7 @@ class _GeoMapState extends State<GeoMap> {
} else { } else {
markerEntry = geoEntry.entry!; markerEntry = geoEntry.entry!;
} }
final locale = context.l10n.localeName; final locale = context.locale;
final markerLocation = LatLng(geoEntry.latitude!, geoEntry.longitude!); final markerLocation = LatLng(geoEntry.latitude!, geoEntry.longitude!);
Widget markerBuilder(BuildContext context) => ImageMarker( Widget markerBuilder(BuildContext context) => ImageMarker(
count: geoEntry.pointsSize, count: geoEntry.pointsSize,

View file

@ -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/common/providers/media_query_data_provider.dart';
import 'package:aves/widgets/dialogs/aves_dialog.dart'; import 'package:aves/widgets/dialogs/aves_dialog.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class DurationDialog extends StatefulWidget { class DurationDialog extends StatefulWidget {
final int initialSeconds; final int initialSeconds;
@ -41,7 +42,10 @@ class _DurationDialogState extends State<DurationDialog> {
return MediaQueryDataProvider( return MediaQueryDataProvider(
child: Builder(builder: (context) { child: Builder(builder: (context) {
final l10n = context.l10n; final l10n = context.l10n;
final timeComponentFormatter = NumberFormat('0', context.locale);
const textStyle = TextStyle(fontSize: 34); const textStyle = TextStyle(fontSize: 34);
const digitsAlign = TextAlign.right;
return AvesDialog( return AvesDialog(
scrollableContent: [ scrollableContent: [
@ -53,9 +57,9 @@ class _DurationDialogState extends State<DurationDialog> {
children: [ children: [
TableRow( TableRow(
children: [ children: [
Center(child: Text(context.l10n.durationDialogMinutes)), Center(child: Text(l10n.durationDialogMinutes)),
const SizedBox(width: 16), const SizedBox(width: 16),
Center(child: Text(context.l10n.durationDialogSeconds)), Center(child: Text(l10n.durationDialogSeconds)),
], ],
), ),
TableRow( TableRow(
@ -66,7 +70,8 @@ class _DurationDialogState extends State<DurationDialog> {
valueNotifier: _minutes, valueNotifier: _minutes,
values: List.generate(minutesInHour, (i) => i), values: List.generate(minutesInHour, (i) => i),
textStyle: textStyle, textStyle: textStyle,
textAlign: TextAlign.end, textAlign: digitsAlign,
format: timeComponentFormatter.format,
), ),
), ),
const Padding( const Padding(
@ -82,7 +87,8 @@ class _DurationDialogState extends State<DurationDialog> {
valueNotifier: _seconds, valueNotifier: _seconds,
values: List.generate(secondsInMinute, (i) => i), values: List.generate(secondsInMinute, (i) => i),
textStyle: textStyle, textStyle: textStyle,
textAlign: TextAlign.end, textAlign: digitsAlign,
format: timeComponentFormatter.format,
), ),
), ),
], ],

View file

@ -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/widgets/dialogs/pick_dialogs/item_pick_page.dart';
import 'package:aves_model/aves_model.dart'; import 'package:aves_model/aves_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class EditEntryDateDialog extends StatefulWidget { class EditEntryDateDialog extends StatefulWidget {
@ -147,19 +148,17 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
} }
Widget _buildSetCustomContent(BuildContext context) { Widget _buildSetCustomContent(BuildContext context) {
final l10n = context.l10n;
final locale = l10n.localeName;
final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final use24hour = MediaQuery.alwaysUse24HourFormatOf(context);
return Padding( return Padding(
padding: const EdgeInsetsDirectional.only(start: 16, end: 8), padding: const EdgeInsetsDirectional.only(start: 16, end: 8),
child: Row( child: Row(
children: [ children: [
Expanded(child: Text(formatDateTime(_customDateTime, locale, use24hour))), Expanded(child: Text(formatDateTime(_customDateTime, context.locale, use24hour))),
IconButton( IconButton(
icon: const Icon(AIcons.edit), icon: const Icon(AIcons.edit),
onPressed: _editDate, onPressed: _editDate,
tooltip: l10n.changeTooltip, tooltip: context.l10n.changeTooltip,
), ),
], ],
), ),
@ -181,15 +180,13 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
} }
Widget _buildCopyItemContent(BuildContext context) { Widget _buildCopyItemContent(BuildContext context) {
final l10n = context.l10n;
final locale = l10n.localeName;
final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final use24hour = MediaQuery.alwaysUse24HourFormatOf(context);
return Padding( return Padding(
padding: const EdgeInsetsDirectional.only(start: 16, end: 8), padding: const EdgeInsetsDirectional.only(start: 16, end: 8),
child: Row( child: Row(
children: [ children: [
Expanded(child: Text(formatDateTime(copyItemDate, locale, use24hour))), Expanded(child: Text(formatDateTime(copyItemDate, context.locale, use24hour))),
const SizedBox(width: 8), const SizedBox(width: 8),
ItemPicker( ItemPicker(
extent: 48, extent: 48,
@ -202,7 +199,12 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
} }
Widget _buildShiftContent(BuildContext context) { Widget _buildShiftContent(BuildContext context) {
final l10n = context.l10n;
final timeComponentFormatter = NumberFormat('0', context.locale);
const textStyle = TextStyle(fontSize: 34); const textStyle = TextStyle(fontSize: 34);
const digitsAlign = TextAlign.right;
return Center( return Center(
child: Table( child: Table(
textDirection: timeComponentsDirection, textDirection: timeComponentsDirection,
@ -210,9 +212,9 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
TableRow( TableRow(
children: [ children: [
const SizedBox(), const SizedBox(),
Center(child: Text(context.l10n.durationDialogHours)), Center(child: Text(l10n.durationDialogHours)),
const SizedBox(width: 16), const SizedBox(width: 16),
Center(child: Text(context.l10n.durationDialogMinutes)), Center(child: Text(l10n.durationDialogMinutes)),
], ],
), ),
TableRow( TableRow(
@ -222,6 +224,7 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
values: const ['+', '-'], values: const ['+', '-'],
textStyle: textStyle, textStyle: textStyle,
textAlign: TextAlign.center, textAlign: TextAlign.center,
format: (v) => v,
), ),
Align( Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
@ -229,7 +232,8 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
valueNotifier: _shiftHour, valueNotifier: _shiftHour,
values: List.generate(hoursInDay, (i) => i), values: List.generate(hoursInDay, (i) => i),
textStyle: textStyle, textStyle: textStyle,
textAlign: TextAlign.end, textAlign: digitsAlign,
format: timeComponentFormatter.format,
), ),
), ),
const Padding( const Padding(
@ -245,7 +249,8 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
valueNotifier: _shiftMinute, valueNotifier: _shiftMinute,
values: List.generate(minutesInHour, (i) => i), values: List.generate(minutesInHour, (i) => i),
textStyle: textStyle, textStyle: textStyle,
textAlign: TextAlign.end, textAlign: digitsAlign,
format: timeComponentFormatter.format,
), ),
), ),
], ],

View file

@ -48,7 +48,7 @@ class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
final TextEditingController _latitudeController = TextEditingController(), _longitudeController = TextEditingController(); final TextEditingController _latitudeController = TextEditingController(), _longitudeController = TextEditingController();
final ValueNotifier<bool> _isValidNotifier = ValueNotifier(false); final ValueNotifier<bool> _isValidNotifier = ValueNotifier(false);
NumberFormat get coordinateFormatter => NumberFormat('0.000000', context.l10n.localeName); NumberFormat get coordinateFormatter => NumberFormat('0.000000', context.locale);
@override @override
void initState() { void initState() {

View file

@ -54,7 +54,7 @@ class _RenameEntrySetPageState extends State<RenameEntrySetPage> {
_patternTextController.addListener(_onUserPatternChanged); _patternTextController.addListener(_onUserPatternChanged);
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
locale = context.l10n.localeName; locale = context.locale;
_onUserPatternChanged(); _onUserPatternChanged();
}); });
} }

View file

@ -156,6 +156,7 @@ class RotationControlPanel extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final controller = context.watch<TransformController>(); final controller = context.watch<TransformController>();
final angleFormatter = NumberFormat('0.0°', context.locale);
return Row( return Row(
children: [ children: [
@ -172,7 +173,7 @@ class RotationControlPanel extends StatelessWidget {
divisions: 18, divisions: 18,
onChangeStart: (v) => controller.activity = TransformActivity.straighten, onChangeStart: (v) => controller.activity = TransformActivity.straighten,
onChangeEnd: (v) => controller.activity = TransformActivity.none, 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, onChanged: (v) => controller.straightenDegrees = v,
); );
}, },

View file

@ -171,8 +171,7 @@ class CoveredFilterChip<T extends CollectionFilter> extends StatelessWidget {
Color _detailColor(BuildContext context) => Theme.of(context).colorScheme.onSurfaceVariant; Color _detailColor(BuildContext context) => Theme.of(context).colorScheme.onSurfaceVariant;
Widget _buildDetails(BuildContext context, CollectionSource source, T filter) { Widget _buildDetails(BuildContext context, CollectionSource source, T filter) {
final locale = context.l10n.localeName; final countFormatter = NumberFormat.decimalPattern(context.locale);
final numberFormat = NumberFormat.decimalPattern(locale);
final padding = min<double>(8.0, extent / 16); final padding = min<double>(8.0, extent / 16);
final iconSize = detailIconSize(extent); final iconSize = detailIconSize(extent);
@ -211,7 +210,7 @@ class CoveredFilterChip<T extends CollectionFilter> extends StatelessWidget {
), ),
), ),
Text( Text(
locked ? AText.valueNotAvailable : numberFormat.format(source.count(filter)), locked ? AText.valueNotAvailable : countFormatter.format(source.count(filter)),
style: TextStyle( style: TextStyle(
color: _detailColor(context), color: _detailColor(context),
fontSize: fontSize, fontSize: fontSize,

View file

@ -36,9 +36,8 @@ class FilterDraggableThumbLabel<T extends CollectionFilter> extends StatelessWid
context.l10n.itemCount(context.read<CollectionSource>().count(filterGridItem.filter)), context.l10n.itemCount(context.read<CollectionSource>().count(filterGridItem.filter)),
]; ];
case ChipSortFactor.size: case ChipSortFactor.size:
final locale = context.l10n.localeName;
return [ return [
formatFileSize(locale, context.read<CollectionSource>().size(filterGridItem.filter)), formatFileSize(context.locale, context.read<CollectionSource>().size(filterGridItem.filter)),
]; ];
} }
}, },

View file

@ -84,10 +84,9 @@ class FilterListDetails<T extends CollectionFilter> extends StatelessWidget {
} }
Widget _buildDateRow(BuildContext context, FilterListDetailsThemeData detailsTheme, bool hasTitleLeading) { Widget _buildDateRow(BuildContext context, FilterListDetailsThemeData detailsTheme, bool hasTitleLeading) {
final locale = context.l10n.localeName;
final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final use24hour = MediaQuery.alwaysUse24HourFormatOf(context);
final date = entry?.bestDate; 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); Widget leading = const Icon(AIcons.date);
if (hasTitleLeading) { if (hasTitleLeading) {
@ -143,8 +142,6 @@ class FilterListDetails<T extends CollectionFilter> extends StatelessWidget {
child: Center(child: leading ?? const SizedBox()), child: Center(child: leading ?? const SizedBox()),
); );
final l10n = context.l10n;
final locale = l10n.localeName;
final source = context.read<CollectionSource>(); final source = context.read<CollectionSource>();
return IconTheme.merge( return IconTheme.merge(
@ -154,7 +151,7 @@ class FilterListDetails<T extends CollectionFilter> extends StatelessWidget {
leading, leading,
const SizedBox(width: 8), const SizedBox(width: 8),
Text( 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, style: detailsTheme.captionStyle,
softWrap: false, softWrap: false,
overflow: TextOverflow.fade, overflow: TextOverflow.fade,

View file

@ -28,8 +28,6 @@ class FilterListDetailsTheme extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ProxyProvider<MediaQueryData, FilterListDetailsThemeData>( return ProxyProvider<MediaQueryData, FilterListDetailsThemeData>(
update: (context, mq, previous) { update: (context, mq, previous) {
final locale = context.l10n.localeName;
final use24hour = mq.alwaysUse24HourFormat; final use24hour = mq.alwaysUse24HourFormat;
final textScaler = mq.textScaler; final textScaler = mq.textScaler;
@ -54,7 +52,7 @@ class FilterListDetailsTheme extends StatelessWidget {
titleLineHeightParagraph.dispose(); titleLineHeightParagraph.dispose();
final captionLineHeightParagraph = RenderParagraph( 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, textDirection: TextDirection.ltr,
textScaler: textScaler, textScaler: textScaler,
)..layout(const BoxConstraints(), parentUsesSize: true); )..layout(const BoxConstraints(), parentUsesSize: true);

View file

@ -16,11 +16,10 @@ class MapDateRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final locale = context.l10n.localeName;
final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final use24hour = MediaQuery.alwaysUse24HourFormatOf(context);
final date = entry?.bestDate; 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( return Text.rich(
TextSpan( TextSpan(
children: [ children: [

View file

@ -112,7 +112,6 @@ class _AppDrawerState extends State<AppDrawer> {
Widget _buildHeader(BuildContext context) { Widget _buildHeader(BuildContext context) {
final l10n = context.l10n; final l10n = context.l10n;
final locale = l10n.localeName;
Future<void> goTo(String routeName, WidgetBuilder pageBuilder) async { Future<void> goTo(String routeName, WidgetBuilder pageBuilder) async {
Navigator.maybeOf(context)?.pop(); Navigator.maybeOf(context)?.pop();
@ -153,7 +152,7 @@ class _AppDrawerState extends State<AppDrawer> {
color: Colors.white, color: Colors.white,
fontSize: 38, fontSize: 38,
fontWeight: FontWeight.w300, fontWeight: FontWeight.w300,
letterSpacing: canHaveLetterSpacing(locale) ? 1 : 0, letterSpacing: canHaveLetterSpacing(context.locale) ? 1 : 0,
fontFeatures: const [FontFeature.enable('smcp')], fontFeatures: const [FontFeature.enable('smcp')],
), ),
), ),
@ -295,7 +294,7 @@ class _AppDrawerState extends State<AppDrawer> {
return CollectionNavTile( return CollectionNavTile(
leading: const DrawerFilterIcon(filter: filter), leading: const DrawerFilterIcon(filter: filter),
title: const DrawerFilterTitle(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, filter: filter,
isSelected: () => currentCollection?.filters.contains(filter) ?? false, isSelected: () => currentCollection?.filters.contains(filter) ?? false,
); );

View file

@ -91,9 +91,6 @@ class _TvRailState extends State<TvRail> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = context.l10n;
final locale = l10n.localeName;
final navEntries = _getNavEntries(context); final navEntries = _getNavEntries(context);
return DirectionalSafeArea( return DirectionalSafeArea(
end: false, end: false,
@ -107,12 +104,12 @@ class _TvRailState extends State<TvRail> {
logo, logo,
const SizedBox(width: 16), const SizedBox(width: 16),
Text( Text(
l10n.appName, context.l10n.appName,
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 32, fontSize: 32,
fontWeight: FontWeight.w300, fontWeight: FontWeight.w300,
letterSpacing: canHaveLetterSpacing(locale) ? 1 : 0, letterSpacing: canHaveLetterSpacing(context.locale) ? 1 : 0,
fontFeatures: const [FontFeature.enable('smcp')], fontFeatures: const [FontFeature.enable('smcp')],
), ),
), ),

View file

@ -223,7 +223,7 @@ class _HistogramState extends State<Histogram> with AutomaticKeepAliveClientMixi
)..setAttribute(charts.rendererIdKey, 'customPoint'), )..setAttribute(charts.rendererIdKey, 'customPoint'),
]; ];
final locale = context.l10n.localeName; final locale = context.locale;
final timeAxisSpec = _firstDate != null && _lastDate != null final timeAxisSpec = _firstDate != null && _lastDate != null
? TimeAxisSpec.forLevel( ? TimeAxisSpec.forLevel(
locale: locale, locale: locale,
@ -232,7 +232,7 @@ class _HistogramState extends State<Histogram> with AutomaticKeepAliveClientMixi
last: _lastDate!, last: _lastDate!,
) )
: null; : null;
final measureFormat = NumberFormat.decimalPattern(locale); final tickFormatter = NumberFormat.decimalPattern(locale);
final domainAxis = charts.DateTimeAxisSpec( final domainAxis = charts.DateTimeAxisSpec(
renderSpec: charts.SmallTickRendererSpec( renderSpec: charts.SmallTickRendererSpec(
@ -254,7 +254,7 @@ class _HistogramState extends State<Histogram> with AutomaticKeepAliveClientMixi
), ),
tickFormatterSpec: charts.BasicNumericTickFormatterSpec((v) { tickFormatterSpec: charts.BasicNumericTickFormatterSpec((v) {
// localize and hide 0 // localize and hide 0
return (v == null || v == 0) ? '' : measureFormat.format(v); return (v == null || v == 0) ? '' : tickFormatter.format(v);
}), }),
), ),
defaultRenderer: charts.LineRendererConfig( defaultRenderer: charts.LineRendererConfig(
@ -304,8 +304,7 @@ class _HistogramState extends State<Histogram> with AutomaticKeepAliveClientMixi
} }
Widget _buildSelectionRow() { Widget _buildSelectionRow() {
final locale = context.l10n.localeName; final countFormatter = NumberFormat.decimalPattern(context.locale);
final numberFormat = NumberFormat.decimalPattern(locale);
return ValueListenableBuilder<_EntryByDate?>( return ValueListenableBuilder<_EntryByDate?>(
valueListenable: _selection, valueListenable: _selection,
@ -326,7 +325,7 @@ class _HistogramState extends State<Histogram> with AutomaticKeepAliveClientMixi
), ),
const Spacer(), const Spacer(),
Text( Text(
numberFormat.format(count), countFormatter.format(count),
style: TextStyle( style: TextStyle(
color: Theme.of(context).colorScheme.onSurfaceVariant, color: Theme.of(context).colorScheme.onSurfaceVariant,
), ),

View file

@ -35,8 +35,7 @@ class FilterTable<T extends Comparable> extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final locale = context.l10n.localeName; final countFormatter = NumberFormat.decimalPattern(context.locale);
final numberFormat = NumberFormat.decimalPattern(locale);
final animate = context.select<Settings, bool>((v) => v.accessibilityAnimations.animate); final animate = context.select<Settings, bool>((v) => v.accessibilityAnimations.animate);
final sortedEntries = entryCountMap.entries.toList(); final sortedEntries = entryCountMap.entries.toList();
@ -104,7 +103,7 @@ class FilterTable<T extends Comparable> extends StatelessWidget {
}, },
), ),
Text( Text(
numberFormat.format(count), countFormatter.format(count),
style: TextStyle( style: TextStyle(
color: colorScheme.onSurfaceVariant, color: colorScheme.onSurfaceVariant,
), ),

View file

@ -24,8 +24,7 @@ class MimeDonut extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final locale = context.l10n.localeName; final countFormatter = NumberFormat.decimalPattern(context.locale);
final numberFormat = NumberFormat.decimalPattern(locale);
String formatKey(d) => MimeUtils.displayType(d.key); String formatKey(d) => MimeUtils.displayType(d.key);
return AvesDonut( return AvesDonut(
@ -33,7 +32,7 @@ class MimeDonut extends StatelessWidget {
byTypes: byMimeTypes, byTypes: byMimeTypes,
animationDuration: animationDuration, animationDuration: animationDuration,
formatKey: formatKey, formatKey: formatKey,
formatValue: numberFormat.format, formatValue: countFormatter.format,
colorize: (context, d) { colorize: (context, d) {
final colors = context.read<AvesColorsData>(); final colors = context.read<AvesColorsData>();
return colors.fromString(formatKey(d)); return colors.fromString(formatKey(d));

View file

@ -16,13 +16,12 @@ class LinearPercentIndicatorText extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final locale = context.l10n.localeName; final percentFormatter = NumberFormat.percentPattern(context.locale);
final percentFormat = NumberFormat.percentPattern(locale);
return OutlinedText( return OutlinedText(
textSpans: [ textSpans: [
TextSpan( TextSpan(
text: percentFormat.format(percent), text: percentFormatter.format(percent),
style: TextStyle( style: TextStyle(
shadows: Theme.of(context).isDark ? AStyles.embossShadows : null, shadows: Theme.of(context).isDark ? AStyles.embossShadows : null,
), ),

View file

@ -168,7 +168,7 @@ class _StatsPageState extends State<StatsPage> with FeedbackMixin, VaultAwareMix
const Icon(AIcons.size), const Icon(AIcons.size),
const SizedBox(width: 16), const SizedBox(width: 16),
Expanded( Expanded(
child: Text(formatFileSize(l10n.localeName, _totalSizeBytes)), child: Text(formatFileSize(context.locale, _totalSizeBytes)),
), ),
], ],
), ),

View file

@ -299,7 +299,7 @@ class _BasicInfoState extends State<_BasicInfo> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = context.l10n; final l10n = context.l10n;
final infoUnknown = l10n.viewerInfoUnknown; final infoUnknown = l10n.viewerInfoUnknown;
final locale = l10n.localeName; final locale = context.locale;
final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); 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 // 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 // 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; final isPhoto = [MimeTypes.heic, MimeTypes.heif, MimeTypes.jpeg, MimeTypes.tiff].contains(entry.mimeType) || entry.isRaw;
if (isPhoto) { if (isPhoto) {
final numberFormat = NumberFormat('0', locale);
final megaPixels = (entry.width * entry.height / 1000000).round(); final megaPixels = (entry.width * entry.height / 1000000).round();
if (megaPixels > 0) { if (megaPixels > 0) {
s += '${numberFormat.format(megaPixels)} MP'; s += '${NumberFormat('0', locale).format(megaPixels)} MP';
} }
} }

View file

@ -21,7 +21,7 @@ class OverlayDateRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final locale = context.l10n.localeName; final locale = context.locale;
final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final use24hour = MediaQuery.alwaysUse24HourFormatOf(context);
final date = entry.bestDate; final date = entry.bestDate;

View file

@ -17,7 +17,7 @@ class OverlayShootingRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final locale = context.l10n.localeName; final locale = context.locale;
final aperture = details.aperture; final aperture = details.aperture;
final apertureText = aperture != null ? 'ƒ/${NumberFormat('0.0', locale).format(aperture)}' : AText.valueNotAvailable; final apertureText = aperture != null ? 'ƒ/${NumberFormat('0.0', locale).format(aperture)}' : AText.valueNotAvailable;

View file

@ -9,7 +9,7 @@ import 'package:latlong2/latlong.dart';
class ImageMarker extends StatelessWidget { class ImageMarker extends StatelessWidget {
final int? count; final int? count;
final intl.NumberFormat numberFormat; final intl.NumberFormat countFormatter;
final bool drawArrow; final bool drawArrow;
final Widget Function(double extent) buildThumbnailImage; final Widget Function(double extent) buildThumbnailImage;
@ -28,7 +28,7 @@ class ImageMarker extends StatelessWidget {
required String locale, required String locale,
this.drawArrow = true, this.drawArrow = true,
required this.buildThumbnailImage, required this.buildThumbnailImage,
}) : numberFormat = intl.NumberFormat.decimalPattern(locale); }) : countFormatter = intl.NumberFormat.decimalPattern(locale);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -110,7 +110,7 @@ class ImageMarker extends StatelessWidget {
), ),
), ),
child: Text( child: Text(
numberFormat.format(count), countFormatter.format(count),
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: theme.colorScheme.onPrimary, color: theme.colorScheme.onPrimary,