mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 19:49:22 +00:00
Merge pull request #95 from cake-tech/CAKE-272-implement-localization-generation-script
CAKE-272 | implemented localization generation script to the app (gen…
This commit is contained in:
commit
4a62e2db33
19 changed files with 349 additions and 8972 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -95,3 +95,4 @@ vendor/
|
|||
|
||||
android/app/.cxx/**
|
||||
ios/Flutter/.last_build_id
|
||||
/lib/generated/**
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import 'package:cake_wallet/generated/locales.dart';
|
||||
import 'package:devicelocale/devicelocale.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class LanguageService {
|
||||
static const Map<String, String> list = {
|
||||
static const Map<String, String> supportedLocales = {
|
||||
'en': 'English',
|
||||
'de': 'Deutsch (German)',
|
||||
'es': 'Español (Spanish)',
|
||||
|
@ -16,6 +17,15 @@ class LanguageService {
|
|||
'uk': 'Українська (Ukrainian)',
|
||||
'zh': '中文 (Chinese)'
|
||||
};
|
||||
static final list = <String, String> {};
|
||||
|
||||
static void loadLocaleList() {
|
||||
supportedLocales.forEach((key, value) {
|
||||
if (locales.contains(key)) {
|
||||
list[key] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static Future<String> localeDetection() async {
|
||||
var locale = await Devicelocale.currentLocale;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/entities/language_service.dart';
|
||||
import 'package:cake_wallet/entities/order.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
@ -135,6 +136,7 @@ Future<void> initialSetup(
|
|||
@required Box<TransactionDescription> transactionDescriptions,
|
||||
FlutterSecureStorage secureStorage,
|
||||
int initialMigrationVersion = 13}) async {
|
||||
LanguageService.loadLocaleList();
|
||||
await defaultSettingsMigration(
|
||||
secureStorage: secureStorage,
|
||||
version: initialMigrationVersion,
|
||||
|
|
|
@ -5,11 +5,8 @@ import 'package:cake_wallet/utils/show_pop_up.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/entities/language_service.dart';
|
||||
|
||||
// import 'package:cake_wallet/src/stores/settings/settings_store.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
|
||||
|
@ -62,7 +59,5 @@ class LanguageListPage extends BasePage {
|
|||
});
|
||||
},
|
||||
));
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -462,5 +462,10 @@
|
|||
"fixed_rate_alert" : "Sie können den Empfangsbetrag eingeben, wenn der Festpreismodus aktiviert ist. Möchten Sie in den Festpreismodus wechseln?",
|
||||
|
||||
"xlm_extra_info" : "Bitte vergessen Sie nicht, die Memo-ID anzugeben, während Sie die XLM-Transaktion für den Austausch senden",
|
||||
"xrp_extra_info" : "Bitte vergessen Sie nicht, das Ziel-Tag anzugeben, während Sie die XRP-Transaktion für den Austausch senden"
|
||||
"xrp_extra_info" : "Bitte vergessen Sie nicht, das Ziel-Tag anzugeben, während Sie die XRP-Transaktion für den Austausch senden",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr" : "Wenn Sie XMR von Ihrem Cake Wallet Monero-Guthaben austauschen möchten, wechseln Sie bitte zuerst zu Ihrem Monero Wallet.",
|
||||
"confirmed" : "Bestätigt",
|
||||
"unconfirmed" : "Unbestätigt",
|
||||
"displayable" : "Anzeigebar"
|
||||
}
|
|
@ -462,5 +462,10 @@
|
|||
"fixed_rate_alert" : "You will be able to enter receive amount when fixed rate mode is checked. Do you want to switch to fixed rate mode?",
|
||||
|
||||
"xlm_extra_info" : "Please don’t forget to specify the Memo ID while sending the XLM transaction for the exchange",
|
||||
"xrp_extra_info" : "Please don’t forget to specify the Destination Tag while sending the XRP transaction for the exchange"
|
||||
"xrp_extra_info" : "Please don’t forget to specify the Destination Tag while sending the XRP transaction for the exchange",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr" : "If you want to exchange XMR from your Cake Wallet Monero balance, please switch to your Monero wallet first.",
|
||||
"confirmed" : "Confirmed",
|
||||
"unconfirmed" : "Unconfirmed",
|
||||
"displayable" : "Displayable"
|
||||
}
|
|
@ -462,5 +462,10 @@
|
|||
"fixed_rate_alert" : "Podrá ingresar la cantidad recibida cuando el modo de tarifa fija esté marcado. ¿Quieres cambiar al modo de tarifa fija?",
|
||||
|
||||
"xlm_extra_info" : "No olvide especificar el ID de nota al enviar la transacción XLM para el intercambio",
|
||||
"xrp_extra_info" : "No olvide especificar la etiqueta de destino al enviar la transacción XRP para el intercambio"
|
||||
"xrp_extra_info" : "No olvide especificar la etiqueta de destino al enviar la transacción XRP para el intercambio",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr" : "Si desea intercambiar XMR de su saldo de Cake Wallet Monero, primero cambie a su billetera Monero.",
|
||||
"confirmed" : "Confirmada",
|
||||
"unconfirmed" : "Inconfirmado",
|
||||
"displayable" : "Visualizable"
|
||||
}
|
|
@ -462,5 +462,10 @@
|
|||
"fixed_rate_alert" : "फिक्स्ड रेट मोड की जांच करने पर आप प्राप्त राशि दर्ज कर पाएंगे। क्या आप निश्चित दर मोड पर स्विच करना चाहते हैं?",
|
||||
|
||||
"xlm_extra_info" : "एक्सचेंज के लिए XLM ट्रांजेक्शन भेजते समय मेमो आईडी निर्दिष्ट करना न भूलें",
|
||||
"xrp_extra_info" : "एक्सचेंज के लिए एक्सआरपी लेनदेन भेजते समय कृपया गंतव्य टैग निर्दिष्ट करना न भूलें"
|
||||
"xrp_extra_info" : "एक्सचेंज के लिए एक्सआरपी लेनदेन भेजते समय कृपया गंतव्य टैग निर्दिष्ट करना न भूलें",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr" : "यदि आप अपने केक वॉलेट मोनेरो बैलेंस से एक्सएमआर का आदान-प्रदान करना चाहते हैं, तो कृपया अपने मोनेरो वॉलेट में जाएं।",
|
||||
"confirmed" : "की पुष्टि की",
|
||||
"unconfirmed" : "अपुष्ट",
|
||||
"displayable" : "प्रदर्शन योग्य"
|
||||
}
|
|
@ -89,7 +89,7 @@
|
|||
"trade_is_powered_by" : "この取引は ${provider}",
|
||||
"copy_address" : "住所をコピー",
|
||||
"exchange_result_confirm" : "確認を押すと、送信されます ${fetchingLabel} ${from} と呼ばれるあなたの財布から ${walletName} 下記の住所へ。 または、外部ウォレットから以下のアドレスに送信することもできます/ QRコードに送信できます.\n\n確認を押して続行するか、戻って金額を変更してください.",
|
||||
"exchange_result_description" : 次のページに示されているアドレスに最低 ${fetchingLabel} ${from} を送信する必要があります。 ${fetchingLabel} ${from} 未満の金額を送信すると、変換されず、返金されない場合があります。",
|
||||
"exchange_result_description" : "次のページに示されているアドレスに最低 ${fetchingLabel} ${from} を送信する必要があります。 ${fetchingLabel} ${from} 未満の金額を送信すると、変換されず、返金されない場合があります。",
|
||||
"exchange_result_write_down_ID" : "*上記のIDをコピーまたは書き留めてください.",
|
||||
"confirm" : "確認する",
|
||||
"confirm_sending" : "送信を確認",
|
||||
|
@ -462,5 +462,10 @@
|
|||
"fixed_rate_alert" : "固定金利モードにチェックを入れると、受取額を入力できるようになります。 固定金利モードに切り替えますか?",
|
||||
|
||||
"xlm_extra_info" : "交換用のXLMトランザクションを送信するときに、メモIDを指定することを忘れないでください",
|
||||
"xrp_extra_info" : "取引所のXRPトランザクションを送信するときに、宛先タグを指定することを忘れないでください"
|
||||
"xrp_extra_info" : "取引所のXRPトランザクションを送信するときに、宛先タグを指定することを忘れないでください",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr" : "Cake Wallet Moneroの残高からXMRを交換する場合は、最初にMoneroウォレットに切り替えてください。",
|
||||
"confirmed" : "確認済み",
|
||||
"unconfirmed" : "未確認",
|
||||
"displayable" : "表示可能"
|
||||
}
|
|
@ -462,5 +462,10 @@
|
|||
"fixed_rate_alert" : "고정 금리 모드 체크시 수취 금액 입력이 가능합니다. 고정 속도 모드로 전환 하시겠습니까?",
|
||||
|
||||
"xlm_extra_info" : "교환을 위해 XLM 거래를 보낼 때 메모 ID를 지정하는 것을 잊지 마십시오",
|
||||
"xrp_extra_info" : "교환을 위해 XRP 트랜잭션을 보내는 동안 대상 태그를 지정하는 것을 잊지 마십시오"
|
||||
"xrp_extra_info" : "교환을 위해 XRP 트랜잭션을 보내는 동안 대상 태그를 지정하는 것을 잊지 마십시오",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr" : "Cake Wallet Monero 잔액에서 XMR을 교환하려면 먼저 Monero 지갑으로 전환하십시오.",
|
||||
"confirmed" : "확인",
|
||||
"unconfirmed" : "미확인",
|
||||
"displayable" : "표시 가능"
|
||||
}
|
|
@ -462,5 +462,10 @@
|
|||
"fixed_rate_alert" : "U kunt het ontvangen bedrag invoeren wanneer de modus voor vaste tarieven is aangevinkt. Wilt u overschakelen naar de vaste-tariefmodus?",
|
||||
|
||||
"xlm_extra_info" : "Vergeet niet om de Memo-ID op te geven tijdens het verzenden van de XLM-transactie voor de uitwisseling",
|
||||
"xrp_extra_info" : "Vergeet niet om de Destination Tag op te geven tijdens het verzenden van de XRP-transactie voor de uitwisseling"
|
||||
"xrp_extra_info" : "Vergeet niet om de Destination Tag op te geven tijdens het verzenden van de XRP-transactie voor de uitwisseling",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr" : "Als u XMR wilt omwisselen van uw Cake Wallet Monero-saldo, moet u eerst overschakelen naar uw Monero-portemonnee.",
|
||||
"confirmed" : "Bevestigd",
|
||||
"unconfirmed" : "Niet bevestigd",
|
||||
"displayable" : "Weer te geven"
|
||||
}
|
|
@ -462,5 +462,10 @@
|
|||
"fixed_rate_alert" : "Będziesz mógł wprowadzić kwotę otrzymaną, gdy zaznaczony jest tryb stałej stawki. Czy chcesz przejść do trybu stałej stawki?",
|
||||
|
||||
"xlm_extra_info" : "Nie zapomnij podać identyfikatora notatki podczas wysyłania transakcji XLM do wymiany",
|
||||
"xrp_extra_info" : "Nie zapomnij podać tagu docelowego podczas wysyłania transakcji XRP do wymiany"
|
||||
"xrp_extra_info" : "Nie zapomnij podać tagu docelowego podczas wysyłania transakcji XRP do wymiany",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr" : "Jeśli chcesz wymienić XMR z salda Cake Wallet Monero, najpierw przełącz się na portfel Monero.",
|
||||
"confirmed" : "Potwierdzony",
|
||||
"unconfirmed" : "Niepotwierdzony",
|
||||
"displayable" : "Wyświetlane"
|
||||
}
|
|
@ -462,5 +462,10 @@
|
|||
"fixed_rate_alert" : "Você poderá inserir a quantia recebida quando o modo de taxa fixa estiver marcado. Quer mudar para o modo de taxa fixa?",
|
||||
|
||||
"xlm_extra_info" : "Não se esqueça de especificar o Memo ID ao enviar a transação XLM para a troca",
|
||||
"xrp_extra_info" : "Não se esqueça de especificar a etiqueta de destino ao enviar a transação XRP para a troca"
|
||||
}
|
||||
"xrp_extra_info" : "Não se esqueça de especificar a etiqueta de destino ao enviar a transação XRP para a troca",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr" : "Se você deseja trocar o XMR de seu saldo da Carteira Monero Cake, troque primeiro para sua carteira Monero.",
|
||||
"confirmed" : "Confirmada",
|
||||
"unconfirmed" : "Não confirmado",
|
||||
"displayable" : "Exibível"
|
||||
}
|
|
@ -462,5 +462,10 @@
|
|||
"fixed_rate_alert" : "Вы сможете ввести сумму получения тогда, когда будет установлен режим фиксированной ставки. Вы хотите перейти в режим фиксированной ставки?",
|
||||
|
||||
"xlm_extra_info" : "Не забудьте указать Memo ID (памятка) при отправке транзакции XLM для обмена",
|
||||
"xrp_extra_info" : "Не забудьте указать целевой тег при отправке транзакции XRP для обмена"
|
||||
"xrp_extra_info" : "Не забудьте указать целевой тег при отправке транзакции XRP для обмена",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr" : "Если вы хотите обменять XMR со своего баланса Monero в Cake Wallet, сначала переключитесь на свой кошелек Monero.",
|
||||
"confirmed" : "Подтверждено",
|
||||
"unconfirmed" : "Неподтвержденный",
|
||||
"displayable" : "Отображаемый"
|
||||
}
|
|
@ -462,5 +462,10 @@
|
|||
"fixed_rate_alert" : "Ви зможете ввести суму отримання тоді, коли буде встановлений режим фіксованої ставки. Ви хочете перейти в режим фіксованої ставки?",
|
||||
|
||||
"xlm_extra_info" : "Будь ласка, не забудьте вказати ідентифікатор пам'ятки під час надсилання транзакції XLM для обміну",
|
||||
"xrp_extra_info" : "Будь ласка, не забудьте вказати тег призначення під час надсилання XRP-транзакції для обміну"
|
||||
"xrp_extra_info" : "Будь ласка, не забудьте вказати тег призначення під час надсилання XRP-транзакції для обміну",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr" : "Якщо ви хочете обміняти XMR із вашого балансу Cake Wallet Monero, спочатку перейдіть на свій гаманець Monero.",
|
||||
"confirmed" : "Підтверджено",
|
||||
"unconfirmed" : "Непідтверджений",
|
||||
"displayable" : "Відображуваний"
|
||||
}
|
|
@ -462,5 +462,10 @@
|
|||
"fixed_rate_alert" : "選中固定費率模式後,您將可以輸入接收金額。 您要切換到固定速率模式嗎?",
|
||||
|
||||
"xlm_extra_info" : "發送用於交換的XLM交易時,請不要忘記指定備忘錄ID",
|
||||
"xrp_extra_info" : "發送用於交換的XRP交易時,請不要忘記指定目標標記"
|
||||
"xrp_extra_info" : "發送用於交換的XRP交易時,請不要忘記指定目標標記",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr" : "如果要从Cake Wallet Monero余额中兑换XMR,请先切换到Monero钱包。",
|
||||
"confirmed" : "已确认",
|
||||
"unconfirmed" : "未经证实",
|
||||
"displayable" : "可显示"
|
||||
}
|
149
tool/generate_localization.dart
Normal file
149
tool/generate_localization.dart
Normal file
|
@ -0,0 +1,149 @@
|
|||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import 'localization/localization_constants.dart';
|
||||
import 'utils/utils.dart';
|
||||
|
||||
const inputPath = 'res/values/';
|
||||
const outputPath = 'lib/generated/';
|
||||
const localizationFileName = 'i18n.dart';
|
||||
const localeListFileName = 'locales.dart';
|
||||
const srcDir = 'srcDir';
|
||||
const defaultLocale = 'en';
|
||||
|
||||
Future<void> main(List<String> args) async {
|
||||
final extraInfo = args.isNotEmpty ?
|
||||
args.fold(<String, dynamic>{}, (Map<String, dynamic> acc, String arg) {
|
||||
final parts = arg.split('=');
|
||||
var key = normalizeKeyName(parts[0]);
|
||||
if (key.contains('--')) {
|
||||
key = key.substring(2);
|
||||
}
|
||||
acc[key] = parts.length > 1
|
||||
? parts[1].isNotEmpty
|
||||
? parts[1]
|
||||
: inputPath
|
||||
: inputPath;
|
||||
return acc;
|
||||
})
|
||||
: <String, dynamic> {srcDir : inputPath};
|
||||
|
||||
extraInfo.forEach((key, dynamic value) async {
|
||||
if (key != srcDir) {
|
||||
print('Wrong key: $key');
|
||||
return;
|
||||
}
|
||||
|
||||
final dirPath = value as String;
|
||||
final dir = Directory(dirPath);
|
||||
|
||||
if (!await dir.exists()) {
|
||||
print('Wrong directory path: $dirPath');
|
||||
return;
|
||||
}
|
||||
|
||||
final localePath = <String, dynamic>{};
|
||||
await dir.list(recursive: false).forEach((element) {
|
||||
try {
|
||||
final shortLocale = element.path.split('_',)[1].split('.')[0];
|
||||
localePath[shortLocale] = element.path;
|
||||
} catch (e) {
|
||||
print('Wrong file: ${element.path}');
|
||||
}
|
||||
});
|
||||
|
||||
if (!localePath.keys.contains(defaultLocale)) {
|
||||
print("Locale list doesn't contain $defaultLocale");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var output = '';
|
||||
var locales = 'const locales = [';
|
||||
|
||||
output += part1;
|
||||
output += textDirectionDeclaration;
|
||||
|
||||
var inputContent =
|
||||
File(localePath[defaultLocale].toString()).readAsStringSync();
|
||||
var config = json.decode(inputContent) as Map<String, dynamic>;
|
||||
|
||||
output += localizedStrings(config: config, hasOverride: false);
|
||||
output += '}' + '\n\n';
|
||||
|
||||
localePath.forEach((key, dynamic value) {
|
||||
inputContent = File(localePath[key].toString()).readAsStringSync();
|
||||
config = json.decode(inputContent) as Map<String, dynamic>;
|
||||
|
||||
locales += "'$key', ";
|
||||
|
||||
output += 'class \$$key extends S {' + '\n';
|
||||
output += ' const \$$key();' + '\n';
|
||||
|
||||
if (key != defaultLocale) {
|
||||
output += textDirectionDeclaration;
|
||||
output += localizedStrings(config: config, hasOverride: true);
|
||||
}
|
||||
|
||||
output += '}' + '\n\n';
|
||||
});
|
||||
|
||||
output += classDeclaration;
|
||||
|
||||
localePath.keys.forEach((key) {
|
||||
output += ' Locale("$key", ""),' + '\n';
|
||||
});
|
||||
|
||||
output += part2;
|
||||
|
||||
localePath.keys.forEach((key) {
|
||||
output += ' case "$key":' + '\n';
|
||||
output += ' S.current = const \$$key();' + '\n';
|
||||
output += ' return SynchronousFuture<S>(S.current);' + '\n';
|
||||
});
|
||||
|
||||
output += part3;
|
||||
|
||||
await File(outputPath + localizationFileName).writeAsString(output);
|
||||
|
||||
locales += '];';
|
||||
|
||||
await File(outputPath + localeListFileName).writeAsString(locales);
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
String localizedStrings({Map<String, dynamic> config, bool hasOverride}) {
|
||||
var output = '';
|
||||
|
||||
final pattern = RegExp('[\$]{(.*?)}');
|
||||
|
||||
config.forEach((key, dynamic value) {
|
||||
final matches = pattern.allMatches(value as String);
|
||||
|
||||
if (hasOverride) {
|
||||
output += ' @override' + '\n';
|
||||
}
|
||||
|
||||
if (matches.isEmpty) {
|
||||
output += ' String get ${key} => \"\"\"${value}\"\"\";' + '\n';
|
||||
} else {
|
||||
final set = matches.map((elem) => elem.group(1)).toSet().toList();
|
||||
|
||||
output += ' String ${key}(';
|
||||
|
||||
for (var elem in set) {
|
||||
if (elem == set.last) {
|
||||
output += 'String ${elem}';
|
||||
} else {
|
||||
output += 'String ${elem}, ';
|
||||
}
|
||||
}
|
||||
output += ') => \"\"\"${value}\"\"\";' + '\n';
|
||||
}
|
||||
});
|
||||
|
||||
return output;
|
||||
}
|
||||
|
112
tool/localization/localization_constants.dart
Normal file
112
tool/localization/localization_constants.dart
Normal file
|
@ -0,0 +1,112 @@
|
|||
const textDirectionDeclaration = """
|
||||
|
||||
@override
|
||||
TextDirection get textDirection => TextDirection.ltr;
|
||||
|
||||
""";
|
||||
|
||||
const classDeclaration = """
|
||||
class GeneratedLocalizationsDelegate extends LocalizationsDelegate<S> {
|
||||
const GeneratedLocalizationsDelegate();
|
||||
|
||||
List<Locale> get supportedLocales {
|
||||
return const <Locale>[
|
||||
""";
|
||||
|
||||
const part1 = """
|
||||
import \'dart:async\';
|
||||
import \'package:flutter/foundation.dart\';
|
||||
import \'package:flutter/material.dart\';
|
||||
|
||||
class S implements WidgetsLocalizations {
|
||||
const S();
|
||||
|
||||
static S current;
|
||||
|
||||
static const GeneratedLocalizationsDelegate delegate =
|
||||
GeneratedLocalizationsDelegate();
|
||||
|
||||
static S of(BuildContext context) => Localizations.of<S>(context, S);
|
||||
""";
|
||||
|
||||
const part2 = """
|
||||
];
|
||||
}
|
||||
|
||||
LocaleListResolutionCallback listResolution({Locale fallback, bool withCountry = true}) {
|
||||
return (List<Locale> locales, Iterable<Locale> supported) {
|
||||
if (locales == null || locales.isEmpty) {
|
||||
return fallback ?? supported.first;
|
||||
} else {
|
||||
return _resolve(locales.first, fallback, supported, withCountry);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
LocaleResolutionCallback resolution({Locale fallback, bool withCountry = true}) {
|
||||
return (Locale locale, Iterable<Locale> supported) {
|
||||
return _resolve(locale, fallback, supported, withCountry);
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Future<S> load(Locale locale) {
|
||||
final String lang = getLang(locale);
|
||||
if (lang != null) {
|
||||
switch (lang) {
|
||||
""";
|
||||
|
||||
const part3 = """
|
||||
default:
|
||||
}
|
||||
}
|
||||
S.current = const S();
|
||||
return SynchronousFuture<S>(S.current);
|
||||
}
|
||||
|
||||
@override
|
||||
bool isSupported(Locale locale) => _isSupported(locale, true);
|
||||
|
||||
@override
|
||||
bool shouldReload(GeneratedLocalizationsDelegate old) => false;
|
||||
|
||||
Locale _resolve(Locale locale, Locale fallback, Iterable<Locale> supported, bool withCountry) {
|
||||
if (locale == null || !_isSupported(locale, withCountry)) {
|
||||
return fallback ?? supported.first;
|
||||
}
|
||||
|
||||
final Locale languageLocale = Locale(locale.languageCode, "");
|
||||
if (supported.contains(locale)) {
|
||||
return locale;
|
||||
} else if (supported.contains(languageLocale)) {
|
||||
return languageLocale;
|
||||
} else {
|
||||
final Locale fallbackLocale = fallback ?? supported.first;
|
||||
return fallbackLocale;
|
||||
}
|
||||
}
|
||||
|
||||
bool _isSupported(Locale locale, bool withCountry) {
|
||||
if (locale != null) {
|
||||
for (Locale supportedLocale in supportedLocales) {
|
||||
if (supportedLocale.languageCode != locale.languageCode) {
|
||||
continue;
|
||||
}
|
||||
if (supportedLocale.countryCode == locale.countryCode) {
|
||||
return true;
|
||||
}
|
||||
if (true != withCountry && (supportedLocale.countryCode == null || supportedLocale.countryCode.isEmpty)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
String getLang(Locale l) => l == null
|
||||
? null
|
||||
: l.countryCode != null && l.countryCode.isEmpty
|
||||
? l.languageCode
|
||||
: l.toString();
|
||||
""";
|
Loading…
Reference in a new issue