chore: migrate mobile translations accessor (3) (#30670)

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
shenlong 2026-08-11 14:41:12 +05:30 committed by GitHub
parent 835c35e940
commit d799698c51
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 227 additions and 263 deletions

View file

@ -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/domain/models/album/local_album.model.dart';
@ -10,7 +9,6 @@ import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/platform_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/backup/backup_toggle_button.widget.dart';
import 'package:immich_mobile/providers/background_sync.provider.dart';
@ -108,7 +106,7 @@ class _DriftBackupPageState extends ConsumerState<DriftBackupPage> {
return Scaffold(
appBar: AppBar(
elevation: 0,
title: Text("backup_controller_page_backup".t()),
title: Text(context.t.backup_controller_page_backup),
leading: IconButton(
onPressed: () {
unawaited(context.maybePop(true));
@ -122,7 +120,7 @@ class _DriftBackupPageState extends ConsumerState<DriftBackupPage> {
unawaited(context.pushRoute(const DriftBackupOptionsRoute()));
},
icon: const Icon(Icons.settings_outlined),
tooltip: "backup_options".t(context: context),
tooltip: context.t.backup_options,
),
],
),
@ -319,7 +317,7 @@ class _BackupAlbumSelectionCard extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
Widget buildSelectedAlbumName() {
String text = "backup_controller_page_backup_selected".tr();
String text = context.t.backup_controller_page_backup_selected;
final albums = ref
.read(backupAlbumProvider)
.where((album) => album.backupSelection == BackupSelection.selected)
@ -328,7 +326,7 @@ class _BackupAlbumSelectionCard extends ConsumerWidget {
if (albums.isNotEmpty) {
for (var album in albums) {
if (album.name == "Recent" || album.name == "Recents") {
text += "${album.name} (${'all'.tr()}), ";
text += "${album.name} (${context.t.all}), ";
} else {
text += "${album.name}, ";
}
@ -345,7 +343,7 @@ class _BackupAlbumSelectionCard extends ConsumerWidget {
return Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
"backup_controller_page_none_selected".tr(),
context.t.backup_controller_page_none_selected,
style: context.textTheme.labelLarge?.copyWith(color: context.primaryColor),
),
);
@ -353,7 +351,7 @@ class _BackupAlbumSelectionCard extends ConsumerWidget {
}
Widget buildExcludedAlbumName() {
String text = "backup_controller_page_excluded".tr();
String text = context.t.backup_controller_page_excluded;
final albums = ref
.read(backupAlbumProvider)
.where((album) => album.backupSelection == BackupSelection.excluded)
@ -385,16 +383,16 @@ class _BackupAlbumSelectionCard extends ConsumerWidget {
borderOnForeground: false,
child: ListTile(
minVerticalPadding: 18,
title: Text("backup_controller_page_albums", style: context.textTheme.titleMedium).tr(),
title: Text(context.t.backup_controller_page_albums, style: context.textTheme.titleMedium),
subtitle: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"backup_controller_page_to_backup",
context.t.backup_controller_page_to_backup,
style: context.textTheme.bodyMedium?.copyWith(color: context.colorScheme.onSurfaceSecondary),
).tr(),
),
buildSelectedAlbumName(),
buildExcludedAlbumName(),
],
@ -413,7 +411,7 @@ class _BackupAlbumSelectionCard extends ConsumerWidget {
}
unawaited(ref.read(driftBackupProvider.notifier).getBackupStatus(currentUser.id));
},
child: const Text("select", style: TextStyle(fontWeight: FontWeight.bold)).tr(),
child: Text(context.t.select, style: const TextStyle(fontWeight: FontWeight.bold)),
),
),
);
@ -428,8 +426,8 @@ class _TotalCard extends ConsumerWidget {
final totalCount = ref.watch(driftBackupProvider.select((p) => p.totalCount));
return BackupInfoCard(
title: "total".tr(),
subtitle: "backup_controller_page_total_sub".tr(),
title: context.t.total,
subtitle: context.t.backup_controller_page_total_sub,
info: totalCount.toString(),
);
}
@ -444,8 +442,8 @@ class _BackupCard extends ConsumerWidget {
final syncStatus = ref.watch(syncStatusProvider);
return BackupInfoCard(
title: "backup_controller_page_backup".tr(),
subtitle: "backup_controller_page_backup_sub".tr(),
title: context.t.backup_controller_page_backup,
subtitle: context.t.backup_controller_page_backup_sub,
info: backupCount.toString(),
isLoading: syncStatus.isRemoteSyncing,
);
@ -472,11 +470,11 @@ class _RemainderCard extends ConsumerWidget {
ListTile(
minVerticalPadding: 18,
isThreeLine: true,
title: Text("backup_controller_page_remainder".t(context: context), style: context.textTheme.titleMedium),
title: Text(context.t.backup_controller_page_remainder, style: context.textTheme.titleMedium),
subtitle: Padding(
padding: const EdgeInsets.only(top: 4.0, right: 18.0),
child: Text(
"backup_controller_page_remainder_sub".t(context: context),
context.t.backup_controller_page_remainder_sub,
style: context.textTheme.bodyMedium?.copyWith(color: context.colorScheme.onSurfaceSecondary),
),
),
@ -509,11 +507,11 @@ class _RemainderCard extends ConsumerWidget {
],
),
Text(
"backup_info_card_assets",
context.t.backup_info_card_assets,
style: context.textTheme.labelLarge?.copyWith(
color: context.colorScheme.onSurface.withAlpha(syncStatus.isRemoteSyncing ? 50 : 255),
),
).tr(),
),
],
),
),
@ -530,7 +528,7 @@ class _RemainderCard extends ConsumerWidget {
),
onTap: () => context.pushRoute(const DriftBackupAssetDetailRoute()),
title: Text(
"view_details".t(context: context),
context.t.view_details,
style: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurface.withAlpha(200)),
),
trailing: Icon(Icons.arrow_forward_ios, size: 16, color: context.colorScheme.onSurfaceVariant),
@ -622,7 +620,7 @@ class _PreparingStatusState extends ConsumerState {
Row(
children: [
Text(
"preparing".t(context: context),
context.t.preparing,
style: context.textTheme.labelLarge?.copyWith(
color: context.colorScheme.onSurface.withAlpha(200),
),
@ -652,7 +650,7 @@ class _PreparingStatusState extends ConsumerState {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"ready_for_upload".t(context: context),
context.t.ready_for_upload,
style: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurface.withAlpha(200)),
),
const SizedBox(height: 2),

View file

@ -1,13 +1,12 @@
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/domain/models/album/local_album.model.dart';
import 'package:immich_mobile/domain/services/sync_linked_album.service.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/infrastructure/repositories/settings.repository.dart';
import 'package:immich_mobile/providers/background_sync.provider.dart';
import 'package:immich_mobile/providers/backup/backup_album.provider.dart';
@ -154,13 +153,13 @@ class _DriftBackupAlbumSelectionPageState extends ConsumerState<DriftBackupAlbum
),
title: _isSearchMode
? SearchField(
hintText: 'search_albums'.t(context: context),
hintText: context.t.search_albums,
autofocus: true,
controller: _searchController,
focusNode: _searchFocusNode,
onChanged: (value) => setState(() => _searchQuery = value.trim()),
)
: const Text("backup_album_selection_page_select_albums").t(context: context),
: Text(context.t.backup_album_selection_page_select_albums),
actions: [
if (!_isSearchMode)
IconButton(
@ -194,9 +193,9 @@ class _DriftBackupAlbumSelectionPageState extends ConsumerState<DriftBackupAlbum
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Text(
"backup_album_selection_page_selection_info",
context.t.backup_album_selection_page_selection_info,
style: context.textTheme.titleSmall,
).t(context: context),
),
),
// Selected Album Chips
@ -211,15 +210,15 @@ class _DriftBackupAlbumSelectionPageState extends ConsumerState<DriftBackupAlbum
),
ListTile(
title: Text(
"albums_on_device_count".t(context: context, args: {'count': albumCount.toString()}),
context.t.albums_on_device_count(count: albumCount),
style: context.textTheme.titleSmall,
),
subtitle: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
"backup_album_selection_page_albums_tap",
context.t.backup_album_selection_page_albums_tap,
style: context.textTheme.labelLarge?.copyWith(color: context.primaryColor),
).t(context: context),
),
),
trailing: IconButton(
splashRadius: 16,
@ -235,20 +234,20 @@ class _DriftBackupAlbumSelectionPageState extends ConsumerState<DriftBackupAlbum
),
elevation: 5,
title: Text(
'backup_album_selection_page_selection_info',
context.t.backup_album_selection_page_selection_info,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: context.primaryColor,
),
).t(context: context),
),
content: SingleChildScrollView(
child: ListBody(
children: [
const Text(
'backup_album_selection_page_assets_scatter',
style: TextStyle(fontSize: 14),
).t(context: context),
Text(
context.t.backup_album_selection_page_assets_scatter,
style: const TextStyle(fontSize: 14),
),
],
),
),
@ -268,16 +267,10 @@ class _DriftBackupAlbumSelectionPageState extends ConsumerState<DriftBackupAlbum
SliverToBoxAdapter(
child: Center(
child: _searchQuery.isNotEmpty
? Padding(
padding: const EdgeInsets.all(24.0),
child: Text('album_search_not_found'.t(context: context)),
)
? Padding(padding: const EdgeInsets.all(24.0), child: Text(context.t.album_search_not_found))
: isLoading
? const CircularProgressIndicator()
: Padding(
padding: const EdgeInsets.all(24.0),
child: Text('no_albums_found'.t(context: context)),
),
: Padding(padding: const EdgeInsets.all(24.0), child: Text(context.t.no_albums_found)),
),
)
else
@ -309,7 +302,7 @@ class _DriftBackupAlbumSelectionPageState extends ConsumerState<DriftBackupAlbum
mainAxisSize: MainAxisSize.max,
children: [
const CircularProgressIndicator(strokeWidth: 4),
Text('creating_linked_albums'.tr(), style: context.textTheme.labelLarge),
Text(context.t.creating_linked_albums, style: context.textTheme.labelLarge),
],
),
),
@ -476,10 +469,7 @@ class _SelectAllButton extends ConsumerWidget {
}
: null,
icon: const Icon(Icons.select_all),
label: AnimatedSwitcher(
duration: const Duration(milliseconds: 200),
child: Text("select_all".t(context: context)),
),
label: AnimatedSwitcher(duration: const Duration(milliseconds: 200), child: Text(context.t.select_all)),
style: ElevatedButton.styleFrom(padding: const EdgeInsets.symmetric(vertical: 12.0)),
),
),
@ -496,7 +486,7 @@ class _SelectAllButton extends ConsumerWidget {
}
: null,
icon: const Icon(Icons.deselect),
label: Text('deselect_all'.t(context: context)),
label: Text(context.t.deselect_all),
style: OutlinedButton.styleFrom(padding: const EdgeInsets.symmetric(vertical: 12.0)),
),
),

