diff --git a/UI/Base/Hotkeys.ts b/UI/Base/Hotkeys.ts index 73093fcf6..5355840b8 100644 --- a/UI/Base/Hotkeys.ts +++ b/UI/Base/Hotkeys.ts @@ -5,18 +5,19 @@ import Title from "./Title" import Table from "./Table" import { UIEventSource } from "../../Logic/UIEventSource" import { VariableUiElement } from "./VariableUIElement" -import doc = Mocha.reporters.doc +import { Translation } from "../i18n/Translation" +import { FixedUiElement } from "./FixedUiElement" export default class Hotkeys { private static readonly _docs: UIEventSource< { key: { ctrl?: string; shift?: string; alt?: string; nomod?: string; onUp?: boolean } - documentation: string + documentation: string | Translation }[] > = new UIEventSource< { key: { ctrl?: string; shift?: string; alt?: string; nomod?: string; onUp?: boolean } - documentation: string + documentation: string | Translation }[] >([]) @@ -41,7 +42,7 @@ export default class Hotkeys { ) & { onUp?: boolean }, - documentation: string, + documentation: string | Translation, action: () => void ) { const type = key["onUp"] ? "keyup" : "keypress" @@ -98,22 +99,22 @@ export default class Hotkeys { } static generateDocumentation(): BaseUIElement { + const byKey: [string, string | Translation][] = Hotkeys._docs.data + .map(({ key, documentation }) => { + const modifiers = Object.keys(key).filter((k) => k !== "nomod" && k !== "onUp") + const keycode: string = key["ctrl"] ?? key["shift"] ?? key["alt"] ?? key["nomod"] + modifiers.push(keycode) + return <[string, string | Translation]>[modifiers.join("+"), documentation] + }) + .sort() return new Combine([ new Title("Hotkeys", 1), "MapComplete supports the following keys:", new Table( ["Key combination", "Action"], - Hotkeys._docs.data - .map(({ key, documentation }) => { - const modifiers = Object.keys(key).filter( - (k) => k !== "nomod" && k !== "onUp" - ) - const keycode: string = - key["ctrl"] ?? key["shift"] ?? key["alt"] ?? key["nomod"] - modifiers.push(keycode) - return [modifiers.join("+"), documentation] - }) - .sort() + byKey.map(([key, doc]) => { + return [new FixedUiElement(key).SetClass("code"), doc] + }) ), ]) } diff --git a/UI/Base/ScrollableFullScreen.ts b/UI/Base/ScrollableFullScreen.ts index b0e8602ce..8001c971b 100644 --- a/UI/Base/ScrollableFullScreen.ts +++ b/UI/Base/ScrollableFullScreen.ts @@ -6,6 +6,7 @@ import Hash from "../../Logic/Web/Hash" import BaseUIElement from "../BaseUIElement" import Title from "./Title" import Hotkeys from "./Hotkeys" +import Translations from "../i18n/Translations"; /** * @@ -85,7 +86,7 @@ export default class ScrollableFullScreen { private static initEmpty(): FixedUiElement { Hotkeys.RegisterHotkey( { nomod: "Escape", onUp: true }, - "Close the sidebar", + Translations.t.hotkeyDocumentation.closeSidebar, ScrollableFullScreen.collapse ) diff --git a/UI/BigComponents/BackgroundMapSwitch.ts b/UI/BigComponents/BackgroundMapSwitch.ts index c210df525..babee2ece 100644 --- a/UI/BigComponents/BackgroundMapSwitch.ts +++ b/UI/BigComponents/BackgroundMapSwitch.ts @@ -8,6 +8,7 @@ import AvailableBaseLayers from "../../Logic/Actors/AvailableBaseLayers" import BaseUIElement from "../BaseUIElement" import { GeoOperations } from "../../Logic/GeoOperations" import Hotkeys from "../Base/Hotkeys" +import Translations from "../i18n/Translations"; class SingleLayerSelectionButton extends Toggle { public readonly activate: () => void @@ -204,7 +205,7 @@ export default class BackgroundMapSwitch extends Combine { if (options?.enableHotkeys) { Hotkeys.RegisterHotkey( { nomod: category.charAt(0).toUpperCase() }, - "Switch to a background layer of category " + category, + Translations.t.hotkeyDocumentation.selectBackground.Subs({category}), () => { button.activate() } diff --git a/UI/BigComponents/GeolocationControl.ts b/UI/BigComponents/GeolocationControl.ts index 265ceeb66..d0e286b51 100644 --- a/UI/BigComponents/GeolocationControl.ts +++ b/UI/BigComponents/GeolocationControl.ts @@ -5,6 +5,7 @@ import GeoLocationHandler from "../../Logic/Actors/GeoLocationHandler" import { BBox } from "../../Logic/BBox" import Loc from "../../Models/Loc" import Hotkeys from "../Base/Hotkeys" +import Translations from "../i18n/Translations" /** * Displays an icon depending on the state of the geolocation. @@ -52,10 +53,7 @@ export class GeolocationControl extends VariableUiElement { // We have a location, so we show a dot in the center - if ( - lastClickWithinThreeSecs.data && - geolocationState.permission.data === "granted" - ) { + if (lastClickWithinThreeSecs.data) { return Svg.location_unlocked_svg() } @@ -72,7 +70,10 @@ export class GeolocationControl extends VariableUiElement { ) async function handleClick() { - if (geolocationState.permission.data !== "granted") { + if ( + geolocationState.permission.data !== "granted" && + geolocationState.currentGPSLocation.data === undefined + ) { await geolocationState.requestPermission() } @@ -102,7 +103,7 @@ export class GeolocationControl extends VariableUiElement { }) } - if (lastClickWithinThreeSecs.data && geolocationState.permission.data === "granted") { + if (lastClickWithinThreeSecs.data) { geolocationState.isLocked.setData(true) lastClick.setData(undefined) return @@ -114,7 +115,7 @@ export class GeolocationControl extends VariableUiElement { this.onClick(handleClick) Hotkeys.RegisterHotkey( { nomod: "L" }, - "Pan the map to the current location or zoom the map to the current location. Requests geopermission", + Translations.t.hotkeyDocumentation.geolocate, handleClick ) diff --git a/UI/BigComponents/LeftControls.ts b/UI/BigComponents/LeftControls.ts index e9af1bb9c..952789d76 100644 --- a/UI/BigComponents/LeftControls.ts +++ b/UI/BigComponents/LeftControls.ts @@ -97,7 +97,7 @@ export default class LeftControls extends Combine { state.featureSwitchFilter.addCallbackAndRun((f) => { Hotkeys.RegisterHotkey( { nomod: "B" }, - "Opens the Background, layers and filters panel", + Translations.t.hotkeyDocumentation.openLayersPanel, () => { guiState.filterViewIsOpened.setData(!guiState.filterViewIsOpened.data) } diff --git a/UI/DefaultGUI.ts b/UI/DefaultGUI.ts index 260e519c0..7497da269 100644 --- a/UI/DefaultGUI.ts +++ b/UI/DefaultGUI.ts @@ -33,6 +33,7 @@ import GeoLocationHandler from "../Logic/Actors/GeoLocationHandler" import { GeoLocationState } from "../Logic/State/GeoLocationState" import Hotkeys from "./Base/Hotkeys" import AvailableBaseLayers from "../Logic/Actors/AvailableBaseLayers" +import { Translation } from "./i18n/Translation" /** * The default MapComplete GUI initializer @@ -65,7 +66,7 @@ export default class DefaultGUI { Hotkeys.RegisterHotkey( { shift: "O" }, - "Switch to default Mapnik-OpenStreetMap background", + Translations.t.hotkeyDocumentation.selectMapnik, () => { this.state.backgroundLayer.setData(AvailableBaseLayers.osmCarto) } @@ -257,7 +258,7 @@ export default class DefaultGUI { ) Hotkeys.RegisterHotkey( { ctrl: "F" }, - "Select the search bar to search locations", + Translations.t.hotkeyDocumentation.selectSearch, () => { search.focus() } diff --git a/langs/en.json b/langs/en.json index 27dd224f2..3e45d78b7 100644 --- a/langs/en.json +++ b/langs/en.json @@ -351,6 +351,14 @@ "wikipediaboxTitle": "Wikipedia" } }, + "hotkeyDocumentation": { + "closeSidebar": "Close the sidebar", + "geolocate": "Pan the map to the current location or zoom the map to the current location. Requests geopermission", + "openLayersPanel": "Opens the Background, layers and filters panel", + "selectBackground": "Select a background layer of category {category}", + "selectMapnik": "Sets the background layer to OpenStreetMap-carto", + "selectSearch": "Select the search bar to search locations" + }, "image": { "addPicture": "Add picture", "ccb": "under the CC-BY-license",