feat(i18n): ③ 原型接单源 — I18N 块由 strings.json 生成,消除重复翻译
原型 design/prototype/screens/{ui-desktop,ui-mobile}.html 的 I18N 数据块不再手写,
改由 strings.json 生成(marker 包裹、生成器唯一写):
- alias.json:protoKey → flutterKey(产品串取单源 zh/en,单源赢);desktop 130 / mobile 143。
- overlay.json:原型专属(开发挡板 + app 没有的串,zh/en);desktop 98 / mobile 104。
- new-strings.json:4 个新产品串(分流规则/自定义/局域网直连/强制),6 语,已并入
strings.json + app_text.dart 抽象声明 + 重生成 6 份 strings_*.dart。
- gen_proto_i18n.mjs:strings.json+alias+overlay → 两份 HTML 的 I18N 块;--check 只比对
marker 块(unrelated HTML 编辑不误报)。
- check-proto-i18n.mjs:两份 HTML 所有 data-i18n key 的 zh/en 必须 resolve。
- ci/check-codegen-drift.sh:加原型 i18n 段(--check 漂移 + resolution 验收)。
同带入之前路由原型 WIP 的 i18n 收口:私有服务内置行→局域网/私网直连行、rr.* 接 data-i18n
(rr.lan→routingLanDirect 等)。路由页其余 UI(段选/添加规则页)仍为独立后续。
验收(自复核全绿):生成器跑通、data-i18n 0 unresolved、两生成器重生成零 diff、
flutter analyze lib/l10n 0 issue、flutter test 244 全绿、new-strings 无红线词。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A79VtQA1BwTuQN1ThpvYpo
This commit is contained in:
@@ -628,4 +628,9 @@ abstract class AppText {
|
||||
String get settingsGroupConn; // 连接 / Connection
|
||||
String get settingsGroupAppearance;// 外观 / Appearance
|
||||
String get settingsGroupAbout; // 关于 / About
|
||||
// ── 分流规则(configurable proxy)──
|
||||
String get routingRulesTitle; // 分流规则 / Routing rules
|
||||
String get routingRulesSub; // 自定义直连 / 走隧道 / 拒绝
|
||||
String get routingLanDirect; // 局域网 / 私网直连 / LAN & private direct
|
||||
String get routingLanForced; // 强制,不可关 / Always on
|
||||
}
|
||||
|
||||
@@ -503,6 +503,14 @@ class StringsEn extends AppText {
|
||||
@override
|
||||
String get promoOriginalPrice => 'Was';
|
||||
@override
|
||||
String get routingRulesTitle => 'Routing rules';
|
||||
@override
|
||||
String get routingRulesSub => 'Custom direct / tunnel / reject';
|
||||
@override
|
||||
String get routingLanDirect => 'LAN & private direct';
|
||||
@override
|
||||
String get routingLanForced => 'Always on';
|
||||
@override
|
||||
List<String> get days7 => const ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
|
||||
@override
|
||||
List<String> get featsFree => const ['1 basic node only', '10 min per day', 'Watch an ad to start', '7-day free trial on sign-up'];
|
||||
|
||||
@@ -503,6 +503,14 @@ class StringsEs extends AppText {
|
||||
@override
|
||||
String get promoOriginalPrice => 'Antes';
|
||||
@override
|
||||
String get routingRulesTitle => 'Reglas de enrutamiento';
|
||||
@override
|
||||
String get routingRulesSub => 'Personalizar: directo / túnel / rechazar';
|
||||
@override
|
||||
String get routingLanDirect => 'LAN y red privada directas';
|
||||
@override
|
||||
String get routingLanForced => 'Siempre activo';
|
||||
@override
|
||||
List<String> get days7 => const ['L', 'M', 'X', 'J', 'V', 'S', 'D'];
|
||||
@override
|
||||
List<String> get featsFree => const ['Solo 1 nodo básico', '10 min al día', 'Mira un anuncio para empezar', 'Prueba gratis de 7 días al registrarte'];
|
||||
|
||||
@@ -503,6 +503,14 @@ class StringsJa extends AppText {
|
||||
@override
|
||||
String get promoOriginalPrice => '通常価格';
|
||||
@override
|
||||
String get routingRulesTitle => 'ルーティングルール';
|
||||
@override
|
||||
String get routingRulesSub => '直接接続 / トンネル / 拒否をカスタム';
|
||||
@override
|
||||
String get routingLanDirect => 'LAN・プライベート直接接続';
|
||||
@override
|
||||
String get routingLanForced => '常時オン';
|
||||
@override
|
||||
List<String> get days7 => const ['月', '火', '水', '木', '金', '土', '日'];
|
||||
@override
|
||||
List<String> get featsFree => const ['基本ノード1つのみ', '1日10分', '広告を見て開始', '登録で7日間無料トライアル'];
|
||||
|
||||
@@ -503,6 +503,14 @@ class StringsKo extends AppText {
|
||||
@override
|
||||
String get promoOriginalPrice => '정가';
|
||||
@override
|
||||
String get routingRulesTitle => '라우팅 규칙';
|
||||
@override
|
||||
String get routingRulesSub => '직접 연결 / 터널 / 거부 사용자 지정';
|
||||
@override
|
||||
String get routingLanDirect => 'LAN / 사설망 직접 연결';
|
||||
@override
|
||||
String get routingLanForced => '항상 켜짐';
|
||||
@override
|
||||
List<String> get days7 => const ['월', '화', '수', '목', '금', '토', '일'];
|
||||
@override
|
||||
List<String> get featsFree => const ['기본 노드 1개', '하루 10분', '광고 시청 후 시작', '가입 시 7일 무료 체험'];
|
||||
|
||||
@@ -503,6 +503,14 @@ class StringsRu extends AppText {
|
||||
@override
|
||||
String get promoOriginalPrice => 'Было';
|
||||
@override
|
||||
String get routingRulesTitle => 'Правила маршрутизации';
|
||||
@override
|
||||
String get routingRulesSub => 'Настройка: напрямую / туннель / отклонить';
|
||||
@override
|
||||
String get routingLanDirect => 'Локальная и частная сеть напрямую';
|
||||
@override
|
||||
String get routingLanForced => 'Всегда включено';
|
||||
@override
|
||||
List<String> get days7 => const ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'];
|
||||
@override
|
||||
List<String> get featsFree => const ['Только 1 базовый узел', '10 минут в день', 'Смотрите рекламу, чтобы начать', '7 дней бесплатно при регистрации'];
|
||||
|
||||
@@ -503,6 +503,14 @@ class StringsZh extends AppText {
|
||||
@override
|
||||
String get promoOriginalPrice => '原价';
|
||||
@override
|
||||
String get routingRulesTitle => '分流规则';
|
||||
@override
|
||||
String get routingRulesSub => '自定义直连 / 走隧道 / 拒绝';
|
||||
@override
|
||||
String get routingLanDirect => '局域网 / 私网直连';
|
||||
@override
|
||||
String get routingLanForced => '强制,不可关';
|
||||
@override
|
||||
List<String> get days7 => const ['一', '二', '三', '四', '五', '六', '日'];
|
||||
@override
|
||||
List<String> get featsFree => const ['仅 1 个基础节点', '每日 10 分钟时长', '使用前观看广告', '注册享 7 天免费试用'];
|
||||
|
||||
Reference in New Issue
Block a user