l10n_extensions.dart
16.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
import 'dart:ui' show PlatformDispatcher;
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'app_locale_resolution.dart';
import 'gen/app_localizations.dart';
export 'app_locale_resolution.dart';
export 'gen/app_localizations.dart';
/// 在 Widget build() 中通过 context 访问:context.l10n.appName
extension AppLocalizationsX on BuildContext {
AppLocalizations get l10n =>
AppLocalizations.of(this) ?? currentAppLocalizations();
}
/// 在 Controller / 无 context 场景中全局访问:l10n.appName
AppLocalizations get l10n {
final context = _safeGetContext();
final localizations = context != null ? AppLocalizations.of(context) : null;
return localizations ?? currentAppLocalizations();
}
AppLocalizations currentAppLocalizations() {
final locale = resolveAppLocale(
Get.locale ?? PlatformDispatcher.instance.locale,
AppLocalizations.supportedLocales,
);
return lookupAppLocalizations(locale);
}
/// Explicit dialog-title vocabulary. Keeping this typed prevents individual
/// reports from drifting away from the interaction-scene table.
enum InteractionSceneTitle {
todayAverageHrv,
todayRestingHeartRate,
todaySleepStatus,
todayFitnessStatus,
weekStressTrend,
monthStressTrend,
stressTrend,
yearStressTrend,
todayActivityBurn,
weekActivityBurn,
monthActivityBurn,
activityBurn,
weekSleepTime,
monthSleepTime,
sleepTime,
pkSteps,
pkCalories,
pkStandTime,
pkMonthlyResult,
}
/// Temporary compatibility getters while the checked-in localization output is
/// regenerated. Once `flutter gen-l10n` runs, the generated instance members
/// take precedence over these extension members.
extension InteractionAppLocalizations on AppLocalizations {
String interactSceneTitle(InteractionSceneTitle title, {int? year}) {
final zhHans = switch (title) {
InteractionSceneTitle.todayAverageHrv => '今日平均HRV',
InteractionSceneTitle.todayRestingHeartRate => '今日静息心率',
InteractionSceneTitle.todaySleepStatus => '今日睡眠情况',
InteractionSceneTitle.todayFitnessStatus => '今日健身情况',
InteractionSceneTitle.weekStressTrend => '本周压力趋势',
InteractionSceneTitle.monthStressTrend => '本月压力趋势',
InteractionSceneTitle.stressTrend => '压力趋势',
InteractionSceneTitle.yearStressTrend =>
'${year ?? DateTime.now().year}年压力趋势',
InteractionSceneTitle.todayActivityBurn => '今日活动消耗',
InteractionSceneTitle.weekActivityBurn => '本周活动消耗',
InteractionSceneTitle.monthActivityBurn => '本月活动消耗',
InteractionSceneTitle.activityBurn => '活动消耗',
InteractionSceneTitle.weekSleepTime => '本周入睡时间',
InteractionSceneTitle.monthSleepTime => '本月入睡时间',
InteractionSceneTitle.sleepTime => '入睡时间',
InteractionSceneTitle.pkSteps => 'PK-今日步数',
InteractionSceneTitle.pkCalories => 'PK-活动记录',
InteractionSceneTitle.pkStandTime => 'PK-站立时间',
InteractionSceneTitle.pkMonthlyResult => 'PK-本月胜率',
};
final english = switch (title) {
InteractionSceneTitle.todayAverageHrv => 'Today’s average HRV',
InteractionSceneTitle.todayRestingHeartRate =>
'Today’s resting heart rate',
InteractionSceneTitle.todaySleepStatus => 'Today’s sleep',
InteractionSceneTitle.todayFitnessStatus => 'Today’s fitness',
InteractionSceneTitle.weekStressTrend => 'Weekly stress trend',
InteractionSceneTitle.monthStressTrend => 'Monthly stress trend',
InteractionSceneTitle.stressTrend => 'Stress trend',
InteractionSceneTitle.yearStressTrend =>
'${year ?? DateTime.now().year} stress trend',
InteractionSceneTitle.todayActivityBurn => 'Today’s activity burn',
InteractionSceneTitle.weekActivityBurn => 'Weekly activity burn',
InteractionSceneTitle.monthActivityBurn => 'Monthly activity burn',
InteractionSceneTitle.activityBurn => 'Activity burn',
InteractionSceneTitle.weekSleepTime => 'Weekly sleep time',
InteractionSceneTitle.monthSleepTime => 'Monthly sleep time',
InteractionSceneTitle.sleepTime => 'Sleep time',
InteractionSceneTitle.pkSteps => 'PK - today’s steps',
InteractionSceneTitle.pkCalories => 'PK - activity record',
InteractionSceneTitle.pkStandTime => 'PK - standing time',
InteractionSceneTitle.pkMonthlyResult => 'PK - monthly win rate',
};
return switch (localeName) {
'zh' || 'zh_Hans' => zhHans,
'zh_Hant' =>
zhHans
.replaceAll('压力', '壓力')
.replaceAll('静息', '靜息')
.replaceAll('情况', '情況')
.replaceAll('活动', '活動')
.replaceAll('站立', '站立')
.replaceAll('胜率', '勝率'),
_ => english,
};
}
String get interactRecordSelf => switch (localeName) {
'zh' || 'zh_Hans' || 'zh_Hant' => '我',
'ja' => '私',
'ko' => '나',
'de' => 'Ich',
'es' => 'Yo',
'fil' => 'Ako',
'fr' => 'Je',
'hi' => 'मैं',
'it' => 'Io',
'nl' => 'Ik',
'pt' || 'pt_BR' || 'pt_PT' => 'Eu',
'ru' => 'Я',
'tr' => 'Ben',
_ => 'I',
};
String get interactRecordYou => switch (localeName) {
'zh' || 'zh_Hans' || 'zh_Hant' => '你',
'ja' => 'あなた',
'ko' => '너',
'de' => 'dich',
'es' => 'ti',
'fil' => 'ikaw',
'fr' => 'toi',
'hi' => 'तुम्हें',
'it' => 'te',
'nl' => 'jou',
'pt' || 'pt_BR' || 'pt_PT' => 'você',
'ru' => 'тебя',
'tr' => 'seni',
_ => 'you',
};
String interactRecordTargetPronoun(bool sentByMe) {
if (!sentByMe) return interactRecordYou;
return switch (localeName) {
'zh' || 'zh_Hans' || 'zh_Hant' => 'Ta',
'ja' => '相手',
'ko' => '상대',
'de' => 'sie',
'es' => 'esa persona',
'fil' => 'siya',
'fr' => 'cette personne',
'hi' => 'उन्हें',
'it' => 'loro',
'nl' => 'hen',
'pt' || 'pt_BR' || 'pt_PT' => 'essa pessoa',
'ru' => 'его/её',
'tr' => 'onu',
_ => 'them',
};
}
/// Localized record text. ##A## is actor, ##B## is the highlighted target,
/// and ##C## is the plain-language action target.
String interactRecordTextTemplate({
required bool sentByMe,
required String? action,
required int? interactionType,
}) {
if (interactionType == 100) {
return _recordTemplate(
action: action,
scene: null,
sentByMe: sentByMe,
useHighlightedTarget: true,
);
}
final sceneTitle = _recordSceneTitle(interactionType);
final scene = sceneTitle == null ? null : interactSceneTitle(sceneTitle);
return _recordTemplate(action: action, scene: scene, sentByMe: sentByMe);
}
InteractionSceneTitle? _recordSceneTitle(int? type) => switch (type) {
100 || null => null,
101 => InteractionSceneTitle.todayAverageHrv,
102 => InteractionSceneTitle.todayRestingHeartRate,
103 => InteractionSceneTitle.todaySleepStatus,
104 => InteractionSceneTitle.todayFitnessStatus,
105 => InteractionSceneTitle.weekStressTrend,
106 => InteractionSceneTitle.monthStressTrend,
107 => InteractionSceneTitle.yearStressTrend,
108 => InteractionSceneTitle.todayActivityBurn,
109 => InteractionSceneTitle.weekActivityBurn,
110 => InteractionSceneTitle.monthActivityBurn,
111 => InteractionSceneTitle.todaySleepStatus,
112 => InteractionSceneTitle.weekSleepTime,
113 => InteractionSceneTitle.monthSleepTime,
114 => InteractionSceneTitle.pkSteps,
115 => InteractionSceneTitle.pkCalories,
116 => InteractionSceneTitle.pkStandTime,
117 => InteractionSceneTitle.pkMonthlyResult,
_ => null,
};
String _recordTemplate({
required String? action,
required String? scene,
required bool sentByMe,
bool useHighlightedTarget = false,
}) {
final verb = _recordActionVerb(action);
final actionSuffix = _recordActionSuffix(action);
final actionTargetToken = useHighlightedTarget ? '##B##' : '##C##';
final defaultText = switch (localeName) {
'zh' ||
'zh_Hans' ||
'zh_Hant' => '##A##$verb$actionTargetToken$actionSuffix~',
'ja' => '##A##が$actionTargetTokenを$verb~',
'ko' => '##A## $actionTargetToken을(를) $verb~',
'de' => '##A## hat $actionTargetToken $verb~',
'es' => '##A## $verb a $actionTargetToken~',
'fil' => '##A## ay $verb si $actionTargetToken~',
'fr' => '##A## a $verb $actionTargetToken~',
'hi' => '##A## ने $actionTargetToken को $verb~',
'it' => '##A## ha $verb $actionTargetToken~',
'nl' => '##A## heeft $actionTargetToken $verb~',
'pt' || 'pt_BR' || 'pt_PT' => '##A## $verb $actionTargetToken~',
'ru' => '##A## $verb $actionTargetToken~',
'tr' => '##A## $actionTargetToken $verb~',
_ => '##A## $verb $actionTargetToken~',
};
if (scene == null) return defaultText;
return switch (localeName) {
'zh' ||
'zh_Hans' ||
'zh_Hant' => '##A## 看了##B##的【$scene】,并$verb##C##$actionSuffix~',
'ja' => '##A##が##B##の【$scene】を見て、##C##を$verb~',
'ko' => '##A## ##B##의【$scene】을 보고 ##C##을(를) $verb~',
'de' => '##A## hat ##B##s [$scene] angesehen und ##C## $verb~',
'es' => '##A## vio [$scene] de ##B## y $verb a ##C##~',
'fil' => '##A## ay tiningnan ang [$scene] ni ##B## at $verb si ##C##~',
'fr' => '##A## a vu le [$scene] de ##B## et a $verb ##C##~',
'hi' => '##A## ने ##B## का [$scene] देखा और ##C## को $verb~',
'it' => '##A## ha visto [$scene] di ##B## e ha $verb ##C##~',
'nl' => '##A## bekeek [$scene] van ##B## en heeft ##C## $verb~',
'pt' ||
'pt_BR' ||
'pt_PT' => '##A## viu [$scene] de ##B## e $verb ##C##~',
'ru' => '##A## посмотрел(а) [$scene] ##B## и $verb ##C##~',
'tr' =>
'##A##, ##B## adlı kişinin [$scene] verisini gördü ve ##C## $verb~',
_ => '##A## viewed ##B##\'s [$scene] and $verb ##C##~',
};
}
String _recordActionVerb(String? action) => switch (localeName) {
'zh' || 'zh_Hans' || 'zh_Hant' => switch (action) {
'stick' => '戳了戳',
'miss' => '想了',
'punch' => '打了',
_ => '互动了',
},
'ja' => switch (action) {
'stick' => 'つついた',
'miss' => '会いたくなった',
'punch' => 'パンチした',
_ => '交流した',
},
'ko' => switch (action) {
'stick' => '콕 찔렀다',
'miss' => '그리워했다',
'punch' => '주먹으로 쳤다',
_ => '상호작용했다',
},
'de' => switch (action) {
'stick' => 'angestupst',
'miss' => 'vermisst',
'punch' => 'geboxt',
_ => 'kontaktiert',
},
'es' => switch (action) {
'stick' => 'dio un toque',
'miss' => 'extrañó',
'punch' => 'golpeó',
_ => 'interactuó con',
},
'fil' => switch (action) {
'stick' => 'tinapik',
'miss' => 'na-miss',
'punch' => 'sinuntok',
_ => 'nakipag-ugnayan kay',
},
'fr' => switch (action) {
'stick' => 'taquiné',
'miss' => 'manqué à',
'punch' => 'donné un coup de poing à',
_ => 'interagi avec',
},
'hi' => switch (action) {
'stick' => 'हल्का धक्का दिया',
'miss' => 'याद किया',
'punch' => 'मुक्का मारा',
_ => 'इंटरैक्ट किया',
},
'it' => switch (action) {
'stick' => 'stuzzicato',
'miss' => 'sentito la mancanza di',
'punch' => 'dato un pugno a',
_ => 'interagito con',
},
'nl' => switch (action) {
'stick' => 'geprikt',
'miss' => 'gemist',
'punch' => 'gestoten',
_ => 'contact gehad met',
},
'pt' || 'pt_BR' || 'pt_PT' => switch (action) {
'stick' => 'cutucou',
'miss' => 'sentiu saudade de',
'punch' => 'deu um soco em',
_ => 'interagiu com',
},
'ru' => switch (action) {
'stick' => 'ткнул(а)',
'miss' => 'скучал(а) по',
'punch' => 'ударил(а)',
_ => 'взаимодействовал(а) с',
},
'tr' => switch (action) {
'stick' => 'dürttü',
'miss' => 'özledi',
'punch' => 'yumrukladı',
_ => 'etkileşime geçti',
},
_ => switch (action) {
'stick' => 'poked',
'miss' => 'missed',
'punch' => 'punched',
_ => 'interacted with',
},
};
String _recordActionSuffix(String? action) => switch (localeName) {
'zh' || 'zh_Hans' || 'zh_Hant' => switch (action) {
'punch' => '一拳',
'miss' => '一次',
_ => '',
},
_ => '',
};
String get interactActionSheetInvitation => _interactionStrings.$1;
String get interactTodaySteps => _interactionStrings.$2;
String get interactStepsUnit => _interactionStrings.$3;
String get interactActionMiss => _interactionStrings.$4;
String get interactActionStick => _interactionStrings.$5;
String get interactActionPunch => _interactionStrings.$6;
String get interactThisWeek => switch (localeName) {
'zh' || 'zh_Hans' => '本周',
'zh_Hant' => '本週',
_ => 'This week',
};
String get interactThisMonth => switch (localeName) {
'zh' || 'zh_Hans' => '本月',
'zh_Hant' => '本月',
_ => 'This month',
};
(String, String, String, String, String, String) get _interactionStrings =>
switch (localeName) {
'zh' || 'zh_Hans' => ('快来和我互动吧~', '今日步数', '步', '想你', '戳一戳', '打一拳'),
'zh_Hant' => ('快來和我互動吧~', '今日步數', '步', '想你', '戳一戳', '打一拳'),
'ja' => ('一緒に交流しよう~', '今日の歩数', '歩', '会いたい', 'つんつん', 'パンチ'),
'ko' => ('나와 함께 소통해요~', '오늘의 걸음 수', '걸음', '보고 싶어', '콕 찌르기', '주먹'),
'de' => (
'Lass uns interagieren~',
'Heutige Schritte',
'Schritte',
'Vermisse dich',
'Anstupsen',
'Boxen',
),
'es' => (
'¡Ven a interactuar conmigo!',
'Pasos de hoy',
'pasos',
'Te extraño',
'Toquecito',
'Puñetazo',
),
'fil' => (
'Makipag-ugnayan tayo~',
'Mga hakbang ngayon',
'hakbang',
'Miss kita',
'Tapikin',
'Suntok',
),
'fr' => (
'Viens interagir avec moi~',
'Pas du jour',
'pas',
'Tu me manques',
'Taquiner',
'Coup de poing',
),
'hi' => (
'मेरे साथ इंटरैक्ट करें~',
'आज के कदम',
'कदम',
'तुम्हारी याद आती है',
'हल्का धक्का',
'मुक्का',
),
'it' => (
'Vieni a interagire con me~',
'Passi di oggi',
'passi',
'Mi manchi',
'Stuzzica',
'Pugno',
),
'nl' => (
'Kom met me interacteren~',
'Stappen van vandaag',
'stappen',
'Ik mis je',
'Prikje',
'Stoot',
),
'pt' || 'pt_BR' => (
'Venha interagir comigo~',
'Passos de hoje',
'passos',
'Sinto sua falta',
'Cutucar',
'Soco',
),
'pt_PT' => (
'Vem interagir comigo~',
'Passos de hoje',
'passos',
'Tenho saudades tuas',
'Picar',
'Soco',
),
'ru' => (
'Давай пообщаемся~',
'Шаги за сегодня',
'шагов',
'Скучаю по тебе',
'Тыкнуть',
'Ударить',
),
'tr' => (
'Benimle etkileşime geç~',
'Bugünün adımları',
'adım',
'Seni özledim',
'Dürt',
'Yumruk',
),
_ => (
'Come interact with me~',
"Today's steps",
'steps',
'Miss you',
'Poke',
'Punch',
),
};
}
BuildContext? _safeGetContext() {
try {
return Get.context;
} catch (_) {
return null;
}
}