perfect-postcode/frontend/src/hooks/useUrlSync.ts
2026-05-31 13:17:11 +01:00

67 lines
1.9 KiB
TypeScript

import { useEffect, useRef } from 'react';
import type { FeatureMeta, FeatureFilters } from '../types';
import { stateToParams } from '../lib/url-state';
import type { OverlayId } from '../lib/overlays';
import type { BasemapId } from '../lib/basemaps';
import type { TravelTimeEntry } from './useTravelTime';
const URL_DEBOUNCE_MS = 300;
export function useUrlSync(
currentView: { latitude: number; longitude: number; zoom: number } | null,
filters: FeatureFilters,
features: FeatureMeta[],
selectedPOICategories: Set<string>,
rightPaneTab: 'properties' | 'area',
travelTimeEntries?: TravelTimeEntry[],
share?: string,
selectedOverlays?: Set<OverlayId>,
basemap?: BasemapId,
selectedCrimeTypes?: Set<string>,
selectedPostcode?: string,
colorOpacity?: number
) {
const urlDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
useEffect(() => {
if (urlDebounceRef.current) {
clearTimeout(urlDebounceRef.current);
}
urlDebounceRef.current = setTimeout(() => {
const params = stateToParams(
currentView,
filters,
features,
selectedPOICategories,
rightPaneTab,
travelTimeEntries,
share,
selectedOverlays,
basemap,
selectedCrimeTypes,
selectedPostcode,
colorOpacity
);
const search = params.toString();
const newUrl = search ? `${window.location.pathname}?${search}` : window.location.pathname;
window.history.replaceState({ ...window.history.state }, '', newUrl);
}, URL_DEBOUNCE_MS);
return () => {
if (urlDebounceRef.current) clearTimeout(urlDebounceRef.current);
};
}, [
currentView,
filters,
features,
selectedPOICategories,
rightPaneTab,
travelTimeEntries,
share,
selectedOverlays,
basemap,
selectedCrimeTypes,
selectedPostcode,
colorOpacity,
]);
}