easy_localization_loader
easy_localization_loader copied to clipboard
load from network
this library can be support getting locale from network when its available?
it seems this class don't work correctly and i get some error. reference
final String assetsLocalePath = 'assets/langs/';
runApp(EasyLocalization(
path: assetsLocalePath,
useOnlyLangCode: true,
child: MyApp(),
assetLoader: AssetOrNetworkAssetLoader(
assetsPath: assetsLocalePath,
localCacheDuration: Duration(days: 1), // how long the localizations file should be kept
localeUrl: (String localeName) => 'http://example.com/$localeName'), // the URL for the remote locale file
supportedLocales:
supportedLocales.map((locale) => Locale(locale)).toList(),
The loader:
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:connectivity/connectivity.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
const defaultTimeout = Duration(seconds: 1);
class AssetOrNetworkAssetLoader extends AssetLoader {
/// The local URL method which accepts a [localeName] and returns the full distant
/// localUrl
final Function localeUrl;
/// The timeout for downloading the distant localization files
final Duration timeout;
/// The default path for assets json files
final String assetsPath;
/// The duration before refreshing local localizations files with distant ones
final Duration localCacheDuration;
AssetOrNetworkAssetLoader(
{@required this.localeUrl,
this.timeout,
this.assetsPath,
this.localCacheDuration});
@override
Future<Map<String, dynamic>> load(String localePath) async {
String string;
String localeName =
localePath.replaceFirst(assetsPath, '').replaceFirst('.json', '');
// try loading local previously-saved localization file
if (await localTranslationExists(localeName)) {
string = await loadFromLocalFile(localeName);
}
// no local or failed, check if internet and download the file
if (string == null && await isInternetConnectionAvailable()) {
string = await loadFromNetwork(localeName);
}
// local cache duration was reached or no internet access but prefer local file to assets
if (string == null &&
await localTranslationExists(localeName, ignoreCacheDuration: true)) {
string = await loadFromLocalFile(localeName);
}
// still nothing? Load from assets
if (string == null) {
string = await rootBundle.loadString(localePath);
}
// then returns the json file
return json.decode(string);
}
@override
Future<bool> localeExists(String localePath) => Future.value(true);
Future<bool> isInternetConnectionAvailable() async {
ConnectivityResult connectivityResult =
await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.none) return false;
final result = await Future.any([
InternetAddress.lookup('example.com'),
Future.delayed(timeout ?? defaultTimeout)
]);
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
return true;
}
return false;
}
Future<String> loadFromNetwork(String localeName) async {
String url = localeUrl(localeName);
try {
final response = await Future.any(
[http.get(url), Future.delayed(timeout ?? defaultTimeout)]);
if (response != null && response.statusCode == 200) {
String content = response.body.toString();
// check valid json before saving it
if (json.decode(content) != null) {
await saveTranslation(localeName, content);
return content;
}
}
} catch (e) {
print(e.toString());
}
return null;
}
Future<bool> localTranslationExists(String localeName,
{bool ignoreCacheDuration: false}) async {
File translationFile = await getFileForLocale(localeName);
if (!await translationFile.exists()) {
return false;
}
// don't check file's age
if (!ignoreCacheDuration) {
Duration difference =
DateTime.now().difference(await translationFile.lastModified());
if (difference > (localCacheDuration ?? Duration(days: 1))) {
return false;
}
}
return true;
}
Future<String> loadFromLocalFile(String localeName) async {
return await (await getFileForLocale(localeName)).readAsString();
}
Future<void> saveTranslation(String localeName, String content) async {
File file = await new File(await getFilenameForLocale(localeName))
.create(recursive: true);
return file.writeAsString(content);
}
Future<String> get _localPath async {
final directory = await getTemporaryDirectory();
return directory.path;
}
Future<String> getFilenameForLocale(String localeName) async {
return "${await _localPath}/langs$localeName.json";
}
Future<File> getFileForLocale(String localeName) async {
return File(await getFilenameForLocale(localeName));
}
}
@aissat Hello Dear,
Please help me with this code there is a problem
@mjubouri i can't fix that yet