40 lines
1.4 KiB
TypeScript
40 lines
1.4 KiB
TypeScript
"use client";
|
|
|
|
import type { Map as MapLibreMap } from "maplibre-gl";
|
|
import { useEffect, useRef, useSyncExternalStore, type RefObject } from "react";
|
|
import { getResponsiveWorkbenchPadding } from "../map/camera";
|
|
import { WorkbenchMapController } from "../map/workbench-map-controller";
|
|
|
|
export function useWorkbenchMapController({
|
|
mapRef,
|
|
mapReady,
|
|
leftPanelOpen,
|
|
rightPanelOpen
|
|
}: {
|
|
mapRef: RefObject<MapLibreMap | null>;
|
|
mapReady: boolean;
|
|
leftPanelOpen: boolean;
|
|
rightPanelOpen: boolean;
|
|
}) {
|
|
const valuesRef = useRef({ mapReady, leftPanelOpen, rightPanelOpen });
|
|
valuesRef.current = { mapReady, leftPanelOpen, rightPanelOpen };
|
|
const controllerRef = useRef<WorkbenchMapController | null>(null);
|
|
if (!controllerRef.current) {
|
|
controllerRef.current = new WorkbenchMapController({
|
|
getMap: () => mapRef.current,
|
|
isReady: () => valuesRef.current.mapReady,
|
|
getPadding: () => {
|
|
const map = mapRef.current;
|
|
return map
|
|
? getResponsiveWorkbenchPadding(map, valuesRef.current.leftPanelOpen, valuesRef.current.rightPanelOpen)
|
|
: { top: 48, right: 48, bottom: 48, left: 48 };
|
|
}
|
|
});
|
|
}
|
|
|
|
const controller = controllerRef.current;
|
|
const state = useSyncExternalStore(controller.subscribe, controller.getSnapshot, controller.getSnapshot);
|
|
useEffect(() => () => controller.destroy(), [controller]);
|
|
return { controller, state };
|
|
}
|