mirror of
				https://github.com/KevinMidboe/immich.git
				synced 2025-10-29 17:40:28 +00:00 
			
		
		
		
	feat(mobile): Multiselect add to favorite from the timeline (#1558)
* multiselect add to favorites
This commit is contained in:
		@@ -34,6 +34,18 @@ class FavoriteSelectionNotifier extends StateNotifier<Set<String>> {
 | 
			
		||||
      state.contains(asset.id),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> addToFavorites(Iterable<Asset> assets) {
 | 
			
		||||
    state = state.union(assets.map((a) => a.id).toSet());
 | 
			
		||||
    final futures = assets.map((a) => 
 | 
			
		||||
        ref.watch(assetProvider.notifier).toggleFavorite(
 | 
			
		||||
          a,
 | 
			
		||||
          true,
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
    return Future.wait(futures);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
final favoriteProvider =
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import 'package:immich_mobile/shared/models/album.dart';
 | 
			
		||||
 | 
			
		||||
class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
  final Function onShare;
 | 
			
		||||
  final Function onFavorite;
 | 
			
		||||
  final Function onDelete;
 | 
			
		||||
  final Function(Album album) onAddToAlbum;
 | 
			
		||||
  final void Function() onCreateNewAlbum;
 | 
			
		||||
@@ -18,6 +19,7 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
  const ControlBottomAppBar({
 | 
			
		||||
    Key? key,
 | 
			
		||||
    required this.onShare,
 | 
			
		||||
    required this.onFavorite,
 | 
			
		||||
    required this.onDelete,
 | 
			
		||||
    required this.sharedAlbums,
 | 
			
		||||
    required this.albums,
 | 
			
		||||
@@ -37,6 +39,13 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
              onShare();
 | 
			
		||||
            },
 | 
			
		||||
          ),
 | 
			
		||||
          ControlBoxButton(
 | 
			
		||||
            iconData: Icons.star_rounded,
 | 
			
		||||
            label: "Favorite",
 | 
			
		||||
            onPressed: () {
 | 
			
		||||
              onFavorite();
 | 
			
		||||
            },
 | 
			
		||||
          ),
 | 
			
		||||
          ControlBoxButton(
 | 
			
		||||
            iconData: Icons.delete_outline_rounded,
 | 
			
		||||
            label: "control_bottom_app_bar_delete".tr(),
 | 
			
		||||
@@ -51,6 +60,7 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
              );
 | 
			
		||||
            },
 | 
			
		||||
          ),
 | 
			
		||||
 | 
			
		||||
        ],
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
			
		||||
import 'package:immich_mobile/modules/album/providers/album.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/modules/album/services/album.service.dart';
 | 
			
		||||
import 'package:immich_mobile/modules/favorite/providers/favorite_provider.dart';
 | 
			
		||||
import 'package:immich_mobile/modules/home/providers/multiselect.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
 | 
			
		||||
import 'package:immich_mobile/modules/home/ui/control_bottom_app_bar.dart';
 | 
			
		||||
@@ -83,27 +84,39 @@ class HomePage extends HookConsumerWidget {
 | 
			
		||||
        selectionEnabledHook.value = false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void onDelete() {
 | 
			
		||||
        ref.watch(assetProvider.notifier).deleteAssets(selection.value);
 | 
			
		||||
        selectionEnabledHook.value = false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      Iterable<Asset> remoteOnlySelection() {
 | 
			
		||||
      Iterable<Asset> remoteOnlySelection({String? localErrorMessage}) {
 | 
			
		||||
        final Set<Asset> assets = selection.value;
 | 
			
		||||
        final bool onlyRemote = assets.every((e) => e.isRemote);
 | 
			
		||||
        if (!onlyRemote) {
 | 
			
		||||
          ImmichToast.show(
 | 
			
		||||
            context: context,
 | 
			
		||||
            msg: "Can not add local assets to albums yet, skipping",
 | 
			
		||||
            gravity: ToastGravity.BOTTOM,
 | 
			
		||||
          );
 | 
			
		||||
          if (localErrorMessage != null && localErrorMessage.isNotEmpty) {
 | 
			
		||||
            ImmichToast.show(
 | 
			
		||||
              context: context,
 | 
			
		||||
              msg: localErrorMessage,
 | 
			
		||||
              gravity: ToastGravity.BOTTOM,
 | 
			
		||||
            );
 | 
			
		||||
          }
 | 
			
		||||
          return assets.where((a) => a.isRemote);
 | 
			
		||||
        }
 | 
			
		||||
        return assets;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void onFavoriteAssets() {
 | 
			
		||||
        final remoteAssests = remoteOnlySelection(
 | 
			
		||||
          localErrorMessage: 'Can not favorite local assets yet, skipping',
 | 
			
		||||
        );
 | 
			
		||||
        ref.watch(favoriteProvider.notifier).addToFavorites(remoteAssests);
 | 
			
		||||
        selectionEnabledHook.value = false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void onDelete() {
 | 
			
		||||
        ref.watch(assetProvider.notifier).deleteAssets(selection.value);
 | 
			
		||||
        selectionEnabledHook.value = false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void onAddToAlbum(Album album) async {
 | 
			
		||||
        final Iterable<Asset> assets = remoteOnlySelection();
 | 
			
		||||
        final Iterable<Asset> assets = remoteOnlySelection(
 | 
			
		||||
          localErrorMessage: "Can not add local assets to albums yet, skipping",
 | 
			
		||||
        );
 | 
			
		||||
        if (assets.isEmpty) {
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -142,7 +155,9 @@ class HomePage extends HookConsumerWidget {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      void onCreateNewAlbum() async {
 | 
			
		||||
        final Iterable<Asset> assets = remoteOnlySelection();
 | 
			
		||||
        final Iterable<Asset> assets = remoteOnlySelection(
 | 
			
		||||
          localErrorMessage: "Can not add local assets to albums yet, skipping",
 | 
			
		||||
        );
 | 
			
		||||
        if (assets.isEmpty) {
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -221,6 +236,7 @@ class HomePage extends HookConsumerWidget {
 | 
			
		||||
            if (selectionEnabledHook.value)
 | 
			
		||||
              ControlBottomAppBar(
 | 
			
		||||
                onShare: onShareAssets,
 | 
			
		||||
                onFavorite: onFavoriteAssets,
 | 
			
		||||
                onDelete: onDelete,
 | 
			
		||||
                onAddToAlbum: onAddToAlbum,
 | 
			
		||||
                albums: albums,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user