fix(web): fix tactical map style.json and implement keep-alive views for instant tab switching
This commit is contained in:
+40
-13
@@ -75,25 +75,52 @@ function ViewNav({ hash }: { hash: string }) {
|
||||
|
||||
function Root() {
|
||||
const [hash, setHash] = useState(window.location.hash || '#tactical')
|
||||
useEffect(() => {
|
||||
const on = () => setHash(window.location.hash || '#tactical')
|
||||
window.addEventListener('hashchange', on)
|
||||
return () => window.removeEventListener('hashchange', on)
|
||||
}, [])
|
||||
|
||||
const view =
|
||||
hash === '#tactical' || hash === '#military' ? <TacticalDefenseView /> :
|
||||
hash === '#executive' || hash === '#pitch' ? <ExecutiveShowcase /> :
|
||||
hash === '#compare' ? <CompareView /> :
|
||||
hash === '#review' ? <IntelligenceDashboard /> :
|
||||
<App />
|
||||
useEffect(() => {
|
||||
const on = () => {
|
||||
const h = window.location.hash || '#tactical';
|
||||
setHash(h);
|
||||
// Trigger a resize event to ensure MapLibre maps adapt to visibility changes instantly
|
||||
setTimeout(() => {
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
}, 50);
|
||||
};
|
||||
window.addEventListener('hashchange', on);
|
||||
return () => window.removeEventListener('hashchange', on);
|
||||
}, []);
|
||||
|
||||
const isTactical = hash === '#tactical' || hash === '#military';
|
||||
const isExecutive = hash === '#executive' || hash === '#pitch';
|
||||
const isCompare = hash === '#compare';
|
||||
const isReview = hash === '#review';
|
||||
const isMap = !isTactical && !isExecutive && !isCompare && !isReview;
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewNav hash={hash} />
|
||||
{view}
|
||||
|
||||
{/* Keep-Alive Persistent Views: Preserves Map Instances and GPU Tile Caches across Tab switches */}
|
||||
<div style={{ display: isTactical ? 'block' : 'none', width: '100vw', height: '100vh', position: 'absolute', top: 0, left: 0 }}>
|
||||
<TacticalDefenseView />
|
||||
</div>
|
||||
|
||||
<div style={{ display: isExecutive ? 'block' : 'none', width: '100vw', height: '100vh', position: 'absolute', top: 0, left: 0 }}>
|
||||
<ExecutiveShowcase />
|
||||
</div>
|
||||
|
||||
<div style={{ display: isCompare ? 'block' : 'none', width: '100vw', height: '100vh', position: 'absolute', top: 0, left: 0 }}>
|
||||
<CompareView />
|
||||
</div>
|
||||
|
||||
<div style={{ display: isReview ? 'block' : 'none', width: '100vw', height: '100vh', position: 'absolute', top: 0, left: 0 }}>
|
||||
<IntelligenceDashboard />
|
||||
</div>
|
||||
|
||||
<div style={{ display: isMap ? 'block' : 'none', width: '100vw', height: '100vh', position: 'absolute', top: 0, left: 0 }}>
|
||||
<App />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||
|
||||
@@ -90,7 +90,7 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
|
||||
const initialMap = new maplibregl.Map({
|
||||
container: mapContainer.current,
|
||||
style: '/style-dark.json',
|
||||
style: '/style.json',
|
||||
center: [35.9106, 31.9539],
|
||||
zoom: 11,
|
||||
pitch: 35,
|
||||
@@ -99,6 +99,11 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
|
||||
map.current = initialMap;
|
||||
|
||||
const handleResize = () => {
|
||||
if (initialMap) initialMap.resize();
|
||||
};
|
||||
window.addEventListener('resize', handleResize);
|
||||
|
||||
initialMap.on('mousemove', (e) => {
|
||||
setCursorPos({
|
||||
lat: Number(e.lngLat.lat.toFixed(5)),
|
||||
|
||||
Reference in New Issue
Block a user