Update html/map.ejs
This commit is contained in:
parent
728db38dde
commit
b7a954a3b3
130
html/map.ejs
130
html/map.ejs
@ -1,4 +1,3 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
@ -13,7 +12,10 @@
|
||||
--vh:100vh;--pad:12px;--radius:14px;--fg:#fff;--bg:rgba(0,0,0,.6);--glass:blur(12px);
|
||||
--marker-size:20px;--marker-color:#e53935;--marker-ring:rgba(229,57,53,.35);--ring-width:3px;
|
||||
--panel:rgba(0,0,0,.85);--accent:#0ea5e9;--chip:#111;--chipb:#222;--tip:#888;
|
||||
--surface:#0b0b0b;--border:#333
|
||||
--surface:#0b0b0b;--border:#333;
|
||||
--sidebar-w:320px; /* default; will be overridden from prefs */
|
||||
--sidebar-min:260px;
|
||||
--sidebar-max:60vw;
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
html,body{height:100%;margin:0}
|
||||
@ -77,18 +79,34 @@
|
||||
.settings textarea{width:100%;min-height:120px;border-radius:10px;border:1px solid var(--border);background:#0a0a0a;color:#eee;padding:8px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
|
||||
.settings .about{font-size:13px;opacity:.92;line-height:1.5}
|
||||
|
||||
/* Desktop layout — simplified & clean */
|
||||
/* Desktop layout — with resizable, scrollable sidebar */
|
||||
.desktop .bar{grid-column:2}
|
||||
.desktop .app{grid-template-columns:320px 1fr;grid-template-rows:auto 1fr}
|
||||
.desktop .sidebar{position:fixed;left:0;top:0;bottom:0;width:320px;background:var(--panel);border-right:1px solid var(--border);display:flex;flex-direction:column;gap:12px;padding:12px;z-index:9}
|
||||
.desktop .app{grid-template-columns:var(--sidebar-w) 1fr;grid-template-rows:auto 1fr}
|
||||
.desktop .sidebar{
|
||||
position:fixed;left:0;top:0;bottom:0;
|
||||
width:var(--sidebar-w);
|
||||
min-width:var(--sidebar-min);max-width:var(--sidebar-max);
|
||||
background:var(--panel);border-right:1px solid var(--border);
|
||||
display:flex;flex-direction:column;gap:12px;padding:12px;z-index:9;
|
||||
overflow:auto; /* scrollable */
|
||||
}
|
||||
.desktop .sidecard{border:1px solid #222;border-radius:12px;overflow:hidden}
|
||||
.desktop .sidecard header{padding:10px 12px;border-bottom:1px solid #222;font-weight:600;display:flex;justify-content:space-between;align-items:center}
|
||||
.desktop .sidecard .row{display:flex;gap:8px;align-items:center;padding:8px 12px;border-top:1px solid #111}
|
||||
.desktop .sidecard .row{display:flex;gap:8px;align-items:center;padding:8px 12px;border-top:1px solid #111;flex-wrap:wrap}
|
||||
.desktop .sidecard .row:first-of-type{border-top:0}
|
||||
.desktop .sidecard .hint{font-size:12px;opacity:.75;padding:8px 12px}
|
||||
.desktop .mapwrap{grid-column:2}
|
||||
/* Suppress popovers on desktop (sidebar replaces them) */
|
||||
/* Suppress popovers and dock on desktop (sidebar replaces them) */
|
||||
.desktop .menu,.desktop .pins,.desktop .settings{display:none !important}
|
||||
.desktop .dock{display:none !important}
|
||||
|
||||
/* Sidebar resizer handle */
|
||||
.desktop .side-resizer{
|
||||
position:fixed; top:0; bottom:0; left:calc(var(--sidebar-w) - 4px);
|
||||
width:8px; cursor:col-resize; z-index:10;
|
||||
background:linear-gradient(to right, transparent 0 6px, #ffffff14 6px 7px, transparent 7px 100%);
|
||||
}
|
||||
.side-resizer.dragging{background:linear-gradient(to right, transparent 0 6px, #ffffff33 6px 7px, transparent 7px 100%)}
|
||||
|
||||
/* Pro detail rows subtly toned down */
|
||||
.pro-only{display:none;}
|
||||
@ -292,8 +310,8 @@
|
||||
const accentColorEl=S("#accentColor"), accentResetEl=S("#accentReset");
|
||||
const customCSSEl=S("#customCSS"), applyCSSEl=S("#applyCSS"), clearCSSEl=S("#clearCSS");
|
||||
|
||||
/* Pro mode */
|
||||
const PREFS_KEY="pokemaps_prefs_v6";
|
||||
/* Prefs */
|
||||
const PREFS_KEY="pokemaps_prefs_v7"; // bump version for new sidebar width
|
||||
const LS_PINS="pokemaps_pins_v1";
|
||||
const LS_SEARCH="pokemaps_search_hist_v1";
|
||||
|
||||
@ -391,13 +409,15 @@
|
||||
if(!("geolocation" in navigator)){ alert("Geolocation not supported."); return }
|
||||
if(watchId!==null) return;
|
||||
followBtn && (followBtn.textContent="🛰️ Following");
|
||||
const d_follow = document.querySelector("#d_follow");
|
||||
d_follow && (d_follow.textContent="Following");
|
||||
watchId = navigator.geolocation.watchPosition(
|
||||
pos=>{ centerOn(pos.coords.latitude,pos.coords.longitude,{push:false}) },
|
||||
_=>stopFollow(),
|
||||
{enableHighAccuracy:true,timeout:15000,maximumAge:1000}
|
||||
)
|
||||
};
|
||||
const stopFollow=()=>{ if(watchId!==null){ navigator.geolocation.clearWatch(watchId); watchId=null } ; followBtn && (followBtn.textContent="🛰️ Follow") };
|
||||
const stopFollow=()=>{ if(watchId!==null){ navigator.geolocation.clearWatch(watchId); watchId=null } ; followBtn && (followBtn.textContent="🛰️ Follow"); const d_follow=document.querySelector("#d_follow"); d_follow && (d_follow.textContent="Follow") };
|
||||
const toggleFollow=()=> watchId===null ? startFollow() : stopFollow();
|
||||
|
||||
const copyLink=async()=>{ try{ await navigator.clipboard.writeText(appURL(state)); alert("Link copied!") }catch{ alert("Could not copy.") } };
|
||||
@ -429,7 +449,6 @@
|
||||
|
||||
const renderSuggest=(items, term="")=>{
|
||||
if(!sug) return;
|
||||
// keep the sticky head; rebuild the rest
|
||||
const head = sug.querySelector(".head");
|
||||
sug.innerHTML="";
|
||||
if(head) sug.appendChild(head);
|
||||
@ -609,7 +628,7 @@
|
||||
|
||||
toggleCoords.onchange=()=>{ prefs.showCoords = toggleCoords.checked; coordsEl.style.display = prefs.showCoords ? "block" : "none"; savePrefs() };
|
||||
coordFmtEl.onchange=()=>{ prefs.coordFmt = coordFmtEl.value; savePrefs() };
|
||||
coordPrecEl.oninput=()=>{ prefs.prec = +coordPrecEl.value; coordPrecVal.textContent=String(prefs.prec); savePrefs() };
|
||||
coordPrecEl.oninput=()=>{ prefs.prec = +coordPrecEl.value; coordPrecVal.textContent = String(prefs.prec); savePrefs() };
|
||||
autoFollowEl.onchange=()=>{ prefs.autoFollow = autoFollowEl.checked; savePrefs() };
|
||||
shareDeltaEl.onchange=()=>{ prefs.includeDelta = shareDeltaEl.checked; savePrefs() };
|
||||
confirmDeleteEl.onchange=()=>{ prefs.confirmDelete = confirmDeleteEl.checked; savePrefs() };
|
||||
@ -653,11 +672,16 @@
|
||||
applyMarkerStyle(prefs.markerStyle||"dot");
|
||||
setAccent(prefs.accent||"#0ea5e9");
|
||||
applyTheme(prefs.theme||"auto");
|
||||
// apply pro mode class on body
|
||||
// sidebar width
|
||||
if(prefs.sidebarW){
|
||||
const w = clamp(prefs.sidebarW, parseSize(getComputedStyle(document.documentElement).getPropertyValue('--sidebar-min')), window.innerWidth*0.6);
|
||||
document.documentElement.style.setProperty('--sidebar-w', w + 'px');
|
||||
}
|
||||
document.body.classList.toggle("pro-enabled", !!prefs.proMode);
|
||||
}
|
||||
function applyMarkerStyle(style){ markerEl.classList.toggle("crosshair", style==="crosshair") }
|
||||
function setAccent(hex){ document.documentElement.style.setProperty("--accent",hex); themeColorMeta?.setAttribute("content",hex) }
|
||||
function parseSize(v){ return Math.max(0, parseFloat(String(v).replace(/[^\d.]/g,'')) || 0) }
|
||||
|
||||
function applyTheme(mode){
|
||||
if(mode==="dark"){ document.documentElement.style.colorScheme="dark" }
|
||||
@ -694,10 +718,68 @@
|
||||
parseURL(); apply(false);
|
||||
const urlHasLat = new URLSearchParams(location.search).has("lat");
|
||||
if(!urlHasLat){ locate() }
|
||||
if(prefs.autoFollow) startFollow();
|
||||
if(prefs.autoFollow)
|
||||
startFollow();
|
||||
|
||||
// Desktop sidebar builder (clean, with Pro toggle)
|
||||
if(isDesktop()) buildDesktopSidebar();
|
||||
// Desktop sidebar builder + resizer
|
||||
if(isDesktop()){
|
||||
buildDesktopSidebar();
|
||||
setupSidebarResizer();
|
||||
}
|
||||
|
||||
function setupSidebarResizer(){
|
||||
let handle=document.querySelector(".side-resizer");
|
||||
if(!handle){
|
||||
handle=document.createElement("div");
|
||||
handle.className="side-resizer";
|
||||
document.body.appendChild(handle);
|
||||
}
|
||||
|
||||
const minPx = ()=> parseSize(getComputedStyle(document.documentElement).getPropertyValue('--sidebar-min'));
|
||||
const maxPx = ()=> Math.min(window.innerWidth*0.6, parseSize(getComputedStyle(document.documentElement).getPropertyValue('--sidebar-max')) || window.innerWidth*0.6);
|
||||
|
||||
let dragging=false, startX=0, startW=0;
|
||||
|
||||
const onDown=(e)=>{
|
||||
if(!isDesktop()) return;
|
||||
dragging=true;
|
||||
startX = e.clientX ?? (e.touches?.[0]?.clientX || 0);
|
||||
startW = parseSize(getComputedStyle(document.documentElement).getPropertyValue('--sidebar-w')) || 320;
|
||||
handle.classList.add("dragging");
|
||||
document.addEventListener("pointermove", onMove);
|
||||
document.addEventListener("pointerup", onUp);
|
||||
e.preventDefault();
|
||||
};
|
||||
const onMove=(e)=>{
|
||||
if(!dragging) return;
|
||||
const x = e.clientX ?? (e.touches?.[0]?.clientX || 0);
|
||||
const raw = startW + (x - startX);
|
||||
const clamped = clamp(raw, minPx(), maxPx());
|
||||
document.documentElement.style.setProperty('--sidebar-w', clamped + 'px');
|
||||
};
|
||||
const onUp=()=>{
|
||||
if(!dragging) return;
|
||||
dragging=false;
|
||||
handle.classList.remove("dragging");
|
||||
// persist
|
||||
const w = parseSize(getComputedStyle(document.documentElement).getPropertyValue('--sidebar-w')) || 320;
|
||||
prefs.sidebarW = Math.round(clamp(w, minPx(), maxPx()));
|
||||
savePrefs();
|
||||
document.removeEventListener("pointermove", onMove);
|
||||
document.removeEventListener("pointerup", onUp);
|
||||
};
|
||||
|
||||
handle.addEventListener("pointerdown", onDown);
|
||||
addEventListener("resize", ()=>{
|
||||
if(!isDesktop()) return;
|
||||
// ensure width stays in bounds on resize
|
||||
const w = parseSize(getComputedStyle(document.documentElement).getPropertyValue('--sidebar-w')) || 320;
|
||||
const clamped = clamp(w, minPx(), maxPx());
|
||||
document.documentElement.style.setProperty('--sidebar-w', clamped + 'px');
|
||||
}, {passive:true});
|
||||
}
|
||||
|
||||
// Desktop sidebar (mirrors mobile features)
|
||||
function buildDesktopSidebar(){
|
||||
const side=document.createElement("div"); side.className="sidebar";
|
||||
side.innerHTML=`
|
||||
@ -718,7 +800,7 @@
|
||||
<div class="row"><button class="iconbtn" id="d_locate">Locate</button><button class="iconbtn" id="d_follow">Follow</button><button class="iconbtn" id="d_reset">Reset</button></div>
|
||||
<div class="row"><button class="iconbtn" id="d_copy">Copy Link</button><button class="iconbtn" id="d_copyc">Copy Coords</button></div>
|
||||
<div class="row"><button class="iconbtn" id="d_osm">Open in OSM</button><button class="iconbtn" id="d_gmaps">Google Maps</button></div>
|
||||
<div class="hint">Tip: / to focus search • 1–4 change layers • S save pin • R reset</div>
|
||||
<div class="hint">Tip: / focus • 1–4 layers • S save pin • R reset</div>
|
||||
</div>
|
||||
|
||||
<div class="sidecard">
|
||||
@ -802,15 +884,15 @@
|
||||
d_style.value=prefs.markerStyle||"dot";
|
||||
d_ms.value=markerSizeEl.value; d_msv.textContent=d_ms.value+"px";
|
||||
d_mc.value=markerColorEl.value;
|
||||
d_mr && (d_mr.checked=markerRingEl.checked);
|
||||
d_rw && (d_rw.value=ringWidthEl.value, d_rwv.textContent=d_rw.value+"px");
|
||||
if(d_mr) d_mr.checked=markerRingEl.checked;
|
||||
if(d_rw){ d_rw.value=ringWidthEl.value; d_rwv.textContent=d_rw.value+"px" }
|
||||
|
||||
d_markerv.onchange=()=>{ markerVisibleEl.checked=d_markerv.checked; markerVisibleEl.onchange() };
|
||||
d_style.onchange=()=>{ markerStyleEl.value=d_style.value; markerStyleEl.onchange() };
|
||||
d_ms.oninput=()=>{ markerSizeEl.value=d_ms.value; markerSizeEl.oninput(); d_msv.textContent=d_ms.value+"px" };
|
||||
d_mc.oninput=()=>{ markerColorEl.value=d_mc.value; markerColorEl.oninput() };
|
||||
d_mr && (d_mr.onchange=()=>{ markerRingEl.checked=d_mr.checked; markerRingEl.onchange() });
|
||||
d_rw && (d_rw.oninput=()=>{ ringWidthEl.value=d_rw.value; ringWidthEl.oninput(); d_rwv.textContent=d_rw.value+"px" });
|
||||
if(d_mr) d_mr.onchange=()=>{ markerRingEl.checked=d_mr.checked; markerRingEl.onchange() };
|
||||
if(d_rw) d_rw.oninput=()=>{ ringWidthEl.value=d_rw.value; ringWidthEl.oninput(); d_rwv.textContent=d_rw.value+"px" };
|
||||
|
||||
// Pins mini
|
||||
const d_save=side.querySelector("#d_save");
|
||||
@ -823,7 +905,7 @@
|
||||
d_pinlistmini.innerHTML="";
|
||||
const pins=loadPins().slice(0,6);
|
||||
if(!pins.length){ d_pinlistmini.innerHTML='<small style="opacity:.6">No pins yet.</small>'; return }
|
||||
pins.forEach((p,idx)=>{
|
||||
pins.forEach((p)=>{
|
||||
const row=document.createElement("div");
|
||||
row.style.display="flex"; row.style.gap="6px"; row.style.alignItems="center"; row.style.justifyContent="space-between";
|
||||
const txt=document.createElement("div");
|
||||
@ -841,11 +923,11 @@
|
||||
const d_accent=side.querySelector("#d_accent"), d_accent_reset=side.querySelector("#d_accent_reset");
|
||||
d_showc.checked=!!prefs.showCoords;
|
||||
d_fmt.value=prefs.coordFmt||"dec";
|
||||
d_prec && (d_prec.value=prefs.prec??6, d_precv.textContent=String(prefs.prec??6));
|
||||
if(d_prec){ d_prec.value=prefs.prec??6; d_precv.textContent=String(prefs.prec??6) }
|
||||
d_accent.value=prefs.accent||"#0ea5e9";
|
||||
d_showc.onchange=()=>{ toggleCoords.checked=d_showc.checked; toggleCoords.onchange() };
|
||||
d_fmt.onchange=()=>{ coordFmtEl.value=d_fmt.value; coordFmtEl.onchange() };
|
||||
d_prec && (d_prec.oninput=()=>{ coordPrecEl.value=d_prec.value; coordPrecEl.oninput(); d_precv.textContent=d_prec.value });
|
||||
if(d_prec) d_prec.oninput=()=>{ coordPrecEl.value=d_prec.value; coordPrecEl.oninput(); d_precv.textContent=d_prec.value };
|
||||
d_accent.oninput=()=>{ accentColorEl.value=d_accent.value; accentColorEl.oninput() };
|
||||
d_accent_reset.onclick=()=>{ accentResetEl.click(); d_accent.value=accentColorEl.value };
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user