added geolocation
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user