feat(i18n): ④ l10n 漂移闸 + codegen 改纯 node 确定性输出
- gen_l10n_dart.mjs 去掉 dart format:其输出依赖包解析状态、跨环境不稳(首次 4 空格、 重跑 8 空格),会让漂移闸误报。改为确定性终态格式(list 单行 const [])。 analyze 不校验格式,不影响;gen 现零 dart 依赖、纯 node 确定。 - ci/check-codegen-drift.sh 增 l10n 段:重生成 strings_*.dart → git diff 非空即 fail (与 token 段同法,纯 node)。 - 验证:往返无损、重生成零 diff(闸稳定)、flutter analyze 0 issue、244 测试全绿。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A79VtQA1BwTuQN1ThpvYpo
This commit is contained in:
@@ -61,8 +61,7 @@ class StringsEn extends AppText {
|
||||
@override
|
||||
String get watchAdMore => 'Watch ad for more time';
|
||||
@override
|
||||
String get quotaExhaustedNotice =>
|
||||
'You\'ve used today\'s free time. Upgrade to keep connecting.';
|
||||
String get quotaExhaustedNotice => 'You\'ve used today\'s free time. Upgrade to keep connecting.';
|
||||
@override
|
||||
String get adPlaying => 'Ad playing…';
|
||||
@override
|
||||
@@ -70,8 +69,7 @@ class StringsEn extends AppText {
|
||||
@override
|
||||
String get quotaDesktopTitle => 'Daily free time used up';
|
||||
@override
|
||||
String get quotaDesktopBody =>
|
||||
'Watch ads in the mobile app to add time, or upgrade for unlimited access.';
|
||||
String get quotaDesktopBody => 'Watch ads in the mobile app to add time, or upgrade for unlimited access.';
|
||||
@override
|
||||
String get gotIt => 'Got it';
|
||||
@override
|
||||
@@ -81,16 +79,13 @@ class StringsEn extends AppText {
|
||||
@override
|
||||
String get smartSelect => 'Smart select';
|
||||
@override
|
||||
String get nodeSwitchBody =>
|
||||
'This disconnects the current link and reconnects to this node.';
|
||||
String get nodeSwitchBody => 'This disconnects the current link and reconnects to this node.';
|
||||
@override
|
||||
String get nodeSwitchConfirm => 'Switch';
|
||||
@override
|
||||
String get nodeUnhealthySwitched =>
|
||||
'Current node unreachable — switched automatically';
|
||||
String get nodeUnhealthySwitched => 'Current node unreachable — switched automatically';
|
||||
@override
|
||||
String get nodeUnhealthyError =>
|
||||
'Current node is unreachable — reconnect or switch node';
|
||||
String get nodeUnhealthyError => 'Current node is unreachable — reconnect or switch node';
|
||||
@override
|
||||
String get nodeReconnecting => 'Network unstable, reconnecting…';
|
||||
@override
|
||||
@@ -148,8 +143,7 @@ class StringsEn extends AppText {
|
||||
@override
|
||||
String get deviceLimitTitle => 'Device limit reached';
|
||||
@override
|
||||
String get deviceLimitDesc =>
|
||||
'Your plan allows up to %s devices. Remove one to continue.';
|
||||
String get deviceLimitDesc => 'Your plan allows up to %s devices. Remove one to continue.';
|
||||
@override
|
||||
String get deviceLimitRemoveOldest => 'Remove least recently used';
|
||||
@override
|
||||
@@ -179,18 +173,15 @@ class StringsEn extends AppText {
|
||||
@override
|
||||
String get devSave => 'Save';
|
||||
@override
|
||||
String get devForceLogoutConfirm =>
|
||||
'This revokes the device\'s login session — it will be kicked offline and must sign in again. The device stays in the list.';
|
||||
String get devForceLogoutConfirm => 'This revokes the device\'s login session — it will be kicked offline and must sign in again. The device stays in the list.';
|
||||
@override
|
||||
String get devClearLoginConfirm =>
|
||||
'This removes the device from the list entirely and revokes its login session and data-plane credential. The device must sign in again to be used.';
|
||||
String get devClearLoginConfirm => 'This removes the device from the list entirely and revokes its login session and data-plane credential. The device must sign in again to be used.';
|
||||
@override
|
||||
String get devCancel => 'Cancel';
|
||||
@override
|
||||
String get sessionRevokedTitle => 'This device was signed out';
|
||||
@override
|
||||
String get sessionRevokedBody =>
|
||||
'Your account signed this device out from another device. Please sign in again.';
|
||||
String get sessionRevokedBody => 'Your account signed this device out from another device. Please sign in again.';
|
||||
@override
|
||||
String get sessionRevokedOk => 'Sign in again';
|
||||
@override
|
||||
@@ -232,8 +223,7 @@ class StringsEn extends AppText {
|
||||
@override
|
||||
String get webUserCenter => 'User Center (Web)';
|
||||
@override
|
||||
String get updateNotesFallback =>
|
||||
'This update includes fixes and stability improvements.';
|
||||
String get updateNotesFallback => 'This update includes fixes and stability improvements.';
|
||||
@override
|
||||
String get updateLater => 'Later';
|
||||
@override
|
||||
@@ -279,8 +269,7 @@ class StringsEn extends AppText {
|
||||
@override
|
||||
String get contactTitle => 'Contact us';
|
||||
@override
|
||||
String get contactIntro =>
|
||||
'Need help? Reach us via any channel below — usually replies in minutes.';
|
||||
String get contactIntro => 'Need help? Reach us via any channel below — usually replies in minutes.';
|
||||
@override
|
||||
String get contactEmail => 'Email support';
|
||||
@override
|
||||
@@ -338,8 +327,7 @@ class StringsEn extends AppText {
|
||||
@override
|
||||
String get ob2Title => 'Allow network setup';
|
||||
@override
|
||||
String get ob2Sub =>
|
||||
'The system will ask to add a network profile to build the encrypted tunnel.';
|
||||
String get ob2Sub => 'The system will ask to add a network profile to build the encrypted tunnel.';
|
||||
@override
|
||||
String get ob3Title => 'Private by design';
|
||||
@override
|
||||
@@ -373,18 +361,15 @@ class StringsEn extends AppText {
|
||||
@override
|
||||
String get payNetworkLabel => 'Network';
|
||||
@override
|
||||
String get payExactAmountHint =>
|
||||
'Send the exact amount; activates automatically';
|
||||
String get payExactAmountHint => 'Send the exact amount; activates automatically';
|
||||
@override
|
||||
String get copied => 'Copied';
|
||||
@override
|
||||
String get openAlipay => 'Pay with Alipay';
|
||||
@override
|
||||
String get openAlipayHint =>
|
||||
'Return after paying; this page refreshes automatically';
|
||||
String get openAlipayHint => 'Return after paying; this page refreshes automatically';
|
||||
@override
|
||||
String get openAlipayFailed =>
|
||||
'Couldn\'t open Alipay; check it\'s installed or try again';
|
||||
String get openAlipayFailed => 'Couldn\'t open Alipay; check it\'s installed or try again';
|
||||
@override
|
||||
String get awaitingPayment => 'Awaiting payment';
|
||||
@override
|
||||
@@ -520,26 +505,11 @@ class StringsEn extends AppText {
|
||||
@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',
|
||||
];
|
||||
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'];
|
||||
@override
|
||||
List<String> get featsPro => const [
|
||||
'80+ locations',
|
||||
'Unlimited · fast',
|
||||
'5 devices',
|
||||
'Streaming optimized',
|
||||
];
|
||||
List<String> get featsPro => const ['80+ locations', 'Unlimited · fast', '5 devices', 'Streaming optimized'];
|
||||
@override
|
||||
List<String> get featsTeam => const [
|
||||
'Everything in Pro',
|
||||
'10 seats',
|
||||
'Central billing',
|
||||
'Priority support',
|
||||
];
|
||||
List<String> get featsTeam => const ['Everything in Pro', '10 seats', 'Central billing', 'Priority support'];
|
||||
@override
|
||||
String adRewarded(int minutes) => '+$minutes min added';
|
||||
@override
|
||||
@@ -547,8 +517,7 @@ class StringsEn extends AppText {
|
||||
@override
|
||||
String autoConnectingTo(String name) => 'Auto-connecting to $name…';
|
||||
@override
|
||||
String updateAvailableTitle(String version) =>
|
||||
'New version v$version available';
|
||||
String updateAvailableTitle(String version) => 'New version v$version available';
|
||||
@override
|
||||
String codeSentTo(String email) => 'Code sent to $email';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user