mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-30 18:35:00 -04:00 
			
		
		
		
	* chore: maplibre gl pubspec * refactor(wip): maplibre for maps * refactor(wip): dual pane + location button * chore: remove flutter_map and deps * refactor(wip): map zoom to location * refactor: location picker * open gallery_viewer on marker tap * remove detectScaleGesture param * test: debounce and throttle * chore: rename get location method * feat(mobile): Adds gps locator to map prompt for easy geolocation (#6282) * Refactored get gps coords * Use var for linter's sake, should handle errors better * Cleanup * Fix linter issues * chore(dep): update maplibre to official lib --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Joshua Herrera <joshua.herrera227@gmail.com>
		
			
				
	
	
		
			98 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'package:flutter/material.dart';
 | |
| import 'package:flutter_hooks/flutter_hooks.dart';
 | |
| import 'package:hooks_riverpod/hooks_riverpod.dart';
 | |
| import 'package:immich_mobile/extensions/build_context_extensions.dart';
 | |
| import 'package:immich_mobile/modules/map/models/map_event.model.dart';
 | |
| import 'package:immich_mobile/modules/map/widgets/map_asset_grid.dart';
 | |
| import 'package:immich_mobile/shared/models/asset.dart';
 | |
| import 'package:immich_mobile/utils/draggable_scroll_controller.dart';
 | |
| 
 | |
| class MapBottomSheet extends HookConsumerWidget {
 | |
|   final Stream<MapEvent> mapEventStream;
 | |
|   final Function(String)? onGridAssetChanged;
 | |
|   final Function(String)? onZoomToAsset;
 | |
|   final Function()? onZoomToLocation;
 | |
|   final Function(bool, Set<Asset>)? onAssetsSelected;
 | |
|   final ValueNotifier<Set<Asset>> selectedAssets;
 | |
| 
 | |
|   const MapBottomSheet({
 | |
|     required this.mapEventStream,
 | |
|     this.onGridAssetChanged,
 | |
|     this.onZoomToAsset,
 | |
|     this.onAssetsSelected,
 | |
|     this.onZoomToLocation,
 | |
|     required this.selectedAssets,
 | |
|     super.key,
 | |
|   });
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context, WidgetRef ref) {
 | |
|     const sheetMinExtent = 0.1;
 | |
|     final sheetController = useDraggableScrollController();
 | |
|     final bottomSheetOffset = useValueNotifier(sheetMinExtent);
 | |
|     final isBottomSheetOpened = useRef(false);
 | |
| 
 | |
|     void handleMapEvents(MapEvent event) async {
 | |
|       if (event is MapCloseBottomSheet) {
 | |
|         sheetController.animateTo(
 | |
|           0.1,
 | |
|           duration: const Duration(milliseconds: 200),
 | |
|           curve: Curves.linearToEaseOut,
 | |
|         );
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     useOnStreamChange<MapEvent>(mapEventStream, onData: handleMapEvents);
 | |
| 
 | |
|     bool onScrollNotification(DraggableScrollableNotification notification) {
 | |
|       isBottomSheetOpened.value =
 | |
|           notification.extent > (notification.maxExtent * 0.9);
 | |
|       bottomSheetOffset.value = notification.extent;
 | |
|       // do not bubble
 | |
|       return true;
 | |
|     }
 | |
| 
 | |
|     return Stack(
 | |
|       children: [
 | |
|         NotificationListener<DraggableScrollableNotification>(
 | |
|           onNotification: onScrollNotification,
 | |
|           child: DraggableScrollableSheet(
 | |
|             controller: sheetController,
 | |
|             minChildSize: sheetMinExtent,
 | |
|             maxChildSize: 0.5,
 | |
|             initialChildSize: sheetMinExtent,
 | |
|             snap: true,
 | |
|             shouldCloseOnMinExtent: false,
 | |
|             builder: (ctx, scrollController) => MapAssetGrid(
 | |
|               controller: scrollController,
 | |
|               mapEventStream: mapEventStream,
 | |
|               selectedAssets: selectedAssets,
 | |
|               onAssetsSelected: onAssetsSelected,
 | |
|               // Do not bother with the event if the bottom sheet is not user scrolled
 | |
|               onGridAssetChanged: (assetId) => isBottomSheetOpened.value
 | |
|                   ? onGridAssetChanged?.call(assetId)
 | |
|                   : null,
 | |
|               onZoomToAsset: onZoomToAsset,
 | |
|             ),
 | |
|           ),
 | |
|         ),
 | |
|         ValueListenableBuilder(
 | |
|           valueListenable: bottomSheetOffset,
 | |
|           builder: (ctx, value, child) => Positioned(
 | |
|             right: 0,
 | |
|             bottom: context.height * (value + 0.02),
 | |
|             child: child!,
 | |
|           ),
 | |
|           child: ElevatedButton(
 | |
|             onPressed: onZoomToLocation,
 | |
|             style: ElevatedButton.styleFrom(
 | |
|               shape: const CircleBorder(),
 | |
|             ),
 | |
|             child: const Icon(Icons.my_location),
 | |
|           ),
 | |
|         ),
 | |
|       ],
 | |
|     );
 | |
|   }
 | |
| }
 |