diff --git a/Models/Constants.ts b/Models/Constants.ts index a979b6476b..65a1da5f8b 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import { Utils } from "../Utils"; export default class Constants { - public static vNumber = "0.9.3"; + public static vNumber = "0.9.4"; // The user journey states thresholds when a new feature gets unlocked public static userJourney = { diff --git a/UI/BigComponents/Attribution.ts b/UI/BigComponents/Attribution.ts index b2cdc44512..3edf60b86d 100644 --- a/UI/BigComponents/Attribution.ts +++ b/UI/BigComponents/Attribution.ts @@ -23,7 +23,10 @@ export default class Attribution extends Combine { const reportBug = new Link(Svg.bug_ui().SetClass("small-image"), "https://github.com/pietervdvn/MapComplete/issues", true); const layoutId = 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` + const now = new Date() + // Note: getMonth is zero-index, we want 1-index but with one substracted, so it checks out! + const startDate = now.getFullYear()+"-"+now.getMonth()+"-"+now.getDate() + 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%22${startDate}%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` const stats = new Link(Svg.statistics_ui().SetClass("small-image"), osmChaLink, true) diff --git a/UI/OpeningHours/OpeningHours.ts b/UI/OpeningHours/OpeningHours.ts index 1b43f16c7b..df1d43bfa9 100644 --- a/UI/OpeningHours/OpeningHours.ts +++ b/UI/OpeningHours/OpeningHours.ts @@ -256,6 +256,9 @@ export class OH { start?: string, end?: string } { + if(str === undefined){ + return null + } str = str.trim(); if (!str.startsWith("PH")) { return null; diff --git a/UI/i18n/Translation.ts b/UI/i18n/Translation.ts index f153b1e653..0d23121b91 100644 --- a/UI/i18n/Translation.ts +++ b/UI/i18n/Translation.ts @@ -111,9 +111,10 @@ export class Translation extends BaseUIElement { rtext = date.toLocaleString(); } else if (el.ConstructElement === undefined) { console.error("ConstructElement is not defined", el); - throw "ConstructElement is not defined, you are working with a "+(typeof el)+":"+(el.constructor.name) + throw "ConstructElement is not defined, you are working with a " + (typeof el) + ":" + (el.constructor.name) + }else if(el["translations"] !== undefined){ + rtext = el["translations"][lang] } else { - Translation.forcedLanguage = lang; // This is a very dirty hack - it'll bite me one day rtext = el.ConstructElement().innerHTML; } @@ -126,7 +127,6 @@ export class Translation extends BaseUIElement { } newTranslations[lang] = template; } - Translation.forcedLanguage = undefined; return new Translation(newTranslations); } diff --git a/assets/layers/.DS_Store b/assets/layers/.DS_Store deleted file mode 100644 index 4db61cc285..0000000000 Binary files a/assets/layers/.DS_Store and /dev/null differ diff --git a/assets/layers/food/Vegetarian-mark.svg b/assets/layers/food/Vegetarian-mark.svg new file mode 100644 index 0000000000..e88ac71e67 --- /dev/null +++ b/assets/layers/food/Vegetarian-mark.svg @@ -0,0 +1,31 @@ + + + Vegetarian mark + + + + image/svg+xml + + Vegetarian mark + + + + + + + diff --git a/assets/layers/food/fastfood.svg b/assets/layers/food/fastfood.svg new file mode 100644 index 0000000000..a6995246d0 --- /dev/null +++ b/assets/layers/food/fastfood.svg @@ -0,0 +1,25 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/assets/layers/food/food.json b/assets/layers/food/food.json new file mode 100644 index 0000000000..27ea83983d --- /dev/null +++ b/assets/layers/food/food.json @@ -0,0 +1,381 @@ +{ + "id": "food", + "name": { + "nl": "Eetgelegenheden", + "en": "Restaurants and fast food" + }, + "source": { + "osmTags": { + "or": [ + "amenity=fast_food", + "amenity=restaurant" + ] + } + }, + "wayHandling": 1, + "icon": { + "render": "circle:white;./assets/layers/food/restaurant.svg", + "mappings": [ + { + "if": { + "and": [ + "amenity=fast_food", + "cuisine=friture" + ] + }, + "then": "circle:white;./assets/layers/food/fries.svg" + }, + { + "if": "amenity=fast_food", + "then": "circle:white;./assets/layers/food/fastfood.svg" + } + ] + }, + "iconOverlays": [ + { + "if": "opening_hours~*", + "then": "isOpen", + "badge": true + }, + { + "if": { + "or": [ + "diet:vegetarian=yes", + "diet:vegan=yes" + ] + }, + "then": { + "render": "circle:white;./assets/themes/fritures/Vegetarian-mark.svg" + }, + "badge": true + } + ], + "label": { + "mappings": [ + { + "if": "name~*", + "then": "
{name}
" + } + ] + }, + "presets": [ + { + "title": { + "en": "restaurant", + "nl": "restaurant" + }, + "tags": [ + "amenity=restaurant" + ], + "description": { + "nl": "Een eetgegelegenheid waar je aan tafel wordt bediend", + "en": "A formal eating place with sit-down facilities selling full meals served by waiters" + }, + "preciseInput": { + "preferredBackground": "map" + } + }, + { + "title": { + "en": "fastfood", + "nl": "fastfood-zaak" + }, + "tags": [ + "amenity=fast_food" + ], + "description": { + "nl": "Een zaak waar je snel bediend wordt, vaak met de focus op afhalen. Zitgelegenheid is eerder beperkt tot afwezig" + }, + "preciseInput": { + "preferredBackground": "map" + } + }, + { + "title": { + "en": "Friture", + "nl": "Friture" + }, + "tags": [ + "amenity=fast_food", + "cuisine=friture" + ], + "description": { + "nl": "Een fastfood-zaak waar je frieten koopt" + }, + "preciseInput": { + "preferredBackground": "map" + } + } + ], + "title": { + "render": { + "nl": "Eetgelegenheid" + }, + "mappings": [ + { + "if": { + "and": [ + "name~*", + "amenity=restaurant" + ] + }, + "then": { + "nl": "Restaurant {name}", + "en": "Restaurant {name}" + } + }, + { + "if": { + "and": [ + "name~*", + "amenity=fast_food" + ] + }, + "then": { + "nl": "Fastfood-zaak {name}", + "en": "Fastfood {name}" + } + } + ] + }, + "tagRenderings": [ + "images", + { + "question": { + "nl": "Wat is de naam van deze eetgelegenheid?" + }, + "render": { + "nl": "De naam van deze eetgelegeheid is {name}" + }, + "freeform": { + "key": "name" + } + }, + "opening_hours", + "website", + "email", + "phone", + + { + "question": { + "nl": "Heeft deze eetgelegenheid een vegetarische optie?", + "en": "Does this restaurant have a vegetarian option?" + }, + "mappings": [ + { + "if": "diet:vegetarian=no", + "then": { + "nl": "Geen vegetarische opties beschikbaar" + } + }, + { + "if": "diet:vegetarian=limited", + "then": { + "nl": "Beperkte vegetarische opties zijn beschikbaar" + } + }, + { + "if": "diet:vegetarian=yes", + "then": { + "nl": "Vegetarische opties zijn beschikbaar" + } + }, + { + "if": "diet:vegetarian=only", + "then": { + "nl": "Enkel vegetarische opties zijn beschikbaar" + } + } + ], + "condition": "cuisine!=friture" + }, + + { + "question": { + "nl": "Heeft deze eetgelegenheid een veganistische optie?" + }, + "mappings": [ + { + "if": "diet:vegan=no", + "then": { + "nl": "Geen veganistische opties beschikbaar" + } + }, + { + "if": "diet:vegan=limited", + "then": { + "nl": "Beperkte veganistische opties zijn beschikbaar" + } + }, + { + "if": "diet:vegan=yes", + "then": { + "nl": "Veganistische opties zijn beschikbaar" + } + }, + { + "if": "diet:vegan=only", + "then": { + "nl": "Enkel veganistische opties zijn beschikbaar" + } + } + ], + "condition": "cuisine!=friture" + }, + + { + "question": { + "nl": "Heeft deze frituur vegetarische snacks?", + "fr": "Cette friterie est-elle équipée de snacks végétariens ?" + }, + "mappings": [ + { + "if": { + "and": [ + "diet:vegetarian=yes" + ] + }, + "then": { + "nl": "Er zijn vegetarische snacks aanwezig", + "fr": "Des collations végétariennes sont disponibles" + } + }, + { + "if": { + "and": [ + "diet:vegetarian=limited" + ] + }, + "then": { + "nl": "Slechts enkele vegetarische snacks", + "fr": "Quelques snacks végétariens seulement" + } + }, + { + "if": { + "and": [ + "diet:vegetarian=no" + ] + }, + "then": { + "nl": "Geen vegetarische snacks beschikbaar", + "fr": "Pas d'en-cas végétariens disponibles" + } + } + ], + "condition": "cuisine=friture" + }, + { + "question": { + "nl": "Heeft deze frituur veganistische snacks?", + "fr": "Cette friterie est-elle équipée de snacks végétaliens ?" + }, + "mappings": [ + { + "if": { + "and": [ + "diet:vegan=yes" + ] + }, + "then": { + "nl": "Er zijn veganistische snacks aanwezig", + "fr": "Des collations végétaliens sont disponibles" + } + }, + { + "if": { + "and": [ + "diet:vegan=limited" + ] + }, + "then": { + "nl": "Slechts enkele veganistische snacks", + "fr": "Quelques snacks végétaliens seulement" + } + }, + { + "if": { + "and": [ + "diet:vegetarian=no" + ] + }, + "then": { + "nl": "Geen veganistische snacks beschikbaar", + "fr": "Pas d'en-cas végétaliens disponibles" + } + } + ], + "condition": "cuisine=friture" + }, + { + "question": { + "nl": "Bakt deze frituur met dierlijk vet of met plantaardige olie?", + "fr": "Cette friteuse fonctionne-t-elle avec de la graisse animale ou végétale ?" + }, + "mappings": [ + { + "if": { + "and": [ + "friture:oil=vegetable" + ] + }, + "then": { + "nl": "Plantaardige olie", + "fr": "Huile végétale" + } + }, + { + "if": { + "and": [ + "friture:oil=animal" + ] + }, + "then": { + "nl": "Dierlijk vet", + "fr": "Graisse animale" + } + } + ], + "condition": "cuisine=friture" + }, + { + "question": { + "nl": "Als je je eigen container (bv. kookpot of kleine potjes voor saus) meeneemt, gebruikt de frituur deze dan om je bestelling in te doen?", + "en": "If you bring your own container (such as a cooking pot and small pots), is it used to package your order?
", + "ja": "お客様が持参容器(調理用の鍋や小さな鍋など)をもってきた場合は、注文の梱包に使用されますか?
", + "fr": "Est-il proposé d’utiliser ses propres contenants pour sa commande ?
" + }, + "mappings": [ + { + "if": "bulk_purchase=yes", + "then": { + "nl": "Je mag je eigen containers meenemen om je bestelling in mee te nemen en zo minder afval te maken", + "en": "You can bring your own containers to get your order, saving on single-use packaging material and thus waste", + "ja": "自分の容器を持ってきて、注文を受け取ることができ、使い捨ての梱包材を節約して、無駄を省くことができます", + "fr": "Vous pouvez apporter vos contenants pour votre commande, limitant l’usage de matériaux à usage unique et les déchets" + } + }, + { + "if": "bulk_purchase=no", + "then": { + "nl": "Je mag geen eigen containers meenemen om je bestelling in mee te nemen", + "en": "Bringing your own container is not allowed", + "ja": "独自の容器を持参することはできません", + "ru": "Приносить свою тару не разрешено", + "fr": "Apporter ses propres contenants n’est pas permis" + } + }, + { + "if": "bulk_purchase=only", + "then": { + "nl": "Je moet je eigen containers meenemen om je bestelling in mee te nemen.", + "en": "You must bring your own container to order here.", + "ja": "自身の容器が注文に必要。", + "fr": "Il est obligatoire d’apporter ses propres contenants" + } + } + ], + "condition": "cuisine=friture" + } + ] +} \ No newline at end of file diff --git a/assets/layers/food/fries.svg b/assets/layers/food/fries.svg new file mode 100644 index 0000000000..80e8071acb --- /dev/null +++ b/assets/layers/food/fries.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/layers/food/license_info.json b/assets/layers/food/license_info.json new file mode 100644 index 0000000000..35d4896450 --- /dev/null +++ b/assets/layers/food/license_info.json @@ -0,0 +1,42 @@ +[ + { + "authors": [ + "OSM Carto" + ], + "path": "fastfood.svg", + "license": "CC0", + "sources": [ + "https://wiki.openstreetmap.org/w/images/1/1f/Fast-food-16.svg" + ] + }, + { + "authors": [ + "OSM Carto" + ], + "path": "restaurant.svg", + "license": "CC0", + "sources": [ + "https://wiki.openstreetmap.org/w/images/b/bb/Restaurant-14.svg" + ] + }, + { + "authors": [ + "European Vegetarian Union" + ], + "path": "Vegetarian-mark.svg", + "license": "PD", + "sources": [ + "https://commons.wikimedia.org/wiki/File:Vegetarian-mark.svg" + ] + }, + { + "authors": [ + "Freepik" + ], + "path": "fries.svg", + "license": "CC-BY", + "sources": [ + "https://www.flaticon.com/free-icon/french-fries_1144288" + ] + } +] \ No newline at end of file diff --git a/assets/layers/food/restaurant.svg b/assets/layers/food/restaurant.svg new file mode 100644 index 0000000000..f077cb042a --- /dev/null +++ b/assets/layers/food/restaurant.svg @@ -0,0 +1,31 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/assets/themes/food/food.json b/assets/themes/food/food.json new file mode 100644 index 0000000000..416f9d1614 --- /dev/null +++ b/assets/themes/food/food.json @@ -0,0 +1,26 @@ +{ + "id": "food", + "title": { + "nl": "Eetgelegenheden", + "en": "Restaurants and fast food" + }, + "description": { + "nl": "Restaurants en fast food" + }, + "language": [ + "nl", + "fr", + "en" + ], + "maintainer": "", + "icon": "./assets/layers/food/restaurant.svg", + "version": "0", + "startLat": 0, + "startLon": 0, + "startZoom": 1, + "widenFactor": 0.05, + "socialImage": "", + "layers": [ + "food" + ] +} \ No newline at end of file diff --git a/assets/themes/fritures/fritures.json b/assets/themes/fritures/fritures.json index d77b05ed45..53e8bad9d3 100644 --- a/assets/themes/fritures/fritures.json +++ b/assets/themes/fritures/fritures.json @@ -229,7 +229,7 @@ }, { "question": { - "nl": "Bakt deze frituur in dierlijk vetof plantaardig olie?", + "nl": "Bakt deze frituur met dierlijk vet of met plantaardige olie?", "fr": "Cette friteuse fonctionne-t-elle avec de la graisse animale ou végétale ?" }, "mappings": [ @@ -266,7 +266,7 @@ }, "mappings": [ { - "if": "bulk_purchase=yes", + "if": "reusable_packaging:accept=yes", "then": { "nl": "Je mag je eigen containers meenemen om je bestelling in mee te nemen en zo minder afval te maken", "en": "You can bring your own containers to get your order, saving on single-use packaging material and thus waste", @@ -275,7 +275,7 @@ } }, { - "if": "bulk_purchase=no", + "if": "reusable_packaging:accept=no", "then": { "nl": "Je mag geen eigen containers meenemen om je bestelling in mee te nemen", "en": "Bringing your own container is not allowed", @@ -285,7 +285,7 @@ } }, { - "if": "bulk_purchase=only", + "if": "reusable_packaging:accept=only", "then": { "nl": "Je moet je eigen containers meenemen om je bestelling in mee te nemen.", "en": "You must bring your own container to order here.", diff --git a/index.ts b/index.ts index cd146653f0..a75d29003f 100644 --- a/index.ts +++ b/index.ts @@ -21,6 +21,7 @@ import * as L from "leaflet"; import ValidatedTextField from "./UI/Input/ValidatedTextField"; import AvailableBaseLayers from "./Logic/Actors/AvailableBaseLayers"; import LayoutConfig from "./Models/ThemeConfig/LayoutConfig"; +import Constants from "./Models/Constants"; // Workaround for a stupid crash: inject some functions which would give stupid circular dependencies or crash the other nodejs scripts SimpleMetaTagger.coder = new CountryCoder("https://pietervdvn.github.io/latlon2country/"); @@ -159,7 +160,8 @@ if (layoutFromBase64.startsWith("http")) { new FixedUiElement("").AttachTo("centermessage") State.state = new State(undefined); new Combine([new MoreScreen(true), - Translations.t.general.aboutMapcomplete.SetClass("link-underline") + Translations.t.general.aboutMapcomplete.SetClass("link-underline"), + new FixedUiElement("v"+Constants.vNumber) ]).SetClass("block m-5 lg:w-3/4 lg:ml-40") .SetStyle("pointer-events: all;") .AttachTo("topleft-tools"); diff --git a/langs/layers/en.json b/langs/layers/en.json index 3f02b7530b..5992072918 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -1499,6 +1499,28 @@ } } }, + "food": { + "name": "Restaurants and fast food", + "presets": { + "0": { + "title": "restaurant", + "description": "A formal eating place with sit-down facilities selling full meals served by waiters" + }, + "1": { + "title": "fastfood" + } + }, + "title": { + "mappings": { + "0": { + "then": "Restaurant {name}" + }, + "1": { + "then": "Fastfood {name}" + } + } + } + }, "ghost_bike": { "name": "Ghost bikes", "title": { diff --git a/langs/layers/nl.json b/langs/layers/nl.json index c595cdcd72..b6484c7ffd 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -1555,6 +1555,36 @@ } } }, + "food": { + "name": "Eetgelegenheden", + "presets": { + "0": { + "title": "restaurant", + "description": "Een eetgegelegenheid waar je aan tafel wordt bediend" + }, + "1": { + "title": "fastfood-zaak", + "description": "Een zaak waar je snel bediend wordt, vaak met de focus op afhalen. Zitgelegenheid is eerder beperkt tot afwezig" + } + }, + "title": { + "render": "Eetgelegenheid", + "mappings": { + "0": { + "then": "Restaurant {name}" + }, + "1": { + "then": "Fastfood-zaak {name}" + } + } + }, + "tagRenderings": { + "1": { + "question": "Wat is de naam van deze eetgelegenheid?", + "render": "De naam van deze eetgelegeheid is {name}" + } + } + }, "ghost_bike": { "name": "Witte Fietsen", "title": { diff --git a/langs/nl.json b/langs/nl.json index 16a02dc266..aa77d93865 100644 --- a/langs/nl.json +++ b/langs/nl.json @@ -52,11 +52,12 @@ "intro": "Je klikte ergens waar er nog geen data is. Kies hieronder welk punt je wilt toevoegen
", "pleaseLogin": "Gelieve je aan te melden om een punt to te voegen", "zoomInFurther": "Gelieve verder in te zoomen om een punt toe te voegen.", - "stillLoading": "De data wordt nog geladen. Nog even geduld en dan kan je een punt toevoegen.", + "stillLoading": "De data worden nog geladen. Nog even geduld en dan kan je een punt toevoegen.", "confirmIntro": "

Voeg hier een {title} toe?

Het punt dat je hier toevoegt, is zichtbaar voor iedereen. Veel applicaties gebruiken deze data, voeg dus enkel punten toe die echt bestaan.", "confirmButton": "Voeg hier een {category} toe
Je toevoeging is voor iedereen zichtbaar
", "openLayerControl": "Open de laag-instellingen", - "layerNotEnabled": "De laag {layer} is gedeactiveerd. Activeer deze om een punt toe te voegen" + "layerNotEnabled": "De laag {layer} is gedeactiveerd. Activeer deze om een punt toe te voegen", + "presetInfo": "Het nieuwe punt krijgt de attributen {tags}" }, "pickLanguage": "Kies je taal: ", "about": "Bewerk en voeg data toe aan OpenStreetMap over een specifiek onderwerp op een gemakkelijke manier", diff --git a/langs/themes/en.json b/langs/themes/en.json index a7a21b9fba..bcb7629f81 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -692,6 +692,18 @@ } } }, + "cycle_highways": { + "title": "Cycle highways", + "description": "This map shows cycle highways", + "layers": { + "0": { + "name": "cycle highways", + "title": { + "render": "cycle highway" + } + } + } + }, "cycle_infra": { "title": "Bicycle infrastructure", "shortDescription": "A map where you can view and edit things related to the bicycle infrastructure.", @@ -845,6 +857,9 @@ } } }, + "food": { + "title": "Restaurants and fast food" + }, "fritures": { "layers": { "0": { diff --git a/langs/themes/nl.json b/langs/themes/nl.json index b10e1705df..83fcb3058a 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -733,6 +733,10 @@ } } }, + "food": { + "title": "Eetgelegenheden", + "description": "Restaurants en fast food" + }, "fritures": { "title": "Friturenkaart", "description": "Op deze kaart vind je je favoriete frituur!", diff --git a/scripts/generateLicenseInfo.ts b/scripts/generateLicenseInfo.ts index db8e818bd0..c9fc05f18a 100644 --- a/scripts/generateLicenseInfo.ts +++ b/scripts/generateLicenseInfo.ts @@ -65,12 +65,6 @@ function missingLicenseInfos(licenseInfos: SmallLicense[], allIcons: string[]) { const prompt = require('prompt-sync')(); const knownLicenses = new Map() -knownLicenses.set("cf", { - authors: ["Pieter Fiers", "Thibault Declercq", "Pierre Barban", "Joost Schouppe", "Pieter Vander Vennet"], - path: undefined, - license: "CC-BY-SA", - sources: ["https://osoc.be/editions/2020/cyclofix"] -}) knownLicenses.set("me", { authors: ["Pieter Vander Vennet"], path: undefined, @@ -92,19 +86,7 @@ knownLicenses.set("na", { sources: [] }) -knownLicenses.set("chrn", { - authors: ["Christian Neumann"], - path: undefined, - license: "CC-BY-SA 3.0", - sources: ["https://utopicode.de/", "https://github.com/chrneumann/MapComplete"] -}) -knownLicenses.set("klimaan", { - authors: ["Klimaan VZW"], - path: undefined, - license: "CC-BY-SA 3.0", - sources: ["https://klimaan.be/"] -}) function promptLicenseFor(path): SmallLicense { console.log("License abbreviations:")