Fix back button; add title
This commit is contained in:
parent
6e77504854
commit
2f57010202
14 changed files with 115 additions and 43 deletions
|
@ -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.<br/>","ca":"Has marcat un lloc on no coneixem les dades.<br/>","es":"Has marcado un lugar del que no conocemos los datos.<br/>","nl":"Je klikte ergens waar er nog geen data is. Kies hieronder welk punt je wilt toevoegen<br/>","fr":"Vous avez cliqué sur un endroit où il n'y a pas encore de données. <br/>","gl":"Marcaches un lugar onde non coñecemos os datos.<br/>","de":"Sie haben irgendwo geklickt, wo noch keine Daten bekannt sind.<br/>"} ),
|
||||
pleaseLogin: new Translation( {"en":"<a class='activate-osm-authentication'>Please log in to add a new point</a>","ca":"<a class='activate-osm-authentication'>Entra per afegir un nou punt</a>","es":"<a class='activate-osm-authentication'>Entra para añadir un nuevo punto</a>","nl":"<a class='activate-osm-authentication'>Gelieve je aan te melden om een punt to te voegen</a>","fr":"<a class='activate-osm-authentication'>Vous devez vous connecter pour ajouter un point</a>","gl":"<a class='activate-osm-authentication'>Inicia a sesión para engadir un novo punto</a>","de":"<a class='activate-osm-authentication'>Bitte loggen Sie sich ein, um einen neuen Punkt hinzuzufügen</a>"} ),
|
||||
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."} ),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 => {
|
||||
|
|
19
Logic/Actors/HistoryHandling.ts
Normal file
19
Logic/Actors/HistoryHandling.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import {UIEventSource} from "../UIEventSource";
|
||||
import {UIElement} from "../../UI/UIElement";
|
||||
|
||||
export default class HistoryHandling {
|
||||
|
||||
constructor(hash: UIEventSource<string>, fullscreenMessage: UIEventSource<{ content: UIElement, hashText: string }>) {
|
||||
hash.addCallback(h => {
|
||||
if (h === undefined || h === "") {
|
||||
fullscreenMessage.setData(undefined);
|
||||
}
|
||||
})
|
||||
|
||||
fullscreenMessage.addCallback(fs => {
|
||||
hash.setData(fs?.hashText);
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -17,7 +17,7 @@ export default class StrayClickHandler {
|
|||
selectedElement: UIEventSource<string>,
|
||||
filteredLayers: UIEventSource<{ readonly isDisplayed: UIEventSource<boolean> }[]>,
|
||||
leafletMap: UIEventSource<L.Map>,
|
||||
fullscreenMessage: UIEventSource<UIElement>,
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
|
33
Logic/Actors/TitleHandler.ts
Normal file
33
Logic/Actors/TitleHandler.ts
Normal file
|
@ -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<LayoutConfig>, 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;
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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<string> = Hash.Get();
|
||||
|
||||
private static Get() : UIEventSource<string>{
|
||||
if(Utils.runningFromConsole){
|
||||
|
||||
public static hash: UIEventSource<string> = 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<string> {
|
||||
if (Utils.runningFromConsole) {
|
||||
return new UIEventSource<string>(undefined);
|
||||
}
|
||||
const hash = new UIEventSource<string>(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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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());
|
||||
|
||||
}
|
||||
|
||||
|
|
17
State.ts
17
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<UIElement>(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<boolean> =
|
||||
public layerControlIsOpened: UIEventSource<boolean> =
|
||||
QueryParameters.GetQueryParameter("layer-control-toggle", "false", "Whether or not the layer control is shown")
|
||||
.map<boolean>((str) => str !== "false", [], b => "" + b)
|
||||
.map<boolean>((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<number>(
|
||||
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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ import ScrollableFullScreen from "../Base/ScrollableFullScreen";
|
|||
export default class FeatureInfoBox extends UIElement {
|
||||
private _component: UIElement;
|
||||
|
||||
public title: UIEventSource<string> ;
|
||||
|
||||
constructor(
|
||||
tags: UIEventSource<any>,
|
||||
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");
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
1
index.ts
1
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 -----------------
|
||||
|
|
Loading…
Reference in a new issue