added geolocation

This commit is contained in:
SlimusMinus
2026-09-01 01:19:59 +03:00
parent 0ce69c14c1
commit 98473d4b59
8 changed files with 196 additions and 54 deletions

View File

@@ -1,5 +1,6 @@
import { useEffect, useRef, useState } from "react";
import { API_URL, getImageUrl } from "../config/authConstants";
import { useGeolocation, GEO_STATUS } from "../hooks/useGeolocation";
const MARKER_COLORS = {
LOST: "#ff3b30",
@@ -42,9 +43,12 @@ const COORD_MATCH_TOLERANCE = 0.005;
export default function MapView({ focusPostId, focusLat, focusLng, onPostClick }) {
const mapRef = useRef(null);
const ymapRef = useRef(null);
const userMarkerRef = useRef(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const { coords: geoCoords, status: geoStatus } = useGeolocation({ onMount: true });
const onPostClickRef = useRef(onPostClick);
onPostClickRef.current = onPostClick;
@@ -157,9 +161,35 @@ export default function MapView({ focusPostId, focusLat, focusLng, onPostClick }
destroyed.current = true;
ymapRef.current?.destroy();
ymapRef.current = null;
userMarkerRef.current = null;
};
}, [focusPostId, focusLat, focusLng]);
// Геолокация: если юзер разрешил и карта уже создана — центр на его месте.
// Не трогаем, если карта была открыта с фокусом на конкретном объявлении.
const hasFocus = focusPostId != null || (Number.isFinite(focusLat) && Number.isFinite(focusLng));
useEffect(() => {
if (hasFocus) return;
if (geoStatus !== GEO_STATUS.SUCCESS || !geoCoords) return;
const map = ymapRef.current;
if (!map) return;
const [lat, lng] = [geoCoords.latitude, geoCoords.longitude];
map.setCenter([lat, lng], 14);
if (userMarkerRef.current) {
userMarkerRef.current.geometry.setCoordinates([lat, lng]);
} else {
const pm = new window.ymaps.Placemark(
[lat, lng],
{},
{ preset: "islands#blueCircleIcon" }
);
map.geoObjects.add(pm);
userMarkerRef.current = pm;
}
}, [hasFocus, geoStatus, geoCoords, loading]);
return (
<div className="f-mapview">
{loading && (
@@ -173,6 +203,18 @@ export default function MapView({ focusPostId, focusLat, focusLng, onPostClick }
</div>
)}
<div ref={mapRef} className="f-mapview-canvas" />
{geoStatus === GEO_STATUS.LOADING && !hasFocus && (
<div className="f-mapview-geo f-mapview-geo-info">Определение местоположения…</div>
)}
{geoStatus === GEO_STATUS.DENIED && (
<div className="f-mapview-geo f-mapview-geo-warn">Доступ к геолокации запрещён</div>
)}
{geoStatus === GEO_STATUS.TIMEOUT && (
<div className="f-mapview-geo f-mapview-geo-warn">Геолокация не определилась</div>
)}
{geoStatus === GEO_STATUS.UNSUPPORTED && (
<div className="f-mapview-geo f-mapview-geo-warn">Геолокация недоступна</div>
)}
</div>
);
}