// Map view — главный экран
const MapView = {
map: null,
markers: [],
radius: 5,
visible: true,
nearby: [],
async render(root) {
root.innerHTML = `
🗺️ Карта
—
`;
if (!this.map) {
this.map = L.map('map').setView([55.7558, 37.6173], 12);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap',
maxZoom: 19,
}).addTo(this.map);
}
setTimeout(() => this.map.invalidateSize(), 100);
document.getElementById('visible-toggle').addEventListener('change', async (e) => {
this.visible = e.target.checked;
try {
await API.Auth.setVisibility(this.visible);
this.refreshLocation();
} catch (err) {
API.Store && console.warn(err);
TG_APP.showAlert('Не удалось обновить видимость');
}
});
document.getElementById('radius-sel').addEventListener('change', (e) => {
this.radius = parseInt(e.target.value, 10);
document.getElementById('radius-label').textContent = this.radius + ' км';
this.refreshNearby();
});
this.refreshLocation();
},
async refreshLocation() {
if (!navigator.geolocation) {
document.getElementById('nearby-count').textContent = 'Геолокация недоступна';
return;
}
navigator.geolocation.getCurrentPosition(
async (pos) => {
const lat = pos.coords.latitude;
const lng = pos.coords.longitude;
try {
await API.Auth.updateLocation(lat, lng, this.visible);
} catch (e) {
console.warn(e);
}
this.map.setView([lat, lng], 13);
L.circle([lat, lng], {
radius: this.radius * 1000,
color: '#FF6B35', fillColor: '#FF6B35', fillOpacity: 0.1, weight: 2,
}).addTo(this.map);
this.refreshNearby();
},
(err) => {
document.getElementById('nearby-count').textContent = 'Нет доступа к GPS: ' + err.message;
},
{ enableHighAccuracy: true, timeout: 15000 }
);
},
async refreshNearby() {
if (!navigator.geolocation) return;
navigator.geolocation.getCurrentPosition(async (pos) => {
try {
const r = await API.Auth.searchNearby(pos.coords.latitude, pos.coords.longitude, this.radius);
this.nearby = r.results || [];
document.getElementById('nearby-count').textContent = this.nearby.length + ' чел. рядом';
// удалить старые маркеры (кроме своего круга)
this.markers.forEach(m => this.map.removeLayer(m));
this.markers = [];
this.nearby.forEach((n) => {
const icon = L.divIcon({
className: 'custom-marker',
html: `${escapeHtml((n.name || '?')[0])}
`,
iconSize: [36, 36],
});
const m = L.marker([n.lat, n.lng], { icon }).addTo(this.map);
m.bindTooltip(n.name + ' • ' + (n.distance_m / 1000).toFixed(1) + ' км', { direction: 'top' });
m.on('click', () => App.openUserProfile(n.user_id, n.name));
this.markers.push(m);
});
} catch (e) {
console.warn(e);
}
});
},
};
window.MapView = MapView;