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({ 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"); const locationButton = document.createElement("button");
locationButton.id = "go-to-target-control-button"; locationButton.id = "go-to-target-control-button";
@ -10,24 +14,58 @@ const GoToTargetControl = L.Control.extend({
locationButton.classList.add("custom-map-control-button"); locationButton.classList.add("custom-map-control-button");
L.DomEvent.on(locationButton, "click", () => {
if (!this._targetLocation) return;
map.setView(this._targetLocation, 18);
});
return locationButton; return locationButton;
}, },
}); });
const AskPermissonControl = L.Control.extend({ const GeolocationControl = L.Control.extend({
onAdd: function () { 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"); const locationButton = document.createElement("button");
this._containerEl = locationButton;
locationButton.id = "ask-permission-control-button"; locationButton.id = "ask-permission-control-button";
locationButton.textContent = "Konum İzni Ver"; locationButton.textContent = this.options.title;
locationButton.classList.add("custom-map-control-button"); locationButton.classList.add("custom-map-control-button");
locationButton.type = "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; 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(); }).showToast();
} }
function onLocationSuccess(locationEvent: L.LocationEvent) { function onLocationSuccess(
locationEvent: L.LocationEvent,
map: L.Map,
currentLocationMarker: L.Marker | undefined
) {
const position = locationEvent.latlng; const position = locationEvent.latlng;
const currentPos = { const currentPos = {
@ -46,13 +50,13 @@ function onLocationSuccess(locationEvent: L.LocationEvent) {
lng: position.lng, lng: position.lng,
}; };
if (this._currentLocationMarker) { if (currentLocationMarker) {
this._currentLocationMarker.setLatLng(currentPos); currentLocationMarker.setLatLng(currentPos);
} else { } else {
this._currentLocationMarker = L.marker(currentPos, { currentLocationMarker = L.marker(currentPos, {
icon: currentLocationIcon, 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 L, { Map } from "leaflet";
import type { LatLngTuple } from "leaflet"; import type { LatLngTuple } from "leaflet";
import { targetLocationIcon } from "./LeafletMap/icons"; import { targetLocationIcon } from "./LeafletMap/icons";
import { AskPermissonControl, GoToTargetControl } from "./LeafletMap/controls"; import { GeolocationControl, GoToTargetControl } from "./LeafletMap/controls";
// Styles // Styles
import leafletStyles from "leaflet/dist/leaflet.css?inline"; import leafletStyles from "leaflet/dist/leaflet.css?inline";
@ -45,17 +45,15 @@ export class LeafletMap extends LitElement {
@state() @state()
protected _watchingLocation = false; protected _watchingLocation = false;
private _startWatchingLocation = () => {
this._map?.locate();
};
firstUpdated(): void { firstUpdated(): void {
if (!this._mapElement || !this.targetLocation) return; if (!this._mapElement || !this.targetLocation) return;
this._map = new Map(this._mapElement).setView(this.targetLocation, 13); this._map = new Map(this._mapElement).setView(this.targetLocation, 13);
this._map.on("locationerror", onLocationError); 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", { L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19, maxZoom: 19,
@ -80,13 +78,9 @@ export class LeafletMap extends LitElement {
position: "bottomleft", position: "bottomleft",
}); });
targetLocationControl.setTargetLocation(this.targetLocation);
targetLocationControl.addTo(this._map); 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 // Check geolocation permission, if user has given permission before
// start watching user location // start watching user location
navigator.permissions navigator.permissions
@ -95,24 +89,25 @@ export class LeafletMap extends LitElement {
switch (permissionStatus.state) { switch (permissionStatus.state) {
case "granted": case "granted":
this._geolocationPermissionStatus = "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; break;
case "denied": case "denied":
this._geolocationPermissionStatus = "denied"; this._geolocationPermissionStatus = "denied";
break; break;
case "prompt": case "prompt":
if (!this._map) break; const askPermissionControl = new GeolocationControl({
const askPermissionControl = new AskPermissonControl({
position: "bottomleft", position: "bottomleft",
}); });
askPermissionControl.onRemove = () => {
L.DomEvent.off(this._askPermissionButton); askPermissionControl.addTo(this._map!);
};
askPermissionControl.addTo(this._map);
L.DomEvent.on(
this._askPermissionButton,
"click",
this._startWatchingLocation
);
break; break;
default: default:
break; break;