From 835c35e9408332762e71afd64286a505cb2a9a6c Mon Sep 17 00:00:00 2001 From: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:41:12 +0530 Subject: [PATCH] chore: migrate mobile translations accessor (2) (#30668) Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> --- .../presentation/pages/drift_memory.page.dart | 4 +- .../add_action_button.widget.dart | 19 ++- .../like_activity_action_button.widget.dart | 9 +- .../motion_photo_action_button.widget.dart | 4 +- .../appears_in_details.widget.dart | 4 +- .../date_time_details.widget.dart | 10 +- .../location_details.widget.dart | 6 +- .../asset_details/people_details.widget.dart | 8 +- .../asset_details/rating_details.widget.dart | 4 +- .../technical_details.widget.dart | 4 +- .../asset_viewer/asset_viewer.page.dart | 4 +- .../motion_photo_button.widget.dart | 4 +- .../asset_viewer/rating_bar.widget.dart | 7 +- .../asset_viewer/sheet_tile.widget.dart | 8 +- .../memory/memory_bottom_info.widget.dart | 5 +- .../widgets/memory/memory_lane.widget.dart | 4 +- .../lib/widgets/asset_grid/delete_dialog.dart | 138 +++++++++--------- .../lib/widgets/asset_viewer/cast_dialog.dart | 22 +-- .../lib/widgets/memories/memory_epilogue.dart | 18 +-- .../image_viewer_quality_setting.dart | 10 +- .../image_viewer_tap_to_navigate_setting.dart | 8 +- .../slideshow_settings.dart | 47 ++---- .../video_viewer_settings.dart | 19 +-- .../sync_status_and_actions.dart | 99 ++++--------- .../settings/free_up_space_settings.dart | 137 +++++++---------- .../networking_settings/endpoint_input.dart | 6 +- .../external_network_preference.dart | 6 +- .../local_network_preference.dart | 31 ++-- .../networking_settings.dart | 31 ++-- .../settings/ssl_client_cert_settings.dart | 29 ++-- 30 files changed, 304 insertions(+), 401 deletions(-) diff --git a/mobile/lib/presentation/pages/drift_memory.page.dart b/mobile/lib/presentation/pages/drift_memory.page.dart index 31371fe581..3ad7d90657 100644 --- a/mobile/lib/presentation/pages/drift_memory.page.dart +++ b/mobile/lib/presentation/pages/drift_memory.page.dart @@ -8,7 +8,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/memory.model.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/presentation/widgets/images/image_provider.dart'; import 'package:immich_mobile/presentation/widgets/memory/memory_bottom_info.widget.dart'; import 'package:immich_mobile/presentation/widgets/memory/memory_card.widget.dart'; @@ -248,7 +248,7 @@ class DriftMemoryPage extends HookConsumerWidget { } final yearsAgo = DateTime.now().year - memories[mIndex].data.year; - final title = 'years_ago'.t(context: context, args: {'years': yearsAgo.toString()}); + final title = context.t.years_ago(years: yearsAgo); // Build horizontal page final assetController = memoryAssetPageControllers[mIndex]; return Column( diff --git a/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart index cfb5887c7c..2466a52ead 100644 --- a/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart @@ -1,13 +1,12 @@ import 'dart:async'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/domain/models/album/album.model.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/presentation/actions/action.widget.dart'; import 'package:immich_mobile/presentation/actions/archive.action.dart'; import 'package:immich_mobile/presentation/actions/lock.action.dart'; @@ -52,11 +51,11 @@ class _AddActionButtonState extends ConsumerState { return [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: Text("add_to_bottom_bar".tr(), style: context.textTheme.labelMedium), + child: Text(context.t.add_to_bottom_bar, style: context.textTheme.labelMedium), ), BaseActionButton( iconData: Icons.photo_album_outlined, - label: "album".tr(), + label: context.t.album, menuItem: true, onPressed: () => _handleMenuSelection(AddToMenuItem.album), ), @@ -65,7 +64,7 @@ class _AddActionButtonState extends ConsumerState { const Divider(), Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: Text("move_to".tr(), style: context.textTheme.labelMedium), + child: Text(context.t.move_to, style: context.textTheme.labelMedium), ), const ActionMenuItem(action: ArchiveAction(source: .viewer)), const ActionMenuItem(action: LockAction(source: .viewer)), @@ -120,7 +119,7 @@ class _AddActionButtonState extends ConsumerState { } if (!result.success) { - ImmichToast.show(context: context, msg: 'scaffold_body_error_occurred'.tr(), toastType: ToastType.error); + ImmichToast.show(context: context, msg: context.t.scaffold_body_error_occurred, toastType: ToastType.error); return; } @@ -128,7 +127,7 @@ class _AddActionButtonState extends ConsumerState { if (result.count > 0) { ImmichToast.show( context: context, - msg: 'add_to_album_bottom_sheet_added'.tr(namedArgs: {'album': album.name}), + msg: context.t.add_to_album_bottom_sheet_added(album: album.name), ); // Refresh the "Appears in" list on the asset's info panel. @@ -136,13 +135,13 @@ class _AddActionButtonState extends ConsumerState { } else if (result.failedCount > 0) { ImmichToast.show( context: context, - msg: 'assets_cannot_be_added_to_album_count'.t(context: context, args: {'count': result.failedCount}), + msg: context.t.assets_cannot_be_added_to_album_count(count: result.failedCount), toastType: ToastType.error, ); } else { ImmichToast.show( context: context, - msg: 'add_to_album_bottom_sheet_already_exists'.tr(namedArgs: {'album': album.name}), + msg: context.t.add_to_album_bottom_sheet_already_exists(album: album.name), ); } @@ -183,7 +182,7 @@ class _AddActionButtonState extends ConsumerState { builder: (context, controller, child) { return BaseActionButton( iconData: Icons.add, - label: "add_to_bottom_bar".tr(), + label: context.t.add_to_bottom_bar, onPressed: () => controller.isOpen ? controller.close() : controller.open(), ); }, diff --git a/mobile/lib/presentation/widgets/action_buttons/like_activity_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/like_activity_action_button.widget.dart index 46a5c2c41e..e39a76ef02 100644 --- a/mobile/lib/presentation/widgets/action_buttons/like_activity_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/like_activity_action_button.widget.dart @@ -1,9 +1,8 @@ import 'package:collection/collection.dart'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/models/activities/activity.model.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart'; import 'package:immich_mobile/providers/activity.provider.dart'; @@ -48,7 +47,7 @@ class LikeActivityActionButton extends ConsumerWidget { return BaseActionButton( maxWidth: 60, iconData: liked != null ? Icons.thumb_up : Icons.thumb_up_off_alt, - label: "like".t(context: context), + label: context.t.like, onPressed: () => onTap(liked), iconOnly: iconOnly, menuItem: menuItem, @@ -58,11 +57,11 @@ class LikeActivityActionButton extends ConsumerWidget { // default to empty heart during loading loading: () => BaseActionButton( iconData: Icons.thumb_up_off_alt, - label: "like".t(context: context), + label: context.t.like, iconOnly: iconOnly, menuItem: menuItem, ), - error: (error, stack) => Text('error_saving_image'.tr(args: [error.toString()])), + error: (error, stack) => Text(context.t.error_saving_image(error: error.toString())), ); } } diff --git a/mobile/lib/presentation/widgets/action_buttons/motion_photo_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/motion_photo_action_button.widget.dart index 878c589b21..6be8a6b023 100644 --- a/mobile/lib/presentation/widgets/action_buttons/motion_photo_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/motion_photo_action_button.widget.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart'; import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.provider.dart'; @@ -16,7 +16,7 @@ class MotionPhotoActionButton extends ConsumerWidget { return BaseActionButton( iconData: isPlaying ? Icons.motion_photos_pause_outlined : Icons.play_circle_outline_rounded, - label: "play_motion_photo".t(context: context), + label: context.t.play_motion_photo, onPressed: ref.watch(isPlayingMotionVideoProvider.notifier).toggle, iconOnly: iconOnly, menuItem: menuItem, diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_details/appears_in_details.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_details/appears_in_details.widget.dart index dffda47b84..efd2ee00a1 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_details/appears_in_details.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_details/appears_in_details.widget.dart @@ -7,7 +7,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/presentation/widgets/album/album_tile.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/sheet_tile.widget.dart'; import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'; @@ -52,7 +52,7 @@ class AppearsInDetails extends ConsumerWidget { spacing: 12, children: [ SheetTile( - title: 'appears_in'.t(context: context), + title: context.t.appears_in, titleStyle: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurfaceSecondary), ), Padding( diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_details/date_time_details.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_details/date_time_details.widget.dart index eff5705eae..9f426f6db7 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_details/date_time_details.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_details/date_time_details.widget.dart @@ -8,7 +8,7 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/exif.model.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/duration_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/presentation/actions/edit_datetime.action.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/sheet_tile.widget.dart'; import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; @@ -100,7 +100,7 @@ class _SheetAssetDescriptionState extends ConsumerState<_SheetAssetDescription> ImmichToast.show( context: context, - msg: 'exif_bottom_sheet_description_error'.t(context: context), + msg: context.t.exif_bottom_sheet_description_error, toastType: ToastType.error, ); } @@ -111,9 +111,9 @@ class _SheetAssetDescriptionState extends ConsumerState<_SheetAssetDescription> @override Widget build(BuildContext context) { final currentDescription = widget.exif.description ?? ''; - final hintText = (widget.isEditable ? 'exif_bottom_sheet_description' : 'exif_bottom_sheet_no_description').t( - context: context, - ); + final hintText = widget.isEditable + ? context.t.exif_bottom_sheet_description + : context.t.exif_bottom_sheet_no_description; if (_controller.text != currentDescription && !_descriptionFocus.hasFocus) { _controller.text = currentDescription; } diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_details/location_details.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_details/location_details.widget.dart index c6d048e458..47ecb53d8a 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_details/location_details.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_details/location_details.widget.dart @@ -6,7 +6,7 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/exif.model.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/presentation/actions/edit_location.action.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/sheet_tile.widget.dart'; import 'package:immich_mobile/widgets/asset_viewer/detail_panel/exif_map.dart'; @@ -75,7 +75,7 @@ class _LocationDetailsState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.start, children: [ SheetTile( - title: 'location'.t(context: context), + title: context.t.location, titleStyle: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurfaceSecondary), trailing: hasCoordinates && editLocation != null ? const Icon(Icons.edit_location_alt, size: 20) : null, onTap: editLocation?.onAction, @@ -107,7 +107,7 @@ class _LocationDetailsState extends ConsumerState { ), if (!hasCoordinates) SheetTile( - title: "add_a_location".t(context: context), + title: context.t.add_a_location, titleStyle: context.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w600, color: context.primaryColor, diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_details/people_details.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_details/people_details.widget.dart index 72db236b3c..739fe0a0d9 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_details/people_details.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_details/people_details.widget.dart @@ -7,7 +7,7 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/person.model.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/presentation/widgets/images/remote_image_provider.dart'; import 'package:immich_mobile/presentation/widgets/people/person_edit_name_modal.widget.dart'; import 'package:immich_mobile/providers/infrastructure/people.provider.dart'; @@ -52,7 +52,7 @@ class PeopleDetails extends ConsumerWidget { Padding( padding: const EdgeInsets.only(left: 16, top: 16, bottom: 16), child: Text( - "people".t(context: context), + context.t.people, style: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurfaceSecondary), ), ), @@ -89,7 +89,7 @@ class PeopleDetails extends ConsumerWidget { duration: Durations.short4, ); }, - error: (error, stack) => Text("error_loading_people".t(context: context), style: context.textTheme.bodyMedium), + error: (error, stack) => Text(context.t.errors.failed_to_load_people, style: context.textTheme.bodyMedium), loading: () => const SizedBox.shrink(), ); } @@ -135,7 +135,7 @@ class _Avatar extends StatelessWidget { GestureDetector( onTap: () => onNameTap?.call(), child: Text( - "add_a_name".t(context: context), + context.t.add_a_name, style: context.textTheme.labelLarge?.copyWith(color: context.primaryColor), maxLines: 2, overflow: TextOverflow.ellipsis, diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_details/rating_details.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_details/rating_details.widget.dart index 352838c761..f07fb5c112 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_details/rating_details.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_details/rating_details.widget.dart @@ -4,7 +4,7 @@ import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/domain/models/exif.model.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/rating_bar.widget.dart'; import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/infrastructure/user_metadata.provider.dart'; @@ -32,7 +32,7 @@ class RatingDetails extends ConsumerWidget { spacing: 8, children: [ Text( - 'rating'.t(context: context), + context.t.rating, style: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurfaceSecondary), ), RatingBar( diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_details/technical_details.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_details/technical_details.widget.dart index e92b671562..e36cd9967b 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_details/technical_details.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_details/technical_details.widget.dart @@ -4,7 +4,7 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/exif.model.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/sheet_tile.widget.dart'; import 'package:immich_mobile/repositories/asset_media.repository.dart'; import 'package:immich_mobile/utils/bytes_units.dart'; @@ -27,7 +27,7 @@ class TechnicalDetails extends ConsumerWidget { return Column( children: [ SheetTile( - title: 'details'.t(context: context), + title: context.t.details, titleStyle: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurfaceSecondary), ), _buildFileInfoTile(context, ref, asset, exifInfo), diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart index 731d8f3481..ad330309ab 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:math' as math; import 'package:auto_route/auto_route.dart'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -14,6 +13,7 @@ import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/platform_extensions.dart'; import 'package:immich_mobile/extensions/scroll_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/download_status_floating_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_page.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_preloader.dart'; @@ -210,7 +210,7 @@ class _AssetViewerState extends ConsumerState { SnackBar( duration: const Duration(seconds: 2), content: Text( - "local_asset_cast_failed".tr(), + context.t.local_asset_cast_failed, style: context.textTheme.bodyLarge?.copyWith(color: context.primaryColor), ), ), diff --git a/mobile/lib/presentation/widgets/asset_viewer/motion_photo_button.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/motion_photo_button.widget.dart index 08d6b59423..78f234d39b 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/motion_photo_button.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/motion_photo_button.widget.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/platform_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.provider.dart'; @@ -66,7 +66,7 @@ class _MotionButton extends StatelessWidget { ), const SizedBox(width: 8), Text( - CurrentPlatform.isAndroid ? 'motion'.t(context: context) : 'live'.t(context: context), + CurrentPlatform.isAndroid ? context.t.motion : context.t.live, style: const TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500), ), ], diff --git a/mobile/lib/presentation/widgets/asset_viewer/rating_bar.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/rating_bar.widget.dart index 0ed37869be..fb5cfff255 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/rating_bar.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/rating_bar.widget.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; class RatingBar extends StatefulWidget { final double initialRating; @@ -129,10 +129,7 @@ class _RatingBarState extends State { }); widget.onClearRating?.call(); }, - child: Text( - 'rating_clear'.t(context: context), - style: TextStyle(color: context.themeData.colorScheme.primary), - ), + child: Text(context.t.rating_clear, style: TextStyle(color: context.themeData.colorScheme.primary)), ), ), ], diff --git a/mobile/lib/presentation/widgets/asset_viewer/sheet_tile.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/sheet_tile.widget.dart index ac6f79a155..8ff0befd7b 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/sheet_tile.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/sheet_tile.widget.dart @@ -3,7 +3,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/providers/haptic_feedback.provider.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; @@ -29,11 +29,7 @@ class SheetTile extends ConsumerWidget { void copyTitle(BuildContext context, WidgetRef ref) { unawaited(Clipboard.setData(ClipboardData(text: title))); - ImmichToast.show( - context: context, - msg: 'copied_to_clipboard'.t(context: context), - toastType: ToastType.info, - ); + ImmichToast.show(context: context, msg: context.t.copied_to_clipboard, toastType: ToastType.info); ref.read(hapticFeedbackProvider.notifier).selectionClick(); } diff --git a/mobile/lib/presentation/widgets/memory/memory_bottom_info.widget.dart b/mobile/lib/presentation/widgets/memory/memory_bottom_info.widget.dart index fc9bfb34e7..2bafdc0843 100644 --- a/mobile/lib/presentation/widgets/memory/memory_bottom_info.widget.dart +++ b/mobile/lib/presentation/widgets/memory/memory_bottom_info.widget.dart @@ -1,12 +1,13 @@ // ignore_for_file: require_trailing_commas import 'package:auto_route/auto_route.dart'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/models/memory.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/routing/router.dart'; +import 'package:intl/intl.dart'; class DriftMemoryBottomInfo extends StatelessWidget { final DriftMemory memory; @@ -36,7 +37,7 @@ class DriftMemoryBottomInfo extends StatelessWidget { ], ), Tooltip( - message: 'view_in_timeline'.tr(), + message: context.t.view_in_timeline, child: MaterialButton( minWidth: 0, onPressed: () async { diff --git a/mobile/lib/presentation/widgets/memory/memory_lane.widget.dart b/mobile/lib/presentation/widgets/memory/memory_lane.widget.dart index 94a91437b0..1732249523 100644 --- a/mobile/lib/presentation/widgets/memory/memory_lane.widget.dart +++ b/mobile/lib/presentation/widgets/memory/memory_lane.widget.dart @@ -4,7 +4,7 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/memory.model.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/presentation/pages/drift_memory.page.dart'; import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart'; import 'package:immich_mobile/providers/haptic_feedback.provider.dart'; @@ -53,7 +53,7 @@ class DriftMemoryCard extends StatelessWidget { @override Widget build(BuildContext context) { final yearsAgo = DateTime.now().year - memory.data.year; - final title = 'years_ago'.t(context: context, args: {'years': yearsAgo.toString()}); + final title = context.t.years_ago(years: yearsAgo); return Center( child: Stack( children: [ diff --git a/mobile/lib/widgets/asset_grid/delete_dialog.dart b/mobile/lib/widgets/asset_grid/delete_dialog.dart index ff5aac617a..9b0367a463 100644 --- a/mobile/lib/widgets/asset_grid/delete_dialog.dart +++ b/mobile/lib/widgets/asset_grid/delete_dialog.dart @@ -1,69 +1,69 @@ -import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/material.dart'; -import 'package:immich_mobile/extensions/build_context_extensions.dart'; - -class DeleteLocalOnlyDialog extends StatelessWidget { - final void Function(bool onlyMerged) onDeleteLocal; - - const DeleteLocalOnlyDialog({super.key, required this.onDeleteLocal}); - - @override - Widget build(BuildContext context) { - void onDeleteBackedUpOnly() { - context.pop(true); - onDeleteLocal(true); - } - - void onForceDelete() { - context.pop(false); - onDeleteLocal(false); - } - - return AlertDialog( - shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10))), - title: const Text("delete_dialog_title").tr(), - content: const Text("delete_dialog_alert_local_non_backed_up").tr(), - actions: [ - SizedBox( - width: double.infinity, - height: 48, - child: FilledButton( - onPressed: () => context.pop(), - style: FilledButton.styleFrom( - backgroundColor: context.colorScheme.surfaceDim, - foregroundColor: context.primaryColor, - ), - child: const Text("cancel", style: TextStyle(fontWeight: FontWeight.bold)).tr(), - ), - ), - const SizedBox(height: 8), - SizedBox( - width: double.infinity, - height: 48, - - child: FilledButton( - onPressed: onDeleteBackedUpOnly, - style: FilledButton.styleFrom( - backgroundColor: context.colorScheme.errorContainer, - foregroundColor: context.colorScheme.onErrorContainer, - ), - child: const Text( - "delete_local_dialog_ok_backed_up_only", - style: TextStyle(fontWeight: FontWeight.bold), - ).tr(), - ), - ), - const SizedBox(height: 8), - SizedBox( - width: double.infinity, - height: 48, - child: FilledButton( - onPressed: onForceDelete, - style: FilledButton.styleFrom(backgroundColor: Colors.red[400], foregroundColor: Colors.white), - child: const Text("delete_local_dialog_ok_force", style: TextStyle(fontWeight: FontWeight.bold)).tr(), - ), - ), - ], - ); - } -} +import 'package:flutter/material.dart'; +import 'package:immich_mobile/extensions/build_context_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; + +class DeleteLocalOnlyDialog extends StatelessWidget { + final void Function(bool onlyMerged) onDeleteLocal; + + const DeleteLocalOnlyDialog({super.key, required this.onDeleteLocal}); + + @override + Widget build(BuildContext context) { + void onDeleteBackedUpOnly() { + context.pop(true); + onDeleteLocal(true); + } + + void onForceDelete() { + context.pop(false); + onDeleteLocal(false); + } + + return AlertDialog( + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10))), + title: Text(context.t.delete_dialog_title), + content: Text(context.t.delete_dialog_alert_local_non_backed_up), + actions: [ + SizedBox( + width: double.infinity, + height: 48, + child: FilledButton( + onPressed: () => context.pop(), + style: FilledButton.styleFrom( + backgroundColor: context.colorScheme.surfaceDim, + foregroundColor: context.primaryColor, + ), + child: Text(context.t.cancel, style: const TextStyle(fontWeight: FontWeight.bold)), + ), + ), + const SizedBox(height: 8), + SizedBox( + width: double.infinity, + height: 48, + + child: FilledButton( + onPressed: onDeleteBackedUpOnly, + style: FilledButton.styleFrom( + backgroundColor: context.colorScheme.errorContainer, + foregroundColor: context.colorScheme.onErrorContainer, + ), + child: Text( + context.t.delete_local_dialog_ok_backed_up_only, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ), + ), + const SizedBox(height: 8), + SizedBox( + width: double.infinity, + height: 48, + child: FilledButton( + onPressed: onForceDelete, + style: FilledButton.styleFrom(backgroundColor: Colors.red[400], foregroundColor: Colors.white), + child: Text(context.t.delete_local_dialog_ok_force, style: const TextStyle(fontWeight: FontWeight.bold)), + ), + ), + ], + ); + } +} diff --git a/mobile/lib/widgets/asset_viewer/cast_dialog.dart b/mobile/lib/widgets/asset_viewer/cast_dialog.dart index f91d8f5b27..70b1b3d3e5 100644 --- a/mobile/lib/widgets/asset_viewer/cast_dialog.dart +++ b/mobile/lib/widgets/asset_viewer/cast_dialog.dart @@ -1,9 +1,9 @@ import 'dart:async'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/models/cast/cast_manager_state.dart'; import 'package:immich_mobile/providers/cast.provider.dart'; @@ -23,7 +23,7 @@ class CastDialog extends ConsumerWidget { } return AlertDialog( - title: const Text("cast", style: TextStyle(fontWeight: FontWeight.bold)).tr(), + title: Text(context.t.cast, style: const TextStyle(fontWeight: FontWeight.bold)), content: SizedBox( width: 250, height: 250, @@ -31,13 +31,13 @@ class CastDialog extends ConsumerWidget { future: ref.watch(castProvider.notifier).getDevices(), builder: (context, snapshot) { if (snapshot.hasError) { - return Text('error_saving_image'.tr(args: [snapshot.error.toString()])); + return Text(context.t.error_saving_image(error: snapshot.error.toString())); } else if (!snapshot.hasData) { return const SizedBox(height: 48, child: Center(child: CircularProgressIndicator())); } if (snapshot.data!.isEmpty) { - return const Text('no_cast_devices_found').tr(); + return Text(context.t.no_cast_devices_found); } final devices = snapshot.data!; @@ -47,12 +47,12 @@ class CastDialog extends ConsumerWidget { final List sectionedList = []; if (connected.isNotEmpty) { - sectionedList.add("connected_device"); + sectionedList.add(context.t.connected_device); sectionedList.addAll(connected); } if (others.isNotEmpty) { - sectionedList.add("discovered_devices"); + sectionedList.add(context.t.discovered_devices); sectionedList.addAll(others); } @@ -66,7 +66,7 @@ class CastDialog extends ConsumerWidget { // It's a section header return Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), - child: Text(item, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16)).tr(), + child: Text(item, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16)), ); } else { final (deviceName, type, deviceObj) = item as (String, CastDestinationType, dynamic); @@ -110,16 +110,16 @@ class CastDialog extends ConsumerWidget { TextButton( onPressed: () => ref.read(castProvider.notifier).disconnect(), child: Text( - "stop_casting", + context.t.stop_casting, style: TextStyle(color: context.colorScheme.secondary, fontWeight: FontWeight.bold), - ).tr(), + ), ), TextButton( onPressed: () => context.pop(), child: Text( - "close", + context.t.close, style: TextStyle(color: context.colorScheme.primary, fontWeight: FontWeight.bold), - ).tr(), + ), ), ], ); diff --git a/mobile/lib/widgets/memories/memory_epilogue.dart b/mobile/lib/widgets/memories/memory_epilogue.dart index b866ed049a..0335b586ac 100644 --- a/mobile/lib/widgets/memories/memory_epilogue.dart +++ b/mobile/lib/widgets/memories/memory_epilogue.dart @@ -1,6 +1,6 @@ -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; class MemoryEpilogue extends StatefulWidget { final Function()? onStartOver; @@ -45,23 +45,23 @@ class _MemoryEpilogueState extends State with TickerProviderStat ), const SizedBox(height: 16.0), Text( - "memories_all_caught_up", + context.t.memories_all_caught_up, style: context.textTheme.headlineMedium?.copyWith(color: Colors.white), - ).tr(), + ), const SizedBox(height: 16.0), Text( - "memories_check_back_tomorrow", + context.t.memories_check_back_tomorrow, style: context.textTheme.bodyMedium?.copyWith(color: Colors.white), - ).tr(), + ), const SizedBox(height: 16.0), TextButton( onPressed: widget.onStartOver, child: Text( - "memories_start_over", + context.t.memories_start_over, style: context.textTheme.displayMedium?.copyWith( color: context.isDarkTheme ? context.colorScheme.primary : context.colorScheme.inversePrimary, ), - ).tr(), + ), ), ], ), @@ -85,9 +85,9 @@ class _MemoryEpilogueState extends State with TickerProviderStat ), ), Text( - "memories_swipe_to_close", + context.t.memories_swipe_to_close, style: context.textTheme.bodyMedium?.copyWith(color: Colors.white), - ).tr(), + ), ], ), ), diff --git a/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_quality_setting.dart b/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_quality_setting.dart index 82a2d804a3..d1b1e3d0f2 100644 --- a/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_quality_setting.dart +++ b/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_quality_setting.dart @@ -3,7 +3,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/providers/app_settings.provider.dart'; import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/setting_group_title.dart'; @@ -23,14 +23,14 @@ class ImageViewerQualitySetting extends HookConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ SettingGroupTitle( - title: "photos".t(context: context), + title: context.t.photos, icon: Icons.image_outlined, - subtitle: "setting_image_viewer_help".t(context: context), + subtitle: context.t.setting_image_viewer_help, ), SettingsSwitchListTile( valueNotifier: isOriginal, - title: "setting_image_viewer_original_title".t(context: context), - subtitle: "setting_image_viewer_original_subtitle".t(context: context), + title: context.t.setting_image_viewer_original_title, + subtitle: context.t.setting_image_viewer_original_subtitle, onChanged: (_) => ref.invalidate(appSettingsServiceProvider), ), ], diff --git a/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_tap_to_navigate_setting.dart b/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_tap_to_navigate_setting.dart index fc3466c3c6..ed07028bcf 100644 --- a/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_tap_to_navigate_setting.dart +++ b/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_tap_to_navigate_setting.dart @@ -1,9 +1,9 @@ import 'dart:async'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/settings_sub_title.dart'; import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart'; @@ -21,11 +21,11 @@ class ImageViewerTapToNavigateSetting extends HookConsumerWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SettingsSubTitle(title: "setting_image_navigation_title".tr()), + SettingsSubTitle(title: context.t.setting_image_navigation_title), SettingsSwitchListTile( valueNotifier: tapToNavigate, - title: "setting_image_navigation_enable_title".tr(), - subtitle: "setting_image_navigation_enable_subtitle".tr(), + title: context.t.setting_image_navigation_enable_title, + subtitle: context.t.setting_image_navigation_enable_subtitle, ), ], ); diff --git a/mobile/lib/widgets/settings/asset_viewer_settings/slideshow_settings.dart b/mobile/lib/widgets/settings/asset_viewer_settings/slideshow_settings.dart index d8ccd4f0ed..bc4d9a1235 100644 --- a/mobile/lib/widgets/settings/asset_viewer_settings/slideshow_settings.dart +++ b/mobile/lib/widgets/settings/asset_viewer_settings/slideshow_settings.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/setting_group_title.dart'; import 'package:immich_mobile/widgets/settings/settings_radio_list_tile.dart'; @@ -39,40 +39,28 @@ class SlideshowSettings extends HookConsumerWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SettingGroupTitle( - title: 'slideshow'.t(context: context), - icon: Icons.slideshow_outlined, - ), + SettingGroupTitle(title: context.t.slideshow, icon: Icons.slideshow_outlined), SettingsSwitchListTile( valueNotifier: useRepeat, - title: "slideshow_repeat".t(context: context), - subtitle: "slideshow_repeat_description".t(context: context), + title: context.t.slideshow_repeat, + subtitle: context.t.slideshow_repeat_description, ), SettingsSliderListTile( valueNotifier: useDuration, - text: "duration".t(context: context), + text: context.t.duration, minValue: 5, noDivisons: 5, maxValue: 30, ), Padding( padding: const EdgeInsets.only(top: 20), - child: SettingsSubTitle(title: 'look'.t(context: context)), + child: SettingsSubTitle(title: context.t.look), ), SettingsRadioListTile( groups: [ - SettingsRadioGroup( - title: 'contain'.t(context: context), - value: SlideshowLook.contain, - ), - SettingsRadioGroup( - title: 'cover'.t(context: context), - value: SlideshowLook.cover, - ), - SettingsRadioGroup( - title: 'blurred_background'.t(context: context), - value: SlideshowLook.blurredBackground, - ), + SettingsRadioGroup(title: context.t.contain, value: SlideshowLook.contain), + SettingsRadioGroup(title: context.t.cover, value: SlideshowLook.cover), + SettingsRadioGroup(title: context.t.blurred_background, value: SlideshowLook.blurredBackground), ], groupBy: useLook.value, onRadioChanged: (value) { @@ -83,24 +71,15 @@ class SlideshowSettings extends HookConsumerWidget { ), Padding( padding: const EdgeInsets.only(top: 20), - child: SettingsSubTitle(title: 'direction'.t(context: context)), + child: SettingsSubTitle(title: context.t.direction), ), Padding( padding: const EdgeInsets.only(bottom: 32), child: SettingsRadioListTile( groups: [ - SettingsRadioGroup( - title: 'forward'.t(context: context), - value: SlideshowDirection.forward, - ), - SettingsRadioGroup( - title: 'backward'.t(context: context), - value: SlideshowDirection.backward, - ), - SettingsRadioGroup( - title: 'shuffle'.t(context: context), - value: SlideshowDirection.shuffle, - ), + SettingsRadioGroup(title: context.t.forward, value: SlideshowDirection.forward), + SettingsRadioGroup(title: context.t.backward, value: SlideshowDirection.backward), + SettingsRadioGroup(title: context.t.shuffle, value: SlideshowDirection.shuffle), ], groupBy: useDirection.value, onRadioChanged: (value) { diff --git a/mobile/lib/widgets/settings/asset_viewer_settings/video_viewer_settings.dart b/mobile/lib/widgets/settings/asset_viewer_settings/video_viewer_settings.dart index 7bea439f0c..2a575061ca 100644 --- a/mobile/lib/widgets/settings/asset_viewer_settings/video_viewer_settings.dart +++ b/mobile/lib/widgets/settings/asset_viewer_settings/video_viewer_settings.dart @@ -3,7 +3,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/setting_group_title.dart'; import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart'; @@ -31,24 +31,21 @@ class VideoViewerSettings extends HookConsumerWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SettingGroupTitle( - title: "videos".t(context: context), - icon: Icons.video_camera_back_outlined, - ), + SettingGroupTitle(title: context.t.videos, icon: Icons.video_camera_back_outlined), SettingsSwitchListTile( valueNotifier: useAutoPlayVideo, - title: "setting_video_viewer_auto_play_title".t(context: context), - subtitle: "setting_video_viewer_auto_play_subtitle".t(context: context), + title: context.t.setting_video_viewer_auto_play_title, + subtitle: context.t.setting_video_viewer_auto_play_subtitle, ), SettingsSwitchListTile( valueNotifier: useLoopVideo, - title: "setting_video_viewer_looping_title".t(context: context), - subtitle: "loop_videos_description".t(context: context), + title: context.t.setting_video_viewer_looping_title, + subtitle: context.t.loop_videos_description, ), SettingsSwitchListTile( valueNotifier: useOriginalVideo, - title: "setting_video_viewer_original_video_title".t(context: context), - subtitle: "setting_video_viewer_original_video_subtitle".t(context: context), + title: context.t.setting_video_viewer_original_video_title, + subtitle: context.t.setting_video_viewer_original_video_subtitle, ), ], ); diff --git a/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart b/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart index 097f72e1e1..d2edef832e 100644 --- a/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart +++ b/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart @@ -5,7 +5,6 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/platform_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/providers/app_settings.provider.dart'; import 'package:immich_mobile/providers/background_sync.provider.dart'; @@ -45,9 +44,7 @@ class SyncStatusAndActions extends HookConsumerWidget { return; } - context.scaffoldMessenger.showSnackBar( - SnackBar(content: Text("Database file not found".t(context: context))), - ); + context.scaffoldMessenger.showSnackBar(const SnackBar(content: Text('Database file not found'))); return; } @@ -77,17 +74,13 @@ class SyncStatusAndActions extends HookConsumerWidget { return; } - context.scaffoldMessenger.showSnackBar( - SnackBar(content: Text("Database exported successfully".t(context: context))), - ); + context.scaffoldMessenger.showSnackBar(const SnackBar(content: Text('Database exported successfully'))); } catch (e) { if (!context.mounted) { return; } - context.scaffoldMessenger.showSnackBar( - SnackBar(content: Text("Failed to export database: $e".t(context: context))), - ); + context.scaffoldMessenger.showSnackBar(SnackBar(content: Text('Failed to export database: $e'))); } } @@ -138,10 +131,10 @@ class SyncStatusAndActions extends HookConsumerWidget { const _SyncStatsCounts(), const Divider(height: 10), const SizedBox(height: 16), - SettingGroupTitle(title: "jobs".t(context: context)), + SettingGroupTitle(title: context.t.jobs), SettingListTile( - title: "sync_local".t(context: context), - subtitle: "tap_to_run_job".t(context: context), + title: context.t.sync_local, + subtitle: context.t.tap_to_run_job, leading: const Icon(Icons.sync), trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).localSyncStatus), onTap: () { @@ -149,8 +142,8 @@ class SyncStatusAndActions extends HookConsumerWidget { }, ), SettingListTile( - title: "sync_remote".t(context: context), - subtitle: "tap_to_run_job".t(context: context), + title: context.t.sync_remote, + subtitle: context.t.tap_to_run_job, leading: const Icon(Icons.cloud_sync), trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).remoteSyncStatus), onTap: () { @@ -159,16 +152,16 @@ class SyncStatusAndActions extends HookConsumerWidget { ), if (CurrentPlatform.isIOS && serverVersion.isAtLeast(major: 2, minor: 5)) SettingListTile( - title: "Sync Cloud Ids".t(context: context), + title: 'Sync Cloud Ids', leading: const Icon(Icons.cloud_circle_rounded), - subtitle: "tap_to_run_job".t(context: context), + subtitle: context.t.tap_to_run_job, trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).cloudIdSyncStatus), onTap: ref.watch(backgroundSyncProvider).syncCloudIds, ), SettingListTile( - title: "hash_asset".t(context: context), + title: context.t.hash_asset, leading: const Icon(Icons.tag), - subtitle: "tap_to_run_job".t(context: context), + subtitle: context.t.tap_to_run_job, trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).hashJobStatus), onTap: () { unawaited(ref.read(backgroundSyncProvider).hashAssets()); @@ -176,27 +169,21 @@ class SyncStatusAndActions extends HookConsumerWidget { ), const Divider(height: 1), const SizedBox(height: 16), - SettingGroupTitle(title: "actions".t(context: context)), + SettingGroupTitle(title: context.t.actions), ListTile( - title: Text( - "clear_file_cache".t(context: context), - style: const TextStyle(fontWeight: FontWeight.w500), - ), + title: Text(context.t.clear_file_cache, style: const TextStyle(fontWeight: FontWeight.w500)), leading: const Icon(Icons.playlist_remove_rounded), onTap: clearFileCache, ), ListTile( - title: Text( - "export_database".t(context: context), - style: const TextStyle(fontWeight: FontWeight.w500), - ), - subtitle: Text("export_database_description".t(context: context)), + title: Text(context.t.export_database, style: const TextStyle(fontWeight: FontWeight.w500)), + subtitle: Text(context.t.export_database_description), leading: const Icon(Icons.download), onTap: exportDatabase, ), ListTile( title: Text( - "reset_sqlite".t(context: context), + context.t.reset_sqlite, style: TextStyle(color: context.colorScheme.error, fontWeight: FontWeight.w500), ), leading: Icon(Icons.settings_backup_restore_rounded, color: context.colorScheme.error), @@ -282,7 +269,7 @@ class _SyncStatsCounts extends ConsumerWidget { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - SettingGroupTitle(title: "assets".t(context: context)), + SettingGroupTitle(title: context.t.assets), Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), // 1. Wrap in IntrinsicHeight @@ -295,24 +282,16 @@ class _SyncStatsCounts extends ConsumerWidget { spacing: 8.0, children: [ Expanded( - child: EntityCountTile( - label: "local".t(context: context), - count: localAssetCount, - icon: Icons.smartphone, - ), + child: EntityCountTile(label: context.t.local, count: localAssetCount, icon: Icons.smartphone), ), Expanded( - child: EntityCountTile( - label: "remote".t(context: context), - count: remoteAssetCount, - icon: Icons.cloud, - ), + child: EntityCountTile(label: context.t.remote, count: remoteAssetCount, icon: Icons.cloud), ), ], ), ), ), - SettingGroupTitle(title: "albums".t(context: context)), + SettingGroupTitle(title: context.t.albums), Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), child: IntrinsicHeight( @@ -323,24 +302,16 @@ class _SyncStatsCounts extends ConsumerWidget { spacing: 8.0, children: [ Expanded( - child: EntityCountTile( - label: "local".t(context: context), - count: localAlbumCount, - icon: Icons.smartphone, - ), + child: EntityCountTile(label: context.t.local, count: localAlbumCount, icon: Icons.smartphone), ), Expanded( - child: EntityCountTile( - label: "remote".t(context: context), - count: remoteAlbumCount, - icon: Icons.cloud, - ), + child: EntityCountTile(label: context.t.remote, count: remoteAlbumCount, icon: Icons.cloud), ), ], ), ), ), - SettingGroupTitle(title: "other".t(context: context)), + SettingGroupTitle(title: context.t.other), Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), child: IntrinsicHeight( @@ -351,18 +322,10 @@ class _SyncStatsCounts extends ConsumerWidget { spacing: 8.0, children: [ Expanded( - child: EntityCountTile( - label: "memories".t(context: context), - count: memoryCount, - icon: Icons.calendar_today, - ), + child: EntityCountTile(label: context.t.memories, count: memoryCount, icon: Icons.calendar_today), ), Expanded( - child: EntityCountTile( - label: "hashed_assets".t(context: context), - count: localHashedCount, - icon: Icons.tag, - ), + child: EntityCountTile(label: context.t.hashed_assets, count: localHashedCount, icon: Icons.tag), ), ], ), @@ -371,7 +334,7 @@ class _SyncStatsCounts extends ConsumerWidget { // To be removed once the experimental feature is stable if (CurrentPlatform.isAndroid && appSettingsService.getSetting(AppSettingsEnum.manageLocalMediaAndroid)) ...[ - SettingGroupTitle(title: "trash".t(context: context)), + SettingGroupTitle(title: context.t.trash), Consumer( builder: (context, ref, _) { final counts = ref.watch(trashedAssetsCountProvider); @@ -387,17 +350,13 @@ class _SyncStatsCounts extends ConsumerWidget { children: [ Expanded( child: EntityCountTile( - label: "local".t(context: context), + label: context.t.local, count: c.total, icon: Icons.delete_outline, ), ), Expanded( - child: EntityCountTile( - label: "hashed_assets".t(context: context), - count: c.hashed, - icon: Icons.tag, - ), + child: EntityCountTile(label: context.t.hashed_assets, count: c.hashed, icon: Icons.tag), ), ], ), diff --git a/mobile/lib/widgets/settings/free_up_space_settings.dart b/mobile/lib/widgets/settings/free_up_space_settings.dart index 8d4785d664..5885601171 100644 --- a/mobile/lib/widgets/settings/free_up_space_settings.dart +++ b/mobile/lib/widgets/settings/free_up_space_settings.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'package:auto_route/auto_route.dart'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; @@ -9,12 +8,13 @@ import 'package:immich_mobile/domain/models/album/local_album.model.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/platform_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/providers/cleanup.provider.dart'; import 'package:immich_mobile/providers/haptic_feedback.provider.dart'; import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/utils/bytes_units.dart'; +import 'package:intl/intl.dart'; import 'package:wakelock_plus/wakelock_plus.dart'; class FreeUpSpaceSettings extends ConsumerStatefulWidget { @@ -236,21 +236,21 @@ class _FreeUpSpaceSettingsState extends ConsumerState { final parts = []; if (state.keepMediaType == AssetKeepType.photosOnly) { - parts.add('all_photos'.t(context: context)); + parts.add(context.t.all_photos); } else if (state.keepMediaType == AssetKeepType.videosOnly) { - parts.add('all_videos'.t(context: context)); + parts.add(context.t.all_videos); } if (state.keepFavorites) { - parts.add('favorites'.t(context: context)); + parts.add(context.t.favorites); } if (state.keepAlbumIds.isNotEmpty) { - parts.add('keep_albums_count'.t(context: context, args: {'count': state.keepAlbumIds.length.toString()})); + parts.add(context.t.keep_albums_count(count: state.keepAlbumIds.length)); } if (parts.isEmpty) { - return 'none'.t(context: context); + return context.t.none; } return parts.join(', '); @@ -274,7 +274,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { borderRadius: const BorderRadius.all(Radius.circular(12)), border: Border.all(color: context.primaryColor.withValues(alpha: 0.25)), ), - child: Text('free_up_space_description'.t(context: context), style: context.textTheme.bodyMedium), + child: Text(context.t.free_up_space_description, style: context.textTheme.bodyMedium), ), ), @@ -307,7 +307,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { color: hasKeepSettings ? context.colorScheme.primary : context.colorScheme.onSurfaceVariant, ), title: Text( - 'keep_on_device'.t(context: context), + context.t.keep_on_device, style: context.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.w600, color: hasKeepSettings ? context.colorScheme.primary : null, @@ -315,8 +315,8 @@ class _FreeUpSpaceSettingsState extends ConsumerState { ), subtitle: Text( hasKeepSettings - ? 'keeping'.t(context: context, args: {'items': getKeepSettingsSummary()}) - : 'keep_on_device_hint'.t(context: context), + ? context.t.keeping(items: getKeepSettingsSummary()) + : context.t.keep_on_device_hint, style: context.textTheme.bodySmall?.copyWith( color: hasKeepSettings ? context.colorScheme.primary : context.colorScheme.onSurfaceVariant, ), @@ -327,12 +327,12 @@ class _FreeUpSpaceSettingsState extends ConsumerState { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Text('keep_description'.t(context: context), style: subtitleStyle), + Text(context.t.keep_description, style: subtitleStyle), const SizedBox(height: 4), SwitchListTile( contentPadding: EdgeInsets.zero, title: Text( - 'keep_favorites'.t(context: context), + context.t.keep_favorites, style: context.textTheme.bodyLarge!.copyWith(fontWeight: FontWeight.w500, height: 1.5), ), @@ -352,7 +352,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { ), const SizedBox(height: 16), Text( - 'always_keep'.t(context: context), + context.t.always_keep, style: context.textTheme.bodyLarge!.copyWith(fontWeight: FontWeight.w500, height: 1.5), ), const SizedBox(height: 4), @@ -362,12 +362,12 @@ class _FreeUpSpaceSettingsState extends ConsumerState { const ButtonSegment(value: AssetKeepType.none, label: Text('—')), ButtonSegment( value: AssetKeepType.photosOnly, - label: Text('photos'.t(context: context)), + label: Text(context.t.photos), icon: const Icon(Icons.photo), ), ButtonSegment( value: AssetKeepType.videosOnly, - label: Text('videos'.t(context: context)), + label: Text(context.t.videos), icon: const Icon(Icons.videocam), ), ], @@ -381,8 +381,8 @@ class _FreeUpSpaceSettingsState extends ConsumerState { const SizedBox(height: 8), Text( state.keepMediaType == AssetKeepType.photosOnly - ? 'always_keep_photos_hint'.t(context: context) - : 'always_keep_videos_hint'.t(context: context), + ? context.t.always_keep_photos_hint + : context.t.always_keep_videos_hint, style: context.textTheme.bodySmall?.copyWith( color: context.colorScheme.onSurfaceVariant, ), @@ -413,7 +413,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { Step( stepStyle: styleForState(step1State), title: Text( - 'select_cutoff_date'.t(context: context), + context.t.select_cutoff_date, style: context.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w600, color: step1State == StepState.complete @@ -433,7 +433,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { content: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Text('cutoff_date_description'.t(context: context), style: subtitleStyle), + Text(context.t.cutoff_date_description, style: subtitleStyle), const SizedBox(height: 16), GridView.count( shrinkWrap: true, @@ -445,39 +445,39 @@ class _FreeUpSpaceSettingsState extends ConsumerState { children: [ _DatePresetCard( value: '30', - unit: 'cutoff_day'.t(context: context, args: {'count': '30'}), + unit: context.t.cutoff_day(count: 30), onTap: () => _setPresetDate(30), isSelected: _isPresetSelected(30), ), _DatePresetCard( value: '60', - unit: 'cutoff_day'.t(context: context, args: {'count': '60'}), + unit: context.t.cutoff_day(count: 60), onTap: () => _setPresetDate(60), isSelected: _isPresetSelected(60), ), _DatePresetCard( value: '90', - unit: 'cutoff_day'.t(context: context, args: {'count': '90'}), + unit: context.t.cutoff_day(count: 90), onTap: () => _setPresetDate(90), isSelected: _isPresetSelected(90), ), _DatePresetCard( value: '1', - unit: 'cutoff_year'.t(context: context, args: {'count': '1'}), + unit: context.t.cutoff_year(count: 1), onTap: () => _setPresetDate(365), isSelected: _isPresetSelected(365), ), _DatePresetCard( value: '2', - unit: 'cutoff_year'.t(context: context, args: {'count': '2'}), + unit: context.t.cutoff_year(count: 2), onTap: () => _setPresetDate(730), isSelected: _isPresetSelected(730), ), _DatePresetCard( value: '3', - unit: 'cutoff_year'.t(context: context, args: {'count': '3'}), + unit: context.t.cutoff_year(count: 3), onTap: () => _setPresetDate(1095), isSelected: _isPresetSelected(1095), ), @@ -487,14 +487,14 @@ class _FreeUpSpaceSettingsState extends ConsumerState { OutlinedButton.icon( onPressed: _selectDate, icon: const Icon(Icons.calendar_today), - label: Text('custom_date'.t(context: context)), + label: Text(context.t.custom_date), style: OutlinedButton.styleFrom(minimumSize: const Size(double.infinity, 48)), ), const SizedBox(height: 16), ElevatedButton.icon( onPressed: hasDate ? _goToScanStep : null, icon: const Icon(Icons.arrow_forward), - label: Text('continue'.t(context: context)), + label: Text(context.t.continue$), style: ElevatedButton.styleFrom(minimumSize: const Size(double.infinity, 48)), ), ], @@ -507,7 +507,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { Step( stepStyle: styleForState(step2State), title: Text( - 'scan'.t(context: context), + context.t.scan, style: context.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w600, color: step2State == StepState.complete @@ -520,17 +520,11 @@ class _FreeUpSpaceSettingsState extends ConsumerState { subtitle: _hasScanned ? Text( state.totalBytes > 0 - ? 'cleanup_found_assets_with_size'.t( - context: context, - args: { - 'count': state.assetsToDelete.length.toString(), - 'size': formatBytes(state.totalBytes), - }, + ? context.t.cleanup_found_assets_with_size( + count: state.assetsToDelete.length, + size: formatBytes(state.totalBytes), ) - : 'cleanup_found_assets'.t( - context: context, - args: {'count': state.assetsToDelete.length.toString()}, - ), + : context.t.cleanup_found_assets(count: state.assetsToDelete.length), style: context.textTheme.bodyMedium?.copyWith( color: state.assetsToDelete.isNotEmpty ? context.colorScheme.primary @@ -541,7 +535,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { : null, content: Column( children: [ - Text('cleanup_step3_description'.t(context: context), style: subtitleStyle), + Text(context.t.cleanup_step3_description, style: subtitleStyle), if (CurrentPlatform.isIOS) ...[ const SizedBox(height: 12), Container( @@ -556,7 +550,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { const SizedBox(width: 12), Expanded( child: Text( - 'cleanup_icloud_shared_albums_excluded'.t(context: context), + context.t.cleanup_icloud_shared_albums_excluded, style: context.textTheme.labelLarge, ), ), @@ -577,7 +571,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { : ElevatedButton.icon( onPressed: state.isScanning ? null : _scanAssets, icon: const Icon(Icons.search), - label: Text(_hasScanned ? 'rescan'.t(context: context) : 'scan'.t(context: context)), + label: Text(_hasScanned ? context.t.rescan : context.t.scan), style: ElevatedButton.styleFrom(minimumSize: const Size(double.infinity, 48)), ), if (_hasScanned && state.assetsToDelete.isEmpty) ...[ @@ -593,10 +587,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { const Icon(Icons.info, color: Colors.orange), const SizedBox(width: 12), Expanded( - child: Text( - 'cleanup_no_assets_found'.t(context: context), - style: context.textTheme.bodyMedium, - ), + child: Text(context.t.cleanup_no_assets_found, style: context.textTheme.bodyMedium), ), ], ), @@ -612,7 +603,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { Step( stepStyle: styleForState(step3State, isDestructive: true), title: Text( - 'move_to_device_trash'.t(context: context), + context.t.move_to_device_trash, style: context.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w600, color: step3State == StepState.disabled @@ -635,12 +626,9 @@ class _FreeUpSpaceSettingsState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'cleanup_step4_summary'.t( - context: context, - args: { - 'count': state.assetsToDelete.length.toString(), - 'date': DateFormat.yMMMd().format(state.selectedDate!), - }, + context.t.cleanup_step4_summary( + count: state.assetsToDelete.length, + date: DateFormat.yMMMd().format(state.selectedDate!), ), style: context.textTheme.labelLarge?.copyWith(fontSize: 15), ), @@ -652,7 +640,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { OutlinedButton.icon( onPressed: () => _showAssetsPreview(state.assetsToDelete), icon: const Icon(Icons.preview), - label: Text('preview'.t(context: context)), + label: Text(context.t.preview), style: OutlinedButton.styleFrom(minimumSize: const Size(double.infinity, 48)), ), const SizedBox(height: 12), @@ -665,11 +653,7 @@ class _FreeUpSpaceSettingsState extends ConsumerState { child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white), ) : const Icon(Icons.delete_forever), - label: Text( - state.isDeleting - ? 'cleanup_deleting'.t(context: context) - : 'move_to_device_trash'.t(context: context), - ), + label: Text(state.isDeleting ? context.t.cleanup_deleting : context.t.move_to_device_trash), style: ElevatedButton.styleFrom( backgroundColor: context.colorScheme.error, foregroundColor: context.colorScheme.onError, @@ -701,26 +685,20 @@ class _DeleteConfirmationDialog extends StatelessWidget { @override Widget build(BuildContext context) { return AlertDialog( - title: Text('cleanup_confirm_prompt_title'.t(context: context)), + title: Text(context.t.cleanup_confirm_prompt_title), content: Text( - 'cleanup_confirm_description'.t( - context: context, - args: {'count': assetCount.toString(), 'date': DateFormat.yMMMd().format(cutoffDate)}, - ), + context.t.cleanup_confirm_description(count: assetCount, date: DateFormat.yMMMd().format(cutoffDate)), style: context.textTheme.labelLarge?.copyWith(fontSize: 15), ), actions: [ - TextButton( - onPressed: () => ContextHelper(context).pop(false), - child: Text('cancel'.t(context: context)), - ), + TextButton(onPressed: () => ContextHelper(context).pop(false), child: Text(context.t.cancel)), ElevatedButton( onPressed: () => ContextHelper(context).pop(true), style: ElevatedButton.styleFrom( backgroundColor: context.colorScheme.error, foregroundColor: context.colorScheme.onError, ), - child: Text('confirm'.t(context: context)), + child: Text(context.t.confirm), ), ], ); @@ -736,29 +714,24 @@ class _DeleteSuccessDialog extends StatelessWidget { Widget build(BuildContext context) { return AlertDialog( icon: Icon(Icons.check_circle, color: context.colorScheme.primary, size: 48), - title: Text('success'.t(context: context)), + title: Text(context.t.success), content: Column( mainAxisSize: MainAxisSize.min, children: [ Text( - 'cleanup_deleted_assets'.t(context: context, args: {'count': deletedCount.toString()}), + context.t.cleanup_deleted_assets(count: deletedCount), style: context.textTheme.labelLarge?.copyWith(fontSize: 16), textAlign: TextAlign.center, ), const SizedBox(height: 16), Text( - 'cleanup_trash_hint'.t(context: context), + context.t.cleanup_trash_hint, style: context.textTheme.labelLarge?.copyWith(fontSize: 16, color: context.primaryColor), textAlign: TextAlign.center, ), ], ), - actions: [ - ElevatedButton( - onPressed: () => ContextHelper(context).pop(), - child: Text('done'.t(context: context)), - ), - ], + actions: [ElevatedButton(onPressed: () => ContextHelper(context).pop(), child: Text(context.t.done))], ); } } @@ -824,7 +797,7 @@ class _KeepAlbumsSection extends ConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'keep_albums'.t(context: context), + context.t.keep_albums, style: context.textTheme.bodyLarge!.copyWith(fontWeight: FontWeight.w500, height: 1.5), ), @@ -834,13 +807,13 @@ class _KeepAlbumsSection extends ConsumerWidget { child: Padding(padding: EdgeInsets.all(16.0), child: CircularProgressIndicator(strokeWidth: 2)), ), error: (error, stack) => Text( - 'error_loading_albums'.t(context: context), + context.t.error_loading_albums, style: context.textTheme.bodyMedium?.copyWith(color: context.colorScheme.error), ), data: (albums) { if (albums.isEmpty) { return Text( - 'no_albums_found'.t(context: context), + context.t.no_albums_found, style: context.textTheme.bodyMedium?.copyWith( color: context.colorScheme.onSurface.withValues(alpha: 0.6), ), @@ -870,7 +843,7 @@ class _KeepAlbumsSection extends ConsumerWidget { if (albumIds.isNotEmpty) ...[ const SizedBox(height: 8), Text( - 'keep_albums_count'.t(context: context, args: {'count': albumIds.length.toString()}), + context.t.keep_albums_count(count: albumIds.length), style: context.textTheme.bodySmall?.copyWith( color: context.colorScheme.primary, fontWeight: FontWeight.w500, diff --git a/mobile/lib/widgets/settings/networking_settings/endpoint_input.dart b/mobile/lib/widgets/settings/networking_settings/endpoint_input.dart index 162f1252a8..349b32287b 100644 --- a/mobile/lib/widgets/settings/networking_settings/endpoint_input.dart +++ b/mobile/lib/widgets/settings/networking_settings/endpoint_input.dart @@ -1,8 +1,8 @@ import 'dart:async'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart'; import 'package:immich_mobile/providers/auth.provider.dart'; import 'package:immich_mobile/widgets/settings/networking_settings/networking_settings.dart'; @@ -78,11 +78,11 @@ class EndpointInputState extends ConsumerState { try { if (url == null || url.isEmpty || !Uri.parse(url).isAbsolute) { isInputValid = false; - return 'validate_endpoint_error'.tr(); + return context.t.validate_endpoint_error; } } catch (_) { isInputValid = false; - return 'validate_endpoint_error'.tr(); + return context.t.validate_endpoint_error; } isInputValid = true; diff --git a/mobile/lib/widgets/settings/networking_settings/external_network_preference.dart b/mobile/lib/widgets/settings/networking_settings/external_network_preference.dart index 81ffb4b19b..63b094b440 100644 --- a/mobile/lib/widgets/settings/networking_settings/external_network_preference.dart +++ b/mobile/lib/widgets/settings/networking_settings/external_network_preference.dart @@ -5,7 +5,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/settings_key.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart'; import 'package:immich_mobile/providers/api.provider.dart'; import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; @@ -103,7 +103,7 @@ class ExternalNetworkPreference extends HookConsumerWidget { children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 24), - child: Text("external_network_sheet_info".t(context: context), style: context.textTheme.bodyMedium), + child: Text(context.t.external_network_sheet_info, style: context.textTheme.bodyMedium), ), const SizedBox(height: 4), Divider(color: context.colorScheme.surfaceContainerHighest), @@ -135,7 +135,7 @@ class ExternalNetworkPreference extends HookConsumerWidget { height: 48, child: OutlinedButton.icon( icon: const Icon(Icons.add), - label: Text('add_endpoint'.t(context: context)), + label: Text(context.t.add_endpoint), onPressed: enabled ? () { entries.value = [ diff --git a/mobile/lib/widgets/settings/networking_settings/local_network_preference.dart b/mobile/lib/widgets/settings/networking_settings/local_network_preference.dart index 8b787bcaea..3c4fa73543 100644 --- a/mobile/lib/widgets/settings/networking_settings/local_network_preference.dart +++ b/mobile/lib/widgets/settings/networking_settings/local_network_preference.dart @@ -1,11 +1,10 @@ import 'dart:async'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/providers/auth.provider.dart'; import 'package:immich_mobile/providers/network.provider.dart'; import 'package:immich_ui/immich_ui.dart'; @@ -34,9 +33,12 @@ class LocalNetworkPreference extends HookConsumerWidget { actions: [ TextButton( onPressed: () => Navigator.pop(context), - child: Text('cancel'.tr().toUpperCase(), style: const TextStyle(color: Colors.red)), + child: Text(context.t.cancel.toUpperCase(), style: const TextStyle(color: Colors.red)), + ), + TextButton( + onPressed: () => Navigator.pop(context, controller.text), + child: Text(context.t.save.toUpperCase()), ), - TextButton(onPressed: () => Navigator.pop(context, controller.text), child: Text('save'.tr().toUpperCase())), ], ), ); @@ -73,7 +75,12 @@ class LocalNetworkPreference extends HookConsumerWidget { } Future handleEditWifiName() async { - final wifiName = await _showEditDialog(context, "wifi_name".tr(), "your_wifi_name".tr(), wifiNameText.value); + final wifiName = await _showEditDialog( + context, + context.t.wifi_name, + context.t.your_wifi_name, + wifiNameText.value, + ); if (wifiName != null) { await saveWifiName(wifiName); @@ -83,7 +90,7 @@ class LocalNetworkPreference extends HookConsumerWidget { Future handleEditServerEndpoint() async { final localEndpoint = await _showEditDialog( context, - "server_endpoint".tr(), + context.t.server_endpoint, "http://local-ip:2283", localEndpointText.value, isUrlField: true, @@ -104,7 +111,7 @@ class LocalNetworkPreference extends HookConsumerWidget { context.showSnackBar( SnackBar( content: Text( - "get_wifiname_error".tr(), + context.t.get_wifiname_error, style: context.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w500, color: context.colorScheme.onSecondary, @@ -149,7 +156,7 @@ class LocalNetworkPreference extends HookConsumerWidget { children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 24), - child: Text("local_network_sheet_info".tr(), style: context.textTheme.bodyMedium), + child: Text(context.t.local_network_sheet_info, style: context.textTheme.bodyMedium), ), const SizedBox(height: 4), Divider(color: context.colorScheme.surfaceContainerHighest), @@ -157,9 +164,9 @@ class LocalNetworkPreference extends HookConsumerWidget { enabled: enabled, contentPadding: const EdgeInsets.only(left: 24, right: 8), leading: const Icon(Icons.wifi_rounded), - title: Text("wifi_name".tr()), + title: Text(context.t.wifi_name), subtitle: wifiNameText.value.isEmpty - ? Text("enter_wifi_name".tr()) + ? Text(context.t.enter_wifi_name) : Text( wifiNameText.value, style: context.textTheme.labelLarge?.copyWith( @@ -177,7 +184,7 @@ class LocalNetworkPreference extends HookConsumerWidget { enabled: enabled, contentPadding: const EdgeInsets.only(left: 24, right: 8), leading: const Icon(Icons.lan_rounded), - title: Text("server_endpoint".t(context: context)), + title: Text(context.t.server_endpoint), subtitle: localEndpointText.value.isEmpty ? const Text("http://local-ip:2283") : Text( @@ -199,7 +206,7 @@ class LocalNetworkPreference extends HookConsumerWidget { height: 48, child: OutlinedButton.icon( icon: const Icon(Icons.wifi_find_rounded), - label: Text('use_current_connection'.t(context: context)), + label: Text(context.t.use_current_connection), onPressed: enabled ? autofillCurrentNetwork : null, ), ), diff --git a/mobile/lib/widgets/settings/networking_settings/networking_settings.dart b/mobile/lib/widgets/settings/networking_settings/networking_settings.dart index dad827230a..581bae4324 100644 --- a/mobile/lib/widgets/settings/networking_settings/networking_settings.dart +++ b/mobile/lib/widgets/settings/networking_settings/networking_settings.dart @@ -1,11 +1,10 @@ import 'dart:async'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; -import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart'; import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/network.provider.dart'; @@ -39,8 +38,8 @@ class NetworkingSettings extends HookConsumerWidget { context: context, builder: (context) { return AlertDialog( - title: Text("location_permission".tr()), - content: Text("location_permission_content".tr()), + title: Text(context.t.location_permission), + content: Text(context.t.location_permission_content), actions: [ TextButton( onPressed: () async { @@ -52,7 +51,7 @@ class NetworkingSettings extends HookConsumerWidget { Navigator.pop(context, isGrant); }, - child: Text("grant_permission".tr()), + child: Text(context.t.grant_permission), ), ], ); @@ -69,8 +68,8 @@ class NetworkingSettings extends HookConsumerWidget { context: context, builder: (context) { return AlertDialog( - title: Text("background_location_permission".tr()), - content: Text("background_location_permission_content".tr()), + title: Text(context.t.background_location_permission), + content: Text(context.t.background_location_permission_content), actions: [ TextButton( onPressed: () async { @@ -82,7 +81,7 @@ class NetworkingSettings extends HookConsumerWidget { Navigator.pop(context, isGrant); }, - child: Text("grant_permission".tr()), + child: Text(context.t.grant_permission), ), ], ); @@ -107,7 +106,7 @@ class NetworkingSettings extends HookConsumerWidget { children: [ const SizedBox(height: 8), SettingGroupTitle( - title: "current_server_address".t(context: context), + title: context.t.current_server_address, icon: (currentEndpoint?.startsWith('https') ?? false) ? Icons.https_outlined : Icons.http_outlined, ), Padding( @@ -136,20 +135,14 @@ class NetworkingSettings extends HookConsumerWidget { SettingsSwitchListTile( enabled: true, valueNotifier: featureEnabled, - title: "automatic_endpoint_switching_title".tr(), - subtitle: "automatic_endpoint_switching_subtitle".tr(), + title: context.t.automatic_endpoint_switching_title, + subtitle: context.t.automatic_endpoint_switching_subtitle, ), const SizedBox(height: 8), - SettingGroupTitle( - title: "local_network".t(context: context), - icon: Icons.home_outlined, - ), + SettingGroupTitle(title: context.t.local_network, icon: Icons.home_outlined), LocalNetworkPreference(enabled: featureEnabled.value), const SizedBox(height: 16), - SettingGroupTitle( - title: "external_network".t(context: context), - icon: Icons.dns_outlined, - ), + SettingGroupTitle(title: context.t.external_network, icon: Icons.dns_outlined), ExternalNetworkPreference(enabled: featureEnabled.value), ], ); diff --git a/mobile/lib/widgets/settings/ssl_client_cert_settings.dart b/mobile/lib/widgets/settings/ssl_client_cert_settings.dart index 77ad7ee179..f37aa04b33 100644 --- a/mobile/lib/widgets/settings/ssl_client_cert_settings.dart +++ b/mobile/lib/widgets/settings/ssl_client_cert_settings.dart @@ -1,10 +1,10 @@ import 'dart:async'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; +import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/platform/network_api.g.dart'; import 'package:immich_mobile/providers/infrastructure/platform.provider.dart'; import 'package:logging/logging.dart'; @@ -44,12 +44,15 @@ class _SslClientCertSettingsState extends State { contentPadding: const EdgeInsets.symmetric(horizontal: 20), horizontalTitleGap: 20, isThreeLine: true, - title: Text("client_cert_title".tr(), style: context.textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w500)), + title: Text( + context.t.client_cert_title, + style: context.textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w500), + ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "client_cert_subtitle".tr(), + context.t.client_cert_subtitle, style: context.textTheme.bodyMedium?.copyWith(color: context.colorScheme.onSurfaceSecondary), ), const SizedBox(height: 6), @@ -58,8 +61,8 @@ class _SslClientCertSettingsState extends State { mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, children: [ - ElevatedButton(onPressed: importCert, child: Text("client_cert_import".tr())), - ElevatedButton(onPressed: !isCertExist ? null : removeCert, child: Text("remove".tr())), + ElevatedButton(onPressed: importCert, child: Text(context.t.client_cert_import)), + ElevatedButton(onPressed: !isCertExist ? null : removeCert, child: Text(context.t.remove)), ], ), ], @@ -79,20 +82,20 @@ class _SslClientCertSettingsState extends State { Future importCert() async { try { final styling = ClientCertPrompt( - title: "client_cert_password_title".tr(), - message: "client_cert_password_message".tr(), - cancel: "cancel".tr(), - confirm: "confirm".tr(), + title: context.t.client_cert_password_title, + message: context.t.client_cert_password_message, + cancel: context.t.cancel, + confirm: context.t.confirm, ); await networkApi.selectCertificate(styling); setState(() => isCertExist = true); - showMessage("client_cert_import_success_msg".tr()); + showMessage(StaticTranslations.instance.client_cert_import_success_msg); } catch (e) { if (_isCancellation(e)) { return; } _log.severe("Error importing client cert", e); - showMessage("client_cert_invalid_msg".tr()); + showMessage(StaticTranslations.instance.client_cert_invalid_msg); } } @@ -100,13 +103,13 @@ class _SslClientCertSettingsState extends State { try { await networkApi.removeCertificate(); setState(() => isCertExist = false); - showMessage("client_cert_remove_msg".tr()); + showMessage(StaticTranslations.instance.client_cert_remove_msg); } catch (e) { if (_isCancellation(e)) { return; } _log.severe("Error removing client cert", e); - showMessage("client_cert_invalid_msg".tr()); + showMessage(StaticTranslations.instance.client_cert_invalid_msg); } }