diff --git a/Logic/Actors/GeoLocationHandler.ts b/Logic/Actors/GeoLocationHandler.ts index 6f702b768..9c6fbce3b 100644 --- a/Logic/Actors/GeoLocationHandler.ts +++ b/Logic/Actors/GeoLocationHandler.ts @@ -45,13 +45,10 @@ export default class GeoLocationHandler { (new Date().getTime() - geolocationState.requestMoment.data?.getTime() ?? 0) / 1000 if (!this.mapHasMoved.data) { // The map hasn't moved yet; we received our first coordinates, so let's move there! - console.log( - "Moving the map to an initial location; time since last request is", - timeSinceLastRequest - ) - if (timeSinceLastRequest < Constants.zoomToLocationTimeout) { - self.MoveMapToCurrentLocation() - } + self.MoveMapToCurrentLocation() + } + if (timeSinceLastRequest < Constants.zoomToLocationTimeout) { + self.MoveMapToCurrentLocation() } if (this.geolocationState.isLocked.data) { @@ -109,11 +106,12 @@ export default class GeoLocationHandler { } mapLocation.setData({ - zoom: mapLocation.data.zoom, + zoom: Math.max(mapLocation.data.zoom, 16), lon: newLocation.longitude, lat: newLocation.latitude, }) this.mapHasMoved.setData(true) + this.geolocationState.requestMoment.setData(undefined) } private CopyGeolocationIntoMapstate() { diff --git a/Logic/State/GeoLocationState.ts b/Logic/State/GeoLocationState.ts index c010d1b78..7184c2e81 100644 --- a/Logic/State/GeoLocationState.ts +++ b/Logic/State/GeoLocationState.ts @@ -11,8 +11,6 @@ export interface GeoLocationPointProperties extends GeolocationCoordinates { /** * An abstract representation of the current state of the geolocation. - * - * */ export class GeoLocationState { /** @@ -21,10 +19,12 @@ export class GeoLocationState { * 'requested' means the user tapped the 'locate me' button at least once * 'granted' means that it is granted * 'denied' means that we don't have access - * */ public readonly permission: UIEventSource = new UIEventSource("prompt") + /** + * Important to determine e.g. if we move automatically on fix or not + */ public readonly requestMoment: UIEventSource = new UIEventSource(undefined) /** * If true: the map will center (and re-center) to this location diff --git a/Models/Constants.ts b/Models/Constants.ts index 73d99d66a..54004ac9b 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -106,7 +106,7 @@ export default class Constants { * * In seconds */ - static zoomToLocationTimeout = 60 + static zoomToLocationTimeout = 15 static countryCoderEndpoint: string = "https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/latlon2country" public static readonly OsmPreferenceKeyPicturesLicense = "pictures-license" diff --git a/UI/BigComponents/GeolocationControl.ts b/UI/BigComponents/GeolocationControl.ts index dfb50fe21..1d1eb6908 100644 --- a/UI/BigComponents/GeolocationControl.ts +++ b/UI/BigComponents/GeolocationControl.ts @@ -6,6 +6,7 @@ import { BBox } from "../../Logic/BBox" import Loc from "../../Models/Loc" import Hotkeys from "../Base/Hotkeys" import Translations from "../i18n/Translations" +import Constants from "../../Models/Constants" /** * Displays an icon depending on the state of the geolocation. @@ -20,6 +21,9 @@ export class GeolocationControl extends VariableUiElement { } ) { const lastClick = new UIEventSource(undefined) + lastClick.addCallbackD((date) => { + geolocationHandler.geolocationState.requestMoment.setData(date) + }) const lastClickWithinThreeSecs = lastClick.map((lastClick) => { if (lastClick === undefined) { return false @@ -27,6 +31,16 @@ export class GeolocationControl extends VariableUiElement { const timeDiff = (new Date().getTime() - lastClick.getTime()) / 1000 return timeDiff <= 3 }) + const lastRequestWithinTimeout = geolocationHandler.geolocationState.requestMoment.map( + (date) => { + if (date === undefined) { + return false + } + const timeDiff = (new Date().getTime() - date.getTime()) / 1000 + console.log("Timediff", timeDiff) + return timeDiff <= Constants.zoomToLocationTimeout + } + ) const geolocationState = geolocationHandler?.geolocationState super( geolocationState?.permission?.map( @@ -43,9 +57,10 @@ export class GeolocationControl extends VariableUiElement { return Svg.location_empty_svg() } // Position not yet found, but permission is either requested or granted: we spin to indicate activity - const icon = !geolocationHandler.mapHasMoved.data - ? Svg.location_svg() - : Svg.location_empty_svg() + const icon = + !geolocationHandler.mapHasMoved.data || lastRequestWithinTimeout.data + ? Svg.location_svg() + : Svg.location_empty_svg() return icon .SetClass("cursor-wait") .SetStyle("animation: spin 4s linear infinite;") @@ -65,6 +80,7 @@ export class GeolocationControl extends VariableUiElement { geolocationState.isLocked, geolocationHandler.mapHasMoved, lastClickWithinThreeSecs, + lastRequestWithinTimeout, ] ) ) @@ -74,6 +90,7 @@ export class GeolocationControl extends VariableUiElement { geolocationState.permission.data !== "granted" && geolocationState.currentGPSLocation.data === undefined ) { + lastClick.setData(new Date()) await geolocationState.requestPermission() } @@ -85,6 +102,7 @@ export class GeolocationControl extends VariableUiElement { if (geolocationState.currentGPSLocation.data === undefined) { // No location is known yet, not much we can do + lastClick.setData(new Date()) return } @@ -126,5 +144,12 @@ export class GeolocationControl extends VariableUiElement { } }, 500) }) + geolocationHandler.geolocationState.requestMoment.addCallbackAndRunD((_) => { + window.setTimeout(() => { + if (lastRequestWithinTimeout.data) { + geolocationHandler.geolocationState.requestMoment.ping() + } + }, 500) + }) } }