Add option to find own location in map views
This commit is contained in:
parent
a756b33fe9
commit
e5a7e83b48
6 changed files with 93 additions and 25 deletions
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ReactNode, useContext, useEffect } from "react";
|
||||
import React, { ReactNode, useContext, useEffect, useState } from "react";
|
||||
import classNames from "classnames";
|
||||
import * as maplibregl from "maplibre-gl";
|
||||
import { ClientEvent, IClientWellKnown } from "matrix-js-sdk/src/matrix";
|
||||
|
@ -22,10 +22,13 @@ import { logger } from "matrix-js-sdk/src/logger";
|
|||
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import { useEventEmitterState } from "../../../hooks/useEventEmitter";
|
||||
import { parseGeoUri } from "../../../utils/location";
|
||||
import { parseGeoUri, positionFailureMessage } from "../../../utils/location";
|
||||
import { tileServerFromWellKnown } from "../../../utils/WellKnownUtils";
|
||||
import { useMap } from "../../../utils/location/useMap";
|
||||
import { Bounds } from "../../../utils/beacon/bounds";
|
||||
import Modal from "../../../Modal";
|
||||
import ErrorDialog from "../dialogs/ErrorDialog";
|
||||
import { _t } from "../../../languageHandler";
|
||||
|
||||
const useMapWithStyle = ({
|
||||
id,
|
||||
|
@ -33,12 +36,14 @@ const useMapWithStyle = ({
|
|||
onError,
|
||||
interactive,
|
||||
bounds,
|
||||
allowGeolocate,
|
||||
}: {
|
||||
id: string;
|
||||
centerGeoUri?: string;
|
||||
onError(error: Error): void;
|
||||
interactive?: boolean;
|
||||
bounds?: Bounds;
|
||||
onError(error: Error): void;
|
||||
allowGeolocate: boolean;
|
||||
}): {
|
||||
map: maplibregl.Map;
|
||||
bodyId: string;
|
||||
|
@ -86,12 +91,41 @@ const useMapWithStyle = ({
|
|||
}
|
||||
}, [map, bounds]);
|
||||
|
||||
const [geolocate] = useState(
|
||||
allowGeolocate
|
||||
? new maplibregl.GeolocateControl({
|
||||
positionOptions: {
|
||||
enableHighAccuracy: true,
|
||||
},
|
||||
trackUserLocation: false,
|
||||
})
|
||||
: null,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (map && geolocate) {
|
||||
map.addControl(geolocate);
|
||||
geolocate.on("error", onGeolocateError);
|
||||
return () => {
|
||||
geolocate.off("error", onGeolocateError);
|
||||
};
|
||||
}
|
||||
}, [map, geolocate]);
|
||||
|
||||
return {
|
||||
map,
|
||||
bodyId,
|
||||
};
|
||||
};
|
||||
|
||||
const onGeolocateError = (e: GeolocationPositionError): void => {
|
||||
logger.error("Could not fetch location", e);
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("Could not fetch location"),
|
||||
description: positionFailureMessage(e.code),
|
||||
});
|
||||
};
|
||||
|
||||
interface MapProps {
|
||||
id: string;
|
||||
interactive?: boolean;
|
||||
|
@ -105,13 +139,24 @@ interface MapProps {
|
|||
centerGeoUri?: string;
|
||||
bounds?: Bounds;
|
||||
className?: string;
|
||||
allowGeolocate?: boolean;
|
||||
onClick?: () => void;
|
||||
onError?: (error: Error) => void;
|
||||
children?: (renderProps: { map: maplibregl.Map }) => ReactNode;
|
||||
}
|
||||
|
||||
const Map: React.FC<MapProps> = ({ bounds, centerGeoUri, children, className, id, interactive, onError, onClick }) => {
|
||||
const { map, bodyId } = useMapWithStyle({ centerGeoUri, onError, id, interactive, bounds });
|
||||
const Map: React.FC<MapProps> = ({
|
||||
bounds,
|
||||
centerGeoUri,
|
||||
children,
|
||||
className,
|
||||
allowGeolocate,
|
||||
id,
|
||||
interactive,
|
||||
onError,
|
||||
onClick,
|
||||
}) => {
|
||||
const { map, bodyId } = useMapWithStyle({ centerGeoUri, onError, id, interactive, bounds, allowGeolocate });
|
||||
|
||||
const onMapClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>): void => {
|
||||
// Eat click events when clicking the attribution button
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue