// Map view — главный экран const MapView = { map: null, markers: [], radius: 5, visible: true, nearby: [], async render(root) { root.innerHTML = `

🗺️ Карта

Я на карте
Другие пользователи видят твоё местоположение ±300м
Нажми чтобы получить координаты
`; if (!this.map) { this.map = L.map('map').setView([55.7558, 37.6173], 12); L.tileLayer('https://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(); }); document.getElementById('loc-share-btn').onclick = (e) => { e.preventDefault(); this.requestLocation(); }; // Если уже есть сохранённые координаты — покажем на карте if (window._lastKnownPos) { this.applyPosition(window._lastKnownPos); } }, requestLocation() { if (!navigator.geolocation) { const s = document.getElementById('loc-status'); if (s) s.textContent = 'Геолокация недоступна в браузере'; return; } const btn = document.getElementById('loc-share-btn'); const status = document.getElementById('loc-status'); if (btn) { btn.disabled = true; btn.textContent = '⏳ Запрашиваю…'; } if (status) status.textContent = 'Браузер спросит разрешение…'; navigator.geolocation.getCurrentPosition( async (pos) => { window._lastKnownPos = pos; if (btn) { btn.disabled = false; btn.textContent = '📍 Обновить геолокацию'; } if (status) status.textContent = `✓ ${pos.coords.latitude.toFixed(4)}, ${pos.coords.longitude.toFixed(4)}`; await this.applyPosition(pos); }, (err) => { if (btn) { btn.disabled = false; btn.textContent = '📍 Попробовать снова'; } if (status) status.textContent = '⚠️ ' + this.geolocationErrorText(err); console.warn('geolocation error:', err); }, { enableHighAccuracy: true, timeout: 15000, maximumAge: 60000 } ); }, geolocationErrorText(err) { switch (err.code) { case err.PERMISSION_DENIED: return 'Доступ к геолокации запрещён. Разреши в настройках браузера.'; case err.POSITION_UNAVAILABLE: return 'Не удалось определить координаты (нет GPS/Wi-Fi).'; case err.TIMEOUT: return 'Таймаут запроса геолокации.'; default: return 'Неизвестная ошибка геолокации.'; } }, async applyPosition(pos) { const lat = pos.coords.latitude; const lng = pos.coords.longitude; try { await API.Auth.updateLocation(lat, lng, this.visible); } catch (e) { console.warn('updateLocation:', e); } if (this.map) { this.map.setView([lat, lng], 13); // удалим старый круг this.map.eachLayer((layer) => { if (layer instanceof L.Circle) this.map.removeLayer(layer); }); L.circle([lat, lng], { radius: this.radius * 1000, color: '#FF6B35', fillColor: '#FF6B35', fillOpacity: 0.1, weight: 2, }).addTo(this.map); this.refreshNearbyFromPos(lat, lng); } }, async refreshNearby() { if (!navigator.geolocation) return; navigator.geolocation.getCurrentPosition(async (pos) => { this.refreshNearbyFromPos(pos.coords.latitude, pos.coords.longitude); }); }, async refreshNearbyFromPos(lat, lng) { try { const r = await API.Auth.searchNearby(lat, lng, this.radius); this.nearby = r.results || []; const c = document.getElementById('nearby-count'); if (c) c.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;