l10n_extensions.dart 8.48 KB
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 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;
  }
}