1
0
forked from baron/baron-sso
Files
baron-sso/userfront/lib/core/i18n/locale_registry.dart

100 lines
2.7 KiB
Dart

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
const _translationAssetPrefix = 'assets/translations/';
const _templateFileName = 'template.toml';
const _safeFallbackLocaleCode = 'en';
List<String> extractSupportedLocaleCodesFromAssets(Iterable<String> assets) {
final localeCodes = <String>{};
for (final asset in assets) {
if (!asset.startsWith(_translationAssetPrefix) ||
!asset.endsWith('.toml')) {
continue;
}
final fileName = asset.substring(_translationAssetPrefix.length);
if (fileName.contains('/') || fileName == _templateFileName) {
continue;
}
final rawCode = fileName.substring(0, fileName.length - '.toml'.length);
final normalized = rawCode.toLowerCase().replaceAll('_', '-');
if (_isValidLocaleCode(normalized)) {
localeCodes.add(normalized);
}
}
final sorted = localeCodes.toList()..sort();
return sorted;
}
class LocaleRegistry {
static final Set<String> _localeCodes = <String>{};
static bool _initialized = false;
static Future<void> initialize({AssetBundle? assetBundle}) async {
if (_initialized) {
return;
}
final bundle = assetBundle ?? rootBundle;
try {
final manifest = await AssetManifest.loadFromAssetBundle(bundle);
final extracted = extractSupportedLocaleCodesFromAssets(
manifest.listAssets(),
);
_localeCodes.addAll(extracted);
} catch (_) {
// manifest 로딩 실패 시 안전 fallback으로 계속 진행합니다.
}
if (_localeCodes.isEmpty) {
_localeCodes.add(_safeFallbackLocaleCode);
}
_initialized = true;
}
static List<String> get supportedLocaleCodes {
final sorted = _localeCodes.toList()..sort();
return List.unmodifiable(sorted);
}
static String get fallbackLocaleCode {
final supported = supportedLocaleCodes;
if (supported.isEmpty) {
return _safeFallbackLocaleCode;
}
if (supported.contains('en')) {
return 'en';
}
return supported.first;
}
static bool contains(String code) {
return _localeCodes.contains(code.toLowerCase());
}
@visibleForTesting
static void setSupportedLocaleCodesForTest(Iterable<String> localeCodes) {
_localeCodes
..clear()
..addAll(
localeCodes
.map((code) => code.toLowerCase().replaceAll('_', '-'))
.where(_isValidLocaleCode),
);
if (_localeCodes.isEmpty) {
_localeCodes.add(_safeFallbackLocaleCode);
}
_initialized = true;
}
@visibleForTesting
static void resetForTest() {
_localeCodes.clear();
_initialized = false;
}
}
bool _isValidLocaleCode(String value) {
return RegExp(r'^[a-z]{2,3}$').hasMatch(value);
}