diff --git a/Customizations/AllKnownLayouts.ts b/Customizations/AllKnownLayouts.ts index f5a0a9d..c58a235 100644 --- a/Customizations/AllKnownLayouts.ts +++ b/Customizations/AllKnownLayouts.ts @@ -1,10 +1,7 @@ import {LayerDefinition} from "./LayerDefinition"; import {Layout} from "./Layout"; -import {Groen} from "./Layouts/Groen"; -import Cyclofix from "./Layouts/Cyclofix"; import {StreetWidth} from "./Layouts/StreetWidth"; import {MetaMap} from "./Layouts/MetaMap"; -import {Natuurpunt} from "./Layouts/Natuurpunt"; import {FromJSON} from "./JSON/FromJSON"; import * as bookcases from "../assets/themes/bookcases/Bookcases.json"; import * as aed from "../assets/themes/aed/aed.json"; @@ -12,29 +9,55 @@ import * as toilets from "../assets/themes/toilets/toilets.json"; import * as artworks from "../assets/themes/artwork/artwork.json"; import * as cyclestreets from "../assets/themes/cyclestreets/cyclestreets.json"; import * as ghostbikes from "../assets/themes/ghostbikes/ghostbikes.json" +import * as cyclofix from "../assets/themes/cyclofix/cyclofix.json" +import * as buurtnatuur from "../assets/themes/buurtnatuur/buurtnatuur.json" + import {PersonalLayout} from "../Logic/PersonalLayout"; export class AllKnownLayouts { public static allLayers: Map = undefined; + private static GenerateCycloFix(): Layout { + const layout = FromJSON.LayoutFromJSON(cyclofix) + const now = new Date(); + const m = now.getMonth() + 1; + const day = new Date().getDay() + 1; + const date = day + "/" + m; + if (date === "31/10" || date === "1/11" || date === "2/11") { + // Around Halloween/Fiesta de muerte/Allerzielen, we remember the dead + layout.layers.push( + FromJSON.sharedLayers.get("ghost_bike") + ); + + } + return layout; + + } + + private static GenerateBuurtNatuur(): Layout { + const layout = FromJSON.LayoutFromJSON(buurtnatuur); + layout.enableMoreQuests = false; + layout.enableShareScreen = false; + return layout; + } + public static layoutsList: Layout[] = [ new PersonalLayout(), - new Natuurpunt(), - new Cyclofix(), + // new Natuurpunt(), + AllKnownLayouts.GenerateBuurtNatuur(), FromJSON.LayoutFromJSON(bookcases), FromJSON.LayoutFromJSON(aed), FromJSON.LayoutFromJSON(toilets), FromJSON.LayoutFromJSON(artworks), FromJSON.LayoutFromJSON(cyclestreets), FromJSON.LayoutFromJSON(ghostbikes), - + AllKnownLayouts.GenerateCycloFix(), + new MetaMap(), new StreetWidth(), - new Groen(), - ]; - + public static allSets: Map = AllKnownLayouts.AllLayouts(); @@ -51,7 +74,6 @@ export class AllKnownLayouts { } } - if (this.allLayers[layer.id] !== undefined) { continue; } diff --git a/Customizations/JSON/FromJSON.ts b/Customizations/JSON/FromJSON.ts index 57a015b..cdeb066 100644 --- a/Customizations/JSON/FromJSON.ts +++ b/Customizations/JSON/FromJSON.ts @@ -18,7 +18,7 @@ import * as birdhides from "../../assets/layers/bird_hide/birdhides.json" import * as nature_reserve from "../../assets/layers/nature_reserve/nature_reserve.json" import * as bike_cafes from "../../assets/layers/bike_cafe/bike_cafes.json" import * as cycling_themed_objects from "../../assets/layers/cycling_themed_object/cycling_themed_objects.json" - +import * as bike_shops from "../../assets/layers/bike_shop/bike_shop.json" import {Utils} from "../../Utils"; import ImageCarouselWithUploadConstructor from "../../UI/Image/ImageCarouselWithUpload"; import {ImageCarouselConstructor} from "../../UI/Image/ImageCarousel"; @@ -44,7 +44,8 @@ export class FromJSON { FromJSON.Layer(birdhides), FromJSON.Layer(nature_reserve), FromJSON.Layer(bike_cafes), - FromJSON.Layer(cycling_themed_objects) + FromJSON.Layer(cycling_themed_objects), + FromJSON.Layer(bike_shops) ]; for (const layer of sharedLayersList) { @@ -77,6 +78,10 @@ export class FromJSON { json.startLat, json.startLon, new Combine(["

", tr(json.title), "

", tr(json.description)]), + undefined, + undefined, + tr(json.descriptionTail) + ); layout.widenFactor = json.widenFactor ?? 0.07; @@ -84,6 +89,7 @@ export class FromJSON { 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; } diff --git a/Customizations/JSON/LayoutConfigJson.ts b/Customizations/JSON/LayoutConfigJson.ts index 274b3f5..08cbe09 100644 --- a/Customizations/JSON/LayoutConfigJson.ts +++ b/Customizations/JSON/LayoutConfigJson.ts @@ -37,11 +37,21 @@ export interface LayoutConfigJson { * The title, as shown in the welcome message and the more-screen */ title: string | any; + + /** + * A short description, showed as social description and in the 'more theme'-buttons + */ + shortDescription?: string | any; + /** * The description, as shown in the welcome message and the more-screen */ description: string | any; + /** + * A part of the description, shown under the login-button. + */ + descriptionTail?: string | any; /** * The icon representing this theme. diff --git a/Customizations/Layers/BikeOtherShops.ts b/Customizations/Layers/BikeOtherShops.ts deleted file mode 100644 index 6dfb7be..0000000 --- a/Customizations/Layers/BikeOtherShops.ts +++ /dev/null @@ -1,94 +0,0 @@ -import {LayerDefinition} from "../LayerDefinition"; -import Translations from "../../UI/i18n/Translations"; -import {And, RegexTag, Tag} from "../../Logic/Tags"; -import ImageCarouselWithUploadConstructor from "../../UI/Image/ImageCarouselWithUpload"; -import ShopRetail from "../Questions/bike/ShopRetail"; -import ShopPump from "../Questions/bike/ShopPump"; -import ShopRental from "../Questions/bike/ShopRental"; -import ShopRepair from "../Questions/bike/ShopRepair"; -import ShopDiy from "../Questions/bike/ShopDiy"; -import ShopName from "../Questions/bike/ShopName"; -import ShopSecondHand from "../Questions/bike/ShopSecondHand"; -import {PhoneNumberQuestion} from "../Questions/PhoneNumberQuestion"; -import Website from "../Questions/Website"; -import {TagRenderingOptions} from "../TagRenderingOptions"; - - -export default class BikeOtherShops extends LayerDefinition { - private readonly sellsBikes = new Tag("service:bicycle:retail", "yes") - - private readonly to = Translations.t.cyclofix.nonBikeShop - - constructor() { - super("bikeOtherShop"); - this.name = this.to.name - this.icon = "./assets/bike/non_bike_repair_shop.svg" - this.overpassFilter = new And([ - new RegexTag("shop", /^bicycle$/, true), - new RegexTag(/^service:bicycle:/, /.*/), - ]) - this.presets = [] - this.maxAllowedOverlapPercentage = 10 - this.wayHandling = LayerDefinition.WAYHANDLING_CENTER_AND_WAY - - this.minzoom = 13; - this.style = this.generateStyleFunction(); - this.title = new TagRenderingOptions({ - mappings: [ - { - k: new And([new Tag("name", "*"), this.sellsBikes]), - txt: this.to.titleShopNamed - }, - { - k: new And([new Tag("name", "*"), new Tag("service:bicycle:retail", "")]), - txt: this.to.titleShop - }, - { - k: new And([new Tag("name", "*"), new Tag("service:bicycle:retail", "no")]), - txt: this.to.titleRepairNamed - }, - {k: this.sellsBikes, txt: this.to.titleShop}, - {k: new Tag("service:bicycle:retail", " "), txt: this.to.title}, - {k: new Tag("service:bicycle:retail", "no"), txt: this.to.titleRepair}, - { - k: new And([new Tag("name", "*")]), - txt: this.to.titleNamed - }, - {k: null, txt: this.to.title}, - ] - }) - - this.elementsToShow = [ - new ImageCarouselWithUploadConstructor(), - new ShopName(), - new PhoneNumberQuestion("{name}"), - new Website("{name}"), - new ShopRetail(), - new ShopRental(), - new ShopRepair(), - new ShopPump(), - new ShopDiy(), - new ShopSecondHand() - ] - } - - private generateStyleFunction() { - const self = this; - return function (tags: any) { - let icon = "assets/bike/non_bike_repair_shop.svg"; - - if (self.sellsBikes.matchesProperties(tags)) { - icon = "assets/bike/non_bike_shop.svg"; - } - - return { - color: "#00bb00", - icon: { - iconUrl: icon, - iconSize: [50, 50], - iconAnchor: [25, 50] - } - } - } - } -} diff --git a/Customizations/Layers/BikeShops.ts b/Customizations/Layers/BikeShops.ts deleted file mode 100644 index 5537ca5..0000000 --- a/Customizations/Layers/BikeShops.ts +++ /dev/null @@ -1,88 +0,0 @@ -import {LayerDefinition} from "../LayerDefinition"; -import Translations from "../../UI/i18n/Translations"; -import {And, Tag} from "../../Logic/Tags"; -import ImageCarouselWithUploadConstructor from "../../UI/Image/ImageCarouselWithUpload"; -import ShopRetail from "../Questions/bike/ShopRetail"; -import ShopPump from "../Questions/bike/ShopPump"; -import ShopRental from "../Questions/bike/ShopRental"; -import ShopRepair from "../Questions/bike/ShopRepair"; -import ShopDiy from "../Questions/bike/ShopDiy"; -import ShopName from "../Questions/bike/ShopName"; -import ShopSecondHand from "../Questions/bike/ShopSecondHand"; -import {PhoneNumberQuestion} from "../Questions/PhoneNumberQuestion"; -import Website from "../Questions/Website"; -import {EmailQuestion} from "../Questions/EmailQuestion"; -import {TagRenderingOptions} from "../TagRenderingOptions"; - - -export default class BikeShops extends LayerDefinition { - private readonly sellsBikes = new Tag("service:bicycle:retail", "yes") - - constructor() { - super("bikeshop"); - this.name = Translations.t.cyclofix.shop.name - this.icon = "./assets/bike/repair_shop.svg" - this.overpassFilter = new Tag("shop", "bicycle"); - this.presets = [{ - title: Translations.t.cyclofix.shop.title, - tags: [ - new Tag("shop", "bicycle"), - ] - }] - this.maxAllowedOverlapPercentage = 10 - this.wayHandling = LayerDefinition.WAYHANDLING_CENTER_AND_WAY - - this.minzoom = 13; - this.style = this.generateStyleFunction(); - this.title = new TagRenderingOptions({ - mappings: [ - {k: new And([new Tag("name", "*"), this.sellsBikes]), txt: Translations.t.cyclofix.shop.titleShopNamed}, - { - k: new And([new Tag("name", "*"), new Tag("service:bicycle:retail", "")]), - txt: Translations.t.cyclofix.shop.titleShop - }, - { - k: new And([new Tag("name", "*"), new Tag("service:bicycle:retail", "no")]), - txt: Translations.t.cyclofix.shop.titleRepairNamed - }, - {k: this.sellsBikes, txt: Translations.t.cyclofix.shop.titleShop}, - {k: new Tag("service:bicycle:retail", " "), txt: Translations.t.cyclofix.shop.title}, - {k: new Tag("service:bicycle:retail", "no"), txt: Translations.t.cyclofix.shop.titleRepair}, - ] - }) - - this.elementsToShow = [ - new ImageCarouselWithUploadConstructor(), - new ShopName(), - new Website("{name}"), - new PhoneNumberQuestion("{name}"), - new EmailQuestion("{name}"), - new ShopRetail(), - new ShopRental(), - new ShopRepair(), - new ShopPump(), - new ShopDiy(), - new ShopSecondHand() - ] - } - - private generateStyleFunction() { - const self = this; - return function (tags: any) { - let icon = "assets/bike/repair_shop.svg"; - - if (self.sellsBikes.matchesProperties(tags)) { - icon = "assets/bike/shop.svg"; - } - - return { - color: "#00bb00", - icon: { - iconUrl: icon, - iconSize: [50, 50], - iconAnchor: [25, 50] - } - } - } - } -} diff --git a/Customizations/Layers/Bos.ts b/Customizations/Layers/Bos.ts deleted file mode 100644 index 8fa93c2..0000000 --- a/Customizations/Layers/Bos.ts +++ /dev/null @@ -1,84 +0,0 @@ -import {LayerDefinition} from "../LayerDefinition"; -import {Or, Tag} from "../../Logic/Tags"; -import {AccessTag} from "../Questions/AccessTag"; -import {OperatorTag} from "../Questions/OperatorTag"; -import {NameQuestion} from "../Questions/NameQuestion"; -import {NameInline} from "../Questions/NameInline"; -import {DescriptionQuestion} from "../Questions/DescriptionQuestion"; -import ImageCarouselWithUploadConstructor from "../../UI/Image/ImageCarouselWithUpload"; - -export class Bos extends LayerDefinition { - - constructor() { - super("bos"); - this.name = "Bos"; - this.icon = ""; - - this.overpassFilter = new Or([ - new Tag("natural", "wood"), - new Tag("landuse", "forest"), - new Tag("natural", "scrub") - ] - ); - - - this.presets = [{ - title: "Bos", - description: "Voeg een ontbrekend bos toe aan de kaart", - icon: undefined, - tags: [ - new Tag("landuse", "forest"), - new Tag("fixme", "Toegevoegd met MapComplete, geometry nog uit te tekenen") - ] - }]; - this.maxAllowedOverlapPercentage = 10; - - this.minzoom = 13; - this.style = this.generateStyleFunction(); - this.title = new NameInline("Bos"); - this.elementsToShow = [ - new ImageCarouselWithUploadConstructor(), - new NameQuestion(), - new AccessTag(), - new OperatorTag(), - new DescriptionQuestion("bos") - ]; - - } - - - private generateStyleFunction() { - const self = this; - return function (properties: any) { - let questionSeverity = 0; - for (const qd of self.elementsToShow) { - if(qd instanceof DescriptionQuestion){ - continue; - } - - if (qd.IsQuestioning(properties)) { - questionSeverity = Math.max(questionSeverity, qd.Priority()); - } - } - - let colormapping = { - 0: "#00bb00", - 1: "#00ff00", - 10: "#dddd00", - 20: "#ff0000" - }; - - let colour = colormapping[questionSeverity]; - while (colour == undefined) { - questionSeverity--; - colour = colormapping[questionSeverity]; - } - - return { - color: colour, - icon: undefined - }; - }; - } - -} \ No newline at end of file diff --git a/Customizations/Layers/NatureReserves.ts b/Customizations/Layers/NatureReserves.ts index 4ebd93a..c502bde 100644 --- a/Customizations/Layers/NatureReserves.ts +++ b/Customizations/Layers/NatureReserves.ts @@ -1,11 +1,6 @@ import {LayerDefinition} from "../LayerDefinition"; import {Or, Tag} from "../../Logic/Tags"; -import {AccessTag} from "../Questions/AccessTag"; -import {OperatorTag} from "../Questions/OperatorTag"; -import {NameQuestion} from "../Questions/NameQuestion"; import {NameInline} from "../Questions/NameInline"; -import {DescriptionQuestion} from "../Questions/DescriptionQuestion"; -import ImageCarouselWithUploadConstructor from "../../UI/Image/ImageCarouselWithUpload"; import {TagRenderingOptions} from "../TagRenderingOptions"; export class NatureReserves extends LayerDefinition { @@ -27,13 +22,13 @@ export class NatureReserves extends LayerDefinition { ]; this.minzoom = 13; this.title = new NameInline("Natuurreservaat"); - this.style = this.generateStyleFunction(); + this.style = function () { + return { + color: "#00bb00", + icon: undefined + }; + }; this.elementsToShow = [ - new ImageCarouselWithUploadConstructor(), - new NameQuestion(), - new AccessTag(), - new OperatorTag(), - new DescriptionQuestion("natuurgebied") ]; @@ -97,38 +92,4 @@ export class NatureReserves extends LayerDefinition { } - - - private generateStyleFunction() { - const self = this; - return function (properties: any) { - let questionSeverity = 0; - for (const qd of self.elementsToShow) { - //if(qd instanceof DescriptionQuestion){ - // continue; - //} - if (qd.IsQuestioning(properties)) { - questionSeverity = Math.max(questionSeverity, qd.Priority() ?? 0); - } - } - - let colormapping = { - 0: "#00bb00", - 10: "#dddd00", - 20: "#ff0000" - }; - - let colour = colormapping[questionSeverity]; - while (colour == undefined) { - questionSeverity--; - colour = colormapping[questionSeverity]; - } - - return { - color: colour, - icon: undefined - }; - }; - } - } \ No newline at end of file diff --git a/Customizations/Layers/Park.ts b/Customizations/Layers/Park.ts deleted file mode 100644 index 69c57b1..0000000 --- a/Customizations/Layers/Park.ts +++ /dev/null @@ -1,110 +0,0 @@ -import {LayerDefinition} from "../LayerDefinition"; -import {Or, Tag} from "../../Logic/Tags"; -import {NameQuestion} from "../Questions/NameQuestion"; -import {NameInline} from "../Questions/NameInline"; -import {DescriptionQuestion} from "../Questions/DescriptionQuestion"; -import ImageCarouselWithUploadConstructor from "../../UI/Image/ImageCarouselWithUpload"; -import {TagRenderingOptions} from "../TagRenderingOptions"; - -export class Park extends LayerDefinition { - - - private accessByDefault = new TagRenderingOptions({ - question: "Is dit park publiek toegankelijk?", - mappings: [ - {k: new Tag("access", "yes"), txt: "Publiek toegankelijk"}, - {k: new Tag("access", ""), txt: "Publiek toegankelijk", hideInAnswer: true}, - {k: new Tag("access", "no"), txt: "Niet publiek toegankelijk"}, - {k: new Tag("access", "private"), txt: "Niet publiek toegankelijk, want privaat"}, - {k: new Tag("access", "guided"), txt: "Enkel toegankelijk met een gids of op een activiteit"}, - ], - freeform: { - key: "access", - renderTemplate: "Dit park is niet toegankelijk: {access}", - template: "De toegankelijkheid van dit park is: $$$" - }, - priority: 20 - }) - - private operatorByDefault = new - - TagRenderingOptions({ - question: "Wie beheert dit park?", - freeform: { - key: "operator", - renderTemplate: "Dit park wordt beheerd door {operator}", - template: "$$$", - }, - mappings: [{ - k: null, txt: "De gemeente beheert dit park" - }], - priority: 15 - }); - - - constructor() { - super("park"); - this.name = "Park"; - this.icon = undefined; - this.overpassFilter = - new Or([new Tag("leisure", "park"), new Tag("landuse", "village_green")]); - this.presets = [{ - title: "Park", - description: "Voeg een ontbrekend park toe. Een park is een groene ruimte die openbaar is." + - "Typisch vind je er banken, vuilbakken, standbeelden, ... ", - tags: [new Tag("leisure", "park"), - new Tag("fixme", "Toegevoegd met MapComplete, geometry nog uit te tekenen")] - }]; - this.maxAllowedOverlapPercentage = 25; - - this.minzoom = 13; - this.style = this.generateStyleFunction(); - this.title = new NameInline("Park"); - this.elementsToShow = [ - new ImageCarouselWithUploadConstructor(), - new NameQuestion(), - this.accessByDefault, - this.operatorByDefault, - new DescriptionQuestion("park"), - - ]; - - } - - - - - private generateStyleFunction() { - const self = this; - return function (properties: any) { - let questionSeverity = 0; - for (const qd of self.elementsToShow) { - if (qd instanceof DescriptionQuestion) { - continue; - } - if (qd.IsQuestioning(properties)) { - questionSeverity = Math.max(questionSeverity, qd.Priority() ?? 0); - } - } - - let colormapping = { - 0: "#00bb00", - 1: "#00ff00", - 10: "#dddd00", - 20: "#ff0000" - }; - - let colour = colormapping[questionSeverity]; - while (colour == undefined) { - questionSeverity--; - colour = colormapping[questionSeverity]; - } - - return { - color: colour, - icon: undefined - }; - }; - } - -} \ No newline at end of file diff --git a/Customizations/Layouts/Cyclofix.ts b/Customizations/Layouts/Cyclofix.ts deleted file mode 100644 index 4206c9d..0000000 --- a/Customizations/Layouts/Cyclofix.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {Layout} from "../Layout"; -import BikeShops from "../Layers/BikeShops"; -import Translations from "../../UI/i18n/Translations"; -import Combine from "../../UI/Base/Combine"; -import BikeOtherShops from "../Layers/BikeOtherShops"; - - -export default class Cyclofix extends Layout { - - private static RememberTheDead(): boolean { - const now = new Date(); - const m = now.getMonth() + 1; - const day = new Date().getDay() + 1; - const date = day + "/" + m; - return (date === "31/10" || date === "1/11" || date === "2/11"); - } - - constructor() { - super( - "cyclofix", - ["en", "nl", "fr", "gl","de"], - Translations.t.cyclofix.title, - ["bike_repair_station", "bike_cafes", new BikeShops(), "drinking_water", "bike_parking", new BikeOtherShops(),"bike_themed_object", - // The first of november, halloween and the second of november, we remember our dead - ...(Cyclofix.RememberTheDead() ? ["ghost_bike"] : [])], - 16, - 50.8465573, - 4.3516970, - new Combine([ - "

", - Translations.t.cyclofix.title, - "


", - Translations.t.cyclofix.description, - "

" - ]) - ); - this.icon = "./assets/bike/logo.svg" - this.description = "Easily search and contribute bicycle data nearby"; - this.socialImage = "./assets/bike/cyclofix.jpeg"; - this.widenFactor = 0.05; - } -} diff --git a/Customizations/Layouts/GRB.ts b/Customizations/Layouts/GRB.ts deleted file mode 100644 index 9efafb9..0000000 --- a/Customizations/Layouts/GRB.ts +++ /dev/null @@ -1,23 +0,0 @@ -import {Layout} from "../Layout"; -import {GrbToFix} from "../Layers/GrbToFix"; - -export class GRB extends Layout { - constructor() { - super("grb", - ["en"], - "Grb import fix tool", - [new GrbToFix()], - 15, - 51.2083, - 3.2279, - - - "

GRB Fix tool

\n" + - "\n" + - "Expert use only" - - , - "", ""); - this.hideFromOverview = true; - } -} \ No newline at end of file diff --git a/Customizations/Layouts/Groen.ts b/Customizations/Layouts/Groen.ts deleted file mode 100644 index 103f479..0000000 --- a/Customizations/Layouts/Groen.ts +++ /dev/null @@ -1,61 +0,0 @@ -import {Park} from "../Layers/Park"; -import {Bos} from "../Layers/Bos"; -import {Layout} from "../Layout"; -import {NatureReserves} from "../Layers/NatureReserves"; - -export class Groen extends Layout { - - constructor() { - super("buurtnatuur", - ["nl"], - "Buurtnatuur.be", - [new NatureReserves(), new Park(), new Bos(), "viewpoint"], - 10, - 50.8435, - 4.3688, - "\n" + - - "
" + - "

Breng jouw buurtnatuur in kaart

" + - "Natuur maakt gelukkig. 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" + - "" + - "

Samen kleuren we heel Vlaanderen en Brussel groen.

" + - "

Blijf op de hoogte van de resultaten van buurtnatuur.be: meld je aan voor e-mailupdates.

\n" - , - - "Begin meteen door een account te maken\n" + - " te maken of\n" + - " in te loggen.", - "", - - "

Tips

" + - - "" + - "" + - "

" + - "De oorspronkelijke data komt van OpenStreetMap en je antwoorden worden daar bewaard.
Omdat iedereen vrij kan meewerken aan dit project, kunnen we niet garanderen dat er geen fouten opduiken." + - "Kan je hier niet aanpassen wat je wilt, dan kan je dat zelf via OpenStreetMap.org doen. Groen kan geen enkele verantwoordelijkheid nemen over de kaart." + - "

" + - "Je privacy is belangrijk. We tellen wel hoeveel gebruikers deze website bezoeken. We plaatsen een cookie waar geen persoonlijke informatie in bewaard wordt. " + - "Als je inlogt, komt er een tweede cookie bij met je inloggegevens." + - "
" - ); - - this.icon = "./assets/themes/buurtnatuur/groen_logo.svg" - this.socialImage = "assets/themes/buurtnatuur/social_image.jpg" - this.description = "Met deze tool kan je natuur in je buurt in kaart brengen en meer informatie geven over je favoriete plekje" - this.enableMoreQuests = false; - this.enableShareScreen = false - } -} \ No newline at end of file diff --git a/Customizations/OnlyShowIf.ts b/Customizations/OnlyShowIf.ts index 6e3a3a0..297c02d 100644 --- a/Customizations/OnlyShowIf.ts +++ b/Customizations/OnlyShowIf.ts @@ -36,10 +36,6 @@ export class OnlyShowIfConstructor implements TagDependantUIElementConstructor{ return this._embedded.IsQuestioning(properties); } - Priority(): number { - return this._embedded.Priority(); - } - GetContent(tags: any): Translation { if(!this.IsKnown(tags)){ return undefined; @@ -78,10 +74,6 @@ class OnlyShowIf extends UIElement implements TagDependantUIElement { } } - Priority(): number { - return this._embedded.Priority(); - } - IsKnown(): boolean { if(!this.Matches()){ return false; diff --git a/Customizations/Questions/AccessTag.ts b/Customizations/Questions/AccessTag.ts deleted file mode 100644 index 6375962..0000000 --- a/Customizations/Questions/AccessTag.ts +++ /dev/null @@ -1,35 +0,0 @@ -import {And, Tag} from "../../Logic/Tags"; -import {TagRenderingOptions} from "../TagRenderingOptions"; - -export class AccessTag extends TagRenderingOptions { - - private static options = { - priority: 20, - question: "Is dit gebied toegankelijk?", - freeform: { - key: "access:description", - template: "Iets anders: $$$", - renderTemplate: "De toegankelijkheid van dit gebied is: {access:description}", - placeholder: "Specifieer" - }, - mappings: [ - {k: new And([new Tag("access", "yes"), new Tag("fee", "")]), txt: "Publiek toegankelijk"}, - {k: new And([new Tag("access", "no"), new Tag("fee", "")]), txt: "Niet toegankelijk"}, - {k: new And([new Tag("access", "private"), new Tag("fee", "")]), txt: "Niet toegankelijk, want privegebied"}, - {k: new And([new Tag("access", "permissive"), new Tag("fee", "")]), txt: "Toegankelijk, maar het is privegebied"}, - {k: new And([new Tag("access", "guided"), new Tag("fee", "")]), txt: "Enkel met een gids of tijdens een activiteit toegankelijk"}, - { - k: new And([new Tag("access", "yes"), - new Tag("fee", "yes")]), - txt: "Toegankelijk mits betaling", - priority: 10 - }, - ] - } - - constructor() { - super(AccessTag.options); - } - - -} \ No newline at end of file diff --git a/Customizations/Questions/EmailQuestion.ts b/Customizations/Questions/EmailQuestion.ts deleted file mode 100644 index 6120ea8..0000000 --- a/Customizations/Questions/EmailQuestion.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {UIElement} from "../../UI/UIElement"; -import Translations from "../../UI/i18n/Translations"; -import {TagRenderingOptions} from "../TagRenderingOptions"; - -export class EmailQuestion extends TagRenderingOptions { - - constructor(category: string | UIElement) { - super({ - question: Translations.t.general.questions.emailOf.Subs({category: category}), - freeform: { - renderTemplate: Translations.t.general.questions.emailIs.Subs({category: category}), - template: "$email$", - key: "email" - } - }); - } - -} \ No newline at end of file diff --git a/Customizations/Questions/OperatorTag.ts b/Customizations/Questions/OperatorTag.ts index dc9290a..b3fcb75 100644 --- a/Customizations/Questions/OperatorTag.ts +++ b/Customizations/Questions/OperatorTag.ts @@ -5,24 +5,21 @@ import {TagRenderingOptions} from "../TagRenderingOptions"; export class OperatorTag extends TagRenderingOptions { - private static options = { - priority: 15, - question: "Wie beheert dit gebied?", - freeform: { - key: "operator", - template: "Beheer door $$$", - renderTemplate: "Beheer door {operator}", - placeholder: "organisatie" - }, - mappings: [ - {k: new Tag("operator", "Natuurpunt"), txt: "Natuurpunt"}, - {k: new Tag("operator", "Agentschap Natuur en Bos"), txt: "het Agentschap Natuur en Bos (ANB)"}, - {k: new Tag("operator", "private"), txt: "Beheer door een privépersoon"} - ] - } - constructor() { - super(OperatorTag.options); + super({ + question: "Wie beheert dit gebied?", + freeform: { + key: "operator", + template: "Beheer door $$$", + renderTemplate: "Beheer door {operator}", + placeholder: "organisatie" + }, + mappings: [ + {k: new Tag("operator", "Natuurpunt"), txt: "Natuurpunt"}, + {k: new Tag("operator", "Agentschap Natuur en Bos"), txt: "het Agentschap Natuur en Bos (ANB)"}, + {k: new Tag("operator", "private"), txt: "Beheer door een privépersoon"} + ] + }); } } \ No newline at end of file diff --git a/Customizations/Questions/PhoneNumberQuestion.ts b/Customizations/Questions/PhoneNumberQuestion.ts deleted file mode 100644 index 7033766..0000000 --- a/Customizations/Questions/PhoneNumberQuestion.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {UIElement} from "../../UI/UIElement"; -import Translations from "../../UI/i18n/Translations"; -import {TagRenderingOptions} from "../TagRenderingOptions"; - -export class PhoneNumberQuestion extends TagRenderingOptions { - - constructor(category: string | UIElement) { - super({ - question: Translations.t.general.questions.phoneNumberOf.Subs({category: category}), - freeform: { - renderTemplate: Translations.t.general.questions.phoneNumberIs.Subs({category: category}), - template: "$phone$", - key: "phone" - } - }); - } - -} \ No newline at end of file diff --git a/Customizations/Questions/Website.ts b/Customizations/Questions/Website.ts deleted file mode 100644 index ce3f3ca..0000000 --- a/Customizations/Questions/Website.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {UIElement} from "../../UI/UIElement"; -import Translations from "../../UI/i18n/Translations"; -import {TagRenderingOptions} from "../TagRenderingOptions"; - - -export default class Website extends TagRenderingOptions { - constructor(category: string | UIElement) { - super({ - question: Translations.t.general.questions.websiteOf.Subs({category: category}), - freeform: { - renderTemplate: Translations.t.general.questions.websiteIs, - template: "$$$", - key: "website" - } - }); - } -} diff --git a/Customizations/Questions/bike/ShopDiy.ts b/Customizations/Questions/bike/ShopDiy.ts deleted file mode 100644 index 2a643a7..0000000 --- a/Customizations/Questions/bike/ShopDiy.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {Tag} from "../../../Logic/Tags"; -import Translations from "../../../UI/i18n/Translations"; -import {TagRenderingOptions} from "../../TagRenderingOptions"; - - -export default class ShopDiy extends TagRenderingOptions { - constructor() { - const key = 'service:bicycle:diy' - const to = Translations.t.cyclofix.shop.diy - super({ - question: to.question, - mappings: [ - {k: new Tag(key, "yes"), txt: to.yes}, - {k: new Tag(key, "no"), txt: to.no}, - ] - }); - } -} diff --git a/Customizations/Questions/bike/ShopName.ts b/Customizations/Questions/bike/ShopName.ts deleted file mode 100644 index 1dd1f48..0000000 --- a/Customizations/Questions/bike/ShopName.ts +++ /dev/null @@ -1,17 +0,0 @@ -import Translations from "../../../UI/i18n/Translations"; -import {TagRenderingOptions} from "../../TagRenderingOptions"; - - -export default class ShopPump extends TagRenderingOptions { - constructor() { - const to = Translations.t.cyclofix.shop.qName - super({ - question: to.question, - freeform: { - key: "name", - renderTemplate: to.render, - template: to.template - } - }) - } -} diff --git a/Customizations/Questions/bike/ShopPump.ts b/Customizations/Questions/bike/ShopPump.ts deleted file mode 100644 index efa2365..0000000 --- a/Customizations/Questions/bike/ShopPump.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {Tag} from "../../../Logic/Tags"; -import Translations from "../../../UI/i18n/Translations"; -import {TagRenderingOptions} from "../../TagRenderingOptions"; - - -export default class ShopPump extends TagRenderingOptions { - constructor() { - const key = 'service:bicycle:pump' - const to = Translations.t.cyclofix.shop.pump - super({ - question: to.question, - mappings: [ - {k: new Tag(key, "yes"), txt: to.yes}, - {k: new Tag(key, "no"), txt: to.no}, - ] - }); - } -} diff --git a/Customizations/Questions/bike/ShopRental.ts b/Customizations/Questions/bike/ShopRental.ts deleted file mode 100644 index 412b923..0000000 --- a/Customizations/Questions/bike/ShopRental.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {Tag} from "../../../Logic/Tags"; -import Translations from "../../../UI/i18n/Translations"; -import {TagRenderingOptions} from "../../TagRenderingOptions"; - - -export default class ShopRental extends TagRenderingOptions { - constructor() { - const key = 'service:bicycle:rental' - const to = Translations.t.cyclofix.shop.rental - super({ - question: to.question, - mappings: [ - {k: new Tag(key, "yes"), txt: to.yes}, - {k: new Tag(key, "no"), txt: to.no}, - ] - }); - } -} diff --git a/Customizations/Questions/bike/ShopRepair.ts b/Customizations/Questions/bike/ShopRepair.ts deleted file mode 100644 index 1196820..0000000 --- a/Customizations/Questions/bike/ShopRepair.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {Tag} from "../../../Logic/Tags"; -import Translations from "../../../UI/i18n/Translations"; -import {TagRenderingOptions} from "../../TagRenderingOptions"; - - -export default class ShopRepair extends TagRenderingOptions { - constructor() { - const key = 'service:bicycle:repair' - const to = Translations.t.cyclofix.shop.repair - super({ - question: to.question, - mappings: [ - {k: new Tag(key, "yes"), txt: to.yes}, - {k: new Tag(key, "only_sold"), txt: to.sold}, - {k: new Tag(key, "brand"), txt: to.brand}, - {k: new Tag(key, "no"), txt: to.no}, - ] - }); - } -} diff --git a/Customizations/Questions/bike/ShopRetail.ts b/Customizations/Questions/bike/ShopRetail.ts deleted file mode 100644 index 9f268c1..0000000 --- a/Customizations/Questions/bike/ShopRetail.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {Tag} from "../../../Logic/Tags"; -import Translations from "../../../UI/i18n/Translations"; -import {TagRenderingOptions} from "../../TagRenderingOptions"; - - -export default class ShopRetail extends TagRenderingOptions { - constructor() { - const key = 'service:bicycle:retail' - const to = Translations.t.cyclofix.shop.retail - super({ - question: to.question, - mappings: [ - {k: new Tag(key, "yes"), txt: to.yes}, - {k: new Tag(key, "no"), txt: to.no}, - ] - }); - } -} diff --git a/Customizations/Questions/bike/ShopSecondHand.ts b/Customizations/Questions/bike/ShopSecondHand.ts deleted file mode 100644 index c8f3379..0000000 --- a/Customizations/Questions/bike/ShopSecondHand.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {Tag} from "../../../Logic/Tags"; -import Translations from "../../../UI/i18n/Translations"; -import {TagRenderingOptions} from "../../TagRenderingOptions"; - - -export default class ShopPump extends TagRenderingOptions { - constructor() { - const key = 'service:bicycle:second_hand' - const to = Translations.t.cyclofix.shop.secondHand - super({ - question: to.question, - mappings: [ - {k: new Tag(key, "yes"), txt: to.yes}, - {k: new Tag(key, "no"), txt: to.no}, - {k: new Tag(key, "only"), txt: to.only}, - ] - }); - } -} diff --git a/Customizations/TagRenderingOptions.ts b/Customizations/TagRenderingOptions.ts index 4de499b..6ad7e3a 100644 --- a/Customizations/TagRenderingOptions.ts +++ b/Customizations/TagRenderingOptions.ts @@ -11,7 +11,6 @@ export class TagRenderingOptions implements TagDependantUIElementConstructor { * Notes: by not giving a 'question', one disables the question form alltogether */ public options: { - priority?: number; question?: string | Translation; freeform?: { key: string; @@ -22,7 +21,7 @@ export class TagRenderingOptions implements TagDependantUIElementConstructor { extraTags?: TagsFilter }; multiAnswer?: boolean, - mappings?: { k: TagsFilter; txt: string | Translation; priority?: number, substitute?: boolean, hideInAnwser?: boolean }[] + mappings?: { k: TagsFilter; txt: string | Translation; substitute?: boolean, hideInAnwser?: boolean }[] }; constructor(options: { @@ -146,8 +145,4 @@ export class TagRenderingOptions implements TagDependantUIElementConstructor { return !this.IsQuestioning(properties); } - Priority(): number { - return this.options.priority ?? 0; - } - } \ No newline at end of file diff --git a/Customizations/UIElementConstructor.ts b/Customizations/UIElementConstructor.ts index b17fb8b..25e29b4 100644 --- a/Customizations/UIElementConstructor.ts +++ b/Customizations/UIElementConstructor.ts @@ -12,7 +12,6 @@ export interface TagDependantUIElementConstructor { construct(dependencies: Dependencies): TagDependantUIElement; IsKnown(properties: any): boolean; IsQuestioning(properties: any): boolean; - Priority(): number; GetContent(tags: any): Translation; } @@ -23,7 +22,5 @@ export abstract class TagDependantUIElement extends UIElement { abstract IsQuestioning(): boolean; - abstract Priority() : number; - abstract IsSkipped() : boolean; } \ No newline at end of file diff --git a/InitUiElements.ts b/InitUiElements.ts index 876a2f1..b288aa0 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -355,11 +355,12 @@ export class InitUiElements { let baseLayerOptions = BaseLayers.baseLayers.map((layer) => { return {value: layer, shown: layer.name} }); - let layerControlPanel = new Combine([new DropDown(Translations.t.general.backgroundMap, baseLayerOptions, State.state.bm.CurrentLayer)]); + let layerControlPanel = new Combine( + [new DropDown(Translations.t.general.backgroundMap, baseLayerOptions, State.state.bm.CurrentLayer)]); layerControlPanel.SetStyle("margin:1em"); if (State.state.filteredLayers.data.length > 1) { const layerSelection = new LayerSelection(); - layerControlPanel = new Combine([layerSelection, layerControlPanel]); + layerControlPanel = new Combine([layerSelection, "
",layerControlPanel]); } return layerControlPanel; } @@ -375,6 +376,7 @@ export class InitUiElements { new Combine([ closeButton, layerControlPanel]).SetStyle("display:flex;flex-direction:row;") + .SetClass("hidden-on-mobile") , new Combine([Img.closedFilterButton]) .SetStyle("display:block;border-radius:50%;background:white;padding:1em;"), @@ -408,15 +410,21 @@ export class InitUiElements { static InitBaseMap(){ const bm = new Basemap("leafletDiv", State.state.locationControl, new VariableUiElement( State.state.locationControl.map((location) => { - const mapComplete = `Mapcomplete ${State.vNumber} Report bug`; + const mapComplete = `Mapcomplete ${State.vNumber}` + const reportBug = ``; + + const layoutId = State.state.layoutToUse.data.id; + const osmChaLink = `https://osmcha.org/?filters=%7B%22comment%22%3A%5B%7B%22label%22%3A%22%23${layoutId}%22%2C%22value%22%3A%22%23${layoutId}%22%7D%5D%2C%22date__gte%22%3A%5B%7B%22label%22%3A%222020-07-05%22%2C%22value%22%3A%222020-07-05%22%7D%5D%2C%22editor%22%3A%5B%7B%22label%22%3A%22MapComplete%22%2C%22value%22%3A%22MapComplete%22%7D%5D%7D` + console.log("OsmCha link is",osmChaLink); + const stats = ``; let editHere = ""; if (location !== undefined) { - editHere = " | " + + editHere = "" + "edit here" + "" } - return mapComplete + editHere; + return new Combine([mapComplete, reportBug, " | ", stats, " | ",editHere]).Render(); }) )); diff --git a/Logic/FilteredLayer.ts b/Logic/FilteredLayer.ts index c908ebc..acc72d2 100644 --- a/Logic/FilteredLayer.ts +++ b/Logic/FilteredLayer.ts @@ -221,7 +221,7 @@ export class FilteredLayer { color: style.color }); - } else if (style.icon.iconUrl.startsWith("$circle ")) { + } else if (style.icon.iconUrl.startsWith("$circle")) { marker = L.circle(latLng, { radius: 25, color: style.color diff --git a/Logic/LayerUpdater.ts b/Logic/LayerUpdater.ts index 6473e7e..178a96c 100644 --- a/Logic/LayerUpdater.ts +++ b/Logic/LayerUpdater.ts @@ -56,7 +56,6 @@ export class LayerUpdater { continue; } if (state.locationControl.data.zoom < layer.minzoom) { - console.log("Not loading layer ", layer.id, " as it needs at least ", layer.minzoom, "zoom") continue; } // Check if data for this layer has already been loaded diff --git a/Logic/Osm/OsmPreferences.ts b/Logic/Osm/OsmPreferences.ts index d57b93d..8ff413a 100644 --- a/Logic/Osm/OsmPreferences.ts +++ b/Logic/Osm/OsmPreferences.ts @@ -140,7 +140,6 @@ export class OsmPreferences { } if (this.preferences.data[k] === v) { - console.log("Not updating preference", k, " to ", v, "not changed"); return; } console.log("Updating preference", k, " to ", Utils.EllipsesAfter(v, 15)); @@ -155,7 +154,6 @@ export class OsmPreferences { console.log("Could not remove preference", error); return; } - console.log("Preference ",k,"removed!"); }); diff --git a/Logic/PersonalLayout.ts b/Logic/PersonalLayout.ts index 77355e0..c1f4d39 100644 --- a/Logic/PersonalLayout.ts +++ b/Logic/PersonalLayout.ts @@ -17,6 +17,7 @@ export class PersonalLayout extends Layout { Translations.t.favourite.description, ); + this.description = "The personal theme allows to select one or more layers from all the layouts, creating a truly personal editor" this.icon = "./assets/star.svg" } diff --git a/Logic/Tags.ts b/Logic/Tags.ts index 0eecb48..307ea06 100644 --- a/Logic/Tags.ts +++ b/Logic/Tags.ts @@ -106,23 +106,18 @@ export class Tag extends TagsFilter { } matches(tags: { k: string; v: string }[]): boolean { - if (this.value === "") { - return true - } for (const tag of tags) { if (this.key == tag.k) { - - if (tag.v === "") { - // This tag has been removed -> always matches false - return false; - } - - if (this.value === tag.v) { - return true; - } + return this.value === tag.v; } } + + // The tag was not found + if(this.value === ""){ + // and it shouldn't be found! + return true; + } return false; } diff --git a/README.md b/README.md index 158e24c..b9876ba 100644 --- a/README.md +++ b/README.md @@ -172,3 +172,12 @@ Home icon by Timothy Miller, CC-BY-SA 3.0 https://commons.wikimedia.org/wiki/File:Map_icons_by_Scott_de_Jonge_-_bicycle-store.svg Bicycle logo, Scott de Jonge + +Nature Reserve icon via http://www.onlinewebfonts.com/icon/389579, CC BY 3.0 (@ Эдуард Черных) + + +Park icon via http://www.onlinewebfonts.com/icon/425974, CC BY 3.0 (@sterankofrank) + +Forest icon via https://www.onlinewebfonts.com/icon/498112, CC BY + +Statistics icon via https://www.onlinewebfonts.com/icon/197818 \ No newline at end of file diff --git a/State.ts b/State.ts index 8ad6604..ef2a7ce 100644 --- a/State.ts +++ b/State.ts @@ -22,10 +22,11 @@ export class State { // The singleton of the global state public static state: State; - public static vNumber = "0.0.8"; + public static vNumber = "0.0.8a"; // The user journey states thresholds when a new feature gets unlocked public static userJourney = { + addNewPointsUnlock: 1, moreScreenUnlock: 5, personalLayoutUnlock: 20, tagsVisibleAt: 100, @@ -33,8 +34,7 @@ export class State { tagsVisibleAndWikiLinked: 150, themeGeneratorReadOnlyUnlock: 200, themeGeneratorFullUnlock: 500, - - + addNewPointWithUnreadMessagesUnlock: 500 }; public static runningFromConsole: boolean = false; @@ -118,7 +118,7 @@ export class State { str => isNaN(Number(str)) ? 0 : Number(str),[],n => ""+n ); - constructor(layoutToUse: Layout, useDevServer = false) { + constructor(layoutToUse: Layout) { const self = this; this.layoutToUse.setData(layoutToUse) this.locationControl = new UIEventSource<{ lat: number, lon: number, zoom: number }>({ diff --git a/UI/Base/SubtleButton.ts b/UI/Base/SubtleButton.ts index 5821d29..1fd801d 100644 --- a/UI/Base/SubtleButton.ts +++ b/UI/Base/SubtleButton.ts @@ -19,7 +19,7 @@ export class SubtleButton extends UIElement{ if ((imageUrl ?? "") === "") { this.image = new FixedUiElement(""); } else if (typeof (imageUrl) === "string") { - this.image = new FixedUiElement(``); + this.image = new FixedUiElement(``); } else { this.image = imageUrl; } diff --git a/UI/CustomGenerator/CustomGeneratorPanel.ts b/UI/CustomGenerator/CustomGeneratorPanel.ts index 6d92eb7..7bf45ce 100644 --- a/UI/CustomGenerator/CustomGeneratorPanel.ts +++ b/UI/CustomGenerator/CustomGeneratorPanel.ts @@ -7,7 +7,6 @@ import Combine from "../Base/Combine"; import {VariableUiElement} from "../Base/VariableUIElement"; import {TabbedComponent} from "../Base/TabbedComponent"; import PageSplit from "../Base/PageSplit"; -import HelpText from "../../Customizations/HelpText"; import AllLayersPanel from "./AllLayersPanel"; import SharePanel from "./SharePanel"; import {LayoutConfigJson} from "../../Customizations/JSON/LayoutConfigJson"; @@ -16,6 +15,7 @@ import {State} from "../../State"; import {FixedUiElement} from "../Base/FixedUiElement"; import SavePanel from "./SavePanel"; import {LocalStorageSource} from "../../Logic/Web/LocalStorageSource"; +import HelpText from "./HelpText"; export default class CustomGeneratorPanel extends UIElement { @@ -42,7 +42,8 @@ export default class CustomGeneratorPanel extends UIElement { const encoded = es.map(config => btoa(JSON.stringify(config))); encoded.addCallback(encoded => LocalStorageSource.Get("last-custom-theme")) const liveUrl = encoded.map(encoded => `./index.html?userlayout=${es.data.id}#${encoded}`) - const iframe = liveUrl.map(url => ``); + const testUrl = encoded.map(encoded => `./index.html?test=true&userlayout=${es.data.id}#${encoded}`) + const iframe = testUrl.map(url => ``); const currentSetting = new UIEventSource>(undefined) const generalSettings = new GeneralSettings(es, currentSetting); const languages = generalSettings.languages; diff --git a/UI/CustomGenerator/GeneralSettings.ts b/UI/CustomGenerator/GeneralSettings.ts index 9f40bc4..c26e971 100644 --- a/UI/CustomGenerator/GeneralSettings.ts +++ b/UI/CustomGenerator/GeneralSettings.ts @@ -43,8 +43,10 @@ export default class GeneralSettingsPanel extends UIElement { "Supported languages", "Which languages do you want to support in this theme? Type the two letter code representing your language, seperated by ;. For example:en;nl "), new SingleSetting(configuration, new MultiLingualTextFields(this.languages), "title", "Title", "The title as shown in the welcome message, in the browser title bar, in the more screen, ..."), + new SingleSetting(configuration, new MultiLingualTextFields(this.languages), "shortDescription","Short description", + "The short description is shown as subtext in the social preview and on the 'more screen'-buttons. It should be at most one sentence of around ~25words"), new SingleSetting(configuration, new MultiLingualTextFields(this.languages, true), - "description", "Description", "The description is shown in the welcomemessage. It is a small text welcoming users"), + "description", "Description", "The description is shown in the welcome-message when opening MapComplete. It is a small text welcoming users"), new SingleSetting(configuration, TextField.StringInput(), "icon", "Icon", "A visual representation for your theme; used as logo in the welcomeMessage. If your theme is official, used as favicon and webapp logo", { diff --git a/UI/CustomGenerator/GenerateEmpty.ts b/UI/CustomGenerator/GenerateEmpty.ts index 7c13fa2..674d78c 100644 --- a/UI/CustomGenerator/GenerateEmpty.ts +++ b/UI/CustomGenerator/GenerateEmpty.ts @@ -32,6 +32,7 @@ export class GenerateEmpty { return { id: "id", title: {}, + shortDescription: {}, description: {}, language: [], maintainer: "", @@ -51,6 +52,7 @@ export class GenerateEmpty { return { id: "test", title: {"en": "Test layout"}, + shortDescription: {}, description: {"en": "A layout for testing"}, language: ["en"], maintainer: "Pieter Vander Vennet", diff --git a/Customizations/HelpText.ts b/UI/CustomGenerator/HelpText.ts similarity index 78% rename from Customizations/HelpText.ts rename to UI/CustomGenerator/HelpText.ts index af0ccf3..2769790 100644 --- a/Customizations/HelpText.ts +++ b/UI/CustomGenerator/HelpText.ts @@ -1,9 +1,9 @@ -import {UIElement} from "../UI/UIElement"; -import {SubtleButton} from "../UI/Base/SubtleButton"; -import {VariableUiElement} from "../UI/Base/VariableUIElement"; -import SingleSetting from "../UI/CustomGenerator/SingleSetting"; -import Combine from "../UI/Base/Combine"; -import {UIEventSource} from "../Logic/UIEventSource"; +import {UIEventSource} from "../../Logic/UIEventSource"; +import {UIElement} from "../UIElement"; +import {VariableUiElement} from "../Base/VariableUIElement"; +import {SubtleButton} from "../Base/SubtleButton"; +import Combine from "../Base/Combine"; +import SingleSetting from "./SingleSetting"; export default class HelpText extends UIElement { @@ -32,7 +32,7 @@ export default class HelpText extends UIElement { return "

Welcome to the Custom Theme Builder

" + "Here, one can make their own custom mapcomplete themes.
" + "Fill out the fields to get a working mapcomplete theme. More information on the selected field will appear here when you click it.
" + - "Want to see how the quests are doing in number of visits? All the stats are open on goatcounter"; + "Want to see how the quests are doing in number of visits? All the stats are open on goatcounter"; } return new Combine(["

", setting._name, "

", setting._description.Render()]).Render(); diff --git a/UI/CustomGenerator/LayerPanel.ts b/UI/CustomGenerator/LayerPanel.ts index 97e3796..563d577 100644 --- a/UI/CustomGenerator/LayerPanel.ts +++ b/UI/CustomGenerator/LayerPanel.ts @@ -96,7 +96,7 @@ export default class LayerPanel extends UIElement { {value: 2, shown: "Show both the ways/areas and the centerpoints"}, {value: 1, shown: "Show everything as centerpoint"}]), "wayHandling", "Way handling", "Describes how ways and areas are represented on the map: areas can be represented as the area itself, or it can be converted into the centerpoint"), - setting(TextField.NumberInput("nat", n => n <= 100), "hideUnderlayingFeaturesMinPercentage", "Max allowed overlap percentage", + setting(TextField.NumberInput("int", n => n <= 100), "hideUnderlayingFeaturesMinPercentage", "Max allowed overlap percentage", "Consider that we want to show 'Nature Reserves' and 'Forests'. Now, ofter, there are pieces of forest mapped _in_ the nature reserve.
" + "Now, showing those pieces of forest overlapping with the nature reserve truly clutters the map and is very user-unfriendly.
" + "The features are placed layer by layer. If a feature below a feature on this layer overlaps for more then 'x'-percent, the underlying feature is hidden."), diff --git a/UI/CustomGenerator/LayerPanelWithPreview.ts b/UI/CustomGenerator/LayerPanelWithPreview.ts index 16e17f1..ec2e56f 100644 --- a/UI/CustomGenerator/LayerPanelWithPreview.ts +++ b/UI/CustomGenerator/LayerPanelWithPreview.ts @@ -2,7 +2,7 @@ import {UIElement} from "../UIElement"; import {UIEventSource} from "../../Logic/UIEventSource"; import SingleSetting from "./SingleSetting"; import LayerPanel from "./LayerPanel"; -import HelpText from "../../Customizations/HelpText"; +import HelpText from "./HelpText"; import {MultiTagInput} from "../Input/MultiTagInput"; import {FromJSON} from "../../Customizations/JSON/FromJSON"; import Combine from "../Base/Combine"; diff --git a/UI/FeatureInfoBox.ts b/UI/FeatureInfoBox.ts index 0ff8b12..dd1bfc0 100644 --- a/UI/FeatureInfoBox.ts +++ b/UI/FeatureInfoBox.ts @@ -115,30 +115,16 @@ export class FeatureInfoBox extends UIElement { let questionElement: UIElement; - if (!State.state.osmConnection.userDetails.data.loggedIn) { - let mostImportantQuestion ; - let score = -1000; - for (const question of questions) { - - if (mostImportantQuestion === undefined || question.Priority() > score) { - mostImportantQuestion = question; - score = question.Priority(); - } - } - - questionElement = mostImportantQuestion; - } else if (questions.length > 0) { + if (questions.length > 0) { // We select the most important question and render that one let mostImportantQuestion; - let score = -1000; for (const question of questions) { - if (mostImportantQuestion === undefined || question.Priority() > score) { + if (mostImportantQuestion === undefined) { mostImportantQuestion = question; - score = question.Priority(); + break; } } - questionElement = mostImportantQuestion; } else if (skippedQuestions == 1) { questionElement = this._oneSkipped; diff --git a/UI/FullScreenMessageBoxHandler.ts b/UI/FullScreenMessageBoxHandler.ts index 2490e40..08e3220 100644 --- a/UI/FullScreenMessageBoxHandler.ts +++ b/UI/FullScreenMessageBoxHandler.ts @@ -23,11 +23,13 @@ export class FullScreenMessageBox extends UIElement { this._uielement = new Combine([State.state.fullScreenMessage.data]).SetStyle( "display:block;"+ "padding: 1em;"+ - "padding-bottom:5em;"+ + "padding-bottom:6em;"+ `margin-bottom:${FullScreenMessageBox._toTheMap_height};`+ "box-sizing:border-box;"+ `height:calc(100vh - ${FullScreenMessageBox._toTheMap_height});`+ "overflow-y: auto;" + + "max-width:100vw;" + + "overflow-x:hidden;" + "background:white;" ); diff --git a/UI/LayerSelection.ts b/UI/LayerSelection.ts index f9fad8c..d023ed7 100644 --- a/UI/LayerSelection.ts +++ b/UI/LayerSelection.ts @@ -4,6 +4,8 @@ import Combine from "./Base/Combine"; import {Img} from "./Img"; import {State} from "../State"; import Translations from "./i18n/Translations"; +import {FixedUiElement} from "./Base/FixedUiElement"; +import {VariableUiElement} from "./Base/VariableUIElement"; export class LayerSelection extends UIElement { @@ -14,17 +16,34 @@ export class LayerSelection extends UIElement { this._checkboxes = []; for (const layer of State.state.filteredLayers.data) { - const checkbox = Img.checkmark; - let icon = ""; + let iconUrl = "./asets/checkbox.svg"; + let iconUrlBlank = ""; if (layer.layerDef.icon && layer.layerDef.icon !== "") { - icon = `` + iconUrl = layer.layerDef.icon as string; + iconUrlBlank = layer.layerDef.icon as string; } - const name = Translations.WT(layer.layerDef.name).Clone() - .SetStyle("font-size:large;"); + const icon = new FixedUiElement(``); + let iconUnselected: UIElement; + iconUnselected = new FixedUiElement(``); + + const name = Translations.WT(layer.layerDef.name).Clone() + .SetStyle("font-size:large;margin-left: 0.5em;"); + + + const zoomStatus = new VariableUiElement(State.state.locationControl.map(location => { + if (location.zoom < layer.layerDef.minzoom) { + return Translations.t.general.zoomInToSeeThisLayer + .SetClass("alert") + .SetStyle("display: block ruby;width:min-content;") + .Render(); + } + return "" + })) + const style = "display:flex;align-items:center;" this._checkboxes.push(new CheckBox( - new Combine([checkbox, icon, name]), - new Combine([Img.no_checkmark, icon, name]), + new Combine([icon, name, zoomStatus]).SetStyle(style), + new Combine([iconUnselected, "", name, "", zoomStatus]).SetStyle(style), layer.isDisplayed) .SetStyle("margin:0.3em;") ); diff --git a/UI/SearchAndGo.ts b/UI/SearchAndGo.ts index 047ae1e..446b6b6 100644 --- a/UI/SearchAndGo.ts +++ b/UI/SearchAndGo.ts @@ -44,11 +44,15 @@ export class SearchAndGo extends UIElement { // Triggered by 'enter' or onclick private RunSearch() { const searchString = this._searchField.GetValue().data; + if(searchString === undefined || searchString === ""){ + return; + } this._searchField.GetValue().setData(""); this._placeholder.setData(Translations.t.general.search.searching); const self = this; Geocoding.Search(searchString, (result) => { + console.log("Search result", result) if (result.length == 0) { self._placeholder.setData(Translations.t.general.search.nothing); return; diff --git a/UI/SimpleAddUI.ts b/UI/SimpleAddUI.ts index 384680e..90cb2db 100644 --- a/UI/SimpleAddUI.ts +++ b/UI/SimpleAddUI.ts @@ -46,6 +46,9 @@ export class SimpleAddUI extends UIElement { const self = this; for (const layer of State.state.filteredLayers.data) { + + this.ListenTo(layer.isDisplayed); + for (const preset of layer.layerDef.presets) { let icon: string = "./assets/bug.svg"; @@ -130,6 +133,15 @@ export class SimpleAddUI extends UIElement { const userDetails = State.state.osmConnection.userDetails; if (this._confirmPreset.data !== undefined) { + + if(!this._confirmPreset.data.layerToAddTo.isDisplayed.data){ + return new Combine([ + Translations.t.general.add.layerNotEnabled.Subs({layer: this._confirmPreset.data.layerToAddTo.layerDef.name}) + .SetClass("alert"), + + this.cancelButton + ]).Render(); + } let tagInfo = ""; const csCount = State.state.osmConnection.userDetails.data.csCount; @@ -153,21 +165,22 @@ export class SimpleAddUI extends UIElement { let header: UIElement = Translations.t.general.add.header; - - if(userDetails === undefined){ + + if (userDetails === undefined) { return header.Render(); } - + if (!userDetails.data.loggedIn) { return new Combine([header, this._loginButton]).Render() } - if (userDetails.data.unreadMessages > 0) { + if (userDetails.data.unreadMessages > 0 && userDetails.data.csCount < State.userJourney.addNewPointWithUnreadMessagesUnlock) { return new Combine([header, "", Translations.t.general.readYourMessages, "", this.goToInboxButton ]).Render(); + } if (userDetails.data.dryRun) { @@ -178,7 +191,7 @@ export class SimpleAddUI extends UIElement { ]); } - if (userDetails.data.csCount < 5) { + if (userDetails.data.csCount < State.userJourney.addNewPointsUnlock) { return new Combine([header, "", Translations.t.general.fewChangesBefore, ""]).Render(); diff --git a/UI/TagRendering.ts b/UI/TagRendering.ts index 662581d..adf7b12 100644 --- a/UI/TagRendering.ts +++ b/UI/TagRendering.ts @@ -21,7 +21,6 @@ import {FixedUiElement} from "./Base/FixedUiElement"; export class TagRendering extends UIElement implements TagDependantUIElement { - private readonly _priority: number; private readonly _question: string | Translation; private readonly _mapping: { k: TagsFilter, txt: string | UIElement, priority?: number }[]; @@ -58,8 +57,6 @@ export class TagRendering extends UIElement implements TagDependantUIElement { } constructor(tags: UIEventSource, options: { - priority?: number - question?: string | Translation, freeform?: { key: string, @@ -80,8 +77,6 @@ export class TagRendering extends UIElement implements TagDependantUIElement { const self = this; - this._priority = options.priority ?? 0; - this.currentTags = this._source.map(tags => { @@ -525,10 +520,6 @@ export class TagRendering extends UIElement implements TagDependantUIElement { } - Priority(): number { - return this._priority; - } - private ApplyTemplate(template: string | Translation): UIElement { if (template === undefined || template === null) { return undefined; diff --git a/UI/i18n/Translation.ts b/UI/i18n/Translation.ts index 316a3f3..ed15631 100644 --- a/UI/i18n/Translation.ts +++ b/UI/i18n/Translation.ts @@ -1,6 +1,7 @@ import {UIElement} from "../UIElement" import Locale from "./Locale" import Combine from "../Base/Combine"; +import {Utils} from "../../Utils"; export default class Translation extends UIElement { @@ -87,4 +88,16 @@ export default class Translation extends UIElement { } + FirstSentence() { + + const tr = {}; + for (const lng in this.translations) { + let txt = this.translations[lng]; + txt = txt.replace(/\..*/, ""); + txt = Utils.EllipsesAfter(txt, 255); + tr[lng] = txt; + } + + return new Translation(tr); + } } diff --git a/UI/i18n/Translations.ts b/UI/i18n/Translations.ts index 19f5a45..322e3ef 100644 --- a/UI/i18n/Translations.ts +++ b/UI/i18n/Translations.ts @@ -12,380 +12,6 @@ export default class Translations { static t = { - - cyclofix: { - title: new T({ - en: 'Cyclofix - an open map for cyclists', - nl: 'Cyclofix - een open kaart voor fietsers', - fr: 'Cyclofix - Une carte ouverte pour les cyclistes', - gl: 'Cyclofix - Un mapa aberto para os ciclistas', - de: 'Cyclofix - eine offene Karte für Radfahrer' - }), - description: new T({ - en: "The goal of this map is to present cyclists with an easy-to-use solution to find the appropriate infrastructure for their needs.

" + //this works in spoken language: ; think about the nearest bike repair station for example - "You can track your precise location (mobile only) and select layers that are relevant for you in the bottom left corner. " + - "You can also use this tool to add or edit pins (points of interest) to the map and provide more data by answering the questions.

" + - "All changes you make will automatically be saved in the global database of OpenStreetMap and can be freely re-used by others.

" + - "For more information about the cyclofix project, go to cyclofix.osm.be.", - nl: "Het doel van deze kaart is om fietsers een gebruiksvriendelijke oplossing te bieden voor het vinden van de juiste infrastructuur voor hun behoeften.

" + //; denk bijvoorbeeld aan de dichtstbijzijnde fietsherstelplaats. - "U kunt uw exacte locatie volgen (enkel mobiel) en in de linkerbenedenhoek categorieën selecteren die voor u relevant zijn. " + - "U kunt deze tool ook gebruiken om 'spelden' aan de kaart toe te voegen of te bewerken en meer gegevens te verstrekken door de vragen te beantwoorden.

" + - "Alle wijzigingen die u maakt worden automatisch opgeslagen in de wereldwijde database van OpenStreetMap en kunnen door anderen vrij worden hergebruikt.

" + - "Bekijk voor meer info over cyclofix ook cyclofix.osm.be.", - fr: "Le but de cette carte est de présenter aux cyclistes une solution facile à utiliser pour trouver l'infrastructure appropriée à leurs besoins.

" + //; pensez par exemple à la station de réparation de vélos la plus proche. - "Vous pouvez suivre votre localisation précise (mobile uniquement) et sélectionner les couches qui vous concernent dans le coin inférieur gauche. " + - "Vous pouvez également utiliser cet outil pour ajouter ou modifier des épingles (points d'intérêt) sur la carte et fournir plus de données en répondant aux questions.

" + - "Toutes les modifications que vous apportez seront automatiquement enregistrées dans la base de données mondiale d'OpenStreetMap et peuvent être librement réutilisées par d'autres.

" + - "Pour plus d'informations sur le projet cyclofix, rendez-vous sur cyclofix.osm.be.", - gl: "O obxectivo deste mapa é amosar ós ciclistas unha solución doada de empregar para atopar a infraestrutura axeitada para as súas necesidades.

" + //isto funciona na lingua falada: ; pensa na estación de arranxo de bicicletas máis preta, por exemplo. - "Podes obter a túa localización precisa (só para dispositivos móbiles) e escoller as capas que sexan relevantes para ti na esquina inferior esquerda. " + - "Tamén podes empregar esta ferramenta para engadir ou editar puntos de interese ó mapa e fornecer máis datos respondendo as cuestións.

" + - "Todas as modificacións que fagas serán gardadas de xeito automático na base de datos global do OpenStreetMap e outros poderán reutilizalos libremente.

" + - "Para máis información sobre o proxecto cyclofix, vai a cyclofix.osm.be.", - de: "Das Ziel dieser Karte ist es, den Radfahrern eine einfach zu benutzende Lösung zu präsentieren, um die geeignete Infrastruktur für ihre Bedürfnisse zu finden.

" + //dies funktioniert in gesprochener Sprache: ; denken Sie zum Beispiel an die nächste Fahrradreparaturstation - "Sie können Ihren genauen Standort verfolgen (nur mobil) und in der linken unteren Ecke die für Sie relevanten Ebenen auswählen. " + - "Sie können dieses Tool auch verwenden, um Pins (Points of Interest/Interessante Orte) zur Karte hinzuzufügen oder zu bearbeiten und mehr Daten durch Beantwortung der Fragen bereitstellen.

" + - "Alle Änderungen, die Sie vornehmen, werden automatisch in der globalen Datenbank von OpenStreetMap gespeichert und können von anderen frei wiederverwendet werden.

" + - "Weitere Informationen über das Projekt Cyclofix finden Sie unter cyclofix.osm.be." - }), - - station: { - name: new T({ - en: 'bike station (repair, pump or both)', - nl: 'fietspunt (herstel, pomp of allebei)', - fr: 'station velo (réparation, pompe à vélo)', - gl: 'estación de bicicletas (arranxo, bomba de ar ou ambos)', - de: 'Fahrradstation (Reparatur, Pumpe oder beides)' - }), - // title: new T({en: 'Bike station', nl: 'Fietsstation', fr: 'Station vélo', gl: 'Estación de bicicletas'}), Old, non-dynamic title - titlePump: new T({ - - }), - titleRepair: new T({ - en: 'Bike repair station', - nl: 'Herstelpunt', - fr: 'TODO: fr', - gl: 'Estación de arranxo de bicicletas', - de: 'Fahrradwerkstatt' - }), - titlePumpAndRepair: new T({ - en: 'Bike station (pump & repair)', - nl: 'Herstelpunt met pomp', - fr: 'Point station velo avec pompe', - gl: 'Estación de bicicletas (arranxo e bomba de ar)', - de: 'Fahrradstation (Pumpe & Reparatur)' - }), - - valves: { - - default: new T({ - }), - dunlop: new T({}), - sclaverand: new T({ - - }), - - template: new T({ - en: 'Some other valve(s): $$$', - nl: 'Een ander type ventiel(en): $$$', - fr: 'Autre(s) type(s) de valve(s): $$$', - gl: 'Algunha outra válvula: $$$', - de: 'Andere(s) Ventil(e): $$$' - }) - }, - }, - shop: { - name: new T({ - en: "bike repair/shop", - nl: "fietszaak", - fr: "magasin ou réparateur de vélo", - gl: "tenda/arranxo de bicicletas", - de: "fahrradwerkstatt/geschäft" - }), - - title: new T({ - en: "Bike repair/shop", - nl: "Fietszaak", - fr: "Magasin et réparateur de vélo", - gl: "Tenda/arranxo de bicicletas", - de: "Fahrradwerkstatt/geschäft" - }), - titleRepair: new T({ - en: "Bike repair", - nl: "Fietsenmaker", - fr: "Réparateur de vélo", - gl: "Arranxo de bicicletas", - de: "Fahrradwerkstatt" - }), - titleShop: new T({ - en: "Bike shop", - nl: "Fietswinkel", - fr: "Magasin de vélo", - gl: "Tenda de bicicletas", - de: "Fahrradgeschäft" - }), - - titleNamed: new T({ - en: "Bike repair/shop {name}", - nl: "Fietszaak {name}", - fr: "Magasin et réparateur de vélo {name}", - gl: "Tenda/arranxo de bicicletas {name}", - de: "Fahrradwerkstatt/geschäft {name}" - }), - titleRepairNamed: new T({ - en: "Bike repair {name}", - nl: "Fietsenmaker {name}", - fr: "Réparateur de vélo {name}", - gl: "Arranxo de bicicletas {name}", - de: "Fahrradwerkstatt {name}" - }), - titleShopNamed: new T({ - en: "Bike shop {name}", - nl: "Fietswinkel {name}", - fr: "Magasin de vélo {name}", - gl: "Tenda de bicicletas {name}", - de: "Fahrradgeschäft {name}" - }), - - - retail: { - question: new T({ - en: "Does this shop sell bikes?", - nl: "Verkoopt deze winkel fietsen?", - fr: "Est-ce que ce magasin vend des vélos?", - gl: "Esta tenda vende bicicletas?", - de: "Verkauft dieser Laden Fahrräder?" - }), - yes: new T({ - en: "This shop sells bikes", - nl: "Deze winkel verkoopt fietsen", - fr: "Ce magasin vend des vélos", - gl: "Esta tenda vende bicicletas", - de: "Dieses Geschäft verkauft Fahrräder" - }), - no: new T({ - en: "This shop doesn't sell bikes", - nl: "Deze winkel verkoopt geen fietsen", - fr: "Ce magasin ne vend pas de vélo", - gl: "Esta tenda non vende bicicletas", - de: "Dieses Geschäft verkauft keine Fahrräder" - }), - }, - repair: { - question: new T({ - en: "Does this shop repair bikes?", - nl: "Herstelt deze winkel fietsen?", - fr: "Est-ce que ce magasin répare des vélos?", - gl: "Esta tenda arranxa bicicletas?", - de: "Repariert dieses Geschäft Fahrräder?" - }), - yes: new T({ - en: "This shop repairs bikes", - nl: "Deze winkel herstelt fietsen", - fr: "Ce magasin répare des vélos", - gl: "Esta tenda arranxa bicicletas", - de: "Dieses Geschäft repariert Fahrräder", - }), - no: new T({ - en: "This shop doesn't repair bikes", - nl: "Deze winkel herstelt geen fietsen", - fr: "Ce magasin ne répare pas les vélos", - gl: "Esta tenda non arranxa bicicletas", - de: "Dieses Geschäft repariert keine Fahrräder" - }), - sold: new T({ - en: "This shop only repairs bikes bought here", - nl: "Deze winkel herstelt enkel fietsen die hier werden gekocht", - fr: "Ce magasin ne répare seulement les vélos achetés là-bas", - gl: "Esta tenda só arranxa bicicletas mercadas aquí", - de: "Dieses Geschäft repariert nur hier gekaufte Fahrräder" - }), - brand: new T({ - en: "This shop only repairs bikes of a certain brand", - nl: "Deze winkel herstelt enkel fietsen van een bepaald merk", - fr: "Ce magasin ne répare seulement des marques spécifiques", - gl: "Esta tenda só arranxa bicicletas dunha certa marca", - de: "Dieses Geschäft repariert nur Fahrräder einer bestimmten Marke" - }), - }, - rental: { - question: new T({ - en: "Does this shop rent out bikes?", - nl: "Verhuurt deze winkel fietsen?", - fr: "Est-ce ce magasin loue des vélos?", - gl: "Esta tenda aluga bicicletas?", - de: "Vermietet dieser Laden Fahrräder?" - }), - yes: new T({ - en: "This shop rents out bikes", - nl: "Deze winkel verhuurt fietsen", - fr: "Ce magasin loue des vélos", - gl: "Esta tenda aluga bicicletas", - de: "Dieses Geschäft vermietet Fahrräder" - }), - no: new T({ - en: "This shop doesn't rent out bikes", - nl: "Deze winkel verhuurt geen fietsen", - fr: "Ce magasin ne loue pas de vélos", - gl: "Esta tenda non aluga bicicletas", - de: "Dieses Geschäft vermietet keine Fahrräder" - }), - }, - pump: { - question: new T({ - en: "Does this shop offer a bike pump for use by anyone?", - nl: "Biedt deze winkel een fietspomp aan voor iedereen?", - fr: "Est-ce que ce magasin offre une pompe en accès libre?", - gl: "Esta tenda ofrece unha bomba de ar para uso de calquera persoa?", - de: "Bietet dieses Geschäft eine Fahrradpumpe zur Benutzung für alle an?" - }), - yes: new T({ - en: "This shop offers a bike pump for anyone", - nl: "Deze winkel biedt geen fietspomp aan voor eender wie", - fr: "Ce magasin offre une pompe en acces libre", - gl: "Esta tenda ofrece unha bomba de ar para uso de calquera persoa", - de: "Dieses Geschäft bietet eine Fahrradpumpe für alle an" - }), - no: new T({ - en: "This shop doesn't offer a bike pump for anyone", - nl: "Deze winkel biedt een fietspomp aan voor iedereen", - fr: "Ce magasin n'offre pas de pompe en libre accès", - gl: "Esta tenda non ofrece unha bomba de ar para uso de calquera persoa", - de: "Dieses Geschäft bietet für niemanden eine Fahrradpumpe an" - }) - }, - qName: { - question: new T({ - en: "What is the name of this bicycle shop?", - nl: "Wat is de naam van deze fietszaak?", - fr: "Quel est le nom du magasin de vélo?", - gl: "Cal é o nome desta tenda de bicicletas?", - de: "Wie heißt dieser Fahrradladen?" - }), - render: new T({ - en: "This bicycle shop is called {name}", - nl: "Deze fietszaak heet {name}", - fr: "Ce magasin s'appelle {name}", - gl: "Esta tenda de bicicletas chámase {name}", - de: "Dieses Fahrradgeschäft heißt {name}", - }), - template: new T({ - en: "This bicycle shop is called: $$$", - nl: "Deze fietszaak heet: $$$", - fr: "Ce magasin s'appelle $$$", - gl: "Esta tenda de bicicletas chámase: $$$", - de: "Dieses Fahrradgeschäft heißt: $$$" - }) - }, - secondHand: { - question: new T({ - en: "Does this shop sell second-hand bikes?", - nl: "Verkoopt deze winkel tweedehands fietsen?", - fr: "Est-ce ce magasin vend des vélos d'occasion", - gl: "Esta tenda vende bicicletas de segunda man?", - de: "Verkauft dieses Geschäft gebrauchte Fahrräder?" - }), - yes: new T({ - en: "This shop sells second-hand bikes", - nl: "Deze winkel verkoopt tweedehands fietsen", - fr: "Ce magasin vend des vélos d'occasion", - gl: "Esta tenda vende bicicletas de segunda man", - de: "Dieses Geschäft verkauft gebrauchte Fahrräder" - }), - no: new T({ - en: "This shop doesn't sell second-hand bikes", - nl: "Deze winkel verkoopt geen tweedehands fietsen", - fr: "Ce magasin ne vend pas de vélos d'occasion", - gl: "Esta tenda non vende bicicletas de segunda man", - de: "Dieses Geschäft verkauft keine gebrauchten Fahrräder" - }), - only: new T({ - en: "This shop only sells second-hand bikes", - nl: "Deze winkel verkoopt enkel tweedehands fietsen", - fr: "Ce magasin vend seulement des vélos d'occasion", - gl: "Esta tenda só vende bicicletas de segunda man", - de: "Dieses Geschäft verkauft nur gebrauchte Fahrräder" - }), - }, - diy: { - question: new T({ - en: "Are there tools here to repair your own bike?", - nl: "Biedt deze winkel gereedschap aan om je fiets zelf te herstellen?", - fr: "Est-ce qu'il y a des outils pour réparer son vélo dans ce magasin?", - gl: "Hai ferramentas aquí para arranxar a túa propia bicicleta?", - de: "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?" - }), - yes: new T({ - en: "This shop offers tools for DIY repair", - nl: "Deze winkel biedt gereedschap aan om je fiets zelf te herstellen", - fr: "Ce magasin offre des outils pour réparer son vélo soi-même", - gl: "Hai ferramentas aquí para arranxar a túa propia bicicleta", - de: "Dieses Geschäft bietet Werkzeuge für die Heimwerkerreparatur an" - }), - no: new T({ - en: "This shop doesn't offer tools for DIY repair", - nl: "Deze winkel biedt geen gereedschap aan om je fiets zelf te herstellen", - fr: "Ce magasin n'offre pas des outils pour réparer son vélo soi-même", - gl: "Non hai ferramentas aquí para arranxar a túa propia bicicleta", - de: "Dieses Geschäft bietet keine Werkzeuge für Heimwerkerreparaturen an" - }), - } - }, - nonBikeShop: { - name: new T({ - en: "shop that sells/repairs bikes", - nl: "winkel die fietsen verkoopt/herstelt", - fr: "magasin qui repare/vend des vélos", - gl: "tenda que vende/arranxa bicicletas", - de: "geschäft, das Fahrräder verkauft/repariert" - }), - - title: new T({ - en: "Shop that sells/repairs bikes", - nl: "Winkel die fietsen verkoopt/herstelt", - fr: "Magasin qui répare/vend des vélos", - gl: "Tenda que vende/arranxa bicicletas", - de: "Geschäft, das Fahrräder verkauft/repariert" - }), - titleRepair: new T({ - en: "Shop that repairs bikes", - nl: "Winkel die fietsen herstelt", - fr: "Magasin qui répare les vélos", - gl: "Tenda que arranxa bicicletas", - de: "Geschäft, das Fahrräder repariert" - }), - titleShop: new T({ - en: "Shop that sells bikes", - nl: "Winkel die fietsen verkoopt", - fr: "Magasin qui vend des vélos", - gl: "Tenda que vende bicicletas", - de: "Geschäft, das Fahrräder verkauft" - }), - - titleNamed: new T({ - en: "{name} (sells/repairs bikes)", - nl: "{name} (verkoopt/herstelt fietsen)", - fr: "vend/repare les vélos", - gl: "{name} (vende/arranxa bicicletas)", - de: "{name} (verkauft/repariert Fahrräder)" - }), - titleRepairNamed: new T({ - en: "{name} (repairs bikes)", - nl: "{name} (herstelt fietsen)", - fr: "{name} (répare les vélos)", - gl: "{name} (arranxa bicicletas)", - de: "{name} (repariert Fahrräder)" - }), - titleShopNamed: new T({ - en: "{name} (sells bikes)", - nl: "{name} (verkoopt fietsen)", - fr: "{name} (vend des vélos)", - gl: "{name} (vende bicicletas)", - de: "{name} (verkauft Fahrräder)" - }), - } - }, - image: { addPicture: new T({ en: 'Add picture', @@ -753,6 +379,10 @@ export default class Translations { fr: "Ajouter un/une {category} ici", gl: "Engadir {category} aquí", de: "Hier eine {category} hinzufügen" + }), + layerNotEnabled: new T({ + "en":"The layer {layer} is not enabled. Enable this layer to add a point", + "nl":"De laag {layer} is gedeactiveerd. Activeer deze om een punt toe te voegn" }) }, pickLanguage: new T({ @@ -851,7 +481,7 @@ export default class Translations { }, openStreetMapIntro: new T({ en: "

An Open Map

" + - "

Wouldn't it be cool if there was a single map, which everyone could freely use and edit?" + + "

Wouldn't it be cool if there was a single map, which everyone could freely use and edit? " + "A single place to store all geo-information? Then, all those websites with different, small and incompatible maps (which are always outdated) wouldn't be needed anymore.

" + "

OpenStreetMap is this map. The map data can be used for free (with attribution and publication of changes to that data)." + " On top of that, everyone can freely add new data and fix errors. This website uses OpenStreetMap as well. All the data is from there, and your answers and corrections are added there as well.

" + @@ -872,7 +502,7 @@ export default class Translations { "

Moltes persones i aplicacions ja utilitzen OpenStreetMap: Maps.me, OsmAnd, però també els mapes de Facebook, Instagram, Apple i Bing són (en part) impulsats ​​per OpenStreetMap." + "Si canvies alguna cosa aquí també es reflectirà en aquestes aplicacions en la seva propera actualització.

", nl: "

Een open kaart

" + - "

Zou het niet fantastisch zijn als er een open kaart zou zijn die door iedereen aangepast én gebruikt kan worden? Een kaart iedereen zijn interesses aan zou kunnen toevoegen? " + + "

Zou het niet fantastisch zijn als er een open kaart zou zijn die door iedereen aangepast én gebruikt kan worden? Een kaart waar iedereen zijn interesses aan zou kunnen toevoegen? " + "Dan zouden er geen duizend-en-één verschillende kleine kaartjes, websites, ... meer nodig zijn

" + "

OpenStreetMap is deze open kaart. Je mag de kaartdata gratis gebruiken (mits bronvermelding en herpublicatie van aanpassingen). Daarenboven mag je de kaart ook gratis aanpassen als je een account maakt. " + "Ook deze website is gebaseerd op OpenStreetMap. Als je hier een vraag beantwoord, gaat het antwoord daar ook naartoe

" + @@ -1165,6 +795,10 @@ export default class Translations { "en": "Background map", "nl": "Achtergrondkaart", "de": "Hintergrundkarte" + }), + zoomInToSeeThisLayer: new T({ + "nl":"Vergroot de kaart om deze laag te zien", + "en":"Zoom in to see this layer" }) }, favourite: { diff --git a/assets/bike/other_services.svg b/assets/bike/other_services.svg deleted file mode 100644 index 2cec6d1..0000000 --- a/assets/bike/other_services.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/assets/layers/bike_cafe/bike_cafes.json b/assets/layers/bike_cafe/bike_cafes.json index 5379ef9..ba76df4 100644 --- a/assets/layers/bike_cafe/bike_cafes.json +++ b/assets/layers/bike_cafe/bike_cafes.json @@ -191,7 +191,11 @@ "gl": "Cal é o enderezo de correo electrónico de {name}?", "de": "Wie lautet die E-Mail-Adresse von {name}?" }, - "render": "{email}" + "render": "{email}", + "freeform": { + "key": "email", + "type": "email" + } } ], "hideUnderlayingFeaturesMinPercentage": 0, diff --git a/assets/layers/bike_shop/bike_shop.json b/assets/layers/bike_shop/bike_shop.json new file mode 100644 index 0000000..e7f752f --- /dev/null +++ b/assets/layers/bike_shop/bike_shop.json @@ -0,0 +1,468 @@ +{ + "id": "bike_shops", + "name": { + "en": "Bike repair/shop", + "nl": "Fietszaak", + "fr": "Magasin ou réparateur de vélo", + "gl": "Tenda/arranxo de bicicletas", + "de": "Fahrradwerkstatt/geschäft" + }, + "minzoom": 13, + "overpassTags": { + "#": "We select all bicycle shops, sport shops (but we try to weed out non-bicycle related shops), and any shop with a bicycle related tag", + "or": [ + "shop=bicycle", + { + "#": "if sport is defined and is not bicycle, it is retrackted; if bicycle retail/repair is marked as 'no', it is retracted too.", + "##": "There will be a few false-positives with this. They will get filtered out by people marking both 'not selling bikes' and 'not repairing bikes'. Furthermore, the OSMers will add a sports-subcategory on it", + "and": [ + "shop=sports", + "service:bicycle:retail!=no", + "service:bicycle:repair!=no", + { + "or": [ + "sport=bicycle", + "sport=cycling", + "sport=" + ] + } + ] + }, + { + "#": "Any shop with any bicycle service", + "and": [ + "shop~*", + "service:bicycle:.*~~.*" + ] + } + ] + }, + "title": { + "render": { + "en": "Bike repair/shop", + "nl": "Fietszaak", + "fr": "Magasin ou réparateur de vélo", + "gl": "Tenda/arranxo de bicicletas", + "de": "Fahrradwerkstatt/geschäft" + }, + "mappings": [ + { + "if": { + "and": [ + "shop=sports", + "name~*" + ] + }, + "then": { + "en": "Sport gear shop {name}", + "nl": "Sportwinkel {name}", + "fr": "Magasin de sport {name}" + } + }, + { + "if": "shop=sports", + "then": { + "en": "Sport gear shop", + "nl": "Sportwinkel", + "fr": "Magasin de sport" + } + }, + { + "if": "shop!~bicycle", + "then": "Other shop" + }, + { + "if": { + "and": [ + "name~*", + "service:bicycle:retail!~yes", + "service:bicycle:repair!~no" + ] + }, + "then": { + "en": "Bike repair {name}", + "nl": "Fietsenmaker {name}", + "fr": "Réparateur de vélo {name}", + "gl": "Arranxo de bicicletas {name}", + "de": "Fahrradwerkstatt {name}" + } + }, + { + "if": { + "and": [ + "service:bicycle:retail!~yes", + "service:bicycle:repair!~no" + ] + }, + "then": { + "en": "Bike repair", + "nl": "Fietsenmaker", + "fr": "Réparateur de vélo", + "gl": "Arranxo de bicicletas", + "de": "Fahrradwerkstatt" + } + }, + { + "if": { + "and": [ + "name~*", + "service:bicycle:repair!~yes" + ] + }, + "then": { + "en": "Bike shop {name}", + "nl": "Fietswinkel {name}", + "fr": "Magasin de vélo {name}", + "gl": "Tenda de bicicletas {name}", + "de": "Fahrradgeschäft {name}" + } + }, + { + "if": "service:bicycle:repair!~yes", + "then": { + "en": "Bike shop", + "nl": "Fietswinkel", + "fr": "Magasin de vélo", + "gl": "Tenda de bicicletas", + "de": "Fahrradgeschäft" + } + }, + { + "if": "name~*", + "then": { + "en": "Bike repair/shop {name}", + "nl": "Fietszaak {name}", + "fr": "Magasin ou réparateur de vélo {name}", + "gl": "Tenda/arranxo de bicicletas {name}", + "de": "Fahrradwerkstatt/geschäft {name}" + } + } + ] + }, + "description": { + "en": "A shop specifically selling bicycles or related items", + "nl": "Een winkel die hoofdzakelijk fietsen en fietstoebehoren verkoopt" + }, + "tagRenderings": [ + "images", + { + "condition": { + "and": [ + "shop!~bicycle", + "shop!~sports" + ] + }, + "render": { + "en": "This shop is specialized in selling {shop} and does bicycle related activities", + "nl": "Deze winkel verkoopt {shop} en heeft fiets-gerelateerde activiteiten." + } + }, + { + "question": { + "en": "What is the name of this bicycle shop?", + "nl": "Wat is de naam van deze fietszaak?", + "fr": "Quel est le nom du magasin de vélo?", + "gl": "Cal é o nome desta tenda de bicicletas?", + "de": "Wie heißt dieser Fahrradladen?" + }, + "render": { + "en": "This bicycle shop is called {name}", + "nl": "Deze fietszaak heet {name}", + "fr": "Ce magasin s'appelle {name}", + "gl": "Esta tenda de bicicletas chámase {name}", + "de": "Dieses Fahrradgeschäft heißt {name}" + }, + "freeform": { + "key": "name" + } + }, + { + "question": { + "en": "What is the website of {name}?", + "nl": "Wat is de website van {name}?", + "fr": "Quel est le site internet de {name}?", + "gl": "Cal é a páxina web de {name}?" + }, + "render": "{website}", + "freeform": { + "key": "website" + } + }, + { + "question": { + "en": "What is the phone number of {name}?", + "nl": "Wat is het telefoonnummer van {name}?", + "fr": "Quel est le nom de {name}?", + "gl": "Cal é o número de teléfono de {name}?" + }, + "render": "{phone}", + "freeform": { + "key": "phone", + "type": "phone" + } + }, + { + "question": { + "en": "What is the email address of {name}?", + "nl": "Wat is het email-adres van {name}?", + "fr": "Quel est l'adresse email de {name}?", + "gl": "Cal é o enderezo de correo electrónico de {name}?" + }, + "render": "{email}", + "freeform": { + "key": "email", + "type": "email" + } + }, + { + "question": { + "en": "Does this shop sell bikes?", + "nl": "Verkoopt deze fietszaak fietsen?", + "fr": "Est-ce que ce magasin vend des vélos?", + "gl": "Esta tenda vende bicicletas?", + "de": "Verkauft dieser Laden Fahrräder?" + }, + "mappings": [ + { + "if": "service:bicycle:retail=yes", + "then": { + "en": "This shop sells bikes", + "nl": "Deze winkel verkoopt fietsen", + "fr": "Ce magasin vend des vélos", + "gl": "Esta tenda vende bicicletas", + "de": "Dieses Geschäft verkauft Fahrräder" + } + }, + { + "if": "service:bicycle:retail=no", + "then": { + "en": "This shop doesn't sell bikes", + "nl": "Deze winkel verkoopt geen fietsen", + "fr": "Ce magasin ne vend pas de vélo", + "gl": "Esta tenda non vende bicicletas", + "de": "Dieses Geschäft verkauft keine Fahrräder" + } + } + ] + }, + { + "question": { + "en": "Does this shop repair bikes?", + "nl": "Herstelt deze winkel fietsen?", + "fr": "Est-ce que ce magasin répare des vélos?", + "gl": "Esta tenda arranxa bicicletas?", + "de": "Repariert dieses Geschäft Fahrräder?" + }, + "mappings": [ + { + "if": "service:bicycle:repair=yes", + "then": { + "en": "This shop repairs bikes", + "nl": "Deze winkel herstelt fietsen", + "fr": "Ce magasin répare des vélos", + "gl": "Esta tenda arranxa bicicletas", + "de": "Dieses Geschäft repariert Fahrräder" + } + }, + { + "if": "service:bicycle:repair=no", + "then": { + "en": "This shop doesn't repair bikes", + "nl": "Deze winkel herstelt geen fietsen", + "fr": "Ce magasin ne répare pas les vélos", + "gl": "Esta tenda non arranxa bicicletas", + "de": "Dieses Geschäft repariert keine Fahrräder" + } + }, + { + "if": "service:bicycle:repair=only_sold", + "then": { + "en": "This shop only repairs bikes bought here", + "nl": "Deze winkel herstelt enkel fietsen die hier werden gekocht", + "fr": "Ce magasin ne répare seulement les vélos achetés là-bas", + "gl": "Esta tenda só arranxa bicicletas mercadas aquí", + "de": "Dieses Geschäft repariert nur hier gekaufte Fahrräder" + } + }, + { + "if": "service:bicycle:repair=brand", + "then": { + "en": "This shop only repairs bikes of a certain brand", + "nl": "Deze winkel herstelt enkel fietsen van een bepaald merk", + "fr": "Ce magasin ne répare seulement des marques spécifiques", + "gl": "Esta tenda só arranxa bicicletas dunha certa marca", + "de": "Dieses Geschäft repariert nur Fahrräder einer bestimmten Marke" + } + } + ] + }, + { + "question": { + "en": "Does this shop rent out bikes?", + "nl": "Verhuurt deze winkel fietsen?", + "fr": "Est-ce ce magasin loue des vélos?", + "gl": "Esta tenda aluga bicicletas?", + "de": "Vermietet dieser Laden Fahrräder?" + }, + "mappings": [ + { + "if": "service:bicycle:rental=yes", + "then": { + "en": "This shop rents out bikes", + "nl": "Deze winkel verhuurt fietsen", + "fr": "Ce magasin loue des vélos", + "gl": "Esta tenda aluga bicicletas", + "de": "Dieses Geschäft vermietet Fahrräder" + } + }, + { + "if": "service:bicycle:rental=no", + "then": { + "en": "This shop doesn't rent out bikes", + "nl": "Deze winkel verhuurt geen fietsen", + "fr": "Ce magasin ne loue pas de vélos", + "gl": "Esta tenda non aluga bicicletas", + "de": "Dieses Geschäft vermietet keine Fahrräder" + } + } + ] + }, + { + "question": { + "en": "Does this shop sell second-hand bikes?", + "nl": "Verkoopt deze winkel tweedehands fietsen?", + "fr": "Est-ce ce magasin vend des vélos d'occasion", + "gl": "Esta tenda vende bicicletas de segunda man?", + "de": "Verkauft dieses Geschäft gebrauchte Fahrräder?" + }, + "mappings": [ + { + "if": "service:bicycle:second_hand=yes", + "then": { + "en": "This shop sells second-hand bikes", + "nl": "Deze winkel verkoopt tweedehands fietsen", + "fr": "Ce magasin vend des vélos d'occasion", + "gl": "Esta tenda vende bicicletas de segunda man", + "de": "Dieses Geschäft verkauft gebrauchte Fahrräder" + } + }, + { + "if": "service:bicycle:second_hand=no", + "then": { + "en": "This shop doesn't sell second-hand bikes", + "nl": "Deze winkel verkoopt geen tweedehands fietsen", + "fr": "Ce magasin ne vend pas de vélos d'occasion", + "gl": "Esta tenda non vende bicicletas de segunda man", + "de": "Dieses Geschäft verkauft keine gebrauchten Fahrräder" + } + }, + { + "if": "service:bicycle:second_hand=only", + "then": { + "en": "This shop only sells second-hand bikes", + "nl": "Deze winkel verkoopt enkel tweedehands fietsen", + "fr": "Ce magasin vend seulement des vélos d'occasion", + "gl": "Esta tenda só vende bicicletas de segunda man", + "de": "Dieses Geschäft verkauft nur gebrauchte Fahrräder" + } + } + ] + }, + { + "question": { + "en": "Does this shop offer a bike pump for use by anyone?", + "nl": "Biedt deze winkel een fietspomp aan voor iedereen?", + "fr": "Est-ce que ce magasin offre une pompe en accès libre?", + "gl": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa?", + "de": "Bietet dieses Geschäft eine Fahrradpumpe zur Benutzung für alle an?" + }, + "mappings": [ + { + "if": "service:bicycle:pump=yes", + "then": { + "en": "This shop offers a bike pump for anyone", + "nl": "Deze winkel biedt een fietspomp aan voor iedereen", + "fr": "Ce magasin offre une pompe en acces libre", + "gl": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa", + "de": "Dieses Geschäft bietet eine Fahrradpumpe für alle an" + } + }, + { + "if": "service:bicycle:pump=no", + "then": { + "en": "This shop doesn't offer a bike pump for anyone", + "nl": "Deze winkel biedt geen fietspomp aan voor eender wie", + "fr": "Ce magasin n'offre pas de pompe en libre accès", + "gl": "Esta tenda non ofrece unha bomba de ar para uso de calquera persoa", + "de": "Dieses Geschäft bietet für niemanden eine Fahrradpumpe an" + } + } + ] + }, + { + "question": { + "en": "Are there tools here to repair your own bike?", + "nl": "Biedt deze winkel gereedschap aan om je fiets zelf te herstellen?", + "fr": "Est-ce qu'il y a des outils pour réparer son vélo dans ce magasin?", + "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta?", + "de": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?" + }, + "mappings": [ + { + "if": "service:bicycle:diy=yes", + "then": { + "en": "This shop offers tools for DIY repair", + "nl": "Deze winkel biedt gereedschap aan om je fiets zelf te herstellen", + "fr": "Ce magasin offre des outils pour réparer son vélo soi-même", + "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta", + "de": "Dieses Geschäft bietet Werkzeuge für die Heimwerkerreparatur an" + } + }, + { + "if": "service:bicycle:diy=no", + "then": { + "en": "This shop doesn't offer tools for DIY repair", + "nl": "Deze winkel biedt geen gereedschap aan om je fiets zelf te herstellen", + "fr": "Ce magasin n'offre pas des outils pour réparer son vélo soi-même", + "gl": "Non hai ferramentas aquí para arranxar a túa propia bicicleta", + "de": "Dieses Geschäft bietet keine Werkzeuge für Heimwerkerreparaturen an" + } + } + ] + } + ], + "hideUnderlayingFeaturesMinPercentage": 1, + "presets": [ + { + "title": { + "en": "Bike repair/shop", + "nl": "Fietszaak", + "fr": "Magasin et réparateur de vélo", + "gl": "Tenda/arranxo de bicicletas", + "de": "Fahrradwerkstatt/geschäft" + }, + "tags": [ + "shop=bicycle" + ] + } + ], + "icon": { + "render": "./assets/layers/bike_shop/repair_shop.svg", + "mappings": [ + { + "if": "service:bicycle:retail=yes", + "then": "./assets/layers/bike_shop/shop.svg" + } + ] + }, + "width": { + "render": "1" + }, + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#c00" + }, + "wayHandling": 2 +} \ No newline at end of file diff --git a/assets/bike/repair_shop.svg b/assets/layers/bike_shop/repair_shop.svg similarity index 100% rename from assets/bike/repair_shop.svg rename to assets/layers/bike_shop/repair_shop.svg diff --git a/assets/bike/shop.svg b/assets/layers/bike_shop/shop.svg similarity index 100% rename from assets/bike/shop.svg rename to assets/layers/bike_shop/shop.svg diff --git a/assets/layers/cycling_themed_object/cycling_themed_objects.json b/assets/layers/cycling_themed_object/cycling_themed_objects.json index de501cc..5acca30 100644 --- a/assets/layers/cycling_themed_object/cycling_themed_objects.json +++ b/assets/layers/cycling_themed_object/cycling_themed_objects.json @@ -6,7 +6,7 @@ "fr": "Objet cycliste", "de": "Mit Fahrrad zusammenhängendes Objekt" }, - "minzoom": 14, + "minzoom": 13, "overpassTags": "theme~cycling|bicycle", "title": { "render": { diff --git a/assets/statistics.svg b/assets/statistics.svg new file mode 100644 index 0000000..4988617 --- /dev/null +++ b/assets/statistics.svg @@ -0,0 +1,7 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + \ No newline at end of file diff --git a/assets/themes/buurtnatuur/ANB.jpg b/assets/themes/buurtnatuur/ANB.jpg new file mode 100644 index 0000000..9ac4776 Binary files /dev/null and b/assets/themes/buurtnatuur/ANB.jpg differ diff --git a/assets/themes/buurtnatuur/Natuurpunt.jpg b/assets/themes/buurtnatuur/Natuurpunt.jpg new file mode 100644 index 0000000..f91c493 Binary files /dev/null and b/assets/themes/buurtnatuur/Natuurpunt.jpg differ diff --git a/assets/themes/buurtnatuur/buurtnatuur.json b/assets/themes/buurtnatuur/buurtnatuur.json new file mode 100644 index 0000000..0bb4981 --- /dev/null +++ b/assets/themes/buurtnatuur/buurtnatuur.json @@ -0,0 +1,557 @@ +{ + "id": "buurtnatuur", + "title": { + "nl": "Breng jouw buurtnatuur in kaart" + }, + "shortDescription": { + "nl": "Met deze tool kan je natuur in je buurt in kaart brengen en meer informatie geven over je favoriete plekje" + }, + "description": { + "nl": "
Natuur maakt gelukkig. 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
  • In welke natuurgebieden kan jij terecht? Hoe toegankelijk zijn ze?
  • In welke bossen kan een gezin in jouw gemeente opnieuw op adem komen?
  • Op welke onbekende plekjes is het zalig spelen?

Samen kleuren we heel Vlaanderen en Brussel groen.

Blijf op de hoogte van de resultaten van buurtnatuur.be: meld je aan voor e-mailupdates."}, +"descriptionTail":{"nl":"

Tips

  • Over groen ingekleurde gebieden weten we alles wat we willen weten.
  • Bij rood ingekleurde gebieden ontbreekt nog heel wat info: klik een gebied aan en beantwoord de vragen.
  • Je kan altijd een vraag overslaan als je het antwoord niet weet of niet zeker bent
  • Je kan altijd een foto toevoegen
  • Je kan ook zelf een gebied toevoegen door op de kaart te klikken
  • Open buurtnatuur.be op je smartphone om al wandelend foto's te maken en vragen te beantwoorden

De oorspronkelijke data komt van OpenStreetMap en je antwoorden worden daar bewaard.
Omdat iedereen vrij kan meewerken aan dit project, kunnen we niet garanderen dat er geen fouten opduiken.Kan je hier niet aanpassen wat je wilt, dan kan je dat zelf via OpenStreetMap.org doen. Groen kan geen enkele verantwoordelijkheid nemen over de kaart.

Je privacy is belangrijk. We tellen wel hoeveel gebruikers deze website bezoeken. We plaatsen een cookie waar geen persoonlijke informatie in bewaard wordt. Als je inlogt, komt er een tweede cookie bij met je inloggegevens.
" + }, + "language": [ + "nl" + ], + "maintainer": "", + "icon": "./assets/themes/buurtnatuur/groen_logo.svg", + "version": "0", + "startLat": 50.8435, + "startLon": 4.3688, + "startZoom": 16, + "widenFactor": 0.05, + "socialImage": "./assets/themes/buurtnatuur/social_image.jpg", + "layers": [ + { + "id": "nature_reserve", + "name": { + "nl": "Natuurgebied" + }, + "minzoom": 12, + "overpassTags": { + "or": [ + "leisure=nature_reserve", + "boundary=protected_area" + ] + }, + "title": { + "render": { + "nl": "Natuurgebied" + }, + "mappings": [ + { + "if": { + "and": [ + "name:nl~" + ] + }, + "then": { + "nl": "{name:nl}" + } + }, + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "{name}" + } + } + ] + }, + "description": { + "nl": "Een natuurgebied is een gebied waar actief ruimte gemaakt word voor de natuur. Typisch zijn deze in beheer van Natuurpunt of het Agentschap Natuur en Bos of zijn deze erkend door de overheid." + }, + "tagRenderings": [], + "hideUnderlayingFeaturesMinPercentage": 10, + "icon": { + "render": "./assets/themes/buurtnatuur/nature_reserve.svg", + "mappings": [ + { + "#": "This is a little bit a hack to force a circle to be shown while keeping the icon in the 'new' menu", + "if": "id~node/[0-9]*", + "then": "$circle" + } + ] + }, + "width": { + "render": "5" + }, + "iconSize": { + "render": "50,50,center" + }, + "color": { + "render": "#3c3", + "mappings": [ + { + "if": { + "and": [ + "name=", + "noname=", + "operator=", + "access=", + "access:description=", + "leisure=park" + ] + }, + "then": "#cc1100" + }, + { + "if": { + "and": [ + "name=", + "noname=" + ] + }, + "then": "#fccb37" + } + ] + }, + "presets": [ + { + "tags": [ + "leisure=nature_reserve", + "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" + ], + "title": { + "nl": "Natuurreservaat" + }, + "description": { + "nl": "Voeg een ontbrekend, erkend natuurreservaat toe, bv. een gebied dat beheerd wordt door het ANB of natuurpunt" + } + } + ] + }, + { + "id": "parks", + "name": { + "nl": "Park" + }, + "minzoom": 12, + "overpassTags": { + "or": [ + "leisure=park", + "landuse=village_green" + ] + }, + "title": { + "render": { + "nl": "Park" + }, + "mappings": [ + { + "if": { + "and": [ + "name:nl~" + ] + }, + "then": { + "nl": "{name:nl}" + } + }, + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "{name}" + } + } + ] + }, + "description": { + "nl": "Een park is een publiek toegankelijke, groene ruimte binnen de stad. Ze is typisch ingericht voor recreatief gebruik, met (verharde) wandelpaden, zitbanken, vuilnisbakken, een gezellig vijvertje, ..." + }, + "tagRenderings": [], + "hideUnderlayingFeaturesMinPercentage": 10, + "icon": { + "render": "./assets/themes/buurtnatuur/park.svg", + "mappings": [ + { + "#": "This is a little bit a hack to force a circle to be shown while keeping the icon in the 'new' menu", + "if": "id~node/[0-9]*", + "then": "$circle" + } + ] + }, + "width": { + "render": "5" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#3c3", + "mappings": [ + { + "if": { + "and": [ + "name=", + "noname=" + ] + }, + "then": "#fccb37" + } + ] + }, + "presets": [ + { + "tags": [ + "leisure=park", + "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" + ], + "title": { + "nl": "Park" + }, + "description": { + "nl": "Voeg een ontbrekend park toe" + } + } + ] + }, + { + "id": "forest", + "name": { + "nl": "Bos" + }, + "minzoom": 12, + "overpassTags": { + "or": [ + "landuse=forest", + "natural=wood", + "natural=scrub" + ] + }, + "title": { + "render": { + "nl": "Bos" + }, + "mappings": [ + { + "if": { + "and": [ + "name:nl~" + ] + }, + "then": { + "nl": "{name:nl}" + } + }, + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "{name}" + } + } + ] + }, + "description": { + "nl": "Een bos is een verzameling bomen, al dan niet als productiehout." + }, + "tagRenderings": [], + "hideUnderlayingFeaturesMinPercentage": 0, + "icon": { + "render": "./assets/themes/buurtnatuur/forest.svg", + "mappings": [ + { + "#": "This is a little bit a hack to force a circle to be shown while keeping the icon in the 'new' menu", + "if": "id~node/[0-9]*", + "then": "$circle" + } + ] + }, + "width": { + "render": "5" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#3a3", + "mappings": [ + { + "if": { + "and": [ + "operator=", + "access=", + "access:description=" + ] + }, + "then": "#cc1100" + }, + { + "if": { + "and": [ + "operator=" + ] + }, + "then": "#cccc00" + }, + { + "if": { + "and": [ + "name=", + "noname=" + ] + }, + "then": "#fccb37" + } + ] + }, + "presets": [ + { + "tags": [ + "landuse=forest", + "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" + ], + "title": { + "nl": "Bos" + }, + "description": { + "nl": "Voeg een ontbrekend bos toe aan de kaart" + } + } + ] + }, + "viewpoint" + ], + "roamingRenderings": [ + { + "#": "Access tag", + "condition": { + "and": [ + "tourism!~viewpoint" + ] + }, + "render": { + "nl": "De toegankelijkheid van dit gebied is: {access:description}" + }, + "question": { + "nl": "Is dit gebied toegankelijk?" + }, + "freeform": { + "key": "access:description" + }, + "mappings": [ + { + "if": { + "and": [ + "access:description=", + "access=", + "leisure=park" + ] + }, + "then": { + "nl": "Dit gebied is vrij toegankelijk" + }, + "hideInAnswer": true + }, + { + "if": { + "and": [ + "access=yes", + "fee=" + ] + }, + "then": { + "nl": "Vrij toegankelijk" + } + }, + { + "if": { + "and": [ + "access=no", + "fee=" + ] + }, + "then": { + "nl": "Niet toegankelijk" + } + }, + { + "if": { + "and": [ + "access=private", + "fee=" + ] + }, + "then": { + "nl": "Niet toegankelijk, want privégebied" + } + }, + { + "if": { + "and": [ + "access=permissive", + "fee=" + ] + }, + "then": { + "nl": "Toegankelijk, ondanks dat het privegebied is" + } + }, + { + "if": { + "and": [ + "access=guided", + "fee=" + ] + }, + "then": { + "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" + } + }, + { + "if": { + "and": [ + "access=yes", + "fee=yes" + ] + }, + "then": { + "nl": "Toegankelijk mits betaling" + } + } + ] + }, + { + "#": "Operator tag", + "render": { + "nl": "Beheer door {operator}" + }, + "question": { + "nl": "Wie beheert dit gebied?" + }, + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": { + "and": [ + "leisure=park", + "operator=" + ] + }, + "then": "Beheer door de gemeente" + }, + { + "if": { + "and": [ + "operator=Natuurpunt" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door Natuurpunt" + } + }, + { + "if": { + "and": [ + "operator~(n|N)atuurpunt.*" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door {operator}" + }, + "hideInAnswer": true + }, + { + "if": { + "and": [ + "operator=Agentschap Natuur en Bos" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" + } + } + ], + "condition": { + "and": [ + "leisure!~park", + "tourism!~viewpoint" + ] + } + }, + { + "#": "Name:nl-tag", + "render": { + "nl": "Dit gebied heet {name:nl}" + }, + "question": { + "nl": "Wat is de Nederlandstalige naam van dit gebied?" + }, + "freeform": { + "key": "name:nl" + }, + "condition": { + "and": [ + "name:nl~*", + "viewpoint!~tourism" + ] + } + }, + { + "#": "Name tag", + "render": { + "nl": "Dit gebied heet {name}" + }, + "question": { + "nl": "Wat is de naam van dit gebied?" + }, + "freeform": { + "key": "name", + "addExtraTags": [ + "noname=" + ] + }, + "condition": { + "and": [ + "name:nl=", + "tourism!~viewpoint" + ] + }, + "mappings": [ + { + "if": { + "and": [ + "noname=yes", + "name=" + ] + }, + "then": { + "nl": "Dit gebied heeft geen naam" + } + } + ] + }, + { + "#": "Non-editable description {description}", + "render": { + "nl": "Extra info: {description}" + }, + "freeform": { + "key": "description" + } + }, + { + "#": "Editable description {description:0}", + "question": "Is er extra info die je kwijt wil?", + "render": { + "nl": "Extra info via buurtnatuur.be: {description:0}" + }, + "freeform": { + "key": "description:0" + } + } + ] +} \ No newline at end of file diff --git a/assets/themes/buurtnatuur/forest.svg b/assets/themes/buurtnatuur/forest.svg new file mode 100644 index 0000000..bc7d6e9 --- /dev/null +++ b/assets/themes/buurtnatuur/forest.svg @@ -0,0 +1,7 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + \ No newline at end of file diff --git a/assets/themes/buurtnatuur/nature_reserve.svg b/assets/themes/buurtnatuur/nature_reserve.svg new file mode 100644 index 0000000..298bdf6 --- /dev/null +++ b/assets/themes/buurtnatuur/nature_reserve.svg @@ -0,0 +1,7 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + \ No newline at end of file diff --git a/assets/themes/buurtnatuur/park.svg b/assets/themes/buurtnatuur/park.svg new file mode 100644 index 0000000..c097ff7 --- /dev/null +++ b/assets/themes/buurtnatuur/park.svg @@ -0,0 +1,7 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + \ No newline at end of file diff --git a/assets/themes/cyclestreets/cyclestreets.json b/assets/themes/cyclestreets/cyclestreets.json index 7240bc4..ad996fb 100644 --- a/assets/themes/cyclestreets/cyclestreets.json +++ b/assets/themes/cyclestreets/cyclestreets.json @@ -2,6 +2,7 @@ "id": "fietsstraten", "version": "2020-08-30", "title": "Fietsstraten", + "shortDescription": "Een kaart met alle gekende fietsstraten", "description": "Een fietsstraat is een straat waar
  • automobilisten geen fietsers mogen inhalen
  • Er een maximumsnelheid van 30km/u geldt
  • Fietsers gemotoriseerde voortuigen links mogen inhalen
  • Fietsers nog steeds voorrang aan rechts moeten verlenen - ook aan auto's en voetgangers op het zebrapad


Op deze open kaart kan je alle gekende fietsstraten zien en kan je ontbrekende fietsstraten aanduiden. Om de kaart aan te passen, moet je je aanmelden met OpenStreetMap en helemaal inzoomen tot straatniveau.", "icon": "./assets/themes/cyclestreets/F111.svg", diff --git a/assets/bike/cyclofix.jpeg b/assets/themes/cyclofix/SocialImage.jpeg similarity index 100% rename from assets/bike/cyclofix.jpeg rename to assets/themes/cyclofix/SocialImage.jpeg diff --git a/assets/themes/cyclofix/cyclofix.json b/assets/themes/cyclofix/cyclofix.json new file mode 100644 index 0000000..b0b018c --- /dev/null +++ b/assets/themes/cyclofix/cyclofix.json @@ -0,0 +1,30 @@ +{ + "id": "cyclofix", + "title": { + "en": "Cyclofix - an open map for cyclists", + "nl": "Cyclofix - een open kaart voor fietsers", + "fr": "Cyclofix - Une carte ouverte pour les cyclistes", + "gl": "Cyclofix - Un mapa aberto para os ciclistas", + "de": "Cyclofix - eine offene Karte für Radfahrer" + }, + "description": { + "en": "The goal of this map is to present cyclists with an easy-to-use solution to find the appropriate infrastructure for their needs.

You can track your precise location (mobile only) and select layers that are relevant for you in the bottom left corner. You can also use this tool to add or edit pins (points of interest) to the map and provide more data by answering the questions.

All changes you make will automatically be saved in the global database of OpenStreetMap and can be freely re-used by others.

For more information about the cyclofix project, go to cyclofix.osm.be.", + "nl": "Het doel van deze kaart is om fietsers een gebruiksvriendelijke oplossing te bieden voor het vinden van de juiste infrastructuur voor hun behoeften.

U kunt uw exacte locatie volgen (enkel mobiel) en in de linkerbenedenhoek categorieën selecteren die voor u relevant zijn. U kunt deze tool ook gebruiken om 'spelden' aan de kaart toe te voegen of te bewerken en meer gegevens te verstrekken door de vragen te beantwoorden.

Alle wijzigingen die u maakt worden automatisch opgeslagen in de wereldwijde database van OpenStreetMap en kunnen door anderen vrij worden hergebruikt.

Bekijk voor meer info over cyclofix ook cyclofix.osm.be.", + "fr": "Le but de cette carte est de présenter aux cyclistes une solution facile à utiliser pour trouver l'infrastructure appropriée à leurs besoins.

Vous pouvez suivre votre localisation précise (mobile uniquement) et sélectionner les couches qui vous concernent dans le coin inférieur gauche. Vous pouvez également utiliser cet outil pour ajouter ou modifier des épingles (points d'intérêt) sur la carte et fournir plus de données en répondant aux questions.

Toutes les modifications que vous apportez seront automatiquement enregistrées dans la base de données mondiale d'OpenStreetMap et peuvent être librement réutilisées par d'autres.

Pour plus d'informations sur le projet cyclofix, rendez-vous sur cyclofix.osm.be.", + "gl": "O obxectivo deste mapa é amosar ós ciclistas unha solución doada de empregar para atopar a infraestrutura axeitada para as súas necesidades.

Podes obter a túa localización precisa (só para dispositivos móbiles) e escoller as capas que sexan relevantes para ti na esquina inferior esquerda. Tamén podes empregar esta ferramenta para engadir ou editar puntos de interese ó mapa e fornecer máis datos respondendo as cuestións.

Todas as modificacións que fagas serán gardadas de xeito automático na base de datos global do OpenStreetMap e outros poderán reutilizalos libremente.

Para máis información sobre o proxecto cyclofix, vai a cyclofix.osm.be.", + "de": "Das Ziel dieser Karte ist es, den Radfahrern eine einfach zu benutzende Lösung zu präsentieren, um die geeignete Infrastruktur für ihre Bedürfnisse zu finden.

Sie können Ihren genauen Standort verfolgen (nur mobil) und in der linken unteren Ecke die für Sie relevanten Ebenen auswählen. Sie können dieses Tool auch verwenden, um Pins (Points of Interest/Interessante Orte) zur Karte hinzuzufügen oder zu bearbeiten und mehr Daten durch Beantwortung der Fragen bereitstellen.

Alle Änderungen, die Sie vornehmen, werden automatisch in der globalen Datenbank von OpenStreetMap gespeichert und können von anderen frei wiederverwendet werden.

Weitere Informationen über das Projekt Cyclofix finden Sie unter cyclofix.osm.be." + + }, + "language": ["en", "nl", "fr", "gl","de"], + "maintainer": "MapComplete", + "icon": "./assets/themes/cyclofix/logo.svg", + "version": "0", + "startLat": 50.8465573, + + "startLon": 4.3516970, + "startZoom": 16, + "widenFactor": 0.05, + "socialImage": "./assets/themes/cyclofix/logo.svg", + "layers": ["bike_repair_station", "bike_cafes", "bike_shops", "drinking_water", "bike_parking","bike_themed_object"], + "roamingRenderings": [] +} \ No newline at end of file diff --git a/assets/bike/logo.svg b/assets/themes/cyclofix/logo.svg similarity index 100% rename from assets/bike/logo.svg rename to assets/themes/cyclofix/logo.svg diff --git a/assets/bike/non_bike_repair_shop.svg b/assets/themes/cyclofix/unused_assets/non_bike_repair_shop.svg similarity index 100% rename from assets/bike/non_bike_repair_shop.svg rename to assets/themes/cyclofix/unused_assets/non_bike_repair_shop.svg diff --git a/assets/bike/non_bike_shop.svg b/assets/themes/cyclofix/unused_assets/non_bike_shop.svg similarity index 100% rename from assets/bike/non_bike_shop.svg rename to assets/themes/cyclofix/unused_assets/non_bike_shop.svg diff --git a/assets/bike/place_with_pump.svg b/assets/themes/cyclofix/unused_assets/place_with_pump.svg similarity index 100% rename from assets/bike/place_with_pump.svg rename to assets/themes/cyclofix/unused_assets/place_with_pump.svg diff --git a/assets/bike/staples-annotated.png b/assets/themes/cyclofix/unused_assets/staples-annotated.png similarity index 100% rename from assets/bike/staples-annotated.png rename to assets/themes/cyclofix/unused_assets/staples-annotated.png diff --git a/createLayouts.ts b/createLayouts.ts index 194590c..97e1cb4 100644 --- a/createLayouts.ts +++ b/createLayouts.ts @@ -70,6 +70,41 @@ function validate(layout: Layout) { } +function generateWikiEntry(layout: Layout){ + if(layout.hideFromOverview){ + return ""; + } + let image = "MapComplete_Screenshot.png"; + if(layout.socialImage){ + // image = layout.socialImage; + } + + + if(!image.startsWith("http")){ + // image = "https://pietervdvn.github.io/MapComplete/"+image + } + + return `{{Software +|name = ${layout.id} +|author = ${layout.maintainer ?? "MapComplete builtin"} +|web = https://pietervdvn.github.io/MapComplete/${layout.id}.html +|repo = https://github.com/pietervdvn/MapComplete +|platform = web +|code = Typescript;HTML;CSS +|languages = ${layout.supportedLanguages.join(";")} +|genre = display;editor +|screenshot = ${image} +|description = A MapComplete theme: ${Translations.W(layout.description)?.InnerRender() ?? ""} +|map = yes +|findLocation = yes +|findNearbyPOI = yes +|addPOI = yes +|editPOI = yes +|editTags = yes +| +}}` +} + const alreadyWritten = [] function createIcon(iconPath: string, size: number) { @@ -183,6 +218,9 @@ function createLandingPage(layout: Layout) { const blacklist = ["", "test", ".", "..", "manifest", "index", "land", "preferences", "account", "openstreetmap"] const all = AllKnownLayouts.allSets; + +let wikiPage = ""; + for (const layoutName in all) { if (blacklist.indexOf(layoutName.toLowerCase()) >= 0) { console.log(`Skipping a layout with name${layoutName}, it is on the blacklist`); @@ -205,8 +243,10 @@ for (const layoutName in all) { console.log("Generating html-file for ", layout.id) writeFile(enc(layout.id) + ".html", landing, err) console.log("done") + + wikiPage += "\n\n"+generateWikiEntry(layout); } - +writeFile("wikiIndex", wikiPage, (err) => {err ?? console.log("Could not save wikiindex", err)}); console.log("Counting all translations") Translations.CountTranslations(); -console.log("All done!") \ No newline at end of file +console.log("All done!"); \ No newline at end of file diff --git a/css/tabbedComponent.css b/css/tabbedComponent.css index f3f8215..741c7ba 100644 --- a/css/tabbedComponent.css +++ b/css/tabbedComponent.css @@ -8,6 +8,8 @@ justify-content: flex-start; align-items: start; background-color: white; + max-width: 100vw; + overflow-x: auto; } diff --git a/index.css b/index.css index e29e1e6..a2e8d35 100644 --- a/index.css +++ b/index.css @@ -65,7 +65,8 @@ body { } form { - display: inline; + display: inline-block; + max-width: 90vw; } .invalid { @@ -187,8 +188,10 @@ body { } #hidden-on-mobile { - display: none; /*Only shown on small screens*/ + display: none; /*Only shown on small screens - this is probably named wrongly*/ } + + .add-popup-all-buttons { max-height: 50vh; @@ -197,21 +200,20 @@ body { width: 100%; } - @media only screen and (max-height: 600px) and (not (max-width: +@media only screen and (max-height: 600px) and (not (max-width:700px)) { - 700px + /* Landscape and portrait */ + #topleft-tools { + padding: 0.1em 0.1em 0.1em unset; + } - )) { + .hidden-on-mobile { + display: none !important; + } - /* Landscape and portrait */ - #topleft-tools { - padding: 0.1em 0.1em 0.1em unset; - } - - - #userbadge-and-search { - position: relative; - display: inline-block; + #userbadge-and-search { + position: relative; + display: inline-block; width: auto; max-width: 50vw; margin: 0; @@ -237,9 +239,12 @@ body { width: auto; max-width: 100vw; } - + .hidden-on-mobile { + display: none !important; + } + #topleft-tools { padding: 0.2em !important; padding-top: 0.3em !important; @@ -363,6 +368,11 @@ body { #hidden-on-mobile { display: block; } + + + .hidden-on-mobile { + display: none !important; + } #messagesbox-wrapper { display: none; @@ -435,6 +445,11 @@ body { display: unset; } + + .hidden-on-mobile { + display: none !important; + } + #messagesboxmobile { position: absolute; display: block; diff --git a/index.ts b/index.ts index f31c2cd..28f7dbb 100644 --- a/index.ts +++ b/index.ts @@ -7,6 +7,7 @@ import {UIEventSource} from "./Logic/UIEventSource"; import * as $ from "jquery"; import {FromJSON} from "./Customizations/JSON/FromJSON"; import {TagRendering} from "./UI/TagRendering"; +import {State} from "./State"; TagRendering.injectFunction(); @@ -18,6 +19,8 @@ if (location.href.startsWith("http://buurtnatuur.be")) { window.location.replace("https://buurtnatuur.be"); } + + let testing: UIEventSource; if (location.hostname === "localhost" || location.hostname === "127.0.0.1") { testing = QueryParameters.GetQueryParameter("test", "true"); diff --git a/test/Tag.spec.ts b/test/Tag.spec.ts index 11674a9..540dbf3 100644 --- a/test/Tag.spec.ts +++ b/test/Tag.spec.ts @@ -9,6 +9,9 @@ import {FromJSON} from "../Customizations/JSON/FromJSON"; import {And, Tag} from "../Logic/Tags"; import Locale from "../UI/i18n/Locale"; import Translations from "../UI/i18n/Translations"; +import {TagRenderingOptions} from "../Customizations/TagRenderingOptions"; +import {UIEventSource} from "../Logic/UIEventSource"; +import {TagRendering} from "../UI/TagRendering"; new T([ @@ -64,10 +67,58 @@ new T([ equal(undefined, tr.GetContent({"foo": "bar"})); })], - [ - "Select right value test", - () => { + [ + "Empty match test", + () => { + const t = new Tag("key",""); + equal(false, t.matches([{k: "key", v:"somevalue"}])) + } + ], + [ + "Tagrendering test", + () => { + + const def = { + "render": { + "nl": "De toegankelijkheid van dit gebied is: {access:description}" + }, + "question": { + "nl": "Is dit gebied toegankelijk?" + }, + "freeform": { + "key": "access:description" + }, + "mappings": [ + { + "if": { + "and": [ + "access:description=", + "access=", + "leisure=park" + ] + }, + "then": { + "nl": "Dit gebied is vrij toegankelijk" + }, + "hideInAnswer": true + }, + { + "if":"access=no", + "then":"Niet toegankelijk" + } + ] + }; + + const constr = FromJSON.TagRendering(def, "test"); + TagRendering.injectFunction(); + const uiEl = constr.construct({ + tags: new UIEventSource( + {leisure: "park", "access": "no"}) + }); + const rendered = uiEl.InnerRender(); + equal(true, rendered.indexOf("Niet toegankelijk") > 0) + } ] diff --git a/wikiIndex b/wikiIndex new file mode 100644 index 0000000..0cb6ee6 --- /dev/null +++ b/wikiIndex @@ -0,0 +1,202 @@ + + +{{Software +|name = personal +|author = MapComplete builtin +|web = https://pietervdvn.github.io/MapComplete/personal.html +|repo = https://github.com/pietervdvn/MapComplete +|platform = web +|code = Typescript;HTML;CSS +|languages = en +|genre = display;editor +|screenshot = MapComplete_Screenshot.png +|description = A MapComplete theme: The personal theme allows to select one or more layers from all the layouts, creating a truly personal editor +|map = yes +|findLocation = yes +|findNearbyPOI = yes +|addPOI = yes +|editPOI = yes +|editTags = yes +| +}} + +{{Software +|name = buurtnatuur +|author = +|web = https://pietervdvn.github.io/MapComplete/buurtnatuur.html +|repo = https://github.com/pietervdvn/MapComplete +|platform = web +|code = Typescript;HTML;CSS +|languages = nl +|genre = display;editor +|screenshot = MapComplete_Screenshot.png +|description = A MapComplete theme: Met deze tool kan je natuur in je buurt in kaart brengen en meer informatie geven over je favoriete plekje +|map = yes +|findLocation = yes +|findNearbyPOI = yes +|addPOI = yes +|editPOI = yes +|editTags = yes +| +}} + +{{Software +|name = bookcases +|author = MapComplete +|web = https://pietervdvn.github.io/MapComplete/bookcases.html +|repo = https://github.com/pietervdvn/MapComplete +|platform = web +|code = Typescript;HTML;CSS +|languages = en;nl +|genre = display;editor +|screenshot = MapComplete_Screenshot.png +|description = A MapComplete theme: A public bookcase is a small streetside cabinet, box, old phone boot or some other objects where books are stored +|map = yes +|findLocation = yes +|findNearbyPOI = yes +|addPOI = yes +|editPOI = yes +|editTags = yes +| +}} + +{{Software +|name = aed +|author = MapComplete +|web = https://pietervdvn.github.io/MapComplete/aed.html +|repo = https://github.com/pietervdvn/MapComplete +|platform = web +|code = Typescript;HTML;CSS +|languages = en;fr;nl +|genre = display;editor +|screenshot = MapComplete_Screenshot.png +|description = A MapComplete theme: On this map, one can find and mark nearby defibrillators +|map = yes +|findLocation = yes +|findNearbyPOI = yes +|addPOI = yes +|editPOI = yes +|editTags = yes +| +}} + +{{Software +|name = toilets +|author = MapComplete +|web = https://pietervdvn.github.io/MapComplete/toilets.html +|repo = https://github.com/pietervdvn/MapComplete +|platform = web +|code = Typescript;HTML;CSS +|languages = en +|genre = display;editor +|screenshot = MapComplete_Screenshot.png +|description = A MapComplete theme: A map of public toilets +|map = yes +|findLocation = yes +|findNearbyPOI = yes +|addPOI = yes +|editPOI = yes +|editTags = yes +| +}} + +{{Software +|name = artworks +|author = MapComplete +|web = https://pietervdvn.github.io/MapComplete/artworks.html +|repo = https://github.com/pietervdvn/MapComplete +|platform = web +|code = Typescript;HTML;CSS +|languages = en;nl;fr +|genre = display;editor +|screenshot = MapComplete_Screenshot.png +|description = A MapComplete theme: Welcome to Open Artwork Map, a map of statues, busts, grafittis, +|map = yes +|findLocation = yes +|findNearbyPOI = yes +|addPOI = yes +|editPOI = yes +|editTags = yes +| +}} + +{{Software +|name = fietsstraten +|author = MapComlete +|web = https://pietervdvn.github.io/MapComplete/fietsstraten.html +|repo = https://github.com/pietervdvn/MapComplete +|platform = web +|code = Typescript;HTML;CSS +|languages = nl +|genre = display;editor +|screenshot = MapComplete_Screenshot.png +|description = A MapComplete theme: Een kaart met alle gekende fietsstraten +|map = yes +|findLocation = yes +|findNearbyPOI = yes +|addPOI = yes +|editPOI = yes +|editTags = yes +| +}} + +{{Software +|name = ghostbikes +|author = MapComplete +|web = https://pietervdvn.github.io/MapComplete/ghostbikes.html +|repo = https://github.com/pietervdvn/MapComplete +|platform = web +|code = Typescript;HTML;CSS +|languages = en;nl +|genre = display;editor +|screenshot = MapComplete_Screenshot.png +|description = A MapComplete theme: A ghost bike is a memorial for a cyclist who died in a traffic accident, in the form of a white bicycle placed permanently near the accident location +|map = yes +|findLocation = yes +|findNearbyPOI = yes +|addPOI = yes +|editPOI = yes +|editTags = yes +| +}} + +{{Software +|name = cyclofix +|author = MapComplete +|web = https://pietervdvn.github.io/MapComplete/cyclofix.html +|repo = https://github.com/pietervdvn/MapComplete +|platform = web +|code = Typescript;HTML;CSS +|languages = en;nl;fr;gl;de +|genre = display;editor +|screenshot = MapComplete_Screenshot.png +|description = A MapComplete theme: The goal of this map is to present cyclists with an easy-to-use solution to find the appropriate infrastructure for their needs +|map = yes +|findLocation = yes +|findNearbyPOI = yes +|addPOI = yes +|editPOI = yes +|editTags = yes +| +}} + +{{Software +|name = metamap +|author = MapComplete builtin +|web = https://pietervdvn.github.io/MapComplete/metamap.html +|repo = https://github.com/pietervdvn/MapComplete +|platform = web +|code = Typescript;HTML;CSS +|languages = en +|genre = display;editor +|screenshot = MapComplete_Screenshot.png +|description = A MapComplete theme: +|map = yes +|findLocation = yes +|findNearbyPOI = yes +|addPOI = yes +|editPOI = yes +|editTags = yes +| +}} +