feat: add runtime i18n API with manifest translations
This commit is contained in:
@@ -15,6 +15,7 @@ class GamePackageManifest {
|
||||
this.display = const GameDisplayConfig(),
|
||||
this.resources = const {},
|
||||
this.modules = const {},
|
||||
this.translations = const {},
|
||||
this.base,
|
||||
});
|
||||
|
||||
@@ -30,6 +31,10 @@ class GamePackageManifest {
|
||||
final Map<String, GameResource> resources;
|
||||
final Map<String, String> modules;
|
||||
|
||||
/// 翻译字典:locale → { key → translatedText }。
|
||||
/// Runtime 会按包加载顺序合并,游戏包覆盖框架包。
|
||||
final Map<String, Map<String, String>> translations;
|
||||
|
||||
/// 依赖的框架包 gameId。加载时会先加载框架包,再加载游戏包。
|
||||
final String? base;
|
||||
|
||||
@@ -64,6 +69,26 @@ class GamePackageManifest {
|
||||
|
||||
final base = map['base'] as String?;
|
||||
|
||||
final translationsValue = map['translations'];
|
||||
final translations = <String, Map<String, String>>{};
|
||||
if (translationsValue is Map) {
|
||||
for (final entry in translationsValue.entries) {
|
||||
if (entry.key is! String || entry.value is! Map) {
|
||||
throw const FormatException('manifest.translations must be a map');
|
||||
}
|
||||
final localeDict = <String, String>{};
|
||||
for (final kv in (entry.value as Map).entries) {
|
||||
if (kv.key is! String || kv.value is! String) {
|
||||
throw const FormatException(
|
||||
'manifest.translations values must be string maps',
|
||||
);
|
||||
}
|
||||
localeDict[kv.key as String] = kv.value as String;
|
||||
}
|
||||
translations[entry.key as String] = localeDict;
|
||||
}
|
||||
}
|
||||
|
||||
final defaultLocale = (map['defaultLocale'] as String?) ?? 'en';
|
||||
final supportedLocales = _stringList(
|
||||
map,
|
||||
@@ -95,6 +120,7 @@ class GamePackageManifest {
|
||||
display: display,
|
||||
resources: resources,
|
||||
modules: modules,
|
||||
translations: translations,
|
||||
base: base,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user