180 lines
No EOL
8.6 KiB
JavaScript
180 lines
No EOL
8.6 KiB
JavaScript
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: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
|
}).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 = `<br><button onclick="openEditNoteModal(${note.id}, '${escapedTitle}', '${escapedContent}')" class="btn-note-edit">✏️ Edit</button><button onclick="window.SpotNotes.deleteNote(${note.id})" class="btn-note-delete">Delete</button>`;
|
|
} else if (isPublic) {
|
|
actionBtns = `<br><button onclick="window.SpotNotes.reportNote(${note.id})" class="btn-note-report">Report</button>`;
|
|
}
|
|
|
|
const shareToken = note.share_token || '';
|
|
const shareBtn = `<button onclick="window.SpotNotes.shareNote(${note.id}, '${shareToken}')" class="btn-note-share">🔗 Share</button>`;
|
|
|
|
const dateStr = new Date(note.created_at).toLocaleString();
|
|
|
|
const padColor = (note.notepad && note.notepad.color) ? note.notepad.color : '#3388ff';
|
|
|
|
const directionsBtn = `<a href="https://www.google.com/maps/dir/?api=1&destination=${note.lat},${note.lng}" target="_blank" class="btn-note-directions" style="display:inline-block; margin-top:5px; margin-right:5px; font-size:0.8rem; text-decoration:none;">🗺️ Directions</a>`;
|
|
|
|
if (showFull) {
|
|
const icon = L.divIcon({
|
|
className: '',
|
|
html: `<div class="map-note-card" style="border-top: 4px solid ${padColor};">
|
|
<div style="font-weight:bold; margin-bottom:4px;">${window.SpotNotes.escapeHtml(note.title)}</div>
|
|
<div style="white-space: pre-wrap;">${window.SpotNotes.escapeHtml(note.content)}</div>
|
|
<div style="font-size:0.7rem; color:#888; margin-top:4px;">${dateStr}</div>
|
|
${directionsBtn} ${shareBtn} ${actionBtns}
|
|
</div>`,
|
|
iconSize: [200, 'auto'],
|
|
iconAnchor: [100, 0]
|
|
});
|
|
marker = L.marker([note.lat, note.lng], { icon: icon });
|
|
} else {
|
|
const teardropSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 36" width="24" height="36"><path fill="${padColor}" d="M12 0C5.373 0 0 5.373 0 12c0 8.442 12 24 12 24s12-15.558 12-24c0-6.627-5.373-12-12-12zm0 17c-2.761 0-5-2.239-5-5s2.239-5 5-5 5 2.239 5 5-2.239 5-5 5z" stroke="white" stroke-width="1.5"/></svg>`;
|
|
|
|
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(`<b>${window.SpotNotes.escapeHtml(note.title)}</b><br><div style="white-space: pre-wrap;">${window.SpotNotes.escapeHtml(note.content)}</div><span style="font-size:0.7rem; color:#888;">${dateStr}</span><br>${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 = "";
|
|
}
|
|
}
|
|
}; |