View file

@ -1,5 +1,4 @@
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/domain/models/asset/base_asset.model.dart';
@ -7,7 +6,7 @@ import 'package:immich_mobile/domain/models/events.model.dart';
import 'package:immich_mobile/domain/utils/event_stream.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/pages/common/large_leading_tile.dart';
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
import 'package:immich_mobile/providers/backup/drift_backup.provider.dart';
@ -22,7 +21,7 @@ class DriftBackupAssetDetailPage extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final AsyncValue<List<LocalAsset>> result = ref.watch(driftBackupCandidateProvider);
return Scaffold(
appBar: AppBar(title: Text('backup_controller_page_remainder'.t(context: context))),
appBar: AppBar(title: Text(context.t.backup_controller_page_remainder)),
body: result.when(
data: (List<LocalAsset> candidates) {
return ListView.separated(
@ -66,7 +65,7 @@ class DriftBackupAssetDetailPage extends ConsumerWidget {
);
},
error: (error, stackTrace) => Text(
'error_saving_image'.tr(args: [error.toString()]),
context.t.error_saving_image(error: error.toString()),
style: TextStyle(color: context.colorScheme.error),
),
loading: () =>
@ -102,7 +101,7 @@ class DriftBackupAssetDetailPage extends ConsumerWidget {
);
},
error: (Object error, StackTrace stackTrace) {
return Center(child: Text('error_saving_image'.tr(args: [error.toString()])));
return Center(child: Text(context.t.error_saving_image(error: error.toString())));
},
loading: () {
return const SizedBox(height: 48, width: 48, child: Center(child: CircularProgressIndicator.adaptive()));

View file

@ -3,7 +3,7 @@ import 'dart:async';
import 'package:auto_route/auto_route.dart';
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/infrastructure/repositories/settings.repository.dart';
import 'package:immich_mobile/providers/background_sync.provider.dart';
import 'package:immich_mobile/providers/backup/drift_backup.provider.dart';
@ -51,10 +51,7 @@ class DriftBackupOptionsPage extends ConsumerWidget {
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("network_requirements_updated".t(context: context)),
duration: const Duration(seconds: 4),
),
SnackBar(content: Text(context.t.network_requirements_updated), duration: const Duration(seconds: 4)),
);
final backupNotifier = ref.read(driftBackupProvider.notifier);
@ -72,7 +69,7 @@ class DriftBackupOptionsPage extends ConsumerWidget {
}
},
child: Scaffold(
appBar: AppBar(title: Text("backup_options".t(context: context))),
appBar: AppBar(title: Text(context.t.backup_options)),
body: const DriftBackupSettings(),
),
);

