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:
Pieter Vander Vennet 2022-04-09 19:29:51 +02:00
parent 0cb306e542
commit 49f26687e3
3 changed files with 72 additions and 38 deletions

View file

@ -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)