diff --git a/AllTranslationAssets.ts b/AllTranslationAssets.ts
index ac65d3d9a0..f4ca2c3e11 100644
--- a/AllTranslationAssets.ts
+++ b/AllTranslationAssets.ts
@@ -39,7 +39,7 @@ 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"} ),
- 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?"} ),
+ title: new Translation( {"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: 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."} ),
diff --git a/Customizations/JSON/LayerConfig.ts b/Customizations/JSON/LayerConfig.ts
index 53825613d3..6dc3f6382e 100644
--- a/Customizations/JSON/LayerConfig.ts
+++ b/Customizations/JSON/LayerConfig.ts
@@ -177,7 +177,6 @@ export default class LayerConfig {
this.tagRenderings.push(...addAll.tagRenderings);
this.iconOverlays.push(...addAll.iconOverlays);
for (const icon of addAll.titleIcons) {
- console.log("Adding ",icon, "to", this.id)
this.titleIcons.splice(0,0, icon);
}
return this;
diff --git a/Customizations/JSON/LayoutConfig.ts b/Customizations/JSON/LayoutConfig.ts
index 81be65c8e2..a1f58c7d6e 100644
--- a/Customizations/JSON/LayoutConfig.ts
+++ b/Customizations/JSON/LayoutConfig.ts
@@ -96,7 +96,6 @@ export default class LayoutConfig {
if (shared === undefined) {
throw "Unkown fixed layer " + name;
}
- console.log("PREMERGE", layer, shared)
// @ts-ignore
layer = Utils.Merge(layer.override, shared);
}
diff --git a/InitUiElements.ts b/InitUiElements.ts
index 6c78117167..62c6e59c60 100644
--- a/InitUiElements.ts
+++ b/InitUiElements.ts
@@ -41,6 +41,7 @@ import FeatureDuplicatorPerLayer from "./Logic/FeatureSource/FeatureDuplicatorPe
import LayerConfig from "./Customizations/JSON/LayerConfig";
import ShowDataLayer from "./UI/ShowDataLayer";
import Hash from "./Logic/Web/Hash";
+import HistoryHandling from "./Logic/Actors/HistoryHandling";
export class InitUiElements {
@@ -133,7 +134,6 @@ export class InitUiElements {
if (feature === undefined) {
State.state.fullScreenMessage.setData(undefined);
- Hash.hash.setData(undefined);
}
if (feature?.properties === undefined) {
return;
@@ -159,12 +159,18 @@ export class InitUiElements {
layer
);
- State.state.fullScreenMessage.setData(featureBox);
+ State.state.fullScreenMessage.setData({
+ content: featureBox,
+ hashText: feature.properties.id.replace("/", "_"),
+ titleText: featureBox.title
+ });
break;
}
}
);
+ new HistoryHandling(Hash.hash, State.state.fullScreenMessage);
+
InitUiElements.OnlyIf(State.state.featureSwitchUserbadge, () => {
new UserBadge().AttachTo('userbadge');
});
@@ -279,20 +285,20 @@ export class InitUiElements {
})
State.state.selectedElement.addCallback(selected => {
- if(selected !== undefined){
+ if (selected !== undefined) {
checkbox.isEnabled.setData(false);
}
})
const fullOptions2 = new FullWelcomePaneWithTabs();
- State.state.fullScreenMessage.setData(fullOptions2)
+ State.state.fullScreenMessage.setData({content: fullOptions2, hashText: "welcome"})
Svg.help_svg()
.SetClass("open-welcome-button")
.SetClass("shadow")
.onClick(() => {
- State.state.fullScreenMessage.setData(fullOptions2)
+ State.state.fullScreenMessage.setData({content: fullOptions2, hashText: "welcome"})
}).AttachTo("help-button-mobile");
@@ -326,7 +332,7 @@ export class InitUiElements {
const fullScreen = new LayerControlPanel();
checkbox.isEnabled.addCallback(isEnabled => {
if (isEnabled) {
- State.state.fullScreenMessage.setData(fullScreen);
+ State.state.fullScreenMessage.setData({content: fullScreen, hashText: "layer-select"});
}
})
State.state.fullScreenMessage.addCallback(latest => {
diff --git a/Logic/Actors/HistoryHandling.ts b/Logic/Actors/HistoryHandling.ts
new file mode 100644
index 0000000000..6b317a286d
--- /dev/null
+++ b/Logic/Actors/HistoryHandling.ts
@@ -0,0 +1,19 @@
+import {UIEventSource} from "../UIEventSource";
+import {UIElement} from "../../UI/UIElement";
+
+export default class HistoryHandling {
+
+ constructor(hash: UIEventSource, fullscreenMessage: UIEventSource<{ content: UIElement, hashText: string }>) {
+ hash.addCallback(h => {
+ if (h === undefined || h === "") {
+ fullscreenMessage.setData(undefined);
+ }
+ })
+
+ fullscreenMessage.addCallback(fs => {
+ hash.setData(fs?.hashText);
+ })
+
+ }
+
+}
\ No newline at end of file
diff --git a/Logic/Actors/StrayClickHandler.ts b/Logic/Actors/StrayClickHandler.ts
index a7041d6dc7..bc185130d8 100644
--- a/Logic/Actors/StrayClickHandler.ts
+++ b/Logic/Actors/StrayClickHandler.ts
@@ -17,7 +17,7 @@ export default class StrayClickHandler {
selectedElement: UIEventSource,
filteredLayers: UIEventSource<{ readonly isDisplayed: UIEventSource }[]>,
leafletMap: UIEventSource,
- fullscreenMessage: UIEventSource,
+ fullscreenMessage: UIEventSource<{content: UIElement, hashText: string}>,
uiToShow: (() => UIElement)) {
this._uiToShow = uiToShow;
const self = this;
@@ -51,7 +51,7 @@ export default class StrayClickHandler {
self._lastMarker.bindPopup(popup);
self._lastMarker.on("click", () => {
- fullscreenMessage.setData(self._uiToShow());
+ fullscreenMessage.setData({content: self._uiToShow(), hashText: "new"});
uiElement.Update();
});
});
diff --git a/Logic/Actors/TitleHandler.ts b/Logic/Actors/TitleHandler.ts
new file mode 100644
index 0000000000..8093b64e0d
--- /dev/null
+++ b/Logic/Actors/TitleHandler.ts
@@ -0,0 +1,33 @@
+import {UIEventSource} from "../UIEventSource";
+import LayoutConfig from "../../Customizations/JSON/LayoutConfig";
+import Translations from "../../UI/i18n/Translations";
+import Locale from "../../UI/i18n/Locale";
+import {UIElement} from "../../UI/UIElement";
+
+export default class TitleHandler{
+ constructor(layoutToUse: UIEventSource, fullScreenMessage: UIEventSource<{ content: UIElement, hashText: string, titleText?: UIElement }>) {
+
+
+ layoutToUse.map((layoutToUse) => {
+ return Translations.WT(layoutToUse?.title)?.txt ?? "MapComplete"
+ }, [Locale.language]
+ ).addCallbackAndRun((title) => {
+ document.title = title
+ });
+
+ fullScreenMessage.addCallbackAndRun(selected => {
+ const title = Translations.WT(layoutToUse.data?.title)?.txt ?? "MapComplete"
+ if(selected?.titleText?.data === undefined){
+ document.title = title
+ }else{
+ selected.titleText.Update();
+ var d = document.createElement('div');
+ d.innerHTML = selected.titleText.InnerRender();
+ const poi = (d.textContent || d.innerText)
+ document.title = title + " | " + poi;
+ }
+ })
+
+
+ }
+}
\ No newline at end of file
diff --git a/Logic/Web/Hash.ts b/Logic/Web/Hash.ts
index 4ef26916bc..07372f2ffb 100644
--- a/Logic/Web/Hash.ts
+++ b/Logic/Web/Hash.ts
@@ -1,29 +1,52 @@
import {UIEventSource} from "../UIEventSource";
-import Constants from "../../Models/Constants";
import {Utils} from "../../Utils";
export default class Hash {
-
- public static hash : UIEventSource = Hash.Get();
-
- private static Get() : UIEventSource{
- if(Utils.runningFromConsole){
+
+ public static hash: UIEventSource = Hash.Get();
+
+ /**
+ * Gets the current string, including the pound sign
+ * @constructor
+ */
+ public static Current(): string {
+ if (Hash.hash.data === undefined || Hash.hash.data === "") {
+ return ""
+ } else {
+ return "#" + Hash.hash.data;
+ }
+ }
+
+ private static Get(): UIEventSource {
+ if (Utils.runningFromConsole) {
return new UIEventSource(undefined);
}
const hash = new UIEventSource(window.location.hash.substr(1));
hash.addCallback(h => {
- if(h === undefined || h === ""){
+ if (h === "undefined") {
+ console.warn("Got a literal 'undefined' as hash, ignoring")
+ h = undefined;
+ }
+
+ if (h === undefined || h === "") {
window.location.hash = "";
return;
}
+
h = h.replace(/\//g, "_");
window.location.hash = "#" + h;
});
+
+
window.onhashchange = () => {
- hash.setData(window.location.hash.substr(1))
+ let newValue = window.location.hash.substr(1);
+ if (newValue === "") {
+ newValue = undefined;
+ }
+ hash.setData(newValue)
}
-
+
return hash;
}
-
+
}
\ No newline at end of file
diff --git a/Logic/Web/QueryParameters.ts b/Logic/Web/QueryParameters.ts
index 7c34583255..406afa214f 100644
--- a/Logic/Web/QueryParameters.ts
+++ b/Logic/Web/QueryParameters.ts
@@ -43,27 +43,23 @@ export class QueryParameters {
private static Serialize() {
const parts = []
for (const key of QueryParameters.order) {
- if (QueryParameters.knownSources[key] === undefined || QueryParameters.knownSources[key].data === undefined) {
+ if (QueryParameters.knownSources[key]?.data === undefined) {
continue;
}
- if (QueryParameters.knownSources[key].data === undefined) {
- continue;
- }
-
if (QueryParameters.knownSources[key].data === "undefined") {
continue;
}
-
- if (QueryParameters.knownSources[key].data == QueryParameters.defaults[key]) {
+ if (QueryParameters.knownSources[key].data === QueryParameters.defaults[key]) {
continue;
}
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);
+
+ history.replaceState(null, "", "?" + parts.join("&") + Hash.Current());
}
diff --git a/State.ts b/State.ts
index 0f3e43d124..2be700e456 100644
--- a/State.ts
+++ b/State.ts
@@ -4,7 +4,6 @@ import {ElementStorage} from "./Logic/ElementStorage";
import {Changes} from "./Logic/Osm/Changes";
import {OsmConnection} from "./Logic/Osm/OsmConnection";
import Locale from "./UI/i18n/Locale";
-import Translations from "./UI/i18n/Translations";
import {UIEventSource} from "./Logic/UIEventSource";
import {LocalStorageSource} from "./Logic/Web/LocalStorageSource";
import {QueryParameters} from "./Logic/Web/QueryParameters";
@@ -18,6 +17,7 @@ import Constants from "./Models/Constants";
import UpdateFromOverpass from "./Logic/Actors/UpdateFromOverpass";
import LayerConfig from "./Customizations/JSON/LayerConfig";
+import TitleHandler from "./Logic/Actors/TitleHandler";
/**
* Contains the global state: a bunch of UI-event sources
@@ -75,7 +75,7 @@ export default class State {
/**
This message is shown full screen on mobile devices
*/
- public readonly fullScreenMessage = new UIEventSource(undefined)
+ public readonly fullScreenMessage = new UIEventSource<{ content: UIElement, hashText: string, titleText?: UIElement }>(undefined)
/**
The latest element that was selected - used to generate the right UI at the right place
@@ -112,9 +112,9 @@ export default class State {
public layoutDefinition: string;
public installedThemes: UIEventSource<{ layout: LayoutConfig; definition: string }[]>;
- public layerControlIsOpened: UIEventSource =
+ public layerControlIsOpened: UIEventSource =
QueryParameters.GetQueryParameter("layer-control-toggle", "false", "Whether or not the layer control is shown")
- .map((str) => str !== "false", [], b => "" + b)
+ .map((str) => str !== "false", [], b => "" + b)
public welcomeMessageOpenedTab = QueryParameters.GetQueryParameter("tab", "0", `The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >${Constants.userJourney.mapCompleteHelpUnlock} changesets)`).map(
str => isNaN(Number(str)) ? 0 : Number(str), [], n => "" + n
@@ -240,13 +240,8 @@ export default class State {
}
}).ping()
- this.layoutToUse.map((layoutToUse) => {
- return Translations.WT(layoutToUse?.title)?.txt ?? "MapComplete"
- }, [Locale.language]
- ).addCallbackAndRun((title) => {
- document.title = title
- });
-
+ new TitleHandler(this.layoutToUse, this.fullScreenMessage);
+
this.allElements = new ElementStorage();
this.changes = new Changes();
diff --git a/UI/FullScreenMessageBoxHandler.ts b/UI/FullScreenMessageBoxHandler.ts
index 0a67765a3f..9fa2493f8d 100644
--- a/UI/FullScreenMessageBoxHandler.ts
+++ b/UI/FullScreenMessageBoxHandler.ts
@@ -19,7 +19,7 @@ export default class FullScreenMessageBox extends UIElement {
if (State.state.fullScreenMessage.data === undefined) {
return "";
}
- this._content = State.state.fullScreenMessage.data;
+ this._content = State.state.fullScreenMessage.data.content;
return new Combine([this._content]).SetClass("fullscreenmessage-content").Render();
}
diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts
index 9ad6f9dfcf..4818e1563d 100644
--- a/UI/Popup/FeatureInfoBox.ts
+++ b/UI/Popup/FeatureInfoBox.ts
@@ -12,6 +12,8 @@ import ScrollableFullScreen from "../Base/ScrollableFullScreen";
export default class FeatureInfoBox extends UIElement {
private _component: UIElement;
+ public title: UIEventSource ;
+
constructor(
tags: UIEventSource,
layerConfig: LayerConfig
@@ -24,6 +26,7 @@ export default class FeatureInfoBox extends UIElement {
const title = new TagRenderingAnswer(tags, layerConfig.title ?? new TagRenderingConfig("POI", undefined))
.SetClass("featureinfobox-title");
+ this.title = title;
const titleIcons = new Combine(
layerConfig.titleIcons.map(icon => new TagRenderingAnswer(tags, icon)))
.SetClass("featureinfobox-icons");
diff --git a/UI/ShowDataLayer.ts b/UI/ShowDataLayer.ts
index 0c9c39b449..1b03a562db 100644
--- a/UI/ShowDataLayer.ts
+++ b/UI/ShowDataLayer.ts
@@ -154,7 +154,7 @@ export default class ShowDataLayer {
this._onSelectedTrigger[feature.properties.id.replace("/","_")] = this._onSelectedTrigger[id];
if (feature.properties.id.replace(/\//g, "_") === Hash.hash.data) {
// This element is in the URL, so this is a share link
- // We already open it
+ // We open the relevant popup straight away
uiElement.Activate();
popup.setContent(uiElement.Render());
diff --git a/index.ts b/index.ts
index 0efc118bc3..eb291a9774 100644
--- a/index.ts
+++ b/index.ts
@@ -6,7 +6,6 @@ import {UIEventSource} from "./Logic/UIEventSource";
import * as $ from "jquery";
import LayoutConfig from "./Customizations/JSON/LayoutConfig";
import {Utils} from "./Utils";
-import {Overpass} from "./Logic/Osm/Overpass";
let defaultLayout = "bookcases"
// --------------------- Special actions based on the parameters -----------------