First part of a huge refactoring

This commit is contained in:
Pieter Vander Vennet 2021-12-21 18:35:31 +01:00
parent 0c22b15c8d
commit 11150a258d
56 changed files with 1425 additions and 1324 deletions

View file

@ -1,9 +1,9 @@
import UserRelatedState from "../Logic/State/UserRelatedState";
import {FixedUiElement} from "./Base/FixedUiElement";
import Combine from "./Base/Combine";
import MoreScreen from "./BigComponents/MoreScreen";
import Translations from "./i18n/Translations";
import Constants from "../Models/Constants";
import UserRelatedState from "../Logic/State/UserRelatedState";
import {Utils} from "../Utils";
import LanguagePicker from "./LanguagePicker";
import IndexText from "./BigComponents/IndexText";
@ -13,7 +13,6 @@ import {SubtleButton} from "./Base/SubtleButton";
export default class AllThemesGui {
constructor() {
try {
new FixedUiElement("").AttachTo("centermessage")
@ -41,6 +40,7 @@ export default class AllThemesGui {
.SetStyle("pointer-events: all;")
.AttachTo("topleft-tools");
} catch (e) {
console.error(">>>> CRITICAL", e)
new FixedUiElement("Seems like no layers are compiled - check the output of `npm run generate:layeroverview`. Is this visible online? Contact pietervdvn immediately!").SetClass("alert")
.AttachTo("centermessage")
}

View file

@ -27,6 +27,7 @@ import {QueryParameters} from "../Logic/Web/QueryParameters";
import {SubstitutedTranslation} from "./SubstitutedTranslation";
import {AutoAction} from "./Popup/AutoApplyButton";
import DynamicGeoJsonTileSource from "../Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource";
import * as themeOverview from "../assets/generated/theme_overview.json"
class AutomationPanel extends Combine{
@ -177,7 +178,7 @@ class AutomationPanel extends Combine{
const feature = ffs.feature
const renderingTr = targetAction.GetRenderValue(feature.properties)
const rendering = renderingTr.txt
log.push("<a href='https://openstreetmap.org/"+feature.properties.id+"' target='_blank'>"+feature.properties.id+"</a>: "+new SubstitutedTranslation(renderingTr, new UIEventSource<any>(feature.properties)).ConstructElement().innerText)
log.push("<a href='https://openstreetmap.org/"+feature.properties.id+"' target='_blank'>"+feature.properties.id+"</a>: "+new SubstitutedTranslation(renderingTr, new UIEventSource<any>(feature.properties), state).ConstructElement().innerText)
const actions = Utils.NoNull(SubstitutedTranslation.ExtractSpecialComponents(rendering)
.map(obj => obj.special))
for (const action of actions) {
@ -251,7 +252,7 @@ class AutomatonGui {
private static GenerateMainPanel(): BaseUIElement {
const themeSelect = new DropDown<string>("Select a theme",
AllKnownLayouts.layoutsList.map(l => ({value: l.id, shown: l.id}))
Array.from(themeOverview).map(l => ({value: l.id, shown: l.id}))
)
LocalStorageSource.Get("automation-theme-id", "missing_streets").syncWith(themeSelect.GetValue())

View file

@ -3,7 +3,7 @@ import * as welcome_messages from "../../assets/welcome_message.json"
import BaseUIElement from "../BaseUIElement";
import {FixedUiElement} from "../Base/FixedUiElement";
import MoreScreen from "./MoreScreen";
import {AllKnownLayouts} from "../../Customizations/AllKnownLayouts";
import * as themeOverview from "../../assets/generated/theme_overview.json"
import Translations from "../i18n/Translations";
import Title from "../Base/Title";
@ -33,6 +33,12 @@ export default class FeaturedMessage extends Combine {
public static WelcomeMessages(): { start_date: Date, end_date: Date, message: string, featured_theme?: string }[] {
const all_messages: { start_date: Date, end_date: Date, message: string, featured_theme?: string }[] = []
const themesById = new Map<string, {id: string, title: any, shortDescription: any}>();
for (const theme of themeOverview["default"]) {
themesById.set(theme.id, theme);
}
for (const i in welcome_messages) {
if (isNaN(Number(i))) {
continue
@ -41,7 +47,8 @@ export default class FeaturedMessage extends Combine {
if (wm === null) {
continue
}
if (AllKnownLayouts.allKnownLayouts.get(wm.featured_theme) === undefined) {
if (themesById.get(wm.featured_theme) === undefined) {
console.log("THEMES BY ID:", themesById)
console.error("Unkown featured theme for ", wm)
continue
}
@ -71,7 +78,10 @@ export default class FeaturedMessage extends Combine {
const msg = new FixedUiElement(welcome_message.message).SetClass("link-underline font-lg")
els.push(new Combine([title, msg]).SetClass("m-4"))
if (welcome_message.featured_theme !== undefined) {
els.push(MoreScreen.createLinkButton({}, AllKnownLayouts.allKnownLayouts.get(welcome_message.featured_theme))
const theme = themeOverview["default"].filter(th => th.id === welcome_message.featured_theme)[0];
els.push(MoreScreen.createLinkButton({}, theme)
.SetClass("m-4 self-center md:w-160")
.SetStyle("height: min-content;"))

View file

@ -1,18 +1,18 @@
import {DropDown} from "../Input/DropDown";
import Translations from "../i18n/Translations";
import State from "../../State";
import {UIEventSource} from "../../Logic/UIEventSource";
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
export default class LicensePicker extends DropDown<string> {
constructor() {
constructor(state: {osmConnection: OsmConnection}) {
super(Translations.t.image.willBePublished.Clone(),
[
{value: "CC0", shown: Translations.t.image.cco.Clone()},
{value: "CC-BY-SA 4.0", shown: Translations.t.image.ccbs.Clone()},
{value: "CC-BY 4.0", shown: Translations.t.image.ccb.Clone()}
],
State.state?.osmConnection?.GetPreference("pictures-license") ?? new UIEventSource<string>("CC0")
state?.osmConnection?.GetPreference("pictures-license") ?? new UIEventSource<string>("CC0")
)
this.SetClass("flex flex-col sm:flex-row").SetStyle("float:left");
}

View file

@ -1,5 +1,4 @@
import {VariableUiElement} from "../Base/VariableUIElement";
import {AllKnownLayouts} from "../../Customizations/AllKnownLayouts";
import Svg from "../../Svg";
import Combine from "../Base/Combine";
import {SubtleButton} from "../Base/SubtleButton";
@ -15,6 +14,8 @@ import UserRelatedState from "../../Logic/State/UserRelatedState";
import Toggle from "../Input/Toggle";
import {Utils} from "../../Utils";
import Title from "../Base/Title";
import * as themeOverview from "../../assets/generated/theme_overview.json"
import {Translation} from "../i18n/Translation";
export default class MoreScreen extends Combine {
@ -47,7 +48,12 @@ export default class MoreScreen extends Combine {
state: {
locationControl?: UIEventSource<Loc>,
layoutToUse?: LayoutConfig
}, layout: LayoutConfig, customThemeDefinition: string = undefined
}, layout: {
id: string,
icon: string,
title: any,
shortDescription: any
}, customThemeDefinition: string = undefined
):
BaseUIElement {
if (layout === undefined) {
@ -75,11 +81,11 @@ export default class MoreScreen extends Combine {
let linkPrefix = `${path}/${layout.id.toLowerCase()}.html?`
let linkSuffix = ""
if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
linkPrefix = `${path}/index.html?layout=${layout.id}&`
linkPrefix = `${path}/theme.html?layout=${layout.id}&`
}
if (customThemeDefinition) {
linkPrefix = `${path}/index.html?userlayout=${layout.id}&`
linkPrefix = `${path}/theme.html?userlayout=${layout.id}&`
linkSuffix = `#${customThemeDefinition}`
}
@ -98,10 +104,10 @@ export default class MoreScreen extends Combine {
return new SubtleButton(layout.icon,
new Combine([
`<dt class='text-lg leading-6 font-medium text-gray-900 group-hover:text-blue-800'>`,
Translations.WT(layout.title),
new Translation(layout.title),
`</dt>`,
`<dd class='mt-1 text-base text-gray-500 group-hover:text-blue-900 overflow-ellipsis'>`,
Translations.WT(layout.shortDescription)?.SetClass("subtle") ?? "",
new Translation(layout.shortDescription)?.SetClass("subtle") ?? "",
`</dd>`,
]), {url: linkText, newTab: false});
}
@ -122,27 +128,29 @@ export default class MoreScreen extends Combine {
private static createPreviouslyVistedHiddenList(state: UserRelatedState, buttonClass: string, themeListStyle: string) {
const t = Translations.t.general.morescreen
const prefix = "mapcomplete-hidden-theme-"
const hiddenTotal = AllKnownLayouts.layoutsList.filter(layout => layout.hideFromOverview).length
const hiddenThemes = themeOverview["default"].filter(layout => layout.hideFromOverview)
const hiddenTotal = hiddenThemes.length
return new Toggle(
new VariableUiElement(
state.osmConnection.preferencesHandler.preferences.map(allPreferences => {
const knownThemes = Utils.NoNull(Object.keys(allPreferences)
const knownThemes: Set<string> = new Set(Utils.NoNull(Object.keys(allPreferences)
.filter(key => key.startsWith(prefix))
.map(key => key.substring(prefix.length, key.length - "-enabled".length))
.map(theme => AllKnownLayouts.allKnownLayouts.get(theme)))
.filter(theme => theme?.hideFromOverview)
if (knownThemes.length === 0) {
.map(key => key.substring(prefix.length, key.length - "-enabled".length))));
if(knownThemes.size === 0){
return undefined
}
const knownThemeDescriptions = hiddenThemes.filter(theme => knownThemes.has(theme.id))
.map(theme => MoreScreen.createLinkButton(state, theme)?.SetClass(buttonClass));
const knownLayouts = new Combine(knownThemes.map(layout =>
MoreScreen.createLinkButton(state, layout)?.SetClass(buttonClass)
)).SetClass(themeListStyle)
const knownLayouts = new Combine(knownThemeDescriptions).SetClass(themeListStyle)
return new Combine([
new Title(t.previouslyHiddenTitle),
t.hiddenExplanation.Subs({
hidden_discovered: "" + knownThemes.length,
hidden_discovered: "" + knownThemes.size,
total_hidden: "" + hiddenTotal
}),
knownLayouts
@ -158,7 +166,7 @@ export default class MoreScreen extends Combine {
}
private static createOfficialThemesList(state: { osmConnection: OsmConnection, locationControl?: UIEventSource<Loc> }, buttonClass: string): BaseUIElement {
let officialThemes = AllKnownLayouts.layoutsList
let officialThemes = themeOverview["default"];
let buttons = officialThemes.map((layout) => {
if (layout === undefined) {

View file

@ -15,13 +15,14 @@ import LeftControls from "./BigComponents/LeftControls";
import RightControls from "./BigComponents/RightControls";
import CenterMessageBox from "./CenterMessageBox";
import ShowDataLayer from "./ShowDataLayer/ShowDataLayer";
import AllKnownLayers from "../Customizations/AllKnownLayers";
import ScrollableFullScreen from "./Base/ScrollableFullScreen";
import Translations from "./i18n/Translations";
import SimpleAddUI from "./BigComponents/SimpleAddUI";
import StrayClickHandler from "../Logic/Actors/StrayClickHandler";
import Lazy from "./Base/Lazy";
import {DefaultGuiState} from "./DefaultGuiState";
import LayerConfig from "../Models/ThemeConfig/LayerConfig";
import * as home_location_json from "../assets/layers/home_location/home_location.json";
/**
@ -111,7 +112,7 @@ export default class DefaultGUI {
new ShowDataLayer({
leafletMap: state.leafletMap,
layerToShow: AllKnownLayers.sharedLayers.get("home_location"),
layerToShow: new LayerConfig(home_location_json, "all_known_layers", true),
features: state.homeLocation,
enablePopups: false,
})

View file

@ -2,20 +2,21 @@ import {UIEventSource} from "../../Logic/UIEventSource";
import Translations from "../i18n/Translations";
import Toggle from "../Input/Toggle";
import Combine from "../Base/Combine";
import State from "../../State";
import Svg from "../../Svg";
import {Tag} from "../../Logic/Tags/Tag";
import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction";
import {Changes} from "../../Logic/Osm/Changes";
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
export default class DeleteImage extends Toggle {
constructor(key: string, tags: UIEventSource<any>) {
constructor(key: string, tags: UIEventSource<any>, state: {changes?: Changes, osmConnection?: OsmConnection}) {
const oldValue = tags.data[key]
const isDeletedBadge = Translations.t.image.isDeleted.Clone()
.SetClass("rounded-full p-1")
.SetStyle("color:white;background:#ff8c8c")
.onClick(async () => {
await State.state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data, {
await state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data, {
changeType: "answer",
theme: "test"
}))
@ -25,7 +26,7 @@ export default class DeleteImage extends Toggle {
.SetClass("block w-full pl-4 pr-4")
.SetStyle("color:white;background:#ff8c8c; border-top-left-radius:30rem; border-top-right-radius: 30rem;")
.onClick(async () => {
await State.state?.changes?.applyAction(
await state?.changes?.applyAction(
new ChangeTagAction(tags.data.id, new Tag(key, ""), tags.data, {
changeType: "answer",
theme: "test"
@ -53,7 +54,7 @@ export default class DeleteImage extends Toggle {
tags.map(tags => (tags[key] ?? "") !== "")
),
undefined /*Login (and thus editing) is disabled*/,
State.state.osmConnection.isLoggedIn
state.osmConnection.isLoggedIn
)
this.SetClass("cursor-pointer")
}

View file

@ -6,12 +6,14 @@ import {AttributedImage} from "./AttributedImage";
import BaseUIElement from "../BaseUIElement";
import Toggle from "../Input/Toggle";
import ImageProvider from "../../Logic/ImageProviders/ImageProvider";
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
import {Changes} from "../../Logic/Osm/Changes";
export class ImageCarousel extends Toggle {
constructor(images: UIEventSource<{ key: string, url: string, provider: ImageProvider }[]>,
tags: UIEventSource<any>,
keys: string[]) {
state: {osmConnection?: OsmConnection, changes?: Changes}) {
const uiElements = images.map((imageURLS: { key: string, url: string, provider: ImageProvider }[]) => {
const uiElements: BaseUIElement[] = [];
for (const url of imageURLS) {
@ -21,7 +23,7 @@ export class ImageCarousel extends Toggle {
if (url.key !== undefined) {
image = new Combine([
image,
new DeleteImage(url.key, tags).SetClass("delete-image-marker absolute top-0 left-0 pl-3")
new DeleteImage(url.key, tags, state).SetClass("delete-image-marker absolute top-0 left-0 pl-3")
]).SetClass("relative");
}
image

View file

@ -1,5 +1,4 @@
import {UIEventSource} from "../../Logic/UIEventSource";
import State from "../../State";
import Combine from "../Base/Combine";
import Translations from "../i18n/Translations";
import Svg from "../../Svg";
@ -13,13 +12,23 @@ import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction";
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
import {FixedUiElement} from "../Base/FixedUiElement";
import {VariableUiElement} from "../Base/VariableUIElement";
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
import {Changes} from "../../Logic/Osm/Changes";
export class ImageUploadFlow extends Toggle {
private static readonly uploadCountsPerId = new Map<string, UIEventSource<number>>()
constructor(tagsSource: UIEventSource<any>, imagePrefix: string = "image", text: string = undefined) {
constructor(tagsSource: UIEventSource<any>,
state: {
osmConnection: OsmConnection;
layoutToUse: LayoutConfig;
changes: Changes,
featureSwitchUserbadge: UIEventSource<boolean>;
},
imagePrefix: string = "image", text: string = undefined) {
const perId = ImageUploadFlow.uploadCountsPerId
const id = tagsSource.data.id
if (!perId.has(id)) {
@ -41,17 +50,17 @@ export class ImageUploadFlow extends Toggle {
console.log("Adding image:" + key, url);
uploadedCount.data++
uploadedCount.ping()
Promise.resolve(State.state.changes
Promise.resolve(state.changes
.applyAction(new ChangeTagAction(
tags.id, new Tag(key, url), tagsSource.data,
{
changeType: "add-image",
theme: State.state.layoutToUse.id
theme: state.layoutToUse.id
}
)))
})
const licensePicker = new LicensePicker()
const licensePicker = new LicensePicker(state)
const t = Translations.t.image;
@ -90,7 +99,7 @@ export class ImageUploadFlow extends Toggle {
const tags = tagsSource.data;
const layout = State.state?.layoutToUse
const layout = state?.layoutToUse
let matchingLayer: LayerConfig = undefined
for (const layer of layout?.layers ?? []) {
if (layer.source.osmTags.matchesProperties(tags)) {
@ -102,7 +111,7 @@ export class ImageUploadFlow extends Toggle {
const title = matchingLayer?.title?.GetRenderValue(tags)?.ConstructElement()?.innerText ?? tags.name ?? "Unknown area";
const description = [
"author:" + State.state.osmConnection.userDetails.data.name,
"author:" + state.osmConnection.userDetails.data.name,
"license:" + license,
"osmid:" + tags.id,
].join("\n");
@ -146,17 +155,17 @@ export class ImageUploadFlow extends Toggle {
const pleaseLoginButton = t.pleaseLogin.Clone()
.onClick(() => State.state.osmConnection.AttemptLogin())
.onClick(() => state.osmConnection.AttemptLogin())
.SetClass("login-button-friendly");
super(
new Toggle(
/*We can show the actual upload button!*/
uploadFlow,
/* User not logged in*/ pleaseLoginButton,
State.state?.osmConnection?.isLoggedIn
state?.osmConnection?.isLoggedIn
),
undefined /* Nothing as the user badge is disabled*/,
State.state.featureSwitchUserbadge
state.featureSwitchUserbadge
)
}

View file

@ -1,6 +1,5 @@
import {UIEventSource} from "../../Logic/UIEventSource";
import Combine from "../Base/Combine";
import State from "../../State";
import {FixedUiElement} from "../Base/FixedUiElement";
import {OH} from "./OpeningHours";
import Translations from "../i18n/Translations";
@ -11,6 +10,7 @@ import Toggle from "../Input/Toggle";
import {VariableUiElement} from "../Base/VariableUIElement";
import Table from "../Base/Table";
import {Translation} from "../i18n/Translation";
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
export default class OpeningHoursVisualization extends Toggle {
private static readonly weekdays: Translation[] = [
@ -23,7 +23,7 @@ export default class OpeningHoursVisualization extends Toggle {
Translations.t.general.weekdays.abbreviations.sunday,
]
constructor(tags: UIEventSource<any>, key: string, prefix = "", postfix = "") {
constructor(tags: UIEventSource<any>, state:{osmConnection?: OsmConnection}, key: string, prefix = "", postfix = "") {
const tagsDirect = tags.data;
const ohTable = new VariableUiElement(tags
.map(tags => {
@ -57,7 +57,7 @@ export default class OpeningHoursVisualization extends Toggle {
new Toggle(
new FixedUiElement(e).SetClass("subtle"),
undefined,
State.state?.osmConnection?.userDetails.map(userdetails => userdetails.csCount >= Constants.userJourney.tagsVisibleAndWikiLinked)
state?.osmConnection?.userDetails.map(userdetails => userdetails.csCount >= Constants.userJourney.tagsVisibleAndWikiLinked)
)
]);
}

View file

@ -42,7 +42,7 @@ export default class EditableTagRendering extends Toggle {
}
private static CreateRendering(tags: UIEventSource<any>, configuration: TagRenderingConfig, units: Unit[], editMode: UIEventSource<boolean>): BaseUIElement {
const answer: BaseUIElement = new TagRenderingAnswer(tags, configuration)
const answer: BaseUIElement = new TagRenderingAnswer(tags, configuration, State.state)
answer.SetClass("w-full")
let rendering = answer;

View file

@ -18,7 +18,6 @@ import {Utils} from "../../Utils";
import {SubstitutedTranslation} from "../SubstitutedTranslation";
import MoveWizard from "./MoveWizard";
import Toggle from "../Input/Toggle";
import {FixedUiElement} from "../Base/FixedUiElement";
export default class FeatureInfoBox extends ScrollableFullScreen {
@ -41,7 +40,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
private static GenerateTitleBar(tags: UIEventSource<any>,
layerConfig: LayerConfig): BaseUIElement {
const title = new TagRenderingAnswer(tags, layerConfig.title ?? new TagRenderingConfig("POI"))
const title = new TagRenderingAnswer(tags, layerConfig.title ?? new TagRenderingConfig("POI"), State.state)
.SetClass("break-words font-bold sm:p-0.5 md:p-1 sm:p-1.5 md:p-2");
const titleIcons = new Combine(
layerConfig.titleIcons.map(icon => new TagRenderingAnswer(tags, icon,
@ -89,7 +88,8 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
if (tr.render !== undefined) {
questionBox.SetClass("text-sm")
const renderedQuestion = new TagRenderingAnswer(tags, tr, tr.group + " questions", "", {
const renderedQuestion = new TagRenderingAnswer(tags, tr,State.state,
tr.group + " questions", "", {
specialViz: new Map<string, BaseUIElement>([["questions", questionBox]])
})
const possiblyHidden = new Toggle(
@ -164,7 +164,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
const hasMinimap = layerConfig.tagRenderings.some(tr => FeatureInfoBox.hasMinimap(tr))
if (!hasMinimap) {
allRenderings.push(new TagRenderingAnswer(tags, SharedTagRenderings.SharedTagRendering.get("minimap")))
allRenderings.push(new TagRenderingAnswer(tags, SharedTagRenderings.SharedTagRendering.get("minimap"), State.state))
}
editElements.push(
@ -178,7 +178,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
return undefined
}
return new TagRenderingAnswer(tags, SharedTagRenderings.SharedTagRendering.get("last_edit"));
return new TagRenderingAnswer(tags, SharedTagRenderings.SharedTagRendering.get("last_edit"), State.state);
}, [State.state.featureSwitchIsDebugging, State.state.featureSwitchIsTesting])
)

View file

@ -19,7 +19,6 @@ import Svg from "../../Svg";
import {Utils} from "../../Utils";
import Minimap from "../Base/Minimap";
import ShowDataLayer from "../ShowDataLayer/ShowDataLayer";
import AllKnownLayers from "../../Customizations/AllKnownLayers";
import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource";
import ShowDataMultiLayer from "../ShowDataLayer/ShowDataMultiLayer";
import CreateWayWithPointReuseAction, {MergePointConfig} from "../../Logic/Osm/Actions/CreateWayWithPointReuseAction";
@ -35,6 +34,8 @@ import ReplaceGeometryAction from "../../Logic/Osm/Actions/ReplaceGeometryAction
import CreateMultiPolygonWithPointReuseAction from "../../Logic/Osm/Actions/CreateMultiPolygonWithPointReuseAction";
import {Tag} from "../../Logic/Tags/Tag";
import TagApplyButton from "./TagApplyButton";
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
import * as conflation_json from "../../assets/layers/conflation/conflation.json";
abstract class AbstractImportButton implements SpecialVisualizations {
@ -255,7 +256,7 @@ ${Utils.special_visualizations_importRequirementDocs}
zoomToFeatures: false,
features: changePreview,
allElements: state.allElements,
layerToShow: AllKnownLayers.sharedLayers.get("conflation")
layerToShow: new LayerConfig(conflation_json, "all_known_layers", true)
})
})

View file

@ -12,6 +12,7 @@ import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig";
export default class TagRenderingAnswer extends VariableUiElement {
constructor(tagsSource: UIEventSource<any>, configuration: TagRenderingConfig,
state: any,
contentClasses: string = "", contentStyle: string = "", options?:{
specialViz: Map<string, BaseUIElement>
}) {
@ -37,7 +38,7 @@ export default class TagRenderingAnswer extends VariableUiElement {
return undefined;
}
const valuesToRender: BaseUIElement[] = trs.map(tr => new SubstitutedTranslation(tr, tagsSource, options?.specialViz))
const valuesToRender: BaseUIElement[] = trs.map(tr => new SubstitutedTranslation(tr, tagsSource, state, options?.specialViz))
if (valuesToRender.length === 1) {
return valuesToRender[0];
} else if (valuesToRender.length > 1) {

View file

@ -71,7 +71,7 @@ export default class TagRenderingQuestion extends Combine {
}
options = options ?? {}
const applicableUnit = (options.units ?? []).filter(unit => unit.isApplicableToKey(configuration.freeform?.key))[0];
const question = new SubstitutedTranslation(configuration.question, tags)
const question = new SubstitutedTranslation(configuration.question, tags, State.state)
.SetClass("question-text");
@ -352,7 +352,7 @@ export default class TagRenderingQuestion extends Combine {
}
return new FixedInputElement(
new SubstitutedTranslation(mapping.then, tagsSource),
new SubstitutedTranslation(mapping.then, tagsSource, State.state),
tagging,
(t0, t1) => t1.isEquivalent(t0));
}

View file

@ -8,8 +8,7 @@ import {Tiles} from "../../Models/TileRange";
import * as clusterstyle from "../../assets/layers/cluster_style/cluster_style.json"
export default class ShowTileInfo {
public static readonly styling = new LayerConfig(
clusterstyle, "tileinfo", true)
public static readonly styling = new LayerConfig(clusterstyle, "ShowTileInfo", true)
constructor(options: {
source: FeatureSource & Tiled, leafletMap: UIEventSource<any>, layer?: LayerConfig,

View file

@ -27,7 +27,6 @@ import AllImageProviders from "../Logic/ImageProviders/AllImageProviders";
import WikipediaBox from "./Wikipedia/WikipediaBox";
import SimpleMetaTagger from "../Logic/SimpleMetaTagger";
import MultiApply from "./Popup/MultiApply";
import AllKnownLayers from "../Customizations/AllKnownLayers";
import ShowDataLayer from "./ShowDataLayer/ShowDataLayer";
import {SubtleButton} from "./Base/SubtleButton";
import {DefaultGuiState} from "./DefaultGuiState";
@ -37,6 +36,7 @@ import FeaturePipelineState from "../Logic/State/FeaturePipelineState";
import {ConflateButton, ImportPointButton, ImportWayButton} from "./Popup/ImportButton";
import TagApplyButton from "./Popup/TagApplyButton";
import AutoApplyButton from "./Popup/AutoApplyButton";
import * as left_right_style_json from "../assets/layers/left_right_style/left_right_style.json";
export interface SpecialVisualization {
funcName: string,
@ -51,7 +51,6 @@ export default class SpecialVisualizations {
public static specialVisualizations = SpecialVisualizations.init()
private static init(){
const specialVisualizations: SpecialVisualization[] =
[
@ -104,7 +103,7 @@ export default class SpecialVisualizations {
if (args.length > 0) {
imagePrefixes = [].concat(...args.map(a => a.split(",")));
}
return new ImageCarousel(AllImageProviders.LoadImagesFor(tags, imagePrefixes), tags, imagePrefixes);
return new ImageCarousel(AllImageProviders.LoadImagesFor(tags, imagePrefixes), tags, state);
}
},
{
@ -120,7 +119,7 @@ export default class SpecialVisualizations {
defaultValue: "Add image"
}],
constr: (state: State, tags, args) => {
return new ImageUploadFlow(tags, args[0], args[1])
return new ImageUploadFlow(tags, state, args[0], args[1])
}
},
{
@ -161,7 +160,7 @@ export default class SpecialVisualizations {
}
],
example: "`{minimap()}`, `{minimap(17, id, _list_of_embedded_feature_ids_calculated_by_calculated_tag):height:10rem; border: 2px solid black}`",
constr: (state, tagSource, args, defaultGuiState) => {
constr: (state, tagSource, args, _) => {
const keys = [...args]
keys.splice(0, 1)
@ -267,7 +266,7 @@ export default class SpecialVisualizations {
leafletMap: minimap["leafletMap"],
enablePopups: false,
zoomToFeatures: true,
layerToShow: AllKnownLayers.sharedLayers.get("left_right_style"),
layerToShow: new LayerConfig(left_right_style_json, "all_known_layers", true),
features: new StaticFeatureSource([copy], false),
allElements: State.state.allElements
}
@ -324,7 +323,7 @@ export default class SpecialVisualizations {
}],
example: "A normal opening hours table can be invoked with `{opening_hours_table()}`. A table for e.g. conditional access with opening hours can be `{opening_hours_table(access:conditional, no @ &LPARENS, &RPARENS)}`",
constr: (state: State, tagSource: UIEventSource<any>, args) => {
return new OpeningHoursVisualization(tagSource, args[0], args[1], args[2])
return new OpeningHoursVisualization(tagSource, state, args[0], args[1], args[2])
}
},
{

View file

@ -1,7 +1,6 @@
import {UIEventSource} from "../Logic/UIEventSource";
import {Translation} from "./i18n/Translation";
import Locale from "./i18n/Locale";
import State from "../State";
import {FixedUiElement} from "./Base/FixedUiElement";
import SpecialVisualizations, {SpecialVisualization} from "./SpecialVisualizations";
import {Utils} from "../Utils";
@ -15,6 +14,7 @@ export class SubstitutedTranslation extends VariableUiElement {
public constructor(
translation: Translation,
tagsSource: UIEventSource<any>,
state,
mapping: Map<string, BaseUIElement> = undefined) {
const extraMappings: SpecialVisualization[] = [];
@ -50,7 +50,7 @@ export class SubstitutedTranslation extends VariableUiElement {
}
const viz = proto.special;
try {
return viz.func.constr(State.state, tagsSource, proto.special.args, DefaultGuiState.state).SetStyle(proto.special.style);
return viz.func.constr(state, tagsSource, proto.special.args, DefaultGuiState.state).SetStyle(proto.special.style);
} catch (e) {
console.error("SPECIALRENDERING FAILED for", tagsSource.data?.id, e)
return new FixedUiElement(`Could not generate special rendering for ${viz.func}(${viz.args.join(", ")}) ${e}`).SetStyle("alert")

View file

@ -13,6 +13,9 @@ export class Translation extends BaseUIElement {
if (translations === undefined) {
throw `Translation without content (${context})`
}
if(typeof translations === "string"){
translations = {"*": translations};
}
let count = 0;
for (const translationsKey in translations) {
if (!translations.hasOwnProperty(translationsKey)) {