Skip to content

Commit

Permalink
Merge pull request #227 from ilteoood/perf/avoid-double-call
Browse files Browse the repository at this point in the history
Perf/avoid double call
  • Loading branch information
ilteoood authored Jul 10, 2024
2 parents 99d613b + 312c950 commit a32db41
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 74 deletions.
4 changes: 2 additions & 2 deletions example/lib/network_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:flutter_i18n/loaders/decoders/json_decode_strategy.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

class CustomNetworkFileTranslationLoader extends NetworkFileTranslationLoader {
CustomNetworkFileTranslationLoader({required baseUri})
CustomNetworkFileTranslationLoader(Uri baseUri)
: super(baseUri: baseUri, decodeStrategies: [JsonDecodeStrategy()]);

@override
Expand All @@ -19,7 +19,7 @@ Future main() async {
WidgetsFlutterBinding.ensureInitialized();
final FlutterI18nDelegate flutterI18nDelegate = FlutterI18nDelegate(
translationLoader: CustomNetworkFileTranslationLoader(
baseUri: Uri.https("postman-echo.com", "get",
Uri.https("postman-echo.com", "get",
{"title": "Basic network example", "content": "Translated content"}),
),
);
Expand Down
14 changes: 8 additions & 6 deletions lib/loaders/e2e_file_translation_loader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import 'dart:async';
import 'dart:convert';

import 'package:flutter/services.dart';
import 'package:flutter_i18n/loaders/decoders/base_decode_strategy.dart';
import 'package:flutter/widgets.dart';

import 'file_translation_loader.dart';

Expand All @@ -19,12 +21,12 @@ class E2EFileTranslationLoader extends FileTranslationLoader {
AssetBundle customAssetBundle = _CustomAssetBundle();

E2EFileTranslationLoader(
{forcedLocale,
fallbackFile = "en",
basePath = "assets/flutter_i18n",
useCountryCode = false,
this.useE2E = true,
decodeStrategies})
{Locale? forcedLocale,
String? fallbackFile = "en",
String basePath = "assets/flutter_i18n",
bool useCountryCode = false,
bool this.useE2E = true,
List<BaseDecodeStrategy>? decodeStrategies})
: super(
fallbackFile: fallbackFile,
basePath: basePath,
Expand Down
47 changes: 24 additions & 23 deletions lib/loaders/file_translation_loader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import '../utils/message_printer.dart';

/// Loads translation files from JSON, YAML or XML format
class FileTranslationLoader extends TranslationLoader implements IFileContent {
final String fallbackFile;
final String? fallbackFile;
final String basePath;
final String separator;
final bool useCountryCode;
Expand All @@ -34,22 +34,28 @@ class FileTranslationLoader extends TranslationLoader implements IFileContent {
];

FileTranslationLoader(
{this.fallbackFile = "en",
this.basePath = "assets/flutter_i18n",
this.separator = "_",
this.useCountryCode = false,
this.useScriptCode = false,
forcedLocale,
decodeStrategies}) {
{String? this.fallbackFile = "en",
String this.basePath = "assets/flutter_i18n",
String this.separator = "_",
bool this.useCountryCode = false,
bool this.useScriptCode = false,
Locale? forcedLocale,
List<BaseDecodeStrategy>? decodeStrategies}) {
this.forcedLocale = forcedLocale;
this.decodeStrategies = decodeStrategies;
}

/// Return the translation Map
Future<Map> load() async {
_decodedMap = Map();
await _loadCurrentTranslation();
await _loadFallback();
await this._defineLocale();
final fileName = composeFileName();
_decodedMap.addAll(await _loadTranslation(fileName, false));
if (fallbackFile != null && fileName != fallbackFile) {
final Map fallbackMap = await _loadTranslation(fallbackFile!, true);
_decodedMap = _deepMergeMaps(fallbackMap, _decodedMap);
MessagePrinter.debug('Fallback maps have been merged');
}
return _decodedMap;
}

Expand All @@ -60,24 +66,19 @@ class FileTranslationLoader extends TranslationLoader implements IFileContent {
cache: false);
}

Future _loadCurrentTranslation() async {
Future<Map<dynamic, dynamic>> _loadTranslation(String fileName, bool isFallback) async {
try {
this.locale = locale ?? await findDeviceLocale();
MessagePrinter.info("The current locale is ${this.locale}");
_decodedMap.addAll(await loadFile(composeFileName()));
return await loadFile(fileName);
} catch (e) {
MessagePrinter.debug('Error loading translation $e');
MessagePrinter.debug(
'Error loading translation${isFallback ? " fallback " : " "}$e');
}
return Map();
}

Future _loadFallback() async {
try {
final Map fallbackMap = await loadFile(fallbackFile);
_decodedMap = _deepMergeMaps(fallbackMap, _decodedMap);
MessagePrinter.debug('Fallback maps have been merged');
} catch (e) {
MessagePrinter.debug('Error loading translation fallback $e');
}
Future _defineLocale() async {
this.locale = locale ?? await findDeviceLocale();
MessagePrinter.info("The current locale is ${this.locale}");
}

Map<K, V> _deepMergeMaps<K, V>(
Expand Down
12 changes: 7 additions & 5 deletions lib/loaders/local_translation_loader.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import 'dart:io';

import 'package:flutter/widgets.dart';
import 'package:flutter_i18n/loaders/decoders/base_decode_strategy.dart';
import 'package:flutter_i18n/loaders/file_translation_loader.dart';

class LocalTranslationLoader extends FileTranslationLoader {
LocalTranslationLoader(
{basePath = "assets/flutter_i18n",
useCountryCode = false,
useScriptCode = false,
forcedLocale,
decodeStrategies})
{String basePath = "assets/flutter_i18n",
bool useCountryCode = false,
bool useScriptCode = false,
Locale? forcedLocale,
List<BaseDecodeStrategy>? decodeStrategies})
: super(
basePath: basePath,
useCountryCode: useCountryCode,
Expand Down
18 changes: 10 additions & 8 deletions lib/loaders/namespace_file_translation_loader.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_i18n/loaders/decoders/base_decode_strategy.dart';
import 'package:flutter_i18n/loaders/file_translation_loader.dart';
import 'package:flutter_i18n/utils/message_printer.dart';

Expand All @@ -11,14 +13,14 @@ class NamespaceFileTranslationLoader extends FileTranslationLoader {
Map<dynamic, dynamic> _decodedMap = {};

NamespaceFileTranslationLoader(
{required this.namespaces,
this.fallbackDir = "en",
basePath = "assets/flutter_i18n",
separator = "_",
useCountryCode = false,
useScriptCode = false,
forcedLocale,
decodeStrategies})
{required List<String>? this.namespaces,
String this.fallbackDir = "en",
String basePath = "assets/flutter_i18n",
String separator = "_",
bool useCountryCode = false,
bool useScriptCode = false,
Locale? forcedLocale,
List<BaseDecodeStrategy>? decodeStrategies})
: super(
basePath: basePath,
separator: separator,
Expand Down
16 changes: 9 additions & 7 deletions lib/loaders/network_file_translation_loader.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'dart:async';

import 'package:flutter/widgets.dart';
import 'package:flutter_i18n/loaders/decoders/base_decode_strategy.dart';
import 'package:http/http.dart' as http;

import 'file_translation_loader.dart';
Expand All @@ -9,13 +11,13 @@ class NetworkFileTranslationLoader extends FileTranslationLoader {
final Uri baseUri;

NetworkFileTranslationLoader(
{required this.baseUri,
forcedLocale,
fallbackFile = "en",
separator = "_",
useCountryCode = false,
useScriptCode = false,
decodeStrategies})
{required Uri this.baseUri,
Locale? forcedLocale,
String fallbackFile = "en",
String separator = "_",
bool useCountryCode = false,
bool useScriptCode = false,
List<BaseDecodeStrategy>? decodeStrategies})
: super(
fallbackFile: fallbackFile,
separator: separator,
Expand Down
33 changes: 27 additions & 6 deletions test/loaders/file_translation_loader_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ void main() {

test('should deep merge fallback map', () async {
var instance = FileTranslationLoader(
forcedLocale: Locale.fromSubtags(languageCode: "fr"),
fallbackFile: "en"
);
forcedLocale: Locale.fromSubtags(languageCode: "fr"),
fallbackFile: "en");
instance.assetBundle = TestAssetBundleFallbackFrToEn();

var result = await instance.load();
Expand All @@ -44,28 +43,50 @@ void main() {
expect(block["label2"], equals("Bonjour"));
});

test('should skip merge fallback map', () async {
var instance = FileTranslationLoader(
forcedLocale: Locale.fromSubtags(languageCode: "fr"),
fallbackFile: null);
instance.assetBundle = TestAssetBundleFallbackFrToEn();

var result = await instance.load();

expect(result, isMap);
expect(result, isNotEmpty);
expect(result["title"], equals("flutter_18n_fr"));
expect(result["sub_title"], equals(null));
var block = result["block"];
expect(block, isMap);
expect(block, isNotEmpty);
expect(block["label1"], equals(null));
expect(block["label2"], equals("Bonjour"));
});

test('`loadString` should load correct string', () async {
final instance = TestJsonLoader();
final result = await instance.loadString("_fileName", "_extension");
expect(result, contains("_fileName"));
expect(result, contains("_extension"));
});

test('`load` should load correct map from JSON with initial values', () async {
test('`load` should load correct map from JSON with initial values',
() async {
final instance = TestJsonLoader();
final result = await instance.load();
expect(result["fileName"], "en");
expect(result["extension"], "json");
});

test('`load` should load correct map from YAML with initial values', () async {
test('`load` should load correct map from YAML with initial values',
() async {
final instance = TestYamlLoader();
final result = await instance.load();
expect(result["fileName"], "en");
expect(result["extension"], "yaml");
});

test('`load` should load correct map from TOML with initial values', () async {
test('`load` should load correct map from TOML with initial values',
() async {
final instance = TestTomlLoader();
final result = await instance.load();
expect(result["fileName"], "en");
Expand Down
35 changes: 18 additions & 17 deletions test/test_loader.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:flutter_i18n/loaders/decoders/toml_decode_strategy.dart';
import 'package:flutter_i18n/loaders/decoders/xml_decode_strategy.dart';
import 'package:flutter_i18n/loaders/decoders/yaml_decode_strategy.dart';
import 'package:flutter_i18n/loaders/decoders/toml_decode_strategy.dart';

Future<String> _loadString(String fileName, String extension) async {
if (fileName.contains('_en')) {
Expand Down Expand Up @@ -31,10 +32,10 @@ Future<String> _loadString(String fileName, String extension) async {

class TestJsonLoader extends FileTranslationLoader {
TestJsonLoader({
forcedLocale,
fallbackFile = "en",
basePath = "assets/flutter_i18n",
useCountryCode = false,
Locale? forcedLocale,
String fallbackFile = "en",
String basePath = "assets/flutter_i18n",
bool useCountryCode = false,
}) : super(
fallbackFile: fallbackFile,
basePath: basePath,
Expand All @@ -49,10 +50,10 @@ class TestJsonLoader extends FileTranslationLoader {

class TestYamlLoader extends FileTranslationLoader {
TestYamlLoader({
forcedLocale,
fallbackFile = "en",
basePath = "assets/flutter_i18n",
useCountryCode = false,
Locale? forcedLocale,
String fallbackFile = "en",
String basePath = "assets/flutter_i18n",
bool useCountryCode = false,
}) : super(
fallbackFile: fallbackFile,
basePath: basePath,
Expand All @@ -77,10 +78,10 @@ class TestYamlLoader extends FileTranslationLoader {

class TestTomlLoader extends FileTranslationLoader {
TestTomlLoader({
forcedLocale,
fallbackFile = "en",
basePath = "assets/flutter_i18n",
useCountryCode = false,
Locale? forcedLocale,
String fallbackFile = "en",
String basePath = "assets/flutter_i18n",
bool useCountryCode = false,
}) : super(
fallbackFile: fallbackFile,
basePath: basePath,
Expand All @@ -105,10 +106,10 @@ class TestTomlLoader extends FileTranslationLoader {

class TestXmlLoader extends FileTranslationLoader {
TestXmlLoader({
forcedLocale,
fallbackFile = "en",
basePath = "assets/flutter_i18n",
useCountryCode = false,
Locale? forcedLocale,
String fallbackFile = "en",
String basePath = "assets/flutter_i18n",
bool useCountryCode = false,
}) : super(
fallbackFile: fallbackFile,
basePath: basePath,
Expand Down

0 comments on commit a32db41

Please sign in to comment.