feat: add geolocation permission control

This commit is contained in:
log101 2024-07-21 13:24:16 +03:00
parent fb31a822a0
commit ecad060770
4 changed files with 126 additions and 16 deletions

View File

@ -1,19 +1,33 @@
import L from "leaflet";
const TargetLocationControl = L.Control.extend({
onAdd: function (map: L.Map, targetLocation: L.LatLngTuple) {
const GoToTargetControl = L.Control.extend({
onAdd: function () {
const locationButton = document.createElement("button");
locationButton.id = "go-to-target-control-button";
locationButton.textContent = "Hedefe Git";
locationButton.classList.add("custom-map-control-button");
locationButton.addEventListener("click", () => {
map.setView(targetLocation, 18);
});
return locationButton;
},
});
const AskPermissonControl = L.Control.extend({
onAdd: function () {
const locationButton = document.createElement("button");
locationButton.id = "ask-permission-control-button";
locationButton.textContent = "Konum İzni Ver";
locationButton.classList.add("custom-map-control-button");
locationButton.type = "button";
return locationButton;
},
});
export { TargetLocationControl };
export { GoToTargetControl, AskPermissonControl };

View File

@ -0,0 +1,59 @@
import Toastify from "toastify-js";
import L from "leaflet";
import { currentLocationIcon } from "./icons";
function onLocationError(err: L.ErrorEvent) {
let errorMessage;
switch (err.code) {
case 1:
errorMessage =
"Konum izni alınamadı, lütfen tarayıcınızın ve cihazınızın gizlilik ayarlarını kontrol edin.";
break;
case 2:
errorMessage =
"Konumunuz tespit edilemedi, lütfen biraz sonra tekrar deneyiniz.";
break;
case 3:
errorMessage =
"Konum isteği zaman aşımına uğradı, lütfen sayfayı yenileyip tekrar deneyiniz.";
break;
default:
errorMessage =
"Konum izni alınamadı, lütfen tarayıcınızın ve cihazınızın gizlilik ayarlarını kontrol edin.";
break;
}
Toastify({
text: errorMessage,
duration: 3000,
gravity: "top", // `top` or `bottom`
position: "center", // `left`, `center` or `right`
stopOnFocus: true, // Prevents dismissing of toast on hover
style: {
background: "black",
borderRadius: "6px",
margin: "16px",
},
onClick: function () {}, // Callback after click
}).showToast();
}
function onLocationSuccess(locationEvent: L.LocationEvent) {
const position = locationEvent.latlng;
const currentPos = {
lat: position.lat,
lng: position.lng,
};
if (this._currentLocationMarker) {
this._currentLocationMarker.setLatLng(currentPos);
} else {
this._currentLocationMarker = L.marker(currentPos, {
icon: currentLocationIcon,
});
this._currentLocationMarker.addTo(this._map);
}
}
export { onLocationError, onLocationSuccess };

View File

@ -1,11 +1,11 @@
import { icon } from "leaflet";
import L from "leaflet";
var targetLocationIcon = icon({
var targetLocationIcon = L.icon({
iconUrl: "goal.svg",
iconSize: [32, 32],
});
var currentLocationIcon = icon({
var currentLocationIcon = L.icon({
iconUrl: "blue-dot.png",
iconSize: [32, 32],
});

View File

@ -6,12 +6,13 @@ 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 { TargetLocationControl } from "./LeafletMap/controls";
import { AskPermissonControl, GoToTargetControl } from "./LeafletMap/controls";
// Styles
import leafletStyles from "leaflet/dist/leaflet.css?inline";
import globalStyles from "@/styles/globals.css?inline";
import mapStyles from "@/styles/locked-page.css?inline";
import { onLocationError, onLocationSuccess } from "./LeafletMap/geolocation";
@customElement("leaflet-map")
export class LeafletMap extends LitElement {
@ -26,6 +27,12 @@ export class LeafletMap extends LitElement {
@query("#mapid")
_mapElement!: HTMLDivElement;
@query("#go-to-target-control-button")
_goToTargetButton!: HTMLButtonElement;
@query("#ask-permission-control-button")
_askPermissionButton!: HTMLButtonElement;
// Properties and states
@property({ type: Object }) targetLocation?: LatLngTuple;
@ -38,32 +45,47 @@ export class LeafletMap extends LitElement {
@state()
protected _watchingLocation = false;
private _startWatchingLocation = () => {
this._map?.locate();
};
firstUpdated(): void {
if (!this._mapElement || !this.targetLocation) return;
var 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("locationfound", onLocationSuccess.bind(this));
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution:
'&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(map);
}).addTo(this._map);
// Add target location icon marker
L.marker(this.targetLocation, { icon: targetLocationIcon }).addTo(map);
L.marker(this.targetLocation, { icon: targetLocationIcon }).addTo(
this._map
);
L.circle(this.targetLocation, {
color: "blue",
fillColor: "#30f",
fillOpacity: 0.2,
radius: 50,
}).addTo(map);
}).addTo(this._map);
// Add target location control
const targetLocationControl = new TargetLocationControl({
const targetLocationControl = new GoToTargetControl({
position: "bottomleft",
});
targetLocationControl.addTo(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
// start watching user location
@ -76,7 +98,22 @@ export class LeafletMap extends LitElement {
break;
case "denied":
this._geolocationPermissionStatus = "denied";
break;
case "prompt":
if (!this._map) break;
const askPermissionControl = new AskPermissonControl({
position: "bottomleft",
});
askPermissionControl.onRemove = () => {
L.DomEvent.off(this._askPermissionButton);
};
askPermissionControl.addTo(this._map);
L.DomEvent.on(
this._askPermissionButton,
"click",
this._startWatchingLocation
);
break;
default:
break;
}