1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-19 00:32:49 +02:00
immich/mobile/lib/modules/map/widgets/map_bottom_sheet.dart
shenlong e6c0f0e3aa
refactor(mobile): maplibre (#6087)
* 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>
2024-01-15 09:26:13 -06:00

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),
),
),
],
);
}
}