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"; import L from "leaflet";
const TargetLocationControl = L.Control.extend({ const GoToTargetControl = L.Control.extend({
onAdd: function (map: L.Map, targetLocation: L.LatLngTuple) { onAdd: function () {
const locationButton = document.createElement("button"); const locationButton = document.createElement("button");
locationButton.id = "go-to-target-control-button";
locationButton.textContent = "Hedefe Git"; locationButton.textContent = "Hedefe Git";
locationButton.classList.add("custom-map-control-button"); locationButton.classList.add("custom-map-control-button");
locationButton.addEventListener("click", () => { return locationButton;
map.setView(targetLocation, 18); },
}); });
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; 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", iconUrl: "goal.svg",
iconSize: [32, 32], iconSize: [32, 32],
}); });
var currentLocationIcon = icon({ var currentLocationIcon = L.icon({
iconUrl: "blue-dot.png", iconUrl: "blue-dot.png",
iconSize: [32, 32], iconSize: [32, 32],
}); });

View File

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