View file

@ -3,7 +3,7 @@ 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/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/widgets/images/thumbnail.widget.dart';
import 'package:immich_mobile/providers/backup/drift_backup.provider.dart';
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
@ -80,7 +80,7 @@ class _DriftUploadDetailPageState extends ConsumerState<DriftUploadDetailPage> {
return Scaffold(
appBar: AppBar(
title: Text("upload_details".t(context: context)),
title: Text(context.t.upload_details),
backgroundColor: context.colorScheme.surface,
elevation: 0,
scrolledUnderElevation: 1,
@ -125,7 +125,7 @@ class _DriftUploadDetailPageState extends ConsumerState<DriftUploadDetailPage> {
SliverToBoxAdapter(
child: _buildSectionHeader(
context,
title: "uploading".t(context: context),
title: context.t.uploading,
count: uploadingItems.length,
color: context.colorScheme.primary,
),
@ -151,7 +151,7 @@ class _DriftUploadDetailPageState extends ConsumerState<DriftUploadDetailPage> {
SliverToBoxAdapter(
child: _buildSectionHeader(
context,
title: "errors_text".t(context: context),
title: context.t.errors_text,
count: failedItems.length,
color: context.colorScheme.error,
),
@ -231,7 +231,7 @@ class _DriftUploadDetailPageState extends ConsumerState<DriftUploadDetailPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"downloading_from_icloud".t(context: context),
context.t.downloading_from_icloud,
style: context.textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w500),
maxLines: 1,
overflow: TextOverflow.ellipsis,
@ -318,7 +318,7 @@ class _DriftUploadDetailPageState extends ConsumerState<DriftUploadDetailPage> {
const SizedBox(height: 2),
Text(
isFailed
? item.error ?? "unable_to_upload_file".t(context: context)
? item.error ?? context.t.errors.unable_to_upload_file
: "${formatHumanReadableBytes(item.fileSize, 1)}${item.networkSpeedAsString}",
style: context.textTheme.labelLarge?.copyWith(
color: isFailed
@ -395,7 +395,7 @@ class _DriftUploadDetailPageState extends ConsumerState<DriftUploadDetailPage> {
),
const SizedBox(height: 4),
Text(
item.error ?? "unable_to_upload_file".t(context: context),
item.error ?? context.t.errors.unable_to_upload_file,
style: context.textTheme.bodySmall?.copyWith(color: context.colorScheme.error),
maxLines: 4,
overflow: TextOverflow.ellipsis,
@ -556,7 +556,7 @@ class FileDetailDialog extends ConsumerWidget {
const SizedBox(width: 8),
Expanded(
child: Text(
"details".t(context: context),
context.t.details,
style: context.textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w600, color: context.primaryColor),
),
),
@ -595,20 +595,14 @@ class FileDetailDialog extends ConsumerWidget {
const SizedBox(height: 24),
if (asset != null)
_buildInfoSection(context, [
_buildInfoRow(context, "filename".t(context: context), path.basename(uploadStatus.filename)),
_buildInfoRow(context, "local_id".t(context: context), asset.id),
_buildInfoRow(
context,
"file_size".t(context: context),
formatHumanReadableBytes(uploadStatus.fileSize, 2),
),
if (asset.width != null) _buildInfoRow(context, "width".t(context: context), "${asset.width}px"),
if (asset.height != null)
_buildInfoRow(context, "height".t(context: context), "${asset.height}px"),
_buildInfoRow(context, "created_at".t(context: context), asset.createdAt.toString()),
_buildInfoRow(context, "updated_at".t(context: context), asset.updatedAt.toString()),
if (asset.checksum != null)
_buildInfoRow(context, "checksum".t(context: context), asset.checksum!),
_buildInfoRow(context, context.t.filename, path.basename(uploadStatus.filename)),
_buildInfoRow(context, context.t.local_id, asset.id),
_buildInfoRow(context, context.t.file_size, formatHumanReadableBytes(uploadStatus.fileSize, 2)),
if (asset.width != null) _buildInfoRow(context, context.t.width, "${asset.width}px"),
if (asset.height != null) _buildInfoRow(context, context.t.height, "${asset.height}px"),
_buildInfoRow(context, context.t.created_at, asset.createdAt.toString()),
_buildInfoRow(context, context.t.updated_at, asset.updatedAt.toString()),
if (asset.checksum != null) _buildInfoRow(context, context.t.checksum, asset.checksum!),
]),
],
),
@ -620,7 +614,7 @@ class FileDetailDialog extends ConsumerWidget {
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(
"close".t(),
context.t.close,
style: TextStyle(fontWeight: FontWeight.w600, color: context.primaryColor),
),
),

View file

@ -1,5 +1,4 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
import 'package:immich_mobile/extensions/build_context_extensions.dart';
@ -18,21 +17,45 @@ import 'package:immich_mobile/widgets/settings/preference_settings/preference_se
import 'package:immich_mobile/widgets/settings/settings_card.dart';
enum SettingSection {
advanced('advanced', Icons.build_outlined, "advanced_settings_tile_subtitle"),
assetViewer('asset_viewer_settings_title', Icons.image_outlined, "asset_viewer_settings_subtitle"),
backup('backup', Icons.cloud_upload_outlined, "backup_settings_subtitle"),
freeUpSpace('free_up_space', Icons.cleaning_services_outlined, "free_up_space_settings_subtitle"),
languages('language', Icons.language, "setting_languages_subtitle"),
networking('networking_settings', Icons.wifi, "networking_subtitle"),
notifications('notifications', Icons.notifications_none_rounded, "setting_notifications_subtitle"),
preferences('preferences_settings_title', Icons.interests_outlined, "preferences_settings_subtitle"),
timeline('asset_list_settings_title', Icons.auto_awesome_mosaic_outlined, "asset_list_settings_subtitle"),
beta('sync_status', Icons.sync_outlined, "sync_status_subtitle");
advanced(Icons.build_outlined),
assetViewer(Icons.image_outlined),
backup(Icons.cloud_upload_outlined),
freeUpSpace(Icons.cleaning_services_outlined),
languages(Icons.language),
networking(Icons.wifi),
notifications(Icons.notifications_none_rounded),
preferences(Icons.interests_outlined),
timeline(Icons.auto_awesome_mosaic_outlined),
beta(Icons.sync_outlined);
final String title;
final String subtitle;
final IconData icon;
String title(Translations t) => switch (this) {
SettingSection.advanced => t.advanced,
SettingSection.assetViewer => t.asset_viewer_settings_title,
SettingSection.backup => t.backup,
SettingSection.freeUpSpace => t.free_up_space,
SettingSection.languages => t.language,
SettingSection.networking => t.networking_settings,
SettingSection.notifications => t.notifications,
SettingSection.preferences => t.preferences_settings_title,
SettingSection.timeline => t.asset_list_settings_title,
SettingSection.beta => t.sync_status,
};
String subtitle(Translations t) => switch (this) {
SettingSection.advanced => t.advanced_settings_tile_subtitle,
SettingSection.assetViewer => t.asset_viewer_settings_subtitle,
SettingSection.backup => t.backup_settings_subtitle,
SettingSection.freeUpSpace => t.free_up_space_settings_subtitle,
SettingSection.languages => t.setting_languages_subtitle,
SettingSection.networking => t.networking_subtitle,
SettingSection.notifications => t.setting_notifications_subtitle,
SettingSection.preferences => t.preferences_settings_subtitle,
SettingSection.timeline => t.asset_list_settings_subtitle,
SettingSection.beta => t.sync_status_subtitle,
};
Widget get widget => switch (this) {
SettingSection.advanced => const AdvancedSettings(),
SettingSection.assetViewer => const AssetViewerSettings(),
@ -46,7 +69,7 @@ enum SettingSection {
SettingSection.beta => const SyncStatusAndActions(),
};
const SettingSection(this.title, this.icon, this.subtitle);
const SettingSection(this.icon);
}
@RoutePage()
@ -55,9 +78,8 @@ class SettingsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
context.locale;
return Scaffold(
appBar: AppBar(centerTitle: false, title: const Text('settings').tr()),
appBar: AppBar(centerTitle: false, title: Text(context.t.settings)),
body: context.isMobile ? const _MobileLayout() : const _TabletLayout(),
);
}
@ -73,15 +95,15 @@ class _MobileLayout extends StatelessWidget {
? [
SettingsCard(
icon: Icons.sync_outlined,
title: 'sync_status'.tr(),
subtitle: 'sync_status_subtitle'.tr(),
title: context.t.sync_status,
subtitle: context.t.sync_status_subtitle,
settingRoute: const SyncStatusRoute(),
),
]
: [
SettingsCard(
title: setting.title.tr(),
subtitle: setting.subtitle.tr(),
title: setting.title(context.t),
subtitle: setting.subtitle(context.t),
icon: setting.icon,
settingRoute: SettingsSubRoute(section: setting),
),
@ -116,7 +138,7 @@ class _TabletLayout extends HookWidget {
...SettingSection.values.map(
(s) => SliverToBoxAdapter(
child: ListTile(
title: Text(s.title).tr(),
title: Text(s.title(context.t)),
leading: Icon(s.icon),
selected: s.index == selectedSection.value.index,
selectedColor: context.primaryColor,
@ -127,7 +149,7 @@ class _TabletLayout extends HookWidget {
),
SliverToBoxAdapter(
child: ListTile(
title: Text('whats_new'.tr()),
title: Text(context.t.whats_new),
leading: const Icon(Icons.auto_awesome_outlined),
onTap: () => context.pushRoute(const WhatsNewRoute()),
),
@ -150,9 +172,8 @@ class SettingsSubPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
context.locale;
return Scaffold(
appBar: AppBar(centerTitle: false, title: Text(section.title).tr()),
appBar: AppBar(centerTitle: false, title: Text(section.title(context.t))),
body: section.widget,
);
}

View file

@ -2,12 +2,12 @@ import 'dart:async';
import 'dart:math';
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/maplibrecontroller_extensions.dart';
import 'package:immich_mobile/generated/translations.g.dart';
import 'package:immich_mobile/utils/map_utils.dart';
import 'package:immich_mobile/widgets/map/map_theme_override.dart';
import 'package:maplibre_gl/maplibre_gl.dart';
@ -148,10 +148,7 @@ class _BottomBar extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: onUseLocation,
child: const Text("map_location_picker_page_use_location").tr(),
),
ElevatedButton(onPressed: onUseLocation, child: Text(context.t.map_location_picker_page_use_location)),
ElevatedButton(onPressed: onGetCurrentLocation, child: const Icon(Icons.my_location)),
],
),

View file

@ -1,6 +1,6 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/translate_extensions.dart';
import 'package:immich_mobile/generated/translations.g.dart';
import 'package:immich_mobile/widgets/settings/beta_sync_settings/sync_status_and_actions.dart';
@RoutePage()
@ -12,7 +12,7 @@ class SyncStatusPage extends StatelessWidget {
return Scaffold(
appBar: AppBar(
elevation: 0,
title: const Text("sync_status").t(context: context),
title: Text(context.t.sync_status),
leading: IconButton(
onPressed: () => context.maybePop(true),
splashRadius: 24,

View file

@ -1,7 +1,7 @@
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/translate_extensions.dart';
import 'package:immich_mobile/generated/translations.g.dart';
import 'package:immich_mobile/providers/backup/drift_backup.provider.dart';
import 'package:immich_mobile/providers/infrastructure/settings.provider.dart';
@ -135,7 +135,7 @@ class BackupToggleButtonState extends ConsumerState<BackupToggleButton> with Sin
children: [
Flexible(
child: Text(
"enable_backup".t(context: context),
context.t.enable_backup,
style: context.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
color: context.primaryColor,
@ -148,7 +148,7 @@ class BackupToggleButtonState extends ConsumerState<BackupToggleButton> with Sin
Padding(
padding: const EdgeInsets.only(top: 2),
child: Text(
"upload_error_with_count".t(context: context, args: {'count': '$errorCount'}),
context.t.upload_error_with_count(count: errorCount),
style: context.textTheme.labelMedium?.copyWith(color: context.colorScheme.error),
),
),

View file

@ -10,7 +10,7 @@ import 'package:immich_mobile/domain/models/events.model.dart';
import 'package:immich_mobile/domain/utils/event_stream.dart';
import 'package:immich_mobile/extensions/asyncvalue_extensions.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/widgets/bottom_sheet/base_bottom_sheet.widget.dart';
import 'package:immich_mobile/presentation/widgets/bottom_sheet/map_bottom_sheet.widget.dart';
import 'package:immich_mobile/presentation/widgets/map/map.state.dart';
@ -164,7 +164,7 @@ class _DriftMapState extends ConsumerState<DriftMap> {
context: context,
gravity: ToastGravity.BOTTOM,
toastType: ToastType.error,
msg: "map_cannot_get_user_location".t(context: context),
msg: context.t.map_cannot_get_user_location,
);
}
return;

View file

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/domain/models/time_range.model.dart';
import 'package:immich_mobile/extensions/translate_extensions.dart';
import 'package:immich_mobile/generated/translations.g.dart';
import 'package:immich_mobile/presentation/widgets/map/map.state.dart';
import 'package:immich_mobile/widgets/map/map_settings/map_custom_time_range.dart';
@ -50,18 +49,18 @@ class _DriftMapSettingsSheetState extends ConsumerState<DriftMapSettingsSheet> {
),
const Divider(height: 30, thickness: 1),
MapSettingsListTile(
title: "map_settings_only_show_favorites".t(context: context),
title: context.t.map_settings_only_show_favorites,
selected: mapState.onlyFavorites,
onChanged: (favoriteOnly) => ref.read(mapStateProvider.notifier).switchFavoriteOnly(favoriteOnly),
),
MapSettingsListTile(
title: "map_settings_include_show_archived".t(context: context),
title: context.t.map_settings_include_show_archived,
selected: mapState.includeArchived,
onChanged: (includeArchive) =>
ref.read(mapStateProvider.notifier).switchIncludeArchived(includeArchive),
),
MapSettingsListTile(
title: "map_settings_include_show_partners".t(context: context),
title: context.t.map_settings_include_show_partners,
selected: mapState.withPartners,
onChanged: (withPartners) => ref.read(mapStateProvider.notifier).switchWithPartners(withPartners),
),

View file

@ -2,7 +2,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:immich_mobile/extensions/translate_extensions.dart';
import 'package:immich_mobile/generated/translations.g.dart';
import 'package:immich_mobile/widgets/common/confirm_dialog.dart';
import 'package:logging/logging.dart';
import 'package:maplibre_gl/maplibre_gl.dart';
@ -124,10 +124,10 @@ class MapUtils {
class _LocationServiceDisabledDialog extends ConfirmDialog {
_LocationServiceDisabledDialog(BuildContext context)
: super(
title: 'map_location_service_disabled_title'.t(context: context),
content: 'map_location_service_disabled_content'.t(context: context),
cancel: 'cancel'.t(context: context),
ok: 'yes'.t(context: context),
title: context.t.map_location_service_disabled_title,
content: context.t.map_location_service_disabled_content,
cancel: context.t.cancel,
ok: context.t.yes,
onOk: () async {
await Geolocator.openLocationSettings();
},
@ -137,10 +137,10 @@ class _LocationServiceDisabledDialog extends ConfirmDialog {
class _LocationPermissionDisabledDialog extends ConfirmDialog {
_LocationPermissionDisabledDialog(BuildContext context)
: super(
title: 'map_no_location_permission_title'.t(context: context),
content: 'map_no_location_permission_content'.t(context: context),
cancel: 'cancel'.t(context: context),
ok: 'yes'.t(context: context),
title: context.t.map_no_location_permission_title,
content: context.t.map_no_location_permission_content,
cancel: context.t.cancel,
ok: context.t.yes,
onOk: () {},
);
}

View file

@ -1,8 +1,8 @@
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:immich_mobile/generated/translations.g.dart';
import 'package:immich_mobile/models/map/map_marker.model.dart';
import 'package:immich_mobile/widgets/common/confirm_dialog.dart';
import 'package:logging/logging.dart';
@ -121,10 +121,10 @@ class MapUtils {
class _LocationServiceDisabledDialog extends ConfirmDialog {
_LocationServiceDisabledDialog()
: super(
title: 'map_location_service_disabled_title'.tr(),
content: 'map_location_service_disabled_content'.tr(),
cancel: 'cancel'.tr(),
ok: 'yes'.tr(),
title: StaticTranslations.instance.map_location_service_disabled_title,
content: StaticTranslations.instance.map_location_service_disabled_content,
cancel: StaticTranslations.instance.cancel,
ok: StaticTranslations.instance.yes,
onOk: () async {
await Geolocator.openLocationSettings();
},
@ -134,10 +134,10 @@ class _LocationServiceDisabledDialog extends ConfirmDialog {
class _LocationPermissionDisabledDialog extends ConfirmDialog {
_LocationPermissionDisabledDialog()
: super(
title: 'map_no_location_permission_title'.tr(),
content: 'map_no_location_permission_content'.tr(),
cancel: 'cancel'.tr(),
ok: 'yes'.tr(),
title: StaticTranslations.instance.map_no_location_permission_title,
content: StaticTranslations.instance.map_no_location_permission_content,
cancel: StaticTranslations.instance.cancel,
ok: StaticTranslations.instance.yes,
onOk: () {},
);
}

View file

@ -1,8 +1,7 @@
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/extensions/theme_extensions.dart';
import 'package:immich_mobile/extensions/translate_extensions.dart';
import 'package:immich_mobile/generated/translations.g.dart';
class BackupInfoCard extends StatelessWidget {
final String title;
@ -73,11 +72,11 @@ class BackupInfoCard extends StatelessWidget {
],
),
Text(
"backup_info_card_assets",
context.t.backup_info_card_assets,
style: context.textTheme.labelLarge?.copyWith(
color: context.colorScheme.onSurface.withAlpha(isLoading ? 50 : 255),
),
).tr(),
),
],
),
),
@ -93,7 +92,7 @@ class BackupInfoCard extends StatelessWidget {
),
onTap: onTap,
title: Text(
"view_details".t(context: context),
context.t.view_details,
style: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurface.withAlpha(200)),
),
trailing: Icon(Icons.arrow_forward_ios, size: 16, color: context.colorScheme.onSurfaceVariant),

View file

@ -1,7 +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/extensions/translate_extensions.dart';
import 'package:immich_mobile/generated/translations.g.dart';
class MapTimeDropDown extends StatelessWidget {
final int relativeTime;
@ -20,7 +19,7 @@ class MapTimeDropDown extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"date_range".t(context: context),
context.t.date_range,
style: context.textTheme.bodyLarge!.copyWith(fontWeight: FontWeight.w500, height: 1.5),
),
Flexible(
@ -30,24 +29,21 @@ class MapTimeDropDown extends StatelessWidget {
initialSelection: relativeTime,
onSelected: (value) => onTimeChange(value!),
dropdownMenuEntries: [
DropdownMenuEntry(value: 0, label: "all".t(context: context)),
DropdownMenuEntry(value: 1, label: "map_settings_date_range_option_day".t(context: context)),
DropdownMenuEntry(value: 7, label: "map_settings_date_range_option_days".tr(namedArgs: {'days': "7"})),
DropdownMenuEntry(
value: 30,
label: "map_settings_date_range_option_days".tr(namedArgs: {'days': "30"}),
),
DropdownMenuEntry(value: 0, label: context.t.all),
DropdownMenuEntry(value: 1, label: context.t.map_settings_date_range_option_day),
DropdownMenuEntry(value: 7, label: context.t.map_settings_date_range_option_days(days: 7)),
DropdownMenuEntry(value: 30, label: context.t.map_settings_date_range_option_days(days: 30)),
DropdownMenuEntry(
value: now
.difference(DateTime(now.year - 1, now.month, now.day, now.hour, now.minute, now.second))
.inDays,
label: "map_settings_date_range_option_year".t(context: context),
label: context.t.map_settings_date_range_option_year,
),
DropdownMenuEntry(
value: now
.difference(DateTime(now.year - 3, now.month, now.day, now.hour, now.minute, now.second))
.inDays,
label: "map_settings_date_range_option_years".t(args: {'years': "3"}),
label: context.t.map_settings_date_range_option_years(years: 3),
),
],
),

View file

@ -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';
import 'package:immich_mobile/widgets/map/map_thumbnail.dart';
import 'package:maplibre_gl/maplibre_gl.dart';
@ -18,7 +18,7 @@ class MapThemePicker extends StatelessWidget {
padding: const EdgeInsets.only(bottom: 20),
child: Center(
child: Text(
"map_settings_theme_settings".t(context: context),
context.t.map_settings_theme_settings,
style: context.textTheme.bodyLarge!.copyWith(fontWeight: FontWeight.w500, height: 1.5),
),
),

View file

@ -2,12 +2,12 @@ import 'dart:async';
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/domain/services/log.service.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/generated/translations.g.dart';
import 'package:immich_mobile/providers/infrastructure/platform.provider.dart';
import 'package:immich_mobile/providers/infrastructure/readonly_mode.provider.dart';
import 'package:immich_mobile/providers/infrastructure/settings.provider.dart';
@ -71,8 +71,8 @@ class AdvancedSettings extends HookConsumerWidget {
SettingsSwitchListTile(
enabled: true,
valueNotifier: advancedTroubleshooting,
title: "advanced_settings_troubleshooting_title".tr(),
subtitle: "advanced_settings_troubleshooting_subtitle".tr(),
title: context.t.advanced_settings_troubleshooting_title,
subtitle: context.t.advanced_settings_troubleshooting_subtitle,
),
if (isManageMediaSupported.value)
Column(
@ -80,8 +80,8 @@ class AdvancedSettings extends HookConsumerWidget {
SettingsSwitchListTile(
enabled: true,
valueNotifier: manageLocalMediaAndroid,
title: "advanced_settings_sync_remote_deletions_title".tr(),
subtitle: "advanced_settings_sync_remote_deletions_subtitle".tr(),
title: context.t.advanced_settings_sync_remote_deletions_title,
subtitle: context.t.advanced_settings_sync_remote_deletions_subtitle,
onChanged: (value) async {
if (value) {
final result = await ref.read(permissionRepositoryProvider).requestManageMediaPermission();
@ -91,9 +91,9 @@ class AdvancedSettings extends HookConsumerWidget {
},
),
SettingsActionTile(
title: "manage_media_access_title".tr(),
statusText: manageMediaAndroidPermission.value ? "allowed".tr() : "not_allowed".tr(),
subtitle: "manage_media_access_rationale".tr(),
title: context.t.manage_media_access_title,
statusText: manageMediaAndroidPermission.value ? context.t.allowed : context.t.not_allowed,
subtitle: context.t.manage_media_access_rationale,
statusColor: manageLocalMediaAndroid.value && !manageMediaAndroidPermission.value
? const Color.fromARGB(255, 243, 188, 106)
: null,
@ -105,7 +105,7 @@ class AdvancedSettings extends HookConsumerWidget {
],
),
SettingsSliderListTile(
text: "advanced_settings_log_level_title".tr(namedArgs: {'level': logLevel}),
text: context.t.advanced_settings_log_level_title(level: logLevel),
valueNotifier: levelId,
maxValue: 8,
minValue: 1,
@ -114,15 +114,15 @@ class AdvancedSettings extends HookConsumerWidget {
),
SettingsSwitchListTile(
valueNotifier: preferRemote,
title: "advanced_settings_prefer_remote_title".tr(),
subtitle: "advanced_settings_prefer_remote_subtitle".tr(),
title: context.t.advanced_settings_prefer_remote_title,
subtitle: context.t.advanced_settings_prefer_remote_subtitle,
),
const CustomProxyHeaderSettings(),
const SslClientCertSettings(),
SettingsSwitchListTile(
valueNotifier: readonlyModeEnabled,
title: "advanced_settings_readonly_mode_title".tr(),
subtitle: "advanced_settings_readonly_mode_subtitle".tr(),
title: context.t.advanced_settings_readonly_mode_title,
subtitle: context.t.advanced_settings_readonly_mode_subtitle,
onChanged: (value) {
readonlyModeEnabled.value = value;
ref.read(readonlyModeProvider.notifier).setReadonlyMode(value);
@ -130,7 +130,7 @@ class AdvancedSettings extends HookConsumerWidget {
SnackBar(
duration: const Duration(seconds: 2),
content: Text(
(value ? "readonly_mode_enabled" : "readonly_mode_disabled").tr(),
value ? context.t.readonly_mode_enabled : context.t.readonly_mode_disabled,
style: context.textTheme.bodyLarge?.copyWith(color: context.primaryColor),
),
),
@ -138,7 +138,7 @@ class AdvancedSettings extends HookConsumerWidget {
},
),
ListTile(
title: Text("advanced_settings_clear_image_cache".tr(), style: const TextStyle(fontWeight: FontWeight.w500)),
title: Text(context.t.advanced_settings_clear_image_cache, style: const TextStyle(fontWeight: FontWeight.w500)),
leading: const Icon(Icons.playlist_remove_rounded),
onTap: () async {
final int clearedBytes;
@ -153,7 +153,7 @@ class AdvancedSettings extends HookConsumerWidget {
SnackBar(
duration: const Duration(seconds: 2),
content: Text(
"advanced_settings_clear_image_cache_error".tr(),
context.t.advanced_settings_clear_image_cache_error,
style: context.textTheme.bodyLarge?.copyWith(color: context.themeData.colorScheme.error),
),
),
@ -171,7 +171,7 @@ class AdvancedSettings extends HookConsumerWidget {
SnackBar(
duration: const Duration(seconds: 2),
content: Text(
"advanced_settings_clear_image_cache_success".tr(namedArgs: {'size': clearedMB}),
context.t.advanced_settings_clear_image_cache_success(size: clearedMB),
style: context.textTheme.bodyLarge?.copyWith(color: context.primaryColor),
),
),

View file

@ -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/domain/models/timeline.model.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/providers/infrastructure/timeline.provider.dart';
@ -34,20 +34,14 @@ class GroupSettings extends HookConsumerWidget {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SettingGroupTitle(
title: "asset_list_group_by_sub_title".t(context: context),
icon: Icons.group_work_outlined,
),
SettingGroupTitle(title: context.t.asset_list_group_by_sub_title, icon: Icons.group_work_outlined),
SettingsRadioListTile(
groups: [
SettingsRadioGroup(
title: 'asset_list_layout_settings_group_by_month_day'.t(context: context),
title: context.t.asset_list_layout_settings_group_by_month_day,
value: GroupAssetsBy.day,
),
SettingsRadioGroup(
title: 'month'.t(context: context),
value: GroupAssetsBy.month,
),
SettingsRadioGroup(title: context.t.month, value: GroupAssetsBy.month),
],
groupBy: groupBy.value,
onRadioChanged: changeGroupValue,

View file

@ -1,10 +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/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,13 +22,10 @@ class LayoutSettings extends HookConsumerWidget {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SettingGroupTitle(
title: "asset_list_layout_sub_title".t(context: context),
icon: Icons.view_module_outlined,
),
SettingGroupTitle(title: context.t.asset_list_layout_sub_title, icon: Icons.view_module_outlined),
SettingsSliderListTile(
valueNotifier: tilesPerRow,
text: 'theme_setting_asset_list_tiles_per_row_title'.tr(namedArgs: {'count': "${tilesPerRow.value}"}),
text: context.t.theme_setting_asset_list_tiles_per_row_title(count: tilesPerRow.value),
label: "${tilesPerRow.value}",
maxValue: 6,
minValue: 2,

View file

@ -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/app_settings.provider.dart';
import 'package:immich_mobile/providers/infrastructure/settings.provider.dart';
import 'package:immich_mobile/widgets/settings/asset_list_settings/asset_list_group_settings.dart';
@ -21,7 +21,7 @@ class AssetListSettings extends HookConsumerWidget {
final assetListSetting = [
SettingsSwitchListTile(
valueNotifier: storageIndicator,
title: 'theme_setting_asset_list_storage_indicator_title'.tr(),
title: context.t.theme_setting_asset_list_storage_indicator_title,
onChanged: (value) {
unawaited(ref.read(settingsProvider).write(.timelineStorageIndicator, value));
ref.invalidate(appSettingsServiceProvider);

View file

@ -8,7 +8,6 @@ import 'package:immich_mobile/domain/models/settings_key.dart';
import 'package:immich_mobile/domain/services/sync_linked_album.service.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/background_sync.provider.dart';
import 'package:immich_mobile/providers/backup/backup_album.provider.dart';
@ -26,26 +25,17 @@ class DriftBackupSettings extends StatelessWidget {
Widget build(BuildContext context) {
return SettingsSubPageScaffold(
settings: [
SettingGroupTitle(
title: "network_requirements".t(context: context),
icon: Icons.cell_tower,
),
SettingGroupTitle(title: context.t.network_requirements, icon: Icons.cell_tower),
const _UseCellularForVideosButton(),
const _UseCellularForPhotosButton(),
if (CurrentPlatform.isAndroid) ...[
const Divider(),
SettingGroupTitle(
title: "background_options".t(context: context),
icon: Icons.charging_station_rounded,
),
SettingGroupTitle(title: context.t.background_options, icon: Icons.charging_station_rounded),
const _BackupOnlyWhenChargingButton(),
const _BackupDelaySlider(),
],
const Divider(),
SettingGroupTitle(
title: "backup_albums_sync".t(context: context),
icon: Icons.sync,
),
SettingGroupTitle(title: context.t.backup_albums_sync, icon: Icons.sync),
const _AlbumSyncActionButton(),
],
);
@ -108,8 +98,8 @@ class _AlbumSyncActionButtonState extends ConsumerState<_AlbumSyncActionButton>
Column(
children: [
SettingListTile(
title: "sync_albums".t(context: context),
subtitle: "sync_upload_album_setting_subtitle".t(context: context),
title: context.t.sync_albums,
subtitle: context.t.sync_upload_album_setting_subtitle,
trailing: Switch(
value: albumSyncEnable,
onChanged: (bool newValue) async {
@ -131,8 +121,8 @@ class _AlbumSyncActionButtonState extends ConsumerState<_AlbumSyncActionButton>
? SettingListTile(
onTap: _manualSyncAlbums,
contentPadding: const EdgeInsets.only(left: 32, right: 16),
title: "organize_into_albums".t(context: context),
subtitle: "organize_into_albums_description".t(context: context),
title: context.t.organize_into_albums,
subtitle: context.t.organize_into_albums_description,
trailing: isAlbumSyncInProgress
? const SizedBox(
width: 32,
@ -161,15 +151,15 @@ class _AlbumSyncActionButtonState extends ConsumerState<_AlbumSyncActionButton>
class _BackupSwitchTile extends ConsumerWidget {
final SettingsKey<bool> metadataKey;
final bool Function(AppConfig) selector;
final String titleKey;
final String subtitleKey;
final String title;
final String subtitle;
final void Function(bool)? onChanged;
const _BackupSwitchTile({
required this.metadataKey,
required this.selector,
required this.titleKey,
required this.subtitleKey,
required this.title,
required this.subtitle,
this.onChanged,
});
@ -179,8 +169,8 @@ class _BackupSwitchTile extends ConsumerWidget {
return Padding(
padding: const EdgeInsets.only(left: 8.0),
child: SettingListTile(
title: titleKey.t(context: context),
subtitle: subtitleKey.t(context: context),
title: title,
subtitle: subtitle,
trailing: Switch(
value: value,
onChanged: (bool newValue) async {
@ -201,8 +191,8 @@ class _UseCellularForVideosButton extends StatelessWidget {
return _BackupSwitchTile(
metadataKey: SettingsKey.backupUseCellularForVideos,
selector: (c) => c.backup.useCellularForVideos,
titleKey: "videos",
subtitleKey: "network_requirement_videos_upload",
title: context.t.videos,
subtitle: context.t.network_requirement_videos_upload,
);
}
}
@ -215,8 +205,8 @@ class _UseCellularForPhotosButton extends StatelessWidget {
return _BackupSwitchTile(
metadataKey: SettingsKey.backupUseCellularForPhotos,
selector: (c) => c.backup.useCellularForPhotos,
titleKey: "photos",
subtitleKey: "network_requirement_photos_upload",
title: context.t.photos,
subtitle: context.t.network_requirement_photos_upload,
);
}
}
@ -230,8 +220,8 @@ class _BackupOnlyWhenChargingButton extends ConsumerWidget {
return _BackupSwitchTile(
metadataKey: SettingsKey.backupRequireCharging,
selector: (c) => c.backup.requireCharging,
titleKey: "charging",
subtitleKey: "charging_requirement_mobile_backup",
title: context.t.charging,
subtitle: context.t.charging_requirement_mobile_backup,
onChanged: (value) {
unawaited(fgService.configure(requireCharging: value));
},

View file

@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:immich_mobile/constants/locales.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/services/localization.service.dart';
import 'package:immich_mobile/widgets/common/search_field.dart';
@ -152,7 +152,7 @@ class _LanguageSearchBar extends StatelessWidget {
child: SearchField(
autofocus: false,
contentPadding: const EdgeInsets.all(12),
hintText: 'language_search_hint'.t(context: context),
hintText: context.t.language_search_hint,
prefixIcon: const Icon(Icons.search_rounded),
suffixIcon: controller.text.isNotEmpty
? IconButton(icon: const Icon(Icons.clear_rounded), onPressed: onClear)
@ -179,12 +179,12 @@ class _LanguageNotFound extends StatelessWidget {
Icon(Icons.search_off_rounded, size: 64, color: context.colorScheme.onSurface.withValues(alpha: 0.4)),
const SizedBox(height: 8),
Text(
'language_no_results_title'.t(context: context),
context.t.language_no_results_title,
style: context.textTheme.titleMedium?.copyWith(color: context.colorScheme.onSurface),
),
const SizedBox(height: 4),
Text(
'language_no_results_subtitle'.t(context: context),
context.t.language_no_results_subtitle,
style: context.textTheme.bodyMedium?.copyWith(color: context.colorScheme.onSurface.withValues(alpha: 0.8)),
),
],
@ -214,7 +214,7 @@ class _LanguageApplyButton extends StatelessWidget {
child: isLoading
? const SizedBox.square(dimension: 24, child: CircularProgressIndicator(strokeWidth: 2))
: Text(
'setting_languages_apply'.t(context: context),
context.t.setting_languages_apply,
style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 16.0),
),
),

View file

@ -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/providers/permission.provider.dart';
import 'package:immich_mobile/widgets/settings/settings_button_list_tile.dart';
import 'package:immich_mobile/widgets/settings/settings_sub_page_scaffold.dart';
@ -29,10 +29,10 @@ class NotificationSetting extends HookConsumerWidget {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
content: const Text('notification_permission_dialog_content').tr(),
content: Text(ctx.t.notification_permission_dialog_content),
actions: [
TextButton(child: const Text('cancel').tr(), onPressed: () => ctx.pop()),
TextButton(onPressed: () => openAppNotificationSettings(ctx), child: const Text('settings').tr()),
TextButton(child: Text(ctx.t.cancel), onPressed: () => ctx.pop()),
TextButton(onPressed: () => openAppNotificationSettings(ctx), child: Text(ctx.t.settings)),
],
),
),
@ -43,9 +43,9 @@ class NotificationSetting extends HookConsumerWidget {
if (!hasPermission)
SettingsButtonListTile(
icon: Icons.notifications_outlined,
title: 'notification_permission_list_tile_title'.tr(),
subtileText: 'notification_permission_list_tile_content'.tr(),
buttonText: 'notification_permission_list_tile_enable_button'.tr(),
title: context.t.notification_permission_list_tile_title,
subtileText: context.t.notification_permission_list_tile_content,
buttonText: context.t.notification_permission_list_tile_enable_button,
onButtonTap: () =>
ref.read(notificationPermissionProvider.notifier).requestNotificationPermission().then((permission) {
if (permission == PermissionStatus.permanentlyDenied) {
@ -56,9 +56,9 @@ class NotificationSetting extends HookConsumerWidget {
else
SettingsButtonListTile(
icon: Icons.notifications_active_outlined,
title: 'notification_enabled_list_tile_title'.tr(),
subtileText: 'notification_enabled_list_tile_content'.tr(),
buttonText: 'notification_enabled_list_tile_open_button'.tr(),
title: context.t.notification_enabled_list_tile_title,
subtileText: context.t.notification_enabled_list_tile_content,
buttonText: context.t.notification_enabled_list_tile_open_button,
onButtonTap: () => openAppSettings(),
),
];

View file

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:immich_mobile/extensions/translate_extensions.dart';
import 'package:immich_mobile/generated/translations.g.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/utils/hooks/app_settings_update_hook.dart';
import 'package:immich_mobile/widgets/settings/setting_group_title.dart';
@ -21,13 +21,10 @@ class HapticSetting extends HookWidget {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SettingGroupTitle(
title: "haptic_feedback_title".t(context: context),
icon: Icons.vibration_outlined,
),
SettingGroupTitle(title: context.t.haptic_feedback_title, icon: Icons.vibration_outlined),
SettingsSwitchListTile(
valueNotifier: isHapticFeedbackEnabled,
title: 'enabled'.t(context: context),
title: context.t.enabled,
onChanged: onHapticFeedbackChange,
),
],

View file

@ -1,11 +1,11 @@
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/colors.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/providers/infrastructure/settings.provider.dart';
import 'package:immich_mobile/providers/theme.provider.dart';
import 'package:immich_mobile/theme/color_scheme.dart';
@ -97,7 +97,7 @@ class PrimaryColorSetting extends HookConsumerWidget {
children: [
Align(
alignment: Alignment.center,
child: Text("theme_setting_primary_color_title".tr(), style: context.textTheme.titleLarge),
child: Text(context.t.theme_setting_primary_color_title, style: context.textTheme.titleLarge),
),
if (DynamicTheme.isAvailable)
Container(
@ -110,7 +110,7 @@ class PrimaryColorSetting extends HookConsumerWidget {
tileColor: context.colorScheme.surfaceContainerHigh,
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(15))),
title: Text(
'theme_setting_system_primary_color_title'.tr(),
context.t.theme_setting_system_primary_color_title,
style: context.textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w500, height: 1.5),
),
value: themeConfig.dynamicTheme,
@ -157,11 +157,11 @@ class PrimaryColorSetting extends HookConsumerWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"theme_setting_primary_color_title".tr(),
context.t.theme_setting_primary_color_title,
style: context.textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w500),
),
Text(
"theme_setting_primary_color_subtitle".tr(),
context.t.theme_setting_primary_color_subtitle,
style: context.textTheme.bodyMedium?.copyWith(color: context.colorScheme.onSurfaceSecondary),
),
],

View file

@ -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/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/infrastructure/settings.provider.dart';
import 'package:immich_mobile/widgets/settings/preference_settings/primary_color_setting.dart';
import 'package:immich_mobile/widgets/settings/setting_group_title.dart';
@ -52,26 +52,23 @@ class ThemeSetting extends HookConsumerWidget {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SettingGroupTitle(
title: "theme".t(context: context),
icon: Icons.color_lens_outlined,
),
SettingGroupTitle(title: context.t.theme, icon: Icons.color_lens_outlined),
SettingsSwitchListTile(
valueNotifier: isSystemTheme,
title: 'theme_setting_system_theme_switch'.t(context: context),
title: context.t.theme_setting_system_theme_switch,
onChanged: onSystemThemeChange,
),
if (currentTheme.value != ThemeMode.system)
SettingsSwitchListTile(
valueNotifier: isDarkTheme,
title: 'map_settings_dark_mode'.t(context: context),
title: context.t.map_settings_dark_mode,
onChanged: onThemeChange,
),
const PrimaryColorSetting(),
SettingsSwitchListTile(
valueNotifier: colorfulInterface,
title: "theme_setting_colorful_interface_title".t(context: context),
subtitle: 'theme_setting_colorful_interface_subtitle'.t(context: context),
title: context.t.theme_setting_colorful_interface_title,
subtitle: context.t.theme_setting_colorful_interface_subtitle,
onChanged: onSurfaceColorSettingChange,
),
],