From dc5fa5dabc5dcfd2eae508ab4d08063b73126107 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Mon, 14 Sep 2020 20:16:03 +0200 Subject: [PATCH] Various bug fixes --- Customizations/JSON/FromJSON.ts | 2 +- Logic/FilteredLayer.ts | 3 +- State.ts | 2 +- UI/CustomGenerator/AllLayersPanel.ts | 1 + UI/CustomGenerator/TagRenderingPanel.ts | 16 +- UI/CustomGenerator/TagRenderingPreview.ts | 2 - UI/FeatureInfoBox.ts | 4 +- UI/Input/MultiInput.ts | 1 + UI/SimpleAddUI.ts | 6 +- UI/TagRendering.ts | 3 +- UI/UIElement.ts | 1 - assets/themes/cyclestreets/cyclestreets.json | 13 +- index.css | 160 ++++++++----------- 13 files changed, 103 insertions(+), 111 deletions(-) diff --git a/Customizations/JSON/FromJSON.ts b/Customizations/JSON/FromJSON.ts index 193f97c..57a015b 100644 --- a/Customizations/JSON/FromJSON.ts +++ b/Customizations/JSON/FromJSON.ts @@ -184,7 +184,7 @@ export class FromJSON { const k = FromJSON.Tag(mapping.if, `IN mapping #${i} of tagrendering ${propertyName}`) if (question !== undefined && !mapping.hideInAnswer && !k.isUsableAsAnswer()) { - throw `Invalid mapping in ${propertyName}: the tags use an OR-expression or regex expression but are also assignable as answer.` + throw `Invalid mapping in ${propertyName}.${i}: this mapping uses a regex tag or an OR, but is also answerable. Either mark 'Not an answer option' or only use '=' to map key/values.` } return { diff --git a/Logic/FilteredLayer.ts b/Logic/FilteredLayer.ts index 280d130..c908ebc 100644 --- a/Logic/FilteredLayer.ts +++ b/Logic/FilteredLayer.ts @@ -39,6 +39,7 @@ export class FilteredLayer { * The leaflet layer object which should be removed on rerendering */ private _geolayer; + private _showOnPopup: (tags: UIEventSource, feature: any) => UIElement; private static readonly grid = codegrid.CodeGrid(); @@ -287,7 +288,7 @@ export class FilteredLayer { }).setContent(uiElement.Render()) .setLatLng(e.latlng) .openOn(State.state.bm.map); - + uiElement.Update(); L.DomEvent.stop(e); // Marks the event as consumed }); } diff --git a/State.ts b/State.ts index 2a51647..d7d4182 100644 --- a/State.ts +++ b/State.ts @@ -22,7 +22,7 @@ export class State { // The singleton of the global state public static state: State; - public static vNumber = "0.0.7l"; + public static vNumber = "0.0.7m"; // The user journey states thresholds when a new feature gets unlocked public static userJourney = { diff --git a/UI/CustomGenerator/AllLayersPanel.ts b/UI/CustomGenerator/AllLayersPanel.ts index 2e28b02..15aac0d 100644 --- a/UI/CustomGenerator/AllLayersPanel.ts +++ b/UI/CustomGenerator/AllLayersPanel.ts @@ -31,6 +31,7 @@ export default class AllLayersPanel extends UIElement { this.createPanels(userDetails); const self = this; + this.dumbMode = false; config.map(config => config.layers.length).addCallback(() => self.createPanels(userDetails)); } diff --git a/UI/CustomGenerator/TagRenderingPanel.ts b/UI/CustomGenerator/TagRenderingPanel.ts index 367ca86..23a6172 100644 --- a/UI/CustomGenerator/TagRenderingPanel.ts +++ b/UI/CustomGenerator/TagRenderingPanel.ts @@ -65,9 +65,6 @@ export default class TagRenderingPanel extends InputElementNote that the Overpass-tags are already always included in this object"), - "

Freeform key

", setting(TextField.KeyInput(true), ["freeform", "key"], "Freeform key
", "If specified, the rendering will search if this key is present." + @@ -84,9 +81,9 @@ export default class TagRenderingPanel extends InputElement)[] = [ setting( options?.noLanguage ? TextField.StringInput() : - new MultiLingualTextFields(languages), "render", "Value to show", " Renders this value. Note that {key}-parts are substituted by the corresponding values of the element. If neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value."), - - questionsNotUnlocked ? `You need at least ${State.userJourney.themeGeneratorFullUnlock} changesets to unlock the 'question'-field and to use your theme to edit OSM data`: "", + new MultiLingualTextFields(languages), "render", "Value to show", " Renders this value. Note that {key}-parts are substituted by the corresponding values of the element. If neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value."), + + questionsNotUnlocked ? `You need at least ${State.userJourney.themeGeneratorFullUnlock} changesets to unlock the 'question'-field and to use your theme to edit OSM data` : "", ...(options?.disableQuestions ? [] : questionSettings), "

Mappings

", @@ -94,7 +91,12 @@ export default class TagRenderingPanel extends InputElement ({if: {and: []}, then: {}}), () => new MappingInput(languages, options?.disableQuestions ?? false), undefined, {allowMovement: true}), "mappings", - "If a tag matches, then show the first respective text", "") + "If a tag matches, then show the first respective text", ""), + + "

Condition

", + setting(new AndOrTagInput(), "condition", "Only show this tagrendering if the following condition applies", + "Only show this tag rendering if these tags matches. Optional field.
Note that the Overpass-tags are already always included in this object"), + ]; diff --git a/UI/CustomGenerator/TagRenderingPreview.ts b/UI/CustomGenerator/TagRenderingPreview.ts index d5757ae..4a16759 100644 --- a/UI/CustomGenerator/TagRenderingPreview.ts +++ b/UI/CustomGenerator/TagRenderingPreview.ts @@ -2,7 +2,6 @@ import {UIElement} from "../UIElement"; import {UIEventSource} from "../../Logic/UIEventSource"; import TagRenderingPanel from "./TagRenderingPanel"; import {VariableUiElement} from "../Base/VariableUIElement"; -import {TagRenderingConfigJson} from "../../Customizations/JSON/TagRenderingConfigJson"; import {FromJSON} from "../../Customizations/JSON/FromJSON"; import {FixedUiElement} from "../Base/FixedUiElement"; import Combine from "../Base/Combine"; @@ -33,7 +32,6 @@ export default class TagRenderingPreview extends UIElement { } let es = tagRenderingPanel.GetValue(); - let tagRenderingConfig: TagRenderingConfigJson = es.data; let rendering: UIElement; try { diff --git a/UI/FeatureInfoBox.ts b/UI/FeatureInfoBox.ts index b5ab38c..0ff8b12 100644 --- a/UI/FeatureInfoBox.ts +++ b/UI/FeatureInfoBox.ts @@ -39,7 +39,7 @@ export class FeatureInfoBox extends UIElement { this._feature = feature; this._tagsES = tagsES; this.ListenTo(State.state.osmConnection.userDetails); - + this.SetClass("featureinfobox"); const deps = {tags: this._tagsES, changes: this._changes} this._infoboxes = []; @@ -153,7 +153,7 @@ export class FeatureInfoBox extends UIElement { this._title, "
", infoboxcontents, - "
"]).SetClass("featureinfobox") + ""]) .Render(); } diff --git a/UI/Input/MultiInput.ts b/UI/Input/MultiInput.ts index 2dd2bb6..6385bb4 100644 --- a/UI/Input/MultiInput.ts +++ b/UI/Input/MultiInput.ts @@ -25,6 +25,7 @@ export class MultiInput extends InputElement { super(undefined); this._value = value ?? new UIEventSource([]); value = this._value; + this.ListenTo(value.map((latest : T[]) => latest.length)); this._options = options ?? {}; this.addTag = new SubtleButton("./assets/addSmall.svg", addAElement) diff --git a/UI/SimpleAddUI.ts b/UI/SimpleAddUI.ts index 70c47b2..384680e 100644 --- a/UI/SimpleAddUI.ts +++ b/UI/SimpleAddUI.ts @@ -42,7 +42,7 @@ export class SimpleAddUI extends UIElement { this._loginButton = Translations.t.general.add.pleaseLogin.Clone().onClick(() => State.state.osmConnection.AttemptLogin()); this._addButtons = []; - this.SetClass("add-ui"); + this.SetStyle("font-size:large"); const self = this; for (const layer of State.state.filteredLayers.data) { @@ -137,10 +137,10 @@ export class SimpleAddUI extends UIElement { tagInfo = this._confirmPreset.data .tags.map(t => t.asHumanString(csCount > State.userJourney.tagsVisibleAndWikiLinked, true)).join("&"); tagInfo = `
More information about the preset: ${tagInfo}` } - + return new Combine([ Translations.t.general.add.confirmIntro.Subs({title: this._confirmPreset.data.name}), - userDetails.data.dryRun ? "TESTING - changes won't be saved":"", + userDetails.data.dryRun ? "TESTING - changes won't be saved" : "", this.confirmButton, this.cancelButton, tagInfo diff --git a/UI/TagRendering.ts b/UI/TagRendering.ts index 114596e..662581d 100644 --- a/UI/TagRendering.ts +++ b/UI/TagRendering.ts @@ -292,14 +292,13 @@ export class TagRendering extends UIElement implements TagDependantUIElement { private InputElementForMapping(mapping: { k: TagsFilter, txt: (string | Translation) }, substituteValues: boolean): FixedInputElement { if (substituteValues) { - return new FixedInputElement(this.ApplyTemplate(mapping.txt), mapping.k.substituteValues(this.currentTags.data), (t0, t1) => t0.isEquivalent(t1) ); } return new FixedInputElement(this.ApplyTemplate(mapping.txt), mapping.k, - (t0, t1) => t0.isEquivalent(t1)); + (t0, t1) => t1.isEquivalent(t0)); } diff --git a/UI/UIElement.ts b/UI/UIElement.ts index 11c9861..08401d6 100644 --- a/UI/UIElement.ts +++ b/UI/UIElement.ts @@ -191,7 +191,6 @@ export abstract class UIElement extends UIEventSource { this.clss.push(clss); this.Update(); } - console.log(this.clss) return this; } diff --git a/assets/themes/cyclestreets/cyclestreets.json b/assets/themes/cyclestreets/cyclestreets.json index 4da116b..7240bc4 100644 --- a/assets/themes/cyclestreets/cyclestreets.json +++ b/assets/themes/cyclestreets/cyclestreets.json @@ -19,10 +19,21 @@ "if": { "and": [ "cyclestreet=yes", + "maxspeed=30", "proposed:cyclestreet=" ] }, - "then": "Deze straat is een fietsstraat" + "then": "Deze straat is een fietsstraat (en dus zone 30)" + }, + { + "if": { + "and": [ + "cyclestreet=yes", + "proposed:cyclestreet=" + ] + }, + "then": "Deze straat is een fietsstraat", + "hideInAnswer": true }, { "if": { diff --git a/index.css b/index.css index 86aa3bf..e29e1e6 100644 --- a/index.css +++ b/index.css @@ -59,12 +59,10 @@ body { background-color: #fee4d1; font-weight: bold; border-radius: 1em; - padding: 0.3em; margin: 0.25em; text-align: center; - padding-top: 0.15em; - padding-bottom: 0.15em; - } + padding: 0.15em 0.3em; +} form { display: inline; @@ -87,11 +85,9 @@ body { background-color: #e5f5ff; font-weight: bold; border-radius: 1em; - padding: 0.3em; margin: 0.25em; text-align: center; - padding-top: 0.15em; - padding-bottom: 0.15em; + padding: 0.15em 0.3em; } @@ -107,11 +103,9 @@ body { background-color: #43d904; font-weight: bold; border-radius: 1em; - padding: 0.3em; margin: 0.25em; text-align: center; - padding-top: 0.15em; - padding-bottom: 0.15em; + padding: 0.15em 0.3em; } .clickable { @@ -139,8 +133,7 @@ body { transition: all 500ms linear; pointer-events: all; border-radius: 1.3em; - margin: 0; - margin-bottom: 0.5em; + margin: 0 0 0.5em; width: 100%; } @@ -212,8 +205,7 @@ body { /* Landscape and portrait */ #topleft-tools { - padding: 0.1em; - padding-left: unset; + padding: 0.1em 0.1em 0.1em unset; } @@ -266,14 +258,12 @@ body { #topleft-tools { display: block; position: absolute; - padding: 0; - padding-top: 0.5em; - padding-left:0.5em; z-index: 5000; transition: all 500ms linear; overflow: hidden; pointer-events: none; - padding-right: 10px; /* Shadow offset */ + /* Shadow offset */ + padding: 0.5em 10px 0 0.5em; } @@ -321,7 +311,6 @@ body { .collapse-button-img img{ width: 1.5em; - padding: 0.5em; margin: 0; padding: 0; } @@ -329,9 +318,7 @@ body { #welcomeMessage { display: inline-block; margin-left: 3.5em; - border-radius: 2em; - border-top-left-radius: 0; - border-bottom-left-radius: 0; + border-radius: 0 2em 2em 0; max-width: 40em; width: 45vw; max-height: calc(100vh - 15em); @@ -526,9 +513,8 @@ body { .infoboxcontents { - margin: 0.5em; - margin-top: 1em; - + margin: 1em 0.5em 0.5em; + } @@ -579,9 +565,7 @@ body { border: solid white 2px; background-color: #3a3aeb; color: white; - padding: 0.2em; - padding-left: 0.6em; - padding-right: 0.6em; + padding: 0.2em 0.6em; font-size: large; font-weight: bold; border-radius: 1.5em; @@ -599,78 +583,74 @@ body { border-radius: 1.5em; } - /****** ShareScreen *****/ +/****** ShareScreen *****/ - .literal-code { - display: inline-block; - background-color: lightgray; - padding: 0.5em; - word-break: break-all; - color: black; - box-sizing: border-box; - } +.literal-code { + display: inline-block; + background-color: lightgray; + padding: 0.5em; + word-break: break-all; + color: black; + box-sizing: border-box; +} - .iframe-escape { - background-color: white; - border-radius: 2em; - display: block; - width: min-content; - } +.iframe-escape { + background-color: white; + border-radius: 2em; + display: block; + width: min-content; +} - .iframe-escape img { - padding: 1em; - width: 2em; - height: 2em; - } +.iframe-escape img { + padding: 1em; + width: 2em; + height: 2em; +} - /** Switch layout **/ - - .subtle-button { - display: flex; - flex-wrap: nowrap; - flex-direction: row; - font-size: large; - margin: 0.5em; - background-color: #e5f5ff; - border-radius: 1em; - align-items: center; - text-decoration: none; - color: black; - } +/** Switch layout **/ +.subtle-button { + display: flex; + flex-wrap: nowrap; + flex-direction: row; + font-size: large; + margin: 0.5em; + background-color: #e5f5ff; + border-radius: 1em; + align-items: center; + text-decoration: none; + color: black; +} - .subtle-button a { - text-decoration: unset !important; - color: unset !important; - display: block ruby; - } +.subtle-button a { + text-decoration: unset !important; + color: unset !important; + display: block ruby; +} - .round-button .subtle-button { - width: 2em; - height: 2em; - border-radius: 1em; - display: block !important; - margin: 0; - padding: 0.5em; - } +.round-button .subtle-button { + width: 2em; + height: 2em; + border-radius: 1em; + display: block !important; + margin: 0; + padding: 0.5em; +} - .small-button .subtle-button { - height: 2em; - } +.small-button .subtle-button { + height: 2em; +} - .small-button .subtle-button img { - max-height: 1.8em; - } +.small-button .subtle-button img { + max-height: 1.8em; +} - .subtle-button img { - max-width: 3em; - max-height: 3em; - margin-right: 0.5em; - padding: 0.5em; - } +.subtle-button img { + max-width: 3em; + max-height: 3em; + margin-right: 0.5em; + padding: 0.5em; +} - .add-ui { - font-size: large; - }