mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-31 10:49:11 -04:00 
			
		
		
		
	* Draggable sheet in asset viewer page * Minor improvements * Fix display bug * Fix some styling Co-authored-by: Alex <alex.tran1502@gmail.com>
		
			
				
	
	
		
			204 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			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:hooks_riverpod/hooks_riverpod.dart';
 | |
| import 'package:immich_mobile/constants/hive_box.dart';
 | |
| import 'package:immich_mobile/modules/home/ui/delete_diaglog.dart';
 | |
| import 'package:immich_mobile/shared/ui/drag_sheet.dart';
 | |
| import 'package:immich_mobile/utils/image_url_builder.dart';
 | |
| import 'package:openapi/api.dart';
 | |
| 
 | |
| class ControlBottomAppBar extends ConsumerWidget {
 | |
|   final Function onShare;
 | |
|   final Function onDelete;
 | |
|   final Function(AlbumResponseDto album) onAddToAlbum;
 | |
|   final void Function() onCreateNewAlbum;
 | |
| 
 | |
|   final List<AlbumResponseDto> albums;
 | |
| 
 | |
|   const ControlBottomAppBar({
 | |
|     Key? key,
 | |
|     required this.onShare,
 | |
|     required this.onDelete,
 | |
|     required this.albums,
 | |
|     required this.onAddToAlbum,
 | |
|     required this.onCreateNewAlbum,
 | |
|   }) : super(key: key);
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context, WidgetRef ref) {
 | |
|     Widget renderActionButtons() {
 | |
|       return Row(
 | |
|         children: [
 | |
|           ControlBoxButton(
 | |
|             iconData: Icons.ios_share_rounded,
 | |
|             label: "control_bottom_app_bar_share".tr(),
 | |
|             onPressed: () {
 | |
|               onShare();
 | |
|             },
 | |
|           ),
 | |
|           ControlBoxButton(
 | |
|             iconData: Icons.delete_outline_rounded,
 | |
|             label: "control_bottom_app_bar_delete".tr(),
 | |
|             onPressed: () {
 | |
|               showDialog(
 | |
|                 context: context,
 | |
|                 builder: (BuildContext context) {
 | |
|                   return DeleteDialog(
 | |
|                     onDelete: onDelete,
 | |
|                   );
 | |
|                 },
 | |
|               );
 | |
|             },
 | |
|           ),
 | |
|         ],
 | |
|       );
 | |
|     }
 | |
| 
 | |
|     Widget renderAlbums() {
 | |
|       Widget renderAlbum(AlbumResponseDto album) {
 | |
|         final box = Hive.box(userInfoBox);
 | |
| 
 | |
|         return Padding(
 | |
|           padding: const EdgeInsets.only(left: 8.0),
 | |
|           child: GestureDetector(
 | |
|             onTap: () => onAddToAlbum(album),
 | |
|             child: Container(
 | |
|               width: 112,
 | |
|               padding: const EdgeInsets.all(6),
 | |
|               child: Column(
 | |
|                 crossAxisAlignment: CrossAxisAlignment.start,
 | |
|                 children: [
 | |
|                   ClipRRect(
 | |
|                     borderRadius: BorderRadius.circular(8),
 | |
|                     child: CachedNetworkImage(
 | |
|                       width: 100,
 | |
|                       height: 100,
 | |
|                       fit: BoxFit.cover,
 | |
|                       imageUrl: getAlbumThumbnailUrl(album),
 | |
|                       httpHeaders: {
 | |
|                         "Authorization": "Bearer ${box.get(accessTokenKey)}"
 | |
|                       },
 | |
|                       cacheKey: getAlbumThumbNailCacheKey(album),
 | |
|                     ),
 | |
|                   ),
 | |
|                   Padding(
 | |
|                     padding: const EdgeInsets.only(top: 12),
 | |
|                     child: Text(
 | |
|                       album.albumName,
 | |
|                       style: const TextStyle(
 | |
|                         fontWeight: FontWeight.bold,
 | |
|                         fontSize: 12.0,
 | |
|                       ),
 | |
|                     ),
 | |
|                   ),
 | |
|                 ],
 | |
|               ),
 | |
|             ),
 | |
|           ),
 | |
|         );
 | |
|       }
 | |
| 
 | |
|       return SizedBox(
 | |
|         height: 200,
 | |
|         child: ListView.builder(
 | |
|           scrollDirection: Axis.horizontal,
 | |
|           itemBuilder: (buildContext, i) => renderAlbum(albums[i]),
 | |
|           itemCount: albums.length,
 | |
|         ),
 | |
|       );
 | |
|     }
 | |
| 
 | |
|     return DraggableScrollableSheet(
 | |
|       initialChildSize: 0.30,
 | |
|       minChildSize: 0.15,
 | |
|       maxChildSize: 0.57,
 | |
|       snap: true,
 | |
|       builder: (
 | |
|         BuildContext context,
 | |
|         ScrollController scrollController,
 | |
|       ) {
 | |
|         return SingleChildScrollView(
 | |
|           controller: scrollController,
 | |
|           child: Card(
 | |
|             elevation: 12.0,
 | |
|             shape: const RoundedRectangleBorder(
 | |
|               borderRadius: BorderRadius.only(
 | |
|                 topLeft: Radius.circular(12),
 | |
|                 topRight: Radius.circular(12),
 | |
|               ),
 | |
|             ),
 | |
|             margin: const EdgeInsets.all(0),
 | |
|             child: Container(
 | |
|               decoration: const BoxDecoration(
 | |
|                 borderRadius: BorderRadius.only(
 | |
|                   topLeft: Radius.circular(12),
 | |
|                   topRight: Radius.circular(12),
 | |
|                 ),
 | |
|               ),
 | |
|               child: Column(
 | |
|                 children: <Widget>[
 | |
|                   const SizedBox(height: 12),
 | |
|                   const CustomDraggingHandle(),
 | |
|                   const SizedBox(height: 12),
 | |
|                   renderActionButtons(),
 | |
|                   const Divider(
 | |
|                     indent: 16,
 | |
|                     endIndent: 16,
 | |
|                     thickness: 1,
 | |
|                   ),
 | |
|                   AddToAlbumTitleRow(
 | |
|                     onCreateNewAlbum: () => onCreateNewAlbum(),
 | |
|                   ),
 | |
|                   renderAlbums(),
 | |
|                   const SizedBox(height: 200),
 | |
|                 ],
 | |
|               ),
 | |
|             ),
 | |
|           ),
 | |
|         );
 | |
|       },
 | |
|     );
 | |
|   }
 | |
