diff --git a/.gitignore b/.gitignore index cdc63ba..6e2d1fd 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ assets/generated/* .parcel-cache Docs/Tools/stats.*.json Docs/Tools/stats.csv + diff --git a/Customizations/JSON/TagRenderingConfig.ts b/Customizations/JSON/TagRenderingConfig.ts index a8169a6..830921f 100644 --- a/Customizations/JSON/TagRenderingConfig.ts +++ b/Customizations/JSON/TagRenderingConfig.ts @@ -1,4 +1,4 @@ -import {And, TagsFilter} from "../../Logic/Tags"; +import {And, TagsFilter, TagUtils} from "../../Logic/Tags"; import {TagRenderingConfigJson} from "./TagRenderingConfigJson"; import Translations from "../../UI/i18n/Translations"; import {FromJSON} from "./FromJSON"; @@ -152,6 +152,40 @@ export default class TagRenderingConfig { } } + + /** + * Returns true if it is known or not shown, false if the question should be asked + * @constructor + */ + public IsKnown(tags: any): boolean { + if (this.condition && + !this.condition.matchesProperties(tags)) { + // Filtered away by the condition + return true; + } + if(this.multiAnswer){ + for (const m of this.mappings) { + if(TagUtils.MatchesMultiAnswer(m.if, tags)){ + return true; + } + } + + const free = this.freeform?.key + if(free !== undefined){ + return tags[free] !== undefined + } + return false + + } + + if (this.GetRenderValue(tags) !== undefined) { + // This value is known and can be rendered + return true; + } + + return false; + } + /** * Gets the correct rendering value (or undefined if not known) * @constructor diff --git a/InitUiElements.ts b/InitUiElements.ts index 5fde430..4df43b7 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -257,7 +257,7 @@ export class InitUiElements { isOpened.setData(false); } }) - isOpened.setData(true) + isOpened.setData(Hash.hash.data === undefined) } diff --git a/Logic/Actors/SelectedFeatureHandler.ts b/Logic/Actors/SelectedFeatureHandler.ts index 9555c52..968a3d1 100644 --- a/Logic/Actors/SelectedFeatureHandler.ts +++ b/Logic/Actors/SelectedFeatureHandler.ts @@ -1,5 +1,4 @@ import {UIEventSource} from "../UIEventSource"; -import {UIElement} from "../../UI/UIElement"; import FeatureSource from "../FeatureSource/FeatureSource"; /** @@ -18,9 +17,7 @@ export default class SelectedFeatureHandler { this._featureSource = featureSource; const self = this; hash.addCallback(h => { - console.log("SelectedFeatureHandler: hash is now ", h) if (h === undefined || h === "") { - console.log("Deselecting...") selectedFeature.setData(undefined); }else{ self.selectFeature(); @@ -30,7 +27,10 @@ export default class SelectedFeatureHandler { featureSource.features.addCallback(_ => self.selectFeature()); selectedFeature.addCallback(feature => { - hash.setData(feature?.properties?.id ?? ""); + const h = feature?.properties?.id; + if(h !== undefined){ + hash.setData(h) + } }) this.selectFeature(); @@ -51,7 +51,6 @@ export default class SelectedFeatureHandler { if(hash === undefined || hash === "" || hash === "#"){ return; } - console.log("Selecting a feature from the hash...") for (const feature of features) { const id = feature.feature?.properties?.id; if(id === hash){ diff --git a/Logic/MetaTagging.ts b/Logic/MetaTagging.ts index c86d7e5..5c78f86 100644 --- a/Logic/MetaTagging.ts +++ b/Logic/MetaTagging.ts @@ -125,7 +125,7 @@ export default class MetaTagging { tags["_isOpen:oldvalue"] = tags.opening_hours window.setTimeout( () => { - console.log("Updating the _isOpen tag for ", tags.id); + console.log("Updating the _isOpen tag for ", tags.id, ", it's timer expired after", timeout); updateTags(); }, timeout diff --git a/Logic/Web/Hash.ts b/Logic/Web/Hash.ts index 035bb97..169b923 100644 --- a/Logic/Web/Hash.ts +++ b/Logic/Web/Hash.ts @@ -43,16 +43,14 @@ export default class Hash { window.onhashchange = () => { let newValue = window.location.hash.substr(1); - console.log("The hash is now:", newValue) if (newValue === "") { newValue = undefined; } hash.setData(newValue) } - window.addEventListener('popstate', e => { + window.addEventListener('popstate', _ => { let newValue = window.location.hash.substr(1); - console.log("Popstate: the hash is now:", newValue) if (newValue === "") { newValue = undefined; } diff --git a/Models/Constants.ts b/Models/Constants.ts index cbaf27a..4ab4072 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import { Utils } from "../Utils"; export default class Constants { - public static vNumber = "0.5.8"; + public static vNumber = "0.5.10"; // The user journey states thresholds when a new feature gets unlocked public static userJourney = { diff --git a/UI/Base/ScrollableFullScreen.ts b/UI/Base/ScrollableFullScreen.ts index ec58967..b6ef108 100644 --- a/UI/Base/ScrollableFullScreen.ts +++ b/UI/Base/ScrollableFullScreen.ts @@ -83,7 +83,7 @@ export default class ScrollableFullScreen extends UIElement { private static clear() { ScrollableFullScreen.empty.AttachTo("fullscreen") const fs = document.getElementById("fullscreen"); - ScrollableFullScreen._currentlyOpen.isShown.setData(false); + ScrollableFullScreen._currentlyOpen?.isShown?.setData(false); fs.classList.add("hidden") Hash.hash.setData(undefined); } diff --git a/UI/Popup/EditableTagRendering.ts b/UI/Popup/EditableTagRendering.ts index 6bafc45..c665d0b 100644 --- a/UI/Popup/EditableTagRendering.ts +++ b/UI/Popup/EditableTagRendering.ts @@ -53,13 +53,8 @@ export default class EditableTagRendering extends UIElement { if (this._editMode.data) { return this._question.Render(); } - if (this._configuration.multiAnswer) { - const atLeastOneMatch = this._configuration.mappings.some(mp =>TagUtils.MatchesMultiAnswer(mp.if, this._tags.data)); - if (!atLeastOneMatch) { - return ""; - } - } else if (this._configuration.GetRenderValue(this._tags.data) === undefined) { - return ""; + if(!this._configuration.IsKnown(this._tags.data)){ + return "" } return new Combine([this._answer, diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts index 52f87b0..5fedaf2 100644 --- a/UI/Popup/FeatureInfoBox.ts +++ b/UI/Popup/FeatureInfoBox.ts @@ -56,24 +56,19 @@ export default class FeatureInfoBox extends ScrollableFullScreen { } let questionBoxIsUsed = false; - const renderings = layerConfig.tagRenderings.map(tr => { + const renderings = layerConfig.tagRenderings.map((tr,i) => { if (tr.question === null) { // This is the question box! questionBoxIsUsed = true; return questionBox; } - return new EditableTagRendering(tags, tr); + return new EditableTagRendering(tags, tr); }); if (!questionBoxIsUsed) { renderings.push(questionBox); } - const tail = new Combine([]).SetClass("only-on-mobile"); - return new Combine([ - ...renderings, - tail.SetClass("featureinfobox-tail") - ] - ).SetClass("block") + return new Combine(renderings).SetClass("block") } diff --git a/UI/Popup/QuestionBox.ts b/UI/Popup/QuestionBox.ts index 7fa94c5..92097a7 100644 --- a/UI/Popup/QuestionBox.ts +++ b/UI/Popup/QuestionBox.ts @@ -46,37 +46,11 @@ export default class QuestionBox extends UIElement { }) } - /** - * Returns true if it is known or not shown, false if the question should be asked - * @constructor - */ - IsKnown(tagRendering: TagRenderingConfig): boolean { - if (tagRendering.condition && - !tagRendering.condition.matchesProperties(this._tags.data)) { - // Filtered away by the condition - return true; - } - if(tagRendering.multiAnswer){ - for (const m of tagRendering.mappings) { - if(TagUtils.MatchesMultiAnswer(m.if, this._tags.data)){ - return true; - } - } - } - - if (tagRendering.GetRenderValue(this._tags.data) !== undefined) { - // This value is known and can be rendered - return true; - } - - return false; - } - InnerRender(): string { for (let i = 0; i < this._tagRenderingQuestions.length; i++) { let tagRendering = this._tagRenderings[i]; - if(this.IsKnown(tagRendering)){ + if(tagRendering.IsKnown(this._tags.data)){ continue; } diff --git a/UI/Popup/TagRenderingAnswer.ts b/UI/Popup/TagRenderingAnswer.ts index f077992..a08698f 100644 --- a/UI/Popup/TagRenderingAnswer.ts +++ b/UI/Popup/TagRenderingAnswer.ts @@ -5,6 +5,7 @@ import {Utils} from "../../Utils"; import Combine from "../Base/Combine"; import {TagUtils} from "../../Logic/Tags"; import {SubstitutedTranslation} from "../SubstitutedTranslation"; +import {Translation} from "../i18n/Translation"; /*** * Displays the correct value for a known tagrendering @@ -43,7 +44,7 @@ export default class TagRenderingAnswer extends UIElement { // The render value doesn't work well with multi-answers (checkboxes), so we have to check for them manually if (this._configuration.multiAnswer) { - const applicableThens = Utils.NoNull(this._configuration.mappings.map(mapping => { + const applicableThens: Translation[] = Utils.NoNull(this._configuration.mappings.map(mapping => { if (mapping.if === undefined) { return mapping.then; } @@ -52,12 +53,20 @@ export default class TagRenderingAnswer extends UIElement { } return undefined; })) - if (applicableThens.length >= 0) { - if (applicableThens.length === 1) { - this._content = applicableThens[0]; + + if (this._configuration.freeform !== undefined && tags[this._configuration.freeform.key] !== undefined) { + applicableThens.push(this._configuration.render) + } + + const self = this + const valuesToRender: UIElement[] = applicableThens.map(tr => SubstitutedTranslation.construct(tr, self._tags)) + + if (valuesToRender.length >= 0) { + if (valuesToRender.length === 1) { + this._content = valuesToRender[0]; } else { this._content = new Combine(["" ]) @@ -66,13 +75,13 @@ export default class TagRenderingAnswer extends UIElement { return this._content.SetClass(this._contentClass).SetStyle(this._contentStyle).Render(); } } - + const tr = this._configuration.GetRenderValue(tags); if (tr !== undefined) { this._content = SubstitutedTranslation.construct(tr, this._tags); return this._content.SetClass(this._contentClass).SetStyle(this._contentStyle).Render(); } - + return ""; } diff --git a/package.json b/package.json index 5785651..ab97e94 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "build": "rm -rf dist/ && npm run generate && parcel build --public-url ./ *.html assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*", "prepare-deploy": "npm run test && npm run generate:editor-layer-index && npm run generate:layouts && npm run generate && npm run build && rm -rf .cache", "deploy:staging": "npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/Staging/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/Staging/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", + "deploy:pietervdvn": "npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/MapComplete/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/MapComplete/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", "deploy:production": "rm -rf ./assets/generated && npm run prepare-deploy && npm run optimize-images && rm -rf /home/pietervdvn/git/mapcomplete.github.io/* && cp -r dist/* /home/pietervdvn/git/mapcomplete.github.io/ && cd /home/pietervdvn/git/mapcomplete.github.io/ && echo \"mapcomplete.osm.be\" > CNAME && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", "clean": "rm -rf .cache/ && (find *.html | grep -v \"\\(index\\|land\\|test\\|preferences\\|customGenerator\\).html\" | xargs rm) && rm *.webmanifest" },