country locale fixes
This commit is contained in:
parent
5db804c0e7
commit
85a0c504d6
10 changed files with 40 additions and 28 deletions
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:aves/geo/countries.dart';
|
import 'package:aves/geo/countries.dart';
|
||||||
import 'package:aves/model/entry_cache.dart';
|
import 'package:aves/model/entry_cache.dart';
|
||||||
|
@ -9,7 +10,6 @@ import 'package:aves/model/metadata/catalog.dart';
|
||||||
import 'package:aves/model/metadata/date_modifier.dart';
|
import 'package:aves/model/metadata/date_modifier.dart';
|
||||||
import 'package:aves/model/metadata/enums.dart';
|
import 'package:aves/model/metadata/enums.dart';
|
||||||
import 'package:aves/model/multipage.dart';
|
import 'package:aves/model/multipage.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
|
||||||
import 'package:aves/model/video/metadata.dart';
|
import 'package:aves/model/video/metadata.dart';
|
||||||
import 'package:aves/ref/mime_types.dart';
|
import 'package:aves/ref/mime_types.dart';
|
||||||
import 'package:aves/services/common/service_policy.dart';
|
import 'package:aves/services/common/service_policy.dart';
|
||||||
|
@ -21,7 +21,6 @@ import 'package:aves/utils/change_notifier.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:country_code/country_code.dart';
|
import 'package:country_code/country_code.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
|
|
||||||
class AvesEntry {
|
class AvesEntry {
|
||||||
|
@ -469,11 +468,11 @@ class AvesEntry {
|
||||||
addressChangeNotifier.notifyListeners();
|
addressChangeNotifier.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> locate({required bool background, required bool force}) async {
|
Future<void> locate({required bool background, required bool force, required Locale geocoderLocale}) async {
|
||||||
if (!hasGps) return;
|
if (!hasGps) return;
|
||||||
await _locateCountry(force: force);
|
await _locateCountry(force: force);
|
||||||
if (await availability.canLocatePlaces) {
|
if (await availability.canLocatePlaces) {
|
||||||
await locatePlace(background: background, force: force);
|
await locatePlace(background: background, force: force, geocoderLocale: geocoderLocale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,15 +492,8 @@ class AvesEntry {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String? _geocoderLocale;
|
|
||||||
|
|
||||||
String get geocoderLocale {
|
|
||||||
_geocoderLocale ??= (settings.locale ?? WidgetsBinding.instance!.window.locale).toString();
|
|
||||||
return _geocoderLocale!;
|
|
||||||
}
|
|
||||||
|
|
||||||
// full reverse geocoding, requiring Play Services and some connectivity
|
// full reverse geocoding, requiring Play Services and some connectivity
|
||||||
Future<void> locatePlace({required bool background, required bool force}) async {
|
Future<void> locatePlace({required bool background, required bool force, required Locale geocoderLocale}) async {
|
||||||
if (!hasGps || (hasFineAddress && !force)) return;
|
if (!hasGps || (hasFineAddress && !force)) return;
|
||||||
try {
|
try {
|
||||||
Future<List<Address>> call() => GeocodingService.getAddress(latLng!, geocoderLocale);
|
Future<List<Address>> call() => GeocodingService.getAddress(latLng!, geocoderLocale);
|
||||||
|
@ -531,7 +523,7 @@ class AvesEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> findAddressLine() async {
|
Future<String?> findAddressLine({required Locale geocoderLocale}) async {
|
||||||
if (!hasGps) return null;
|
if (!hasGps) return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -608,7 +600,7 @@ class AvesEntry {
|
||||||
metadataChangeNotifier.notifyListeners();
|
metadataChangeNotifier.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> refresh({required bool background, required bool persist, required bool force}) async {
|
Future<void> refresh({required bool background, required bool persist, required bool force, required Locale geocoderLocale}) async {
|
||||||
_catalogMetadata = null;
|
_catalogMetadata = null;
|
||||||
_addressDetails = null;
|
_addressDetails = null;
|
||||||
_bestDate = null;
|
_bestDate = null;
|
||||||
|
@ -622,7 +614,7 @@ class AvesEntry {
|
||||||
if (updated != null) {
|
if (updated != null) {
|
||||||
await _applyNewFields(updated.toMap(), persist: persist);
|
await _applyNewFields(updated.toMap(), persist: persist);
|
||||||
await catalog(background: background, persist: persist, force: force);
|
await catalog(background: background, persist: persist, force: force);
|
||||||
await locate(background: background, force: force);
|
await locate(background: background, force: force, geocoderLocale: geocoderLocale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import 'package:aves/services/common/services.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
final Settings settings = Settings._private();
|
final Settings settings = Settings._private();
|
||||||
|
@ -202,6 +203,17 @@ class Settings extends ChangeNotifier {
|
||||||
].join(localeSeparator);
|
].join(localeSeparator);
|
||||||
}
|
}
|
||||||
setAndNotify(localeKey, tag);
|
setAndNotify(localeKey, tag);
|
||||||
|
_appliedLocale = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Locale? _appliedLocale;
|
||||||
|
|
||||||
|
Locale get appliedLocale {
|
||||||
|
if (_appliedLocale == null) {
|
||||||
|
final preferredLocale = locale;
|
||||||
|
_appliedLocale = basicLocaleListResolution(preferredLocale != null ? [preferredLocale] : null, AppLocalizations.supportedLocales);
|
||||||
|
}
|
||||||
|
return _appliedLocale!;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get mustBackTwiceToExit => getBoolOrDefault(mustBackTwiceToExitKey, SettingsDefaults.mustBackTwiceToExit);
|
bool get mustBackTwiceToExit => getBoolOrDefault(mustBackTwiceToExitKey, SettingsDefaults.mustBackTwiceToExit);
|
||||||
|
|
|
@ -264,7 +264,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
|
||||||
Future<Set<String>> refreshUris(Set<String> changedUris, {AnalysisController? analysisController});
|
Future<Set<String>> refreshUris(Set<String> changedUris, {AnalysisController? analysisController});
|
||||||
|
|
||||||
Future<void> refreshEntry(AvesEntry entry) async {
|
Future<void> refreshEntry(AvesEntry entry) async {
|
||||||
await entry.refresh(background: false, persist: true, force: true);
|
await entry.refresh(background: false, persist: true, force: true, geocoderLocale: settings.appliedLocale);
|
||||||
updateDerivedFilters({entry});
|
updateDerivedFilters({entry});
|
||||||
eventBus.fire(EntryRefreshedEvent({entry}));
|
eventBus.fire(EntryRefreshedEvent({entry}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'package:aves/geo/countries.dart';
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/filters/location.dart';
|
import 'package:aves/model/filters/location.dart';
|
||||||
import 'package:aves/model/metadata/address.dart';
|
import 'package:aves/model/metadata/address.dart';
|
||||||
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/analysis_controller.dart';
|
import 'package:aves/model/source/analysis_controller.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/model/source/enums.dart';
|
import 'package:aves/model/source/enums.dart';
|
||||||
|
@ -110,7 +111,7 @@ mixin LocationMixin on SourceBase {
|
||||||
if (knownLocations.containsKey(latLng)) {
|
if (knownLocations.containsKey(latLng)) {
|
||||||
entry.addressDetails = knownLocations[latLng]?.copyWith(contentId: entry.contentId);
|
entry.addressDetails = knownLocations[latLng]?.copyWith(contentId: entry.contentId);
|
||||||
} else {
|
} else {
|
||||||
await entry.locatePlace(background: true, force: force);
|
await entry.locatePlace(background: true, force: force, geocoderLocale: settings.appliedLocale);
|
||||||
// it is intended to insert `null` if the geocoder failed,
|
// it is intended to insert `null` if the geocoder failed,
|
||||||
// so that we skip geocoding of following entries with the same coordinates
|
// so that we skip geocoding of following entries with the same coordinates
|
||||||
knownLocations[latLng] = entry.addressDetails;
|
knownLocations[latLng] = entry.addressDetails;
|
||||||
|
@ -153,9 +154,15 @@ mixin LocationMixin on SourceBase {
|
||||||
// so we merge countries by code, keeping only one name for each code
|
// so we merge countries by code, keeping only one name for each code
|
||||||
final countriesByCode = Map.fromEntries(locations.map((address) {
|
final countriesByCode = Map.fromEntries(locations.map((address) {
|
||||||
final code = address.countryCode;
|
final code = address.countryCode;
|
||||||
return code?.isNotEmpty == true ? MapEntry(code, address.countryName) : null;
|
if (code == null || code.isEmpty) return null;
|
||||||
|
return MapEntry(code, address.countryName);
|
||||||
}).whereNotNull());
|
}).whereNotNull());
|
||||||
final updatedCountries = countriesByCode.entries.map((kv) => '${kv.value}${LocationFilter.locationSeparator}${kv.key}').toList()..sort(compareAsciiUpperCase);
|
final updatedCountries = countriesByCode.entries.map((kv) {
|
||||||
|
final code = kv.key;
|
||||||
|
final name = kv.value;
|
||||||
|
return '${name != null && name.isNotEmpty ? name : code}${LocationFilter.locationSeparator}$code';
|
||||||
|
}).toList()
|
||||||
|
..sort(compareAsciiUpperCase);
|
||||||
if (!listEquals(updatedCountries, sortedCountries)) {
|
if (!listEquals(updatedCountries, sortedCountries)) {
|
||||||
sortedCountries = List.unmodifiable(updatedCountries);
|
sortedCountries = List.unmodifiable(updatedCountries);
|
||||||
invalidateCountryFilterSummary();
|
invalidateCountryFilterSummary();
|
||||||
|
|
|
@ -98,9 +98,7 @@ class Analyzer {
|
||||||
debugPrint('$runtimeType start');
|
debugPrint('$runtimeType start');
|
||||||
_serviceStateNotifier.value = AnalyzerState.running;
|
_serviceStateNotifier.value = AnalyzerState.running;
|
||||||
|
|
||||||
final preferredLocale = settings.locale;
|
_l10n = await AppLocalizations.delegate.load(settings.appliedLocale);
|
||||||
final appLocale = basicLocaleListResolution(preferredLocale != null ? [preferredLocale] : null, AppLocalizations.supportedLocales);
|
|
||||||
_l10n = await AppLocalizations.delegate.load(appLocale);
|
|
||||||
|
|
||||||
_controller.stopSignal.value = false;
|
_controller.stopSignal.value = false;
|
||||||
await _source.init();
|
await _source.init();
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
@ -9,12 +10,12 @@ class GeocodingService {
|
||||||
static const platform = MethodChannel('deckers.thibault/aves/geocoding');
|
static const platform = MethodChannel('deckers.thibault/aves/geocoding');
|
||||||
|
|
||||||
// geocoding requires Google Play Services
|
// geocoding requires Google Play Services
|
||||||
static Future<List<Address>> getAddress(LatLng coordinates, String locale) async {
|
static Future<List<Address>> getAddress(LatLng coordinates, Locale locale) async {
|
||||||
try {
|
try {
|
||||||
final result = await platform.invokeMethod('getAddress', <String, dynamic>{
|
final result = await platform.invokeMethod('getAddress', <String, dynamic>{
|
||||||
'latitude': coordinates.latitude,
|
'latitude': coordinates.latitude,
|
||||||
'longitude': coordinates.longitude,
|
'longitude': coordinates.longitude,
|
||||||
'locale': locale,
|
'locale': locale.toString(),
|
||||||
// we only really need one address, but sometimes the native geocoder
|
// we only really need one address, but sometimes the native geocoder
|
||||||
// returns nothing with `maxResults` of 1, but succeeds with `maxResults` of 2+
|
// returns nothing with `maxResults` of 1, but succeeds with `maxResults` of 2+
|
||||||
'maxResults': 2,
|
'maxResults': 2,
|
||||||
|
|
|
@ -147,7 +147,7 @@ class _AddressRowState extends State<_AddressRow> {
|
||||||
|
|
||||||
Future<String?> _getAddressLine(AvesEntry? entry) async {
|
Future<String?> _getAddressLine(AvesEntry? entry) async {
|
||||||
if (entry != null && await availability.canLocatePlaces) {
|
if (entry != null && await availability.canLocatePlaces) {
|
||||||
final addresses = await GeocodingService.getAddress(entry.latLng!, entry.geocoderLocale);
|
final addresses = await GeocodingService.getAddress(entry.latLng!, settings.appliedLocale);
|
||||||
if (addresses.isNotEmpty) {
|
if (addresses.isNotEmpty) {
|
||||||
final address = addresses.first;
|
final address = addresses.first;
|
||||||
return address.addressLine;
|
return address.addressLine;
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/collection_lens.dart';
|
import 'package:aves/model/source/collection_lens.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
import 'package:aves/widgets/common/magnifier/pan/scroll_physics.dart';
|
import 'package:aves/widgets/common/magnifier/pan/scroll_physics.dart';
|
||||||
|
@ -169,7 +170,7 @@ class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
|
||||||
// so that we can display the address instead of coordinates
|
// so that we can display the address instead of coordinates
|
||||||
// even when initial collection locating has not reached this entry yet
|
// even when initial collection locating has not reached this entry yet
|
||||||
await _entry.catalog(background: false, persist: true, force: false);
|
await _entry.catalog(background: false, persist: true, force: false);
|
||||||
await _entry.locate(background: false, force: false);
|
await _entry.locate(background: false, force: false, geocoderLocale: settings.appliedLocale);
|
||||||
} else {
|
} else {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:aves/model/actions/entry_info_actions.dart';
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/metadata/date_modifier.dart';
|
import 'package:aves/model/metadata/date_modifier.dart';
|
||||||
import 'package:aves/model/metadata/enums.dart';
|
import 'package:aves/model/metadata/enums.dart';
|
||||||
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/widgets/common/action_mixins/feedback.dart';
|
import 'package:aves/widgets/common/action_mixins/feedback.dart';
|
||||||
import 'package:aves/widgets/common/action_mixins/permission_aware.dart';
|
import 'package:aves/widgets/common/action_mixins/permission_aware.dart';
|
||||||
|
@ -42,7 +43,7 @@ class EntryInfoActionDelegate with FeedbackMixin, PermissionAwareMixin {
|
||||||
if (_isMainMode(context) && source != null) {
|
if (_isMainMode(context) && source != null) {
|
||||||
await source.refreshEntry(entry);
|
await source.refreshEntry(entry);
|
||||||
} else {
|
} else {
|
||||||
await entry.refresh(background: false, persist: false, force: true);
|
await entry.refresh(background: false, persist: false, force: true, geocoderLocale: settings.appliedLocale);
|
||||||
}
|
}
|
||||||
showFeedback(context, l10n.genericSuccessFeedback);
|
showFeedback(context, l10n.genericSuccessFeedback);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -158,7 +158,7 @@ class _AddressInfoGroupState extends State<_AddressInfoGroup> {
|
||||||
super.initState();
|
super.initState();
|
||||||
_addressLineLoader = availability.canLocatePlaces.then((connected) {
|
_addressLineLoader = availability.canLocatePlaces.then((connected) {
|
||||||
if (connected) {
|
if (connected) {
|
||||||
return entry.findAddressLine();
|
return entry.findAddressLine(geocoderLocale: settings.appliedLocale);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue