Skip to content

Commit 829db2e

Browse files
authored
Merge pull request #580 from kabalin/mylocation
Add current location button to position map using geolocation.
2 parents fa235c8 + 1c3d3aa commit 829db2e

File tree

3 files changed

+85
-2
lines changed

3 files changed

+85
-2
lines changed

public/js/module/map/map.js

+52-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ define([
1818
minZoom: 3,
1919
maxZoom: 18,
2020
zoom: 17,
21+
geolocationZoom: 12,
22+
};
23+
24+
const geoStatus = {
25+
READY: 'ready',
26+
PENDING: 'pending',
27+
ERROR: 'error',
28+
DENIED: 'denied',
2129
};
2230

2331
return Cliche.extend({
@@ -119,7 +127,17 @@ define([
119127
this.yearRefreshMarkersBind = this.yearRefreshMarkers.bind(this);
120128
this.yearRefreshMarkersTimeout = null;
121129

122-
this.infoShow = ko.observable(true);
130+
// Geolocation
131+
this.geolocationStatus = ko.observable(geoStatus.READY);
132+
133+
if ('permissions' in navigator) {
134+
navigator.permissions.query({ name: 'geolocation' }).then(result => {
135+
if (result.state === 'denied') {
136+
// Use of geolocation is already denied for this site.
137+
this.geolocationStatus(geoStatus.DENIED);
138+
}
139+
});
140+
}
123141

124142
this.layers.push({
125143
id: 'osm',
@@ -876,6 +894,39 @@ define([
876894

877895
return false;
878896
},
897+
isGeolocationSupported: function () {
898+
return !!('geolocation' in navigator);
899+
},
900+
showMyLocation: function () {
901+
// Geolocate current position. Query position even if we know
902+
// that user denied it already, in Chrome for example this will show
903+
// location icon in status bar, making easier to find
904+
// where to change this setting. Don't query if there is a pending
905+
// request already.
906+
if (this.geolocationStatus() !== geoStatus.PENDING) {
907+
this.geolocationStatus(geoStatus.PENDING);
908+
909+
const success = function (position) {
910+
this.geolocationStatus(geoStatus.READY);
911+
this.map.setView(new L.LatLng(position.coords.latitude, position.coords.longitude),
912+
defaults.geolocationZoom, { animate: true });
913+
}.bind(this);
914+
915+
const error = function error(err) {
916+
if (err.code === err.PERMISSION_DENIED) {
917+
// User denied geolocation.
918+
this.geolocationStatus(geoStatus.DENIED);
919+
} else {
920+
// Position unavilable due to timeout or device internal error.
921+
this.geolocationStatus(geoStatus.ERROR);
922+
}
923+
924+
console.warn(`Geolocation error: ${err.message}`);
925+
}.bind(this);
926+
927+
navigator.geolocation.getCurrentPosition(success, error, { maximumAge: 30000, timeout: 10000 });
928+
}
929+
},
879930
copyGeo: function (data, evt) {
880931
if (this.point.geo()) {
881932
// Temporaly hide custom tooltip so it does not overlap flashing one.

public/style/map/map.less

+27
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,21 @@
158158
}
159159
}
160160

161+
.mapPosTools {
162+
position: absolute;
163+
right: 5px;
164+
bottom: 52px;
165+
width: max-content;
166+
}
167+
168+
.mapPosTool {
169+
position: relative;
170+
display: inline-block;
171+
height: 25px;
172+
margin-left: 3px;
173+
vertical-align: top;
174+
}
175+
161176
.button {
162177
width: 26px;
163178
padding-top: 1px;
@@ -185,6 +200,18 @@
185200
&.no .location-copy {
186201
content: url('@{iconLocationCopyI}');
187202
}
203+
204+
.my-location::before {
205+
content: '\e55c';
206+
}
207+
208+
&.nogeo .my-location::before {
209+
content: '\e1b6';
210+
}
211+
212+
&.pendinggeo .my-location::before {
213+
content: '\e1b7';
214+
}
188215
}
189216

190217
.mapYearSelector {

views/module/map/map.pug

+6-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,12 @@
3030
|  Координаты фотографии не указаны
3131
// /ko
3232
// /ko
33-
33+
// ko if: isGeolocationSupported()
34+
.mapPosTools.tltp-wrap
35+
.mapPosTool.button.fringe(data-bind="click: showMyLocation, css: {no: geolocationStatus() === 'denied' || geolocationStatus() === 'error', nogeo: geolocationStatus() === 'denied', pendinggeo: geolocationStatus() === 'pending' }" aria-describedby="mylocation")
36+
span.material-icons.my-location
37+
.tltp.tltp-left.tltp-animate-opacity(id="mylocation" role="tooltip" style="white-space:nowrap" data-bind="text: (geolocationStatus() === 'denied' ? 'Определение местоположения запрещено браузером' : geolocationStatus() === 'error' ? 'Не удается определить местоположение' : 'Моё местоположение')")
38+
// /ko
3439
.mapYearSelector
3540
.yearSlider
3641
.ui-slider-handle.L

0 commit comments

Comments
 (0)