| }
 | |
| 
 | |
| class AddToAlbumTitleRow extends StatelessWidget {
 | |
|   const AddToAlbumTitleRow({
 | |
|     super.key,
 | |
|     required this.onCreateNewAlbum,
 | |
|   });
 | |
| 
 | |
|   final VoidCallback onCreateNewAlbum;
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) {
 | |
|     return Padding(
 | |
|       padding: const EdgeInsets.symmetric(horizontal: 16),
 | |
|       child: Row(
 | |
|         mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | |
|         children: [
 | |
|           const Text(
 | |
|             "control_bottom_app_bar_add_to_album",
 | |
|             style: TextStyle(
 | |
|               fontSize: 14,
 | |
|               fontWeight: FontWeight.bold,
 | |
|             ),
 | |
|           ).tr(),
 | |
|           TextButton(
 | |
|             onPressed: onCreateNewAlbum,
 | |
|             child: Text(
 | |
|               "control_bottom_app_bar_create_new_album",
 | |
|               style: TextStyle(
 | |
|                 color: Theme.of(context).primaryColor,
 | |
|                 fontWeight: FontWeight.bold,
 | |
|                 fontSize: 14,
 | |
|               ),
 | |
|             ).tr(),
 | |
|           ),
 | |
|         ],
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| }
 |