diff --git a/src/components/LeafletMap/controls.ts b/src/components/LeafletMap/controls.ts index c906707..af3963c 100644 --- a/src/components/LeafletMap/controls.ts +++ b/src/components/LeafletMap/controls.ts @@ -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 }; diff --git a/src/components/LeafletMap/geolocation.ts b/src/components/LeafletMap/geolocation.ts index 382fc38..05b88fc 100644 --- a/src/components/LeafletMap/geolocation.ts +++ b/src/components/LeafletMap/geolocation.ts @@ -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); } } diff --git a/src/components/leaflet-map.ts b/src/components/leaflet-map.ts index cdfc7e2..6b637c9 100644 --- a/src/components/leaflet-map.ts +++ b/src/components/leaflet-map.ts @@ -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;