mirror of
https://github.com/immich-app/immich.git
synced 2024-12-19 00:32:49 +02:00
e6c0f0e3aa
* 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),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|