Fix keyboard navigation for the map if the focus is not on the main map element

This commit is contained in:
Pieter Vander Vennet 2023-12-12 17:08:59 +01:00
parent 512a0b87ac
commit a20f6a2d27
5 changed files with 183 additions and 149 deletions

View file

@ -1,6 +1,6 @@
import { VariableUiElement } from "../Base/VariableUIElement"
import Svg from "../../Svg"
import { UIEventSource } from "../../Logic/UIEventSource"
import { Store, UIEventSource } from "../../Logic/UIEventSource"
import GeoLocationHandler from "../../Logic/Actors/GeoLocationHandler"
import Hotkeys from "../Base/Hotkeys"
import Translations from "../i18n/Translations"
@ -12,8 +12,16 @@ import { MapProperties } from "../../Models/MapProperties"
* Will set the 'lock' if clicked twice
*/
export class GeolocationControl extends VariableUiElement {
constructor(geolocationHandler: GeoLocationHandler, state: MapProperties) {
const lastClick = new UIEventSource<Date>(undefined)
public readonly lastClick = new UIEventSource<Date>(undefined)
private readonly _geolocationHandler: GeoLocationHandler
private readonly _mapProperties: MapProperties
private readonly _lastClickWithinThreeSecs: Store<boolean>
constructor(
geolocationHandler: GeoLocationHandler,
state: MapProperties,
lastGeolocationRequestByUser: UIEventSource<Date> = undefined
) {
const lastClick = lastGeolocationRequestByUser ?? new UIEventSource<Date>(undefined)
lastClick.addCallbackD((date) => {
geolocationHandler.geolocationState.requestMoment.setData(date)
})
@ -77,52 +85,15 @@ export class GeolocationControl extends VariableUiElement {
)
)
async function handleClick() {
if (
geolocationState.permission.data !== "granted" &&
geolocationState.currentGPSLocation.data === undefined
) {
lastClick.setData(new Date())
geolocationState.requestMoment.setData(new Date())
await geolocationState.requestPermission()
}
this._geolocationHandler = geolocationHandler
this._mapProperties = state
if (geolocationState.allowMoving.data === false) {
// Unlock
geolocationState.allowMoving.setData(true)
return
}
this.lastClick = lastClick
this._lastClickWithinThreeSecs = lastClickWithinThreeSecs
// A location _is_ known! Let's move to this location
const currentLocation = geolocationState.currentGPSLocation.data
if (currentLocation === undefined) {
// No location is known yet, not much we can do
lastClick.setData(new Date())
return
}
const inBounds = state.bounds.data.contains([
currentLocation.longitude,
currentLocation.latitude,
])
geolocationHandler.MoveMapToCurrentLocation()
if (inBounds) {
state.zoom.update((z) => z + 3)
}
if (lastClickWithinThreeSecs.data) {
geolocationState.allowMoving.setData(false)
lastClick.setData(undefined)
return
}
lastClick.setData(new Date())
}
this.onClick(handleClick)
Hotkeys.RegisterHotkey(
{ nomod: "L" },
Translations.t.hotkeyDocumentation.geolocate,
handleClick
this.onClick(() => this.handleClick())
Hotkeys.RegisterHotkey({ nomod: "L" }, Translations.t.hotkeyDocumentation.geolocate, () =>
this.handleClick()
)
lastClick.addCallbackAndRunD((_) => {
@ -140,4 +111,49 @@ export class GeolocationControl extends VariableUiElement {
}, 500)
})
}
public async handleClick() {
const geolocationHandler = this._geolocationHandler
const geolocationState = this._geolocationHandler.geolocationState
const lastClick = this.lastClick
const state = this._mapProperties
if (
geolocationState.permission.data !== "granted" &&
geolocationState.currentGPSLocation.data === undefined
) {
lastClick.setData(new Date())
geolocationState.requestMoment.setData(new Date())
await geolocationState.requestPermission()
}
if (geolocationState.allowMoving.data === false) {
// Unlock
geolocationState.allowMoving.setData(true)
return
}
// A location _is_ known! Let's move to this location
const currentLocation = geolocationState.currentGPSLocation.data
if (currentLocation === undefined) {
// No location is known yet, not much we can do
lastClick.setData(new Date())
return
}
const inBounds = state.bounds.data.contains([
currentLocation.longitude,
currentLocation.latitude,
])
geolocationHandler.MoveMapToCurrentLocation()
if (inBounds) {
state.zoom.update((z) => z + 3)
}
if (this._lastClickWithinThreeSecs.data) {
geolocationState.allowMoving.setData(false)
lastClick.setData(undefined)
return
}
lastClick.setData(new Date())
}
}