Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance Text Translation Functionality for Localization #665

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions lib/src/easy_localization_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,8 @@ class _EasyLocalizationState extends State<EasyLocalization> {
useOnlyLangCode: widget.useOnlyLangCode,
useFallbackTranslations: widget.useFallbackTranslations,
path: widget.path,
onLoadError: (FlutterError e) {
setState(() {
translationsLoadError = e;
});
},
onLoadError: (FlutterError e) =>
setState(() => translationsLoadError = e),
);
// causes localization to rebuild with new language
localizationController!.addListener(() {
Expand Down Expand Up @@ -219,9 +216,12 @@ class _EasyLocalizationProvider extends InheritedWidget {

// _EasyLocalizationDelegate get delegate => parent.delegate;

_EasyLocalizationProvider(this.parent, this._localeState,
{Key? key, required this.delegate})
: currentLocale = _localeState.locale,
_EasyLocalizationProvider(
this.parent,
this._localeState, {
Key? key,
required this.delegate,
}) : currentLocale = _localeState.locale,
super(key: key, child: parent.child) {
EasyLocalization.logger.debug('Init provider');
}
Expand Down Expand Up @@ -269,8 +269,10 @@ class _EasyLocalizationDelegate extends LocalizationsDelegate<Localization> {
/// * use only the lang code to generate i18n file path like en.json or ar.json
// final bool useOnlyLangCode;

_EasyLocalizationDelegate(
{this.localizationController, this.supportedLocales}) {
_EasyLocalizationDelegate({
this.localizationController,
this.supportedLocales,
}) {
EasyLocalization.logger.debug('Init Localization Delegate');
}

Expand All @@ -280,13 +282,17 @@ class _EasyLocalizationDelegate extends LocalizationsDelegate<Localization> {
@override
Future<Localization> load(Locale value) async {
EasyLocalization.logger.debug('Load Localization Delegate');
if (localizationController!.translations == null) {

if (localizationController!.translations.isEmpty) {
await localizationController!.loadTranslations();
}

Localization.load(value,
translations: localizationController!.translations,
fallbackTranslations: localizationController!.fallbackTranslations);
Localization.load(
value,
fallbackTranslations: localizationController!.fallbackTranslations,
translations: localizationController!.translations,
);

return Future.value(Localization.instance);
}

Expand Down
96 changes: 64 additions & 32 deletions lib/src/easy_localization_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,39 @@ import 'translations.dart';

class EasyLocalizationController extends ChangeNotifier {
static Locale? _savedLocale;

static late Locale _deviceLocale;

late Locale _locale;

Locale? _fallbackLocale;

final Function(FlutterError e) onLoadError;

final AssetLoader assetLoader;

final String path;

final List<Locale> supportedLocales;

final bool useFallbackTranslations;

final bool saveLocale;

final bool useOnlyLangCode;

List<AssetLoader>? extraAssetLoaders;
Translations? _translations, _fallbackTranslations;
Translations? get translations => _translations;

final Map<Locale, Translations> _allTranslations = {};

Map<Locale, Translations> get translations => _allTranslations;

Translations? _fallbackTranslations;

Translations? get fallbackTranslations => _fallbackTranslations;

EasyLocalizationController({
required List<Locale> supportedLocales,
required this.supportedLocales,
required this.useFallbackTranslations,
required this.saveLocale,
required this.assetLoader,
Expand Down Expand Up @@ -77,34 +92,43 @@ class EasyLocalizationController extends ChangeNotifier {

//Get fallback Locale
static Locale _getFallbackLocale(
List<Locale> supportedLocales, Locale? fallbackLocale) {
//If fallbackLocale not set then return first from supportedLocales
if (fallbackLocale != null) {
return fallbackLocale;
} else {
return supportedLocales.first;
}
List<Locale> supportedLocales,
Locale? fallbackLocale,
) {
return fallbackLocale ?? supportedLocales.first;
}

Future loadTranslations() async {
Map<String, dynamic> data;
try {
data = Map.from(await loadTranslationData(_locale));
_translations = Translations(data);
Map<Locale, Map<String, dynamic>> allTranslationData =
await loadAllTranslationData();

allTranslationData.forEach((key, value) {
_allTranslations.addAll({key: Translations(value)});
});

if (useFallbackTranslations && _fallbackLocale != null) {
Map<String, dynamic>? baseLangData;

if (_locale.countryCode != null && _locale.countryCode!.isNotEmpty) {
baseLangData =
await loadBaseLangTranslationData(Locale(locale.languageCode));
try {
baseLangData = allTranslationData[Locale(locale.languageCode)];
} on FlutterError catch (e) {
// Disregard asset not found FlutterError when attempting to load base language fallback
EasyLocalization.logger.warning(e.message);
}
}
data = Map.from(await loadTranslationData(_fallbackLocale!));

Map<String, dynamic> data = allTranslationData[_fallbackLocale]!;

if (baseLangData != null) {
try {
data.addAll(baseLangData);
} on UnsupportedError {
data = Map.of(data)..addAll(baseLangData);
}
}

_fallbackTranslations = Translations(data);
}
} on FlutterError catch (e) {
Expand All @@ -114,17 +138,6 @@ class EasyLocalizationController extends ChangeNotifier {
}
}

Future<Map<String, dynamic>?> loadBaseLangTranslationData(
Locale locale) async {
try {
return await loadTranslationData(Locale(locale.languageCode));
} on FlutterError catch (e) {
// Disregard asset not found FlutterError when attempting to load base language fallback
EasyLocalization.logger.warning(e.message);
}
return null;
}

Future<Map<String, dynamic>> loadTranslationData(Locale locale) async =>
_combineAssetLoaders(
path: path,
Expand All @@ -134,15 +147,31 @@ class EasyLocalizationController extends ChangeNotifier {
extraAssetLoaders: extraAssetLoaders,
);

Future<Map<Locale, Map<String, dynamic>>> loadAllTranslationData() async {
Map<Locale, Map<String, dynamic>> data = {};

for (final locale in supportedLocales) {
data[locale] = await _combineAssetLoaders(
path: path,
locale: locale,
assetLoader: assetLoader,
useOnlyLangCode: useOnlyLangCode,
extraAssetLoaders: extraAssetLoaders,
);
}

return data;
}

Future<Map<String, dynamic>> _combineAssetLoaders({
required String path,
required Locale locale,
required AssetLoader assetLoader,
required bool useOnlyLangCode,
List<AssetLoader>? extraAssetLoaders,
}) async {
final result = <String, dynamic>{};
final loaderFutures = <Future<Map<String, dynamic>?>>[];
final Map<String, dynamic> result = {};
final List<Future<Map<String, dynamic>?>> loaderFutures = [];

final Locale desiredLocale =
useOnlyLangCode ? Locale(locale.languageCode) : locale;
Expand All @@ -169,12 +198,12 @@ class EasyLocalizationController extends ChangeNotifier {

Locale get locale => _locale;

Future<void> setLocale(Locale l) async {
_locale = l;
Future<void> setLocale(Locale locale) async {
_locale = locale;
await loadTranslations();
notifyListeners();
EasyLocalization.logger('Locale $locale changed');
await _saveLocale(_locale);
await _saveLocale(locale);
}

Future<void> _saveLocale(Locale? locale) async {
Expand Down Expand Up @@ -215,14 +244,17 @@ extension LocaleExtension on Locale {
if (this == locale) {
return true;
}

if (languageCode != locale.languageCode) {
return false;
}

if (countryCode != null &&
countryCode!.isNotEmpty &&
countryCode != locale.countryCode) {
return false;
}

if (scriptCode != null && scriptCode != locale.scriptCode) {
return false;
}
Expand Down
Loading