forked from MapComplete/MapComplete
Zoom to geolocation automatically if within 60 seconds, fix reading the previous map location from local storage if not initialized, fix #724"
This commit is contained in:
parent
0cb306e542
commit
49f26687e3
3 changed files with 72 additions and 38 deletions
|
@ -6,6 +6,7 @@ import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
|
|||
import {QueryParameters} from "../Web/QueryParameters";
|
||||
import FeatureSource from "../FeatureSource/FeatureSource";
|
||||
import {BBox} from "../BBox";
|
||||
import Constants from "../../Models/Constants";
|
||||
|
||||
export interface GeoLocationPointProperties {
|
||||
id: "gps",
|
||||
|
@ -25,13 +26,11 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
|
||||
/**
|
||||
* Wether or not the geolocation is active, aka the user requested the current location
|
||||
* @private
|
||||
*/
|
||||
private readonly _isActive: UIEventSource<boolean>;
|
||||
|
||||
/**
|
||||
* Wether or not the geolocation is locked, aka the user requested the current location and wants the crosshair to follow the user
|
||||
* @private
|
||||
*/
|
||||
private readonly _isLocked: UIEventSource<boolean>;
|
||||
|
||||
|
@ -54,9 +53,8 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
|
||||
/**
|
||||
* The date when the user requested the geolocation. If we have a location, it'll autozoom to it the first 30 secs
|
||||
* @private
|
||||
*/
|
||||
private _lastUserRequest: Date;
|
||||
private _lastUserRequest: UIEventSource<Date>;
|
||||
|
||||
/**
|
||||
* A small flag on localstorage. If the user previously granted the geolocation, it will be set.
|
||||
|
@ -80,6 +78,8 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
) {
|
||||
const currentGPSLocation = new UIEventSource<Coordinates>(undefined, "GPS-coordinate")
|
||||
const leafletMap = state.leafletMap
|
||||
const initedAt = new Date()
|
||||
let autozoomDone = false;
|
||||
const hasLocation = currentGPSLocation.map(
|
||||
(location) => location !== undefined
|
||||
);
|
||||
|
@ -97,13 +97,30 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
const timeDiff = (new Date().getTime() - lastClick.getTime()) / 1000
|
||||
return timeDiff <= 3
|
||||
})
|
||||
|
||||
const latLonGiven = QueryParameters.wasInitialized("lat") && QueryParameters.wasInitialized("lon")
|
||||
const willFocus = lastClick.map(lastUserRequest => {
|
||||
const timeDiffInited = (new Date().getTime() - initedAt.getTime()) / 1000
|
||||
console.log("TimeDiff with initedAtt is ", timeDiffInited)
|
||||
if (!latLonGiven && !autozoomDone && timeDiffInited < Constants.zoomToLocationTimeout) {
|
||||
return true
|
||||
}
|
||||
if (lastUserRequest === undefined) {
|
||||
return false;
|
||||
}
|
||||
const timeDiff = (new Date().getTime() - lastUserRequest.getTime()) / 1000
|
||||
console.log("TimeDiff with lastClick is ", timeDiff)
|
||||
return timeDiff <= Constants.zoomToLocationTimeout
|
||||
})
|
||||
|
||||
lastClick.addCallbackAndRunD(_ => {
|
||||
window.setTimeout(() => {
|
||||
if (lastClickWithinThreeSecs.data) {
|
||||
if (lastClickWithinThreeSecs.data || willFocus.data) {
|
||||
lastClick.ping()
|
||||
}
|
||||
}, 500)
|
||||
})
|
||||
|
||||
super(
|
||||
hasLocation.map(
|
||||
(hasLocationData) => {
|
||||
|
@ -116,7 +133,8 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
}
|
||||
if (!hasLocationData) {
|
||||
// Position not yet found but we are active: we spin to indicate activity
|
||||
const icon = Svg.location_empty_svg()
|
||||
// If will focus is active too, we indicate this differently
|
||||
const icon = willFocus.data ? Svg.location_svg() : Svg.location_empty_svg()
|
||||
icon.SetStyle("animation: spin 4s linear infinite;")
|
||||
return icon;
|
||||
}
|
||||
|
@ -130,7 +148,7 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
// We have a location, so we show a dot in the center
|
||||
return Svg.location_svg();
|
||||
},
|
||||
[isActive, isLocked, permission, lastClickWithinThreeSecs]
|
||||
[isActive, isLocked, permission, lastClickWithinThreeSecs, willFocus]
|
||||
)
|
||||
);
|
||||
this.SetClass("mapcontrol")
|
||||
|
@ -142,6 +160,7 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
this._leafletMap = leafletMap;
|
||||
this._layoutToUse = state.layoutToUse;
|
||||
this._hasLocation = hasLocation;
|
||||
this._lastUserRequest = lastClick
|
||||
const self = this;
|
||||
|
||||
const currentPointer = this._isActive.map(
|
||||
|
@ -183,8 +202,7 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
self.init(true, true);
|
||||
});
|
||||
|
||||
const latLonGiven = QueryParameters.wasInitialized("lat") && QueryParameters.wasInitialized("lon")
|
||||
|
||||
|
||||
const doAutoZoomToLocation = !latLonGiven && state.featureSwitchGeolocation.data && state.selectedElement.data !== undefined
|
||||
this.init(false, doAutoZoomToLocation);
|
||||
|
||||
|
@ -221,8 +239,12 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
self.currentLocation?.features?.setData([{feature, freshness: new Date()}])
|
||||
|
||||
const timeSinceRequest =
|
||||
(new Date().getTime() - (self._lastUserRequest?.getTime() ?? 0)) / 1000;
|
||||
if (timeSinceRequest < 30) {
|
||||
(new Date().getTime() - (self._lastUserRequest.data?.getTime() ?? 0)) / 1000;
|
||||
|
||||
if (willFocus.data) {
|
||||
console.log("Zooming to user location: willFocus is set")
|
||||
willFocus.setData(false)
|
||||
autozoomDone = true;
|
||||
self.MoveToCurrentLocation(16);
|
||||
} else if (self._isLocked.data) {
|
||||
self.MoveToCurrentLocation();
|
||||
|
@ -239,8 +261,8 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
self.MoveToCurrentLocation(16);
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof navigator === "undefined"){
|
||||
|
||||
if (typeof navigator === "undefined") {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -271,7 +293,7 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
|
||||
/**
|
||||
* Moves to the currently loaded location.
|
||||
*
|
||||
*
|
||||
* // Should move to any location
|
||||
* let resultingLocation = undefined
|
||||
* let resultingzoom = 1
|
||||
|
@ -321,7 +343,7 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
*/
|
||||
private MoveToCurrentLocation(targetZoom?: number) {
|
||||
const location = this._currentGPSLocation.data;
|
||||
this._lastUserRequest = undefined;
|
||||
this._lastUserRequest.setData(undefined);
|
||||
|
||||
if (
|
||||
this._currentGPSLocation.data.latitude === 0 &&
|
||||
|
@ -356,7 +378,7 @@ export default class GeoLocationHandler extends VariableUiElement {
|
|||
private StartGeolocating(zoomToGPS = true) {
|
||||
const self = this;
|
||||
|
||||
this._lastUserRequest = zoomToGPS ? new Date() : new Date(0);
|
||||
this._lastUserRequest.setData(zoomToGPS ? new Date() : new Date(0))
|
||||
if (self._permission.data === "denied") {
|
||||
self._previousLocationGrant.setData("");
|
||||
self._isActive.setData(false)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue