mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:17:11 -05:00 
			
		
		
		
	feat(mobile): Add to album from asset detail view (#1413)
* add to album from asset detail view * layout and design * added shared albums * fixed remote, asset update, and hit test * made static size * fixed create album * suppress shared expansion tile if there are no shared albums * updates album * padding on tile
This commit is contained in:
		
							parent
							
								
									788b435f9b
								
							
						
					
					
						commit
						d377cf0d02
					
				
							
								
								
									
										129
									
								
								mobile/lib/modules/album/ui/add_to_album_list.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								mobile/lib/modules/album/ui/add_to_album_list.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,129 @@
 | 
				
			|||||||
 | 
					import 'package:auto_route/auto_route.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:flutter_hooks/flutter_hooks.dart';
 | 
				
			||||||
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/modules/album/providers/album.provider.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/modules/album/providers/asset_selection.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/album/ui/album_thumbnail_listtile.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/routing/router.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/shared/models/asset.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/shared/ui/drag_sheet.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/shared/ui/immich_toast.dart';
 | 
				
			||||||
 | 
					import 'package:openapi/api.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AddToAlbumList extends HookConsumerWidget {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The asset to add to an album
 | 
				
			||||||
 | 
					  final Asset asset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const AddToAlbumList({
 | 
				
			||||||
 | 
					    Key? key,
 | 
				
			||||||
 | 
					    required this.asset,
 | 
				
			||||||
 | 
					  }) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context, WidgetRef ref) {
 | 
				
			||||||
 | 
					    final albums = ref.watch(albumProvider);
 | 
				
			||||||
 | 
					    final albumService = ref.watch(albumServiceProvider);
 | 
				
			||||||
 | 
					    final sharedAlbums = ref.watch(sharedAlbumProvider);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    useEffect(
 | 
				
			||||||
 | 
					      () {
 | 
				
			||||||
 | 
					        // Fetch album updates, e.g., cover image
 | 
				
			||||||
 | 
					        ref.read(albumProvider.notifier).getAllAlbums();
 | 
				
			||||||
 | 
					        ref.read(sharedAlbumProvider.notifier).getAllSharedAlbums();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      [], 
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void addToAlbum(AlbumResponseDto album) async {
 | 
				
			||||||
 | 
					      final result = await albumService.addAdditionalAssetToAlbum(
 | 
				
			||||||
 | 
					        [asset],
 | 
				
			||||||
 | 
					        album.id,
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      if (result != null) {
 | 
				
			||||||
 | 
					        if (result.alreadyInAlbum.isNotEmpty) {
 | 
				
			||||||
 | 
					          ImmichToast.show(
 | 
				
			||||||
 | 
					            context: context,
 | 
				
			||||||
 | 
					            msg: 'Already in ${album.albumName}',
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          ImmichToast.show(
 | 
				
			||||||
 | 
					            context: context,
 | 
				
			||||||
 | 
					            msg: 'Added to ${album.albumName}',
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ref.read(albumProvider.notifier).getAllAlbums();
 | 
				
			||||||
 | 
					      ref.read(sharedAlbumProvider.notifier).getAllSharedAlbums();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Navigator.pop(context);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return Card(
 | 
				
			||||||
 | 
					      shape: const RoundedRectangleBorder(
 | 
				
			||||||
 | 
					        borderRadius: BorderRadius.only(
 | 
				
			||||||
 | 
					          topLeft: Radius.circular(15),
 | 
				
			||||||
 | 
					          topRight: Radius.circular(15),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      child: ListView(
 | 
				
			||||||
 | 
					        padding: const EdgeInsets.all(18.0),
 | 
				
			||||||
 | 
					        children: [
 | 
				
			||||||
 | 
					          Column(
 | 
				
			||||||
 | 
					            crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
 | 
					            children: [
 | 
				
			||||||
 | 
					              const Align(
 | 
				
			||||||
 | 
					                alignment: Alignment.center,
 | 
				
			||||||
 | 
					                child: CustomDraggingHandle(),
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					              const SizedBox(height: 12),
 | 
				
			||||||
 | 
					              Text('Add to album',
 | 
				
			||||||
 | 
					                style: Theme.of(context).textTheme.headline1,
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					              TextButton.icon(
 | 
				
			||||||
 | 
					                icon: const Icon(Icons.add),
 | 
				
			||||||
 | 
					                label: const Text('New album'),
 | 
				
			||||||
 | 
					                onPressed: () {
 | 
				
			||||||
 | 
					                  ref.watch(assetSelectionProvider.notifier).removeAll();
 | 
				
			||||||
 | 
					                  ref.watch(assetSelectionProvider.notifier).addNewAssets([asset]);
 | 
				
			||||||
 | 
					                  AutoRouter.of(context).push(
 | 
				
			||||||
 | 
					                    CreateAlbumRoute(
 | 
				
			||||||
 | 
					                      isSharedAlbum: false,
 | 
				
			||||||
 | 
					                      initialAssets: [asset],
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                  );
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          if (sharedAlbums.isNotEmpty)
 | 
				
			||||||
 | 
					            ExpansionTile(
 | 
				
			||||||
 | 
					              title: const Text('Shared'),
 | 
				
			||||||
 | 
					              tilePadding: const EdgeInsets.symmetric(horizontal: 10.0),
 | 
				
			||||||
 | 
					              leading: const Icon(Icons.group),
 | 
				
			||||||
 | 
					              children: sharedAlbums.map((album) => 
 | 
				
			||||||
 | 
					                AlbumThumbnailListTile(
 | 
				
			||||||
 | 
					                  album: album,
 | 
				
			||||||
 | 
					                  onTap: () => addToAlbum(album),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					              ).toList(),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            const SizedBox(height: 12),
 | 
				
			||||||
 | 
					            ... albums.map((album) =>
 | 
				
			||||||
 | 
					              AlbumThumbnailListTile(
 | 
				
			||||||
 | 
					                album: album,
 | 
				
			||||||
 | 
					                onTap: () => addToAlbum(album),
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					            ).toList(),
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										115
									
								
								mobile/lib/modules/album/ui/album_thumbnail_listtile.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								mobile/lib/modules/album/ui/album_thumbnail_listtile.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,115 @@
 | 
				
			|||||||
 | 
					import 'package:auto_route/auto_route.dart';
 | 
				
			||||||
 | 
					import 'package:cached_network_image/cached_network_image.dart';
 | 
				
			||||||
 | 
					import 'package:easy_localization/easy_localization.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:hive/hive.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/constants/hive_box.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/routing/router.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/utils/image_url_builder.dart';
 | 
				
			||||||
 | 
					import 'package:openapi/api.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AlbumThumbnailListTile extends StatelessWidget {
 | 
				
			||||||
 | 
					  const AlbumThumbnailListTile({
 | 
				
			||||||
 | 
					    Key? key,
 | 
				
			||||||
 | 
					    required this.album,
 | 
				
			||||||
 | 
					    this.onTap,
 | 
				
			||||||
 | 
					  }) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final AlbumResponseDto album;
 | 
				
			||||||
 | 
					  final void Function()? onTap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    var box = Hive.box(userInfoBox);
 | 
				
			||||||
 | 
					    var cardSize = 68.0;
 | 
				
			||||||
 | 
					    var isDarkMode = Theme.of(context).brightness == Brightness.dark;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buildEmptyThumbnail() {
 | 
				
			||||||
 | 
					      return Container(
 | 
				
			||||||
 | 
					        decoration: BoxDecoration(
 | 
				
			||||||
 | 
					          color: isDarkMode ? Colors.grey[800] : Colors.grey[200],
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        child: SizedBox(
 | 
				
			||||||
 | 
					          height: cardSize,
 | 
				
			||||||
 | 
					          width: cardSize,
 | 
				
			||||||
 | 
					          child: const Center(
 | 
				
			||||||
 | 
					            child: Icon(Icons.no_photography),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buildAlbumThumbnail() {
 | 
				
			||||||
 | 
					      return CachedNetworkImage(
 | 
				
			||||||
 | 
					        width: cardSize,
 | 
				
			||||||
 | 
					        height: cardSize,
 | 
				
			||||||
 | 
					        fit: BoxFit.cover,
 | 
				
			||||||
 | 
					        fadeInDuration: const Duration(milliseconds: 200),
 | 
				
			||||||
 | 
					        imageUrl: getAlbumThumbnailUrl(
 | 
				
			||||||
 | 
					          album,
 | 
				
			||||||
 | 
					          type: ThumbnailFormat.JPEG,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"},
 | 
				
			||||||
 | 
					        cacheKey: getAlbumThumbNailCacheKey(album, type: ThumbnailFormat.JPEG),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return GestureDetector(
 | 
				
			||||||
 | 
					      behavior: HitTestBehavior.opaque,
 | 
				
			||||||
 | 
					      onTap: onTap ?? () {
 | 
				
			||||||
 | 
					        AutoRouter.of(context).push(AlbumViewerRoute(albumId: album.id));
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      child: Padding(
 | 
				
			||||||
 | 
					        padding: const EdgeInsets.only(bottom: 12.0),
 | 
				
			||||||
 | 
					        child: Row(
 | 
				
			||||||
 | 
					          crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
 | 
					          children: [
 | 
				
			||||||
 | 
					            ClipRRect(
 | 
				
			||||||
 | 
					              borderRadius: BorderRadius.circular(8),
 | 
				
			||||||
 | 
					              child: album.albumThumbnailAssetId == null
 | 
				
			||||||
 | 
					                  ? buildEmptyThumbnail()
 | 
				
			||||||
 | 
					                  : buildAlbumThumbnail(),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            Padding(
 | 
				
			||||||
 | 
					              padding: const EdgeInsets.only(
 | 
				
			||||||
 | 
					                left: 8.0,
 | 
				
			||||||
 | 
					                right: 8.0,
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					              child: Column(
 | 
				
			||||||
 | 
					                crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
 | 
					                children: [
 | 
				
			||||||
 | 
					                  Text(
 | 
				
			||||||
 | 
					                    album.albumName,
 | 
				
			||||||
 | 
					                    style: const TextStyle(
 | 
				
			||||||
 | 
					                      fontWeight: FontWeight.bold,
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                  ),
 | 
				
			||||||
 | 
					                  Row(
 | 
				
			||||||
 | 
					                    mainAxisSize: MainAxisSize.min,
 | 
				
			||||||
 | 
					                    children: [
 | 
				
			||||||
 | 
					                      Text(
 | 
				
			||||||
 | 
					                        album.assetCount == 1
 | 
				
			||||||
 | 
					                            ? 'album_thumbnail_card_item'
 | 
				
			||||||
 | 
					                            : 'album_thumbnail_card_items',
 | 
				
			||||||
 | 
					                        style: const TextStyle(
 | 
				
			||||||
 | 
					                          fontSize: 12,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                      ).tr(args: ['${album.assetCount}']),
 | 
				
			||||||
 | 
					                      if (album.shared)
 | 
				
			||||||
 | 
					                        const Text(
 | 
				
			||||||
 | 
					                          'album_thumbnail_card_shared',
 | 
				
			||||||
 | 
					                          style: TextStyle(
 | 
				
			||||||
 | 
					                            fontSize: 12,
 | 
				
			||||||
 | 
					                          ),
 | 
				
			||||||
 | 
					                        ).tr()
 | 
				
			||||||
 | 
					                    ],
 | 
				
			||||||
 | 
					                  )
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -11,12 +11,18 @@ import 'package:immich_mobile/modules/album/ui/album_action_outlined_button.dart
 | 
				
			|||||||
import 'package:immich_mobile/modules/album/ui/album_title_text_field.dart';
 | 
					import 'package:immich_mobile/modules/album/ui/album_title_text_field.dart';
 | 
				
			||||||
import 'package:immich_mobile/modules/album/ui/shared_album_thumbnail_image.dart';
 | 
					import 'package:immich_mobile/modules/album/ui/shared_album_thumbnail_image.dart';
 | 
				
			||||||
import 'package:immich_mobile/routing/router.dart';
 | 
					import 'package:immich_mobile/routing/router.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/shared/models/asset.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ignore: must_be_immutable
 | 
					// ignore: must_be_immutable
 | 
				
			||||||
class CreateAlbumPage extends HookConsumerWidget {
 | 
					class CreateAlbumPage extends HookConsumerWidget {
 | 
				
			||||||
  bool isSharedAlbum;
 | 
					  final bool isSharedAlbum;
 | 
				
			||||||
 | 
					  final List<Asset>? initialAssets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CreateAlbumPage({Key? key, required this.isSharedAlbum}) : super(key: key);
 | 
					  const CreateAlbumPage({
 | 
				
			||||||
 | 
					    Key? key, 
 | 
				
			||||||
 | 
					    required this.isSharedAlbum,
 | 
				
			||||||
 | 
					    this.initialAssets,
 | 
				
			||||||
 | 
					  }) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
					  Widget build(BuildContext context, WidgetRef ref) {
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,7 @@ class TopControlAppBar extends HookConsumerWidget with PreferredSizeWidget {
 | 
				
			|||||||
    required this.onDownloadPressed,
 | 
					    required this.onDownloadPressed,
 | 
				
			||||||
    required this.onSharePressed,
 | 
					    required this.onSharePressed,
 | 
				
			||||||
    required this.onDeletePressed,
 | 
					    required this.onDeletePressed,
 | 
				
			||||||
 | 
					    required this.onAddToAlbumPressed,
 | 
				
			||||||
    required this.onToggleMotionVideo,
 | 
					    required this.onToggleMotionVideo,
 | 
				
			||||||
    required this.isPlayingMotionVideo,
 | 
					    required this.isPlayingMotionVideo,
 | 
				
			||||||
  }) : super(key: key);
 | 
					  }) : super(key: key);
 | 
				
			||||||
@ -20,6 +21,7 @@ class TopControlAppBar extends HookConsumerWidget with PreferredSizeWidget {
 | 
				
			|||||||
  final VoidCallback? onDownloadPressed;
 | 
					  final VoidCallback? onDownloadPressed;
 | 
				
			||||||
  final VoidCallback onToggleMotionVideo;
 | 
					  final VoidCallback onToggleMotionVideo;
 | 
				
			||||||
  final VoidCallback onDeletePressed;
 | 
					  final VoidCallback onDeletePressed;
 | 
				
			||||||
 | 
					  final VoidCallback onAddToAlbumPressed;
 | 
				
			||||||
  final Function onSharePressed;
 | 
					  final Function onSharePressed;
 | 
				
			||||||
  final bool isPlayingMotionVideo;
 | 
					  final bool isPlayingMotionVideo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -80,6 +82,18 @@ class TopControlAppBar extends HookConsumerWidget with PreferredSizeWidget {
 | 
				
			|||||||
            color: Colors.grey[200],
 | 
					            color: Colors.grey[200],
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
 | 
					        if (asset.isRemote)
 | 
				
			||||||
 | 
					          IconButton(
 | 
				
			||||||
 | 
					            iconSize: iconSize,
 | 
				
			||||||
 | 
					            splashRadius: iconSize,
 | 
				
			||||||
 | 
					            onPressed: () {
 | 
				
			||||||
 | 
					              onAddToAlbumPressed();
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            icon: Icon(
 | 
				
			||||||
 | 
					              Icons.add,
 | 
				
			||||||
 | 
					              color: Colors.grey[200],
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
        IconButton(
 | 
					        IconButton(
 | 
				
			||||||
          iconSize: iconSize,
 | 
					          iconSize: iconSize,
 | 
				
			||||||
          splashRadius: iconSize,
 | 
					          splashRadius: iconSize,
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
 | 
				
			|||||||
import 'package:hive/hive.dart';
 | 
					import 'package:hive/hive.dart';
 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
import 'package:immich_mobile/constants/hive_box.dart';
 | 
					import 'package:immich_mobile/constants/hive_box.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/modules/album/ui/add_to_album_list.dart';
 | 
				
			||||||
import 'package:immich_mobile/modules/asset_viewer/providers/image_viewer_page_state.provider.dart';
 | 
					import 'package:immich_mobile/modules/asset_viewer/providers/image_viewer_page_state.provider.dart';
 | 
				
			||||||
import 'package:immich_mobile/modules/asset_viewer/ui/exif_bottom_sheet.dart';
 | 
					import 'package:immich_mobile/modules/asset_viewer/ui/exif_bottom_sheet.dart';
 | 
				
			||||||
import 'package:immich_mobile/modules/asset_viewer/ui/top_control_app_bar.dart';
 | 
					import 'package:immich_mobile/modules/asset_viewer/ui/top_control_app_bar.dart';
 | 
				
			||||||
@ -105,6 +106,22 @@ class GalleryViewerPage extends HookConsumerWidget {
 | 
				
			|||||||
      );
 | 
					      );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void addToAlbum(Asset addToAlbumAsset) {
 | 
				
			||||||
 | 
					      showModalBottomSheet(
 | 
				
			||||||
 | 
					        shape: RoundedRectangleBorder(
 | 
				
			||||||
 | 
					          borderRadius: BorderRadius.circular(15.0),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        barrierColor: Colors.transparent,
 | 
				
			||||||
 | 
					        backgroundColor: Colors.transparent,
 | 
				
			||||||
 | 
					        context: context,
 | 
				
			||||||
 | 
					        builder: (BuildContext _) {
 | 
				
			||||||
 | 
					          return AddToAlbumList(
 | 
				
			||||||
 | 
					            asset: addToAlbumAsset,
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return Scaffold(
 | 
					    return Scaffold(
 | 
				
			||||||
      backgroundColor: Colors.black,
 | 
					      backgroundColor: Colors.black,
 | 
				
			||||||
      appBar: TopControlAppBar(
 | 
					      appBar: TopControlAppBar(
 | 
				
			||||||
@ -130,6 +147,7 @@ class GalleryViewerPage extends HookConsumerWidget {
 | 
				
			|||||||
          isPlayingMotionVideo.value = !isPlayingMotionVideo.value;
 | 
					          isPlayingMotionVideo.value = !isPlayingMotionVideo.value;
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        onDeletePressed: () => handleDelete((assetList[indexOfAsset.value])),
 | 
					        onDeletePressed: () => handleDelete((assetList[indexOfAsset.value])),
 | 
				
			||||||
 | 
					        onAddToAlbumPressed: () => addToAlbum(assetList[indexOfAsset.value]),
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
      body: SafeArea(
 | 
					      body: SafeArea(
 | 
				
			||||||
        child: PageView.builder(
 | 
					        child: PageView.builder(
 | 
				
			||||||
 | 
				
			|||||||
@ -60,7 +60,8 @@ class _$AppRouter extends RootStackRouter {
 | 
				
			|||||||
              isZoomedFunction: args.isZoomedFunction,
 | 
					              isZoomedFunction: args.isZoomedFunction,
 | 
				
			||||||
              isZoomedListener: args.isZoomedListener,
 | 
					              isZoomedListener: args.isZoomedListener,
 | 
				
			||||||
              loadPreview: args.loadPreview,
 | 
					              loadPreview: args.loadPreview,
 | 
				
			||||||
              loadOriginal: args.loadOriginal));
 | 
					              loadOriginal: args.loadOriginal,
 | 
				
			||||||
 | 
					              showExifSheet: args.showExifSheet));
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    VideoViewerRoute.name: (routeData) {
 | 
					    VideoViewerRoute.name: (routeData) {
 | 
				
			||||||
      final args = routeData.argsAs<VideoViewerRouteArgs>();
 | 
					      final args = routeData.argsAs<VideoViewerRouteArgs>();
 | 
				
			||||||
@ -87,7 +88,9 @@ class _$AppRouter extends RootStackRouter {
 | 
				
			|||||||
      return MaterialPageX<dynamic>(
 | 
					      return MaterialPageX<dynamic>(
 | 
				
			||||||
          routeData: routeData,
 | 
					          routeData: routeData,
 | 
				
			||||||
          child: CreateAlbumPage(
 | 
					          child: CreateAlbumPage(
 | 
				
			||||||
              key: args.key, isSharedAlbum: args.isSharedAlbum));
 | 
					              key: args.key,
 | 
				
			||||||
 | 
					              isSharedAlbum: args.isSharedAlbum,
 | 
				
			||||||
 | 
					              initialAssets: args.initialAssets));
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    AssetSelectionRoute.name: (routeData) {
 | 
					    AssetSelectionRoute.name: (routeData) {
 | 
				
			||||||
      return CustomPage<AssetSelectionPageResult?>(
 | 
					      return CustomPage<AssetSelectionPageResult?>(
 | 
				
			||||||
@ -307,7 +310,8 @@ class ImageViewerRoute extends PageRouteInfo<ImageViewerRouteArgs> {
 | 
				
			|||||||
      required void Function() isZoomedFunction,
 | 
					      required void Function() isZoomedFunction,
 | 
				
			||||||
      required ValueNotifier<bool> isZoomedListener,
 | 
					      required ValueNotifier<bool> isZoomedListener,
 | 
				
			||||||
      required bool loadPreview,
 | 
					      required bool loadPreview,
 | 
				
			||||||
      required bool loadOriginal})
 | 
					      required bool loadOriginal,
 | 
				
			||||||
 | 
					      void Function()? showExifSheet})
 | 
				
			||||||
      : super(ImageViewerRoute.name,
 | 
					      : super(ImageViewerRoute.name,
 | 
				
			||||||
            path: '/image-viewer-page',
 | 
					            path: '/image-viewer-page',
 | 
				
			||||||
            args: ImageViewerRouteArgs(
 | 
					            args: ImageViewerRouteArgs(
 | 
				
			||||||
@ -318,7 +322,8 @@ class ImageViewerRoute extends PageRouteInfo<ImageViewerRouteArgs> {
 | 
				
			|||||||
                isZoomedFunction: isZoomedFunction,
 | 
					                isZoomedFunction: isZoomedFunction,
 | 
				
			||||||
                isZoomedListener: isZoomedListener,
 | 
					                isZoomedListener: isZoomedListener,
 | 
				
			||||||
                loadPreview: loadPreview,
 | 
					                loadPreview: loadPreview,
 | 
				
			||||||
                loadOriginal: loadOriginal));
 | 
					                loadOriginal: loadOriginal,
 | 
				
			||||||
 | 
					                showExifSheet: showExifSheet));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static const String name = 'ImageViewerRoute';
 | 
					  static const String name = 'ImageViewerRoute';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -332,7 +337,8 @@ class ImageViewerRouteArgs {
 | 
				
			|||||||
      required this.isZoomedFunction,
 | 
					      required this.isZoomedFunction,
 | 
				
			||||||
      required this.isZoomedListener,
 | 
					      required this.isZoomedListener,
 | 
				
			||||||
      required this.loadPreview,
 | 
					      required this.loadPreview,
 | 
				
			||||||
      required this.loadOriginal});
 | 
					      required this.loadOriginal,
 | 
				
			||||||
 | 
					      this.showExifSheet});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  final Key? key;
 | 
					  final Key? key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -350,9 +356,11 @@ class ImageViewerRouteArgs {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  final bool loadOriginal;
 | 
					  final bool loadOriginal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final void Function()? showExifSheet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  String toString() {
 | 
					  String toString() {
 | 
				
			||||||
    return 'ImageViewerRouteArgs{key: $key, heroTag: $heroTag, asset: $asset, authToken: $authToken, isZoomedFunction: $isZoomedFunction, isZoomedListener: $isZoomedListener, loadPreview: $loadPreview, loadOriginal: $loadOriginal}';
 | 
					    return 'ImageViewerRouteArgs{key: $key, heroTag: $heroTag, asset: $asset, authToken: $authToken, isZoomedFunction: $isZoomedFunction, isZoomedListener: $isZoomedListener, loadPreview: $loadPreview, loadOriginal: $loadOriginal, showExifSheet: $showExifSheet}';
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -432,24 +440,31 @@ class SearchResultRouteArgs {
 | 
				
			|||||||
/// generated route for
 | 
					/// generated route for
 | 
				
			||||||
/// [CreateAlbumPage]
 | 
					/// [CreateAlbumPage]
 | 
				
			||||||
class CreateAlbumRoute extends PageRouteInfo<CreateAlbumRouteArgs> {
 | 
					class CreateAlbumRoute extends PageRouteInfo<CreateAlbumRouteArgs> {
 | 
				
			||||||
  CreateAlbumRoute({Key? key, required bool isSharedAlbum})
 | 
					  CreateAlbumRoute(
 | 
				
			||||||
 | 
					      {Key? key, required bool isSharedAlbum, List<Asset>? initialAssets})
 | 
				
			||||||
      : super(CreateAlbumRoute.name,
 | 
					      : super(CreateAlbumRoute.name,
 | 
				
			||||||
            path: '/create-album-page',
 | 
					            path: '/create-album-page',
 | 
				
			||||||
            args: CreateAlbumRouteArgs(key: key, isSharedAlbum: isSharedAlbum));
 | 
					            args: CreateAlbumRouteArgs(
 | 
				
			||||||
 | 
					                key: key,
 | 
				
			||||||
 | 
					                isSharedAlbum: isSharedAlbum,
 | 
				
			||||||
 | 
					                initialAssets: initialAssets));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static const String name = 'CreateAlbumRoute';
 | 
					  static const String name = 'CreateAlbumRoute';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CreateAlbumRouteArgs {
 | 
					class CreateAlbumRouteArgs {
 | 
				
			||||||
  const CreateAlbumRouteArgs({this.key, required this.isSharedAlbum});
 | 
					  const CreateAlbumRouteArgs(
 | 
				
			||||||
 | 
					      {this.key, required this.isSharedAlbum, this.initialAssets});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  final Key? key;
 | 
					  final Key? key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  final bool isSharedAlbum;
 | 
					  final bool isSharedAlbum;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final List<Asset>? initialAssets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  String toString() {
 | 
					  String toString() {
 | 
				
			||||||
    return 'CreateAlbumRouteArgs{key: $key, isSharedAlbum: $isSharedAlbum}';
 | 
					    return 'CreateAlbumRouteArgs{key: $key, isSharedAlbum: $isSharedAlbum, initialAssets: $initialAssets}';
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user