From 877910f84bd53c9e315fdfa08a883a43019b2862 Mon Sep 17 00:00:00 2001 From: dvbthien Date: Fri, 6 Jun 2025 11:27:39 +0700 Subject: [PATCH] update new translate context --- .../extensions/build_context_extensions.dart | 15 ------ .../lib/extensions/translate_extensions.dart | 50 +++++++++++++++++++ .../widgets/settings/language_settings.dart | 18 ++++--- 3 files changed, 61 insertions(+), 22 deletions(-) create mode 100644 mobile/lib/extensions/translate_extensions.dart diff --git a/mobile/lib/extensions/build_context_extensions.dart b/mobile/lib/extensions/build_context_extensions.dart index 90292d183a..69a9c3b347 100644 --- a/mobile/lib/extensions/build_context_extensions.dart +++ b/mobile/lib/extensions/build_context_extensions.dart @@ -1,6 +1,4 @@ -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; -import 'package:intl/message_format.dart'; extension ContextHelper on BuildContext { // Returns the current padding from MediaQuery @@ -60,17 +58,4 @@ extension ContextHelper on BuildContext { // Show SnackBars from the current context void showSnackBar(SnackBar snackBar) => ScaffoldMessenger.of(this).showSnackBar(snackBar); - - String t(String key, [Map? args]) { - try { - String message = this.tr(key); - if (args != null) { - return MessageFormat(message, locale: Intl.defaultLocale ?? 'en') - .format(args); - } - return message; - } catch (e) { - return key; - } - } } diff --git a/mobile/lib/extensions/translate_extensions.dart b/mobile/lib/extensions/translate_extensions.dart new file mode 100644 index 0000000000..6ec0c58c07 --- /dev/null +++ b/mobile/lib/extensions/translate_extensions.dart @@ -0,0 +1,50 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:intl/message_format.dart'; +import 'package:flutter/material.dart'; + +extension StringTranslateExtension on String { + String t(BuildContext context, [Map? args]) { + return _translateHelper(context, this, args); + } +} + +extension TextTranslateExtension on Text { + Text t(BuildContext context, [Map? args]) { + return Text( + _translateHelper(context, data ?? '', args), + key: key, + style: style, + strutStyle: strutStyle, + textAlign: textAlign, + textDirection: textDirection, + locale: locale, + softWrap: softWrap, + overflow: overflow, + textScaler: textScaler, + maxLines: maxLines, + semanticsLabel: semanticsLabel, + textWidthBasis: textWidthBasis, + textHeightBehavior: textHeightBehavior, + ); + } +} + +String _translateHelper( + BuildContext context, + String key, [ + Map? args, +]) { + if (key.isEmpty) { + return ''; + } + try { + final translatedMessage = context.tr(key); + return args != null + ? MessageFormat(translatedMessage, locale: Intl.defaultLocale ?? 'en') + .format(args) + : translatedMessage; + } catch (e) { + debugPrint('Translation failed for key "$key". Error: $e'); + return key; + } +} diff --git a/mobile/lib/widgets/settings/language_settings.dart b/mobile/lib/widgets/settings/language_settings.dart index 08b0ce0046..7e38ba280c 100644 --- a/mobile/lib/widgets/settings/language_settings.dart +++ b/mobile/lib/widgets/settings/language_settings.dart @@ -4,6 +4,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:immich_mobile/constants/locales.dart'; +import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/services/localization.service.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/widgets/common/search_field.dart'; @@ -91,6 +92,7 @@ class LanguageSettings extends HookConsumerWidget { padding: const EdgeInsets.all(8), itemCount: filteredLocaleEntries.value.length, itemExtent: 64.0, + cacheExtent: 100, itemBuilder: (context, index) { final countryName = filteredLocaleEntries.value[index].key; @@ -100,6 +102,7 @@ class LanguageSettings extends HookConsumerWidget { selectedLocale.value == localeValue; return _LanguageItem( + key: ValueKey(localeValue.toString()), countryName: countryName, localeValue: localeValue, isSelected: isSelected, @@ -162,7 +165,7 @@ class _LanguageSearchBar extends StatelessWidget { child: SearchField( autofocus: false, contentPadding: const EdgeInsets.all(12), - hintText: context.t('language_search_hint'), + hintText: 'language_search_hint'.t(context), prefixIcon: const Icon(Icons.search_rounded), suffixIcon: controller.text.isNotEmpty ? IconButton( @@ -196,14 +199,14 @@ class _LanguageNotFound extends StatelessWidget { ), const SizedBox(height: 8), Text( - context.t('language_no_results_title'), + 'language_no_results_title'.t(context), style: context.textTheme.titleMedium?.copyWith( color: context.colorScheme.onSurface, ), ), const SizedBox(height: 4), Text( - context.t('language_no_results_subtitle'), + 'language_no_results_subtitle'.t(context), style: context.textTheme.bodyMedium?.copyWith( color: context.colorScheme.onSurface.withValues(alpha: 0.8), ), @@ -245,13 +248,13 @@ class _LanguageApplyButton extends StatelessWidget { strokeWidth: 2, ), ) - : Text( - context.t('setting_languages_apply'), - style: const TextStyle( + : const Text( + 'setting_languages_apply', + style: TextStyle( fontWeight: FontWeight.w600, fontSize: 16.0, ), - ), + ).t(context), ), ), ), @@ -261,6 +264,7 @@ class _LanguageApplyButton extends StatelessWidget { class _LanguageItem extends StatelessWidget { const _LanguageItem({ + super.key, required this.countryName, required this.localeValue, required this.isSelected,