diff --git a/AllTranslationAssets.ts b/AllTranslationAssets.ts
index d2b4dd4..ac65d3d 100644
--- a/AllTranslationAssets.ts
+++ b/AllTranslationAssets.ts
@@ -39,7 +39,8 @@ export default class AllTranslationAssets {
number: new Translation( {"en":"number","ca":"nombre","es":"número","nl":"getal","fr":"nombre","gl":"número","de":"Zahl"} ),
osmLinkTooltip: new Translation( {"en":"See this object on OpenStreetMap for history and more editing options","ca":"Mira aquest objecte a OpenStreetMap per veure historial i altres opcions d'edició","es":"Mira este objeto en OpenStreetMap para ver historial y otras opciones de edición","nl":"Bekijk dit object op OpenStreetMap waar geschiedenis en meer aanpasopties zijn","fr":"Voir l'historique de cet objet sur OpenStreetMap et plus d'options d'édition","gl":"Ollar este obxecto no OpenStreetMap para ollar o historial e outras opcións de edición","de":"Dieses Objekt auf OpenStreetMap anschauen für die Geschichte und weitere Bearbeitungsmöglichkeiten"} ),
add: { addNew: new Translation( {"en":"Add a new {category} here","ca":"Afegir {category} aquí","es":"Añadir {category} aquí","nl":"Voeg hier een {category} toe","fr":"Ajouter un/une {category} ici","gl":"Engadir {category} aquí","de":"Hier eine neue {category} hinzufügen"} ),
- header: new Translation( {"en":"
Add a point?
You clicked somewhere where no data is known yet.
","ca":"Vols afegir un punt?
Has marcat un lloc on no coneixem les dades.
","es":"Quieres añadir un punto?
Has marcado un lugar del que no conocemos los datos.
","nl":"Punt toevoegen?
Je klikte ergens waar er nog geen data is. Kies hieronder welk punt je wilt toevoegen
","fr":"Pas de données
Vous avez cliqué sur un endroit où il n'y a pas encore de données.
","gl":"Queres engadir un punto?
Marcaches un lugar onde non coñecemos os datos.
","de":"Punkt hinzufügen?
Sie haben irgendwo geklickt, wo noch keine Daten bekannt sind.
"} ),
+ title: new Translation( {"en":"Add a point?","ca":"Vols afegir un punt?","es":"Quieres añadir un punto?","nl":"Punt toevoegen?","fr":"Pas de données","gl":"Queres engadir un punto?","de":"Punkt hinzufügen?"} ),
+ intro: new Translation( {"en":"You clicked somewhere where no data is known yet.
","ca":"Has marcat un lloc on no coneixem les dades.
","es":"Has marcado un lugar del que no conocemos los datos.
","nl":"Je klikte ergens waar er nog geen data is. Kies hieronder welk punt je wilt toevoegen
","fr":"Vous avez cliqué sur un endroit où il n'y a pas encore de données.
","gl":"Marcaches un lugar onde non coñecemos os datos.
","de":"Sie haben irgendwo geklickt, wo noch keine Daten bekannt sind.
"} ),
pleaseLogin: new Translation( {"en":"Please log in to add a new point","ca":"Entra per afegir un nou punt","es":"Entra para añadir un nuevo punto","nl":"Gelieve je aan te melden om een punt to te voegen","fr":"Vous devez vous connecter pour ajouter un point","gl":"Inicia a sesión para engadir un novo punto","de":"Bitte loggen Sie sich ein, um einen neuen Punkt hinzuzufügen"} ),
zoomInFurther: new Translation( {"en":"Zoom in further to add a point.","ca":"Apropa per afegir un punt.","es":"Acerca para añadir un punto.","nl":"Gelieve verder in te zoomen om een punt toe te voegen.","fr":"Rapprochez vous pour ajouter un point.","gl":"Achégate para engadir un punto.","de":"Weiter einzoomen, um einen Punkt hinzuzufügen."} ),
stillLoading: new Translation( {"en":"The data is still loading. Please wait a bit before you add a new point.","ca":"Les dades es segueixen carregant. Espera una mica abans d'afegir cap punt.","es":"Los datos se siguen cargando. Espera un poco antes de añadir ningún punto.","nl":"De data wordt nog geladen. Nog even geduld en dan kan je een punt toevoegen.","fr":"Chargement des données en cours. Patientez un instant avant d'ajouter un nouveau point.","gl":"Os datos seguen a cargarse. Agarda un intre antes de engadir ningún punto.","de":"Die Daten werden noch geladen. Bitte warten Sie etwas, bevor Sie einen neuen Punkt hinzufügen."} ),
diff --git a/Logic/Web/QueryParameters.ts b/Logic/Web/QueryParameters.ts
index 715ee32..7c34583 100644
--- a/Logic/Web/QueryParameters.ts
+++ b/Logic/Web/QueryParameters.ts
@@ -62,6 +62,7 @@ export class QueryParameters {
parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(QueryParameters.knownSources[key].data))
}
+ // Don't pollute the history every time a parameter changes
history.replaceState(null, "", "?" + parts.join("&") + "#" + Hash.hash.data);
}
diff --git a/Models/Constants.ts b/Models/Constants.ts
index 106bec8..dcd75e0 100644
--- a/Models/Constants.ts
+++ b/Models/Constants.ts
@@ -1,7 +1,7 @@
import { Utils } from "../Utils";
export default class Constants {
- public static vNumber = "0.4.3";
+ public static vNumber = "0.4.4";
// The user journey states thresholds when a new feature gets unlocked
public static userJourney = {
diff --git a/UI/Base/ScrollableFullScreen.ts b/UI/Base/ScrollableFullScreen.ts
index f5770d7..6c27d12 100644
--- a/UI/Base/ScrollableFullScreen.ts
+++ b/UI/Base/ScrollableFullScreen.ts
@@ -2,6 +2,7 @@ import {UIElement} from "../UIElement";
import Svg from "../../Svg";
import State from "../../State";
import Combine from "./Combine";
+import Ornament from "./Ornament";
/**
* Wraps some contents into a panel that scrolls the content _under_ the title
@@ -17,10 +18,12 @@ export default class ScrollableFullScreen extends UIElement{
State.state.selectedElement.setData(undefined);
}).SetClass("only-on-mobile")
.SetClass("featureinfobox-back-to-the-map")
-
+ title.SetClass("featureinfobox-title")
this._component = new Combine([
new Combine([returnToTheMap, title]).SetClass("featureinfobox-titlebar"),
- new Combine([content]).SetClass("featureinfobox-content")
+ new Combine([content]).SetClass("featureinfobox-content"),
+ new Combine([ new Ornament().SetStyle("height:5em;")]).SetClass("only-on-mobile")
+ // We add an ornament which takes around 5em. This is in order to make sure the Web UI doesn't hide
])
this.SetClass("featureinfobox");
diff --git a/UI/BigComponents/SimpleAddUI.ts b/UI/BigComponents/SimpleAddUI.ts
index c2c73ae..cecafdb 100644
--- a/UI/BigComponents/SimpleAddUI.ts
+++ b/UI/BigComponents/SimpleAddUI.ts
@@ -13,47 +13,175 @@ import {FixedUiElement} from "../Base/FixedUiElement";
import Translations from "../i18n/Translations";
import Constants from "../../Models/Constants";
import LayerConfig from "../../Customizations/JSON/LayerConfig";
+import ScrollableFullScreen from "../Base/ScrollableFullScreen";
export default class SimpleAddUI extends UIElement {
- private readonly _addButtons: UIElement[];
-
- private _loginButton : UIElement;
-
- private _confirmPreset: UIEventSource<{
+ private readonly _loginButton: UIElement;
+
+ private readonly _confirmPreset: UIEventSource<{
description: string | UIElement,
name: string | UIElement,
icon: UIElement,
tags: Tag[],
layerToAddTo: {
layerDef: LayerConfig,
- isDisplayed: UIEventSource }
+ isDisplayed: UIEventSource
+ }
}>
= new UIEventSource(undefined);
- private confirmButton: UIElement = undefined;
- private _confirmDescription: UIElement = undefined;
- private openLayerControl: UIElement;
- private cancelButton: UIElement;
- private goToInboxButton: UIElement = new SubtleButton(Svg.envelope_ui(),
- Translations.t.general.goToInbox, {url:"https://www.openstreetmap.org/messages/inbox", newTab: false});
+
+ private _component: UIElement;
+
+ private readonly openLayerControl: UIElement;
+ private readonly cancelButton: UIElement;
+ private readonly goToInboxButton: UIElement = new SubtleButton(Svg.envelope_ui(),
+ Translations.t.general.goToInbox, {url: "https://www.openstreetmap.org/messages/inbox", newTab: false});
constructor() {
- super(State.state.locationControl);
+ super(State.state.locationControl.map(loc => loc.zoom));
+ const self = this;
this.ListenTo(Locale.language);
this.ListenTo(State.state.osmConnection.userDetails);
this.ListenTo(State.state.layerUpdater.runningQuery);
this.ListenTo(this._confirmPreset);
this.ListenTo(State.state.locationControl);
-
+ State.state.filteredLayers.data?.map(layer => {
+ self.ListenTo(layer.isDisplayed)
+ })
+
this._loginButton = Translations.t.general.add.pleaseLogin.Clone().onClick(() => State.state.osmConnection.AttemptLogin());
-
- this._addButtons = [];
+
this.SetStyle("font-size:large");
-
+ this.cancelButton = new SubtleButton(Svg.close_ui(),
+ Translations.t.general.cancel
+ ).onClick(() => {
+ self._confirmPreset.setData(undefined);
+ })
+
+ this.openLayerControl = new SubtleButton(Svg.layers_ui(),
+ Translations.t.general.add.openLayerControl
+ ).onClick(() => {
+ State.state.fullScreenMessage.setData(undefined);
+ State.state.layerControlIsOpened.setData(true);
+ })
+ }
+
+ InnerRender(): string {
+
+ this._component = new ScrollableFullScreen(
+ Translations.t.general.add.title,
+ this.CreateContent()
+ )
+ return this._component.Render();
+
+ }
+
+ private CreatePresetsPanel(): UIElement {
+ const userDetails = State.state.osmConnection.userDetails;
+ if (userDetails === undefined) {
+ return undefined;
+ }
+
+ if (!userDetails.data.loggedIn) {
+ return this._loginButton;
+ }
+
+ if (userDetails.data.unreadMessages > 0 && userDetails.data.csCount < Constants.userJourney.addNewPointWithUnreadMessagesUnlock) {
+ return new Combine([
+ Translations.t.general.readYourMessages.Clone().SetClass("alert"),
+ this.goToInboxButton
+ ]);
+
+ }
+
+ if (userDetails.data.csCount < Constants.userJourney.addNewPointsUnlock) {
+ return new Combine(["",
+ Translations.t.general.fewChangesBefore,
+ ""]);
+ }
+
+ if (State.state.locationControl.data.zoom < Constants.userJourney.minZoomLevelToAddNewPoints) {
+ return Translations.t.general.add.zoomInFurther.SetClass("alert")
+ }
+
+ if (State.state.layerUpdater.runningQuery.data) {
+ return Translations.t.general.add.stillLoading
+ }
+
+ const presetButtons = this.CreatePresetButtons()
+ return new Combine(presetButtons).SetClass("add-popup-all-buttons")
+ }
+
+
+ private CreateContent(): UIElement {
+ const confirmPanel = this.CreateConfirmPanel();
+ if (confirmPanel !== undefined) {
+ return confirmPanel;
+ }
+
+ let intro: UIElement = Translations.t.general.add.intro;
+
+ let testMode: UIElement = undefined;
+ if (State.state.osmConnection?.userDetails?.data?.dryRun) {
+ testMode = new Combine([
+ "",
+ "Test mode - changes won't be saved",
+ ""
+ ]);
+ }
+
+ let presets = this.CreatePresetsPanel();
+ return new Combine([intro, testMode, presets])
+
+
+ }
+
+ private CreateConfirmPanel(): UIElement {
+ const preset = this._confirmPreset.data;
+ if (preset === undefined) {
+ return undefined;
+ }
+
+ const confirmButton = new SubtleButton(preset.icon,
+ new Combine([
+ "",
+ Translations.t.general.add.confirmButton.Subs({category: preset.name}),
+ ""]));
+ confirmButton.onClick(this.CreatePoint(preset.tags));
+
+ if (!this._confirmPreset.data.layerToAddTo.isDisplayed.data) {
+ return new Combine([
+ Translations.t.general.add.layerNotEnabled.Subs({layer: this._confirmPreset.data.layerToAddTo.layerDef.name})
+ .SetClass("alert"),
+ this.openLayerControl,
+
+ this.cancelButton
+ ]);
+ }
+
+ let tagInfo = "";
+ const csCount = State.state.osmConnection.userDetails.data.csCount;
+ if (csCount > Constants.userJourney.tagsVisibleAt) {
+ tagInfo = this._confirmPreset.data.tags.map(t => t.asHumanString(csCount > Constants.userJourney.tagsVisibleAndWikiLinked, true)).join("&");
+ tagInfo = `
More information about the preset: ${tagInfo}`
+ }
+
+ return new Combine([
+ Translations.t.general.add.confirmIntro.Subs({title: this._confirmPreset.data.name}),
+ State.state.osmConnection.userDetails.data.dryRun ? "TESTING - changes won't be saved" : "",
+ confirmButton,
+ this.cancelButton,
+ preset.description,
+ tagInfo
+
+ ])
+
+ }
+
+ private CreatePresetButtons() {
+ const allButtons = [];
const self = this;
for (const layer of State.state.filteredLayers.data) {
-
- this.ListenTo(layer.isDisplayed);
-
const presets = layer.layerDef.presets;
for (const preset of presets) {
const tags = TagUtils.KVtoProperties(preset.tags ?? []);
@@ -77,13 +205,6 @@ export default class SimpleAddUI extends UIElement {
])
).onClick(
() => {
- self.confirmButton = new SubtleButton(icon,
- new Combine([
- "",
- Translations.t.general.add.confirmButton.Subs({category: preset.title}),
- ""]));
- self.confirmButton.onClick(self.CreatePoint(preset.tags));
- self._confirmDescription = preset.description;
self._confirmPreset.setData({
tags: preset.tags,
layerToAddTo: layer,
@@ -94,23 +215,10 @@ export default class SimpleAddUI extends UIElement {
self.Update();
}
)
-
-
- this._addButtons.push(button);
+ allButtons.push(button);
}
}
-
- this.cancelButton = new SubtleButton(Svg.close_ui(),
- Translations.t.general.cancel
- ).onClick(() => {
- self._confirmPreset.setData(undefined);
- })
-
- this.openLayerControl = new SubtleButton(Svg.layers_ui(),
- Translations.t.general.add.openLayerControl
- ).onClick(() => {
- State.state.layerControlIsOpened.setData(true);
- })
+ return allButtons;
}
private CreatePoint(tags: Tag[]) {
@@ -121,86 +229,5 @@ export default class SimpleAddUI extends UIElement {
}
}
- InnerRender(): string {
-
- const userDetails = State.state.osmConnection.userDetails;
-
- if (this._confirmPreset.data !== undefined) {
-
- if(!this._confirmPreset.data.layerToAddTo.isDisplayed.data){
- return new Combine([
- Translations.t.general.add.layerNotEnabled.Subs({layer: this._confirmPreset.data.layerToAddTo.layerDef.name})
- .SetClass("alert"),
- this.openLayerControl,
-
- this.cancelButton
- ]).Render();
- }
-
- let tagInfo = "";
- const csCount = State.state.osmConnection.userDetails.data.csCount;
- if (csCount > Constants.userJourney.tagsVisibleAt) {
- tagInfo = this._confirmPreset.data .tags.map(t => t.asHumanString(csCount > Constants.userJourney.tagsVisibleAndWikiLinked, true)).join("&");
- tagInfo = `
More information about the preset: ${tagInfo}`
- }
-
- return new Combine([
- Translations.t.general.add.confirmIntro.Subs({title: this._confirmPreset.data.name}),
- userDetails.data.dryRun ? "TESTING - changes won't be saved" : "",
- this.confirmButton,
- this.cancelButton,
- this._confirmDescription,
- tagInfo
-
- ]).Render();
-
-
- }
-
-
- let header: UIElement = Translations.t.general.add.header;
-
-
- if (userDetails === undefined) {
- return header.Render();
- }
-
- if (!userDetails.data.loggedIn) {
- return new Combine([header, this._loginButton]).Render()
- }
-
- if (userDetails.data.unreadMessages > 0 && userDetails.data.csCount < Constants.userJourney.addNewPointWithUnreadMessagesUnlock) {
- return new Combine([header,
- Translations.t.general.readYourMessages.Clone().SetClass("alert"),
- this.goToInboxButton
- ]).Render();
-
- }
-
- if (userDetails.data.dryRun) {
- header = new Combine([header,
- "",
- "Test mode - changes won't be saved",
- ""
- ]);
- }
-
- if (userDetails.data.csCount < Constants.userJourney.addNewPointsUnlock) {
- return new Combine([header, "",
- Translations.t.general.fewChangesBefore,
- ""]).Render();
- }
-
- if (State.state.locationControl.data.zoom < Constants.userJourney.minZoomLevelToAddNewPoints) {
- return new Combine([header, Translations.t.general.add.zoomInFurther.SetClass("alert")]).Render()
- }
-
- if (State.state.layerUpdater.runningQuery.data) {
- return new Combine([header, Translations.t.general.add.stillLoading]).Render()
- }
-
- return header.Render() + new Combine(this._addButtons).SetClass("add-popup-all-buttons").Render();
- }
-
}
\ No newline at end of file
diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts
index 57e7e99..9ad6f9d 100644
--- a/UI/Popup/FeatureInfoBox.ts
+++ b/UI/Popup/FeatureInfoBox.ts
@@ -6,10 +6,7 @@ import QuestionBox from "./QuestionBox";
import Combine from "../Base/Combine";
import TagRenderingAnswer from "./TagRenderingAnswer";
import State from "../../State";
-import {FixedUiElement} from "../Base/FixedUiElement";
import TagRenderingConfig from "../../Customizations/JSON/TagRenderingConfig";
-import Svg from "../../Svg";
-import Ornament from "../Base/Ornament";
import ScrollableFullScreen from "../Base/ScrollableFullScreen";
export default class FeatureInfoBox extends UIElement {
@@ -49,7 +46,7 @@ export default class FeatureInfoBox extends UIElement {
if (!questionBoxIsUsed) {
renderings.push(questionBox);
}
- const tail = new Combine([new Ornament()]).SetClass("only-on-mobile");
+ const tail = new Combine([]).SetClass("only-on-mobile");
const content = new Combine([
...renderings,
diff --git a/assets/translations.json b/assets/translations.json
index 65dc283..77cbb72 100644
--- a/assets/translations.json
+++ b/assets/translations.json
@@ -309,14 +309,24 @@
"gl": "Engadir {category} aquí",
"de": "Hier eine neue {category} hinzufügen"
},
- "header": {
- "en": "Add a point?
You clicked somewhere where no data is known yet.
",
- "ca": "Vols afegir un punt?
Has marcat un lloc on no coneixem les dades.
",
- "es": "Quieres añadir un punto?
Has marcado un lugar del que no conocemos los datos.
",
- "nl": "Punt toevoegen?
Je klikte ergens waar er nog geen data is. Kies hieronder welk punt je wilt toevoegen
",
- "fr": "Pas de données
Vous avez cliqué sur un endroit où il n'y a pas encore de données.
",
- "gl": "Queres engadir un punto?
Marcaches un lugar onde non coñecemos os datos.
",
- "de": "Punkt hinzufügen?
Sie haben irgendwo geklickt, wo noch keine Daten bekannt sind.
"
+ "title": {
+ "en": "Add a new point?",
+ "ca": "Vols afegir un punt?",
+ "es": "Quieres añadir un punto?",
+ "nl": "Nieuw punt toevoegen?",
+ "fr": "Pas de données",
+ "gl": "Queres engadir un punto?",
+ "de": "Punkt hinzufügen?"
+
+ },
+ "intro": {
+ "en": "You clicked somewhere where no data is known yet.
",
+ "ca": "Has marcat un lloc on no coneixem les dades.
",
+ "es": "Has marcado un lugar del que no conocemos los datos.
",
+ "nl": "Je klikte ergens waar er nog geen data is. Kies hieronder welk punt je wilt toevoegen
",
+ "fr": "Vous avez cliqué sur un endroit où il n'y a pas encore de données.
",
+ "gl": "Marcaches un lugar onde non coñecemos os datos.
",
+ "de": "Sie haben irgendwo geklickt, wo noch keine Daten bekannt sind.
"
},
"pleaseLogin": {
"en": "Please log in to add a new point",