feat: add geolocation permission control
This commit is contained in:
parent
fb31a822a0
commit
ecad060770
|
@ -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 };
|
||||||
|
|
59
src/components/LeafletMap/geolocation.ts
Normal file
59
src/components/LeafletMap/geolocation.ts
Normal 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 };
|
|
@ -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],
|
||||||
});
|
});
|
||||||
|
|
|
@ -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:
|
||||||
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
'© <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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user