diff --git a/mobile/lib/pages/common/gallery_viewer.page.dart b/mobile/lib/pages/common/gallery_viewer.page.dart index 57f0c5e93b..704ee2829f 100644 --- a/mobile/lib/pages/common/gallery_viewer.page.dart +++ b/mobile/lib/pages/common/gallery_viewer.page.dart @@ -420,7 +420,7 @@ class GalleryViewerPage extends HookConsumerWidget { showStack: showStack, stackIndex: stackIndex.value, asset: asset, - assetIndex: currentIndex.value, + assetIndex: currentIndex, showVideoPlayerControls: !asset.isImage && !isMotionPhoto, ), ], 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 f885e06bc3..060e0bc04e 100644 --- a/mobile/lib/widgets/asset_grid/control_bottom_app_bar.dart +++ b/mobile/lib/widgets/asset_grid/control_bottom_app_bar.dart @@ -247,7 +247,7 @@ class ControlBottomAppBar extends HookConsumerWidget { ConstrainedBox( constraints: const BoxConstraints(maxWidth: 90), child: ControlBoxButton( - iconData: Icons.delete_sweep_rounded, + iconData: Icons.remove_circle_outline, label: 'album_viewer_appbar_share_remove'.tr(), onPressed: enabled ? onRemoveFromAlbum : null, ), diff --git a/mobile/lib/widgets/asset_viewer/bottom_gallery_bar.dart b/mobile/lib/widgets/asset_viewer/bottom_gallery_bar.dart index fa76528a46..a4370cab84 100644 --- a/mobile/lib/widgets/asset_viewer/bottom_gallery_bar.dart +++ b/mobile/lib/widgets/asset_viewer/bottom_gallery_bar.dart @@ -6,6 +6,8 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; +import 'package:immich_mobile/providers/album/current_album.provider.dart'; +import 'package:immich_mobile/providers/album/shared_album.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/asset_stack.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/image_viewer_page_state.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/show_controls.provider.dart'; @@ -22,7 +24,7 @@ import 'package:immich_mobile/widgets/common/immich_toast.dart'; class BottomGalleryBar extends ConsumerWidget { final Asset asset; - final int assetIndex; + final ValueNotifier assetIndex; final bool showStack; final int stackIndex; final ValueNotifier totalAssets; @@ -57,6 +59,7 @@ class BottomGalleryBar extends ConsumerWidget { final isFromTrash = isTrashEnabled && navStack.length > 2 && navStack.elementAt(navStack.length - 2).name == TrashRoute.name; + final isInAlbum = ref.watch(currentAlbumProvider)?.isRemote ?? false; // !!!! itemsList and actionlist should always be in sync final itemsList = [ BottomNavigationBarItem( @@ -96,6 +99,12 @@ class BottomGalleryBar extends ConsumerWidget { label: 'download'.tr(), tooltip: 'download'.tr(), ), + if (isInAlbum) + BottomNavigationBarItem( + icon: const Icon(Icons.remove_circle_outline), + label: 'album_viewer_appbar_share_remove'.tr(), + tooltip: 'album_viewer_appbar_share_remove'.tr(), + ), ]; void removeAssetFromStack() { @@ -118,7 +127,8 @@ class BottomGalleryBar extends ConsumerWidget { // `assetIndex == totalAssets.value - 1` handle the case of removing the last asset // to not throw the error when the next preCache index is called - if (totalAssets.value == 1 || assetIndex == totalAssets.value - 1) { + if (totalAssets.value == 1 || + assetIndex.value == totalAssets.value - 1) { // Handle only one asset context.maybePop(); } @@ -299,12 +309,45 @@ class BottomGalleryBar extends ConsumerWidget { ); } + handleRemoveFromAlbum() async { + final album = ref.read(currentAlbumProvider); + final bool isSuccess = album != null && + await ref + .read(sharedAlbumProvider.notifier) + .removeAssetFromAlbum(album, [asset]); + + if (isSuccess) { + // Workaround for asset remaining in the gallery + renderList.deleteAsset(asset); + + if (totalAssets.value == 1) { + // Handle empty viewer + await context.maybePop(); + } else { + // changing this also for the last asset causes the parent to rebuild with an error + totalAssets.value -= 1; + } + if (assetIndex.value == totalAssets.value && assetIndex.value > 0) { + // handle the case of removing the last asset in the list + assetIndex.value -= 1; + } + } else { + ImmichToast.show( + context: context, + msg: "album_viewer_appbar_share_err_remove".tr(), + toastType: ToastType.error, + gravity: ToastGravity.BOTTOM, + ); + } + } + List actionslist = [ (_) => shareAsset(), if (isOwner) (_) => handleArchive(), if (isOwner && stack.isNotEmpty) (_) => showStackActionItems(), if (isOwner) (_) => handleDelete(), if (!isOwner) (_) => handleDownload(), + if (isInAlbum) (_) => handleRemoveFromAlbum(), ]; return IgnorePointer(