diff --git a/lib/community-sync.ts b/lib/community-sync.ts index b7f213c..f461475 100644 --- a/lib/community-sync.ts +++ b/lib/community-sync.ts @@ -770,7 +770,7 @@ export class CommunitySync extends EventTarget { * Shapes already forgotten get hard-deleted; others get soft-forgotten. */ bulkForget(shapeIds: string[], did: string): void { - const changes: Array<{ id: string; before: unknown; action: 'forget' | 'delete' }> = []; + const changes: Array<{ id: string; before: ShapeData | null; action: 'forget' | 'delete' }> = []; for (const id of shapeIds) { const state = this.getShapeVisualState(id); changes.push({ id, before: this.#cloneShapeData(id), action: state === 'forgotten' ? 'delete' : 'forget' }); diff --git a/modules/rmaps/components/folk-map-viewer.ts b/modules/rmaps/components/folk-map-viewer.ts index dc4bc57..868a8ed 100644 --- a/modules/rmaps/components/folk-map-viewer.ts +++ b/modules/rmaps/components/folk-map-viewer.ts @@ -1075,11 +1075,24 @@ class FolkMapViewer extends HTMLElement { this.room = slug; this.view = "map"; this.render(); - this.initMapView(); + this.initMapView().then(() => this.restoreLastLocation()); this.initRoomSync(); this.initLocalFirstClient(); // Periodically refresh staleness indicators this.stalenessTimer = setInterval(() => this.refreshStaleness(), 15000); + // Auto-start sharing if user had it enabled previously + if (localStorage.getItem(`rmaps_sharing_${slug}`) === "true") { + setTimeout(() => this.toggleLocationSharing(), 500); + } + } + + private restoreLastLocation() { + try { + const saved = JSON.parse(localStorage.getItem(`rmaps_loc_${this.room}`) || "null"); + if (saved && this.map && Date.now() - saved.ts < 30 * 60 * 1000) { + this.map.flyTo({ center: [saved.lng, saved.lat], zoom: 13 }); + } + } catch {} } private async initLocalFirstClient() { @@ -1173,6 +1186,7 @@ class FolkMapViewer extends HTMLElement { }); this.map.addControl(new (window as any).maplibregl.NavigationControl(), "top-right"); + this.map.addControl(new (window as any).maplibregl.ScaleControl(), "bottom-left"); // If inside a folk-shape and not in editing mode, disable map interactions if (this._parentShape && !this._mapInteractive) { @@ -1250,11 +1264,14 @@ class FolkMapViewer extends HTMLElement { navigator.serviceWorker.addEventListener("message", (event) => { if (event.data?.type === "LOCATION_REQUEST") { const reqRoom = event.data.data?.roomSlug; - if (reqRoom === this.room && this.sharingLocation) { - // Already sharing — sync will propagate automatically - } else if (reqRoom === this.room && this.privacySettings.precision !== "hidden") { - // Not sharing yet — start sharing in response to ping - this.toggleLocationSharing(); + if (reqRoom === this.room) { + this.showPingToast(event.data.data?.fromName || "Someone"); + if (this.sharingLocation) { + // Already sharing — sync will propagate automatically + } else if (this.privacySettings.precision !== "hidden") { + // Not sharing yet — start sharing in response to ping + this.toggleLocationSharing(); + } } } }); @@ -1526,6 +1543,11 @@ class FolkMapViewer extends HTMLElement { this.renderNavigationPanel(); }); }); + container.querySelector("#sidebar-ping-all-btn")?.addEventListener("click", () => { + this.pushManager?.requestLocation(this.room, "all"); + const btn = container.querySelector("#sidebar-ping-all-btn"); + if (btn) { btn.textContent = "\u2713 Pinged!"; setTimeout(() => { btn.textContent = "\u{1F4E2} Ping All"; }, 2000); } + }); container.querySelector("#sidebar-meeting-btn")?.addEventListener("click", () => { this.showMeetingModal = true; this.renderMeetingPointModal(); @@ -1545,6 +1567,7 @@ class FolkMapViewer extends HTMLElement {