diff --git a/lib/model/filters/coordinate.dart b/lib/model/filters/coordinate.dart index 4a17edb2e..57b7b4ebe 100644 --- a/lib/model/filters/coordinate.dart +++ b/lib/model/filters/coordinate.dart @@ -4,12 +4,10 @@ import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/settings/enums/coordinate_format.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves_map/aves_map.dart'; import 'package:aves_model/aves_model.dart'; import 'package:flutter/widgets.dart'; import 'package:latlong2/latlong.dart'; -import 'package:provider/provider.dart'; class CoordinateFilter extends CollectionFilter { static const type = 'coordinate'; @@ -45,24 +43,30 @@ class CoordinateFilter extends CollectionFilter { @override EntryFilter get positiveTest => _test; - String _formatBounds(AppLocalizations l10n, CoordinateFormat format) { - String s(LatLng latLng) => format.format( - l10n, - latLng, - minuteSecondPadding: minuteSecondPadding, - dmsSecondDecimals: 0, - ); - return '${s(ne)}\n${s(sw)}'; - } + String _formatBounds(String Function(LatLng latLng) s) => '${s(ne)}\n${s(sw)}'; @override bool get exclusiveProp => false; @override - String get universalLabel => _formatBounds(lookupAppLocalizations(AppLocalizations.supportedLocales.first), CoordinateFormat.decimal); + String get universalLabel { + return _formatBounds((latLng) => CoordinateFormat.decimal.formatWithoutDirectionality( + lookupAppLocalizations(AppLocalizations.supportedLocales.first), + latLng, + minuteSecondPadding: minuteSecondPadding, + dmsSecondDecimals: 0, + )); + } @override - String getLabel(BuildContext context) => _formatBounds(context.l10n, context.read().coordinateFormat); + String getLabel(BuildContext context) { + return _formatBounds((latLng) => settings.coordinateFormat.format( + context, + latLng, + minuteSecondPadding: minuteSecondPadding, + dmsSecondDecimals: 0, + )); + } @override Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.geoBounds, size: size); diff --git a/lib/model/settings/enums/coordinate_format.dart b/lib/model/settings/enums/coordinate_format.dart index ed81bad64..ca5835744 100644 --- a/lib/model/settings/enums/coordinate_format.dart +++ b/lib/model/settings/enums/coordinate_format.dart @@ -1,12 +1,19 @@ import 'package:aves/l10n/l10n.dart'; +import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves_model/aves_model.dart'; +import 'package:flutter/widgets.dart'; import 'package:intl/intl.dart'; import 'package:latlong2/latlong.dart'; extension ExtraCoordinateFormat on CoordinateFormat { static const _separator = ', '; - String format(AppLocalizations l10n, LatLng latLng, {bool minuteSecondPadding = false, int dmsSecondDecimals = 2}) { + String format(BuildContext context, LatLng latLng, {bool minuteSecondPadding = false, int dmsSecondDecimals = 2}) { + final text = formatWithoutDirectionality(context.l10n, latLng, minuteSecondPadding: minuteSecondPadding, dmsSecondDecimals: dmsSecondDecimals); + return context.applyDirectionality(text); + } + + String formatWithoutDirectionality(AppLocalizations l10n, LatLng latLng, {bool minuteSecondPadding = false, int dmsSecondDecimals = 2}) { switch (this) { case CoordinateFormat.dms: return toDMS(l10n, latLng, minuteSecondPadding: minuteSecondPadding, secondDecimals: dmsSecondDecimals).join(_separator); diff --git a/lib/widgets/collection/grid/list_details.dart b/lib/widgets/collection/grid/list_details.dart index 1175dc0bd..774eb511d 100644 --- a/lib/widgets/collection/grid/list_details.dart +++ b/lib/widgets/collection/grid/list_details.dart @@ -97,7 +97,7 @@ class EntryListDetails extends StatelessWidget { } Widget _buildLocationRow(BuildContext context, TextStyle style) { - final location = entry.hasAddress ? entry.shortAddress : settings.coordinateFormat.format(context.l10n, entry.latLng!); + final location = entry.hasAddress ? entry.shortAddress : settings.coordinateFormat.format(context, entry.latLng!); return _buildRow( [ diff --git a/lib/widgets/common/extensions/build_context.dart b/lib/widgets/common/extensions/build_context.dart index 6a4a86af0..7a5585e74 100644 --- a/lib/widgets/common/extensions/build_context.dart +++ b/lib/widgets/common/extensions/build_context.dart @@ -1,4 +1,5 @@ import 'package:aves/l10n/l10n.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; extension ExtraContext on BuildContext { @@ -6,5 +7,17 @@ extension ExtraContext on BuildContext { AppLocalizations get l10n => AppLocalizations.of(this)!; + bool get isArabic => l10n.localeName.startsWith('ar'); + bool get isRtl => Directionality.of(this) == TextDirection.rtl; + + String applyDirectionality(String text) => '$_directionalityMark$text'; + + String get _directionalityMark { + if (isRtl) { + return isArabic ? Unicode.ALM : Unicode.RLM; + } else { + return Unicode.LRM; + } + } } diff --git a/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart b/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart index 82f928955..af859416c 100644 --- a/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart +++ b/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart @@ -330,7 +330,7 @@ class _CoordinateRow extends StatelessWidget { const SizedBox(width: _LocationInfo.iconPadding), Expanded( child: Text( - location != null ? settings.coordinateFormat.format(context.l10n, location!) : AText.valueNotAvailable, + location != null ? settings.coordinateFormat.format(context, location!) : AText.valueNotAvailable, strutStyle: AStyles.overflowStrut, softWrap: false, overflow: TextOverflow.fade, diff --git a/lib/widgets/map/address_row.dart b/lib/widgets/map/address_row.dart index 983d7ca06..6c760d9e5 100644 --- a/lib/widgets/map/address_row.dart +++ b/lib/widgets/map/address_row.dart @@ -7,7 +7,6 @@ import 'package:aves/services/geocoding_service.dart'; import 'package:aves/theme/icons.dart'; import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; -import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:flutter/material.dart'; import 'info_row.dart'; @@ -65,7 +64,7 @@ class _MapAddressRowState extends State { ? AText.valueNotAvailable : entry.hasAddress ? entry.shortAddress - : settings.coordinateFormat.format(context.l10n, entry.latLng!)); + : settings.coordinateFormat.format(context, entry.latLng!)); return Text.rich( TextSpan( children: [ diff --git a/lib/widgets/settings/language/language.dart b/lib/widgets/settings/language/language.dart index be642a582..f866c9bea 100644 --- a/lib/widgets/settings/language/language.dart +++ b/lib/widgets/settings/language/language.dart @@ -56,7 +56,7 @@ class SettingsTileLanguageCoordinateFormat extends SettingsTile { onSelection: (v) => settings.coordinateFormat = v, tileTitle: title(context), dialogTitle: context.l10n.settingsCoordinateFormatDialogTitle, - optionSubtitleBuilder: (value) => value.format(context.l10n, PointsOfInterest.pointNemo), + optionSubtitleBuilder: (value) => value.format(context, PointsOfInterest.pointNemo), ); } diff --git a/lib/widgets/viewer/info/basic_section.dart b/lib/widgets/viewer/info/basic_section.dart index 16bd68d55..ff76fd69c 100644 --- a/lib/widgets/viewer/info/basic_section.dart +++ b/lib/widgets/viewer/info/basic_section.dart @@ -330,8 +330,8 @@ class _BasicInfoState extends State<_BasicInfo> { l10n.viewerInfoLabelTitle: title, l10n.viewerInfoLabelDate: dateText, if (entry.isVideo) ..._buildVideoRows(context), - if (showResolution) l10n.viewerInfoLabelResolution: _forceDirectionality(rasterResolutionText), - l10n.viewerInfoLabelSize: _forceDirectionality(sizeText), + if (showResolution) l10n.viewerInfoLabelResolution: context.applyDirectionality(rasterResolutionText), + l10n.viewerInfoLabelSize: context.applyDirectionality(sizeText), if (!entry.trashed) l10n.viewerInfoLabelUri: entry.uri, if (path != null) l10n.viewerInfoLabelPath: path, if (ownerPackage != null) l10n.viewerInfoLabelOwner: ownerPackage, @@ -383,6 +383,4 @@ class _BasicInfoState extends State<_BasicInfo> { ), ]; } - - String _forceDirectionality(String text) => context.isRtl ? '${Unicode.RLI}$text${Unicode.PDI}' : '${Unicode.LRI}$text${Unicode.PDI}'; } diff --git a/lib/widgets/viewer/info/location_section.dart b/lib/widgets/viewer/info/location_section.dart index df001809f..84606cb3b 100644 --- a/lib/widgets/viewer/info/location_section.dart +++ b/lib/widgets/viewer/info/location_section.dart @@ -201,7 +201,7 @@ class _AddressInfoGroupState extends State<_AddressInfoGroup> { final l10n = context.l10n; return InfoRowGroup( info: { - l10n.viewerInfoLabelCoordinates: settings.coordinateFormat.format(l10n, entry.latLng!), + l10n.viewerInfoLabelCoordinates: settings.coordinateFormat.format(context, entry.latLng!), if (address.isNotEmpty) l10n.viewerInfoLabelAddress: address, }, ); diff --git a/lib/widgets/viewer/overlay/details/location.dart b/lib/widgets/viewer/overlay/details/location.dart index b646168e6..12b7126be 100644 --- a/lib/widgets/viewer/overlay/details/location.dart +++ b/lib/widgets/viewer/overlay/details/location.dart @@ -5,7 +5,6 @@ import 'package:aves/model/settings/settings.dart'; import 'package:aves/theme/icons.dart'; import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; -import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/viewer/overlay/details/details.dart'; import 'package:decorated_icon/decorated_icon.dart'; import 'package:flutter/material.dart'; @@ -27,7 +26,7 @@ class OverlayLocationRow extends AnimatedWidget { if (location == null || location.isEmpty) { final latLng = entry.latLng; if (latLng != null) { - location = settings.coordinateFormat.format(context.l10n, latLng); + location = settings.coordinateFormat.format(context, latLng); } } return Row(