/** * — unified 5-level privacy control for rMaps. * Dispatches 'precision-change' CustomEvent with the selected PrecisionLevel. * "hidden" level replaces the old ghost mode toggle. */ import type { PrecisionLevel, PrivacySettings } from "./map-sync"; const LEVELS: { value: PrecisionLevel; label: string; icon: string; desc: string }[] = [ { value: "exact", label: "Exact", icon: "\u{1F4CD}", desc: "Precise GPS location" }, { value: "building", label: "~50m Building", icon: "\u{1F3E2}", desc: "Fuzzy to nearby building" }, { value: "area", label: "~500m Area", icon: "\u{1F3D8}", desc: "Fuzzy to neighborhood" }, { value: "approximate", label: "~5km Approx", icon: "\u{1F30D}", desc: "Fuzzy to city area" }, { value: "hidden", label: "Hidden (Ghost)", icon: "\u{1F47B}", desc: "Stops sharing entirely" }, ]; class MapPrivacyPanel extends HTMLElement { private _settings: PrivacySettings = { precision: "exact", ghostMode: false }; static get observedAttributes() { return ["precision", "ghost"]; } get settings(): PrivacySettings { return this._settings; } set settings(v: PrivacySettings) { this._settings = v; // Sync ghost→hidden on ingest if (v.ghostMode && v.precision !== "hidden") this._settings.precision = "hidden"; this.render(); } attributeChangedCallback() { this._settings.precision = (this.getAttribute("precision") as PrecisionLevel) || "exact"; this._settings.ghostMode = this.getAttribute("ghost") === "true"; if (this._settings.ghostMode && this._settings.precision !== "hidden") this._settings.precision = "hidden"; this.render(); } connectedCallback() { this.render(); } private render() { const active = this._settings.ghostMode ? "hidden" : this._settings.precision; this.innerHTML = `
Privacy Level
${LEVELS.map(l => { const isActive = l.value === active; const borderColor = isActive ? (l.value === "hidden" ? "#8b5cf6" : "#4f46e5") : "var(--rs-border)"; const bg = isActive ? (l.value === "hidden" ? "#8b5cf620" : "#4f46e520") : "transparent"; return ` `; }).join("")}
`; this.querySelectorAll(".priv-level-btn").forEach((btn) => { btn.addEventListener("click", () => { const level = (btn as HTMLElement).dataset.level as PrecisionLevel; this._settings.precision = level; this._settings.ghostMode = level === "hidden"; this.dispatchEvent(new CustomEvent("precision-change", { detail: level, bubbles: true, composed: true })); this.render(); }); }); } } customElements.define("map-privacy-panel", MapPrivacyPanel); export { MapPrivacyPanel };