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