window.SpotNotes = window.SpotNotes || {}; window.SpotNotes.initMap = function() { // Default view (e.g., Oklahoma area if geolocation fails) window.SpotNotes.map = L.map('map').setView([35.6528, -97.4781], 10); // Ask for location if (navigator.geolocation) { navigator.geolocation.watchPosition((position) => { const { latitude, longitude } = position.coords; window.SpotNotes.userLocation = { lat: latitude, lng: longitude }; const centerBtn = document.getElementById('btn-center-user'); if (centerBtn) centerBtn.style.display = 'block'; if (window.SpotNotes.isTracking) { window.SpotNotes.map.setView([latitude, longitude]); } else if (!window.SpotNotes.userMarker && !new URLSearchParams(window.location.search).has('pad') && !new URLSearchParams(window.location.search).has('note')) { window.SpotNotes.map.setView([latitude, longitude], 13); console.log("Map centered on user location:", latitude, longitude); } // Add User Location Dot if (window.SpotNotes.userMarker) { window.SpotNotes.userMarker.setLatLng([latitude, longitude]); } else { window.SpotNotes.userMarker = L.circleMarker([latitude, longitude], { radius: 8, fillColor: "#3388ff", color: "#fff", weight: 2, opacity: 1, fillOpacity: 0.8 }).addTo(window.SpotNotes.map).bindPopup("You are here"); } // Location-Based Browser Alerts const userLatLng = L.latLng(latitude, longitude); if (window.SpotNotes.activeNotes && window.SpotNotes.activeNotes.length > 0) { window.SpotNotes.activeNotes.forEach(note => { const noteLatLng = L.latLng(note.lat, note.lng); if (userLatLng.distanceTo(noteLatLng) <= 50) { if (!window.SpotNotes.notifiedNoteIds.has(note.id)) { window.SpotNotes.notifiedNoteIds.add(note.id); alert(`You are near a note!\n\n${note.title}\n${note.content}`); } } }); } }, (err) => { console.warn("Geolocation error:", err); }, { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }); } // Add OpenStreetMap tiles L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© OpenStreetMap' }).addTo(window.SpotNotes.map); // Listen for zoom changes to toggle note display window.SpotNotes.map.on('zoomend', () => { if (window.SpotNotes.activeNotes.length > 0) { window.SpotNotes.renderMapMarkers(); } }); window.SpotNotes.map.on('dragstart', window.SpotNotes.stopTracking); window.SpotNotes.map.on('popupopen', window.SpotNotes.stopTracking); // Initialize MarkerClusterGroup window.SpotNotes.markerClusterGroup = L.markerClusterGroup({ disableClusteringAtZoom: 16 }); window.SpotNotes.map.addLayer(window.SpotNotes.markerClusterGroup); }; window.SpotNotes.renderMapMarkers = function() { // Clear existing if (window.SpotNotes.markerClusterGroup) { window.SpotNotes.markerClusterGroup.clearLayers(); } // Also remove from map directly just in case (fallback) window.SpotNotes.currentMarkers.forEach(marker => window.SpotNotes.map.removeLayer(marker)); window.SpotNotes.currentMarkers = []; const zoom = window.SpotNotes.map.getZoom(); const showFull = zoom >= 14; // Zoom threshold window.SpotNotes.activeNotes.forEach(note => { let marker; let actionBtns = ''; // Determine permissions: Use note-specific info if available (search results), else fall back to pad globals const isOwner = window.SpotNotes.currentUser && (note.owner_id ? note.owner_id === window.SpotNotes.currentUser.id : window.SpotNotes.activePadOwnerId === window.SpotNotes.currentUser.id); const isPublic = note.is_public !== undefined ? note.is_public : window.SpotNotes.activePadIsPublic; const canWrite = (note.notepad && note.notepad.can_write !== undefined) ? note.notepad.can_write : window.SpotNotes.activePadCanWrite; if (canWrite) { const escapedTitle = window.SpotNotes.escapeHtml(note.title).replace(/'/g, "\\'").replace(/"/g, '"'); const escapedContent = window.SpotNotes.escapeHtml(note.content).replace(/'/g, "\\'").replace(/"/g, '"').replace(/\n/g, '\\n'); actionBtns = `
`; } else if (isPublic) { actionBtns = `
`; } const shareToken = note.share_token || ''; const shareBtn = ``; const dateStr = new Date(note.created_at).toLocaleString(); const padColor = (note.notepad && note.notepad.color) ? note.notepad.color : '#3388ff'; const directionsBtn = `πŸ—ΊοΈ Directions`; if (showFull) { const icon = L.divIcon({ className: '', html: `
${window.SpotNotes.escapeHtml(note.title)}
${window.SpotNotes.escapeHtml(note.content)}
${dateStr}
${directionsBtn} ${shareBtn} ${actionBtns}
`, iconSize: [200, 'auto'], iconAnchor: [100, 0] }); marker = L.marker([note.lat, note.lng], { icon: icon }); } else { const teardropSvg = ``; const svgIcon = L.divIcon({ className: 'custom-div-icon', html: teardropSvg, iconSize: [24, 36], iconAnchor: [12, 36], popupAnchor: [0, -36] }); marker = L.marker([note.lat, note.lng], { icon: svgIcon }); marker.bindPopup(`${window.SpotNotes.escapeHtml(note.title)}
${window.SpotNotes.escapeHtml(note.content)}
${dateStr}
${directionsBtn} ${shareBtn} ${actionBtns}`); } const bumpZIndex = function() { this.setZIndexOffset(window.SpotNotes.topZIndex++); }; marker.on('click', bumpZIndex); marker.on('mousedown', bumpZIndex); if (window.SpotNotes.markerClusterGroup) { window.SpotNotes.markerClusterGroup.addLayer(marker); } else { marker.addTo(window.SpotNotes.map); } window.SpotNotes.currentMarkers.push(marker); }); }; window.SpotNotes.stopTracking = function() { window.SpotNotes.isTracking = false; window.SpotNotes.updateTrackingUI(); }; window.SpotNotes.updateTrackingUI = function() { const btn = document.getElementById('btn-center-user'); if (btn) { if (window.SpotNotes.isTracking) { btn.textContent = "Tracking Location..."; btn.style.backgroundColor = "#28a745"; } else { btn.textContent = "Target My Location"; btn.style.backgroundColor = ""; } } };