mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 07:40:59 +00:00
f51a64017d
MapViewAuto took props: any and the Leaflet MapView destructured any, so a prop one renderer learned and the other never heard of went unnoticed. components/Map/mapViewContract.ts holds MapViewProps, derived from the GL renderer's props and what the callers pass; MapView and the GL bindings in glLazy declare satisfies ComponentType against it, and the GL renderer extends it with its engine. The file imports types only, so check:gl-split is not affected. Types only, no runtime change. The types show two known gaps, recorded in the contract rather than papered over: onMapReady is called by the GL renderer only, and callers pass pins without trip_id (assignment and collection places) while both renderers type their pins as Place; MapViewAuto bridges the latter with one commented cast.
57 lines
3.1 KiB
TypeScript
57 lines
3.1 KiB
TypeScript
import { Suspense } from 'react'
|
|
import { AlertTriangle, Clock, Info } from 'lucide-react'
|
|
import { Tooltip } from '../shared/Tooltip'
|
|
import { useSettingsStore } from '../../store/settingsStore'
|
|
import { MapView } from './MapView'
|
|
import ErrorBoundary from '../shared/ErrorBoundary'
|
|
import { MapViewGLMapbox, MapViewGLMaplibre } from './glLazy'
|
|
import { useRoadtripHazards } from './useRoadtripHazards'
|
|
import { useTranslation } from '../../i18n/TranslationContext'
|
|
import type { MapViewAutoProps, MapViewProps } from './mapViewContract'
|
|
|
|
// Auto-selects the map renderer based on user settings. Keeps the existing
|
|
// Leaflet MapView untouched so the Mapbox GL variant can mature iteratively
|
|
// behind a toggle. Atlas is not affected — it imports Leaflet directly.
|
|
//
|
|
// Offline maps: only the Leaflet renderer supports full pre-download (raster
|
|
// tiles via sync/tilePrefetcher.ts). GL maps are best-effort offline — their
|
|
// vector tiles are cached opportunistically by the Service Worker as you view
|
|
// them online (see the GL tile rules in vite.config.js), not prefetched.
|
|
export function MapViewAuto(props: MapViewAutoProps) {
|
|
const { t } = useTranslation()
|
|
const hazards = useRoadtripHazards(props.tripId, !!props.clusterLoosely)
|
|
// `dawarichTrack` arrives as a prop rather than being fetched here: the pill
|
|
// that switches it on lives at page level and needs the load status, so the
|
|
// fetch sits in useTripPlanner and both shells read the same one.
|
|
// The one cast between what callers pass and what the renderers type: pins
|
|
// without trip_id (see MapViewAutoProps). Neither renderer reads trip_id.
|
|
const mapProps = { ...props, hazards: hazards.feed?.hazards } as MapViewProps
|
|
const provider = useSettingsStore(s => s.settings.map_provider)
|
|
const token = useSettingsStore(s => s.settings.mapbox_access_token)
|
|
// Fall back to Leaflet when Mapbox is selected but no token is set,
|
|
// so trip planner never shows an empty map due to a missing token.
|
|
const glProvider = provider === 'maplibre-gl' ? 'maplibre-gl'
|
|
: provider === 'mapbox-gl' && token ? 'mapbox-gl'
|
|
: null
|
|
// One chunk per engine: picking the binding here is what keeps mapbox-gl and
|
|
// maplibre-gl out of each other's downloads.
|
|
const MapViewGL = glProvider === 'maplibre-gl' ? MapViewGLMaplibre : MapViewGLMapbox
|
|
if (glProvider) {
|
|
// Render the previous Leaflet map as the fallback so there's no blank flash
|
|
// while the GL chunk loads on first use.
|
|
return (
|
|
// Outside the Suspense on purpose: Suspense handles the pending promise,
|
|
// a rejected one (chunk gone after a deploy) throws past it. Falling back
|
|
// to Leaflet keeps a usable map instead of an error card.
|
|
// resetKeys: with two engine chunks, a failure under one provider must not
|
|
// keep showing Leaflet after the user switches to the other.
|
|
<ErrorBoundary boundaryId="map:gl" resetKeys={[glProvider]} fallback={<MapView {...mapProps} />}>
|
|
<Suspense fallback={<MapView {...mapProps} />}>
|
|
<MapViewGL {...mapProps} glProvider={glProvider} />
|
|
</Suspense>
|
|
</ErrorBoundary>
|
|
)
|
|
}
|
|
return <MapView {...mapProps} />
|
|
}
|