Refactored out 'layout.ts'
This commit is contained in:
parent
36f5e896df
commit
73f32e0ecf
30 changed files with 465 additions and 400 deletions
|
@ -120,10 +120,27 @@ export default class AllTranslationAssets {
|
|||
ph_open: new Translation( {"en":"opened","ca":"tancat","es":"abierto","nl":"open"} ),
|
||||
},
|
||||
},
|
||||
favourite: { title: new Translation( {"en":"Personal theme","nl":"Persoonlijk thema","es":"Interficie personal","ca":"Interfície personal","gl":"Tema personalizado","de":"Persönliches Thema"} ),
|
||||
description: new Translation( {"en":"Create a personal theme based on all the available layers of all themes","es":"Crea una interficie basada en todas las capas disponibles de todas las interficies","ca":"Crea una interfície basada en totes les capes disponibles de totes les interfícies","gl":"Crea un tema baseado en todas as capas dispoñíbeis de todos os temas","de":"Erstellen Sie ein persönliches Thema auf der Grundlage aller verfügbaren Ebenen aller Themen"} ),
|
||||
panelIntro: new Translation( {"en":"<h3>Your personal theme</h3>Activate your favourite layers from all the official themes","ca":"<h3>La teva interfície personal</h3>Activa les teves capes favorites de totes les interfícies oficials","es":"<h3>Tu interficie personal</h3>Activa tus capas favoritas de todas las interficies oficiales","gl":"<h3>O teu tema personalizado</h3>Activa as túas capas favoritas de todos os temas oficiais","de":"<h3>Ihr persönliches Thema</h3>Aktivieren Sie Ihre Lieblingsebenen aus allen offiziellen Themen"} ),
|
||||
loginNeeded: new Translation( {"en":"<h3>Log in</h3>A personal layout is only available for OpenStreetMap users","es":"<h3>Entrar</h3>El diseño personalizado sólo está disponible para los usuarios de OpenstreetMap","ca":"<h3>Entrar</h3>El disseny personalizat només està disponible pels usuaris d' OpenstreetMap","gl":"<h3>Iniciar a sesión</h3>O deseño personalizado só está dispoñíbel para os usuarios do OpenstreetMap","de":"<h3>Anmelden</h3>Ein persönliches Layout ist nur für OpenStreetMap-Benutzer verfügbar"} ),
|
||||
reload: new Translation( {"en":"Reload the data","es":"Recargar datos","ca":"Recarregar dades","gl":"Recargar os datos","de":"Daten neu laden"} ),
|
||||
},
|
||||
favourite: {
|
||||
panelIntro: new Translation({
|
||||
"en": "<h3>Your personal theme</h3>Activate your favourite layers from all the official themes",
|
||||
"ca": "<h3>La teva interfície personal</h3>Activa les teves capes favorites de totes les interfícies oficials",
|
||||
"es": "<h3>Tu interficie personal</h3>Activa tus capas favoritas de todas las interficies oficiales",
|
||||
"gl": "<h3>O teu tema personalizado</h3>Activa as túas capas favoritas de todos os temas oficiais",
|
||||
"de": "<h3>Ihr persönliches Thema</h3>Aktivieren Sie Ihre Lieblingsebenen aus allen offiziellen Themen"
|
||||
}),
|
||||
loginNeeded: new Translation({
|
||||
"en": "<h3>Log in</h3>A personal layout is only available for OpenStreetMap users",
|
||||
"es": "<h3>Entrar</h3>El diseño personalizado sólo está disponible para los usuarios de OpenstreetMap",
|
||||
"ca": "<h3>Entrar</h3>El disseny personalizat només està disponible pels usuaris d' OpenstreetMap",
|
||||
"gl": "<h3>Iniciar a sesión</h3>O deseño personalizado só está dispoñíbel para os usuarios do OpenstreetMap",
|
||||
"de": "<h3>Anmelden</h3>Ein persönliches Layout ist nur für OpenStreetMap-Benutzer verfügbar"
|
||||
}),
|
||||
reload: new Translation({
|
||||
"en": "Reload the data",
|
||||
"es": "Recargar datos",
|
||||
"ca": "Recarregar dades",
|
||||
"gl": "Recargar os datos",
|
||||
"de": "Daten neu laden"
|
||||
}),
|
||||
},
|
||||
}}
|
|
@ -1,4 +1,3 @@
|
|||
import {Layout} from "./Layout";
|
||||
import * as bookcases from "../assets/themes/bookcases/Bookcases.json";
|
||||
import * as aed from "../assets/themes/aed/aed.json";
|
||||
import * as toilets from "../assets/themes/toilets/toilets.json";
|
||||
|
@ -15,17 +14,18 @@ import * as fritures from "../assets/themes/fritures/fritures.json"
|
|||
import * as benches from "../assets/themes/benches/benches.json";
|
||||
import * as charging_stations from "../assets/themes/charging_stations/charging_stations.json"
|
||||
import * as widths from "../assets/themes/widths/width.json"
|
||||
|
||||
import {PersonalLayout} from "../Logic/PersonalLayout";
|
||||
import * as drinking_water from "../assets/themes/drinking_water/drinking_water.json"
|
||||
import LayerConfig from "./JSON/LayerConfig";
|
||||
import SharedLayers from "./SharedLayers";
|
||||
import * as personal from "../assets/themes/personalLayout/personalLayout.json"
|
||||
import LayoutConfig from "./JSON/LayoutConfig";
|
||||
|
||||
export class AllKnownLayouts {
|
||||
|
||||
public static allLayers: Map<string, LayerConfig> = undefined;
|
||||
|
||||
private static GenerateCycloFix(): Layout {
|
||||
const layout = Layout.LayoutFromJSON(cyclofix, SharedLayers.sharedLayers)
|
||||
private static GenerateCycloFix(): LayoutConfig {
|
||||
const layout = new LayoutConfig(cyclofix)
|
||||
const now = new Date();
|
||||
const m = now.getMonth() + 1;
|
||||
const day = new Date().getDate() + 1;
|
||||
|
@ -41,63 +41,31 @@ export class AllKnownLayouts {
|
|||
return layout;
|
||||
|
||||
}
|
||||
|
||||
private static GenerateWidths(): Layout {
|
||||
const layout = Layout.LayoutFromJSON(widths, SharedLayers.sharedLayers);
|
||||
|
||||
layout.enableUserBadge = false;
|
||||
layout.enableShareScreen = false;
|
||||
layout.enableMoreQuests = false;
|
||||
layout.enableLayers = false;
|
||||
layout.hideFromOverview = true;
|
||||
layout.enableSearch = false;
|
||||
layout.enableGeolocation = false;
|
||||
return layout;
|
||||
}
|
||||
|
||||
private static GenerateBuurtNatuur(): Layout {
|
||||
const layout = Layout.LayoutFromJSON(buurtnatuur, SharedLayers.sharedLayers);
|
||||
layout.enableMoreQuests = false;
|
||||
layout.enableShareScreen = false;
|
||||
layout.hideFromOverview = true;
|
||||
console.log("Buurtnatuur:",layout)
|
||||
return layout;
|
||||
}
|
||||
|
||||
private static GenerateBikeMonitoringStations(): Layout {
|
||||
const layout = Layout.LayoutFromJSON(bike_monitoring_stations, SharedLayers.sharedLayers);
|
||||
layout.hideFromOverview = true;
|
||||
return layout;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static layoutsList: Layout[] = [
|
||||
new PersonalLayout(),
|
||||
|
||||
Layout.LayoutFromJSON(shops, SharedLayers.sharedLayers),
|
||||
Layout.LayoutFromJSON(bookcases, SharedLayers.sharedLayers),
|
||||
Layout.LayoutFromJSON(aed, SharedLayers.sharedLayers),
|
||||
Layout.LayoutFromJSON(toilets, SharedLayers.sharedLayers),
|
||||
Layout.LayoutFromJSON(artworks, SharedLayers.sharedLayers),
|
||||
public static layoutsList: LayoutConfig[] = [
|
||||
new LayoutConfig(personal),
|
||||
AllKnownLayouts.GenerateCycloFix(),
|
||||
Layout.LayoutFromJSON(ghostbikes, SharedLayers.sharedLayers),
|
||||
Layout.LayoutFromJSON(nature, SharedLayers.sharedLayers),
|
||||
Layout.LayoutFromJSON(cyclestreets, SharedLayers.sharedLayers),
|
||||
Layout.LayoutFromJSON(maps, SharedLayers.sharedLayers),
|
||||
Layout.LayoutFromJSON(fritures, SharedLayers.sharedLayers),
|
||||
Layout.LayoutFromJSON(benches, SharedLayers.sharedLayers),
|
||||
Layout.LayoutFromJSON(charging_stations, SharedLayers.sharedLayers),
|
||||
AllKnownLayouts.GenerateWidths(),
|
||||
AllKnownLayouts.GenerateBuurtNatuur(),
|
||||
AllKnownLayouts.GenerateBikeMonitoringStations(),
|
||||
|
||||
new LayoutConfig(aed),
|
||||
new LayoutConfig(bookcases),
|
||||
new LayoutConfig(toilets),
|
||||
new LayoutConfig(artworks),
|
||||
new LayoutConfig(ghostbikes),
|
||||
new LayoutConfig(shops),
|
||||
new LayoutConfig(drinking_water),
|
||||
new LayoutConfig(nature),
|
||||
new LayoutConfig(cyclestreets),
|
||||
new LayoutConfig(maps),
|
||||
new LayoutConfig(fritures),
|
||||
new LayoutConfig(benches),
|
||||
new LayoutConfig(charging_stations),
|
||||
new LayoutConfig(widths),
|
||||
new LayoutConfig(buurtnatuur),
|
||||
new LayoutConfig(bike_monitoring_stations),
|
||||
];
|
||||
|
||||
|
||||
public static allSets: Map<string, Layout> = AllKnownLayouts.AllLayouts();
|
||||
public static allSets: Map<string, LayoutConfig> = AllKnownLayouts.AllLayouts();
|
||||
|
||||
private static AllLayouts(): Map<string, Layout> {
|
||||
private static AllLayouts(): Map<string, LayoutConfig> {
|
||||
this.allLayers = new Map<string, LayerConfig>();
|
||||
for (const layout of this.layoutsList) {
|
||||
for (let i = 0; i < layout.layers.length; i++) {
|
||||
|
@ -118,7 +86,7 @@ export class AllKnownLayouts {
|
|||
}
|
||||
}
|
||||
|
||||
const allSets: Map<string, Layout> = new Map();
|
||||
const allSets: Map<string, LayoutConfig> = new Map();
|
||||
for (const layout of this.layoutsList) {
|
||||
allSets[layout.id] = layout;
|
||||
allSets[layout.id.toLowerCase()] = layout;
|
||||
|
|
|
@ -2,35 +2,9 @@ import {AndOrTagConfigJson} from "./TagConfigJson";
|
|||
import {And, Or, RegexTag, Tag, TagsFilter} from "../../Logic/Tags";
|
||||
|
||||
import {Utils} from "../../Utils";
|
||||
import {Translation} from "../../UI/i18n/Translation";
|
||||
|
||||
export class FromJSON {
|
||||
|
||||
|
||||
public static Translation(json: string | any): Translation {
|
||||
if (json === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof (json) === "string") {
|
||||
return new Translation({"*": json});
|
||||
}
|
||||
if(json.render !== undefined){
|
||||
console.error("Using a 'render' where a translation is expected. Content is", json.render);
|
||||
throw "ERROR: using a 'render' where none is expected"
|
||||
}
|
||||
const tr = {};
|
||||
let keyCount = 0;
|
||||
for (let key in json) {
|
||||
keyCount++;
|
||||
tr[key] = json[key]; // I'm doing this wrong, I know
|
||||
}
|
||||
if(keyCount == 0){
|
||||
return undefined;
|
||||
}
|
||||
const transl = new Translation(tr);
|
||||
return transl;
|
||||
}
|
||||
|
||||
public static SimpleTag(json: string): Tag {
|
||||
const tag = Utils.SplitFirst(json, "=");
|
||||
return new Tag(tag[0], tag[1]);
|
||||
|
|
98
Customizations/JSON/LayoutConfig.ts
Normal file
98
Customizations/JSON/LayoutConfig.ts
Normal file
|
@ -0,0 +1,98 @@
|
|||
import {Translation} from "../../UI/i18n/Translation";
|
||||
import TagRenderingConfig from "./TagRenderingConfig";
|
||||
import LayerConfig from "./LayerConfig";
|
||||
import {LayoutConfigJson} from "./LayoutConfigJson";
|
||||
import SharedLayers from "../SharedLayers";
|
||||
import SharedTagRenderings from "../SharedTagRenderings";
|
||||
|
||||
export default class LayoutConfig {
|
||||
public readonly id: string;
|
||||
public readonly maintainer: string;
|
||||
public readonly changesetmessage?: string;
|
||||
public readonly version: string;
|
||||
public readonly language: string[];
|
||||
public readonly title: Translation;
|
||||
public readonly shortDescription?: Translation;
|
||||
public readonly description: Translation;
|
||||
public readonly descriptionTail?: Translation;
|
||||
public readonly icon: string;
|
||||
public readonly socialImage?: string;
|
||||
public readonly startZoom: number;
|
||||
public readonly startLat: number;
|
||||
public readonly startLon: number;
|
||||
public readonly widenFactor: number;
|
||||
public readonly roamingRenderings: TagRenderingConfig[];
|
||||
public readonly defaultBackgroundId?: string;
|
||||
public readonly layers: LayerConfig[];
|
||||
public readonly hideFromOverview: boolean;
|
||||
public readonly enableUserBadge: boolean;
|
||||
public readonly enableShareScreen: boolean;
|
||||
public readonly enableMoreQuests: boolean;
|
||||
public readonly enableAddNewPoints: boolean;
|
||||
public readonly enableLayers: boolean;
|
||||
public readonly enableSearch: boolean;
|
||||
public readonly enableGeolocation: boolean;
|
||||
public readonly enableBackgroundLayerSelection: boolean;
|
||||
public readonly customCss?: string;
|
||||
|
||||
constructor(json: LayoutConfigJson, context?:string) {
|
||||
this.id = json.id;
|
||||
context = (context ?? "")+"."+this.id;
|
||||
this.maintainer = json.maintainer;
|
||||
this.changesetmessage = json.changesetmessage;
|
||||
this.version = json.version;
|
||||
this.language = [];
|
||||
if (typeof json.language === "string") {
|
||||
this.language = [json.language];
|
||||
} else {
|
||||
this.language = json.language;
|
||||
}
|
||||
if(json.title === undefined){
|
||||
throw "Title not defined in "+this.id;
|
||||
}
|
||||
if(json.description === undefined){
|
||||
throw "Description not defined in "+this.id;
|
||||
}
|
||||
this.title = new Translation(json.title, context+".title");
|
||||
this.description = new Translation(json.description, context+".description");
|
||||
this.shortDescription = json.shortDescription === undefined ? this.description.FirstSentence() : new Translation(json.shortDescription, context+".shortdescription");
|
||||
this.descriptionTail = json.descriptionTail === undefined ? new Translation({"*":""}, context) : new Translation(json.descriptionTail, context+".descriptionTail");
|
||||
this.icon = json.icon;
|
||||
this.socialImage = json.socialImage;
|
||||
this.startZoom = json.startZoom;
|
||||
this.startLat = json.startLat;
|
||||
this.startLon = json.startLon;
|
||||
this.widenFactor = json.widenFactor ?? 0.05;
|
||||
this.roamingRenderings = (json.roamingRenderings ?? []).map((tr, i) => {
|
||||
if (typeof tr === "string") {
|
||||
if (SharedTagRenderings.SharedTagRendering[tr] !== undefined) {
|
||||
return SharedTagRenderings.SharedTagRendering[tr];
|
||||
}
|
||||
}
|
||||
return new TagRenderingConfig(tr, `${this.id}.roaming_renderings[${i}]`);
|
||||
}
|
||||
);
|
||||
this.defaultBackgroundId = json.defaultBackgroundId;
|
||||
this.layers = json.layers.map((layer, i) => {
|
||||
if (typeof layer === "string")
|
||||
if (SharedLayers.sharedLayers[layer] !== undefined) {
|
||||
return SharedLayers.sharedLayers[layer];
|
||||
} else {
|
||||
throw "Unkown fixed layer " + layer;
|
||||
}
|
||||
return new LayerConfig(layer, `${this.id}.layers[${i}]`);
|
||||
});
|
||||
this.hideFromOverview = json.hideFromOverview ?? false;
|
||||
|
||||
this.enableUserBadge = json.enableUserBadge ?? true;
|
||||
this.enableShareScreen = json.enableShareScreen ?? true;
|
||||
this.enableMoreQuests = json.enableMoreQuests ?? true;
|
||||
this.enableLayers = json.enableLayers ?? true;
|
||||
this.enableSearch = json.enableSearch ?? true;
|
||||
this.enableGeolocation = json.enableGeolocation ?? true;
|
||||
this.enableAddNewPoints = json.enableAddNewPoints ?? true;
|
||||
this.enableBackgroundLayerSelection = json.enableBackgroundLayerSelection ?? true;
|
||||
this.customCss = json.customCss;
|
||||
}
|
||||
|
||||
}
|
|
@ -106,9 +106,21 @@ export interface LayoutConfigJson {
|
|||
*/
|
||||
layers: (LayerConfigJson | string)[],
|
||||
|
||||
/**
|
||||
* The URL of a custom CSS stylesheet to modify the layout
|
||||
*/
|
||||
customCss?: string;
|
||||
/**
|
||||
* If set to true, this layout will not be shown in the overview with more themes
|
||||
*/
|
||||
hideFromOverview?: boolean;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enableUserBadge?: boolean;
|
||||
enableShareScreen?: boolean;
|
||||
enableMoreQuests?: boolean;
|
||||
enableLayers?: boolean;
|
||||
enableSearch?: boolean;
|
||||
enableAddNewPoints?: boolean;
|
||||
enableGeolocation?: boolean;
|
||||
enableBackgroundLayerSelection?: boolean;
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
import {UIElement} from "../UI/UIElement";
|
||||
import Translations from "../UI/i18n/Translations";
|
||||
import Combine from "../UI/Base/Combine";
|
||||
import State from "../State";
|
||||
import LayerConfig from "./JSON/LayerConfig";
|
||||
import {LayoutConfigJson} from "./JSON/LayoutConfigJson";
|
||||
import TagRenderingConfig from "./JSON/TagRenderingConfig";
|
||||
import {FromJSON} from "./JSON/FromJSON";
|
||||
import {Translation} from "../UI/i18n/Translation";
|
||||
import Svg from "../Svg";
|
||||
import {Img} from "../UI/Img";
|
||||
|
||||
/**
|
||||
* A layout is a collection of settings of the global view (thus: welcome text, title, selection of layers).
|
||||
*/
|
||||
export class Layout {
|
||||
|
||||
public id: string;
|
||||
public icon: string = Img.AsData(Svg.bug);
|
||||
public title: UIElement;
|
||||
public maintainer: string;
|
||||
public version: string;
|
||||
public description: string | UIElement;
|
||||
public changesetMessage: string;
|
||||
public socialImage: string = "";
|
||||
/**
|
||||
* Custom CSS link
|
||||
*/
|
||||
public customCss: string = undefined;
|
||||
|
||||
public layers: LayerConfig[];
|
||||
public welcomeMessage: UIElement;
|
||||
public gettingStartedPlzLogin: UIElement;
|
||||
public welcomeBackMessage: UIElement;
|
||||
public welcomeTail: UIElement;
|
||||
|
||||
public supportedLanguages: string[];
|
||||
|
||||
public startzoom: number;
|
||||
public startLon: number;
|
||||
public startLat: number;
|
||||
|
||||
public enableAdd: boolean = true;
|
||||
public enableUserBadge: boolean = true;
|
||||
public enableSearch: boolean = true;
|
||||
public enableLayers: boolean = true;
|
||||
public enableBackgroundLayers: boolean = true;
|
||||
public enableMoreQuests: boolean = true;
|
||||
public enableShareScreen: boolean = true;
|
||||
public enableGeolocation: boolean = true;
|
||||
public hideFromOverview: boolean = false;
|
||||
|
||||
/**
|
||||
* The BBOX of the currently visible map are widened by this factor, in order to make some panning possible.
|
||||
* This number influences this
|
||||
*/
|
||||
public widenFactor: number = 0.07;
|
||||
public defaultBackground: string = "osm";
|
||||
|
||||
public static LayoutFromJSON(json: LayoutConfigJson, sharedLayers): Layout {
|
||||
const tr = FromJSON.Translation;
|
||||
const layers = json.layers.map(jsonLayer => {
|
||||
if(typeof jsonLayer === "string"){
|
||||
return sharedLayers[jsonLayer];
|
||||
}
|
||||
return new LayerConfig(jsonLayer, "theme."+json.id);
|
||||
});
|
||||
const roaming: TagRenderingConfig[] = json.roamingRenderings?.map((tr, i) =>
|
||||
new TagRenderingConfig(tr, `theme.${json.id}.roamingRendering[${i}]`)) ?? [];
|
||||
for (const layer of layers) {
|
||||
layer.tagRenderings.push(...roaming);
|
||||
}
|
||||
|
||||
const layout = new Layout(
|
||||
json.id,
|
||||
typeof (json.language) === "string" ? [json.language] : json.language,
|
||||
tr(json.title ?? "Title not defined"),
|
||||
layers,
|
||||
json.startZoom,
|
||||
json.startLat,
|
||||
json.startLon,
|
||||
new Combine(["<h3>", tr(json.title), "</h3>", tr(json.description)]),
|
||||
undefined,
|
||||
undefined,
|
||||
tr(json.descriptionTail)
|
||||
|
||||
);
|
||||
|
||||
layout.defaultBackground = json.defaultBackgroundId ?? "osm";
|
||||
layout.widenFactor = json.widenFactor ?? 0.07;
|
||||
layout.icon = json.icon;
|
||||
layout.maintainer = json.maintainer;
|
||||
layout.version = json.version;
|
||||
layout.socialImage = json.socialImage;
|
||||
layout.description = tr(json.shortDescription) ?? tr(json.description)?.FirstSentence();
|
||||
layout.changesetMessage = json.changesetmessage;
|
||||
return layout;
|
||||
}
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
supportedLanguages: string[],
|
||||
title: Translation | string,
|
||||
layers: LayerConfig[],
|
||||
startzoom: number,
|
||||
startLat: number,
|
||||
startLon: number,
|
||||
welcomeMessage: UIElement | string,
|
||||
gettingStartedPlzLogin: UIElement | string = new Combine([
|
||||
Translations.t.general.getStartedLogin
|
||||
.SetClass("soft")
|
||||
.onClick(() => {State.state.osmConnection.AttemptLogin()}),
|
||||
Translations.t.general.getStartedNewAccount
|
||||
]),
|
||||
welcomeBackMessage: UIElement | string = Translations.t.general.welcomeBack,
|
||||
welcomeTail: UIElement | string = "",
|
||||
) {
|
||||
this.supportedLanguages = supportedLanguages;
|
||||
this.title = Translations.WT(title)
|
||||
this.startLon = startLon;
|
||||
this.startLat = startLat;
|
||||
this.startzoom = startzoom;
|
||||
this.id = id;
|
||||
this.layers = layers;
|
||||
this.welcomeMessage = Translations.W(welcomeMessage)
|
||||
this.gettingStartedPlzLogin = Translations.W(gettingStartedPlzLogin);
|
||||
this.welcomeBackMessage = Translations.W(welcomeBackMessage);
|
||||
this.welcomeTail = Translations.W(welcomeTail);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,6 @@ import {VariableUiElement} from "./UI/Base/VariableUIElement";
|
|||
import {UpdateFromOverpass} from "./Logic/UpdateFromOverpass";
|
||||
import {UIEventSource} from "./Logic/UIEventSource";
|
||||
import {QueryParameters} from "./Logic/Web/QueryParameters";
|
||||
import {PersonalLayout} from "./Logic/PersonalLayout";
|
||||
import {PersonalLayersPanel} from "./Logic/PersonalLayersPanel";
|
||||
import Locale from "./UI/i18n/Locale";
|
||||
import {StrayClickHandler} from "./Logic/Leaflet/StrayClickHandler";
|
||||
|
@ -27,15 +26,15 @@ import {UserBadge} from "./UI/UserBadge";
|
|||
import {SearchAndGo} from "./UI/SearchAndGo";
|
||||
import {FullScreenMessageBox} from "./UI/FullScreenMessageBoxHandler";
|
||||
import {GeoLocationHandler} from "./Logic/Leaflet/GeoLocationHandler";
|
||||
import {Layout} from "./Customizations/Layout";
|
||||
import {LocalStorageSource} from "./Logic/Web/LocalStorageSource";
|
||||
import {Utils} from "./Utils";
|
||||
import BackgroundSelector from "./UI/BackgroundSelector";
|
||||
import AvailableBaseLayers from "./Logic/AvailableBaseLayers";
|
||||
import {FeatureInfoBox} from "./UI/Popup/FeatureInfoBox";
|
||||
import SharedLayers from "./Customizations/SharedLayers";
|
||||
import Svg from "./Svg";
|
||||
import Link from "./UI/Base/Link";
|
||||
import * as personal from "./assets/themes/personalLayout/personalLayout.json"
|
||||
import LayoutConfig from "./Customizations/JSON/LayoutConfig";
|
||||
|
||||
export class InitUiElements {
|
||||
|
||||
|
@ -74,7 +73,7 @@ export class InitUiElements {
|
|||
|
||||
}
|
||||
|
||||
static InitAll(layoutToUse: Layout, layoutFromBase64: string, testing: UIEventSource<string>, layoutName: string,
|
||||
static InitAll(layoutToUse: LayoutConfig, layoutFromBase64: string, testing: UIEventSource<string>, layoutName: string,
|
||||
layoutDefinition: string = "") {
|
||||
if (layoutToUse === undefined) {
|
||||
console.log("Incorrect layout")
|
||||
|
@ -115,7 +114,7 @@ export class InitUiElements {
|
|||
function updateFavs() {
|
||||
const favs = State.state.favouriteLayers.data ?? [];
|
||||
|
||||
layoutToUse.layers = [];
|
||||
layoutToUse.layers.splice(0, layoutToUse.layers.length);
|
||||
for (const fav of favs) {
|
||||
const layer = AllKnownLayouts.allLayers[fav];
|
||||
if (!!layer) {
|
||||
|
@ -140,8 +139,7 @@ export class InitUiElements {
|
|||
|
||||
}
|
||||
|
||||
if (layoutToUse === AllKnownLayouts.allSets[PersonalLayout.NAME]) {
|
||||
|
||||
if (layoutToUse.id === personal.id) {
|
||||
State.state.favouriteLayers.addCallback(updateFavs);
|
||||
State.state.installedThemes.addCallback(updateFavs);
|
||||
}
|
||||
|
@ -208,15 +206,8 @@ export class InitUiElements {
|
|||
.SetStyle(`position:relative;display:block;border: solid 2px #0005;cursor: pointer; z-index: 999; /*Just below leaflets zoom*/background-color: white;border-radius: 5px;width: 43px;height: 43px;`)
|
||||
.AttachTo("geolocate-button");
|
||||
State.state.locationControl.ping();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static FromBase64(layoutFromBase64: string): Layout {
|
||||
return Layout.LayoutFromJSON(JSON.parse(atob(layoutFromBase64)), SharedLayers.sharedLayers);
|
||||
}
|
||||
|
||||
|
||||
static LoadLayoutFromHash(userLayoutParam: UIEventSource<string>) {
|
||||
try {
|
||||
let hash = location.hash.substr(1);
|
||||
|
@ -236,7 +227,7 @@ export class InitUiElements {
|
|||
hashFromLocalStorage.setData(hash);
|
||||
dedicatedHashFromLocalStorage.setData(hash);
|
||||
}
|
||||
const layoutToUse = InitUiElements.FromBase64(hash);
|
||||
const layoutToUse = new LayoutConfig(JSON.parse(atob(hash)));
|
||||
userLayoutParam.setData(layoutToUse.id);
|
||||
return layoutToUse;
|
||||
} catch (e) {
|
||||
|
@ -264,7 +255,7 @@ export class InitUiElements {
|
|||
|
||||
const layoutToUse = State.state.layoutToUse.data;
|
||||
let welcome: UIElement = new WelcomeMessage();
|
||||
if (layoutToUse.id === PersonalLayout.NAME) {
|
||||
if (layoutToUse.id === personal.id) {
|
||||
welcome = new PersonalLayersPanel();
|
||||
}
|
||||
|
||||
|
@ -351,7 +342,7 @@ export class InitUiElements {
|
|||
|
||||
|
||||
let layerControlPanel: UIElement = undefined;
|
||||
if (State.state.layoutToUse.data.enableBackgroundLayers) {
|
||||
if (State.state.layoutToUse.data.enableBackgroundLayerSelection) {
|
||||
layerControlPanel = new BackgroundSelector();
|
||||
layerControlPanel.SetStyle("margin:1em");
|
||||
layerControlPanel.onClick(() => { });
|
||||
|
@ -451,7 +442,7 @@ export class InitUiElements {
|
|||
State.state.layerUpdater = new UpdateFromOverpass(State.state);
|
||||
|
||||
State.state.availableBackgroundLayers = new AvailableBaseLayers(State.state).availableEditorLayers;
|
||||
const queryParam = QueryParameters.GetQueryParameter("background", State.state.layoutToUse.data.defaultBackground);
|
||||
const queryParam = QueryParameters.GetQueryParameter("background", State.state.layoutToUse.data.defaultBackgroundId);
|
||||
|
||||
queryParam.addCallbackAndRun((selectedId: string) => {
|
||||
const available = State.state.availableBackgroundLayers.data;
|
||||
|
|
|
@ -246,7 +246,12 @@ export default class MetaTagging {
|
|||
static addMetatags(features: any[]) {
|
||||
|
||||
for (const metatag of MetaTagging.metatags) {
|
||||
metatag.addMetaTags(features);
|
||||
try {
|
||||
metatag.addMetaTags(features);
|
||||
} catch (e) {
|
||||
console.error("Could not calculate metatag ", metatag.keys.join(","), ":", e)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import {OsmConnection, UserDetails} from "./OsmConnection";
|
||||
import {UIEventSource} from "../UIEventSource";
|
||||
import {ElementStorage} from "../ElementStorage";
|
||||
import {Layout} from "../../Customizations/Layout";
|
||||
import State from "../../State";
|
||||
import Locale from "../../UI/i18n/Locale";
|
||||
import LayoutConfig from "../../Customizations/JSON/LayoutConfig";
|
||||
|
||||
export class ChangesetHandler {
|
||||
|
||||
|
@ -26,7 +26,7 @@ export class ChangesetHandler {
|
|||
|
||||
|
||||
public UploadChangeset(
|
||||
layout: Layout,
|
||||
layout: LayoutConfig,
|
||||
allElements: ElementStorage,
|
||||
generateChangeXML: (csid: string) => string,
|
||||
continuation: () => void) {
|
||||
|
@ -85,10 +85,10 @@ export class ChangesetHandler {
|
|||
|
||||
|
||||
private OpenChangeset(
|
||||
layout : Layout,
|
||||
layout : LayoutConfig,
|
||||
continuation: (changesetId: string) => void) {
|
||||
|
||||
const commentExtra = layout.changesetMessage !== undefined ? " - " + layout.changesetMessage : "";
|
||||
const commentExtra = layout.changesetmessage !== undefined ? " - " + layout.changesetmessage : "";
|
||||
|
||||
let surveySource = "";
|
||||
if (State.state.currentGPSLocation.data !== undefined) {
|
||||
|
|
|
@ -3,10 +3,10 @@ import osmAuth from "osm-auth";
|
|||
import {UIEventSource} from "../UIEventSource";
|
||||
import {OsmPreferences} from "./OsmPreferences";
|
||||
import {ChangesetHandler} from "./ChangesetHandler";
|
||||
import {Layout} from "../../Customizations/Layout";
|
||||
import {ElementStorage} from "../ElementStorage";
|
||||
import {Img} from "../../UI/Img";
|
||||
import Svg from "../../Svg";
|
||||
import LayoutConfig from "../../Customizations/JSON/LayoutConfig";
|
||||
|
||||
export class UserDetails {
|
||||
|
||||
|
@ -97,7 +97,7 @@ export class OsmConnection {
|
|||
|
||||
|
||||
public UploadChangeset(
|
||||
layout: Layout,
|
||||
layout: LayoutConfig,
|
||||
allElements: ElementStorage,
|
||||
generateChangeXML: (csid: string) => string,
|
||||
continuation: () => void = () => {}) {
|
||||
|
|
|
@ -5,12 +5,12 @@ import {UIEventSource} from "./UIEventSource";
|
|||
import {AllKnownLayouts} from "../Customizations/AllKnownLayouts";
|
||||
import Combine from "../UI/Base/Combine";
|
||||
import CheckBox from "../UI/Input/CheckBox";
|
||||
import {PersonalLayout} from "./PersonalLayout";
|
||||
import {Layout} from "../Customizations/Layout";
|
||||
import * as personal from "../assets/themes/personalLayout/personalLayout.json";
|
||||
import {SubtleButton} from "../UI/Base/SubtleButton";
|
||||
import {FixedUiElement} from "../UI/Base/FixedUiElement";
|
||||
import {Img} from "../UI/Img";
|
||||
import Svg from "../Svg";
|
||||
import LayoutConfig from "../Customizations/JSON/LayoutConfig";
|
||||
|
||||
export class PersonalLayersPanel extends UIElement {
|
||||
private checkboxes: UIElement[] = [];
|
||||
|
@ -22,19 +22,19 @@ export class PersonalLayersPanel extends UIElement {
|
|||
this.UpdateView([]);
|
||||
const self = this;
|
||||
State.state.installedThemes.addCallback(extraThemes => {
|
||||
self.UpdateView(extraThemes.map(layout => layout.layout));
|
||||
self.UpdateView(extraThemes.map(layout => layout.layout.layoutConfig));
|
||||
self.Update();
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
private UpdateView(extraThemes: Layout[]) {
|
||||
private UpdateView(extraThemes: LayoutConfig[]) {
|
||||
this.checkboxes = [];
|
||||
const favs = State.state.favouriteLayers.data ?? [];
|
||||
const controls = new Map<string, UIEventSource<boolean>>();
|
||||
const allLayouts = AllKnownLayouts.layoutsList.concat(extraThemes);
|
||||
for (const layout of allLayouts) {
|
||||
if (layout.id === PersonalLayout.NAME) {
|
||||
if (layout.id === personal.id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -44,11 +44,15 @@ export class PersonalLayersPanel extends UIElement {
|
|||
"<b>",
|
||||
layout.title,
|
||||
"</b><br/>",
|
||||
layout.description ?? ""
|
||||
layout.shortDescription ?? ""
|
||||
]).SetStyle("background: #eee; display: block; padding: 0.5em; border-radius:0.5em; overflow:auto;")
|
||||
this.checkboxes.push(header);
|
||||
|
||||
for (const layer of layout.layers) {
|
||||
if(layer === undefined){
|
||||
console.warn("Undefined layer for ",layout.id)
|
||||
continue;
|
||||
}
|
||||
if (typeof layer === "string") {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
import {Layout} from "../Customizations/Layout";
|
||||
import Translations from "../UI/i18n/Translations";
|
||||
import {Img} from "../UI/Img";
|
||||
import Svg from "../Svg";
|
||||
|
||||
export class PersonalLayout extends Layout {
|
||||
|
||||
public static NAME: string = "personal";
|
||||
|
||||
constructor() {
|
||||
super(
|
||||
PersonalLayout.NAME,
|
||||
["en"],
|
||||
Translations.t.favourite.title,
|
||||
[],
|
||||
12,
|
||||
0,
|
||||
0,
|
||||
Translations.t.favourite.description,
|
||||
);
|
||||
this.maintainer = "MapComplete"
|
||||
this.description = "The personal theme allows to select one or more layers from all the layouts, creating a truly personal editor"
|
||||
this.icon = Img.AsData(Svg.add)
|
||||
}
|
||||
|
||||
}
|
38
State.ts
38
State.ts
|
@ -1,5 +1,4 @@
|
|||
import {UIElement} from "./UI/UIElement";
|
||||
import {Layout} from "./Customizations/Layout";
|
||||
import {Utils} from "./Utils";
|
||||
import {ElementStorage} from "./Logic/ElementStorage";
|
||||
import {Changes} from "./Logic/Osm/Changes";
|
||||
|
@ -12,6 +11,7 @@ import {UIEventSource} from "./Logic/UIEventSource";
|
|||
import {LocalStorageSource} from "./Logic/Web/LocalStorageSource";
|
||||
import {QueryParameters} from "./Logic/Web/QueryParameters";
|
||||
import {BaseLayer} from "./Logic/BaseLayer";
|
||||
import LayoutConfig from "./Customizations/JSON/LayoutConfig";
|
||||
|
||||
/**
|
||||
* Contains the global state: a bunch of UI-event sources
|
||||
|
@ -40,7 +40,7 @@ export default class State {
|
|||
|
||||
public static runningFromConsole: boolean = false;
|
||||
|
||||
public readonly layoutToUse = new UIEventSource<Layout>(undefined);
|
||||
public readonly layoutToUse = new UIEventSource<LayoutConfig>(undefined);
|
||||
|
||||
/**
|
||||
The mapping from id -> UIEventSource<properties>
|
||||
|
@ -113,7 +113,7 @@ export default class State {
|
|||
accuracy: number
|
||||
}> = new UIEventSource<{ latlng: {lat:number, lng:number}, accuracy: number }>(undefined);
|
||||
public layoutDefinition: string;
|
||||
public installedThemes: UIEventSource<{ layout: Layout; definition: string }[]>;
|
||||
public installedThemes: UIEventSource<{ layout: LayoutConfig; definition: string }[]>;
|
||||
|
||||
public layerControlIsOpened: UIEventSource<boolean> = QueryParameters.GetQueryParameter("layer-control-toggle", "false")
|
||||
.map<boolean>((str) => str !== "false", [], b => "" + b)
|
||||
|
@ -122,7 +122,7 @@ export default class State {
|
|||
str => isNaN(Number(str)) ? 0 : Number(str), [], n => "" + n
|
||||
);
|
||||
|
||||
constructor(layoutToUse: Layout) {
|
||||
constructor(layoutToUse: LayoutConfig) {
|
||||
const self = this;
|
||||
this.layoutToUse.setData(layoutToUse);
|
||||
|
||||
|
@ -138,7 +138,7 @@ export default class State {
|
|||
})
|
||||
}
|
||||
this.zoom = asFloat(
|
||||
QueryParameters.GetQueryParameter("z", "" + layoutToUse.startzoom)
|
||||
QueryParameters.GetQueryParameter("z", "" + layoutToUse.startZoom)
|
||||
.syncWith(LocalStorageSource.Get("zoom")));
|
||||
this.lat = asFloat(QueryParameters.GetQueryParameter("lat", "" + layoutToUse.startLat)
|
||||
.syncWith(LocalStorageSource.Get("lat")));
|
||||
|
@ -158,14 +158,14 @@ export default class State {
|
|||
|
||||
this.layoutToUse.addCallback(layoutToUse => {
|
||||
const lcd = self.locationControl.data;
|
||||
lcd.zoom = lcd.zoom ?? layoutToUse?.startzoom;
|
||||
lcd.zoom = lcd.zoom ?? layoutToUse?.startZoom;
|
||||
lcd.lat = lcd.lat ?? layoutToUse?.startLat;
|
||||
lcd.lon = lcd.lon ?? layoutToUse?.startLon;
|
||||
self.locationControl.ping();
|
||||
});
|
||||
|
||||
|
||||
function featSw(key: string, deflt: (layout: Layout) => boolean): UIEventSource<boolean> {
|
||||
function featSw(key: string, deflt: (layout: LayoutConfig) => boolean): UIEventSource<boolean> {
|
||||
const queryParameterSource = QueryParameters.GetQueryParameter(key, undefined);
|
||||
// I'm so sorry about someone trying to decipher this
|
||||
|
||||
|
@ -182,7 +182,7 @@ export default class State {
|
|||
this.featureSwitchUserbadge = featSw("fs-userbadge", (layoutToUse) => layoutToUse?.enableUserBadge ?? true);
|
||||
this.featureSwitchSearch = featSw("fs-search", (layoutToUse) => layoutToUse?.enableSearch ?? true);
|
||||
this.featureSwitchLayers = featSw("fs-layers", (layoutToUse) => layoutToUse?.enableLayers ?? true);
|
||||
this.featureSwitchAddNew = featSw("fs-add-new", (layoutToUse) => layoutToUse?.enableAdd ?? true);
|
||||
this.featureSwitchAddNew = featSw("fs-add-new", (layoutToUse) => layoutToUse?.enableAddNewPoints ?? true);
|
||||
this.featureSwitchWelcomeMessage = featSw("fs-welcome-message", () => true);
|
||||
this.featureSwitchIframe = featSw("fs-iframe", () => false);
|
||||
this.featureSwitchMoreQuests = featSw("fs-more-quests", (layoutToUse) => layoutToUse?.enableMoreQuests ?? true);
|
||||
|
@ -198,8 +198,8 @@ export default class State {
|
|||
);
|
||||
|
||||
|
||||
this.installedThemes = this.osmConnection.preferencesHandler.preferences.map<{ layout: Layout, definition: string }[]>(allPreferences => {
|
||||
const installedThemes: { layout: Layout, definition: string }[] = [];
|
||||
this.installedThemes = this.osmConnection.preferencesHandler.preferences.map<{ layout: LayoutConfig, definition: string }[]>(allPreferences => {
|
||||
const installedThemes: { layout: LayoutConfig, definition: string }[] = [];
|
||||
if (allPreferences === undefined) {
|
||||
return installedThemes;
|
||||
}
|
||||
|
@ -208,18 +208,13 @@ export default class State {
|
|||
const themename = allPreferencesKey.match(/^mapcomplete-installed-theme-(.*)-combined-length$/);
|
||||
if (themename && themename[1] !== "") {
|
||||
const customLayout = self.osmConnection.GetLongPreference("installed-theme-" + themename[1]);
|
||||
if(customLayout.data === undefined){
|
||||
if (customLayout.data === undefined) {
|
||||
console.log("No data defined for ", themename[1]);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
const layout = State.FromBase64(customLayout.data);
|
||||
if(layout.id === undefined){
|
||||
// This is an old style theme
|
||||
// We remove it
|
||||
customLayout.setData(undefined);
|
||||
continue;
|
||||
}
|
||||
const layout = new LayoutConfig(
|
||||
JSON.parse(btoa(customLayout.data)));
|
||||
installedThemes.push({
|
||||
layout: layout,
|
||||
definition: customLayout.data
|
||||
|
@ -257,10 +252,10 @@ export default class State {
|
|||
if (layoutToUse === undefined) {
|
||||
return;
|
||||
}
|
||||
if (this.layoutToUse.data.supportedLanguages.indexOf(currentLanguage) < 0) {
|
||||
console.log("Resetting language to", layoutToUse.supportedLanguages[0], "as", currentLanguage, " is unsupported")
|
||||
if (this.layoutToUse.data.language.indexOf(currentLanguage) < 0) {
|
||||
console.log("Resetting language to", layoutToUse.language[0], "as", currentLanguage, " is unsupported")
|
||||
// The current language is not supported -> switch to a supported one
|
||||
Locale.language.setData(layoutToUse.supportedLanguages[0]);
|
||||
Locale.language.setData(layoutToUse.language[0]);
|
||||
}
|
||||
}).ping()
|
||||
|
||||
|
@ -288,5 +283,4 @@ export default class State {
|
|||
|
||||
}
|
||||
|
||||
public static FromBase64 : (data: string) => Layout = undefined;
|
||||
}
|
||||
|
|
|
@ -6,11 +6,9 @@ import Combine from "./Base/Combine";
|
|||
import {SubtleButton} from "./Base/SubtleButton";
|
||||
import State from "../State";
|
||||
import {VariableUiElement} from "./Base/VariableUIElement";
|
||||
import {PersonalLayout} from "../Logic/PersonalLayout";
|
||||
import {Layout} from "../Customizations/Layout";
|
||||
import Svg from "../Svg";
|
||||
import {Img} from "./Img";
|
||||
|
||||
import LayoutConfig from "../Customizations/JSON/LayoutConfig";
|
||||
import * as personal from "../assets/themes/personalLayout/personalLayout.json"
|
||||
|
||||
export class MoreScreen extends UIElement {
|
||||
|
||||
|
@ -21,7 +19,7 @@ export class MoreScreen extends UIElement {
|
|||
this.ListenTo(State.state.installedThemes);
|
||||
}
|
||||
|
||||
private createLinkButton(layout: Layout, customThemeDefinition: string = undefined) {
|
||||
private createLinkButton(layout: LayoutConfig, customThemeDefinition: string = undefined) {
|
||||
if (layout === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -53,7 +51,7 @@ export class MoreScreen extends UIElement {
|
|||
|
||||
}
|
||||
|
||||
let description = Translations.W(layout.description);
|
||||
let description = Translations.W(layout.shortDescription);
|
||||
if (description !== undefined) {
|
||||
description = new Combine(["<br/>", description]);
|
||||
}
|
||||
|
@ -88,8 +86,8 @@ export class MoreScreen extends UIElement {
|
|||
|
||||
|
||||
for (const k in AllKnownLayouts.allSets) {
|
||||
const layout : Layout = AllKnownLayouts.allSets[k];
|
||||
if (k === PersonalLayout.NAME) {
|
||||
const layout : LayoutConfig = AllKnownLayouts.allSets[k];
|
||||
if (k === personal.id) {
|
||||
if (State.state.osmConnection.userDetails.data.csCount < State.userJourney.personalLayoutUnlock) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -5,16 +5,15 @@ import Combine from "./Base/Combine";
|
|||
import {VariableUiElement} from "./Base/VariableUIElement";
|
||||
import CheckBox from "./Input/CheckBox";
|
||||
import {VerticalCombine} from "./Base/VerticalCombine";
|
||||
import {Img} from "./Img";
|
||||
import State from "../State";
|
||||
import {Basemap} from "../Logic/Leaflet/Basemap";
|
||||
import {FilteredLayer} from "../Logic/FilteredLayer";
|
||||
import {Utils} from "../Utils";
|
||||
import {UIEventSource} from "../Logic/UIEventSource";
|
||||
import {SubtleButton} from "./Base/SubtleButton";
|
||||
import {Layout} from "../Customizations/Layout";
|
||||
import Svg from "../Svg";
|
||||
import {Translation} from "./i18n/Translation";
|
||||
import LayoutConfig from "../Customizations/JSON/LayoutConfig";
|
||||
|
||||
export class ShareScreen extends UIElement {
|
||||
private readonly _options: UIElement;
|
||||
|
@ -24,7 +23,7 @@ export class ShareScreen extends UIElement {
|
|||
private readonly _linkStatus: UIEventSource<string | UIElement>;
|
||||
private readonly _editLayout: UIElement;
|
||||
|
||||
constructor(layout: Layout = undefined, layoutDefinition: string = undefined) {
|
||||
constructor(layout: LayoutConfig = undefined, layoutDefinition: string = undefined) {
|
||||
super(undefined)
|
||||
layout = layout ?? State.state?.layoutToUse?.data;
|
||||
layoutDefinition = layoutDefinition ?? State.state?.layoutDefinition;
|
||||
|
@ -164,12 +163,12 @@ export class ShareScreen extends UIElement {
|
|||
}, optionParts);
|
||||
|
||||
|
||||
this.iframe = url.map(url => `<iframe src="${url}" width="100%" height="100%" title="${layout.title?.InnerRender()??"MapComplete"} with MapComplete"></iframe>`);
|
||||
this.iframe = url.map(url => `<iframe src="${url}" width="100%" height="100%" title="${layout?.title?.txt ?? "MapComplete"} with MapComplete"></iframe>`);
|
||||
|
||||
this._iframeCode = new VariableUiElement(
|
||||
url.map((url) => {
|
||||
return `<span class='literal-code iframe-code-block'>
|
||||
<iframe src="${url}" width="100%" height="100%" title="${layout.title?.InnerRender() ?? "MapComplete"} with MapComplete"></iframe>
|
||||
<iframe src="${url}" width="100%" height="100%" title="${layout.title?.txt ?? "MapComplete"} with MapComplete"></iframe>
|
||||
</span>`
|
||||
})
|
||||
);
|
||||
|
|
|
@ -26,7 +26,7 @@ export class UserBadge extends UIElement {
|
|||
constructor() {
|
||||
super(State.state.osmConnection.userDetails);
|
||||
this._userDetails = State.state.osmConnection.userDetails;
|
||||
this._languagePicker = (LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.data.supportedLanguages) ?? new FixedUiElement(""))
|
||||
this._languagePicker = (LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.data.language) ?? new FixedUiElement(""))
|
||||
.SetStyle("display:inline-block;width:min-content;");
|
||||
|
||||
this._loginButton = Translations.t.general.loginWithOpenStreetMap
|
||||
|
|
|
@ -18,17 +18,24 @@ export class WelcomeMessage extends UIElement {
|
|||
constructor() {
|
||||
super(State.state.osmConnection.userDetails);
|
||||
this.ListenTo(Locale.language);
|
||||
this.languagePicker = LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.data.supportedLanguages, Translations.t.general.pickLanguage);
|
||||
this.languagePicker = LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.data.language, Translations.t.general.pickLanguage);
|
||||
const layout = State.state.layoutToUse.data;
|
||||
|
||||
this.description =Translations.W(layout.welcomeMessage);
|
||||
this.description = new Combine([
|
||||
"<h3>", layout.title, "</h3>",
|
||||
layout.description
|
||||
|
||||
])
|
||||
layout.descriptionTail
|
||||
|
||||
|
||||
this.plzLogIn =
|
||||
Translations.W(layout.gettingStartedPlzLogin)
|
||||
Translations.t.general.loginWithOpenStreetMap
|
||||
.onClick(() => {
|
||||
State.state.osmConnection.AttemptLogin()
|
||||
});
|
||||
this.welcomeBack = Translations.W(layout.welcomeBackMessage);
|
||||
this.tail = Translations.W(layout.welcomeTail);
|
||||
this.welcomeBack = Translations.t.general.welcomeBack;
|
||||
this.tail = layout.descriptionTail;
|
||||
}
|
||||
|
||||
InnerRender(): string {
|
||||
|
|
|
@ -7,6 +7,24 @@ export class Translation extends UIElement {
|
|||
|
||||
private static forcedLanguage = undefined;
|
||||
|
||||
public readonly translations: object
|
||||
|
||||
constructor(translations: object, context?: string) {
|
||||
super(Locale.language)
|
||||
if(translations === undefined){
|
||||
throw `Translation without content (${context})`
|
||||
}
|
||||
let count = 0;
|
||||
for (const translationsKey in translations) {
|
||||
count++;
|
||||
}
|
||||
this.translations = translations;
|
||||
if(count === 0){
|
||||
throw `No translations given in the object (${context})`
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Subs(text: any): Translation {
|
||||
const newTranslations = {};
|
||||
for (const lang in this.translations) {
|
||||
|
@ -56,7 +74,7 @@ export class Translation extends UIElement {
|
|||
return this.translations[i]; // Return a random language
|
||||
}
|
||||
console.error("Missing language ", Locale.language.data, "for", this.translations)
|
||||
return undefined;
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
@ -64,17 +82,6 @@ export class Translation extends UIElement {
|
|||
return this.txt
|
||||
}
|
||||
|
||||
public readonly translations: object
|
||||
|
||||
constructor(translations: object) {
|
||||
super(Locale.language)
|
||||
let count = 0;
|
||||
for (const translationsKey in translations) {
|
||||
count++;
|
||||
}
|
||||
this.translations = translations
|
||||
}
|
||||
|
||||
public replace(a: string, b: string) {
|
||||
if (a.startsWith("{") && a.endsWith("}")) {
|
||||
a = a.substr(1, a.length - 2);
|
||||
|
|
|
@ -10,17 +10,6 @@ export default class Translations {
|
|||
}
|
||||
|
||||
static t = AllTranslationAssets.t;
|
||||
|
||||
private static isTranslation(tr: any): boolean {
|
||||
for (const key in tr) {
|
||||
if (typeof tr[key] !== "string") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static W(s: string | UIElement): UIElement {
|
||||
if (typeof (s) === "string") {
|
||||
return new FixedUiElement(s);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
"language": [
|
||||
"en"
|
||||
],
|
||||
"hideFromOverview": true,
|
||||
"maintainer": "",
|
||||
"icon": "./assets/layers/bike_monitoring_station/monitoring_station.svg",
|
||||
"version": "0",
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
"shortDescription": {
|
||||
"nl": "Met deze tool kan je natuur in je buurt in kaart brengen en meer informatie geven over je favoriete plekje"
|
||||
},
|
||||
"hideFromOverview": true,
|
||||
"enableShareScreen": false,
|
||||
"enableMoreQuests": false,
|
||||
"description": {
|
||||
"nl": "<img style='float:right;margin: 1em;width: 10em;height: auto;' src='./assets/themes/buurtnatuur/groen_logo.svg' alt='logo-groen' class='logo'> <br /><b>Natuur maakt gelukkig.</b> Aan de hand van deze website willen we de natuur dicht bij ons beter inventariseren. Met als doel meer mensen te laten genieten van toegankelijke natuur én te strijden voor meer natuur in onze buurten. \n<ul><li>In welke natuurgebieden kan jij terecht? Hoe toegankelijk zijn ze?</li><li>In welke bossen kan een gezin in jouw gemeente opnieuw op adem komen?</li><li>Op welke onbekende plekjes is het zalig spelen?</li></ul><p>Samen kleuren we heel Vlaanderen en Brussel groen.</p>Blijf op de hoogte van de resultaten van buurtnatuur.be: <a href=\"https://www.groen.be/buurtnatuur\" target='_blank'>meld je aan voor e-mailupdates</a>."
|
||||
},
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="123"
|
||||
height="123"
|
||||
viewBox="0 0 123 123"
|
||||
width="98"
|
||||
height="98"
|
||||
viewBox="0 0 98 98"
|
||||
version="1.1"
|
||||
id="svg42"
|
||||
sodipodi:docname="logo.svg"
|
||||
|
@ -36,17 +36,17 @@
|
|||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1013"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview44"
|
||||
showgrid="false"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="51.676089"
|
||||
inkscape:cy="85.90359"
|
||||
inkscape:cx="-2.2900136"
|
||||
inkscape:cy="62.988337"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
inkscape:current-layer="layer4" />
|
||||
<defs
|
||||
id="defs40">
|
||||
<filter
|
||||
|
@ -105,12 +105,7 @@
|
|||
id="layer4"
|
||||
inkscape:label="pin"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
d="m 66.510602,115.17875 c -1.7831,3.887 -7.3059,3.887 -9.089,0 l -30.7431,-67.009004 c -1.5196,-3.3121 0.9005,-7.085 4.5445,-7.085 h 61.4862 c 3.644,0 6.0641,3.7729 4.5445,7.085 z"
|
||||
id="path2"
|
||||
inkscape:connector-curvature="0"
|
||||
style="display:inline;fill:#e2783d" />
|
||||
transform="translate(-12.466103,-2.0847473)">
|
||||
<circle
|
||||
cx="61.466103"
|
||||
cy="51.084747"
|
||||
|
@ -122,7 +117,8 @@
|
|||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
inkscape:label="re"
|
||||
style="display:inline">
|
||||
style="display:inline"
|
||||
transform="translate(-12.466103,-2.0847473)">
|
||||
<rect
|
||||
style="fill:#fffcff;fill-opacity:1;stroke:#ffffff;stroke-width:3.50900006;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect834"
|
||||
|
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.4 KiB |
22
assets/themes/drinking_water/drinking_water.json
Normal file
22
assets/themes/drinking_water/drinking_water.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"id": "drinking_water",
|
||||
"title": {
|
||||
"en": "Drinking Water",
|
||||
"nl": "Drinkwaterpunten"
|
||||
},
|
||||
"description": {
|
||||
"en": "On this map, publicly accessible drinkging water spots are shown and can be easily added",
|
||||
"nl": "Op deze kaart staan publiek toegankelijke drinkwaterpunten en kan je makkelijk een nieuw drinkwaterpunt toevoegen",
|
||||
},
|
||||
"language": ["en", "nl"],
|
||||
"maintainer": "MapComplete",
|
||||
"icon": "./assets/themes/drinking_water/logo.svg",
|
||||
"version": "0",
|
||||
"startLat": 50.8465573,
|
||||
"defaultBackgroundId": "CartoDB.Voyager",
|
||||
"startLon": 4.3516970,
|
||||
"startZoom": 16,
|
||||
"widenFactor": 0.05,
|
||||
"layers": ["drinking_water"],
|
||||
"roamingRenderings": []
|
||||
}
|
106
assets/themes/drinking_water/logo.svg
Normal file
106
assets/themes/drinking_water/logo.svg
Normal file
|
@ -0,0 +1,106 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="98"
|
||||
height="98"
|
||||
viewBox="0 0 98 98"
|
||||
version="1.1"
|
||||
id="svg27"
|
||||
sodipodi:docname="logo.svg"
|
||||
style="fill:none"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
|
||||
<metadata
|
||||
id="metadata31">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="697"
|
||||
inkscape:window-height="480"
|
||||
id="namedview29"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.9032258"
|
||||
inkscape:cx="49"
|
||||
inkscape:cy="36"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg27" />
|
||||
<circle
|
||||
cx="49"
|
||||
cy="49"
|
||||
r="49"
|
||||
id="circle4"
|
||||
style="fill:#6bc4f7" />
|
||||
<g
|
||||
id="g8"
|
||||
style="filter:url(#filter0_d)">
|
||||
<path
|
||||
d="M 79,41.8705 C 79,39.3976 77.4079,35.6726 74.1327,30.4823 71.8064,26.7956 69.5171,23.8005 69.4208,23.6747 69.0964,23.2513 68.5726,23 68.0144,23 c -0.5582,0 -1.0822,0.2514 -1.4066,0.6748 -0.2291,0.299 -4.7798,6.2642 -7.5136,11.694 C 54.8849,28.8794 50.9494,23.7307 50.9067,23.6748 50.5821,23.2513 50.0582,23 49.5,23 c -0.5582,0 -1.0821,0.2513 -1.4066,0.6747 -0.0466,0.061 -4.7264,6.1834 -9.3404,13.4954 -0.4943,0.7835 -0.9674,1.5491 -1.4235,2.3005 -2.3812,-3.8202 -4.8133,-7.0045 -4.9373,-7.1663 -0.3245,-0.4234 -0.8484,-0.6747 -1.4066,-0.6747 -0.5582,0 -1.082,0.2513 -1.4065,0.6747 -0.0963,0.1257 -2.3856,3.1209 -4.7119,6.8076 C 21.5921,44.3021 20,48.0271 20,50.5 c 0,5.1193 4.0504,9.3732 9.3205,10.1234 C 30.1402,70.3329 38.8775,78 49.5,78 c 11.1619,0 20.2429,-8.4653 20.2429,-18.8705 0,-1.8756 -0.5352,-4.2206 -1.598,-7.0198 C 74.1423,52.0443 79,47.4766 79,41.8705 Z M 23.457,50.5 c 0,-1.043 0.5687,-3.6947 4.3774,-9.7344 1.1411,-1.8094 2.2916,-3.4709 3.1512,-4.6727 1.172,1.6389 2.8862,4.1349 4.3885,6.7079 -3.4518,6.0994 -5.4558,10.9816 -5.9787,14.5599 C 26.0053,56.6784 23.457,53.8613 23.457,50.5 Z M 49.5,74.7773 c -9.2557,0 -16.7858,-7.0195 -16.7858,-15.6478 0,-2.7503 1.5624,-8.5056 9.0059,-20.3054 3.0174,-4.7834 6.0639,-9.0496 7.7799,-11.3887 1.713,2.3348 4.7519,6.5904 7.7673,11.3688 7.4539,11.8125 9.0184,17.5731 9.0184,20.3254 10e-5,8.6282 -7.53,15.6477 -16.7857,15.6477 z M 68.0144,48.8887 c -0.4308,0 -0.8584,-0.0338 -1.2782,-0.1008 -1.3649,-2.9346 -3.199,-6.2819 -5.4645,-9.9716 1.536,-3.812 4.8482,-8.7016 6.7432,-11.3525 0.8558,1.1963 1.9999,2.8487 3.1381,4.6524 3.8197,6.0532 4.39,8.7095 4.39,9.7543 0,3.8697 -3.3774,7.0182 -7.5286,7.0182 z"
|
||||
id="path6"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffffff" />
|
||||
</g>
|
||||
<defs
|
||||
id="defs25">
|
||||
<filter
|
||||
id="filter0_d"
|
||||
x="16"
|
||||
y="23"
|
||||
width="67"
|
||||
height="63"
|
||||
filterUnits="userSpaceOnUse"
|
||||
style="color-interpolation-filters:sRGB">
|
||||
<feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood10" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
id="feColorMatrix12" />
|
||||
<feOffset
|
||||
dy="4"
|
||||
id="feOffset14" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="2"
|
||||
id="feGaussianBlur16" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
||||
id="feColorMatrix18" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow"
|
||||
id="feBlend20" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow"
|
||||
result="shape"
|
||||
id="feBlend22" />
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
|
@ -251,6 +251,5 @@
|
|||
"wayHandling": 1
|
||||
}
|
||||
],
|
||||
"roamingRenderings": [],
|
||||
"shortDescription": {}
|
||||
"roamingRenderings": []
|
||||
}
|
37
assets/themes/personalLayout/personalLayout.json
Normal file
37
assets/themes/personalLayout/personalLayout.json
Normal file
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"id": "personal",
|
||||
"title": {
|
||||
"en": "Personal theme",
|
||||
"nl": "Persoonlijk thema",
|
||||
"es": "Interficie personal",
|
||||
"ca": "Interfície personal",
|
||||
"gl": "Tema personalizado",
|
||||
"de": "Persönliches Thema"
|
||||
},
|
||||
"description": {
|
||||
"en": "Create a personal theme based on all the available layers of all themes",
|
||||
"es": "Crea una interficie basada en todas las capas disponibles de todas las interficies",
|
||||
"ca": "Crea una interfície basada en totes les capes disponibles de totes les interfícies",
|
||||
"gl": "Crea un tema baseado en todas as capas dispoñíbeis de todos os temas",
|
||||
"de": "Erstellen Sie ein persönliches Thema auf der Grundlage aller verfügbaren Ebenen aller Themen"
|
||||
},
|
||||
"language": [
|
||||
"en",
|
||||
"nl",
|
||||
"es",
|
||||
"ca",
|
||||
"gl",
|
||||
"de"
|
||||
],
|
||||
"maintainer": "MapComplete",
|
||||
"icon": "./assets/svg/addSmall.svg",
|
||||
"version": "0",
|
||||
"startLat": 0,
|
||||
"startLon": 0,
|
||||
"startZoom": 16,
|
||||
"widenFactor": 0.05,
|
||||
"layers": [
|
||||
"drinking_water"
|
||||
],
|
||||
"roamingRenderings": []
|
||||
}
|
|
@ -12,6 +12,15 @@
|
|||
"language": [
|
||||
"nl"
|
||||
],
|
||||
"hideFromOverview": true,
|
||||
|
||||
"enableUserBadge": false,
|
||||
"enableShareScreen":false,
|
||||
"enableMoreQuests": false,
|
||||
"enableLayers":false,
|
||||
"enableSearch": false,
|
||||
"enableGeolocation":false,
|
||||
|
||||
"maintainer": "",
|
||||
"icon": "./assets/themes/widths/icon.svg",
|
||||
"version": "0",
|
||||
|
|
|
@ -886,21 +886,6 @@
|
|||
}
|
||||
},
|
||||
"favourite": {
|
||||
"title": {
|
||||
"en": "Personal theme",
|
||||
"nl": "Persoonlijk thema",
|
||||
"es": "Interficie personal",
|
||||
"ca": "Interfície personal",
|
||||
"gl": "Tema personalizado",
|
||||
"de": "Persönliches Thema"
|
||||
},
|
||||
"description": {
|
||||
"en": "Create a personal theme based on all the available layers of all themes",
|
||||
"es": "Crea una interficie basada en todas las capas disponibles de todas las interficies",
|
||||
"ca": "Crea una interfície basada en totes les capes disponibles de totes les interfícies",
|
||||
"gl": "Crea un tema baseado en todas as capas dispoñíbeis de todos os temas",
|
||||
"de": "Erstellen Sie ein persönliches Thema auf der Grundlage aller verfügbaren Ebenen aller Themen"
|
||||
},
|
||||
"panelIntro": {
|
||||
"en": "<h3>Your personal theme</h3>Activate your favourite layers from all the official themes",
|
||||
"ca": "<h3>La teva interfície personal</h3>Activa les teves capes favorites de totes les interfícies oficials",
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import {Img} from "./UI/Img"
|
||||
|
||||
Img.runningFromConsole = true;
|
||||
import {UIElement} from "./UI/UIElement";
|
||||
// We HAVE to mark this while importing
|
||||
UIElement.runningFromConsole = true;
|
||||
import {AllKnownLayouts} from "./Customizations/AllKnownLayouts";
|
||||
import {Layout} from "./Customizations/Layout";
|
||||
import {readFileSync, writeFile, writeFileSync} from "fs";
|
||||
import Locale from "./UI/i18n/Locale";
|
||||
import svg2img from 'promise-svg2img';
|
||||
import Translations from "./UI/i18n/Translations";
|
||||
import {Translation} from "./UI/i18n/Translation";
|
||||
import LayoutConfig from "./Customizations/JSON/LayoutConfig";
|
||||
|
||||
Img.runningFromConsole = true;
|
||||
// We HAVE to mark this while importing
|
||||
UIElement.runningFromConsole = true;
|
||||
|
||||
function enc(str: string): string {
|
||||
return encodeURIComponent(str.toLowerCase());
|
||||
}
|
||||
|
||||
function validate(layout: Layout) {
|
||||
function validate(layout: LayoutConfig) {
|
||||
const translations: Translation[] = [];
|
||||
const queue: any[] = [layout]
|
||||
|
||||
|
@ -38,7 +38,7 @@ function validate(layout: Layout) {
|
|||
|
||||
const missing = {}
|
||||
const present = {}
|
||||
for (const ln of layout.supportedLanguages) {
|
||||
for (const ln of layout.language) {
|
||||
missing[ln] = 0;
|
||||
present[ln] = 0;
|
||||
for (const translation of translations) {
|
||||
|
@ -58,7 +58,7 @@ function validate(layout: Layout) {
|
|||
|
||||
let message = `Translation completenes for theme ${layout.id}`
|
||||
let isComplete = true;
|
||||
for (const ln of layout.supportedLanguages) {
|
||||
for (const ln of layout.language) {
|
||||
const amiss = missing[ln];
|
||||
const ok = present[ln];
|
||||
const total = amiss + ok;
|
||||
|
@ -75,11 +75,11 @@ function validate(layout: Layout) {
|
|||
|
||||
}
|
||||
|
||||
function generateWikiEntry(layout: Layout){
|
||||
function generateWikiEntry(layout: LayoutConfig){
|
||||
if(layout.hideFromOverview){
|
||||
return "";
|
||||
}
|
||||
const languages = layout.supportedLanguages.map(ln => `{{#language:${ln}|en}}`).join(", ")
|
||||
const languages = layout.language.map(ln => `{{#language:${ln}|en}}`).join(", ")
|
||||
let auth = "Yes";
|
||||
if(layout.maintainer !== "" && layout.maintainer !== "MapComplete"){
|
||||
auth=`Yes, by ${layout.maintainer};`
|
||||
|
@ -97,7 +97,7 @@ function generateWikiEntry(layout: Layout){
|
|||
|
||||
const alreadyWritten = []
|
||||
|
||||
function createIcon(iconPath: string, size: number, layout: Layout) {
|
||||
function createIcon(iconPath: string, size: number, layout: LayoutConfig) {
|
||||
let name = iconPath.split(".").slice(0, -1).join(".");
|
||||
if (name.startsWith("./")) {
|
||||
name = name.substr(2)
|
||||
|
@ -138,7 +138,7 @@ function createIcon(iconPath: string, size: number, layout: Layout) {
|
|||
return newname;
|
||||
}
|
||||
|
||||
function createManifest(layout: Layout, relativePath: string) {
|
||||
function createManifest(layout: LayoutConfig, relativePath: string) {
|
||||
const name = layout.id;
|
||||
|
||||
const icons = [];
|
||||
|
@ -191,9 +191,9 @@ function createManifest(layout: Layout, relativePath: string) {
|
|||
}
|
||||
|
||||
const template = readFileSync("index.html", "utf8");
|
||||
function createLandingPage(layout: Layout) {
|
||||
function createLandingPage(layout: LayoutConfig) {
|
||||
|
||||
Locale.language.setData(layout.supportedLanguages[0]);
|
||||
Locale.language.setData(layout.language[0]);
|
||||
|
||||
const ogTitle = Translations.W(layout.title)?.InnerRender();
|
||||
const ogDescr = Translations.W(layout.description ?? "Easily add and edit geodata with OpenStreetMap")?.InnerRender();
|
||||
|
|
11
index.ts
11
index.ts
|
@ -1,11 +1,11 @@
|
|||
import {AllKnownLayouts} from "./Customizations/AllKnownLayouts";
|
||||
import {Layout} from "./Customizations/Layout";
|
||||
import {FixedUiElement} from "./UI/Base/FixedUiElement";
|
||||
import {InitUiElements} from "./InitUiElements";
|
||||
import {QueryParameters} from "./Logic/Web/QueryParameters";
|
||||
import {UIEventSource} from "./Logic/UIEventSource";
|
||||
import * as $ from "jquery";
|
||||
import SharedLayers from "./Customizations/SharedLayers";
|
||||
import LayoutConfig from "./Customizations/JSON/LayoutConfig";
|
||||
|
||||
let defaultLayout = "bookcases"
|
||||
// --------------------- Special actions based on the parameters -----------------
|
||||
|
@ -57,7 +57,7 @@ if (path !== "index.html" && path !== "") {
|
|||
|
||||
// Run over all questsets. If a part of the URL matches a searched-for part in the layout, it'll take that as the default
|
||||
for (const k in AllKnownLayouts.allSets) {
|
||||
const layout = AllKnownLayouts.allSets[k];
|
||||
const layout : LayoutConfig= AllKnownLayouts.allSets[k];
|
||||
const possibleParts = (layout.locationContains ?? []);
|
||||
for (const locationMatch of possibleParts) {
|
||||
if (locationMatch === "") {
|
||||
|
@ -71,7 +71,7 @@ for (const k in AllKnownLayouts.allSets) {
|
|||
|
||||
defaultLayout = QueryParameters.GetQueryParameter("layout", defaultLayout).data;
|
||||
|
||||
let layoutToUse: Layout = AllKnownLayouts.allSets[defaultLayout.toLowerCase()] ?? AllKnownLayouts["all"];
|
||||
let layoutToUse: LayoutConfig = AllKnownLayouts.allSets[defaultLayout.toLowerCase()] ?? AllKnownLayouts["all"];
|
||||
|
||||
|
||||
const userLayoutParam = QueryParameters.GetQueryParameter("userlayout", "false");
|
||||
|
@ -94,8 +94,9 @@ if (layoutFromBase64.startsWith("wiki:")) {
|
|||
.firstChild.textContent;
|
||||
try {
|
||||
console.log("DOWNLOADED:",layoutJson);
|
||||
const layout = Layout.LayoutFromJSON(JSON.parse(layoutJson), SharedLayers.sharedLayers);
|
||||
layout.id = layoutFromBase64;
|
||||
const parsed = JSON.parse(layoutJson);
|
||||
parsed["id"] = layoutFromBase64
|
||||
const layout =new LayoutConfig(parsed);
|
||||
InitUiElements.InitAll(layout, layoutFromBase64, testing, layoutFromBase64, btoa(layoutJson));
|
||||
} catch (e) {
|
||||
new FixedUiElement(`<a href="${cleanUrl}">${themeName}</a> is invalid:<br/>${e}`)
|
||||
|
|
Loading…
Reference in a new issue