feat: merge geolocation and ask permission controls

This commit is contained in:
log101 2024-07-21 19:22:41 +03:00
parent ecad060770
commit 100d329d47
3 changed files with 70 additions and 33 deletions

View File

@ -1,7 +1,11 @@
import L from "leaflet";
import L, { type LatLngTuple } from "leaflet";
const GoToTargetControl = L.Control.extend({
onAdd: function () {
_targetLocation: null as LatLngTuple | null,
setTargetLocation: function (latlng: LatLngTuple) {
this._targetLocation = latlng;
},
onAdd: function (map: L.Map) {
const locationButton = document.createElement("button");
locationButton.id = "go-to-target-control-button";
@ -10,24 +14,58 @@ const GoToTargetControl = L.Control.extend({
locationButton.classList.add("custom-map-control-button");
L.DomEvent.on(locationButton, "click", () => {
if (!this._targetLocation) return;
map.setView(this._targetLocation, 18);
});
return locationButton;
},
});
const AskPermissonControl = L.Control.extend({
onAdd: function () {
const GeolocationControl = L.Control.extend({
options: {
title: "Konum İzni Ver",
},
_watchingLocation: false,
_containerEl: null as HTMLButtonElement | null,
_currentLocationMarker: null as L.Marker | null,
setCurrentLocationMarker: function (marker?: L.Marker) {
if (marker) this._currentLocationMarker = marker;
},
initialize: function (options: any) {
L.Util.setOptions(this, options);
},
startWatching: function () {
this._watchingLocation = true;
if (this._containerEl) this._containerEl.textContent = "Konumuma Git";
},
onAdd: function (map: L.Map) {
const locationButton = document.createElement("button");
this._containerEl = locationButton;
locationButton.id = "ask-permission-control-button";
locationButton.textContent = "Konum İzni Ver";
locationButton.textContent = this.options.title;
locationButton.classList.add("custom-map-control-button");
locationButton.type = "button";
L.DomEvent.on(locationButton, "click", () => {
if (this._watchingLocation && this._currentLocationMarker) {
map.setView(this._currentLocationMarker.getLatLng(), 12);
} else {
this.startWatching();
}
});
return locationButton;
},
onRemove: function () {
L.DomEvent.off(this._containerEl!);
},
});
export { GoToTargetControl, AskPermissonControl };
export { GoToTargetControl, GeolocationControl };

View File

@ -38,7 +38,11 @@ function onLocationError(err: L.ErrorEvent) {
}).showToast();
}
function onLocationSuccess(locationEvent: L.LocationEvent) {
function onLocationSuccess(
locationEvent: L.LocationEvent,
map: L.Map,
currentLocationMarker: L.Marker | undefined
) {
const position = locationEvent.latlng;
const currentPos = {
@ -46,13 +50,13 @@ function onLocationSuccess(locationEvent: L.LocationEvent) {
lng: position.lng,
};
if (this._currentLocationMarker) {
this._currentLocationMarker.setLatLng(currentPos);
if (currentLocationMarker) {
currentLocationMarker.setLatLng(currentPos);
} else {
this._currentLocationMarker = L.marker(currentPos, {
currentLocationMarker = L.marker(currentPos, {
icon: currentLocationIcon,
});
this._currentLocationMarker.addTo(this._map);
currentLocationMarker.addTo(map);
}
}

View File

@ -6,7 +6,7 @@ import { customElement, property, query, state } from "lit/decorators.js";
import L, { Map } from "leaflet";
import type { LatLngTuple } from "leaflet";
import { targetLocationIcon } from "./LeafletMap/icons";
import { AskPermissonControl, GoToTargetControl } from "./LeafletMap/controls";
import { GeolocationControl, GoToTargetControl } from "./LeafletMap/controls";
// Styles
import leafletStyles from "leaflet/dist/leaflet.css?inline";
@ -45,17 +45,15 @@ export class LeafletMap extends LitElement {
@state()
protected _watchingLocation = false;
private _startWatchingLocation = () => {
this._map?.locate();
};
firstUpdated(): void {
if (!this._mapElement || !this.targetLocation) return;
this._map = new Map(this._mapElement).setView(this.targetLocation, 13);
this._map.on("locationerror", onLocationError);
this._map.on("locationfound", onLocationSuccess.bind(this));
this._map.on("locationfound", (ev) =>
onLocationSuccess(ev, this._map!, this._currentLocationMarker)
);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
@ -80,13 +78,9 @@ export class LeafletMap extends LitElement {
position: "bottomleft",
});
targetLocationControl.setTargetLocation(this.targetLocation);
targetLocationControl.addTo(this._map);
L.DomEvent.on(this._goToTargetButton, "click", () => {
if (!this.targetLocation || !this._map) return;
this._map.setView(this.targetLocation, 18);
});
// Check geolocation permission, if user has given permission before
// start watching user location
navigator.permissions
@ -95,24 +89,25 @@ export class LeafletMap extends LitElement {
switch (permissionStatus.state) {
case "granted":
this._geolocationPermissionStatus = "granted";
const locateUserControl = new GeolocationControl({
// @ts-expect-error
title: "Konumuma Git",
position: "bottomleft",
});
locateUserControl.setCurrentLocationMarker(
this._currentLocationMarker
);
locateUserControl.addTo(this._map!);
break;
case "denied":
this._geolocationPermissionStatus = "denied";
break;
case "prompt":
if (!this._map) break;
const askPermissionControl = new AskPermissonControl({
const askPermissionControl = new GeolocationControl({
position: "bottomleft",
});
askPermissionControl.onRemove = () => {
L.DomEvent.off(this._askPermissionButton);
};
askPermissionControl.addTo(this._map);
L.DomEvent.on(
this._askPermissionButton,
"click",
this._startWatchingLocation
);
askPermissionControl.addTo(this._map!);
break;
default:
break;