148 lines
4.7 KiB
Dart
148 lines
4.7 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:intl/intl.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
|
|
class AppLocalizations {
|
|
Locale locale;
|
|
late Map<String, String> _localizedStrings;
|
|
static Iterable<Locale> locales = <Locale>[
|
|
const Locale(
|
|
"vi",
|
|
"VN",
|
|
),
|
|
const Locale(
|
|
"en",
|
|
"US",
|
|
)
|
|
];
|
|
String _defaultPath = "lib/core/language/";
|
|
|
|
AppLocalizations(this.locale);
|
|
|
|
static AppLocalizations? of(BuildContext context) {
|
|
return Localizations.of<AppLocalizations>(context, AppLocalizations);
|
|
}
|
|
|
|
static LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate(locales);
|
|
|
|
void init({List<Locale>? supportLocales, String? defaultPathI18n}) {
|
|
if (supportLocales != null && supportLocales.length > 0) locales = supportLocales;
|
|
if (!defaultPathI18n!.isNotEmpty) _defaultPath = defaultPathI18n;
|
|
|
|
if (_defaultPath[_defaultPath.length - 1] != '/') _defaultPath += "/";
|
|
}
|
|
|
|
Future<bool> load() async {
|
|
// set Intl
|
|
Intl.defaultLocale = locale.languageCode;
|
|
//Todo chỉnh phần này nếu muốn load API
|
|
final String jsonString = await rootBundle.loadString('$_defaultPath${locale.languageCode}.json');
|
|
|
|
final Map<String, dynamic> jsonMap = json.decode(jsonString);
|
|
_localizedStrings = jsonMap.map((String key, dynamic value) {
|
|
return MapEntry(key, value.toString());
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
//Dịch từ
|
|
String translate(String key) {
|
|
return _localizedStrings[key] ?? key;
|
|
}
|
|
|
|
String displayNumber(dynamic value) {
|
|
if (value == null) return "";
|
|
if (value - double.parse(value.toString()).toInt() < 1) return NumberFormat("##0.0#").format(value);
|
|
if (value - double.parse(value.toString()).toInt() > 0) return NumberFormat("###.0#").format(value);
|
|
return NumberFormat().format(value);
|
|
}
|
|
|
|
String displayScore(BuildContext context, dynamic value) {
|
|
return displayNumber(value) + ' ' + AppLocalizations.of(context)!.translate("point").toLowerCase();
|
|
}
|
|
|
|
DateFormat getDefaultDateTimeFormat(
|
|
{bool isFullTime = false, bool isDateOfWeek = false, bool isOnlyTime = false, bool isDateOfMonth = false}) {
|
|
final String? languageCode = locale.languageCode;
|
|
if (isFullTime) {
|
|
return DateFormat.Hm(languageCode).add_yMd();
|
|
} else if (isDateOfMonth) {
|
|
return DateFormat.Hm(languageCode).addPattern('-').add_Md();
|
|
} else if (isDateOfWeek) {
|
|
return DateFormat.yMMMMEEEEd(languageCode);
|
|
} else if (isOnlyTime) {
|
|
return DateFormat.Hm(languageCode);
|
|
} else {
|
|
return DateFormat.yMd(languageCode);
|
|
}
|
|
}
|
|
|
|
String displayDateTime(DateTime? value,
|
|
{bool isFullTime = true, bool isDateOfWeek = false, bool isOnlyTime = false, bool isDateOfMonth = false}) {
|
|
return value != null
|
|
? getDefaultDateTimeFormat(
|
|
isFullTime: isFullTime,
|
|
isDateOfWeek: isDateOfWeek,
|
|
isOnlyTime: isOnlyTime,
|
|
isDateOfMonth: isDateOfMonth)
|
|
.format(value)
|
|
: '';
|
|
}
|
|
|
|
String displayTime(DateTime value) {
|
|
final String? languageCode = locale.languageCode;
|
|
return DateFormat.Hm(languageCode).format(value);
|
|
}
|
|
|
|
//Khởi tạo Locale
|
|
static Locale localeResolutionCallback(Locale? locale, Iterable<Locale> supportedLocales) {
|
|
for (final Locale supportedLocale in supportedLocales) {
|
|
if (locale != null &&
|
|
supportedLocale.languageCode == locale.languageCode &&
|
|
supportedLocale.countryCode == locale.countryCode) {
|
|
return supportedLocale;
|
|
}
|
|
}
|
|
return supportedLocales.first;
|
|
}
|
|
|
|
Future<bool> changeLocale(BuildContext context, Locale locale) {
|
|
AppLocalizations.of(context)!.locale = locale;
|
|
Intl.defaultLocale = locale.languageCode;
|
|
return AppLocalizations.of(context)!.load();
|
|
}
|
|
|
|
// Convert tiền
|
|
String displayCurrency(double price) {
|
|
final String? languageCode = locale.languageCode;
|
|
final String curency = NumberFormat.simpleCurrency(locale: languageCode).format(price);
|
|
return curency;
|
|
}
|
|
}
|
|
|
|
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
|
|
final Iterable<Locale> _supportLocale;
|
|
|
|
_AppLocalizationsDelegate(this._supportLocale);
|
|
|
|
@override
|
|
bool isSupported(Locale locale) {
|
|
// Include all of your supported language codes here
|
|
return _supportLocale.map((e) => e.languageCode).contains(locale.languageCode);
|
|
}
|
|
|
|
@override
|
|
Future<AppLocalizations> load(Locale locale) async {
|
|
// AppLocalizations class is where the JSON loading actually runs
|
|
final AppLocalizations localizations = AppLocalizations(locale);
|
|
await localizations.load();
|
|
return localizations;
|
|
}
|
|
|
|
@override
|
|
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
|
}
|