From 9d68e12a08d04e6c2888bbe223ff7b4436509930 Mon Sep 17 00:00:00 2001 From: timonrieger Date: Sun, 25 Jan 2026 23:47:07 +0100 Subject: [PATCH] add to legacy control bottom bar --- .../asset_grid/control_bottom_app_bar.dart | 11 ++++++ .../widgets/asset_grid/multiselect_grid.dart | 37 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/mobile/lib/widgets/asset_grid/control_bottom_app_bar.dart b/mobile/lib/widgets/asset_grid/control_bottom_app_bar.dart index cd2dc70dae..124666e2ff 100644 --- a/mobile/lib/widgets/asset_grid/control_bottom_app_bar.dart +++ b/mobile/lib/widgets/asset_grid/control_bottom_app_bar.dart @@ -33,6 +33,7 @@ class ControlBottomAppBar extends HookConsumerWidget { final void Function([bool force])? onDelete; final void Function([bool force])? onDeleteServer; final void Function(bool onlyBackedUp)? onDeleteLocal; + final void Function()? onSetAlbumCover; final Function(Album album) onAddToAlbum; final void Function() onCreateNewAlbum; final void Function() onUpload; @@ -57,6 +58,7 @@ class ControlBottomAppBar extends HookConsumerWidget { this.onDelete, this.onDeleteServer, this.onDeleteLocal, + this.onSetAlbumCover, required this.onAddToAlbum, required this.onCreateNewAlbum, required this.onUpload, @@ -267,6 +269,15 @@ class ControlBottomAppBar extends HookConsumerWidget { onPressed: enabled ? onRemoveFromAlbum : null, ), ), + if (onSetAlbumCover != null) + ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 90), + child: ControlBoxButton( + iconData: Icons.image_outlined, + label: 'set_as_album_cover'.tr(), + onPressed: enabled ? onSetAlbumCover : null, + ), + ), if (selectionAssetState.hasLocal) ControlBoxButton( iconData: Icons.backup_outlined, diff --git a/mobile/lib/widgets/asset_grid/multiselect_grid.dart b/mobile/lib/widgets/asset_grid/multiselect_grid.dart index c0d8a6bea2..61880d0c75 100644 --- a/mobile/lib/widgets/asset_grid/multiselect_grid.dart +++ b/mobile/lib/widgets/asset_grid/multiselect_grid.dart @@ -17,11 +17,13 @@ import 'package:immich_mobile/providers/album/album.provider.dart'; import 'package:immich_mobile/providers/asset.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/download.provider.dart'; import 'package:immich_mobile/providers/backup/manual_upload.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/current_album.provider.dart'; import 'package:immich_mobile/providers/multiselect.provider.dart'; import 'package:immich_mobile/providers/routes.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/services/album.service.dart'; +import 'package:immich_mobile/services/action.service.dart'; import 'package:immich_mobile/services/stack.service.dart'; import 'package:immich_mobile/utils/immich_loading_overlay.dart'; import 'package:immich_mobile/utils/selection_handlers.dart'; @@ -77,6 +79,7 @@ class MultiselectGrid extends HookConsumerWidget { final selection = useState({}); final currentUser = ref.watch(currentUserProvider); + final currentAlbum = ref.watch(currentRemoteAlbumProvider); final processing = useProcessingOverlay(); useEffect(() { @@ -400,6 +403,37 @@ class MultiselectGrid extends HookConsumerWidget { } }; + Future setAsAlbumCover() async { + final album = currentAlbum; + if (album == null) { + return false; + } + + if (currentUser?.id != album.ownerId) { + return false; + } + + if (selection.value.length != 1) { + return false; + } + + final asset = selection.value.first; + final assetId = asset.remoteId; + if (assetId == null) { + ImmichToast.show(context: context, msg: 'errors.unable_to_update_album_cover'.tr(), toastType: ToastType.error); + return false; + } + + try { + await ref.read(actionServiceProvider).setAlbumCover(album.id, assetId); + ImmichToast.show(context: context, msg: 'album_cover_updated'.tr(), toastType: ToastType.success); + return true; + } catch (_) { + ImmichToast.show(context: context, msg: 'errors.unable_to_update_album_cover'.tr(), toastType: ToastType.error); + return false; + } + } + return SafeArea( top: true, bottom: false, @@ -447,6 +481,9 @@ class MultiselectGrid extends HookConsumerWidget { unfavorite: unfavorite, unarchive: unarchive, onToggleLocked: onToggleLockedVisibility, + onSetAlbumCover: (currentAlbum != null && currentUser?.id == currentAlbum.ownerId) + ? wrapLongRunningFun(setAsAlbumCover) + : null, onRemoveFromAlbum: onRemoveFromAlbum != null ? wrapLongRunningFun(() => onRemoveFromAlbum!(selection.value)) : null,