fix: monter la carte une seule fois après chargement du style
Le style basculait de positron (URL) vers cartoonizeStyle() ~500 ms après le premier rendu. Ce setStyle() déclenchait une réinscription des sources/layers (react-map-gl v8 / maplibre-gl v5) qui échouait silencieusement — les bancs de sargasses devenaient invisibles. La carte est désormais montée UNE SEULE FOIS quand le style est prêt (avec timeout 4 s → fallback positron). Plus de transition post-mount, plus de race condition. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
/* ── Placeholder avant chargement du style ── */
|
||||
.smap-placeholder {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background: #3ab5e6; /* couleur océan = pas de flash blanc */
|
||||
}
|
||||
|
||||
/* ── Logo ── */
|
||||
.smap-logo {
|
||||
position: absolute;
|
||||
|
||||
@@ -154,7 +154,7 @@ export default function SargassesMap({ onSpotSelect, selectedSpotId, activeStep,
|
||||
const [spotScores, setSpotScores] = useState({});
|
||||
const [viewState, setViewState] = useState(INITIAL_VIEW);
|
||||
const [layerOpacity, setLayerOpacity] = useState(1);
|
||||
const [mapStyle, setMapStyle] = useState(FALLBACK_STYLE);
|
||||
const [mapStyle, setMapStyle] = useState(null); // null = style not yet ready
|
||||
const [dataDate, setDataDate] = useState(null);
|
||||
|
||||
const tilesOrigin = window.location.origin;
|
||||
@@ -170,12 +170,17 @@ export default function SargassesMap({ onSpotSelect, selectedSpotId, activeStep,
|
||||
.catch(() => {});
|
||||
}, []);
|
||||
|
||||
// Load cartoon map style
|
||||
// Load cartoon map style once — map is only mounted when style is ready,
|
||||
// preventing the setStyle() race condition that silently drops custom sources.
|
||||
useEffect(() => {
|
||||
fetch('https://tiles.openfreemap.org/styles/bright')
|
||||
const ctrl = new AbortController();
|
||||
const timeout = setTimeout(() => ctrl.abort(), 4000); // 4 s timeout
|
||||
fetch('https://tiles.openfreemap.org/styles/bright', { signal: ctrl.signal })
|
||||
.then(r => r.json())
|
||||
.then(style => setMapStyle(cartoonizeStyle(style)))
|
||||
.catch(() => {}); // keep positron on error
|
||||
.catch(() => setMapStyle(FALLBACK_STYLE)) // positron fallback on error/timeout
|
||||
.finally(() => clearTimeout(timeout));
|
||||
return () => ctrl.abort();
|
||||
}, []);
|
||||
|
||||
// Load coastal spots once
|
||||
@@ -221,6 +226,10 @@ export default function SargassesMap({ onSpotSelect, selectedSpotId, activeStep,
|
||||
const OBS_STYLES = makeLayerStyles(false, layerOpacity);
|
||||
const FORE_STYLES = makeLayerStyles(true, layerOpacity);
|
||||
|
||||
if (!mapStyle) {
|
||||
return <div className="smap-placeholder" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Map
|
||||
ref={mapRef}
|
||||
|
||||
Reference in New Issue
Block a user