easy_localization icon indicating copy to clipboard operation
easy_localization copied to clipboard

startLocale may not be used

Open emri99 opened this issue 3 years ago • 3 comments

Depending on arguments passed to the EasyLocalization widget, the startLocale is not used.

Problem encountered The device locale is used as initial locale even if we supply another value in startLocale argument.

Why is this happenning ? In our case, this happens because we explicitly ask the widget not to handle save & restoration to handle it in our app, and we store the locale in SharedPreferences with the same key than this package.

Context to reproduce To get into this usecase :

  • A locale must be saved in sharedPreferences as locale key (I think its value is not important, but it must exists)
  • When instanciating EasyLocalisationwiget:
    • saveLocale argument must be set to false
    • startLocale argument must be supply optionally the same as saved in locale key, but at least it must be different of the device locale otherwise the issue is not visible

Source code issue explanation Source code of controller where the problem occurs annotated :

class EasyLocalizationController extends ChangeNotifier {
  static Locale? _savedLocale;   ## value initialized in static method
                                 ## initEasyLocation
  // ....

  EasyLocalizationController({
    // ....
    required this.saveLocale,  # false
    // ....
    Locale? startLocale,   # value initialized to anything else than device locale to see the problem
    // ....
  }) {
    _fallbackLocale = fallbackLocale;
    if (forceLocale != null) {
      _locale = forceLocale;

   // #### ISSUE IS HERE #####
   // #### startLocale is NOT USED because the `_savedLocale` is read ####
   // #### from the `locale` SharedPreferences key, which is the one ####
   // #### we use internally in our app ####
    } else if (_savedLocale == null && startLocale != null) {
      _locale = _getFallbackLocale(supportedLocales, startLocale);
      EasyLocalization.logger('Start locale loaded ${_locale.toString()}');
    }

    // ####
    // #### It don't match this condition neither as `saveLocale` is false ####
    // If saved locale then get
    else if (saveLocale && _savedLocale != null) {
      EasyLocalization.logger('Saved locale loaded ${_savedLocale.toString()}');
      _locale = _savedLocale!;

    // ####
    // #### so although we supply a startLocale, it's ignored ####
    // #### and the device locale is used ####
    } else {
      // From Device Locale
      _locale = supportedLocales.firstWhere(
          (locale) => _checkInitLocale(locale, _deviceLocale),
          orElse: () => _getFallbackLocale(supportedLocales, fallbackLocale));
    }
  // ...

  
  static Future<void> initEasyLocation() async {
    final _preferences = await SharedPreferences.getInstance();

    // #### read from SharedPreferences that can be written easily ####
    // #### outside of this class due to a too common SP key ####
    final _strLocale = _preferences.getString('locale');
    _savedLocale = _strLocale != null ? _strLocale.toLocale() : null;

  // ...

Potential resolution IMHO, the locale SharedPreferences key is too common and can conflict with the application one, I think it should be more package specific like easy_localization_locale.

emri99 avatar Sep 10 '21 12:09 emri99

+1 same issue.

jgoyvaerts avatar Apr 26 '22 11:04 jgoyvaerts

A workaround is to rename your own sharedpreferences key containing the expected locale to use ;)

emri99 avatar Apr 26 '22 11:04 emri99

A workaround is to rename your own sharedpreferences key containing the expected locale to use ;)

Yea, we did that, still annoying though :)

jgoyvaerts avatar Apr 26 '22 11:04 jgoyvaerts