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

Perf/avoid double call #227

Merged
merged 7 commits into from
Jul 10, 2024
Merged
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
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
Loading