Map tab: much bigger map with its own remembered view
Publish Container / publish (push) Successful in 2m12s
Publish Container / publish (push) Successful in 2m12s
- Map fills the screen (was a 56vh strip); timeline and details sit below it - No longer snaps back to the main-page radar's location/zoom on every refresh or tab switch; starts as a wider regional view, remembers pan/zoom, and recentres only when the location changes - New 'My location' button Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
acdcd6a2c5
commit
4f47d67a7e
4 files changed
+49
-5
No files matched your search
@@ -241,3 +241,17 @@ body:not([data-tab="conditions"]) #loading { display: none; }
|
||||
.app { padding-left: calc(var(--gutter) + env(safe-area-inset-left, 0px)); padding-right: calc(var(--gutter) + env(safe-area-inset-right, 0px)); }
|
||||
.topbar { margin-left: calc(-1 * (var(--gutter) + env(safe-area-inset-left, 0px))); margin-right: calc(-1 * (var(--gutter) + env(safe-area-inset-right, 0px))); }
|
||||
.install-dialog { margin-top: max(1rem, env(safe-area-inset-top, 0px)); }
|
||||
|
||||
/* ── Map tab: the map is the page (not a 56vh strip); timeline and details sit below it ── */
|
||||
body:not(.map-fs) #tab-unified-map .unified-map-wrap { height: auto; min-height: 0; padding: 0.7rem; gap: 0.6rem; border-radius: 16px; }
|
||||
body:not(.map-fs) #tab-unified-map .unified-map-container {
|
||||
height: max(540px, calc(100dvh - var(--topbar-h) - 250px)); border-radius: 12px;
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
body:not(.map-fs) #tab-unified-map .unified-map-container {
|
||||
height: max(460px, calc(100dvh - var(--topbar-h) - 58px - max(6px, env(safe-area-inset-bottom, 0px)) - 190px));
|
||||
}
|
||||
}
|
||||
.map-controls-header { padding-bottom: 0.5rem; gap: 0.5rem; }
|
||||
.map-recenter { font: inherit; font-size: 0.78rem; font-weight: 700; min-height: 40px; padding: 0 0.9rem; border-radius: 999px; border: 1px solid var(--border); background: var(--paper-dark); color: var(--ink); cursor: pointer; margin-left: auto; white-space: nowrap; }
|
||||
.map-recenter:hover { border-color: var(--accent); color: var(--accent); }
|
||||
@@ -378,6 +378,33 @@ function updateRadar(city, outlook) {
|
||||
if (map.isStyleLoaded()) apply(); else map.once('idle', apply);
|
||||
}
|
||||
|
||||
|
||||
// ── Map tab: independent, remembered view (not tied to the main-page radar) ──
|
||||
let mapCenteredFor = null;
|
||||
const mapCityKey = (c) => `${(+c.latitude).toFixed(2)},${(+c.longitude).toFixed(2)}`;
|
||||
function centerMap(city, force) {
|
||||
const m = typeof mapsOverview !== 'undefined' ? mapsOverview?.map : null;
|
||||
if (!m || city?.latitude == null) return;
|
||||
const key = mapCityKey(city);
|
||||
if (!force && mapCenteredFor === key) return; // keep wherever the user panned/zoomed to
|
||||
let saved = null;
|
||||
try { saved = JSON.parse(localStorage.getItem('mapView') || 'null'); } catch {}
|
||||
if (!force && !mapCenteredFor && saved && saved.key === key && Number.isFinite(saved.zoom)) m.jumpTo({ center: [saved.lng, saved.lat], zoom: saved.zoom });
|
||||
else mapsOverview.panTo(city.latitude, city.longitude, force ? 7 : 5); // wider regional view than the main-page radar
|
||||
mapCenteredFor = key;
|
||||
}
|
||||
(() => {
|
||||
const m = typeof mapsOverview !== 'undefined' ? mapsOverview?.map : null;
|
||||
if (!m) return;
|
||||
let t = 0;
|
||||
m.on('moveend', () => {
|
||||
if (!mapCenteredFor) return;
|
||||
clearTimeout(t);
|
||||
t = setTimeout(() => { try { const c = m.getCenter(); localStorage.setItem('mapView', JSON.stringify({ key: mapCenteredFor, lng: c.lng, lat: c.lat, zoom: m.getZoom() })); } catch {} }, 400);
|
||||
});
|
||||
$('map-recenter-btn')?.addEventListener('click', () => { if (state.currentCity) centerMap(state.currentCity, true); });
|
||||
})();
|
||||
|
||||
// ── Public hooks ─────────────────────────────────────────────────────────────
|
||||
let lastOutlook = null;
|
||||
window.AppUI = {
|
||||
@@ -399,6 +426,7 @@ window.AppUI = {
|
||||
if (state.currentAir) renderAqi(state.currentAir);
|
||||
if (stationFresh) renderStationContext();
|
||||
},
|
||||
centerMap,
|
||||
onAir(air) { renderAqi(air); },
|
||||
refreshFx() { const c = $('sky-fx'); if (c && fx.kind) { cancelAnimationFrame(fx.raf); fxResize(c); fxSeed(fx.kind); if (fx.parts.length) fxFrame(performance.now()); } },
|
||||
onStation() { syncTopbarLocation(); renderStationContext(); },
|
||||
|
||||
+5
-4
@@ -1281,8 +1281,9 @@ function refreshMapsOverview() {
|
||||
|
||||
if (!state.currentCity) return;
|
||||
|
||||
const zoom = mapsOverview.map.getZoom ? mapsOverview.map.getZoom() : 6;
|
||||
mapsOverview.panTo(state.currentCity.latitude, state.currentCity.longitude, zoom || 6);
|
||||
// Keep the user's own pan/zoom; only (re)centre when the location changes
|
||||
if (window.AppUI && window.AppUI.centerMap) window.AppUI.centerMap(state.currentCity);
|
||||
else mapsOverview.panTo(state.currentCity.latitude, state.currentCity.longitude, mapsOverview.map.getZoom ? mapsOverview.map.getZoom() : 6);
|
||||
|
||||
clearLightningMarkers();
|
||||
clearWindArrows();
|
||||
@@ -1599,8 +1600,8 @@ function renderWeather(data, city) {
|
||||
|
||||
radarEmbed.panTo(city.latitude, city.longitude, 6);
|
||||
radarFull.panTo(city.latitude, city.longitude, 6);
|
||||
const mapZoom = mapsOverview?.map?.getZoom ? mapsOverview.map.getZoom() : 6;
|
||||
mapsOverview.panTo(city.latitude, city.longitude, mapZoom || 6);
|
||||
if (window.AppUI && window.AppUI.centerMap) window.AppUI.centerMap(city);
|
||||
else mapsOverview.panTo(city.latitude, city.longitude, (mapsOverview?.map?.getZoom ? mapsOverview.map.getZoom() : 6) || 6);
|
||||
if (mapsWindEl) mapsWindEl.textContent = `${speedDisplay(c.wind_speed_10m)} ${speedUnit()} ${compassDir(c.wind_direction_10m)}`;
|
||||
updateSourceLocation(city);
|
||||
updateShareUrl(city);
|
||||
|
||||
@@ -259,6 +259,7 @@
|
||||
<option value="light">Light</option>
|
||||
<option value="satellite">Satellite</option>
|
||||
</select>
|
||||
<button id="map-recenter-btn" class="map-recenter" type="button" title="Back to my location">📍 My location</button>
|
||||
<button id="map-fullscreen-btn" class="radar-btn radar-fs-btn" title="Fullscreen">⛶</button>
|
||||
</div>
|
||||
|
||||
@@ -351,7 +352,7 @@
|
||||
|
||||
<!-- Main Map -->
|
||||
<div class="unified-map-shell">
|
||||
<div id="unified-map" class="unified-map-container" style="height:56vh; min-height:420px;"></div>
|
||||
<div id="unified-map" class="unified-map-container"></div>
|
||||
<div class="map-overlay-readouts" id="map-overlay-readouts">
|
||||
<span class="map-readout-chip" id="overlay-temp">Temp --</span>
|
||||
<span class="map-readout-chip" id="overlay-aqi">AQI --</span>
|
||||
|
||||
Reference in new issue
Block a user