Small fixes

This commit is contained in:
pietervdvn 2021-04-23 17:22:01 +02:00
parent 5c0e3662c1
commit 3e3da25edb
18 changed files with 263 additions and 103 deletions

2
.gitignore vendored
View File

@ -11,4 +11,4 @@ assets/generated/*
.parcel-cache
Docs/Tools/stats.*.json
Docs/Tools/stats.csv
missing_translations.txt

View File

@ -375,8 +375,8 @@ export class InitUiElements {
state.layoutToUse.map(layoutToUse => {
const flayers = [];
for (const layer of layoutToUse.layers) {
const isDisplayed = QueryParameters.GetQueryParameter("layer-" + layer.id, "true", "Wether or not layer " + layer.id + " is shown")
.map<boolean>((str) => str !== "false", [], (b) => b.toString());
const flayer = {

View File

@ -3,9 +3,9 @@ import {UIEventSource} from "../UIEventSource";
import {Review} from "./Review";
export class MangroveIdentity {
private readonly _mangroveIdentity: UIEventSource<string>;
public keypair: any = undefined;
public readonly kid: UIEventSource<string> = new UIEventSource<string>(undefined);
private readonly _mangroveIdentity: UIEventSource<string>;
constructor(mangroveIdentity: UIEventSource<string>) {
const self = this;
@ -26,7 +26,7 @@ export class MangroveIdentity {
if ((mangroveIdentity.data ?? "") === "") {
this.CreateIdentity();
}
}catch(e){
} catch (e) {
console.error("Could not create identity: ", e)
}
}
@ -53,46 +53,47 @@ export class MangroveIdentity {
}
export default class MangroveReviews {
private static _reviewsCache = {};
private static didWarn = false;
private readonly _lon: number;
private readonly _lat: number;
private readonly _name: string;
private readonly _reviews: UIEventSource<Review[]> = new UIEventSource<Review[]>([]);
private _dryRun: boolean;
private _mangroveIdentity: MangroveIdentity;
private _lastUpdate : Date = undefined;
private _lastUpdate: Date = undefined;
private constructor(lon: number, lat: number, name: string,
identity: MangroveIdentity,
dryRun?: boolean) {
private static _reviewsCache = {};
public static Get(lon: number, lat: number, name: string,
identity: MangroveIdentity,
dryRun?: boolean){
const newReviews = new MangroveReviews(lon, lat, name, identity, dryRun);
const uri = newReviews.GetSubjectUri();
const cached = MangroveReviews._reviewsCache[uri];
if(cached !== undefined){
return cached;
}
MangroveReviews._reviewsCache[uri] = newReviews;
return newReviews;
}
private constructor(lon: number, lat: number, name: string,
identity: MangroveIdentity,
dryRun?: boolean) {
this._lon = lon;
this._lat = lat;
this._name = name;
this._mangroveIdentity = identity;
this._dryRun = dryRun;
if(dryRun){
if (dryRun && !MangroveReviews.didWarn) {
MangroveReviews.didWarn = true;
console.warn("Mangrove reviews will _not_ be saved as dryrun is specified")
}
}
public static Get(lon: number, lat: number, name: string,
identity: MangroveIdentity,
dryRun?: boolean) {
const newReviews = new MangroveReviews(lon, lat, name, identity, dryRun);
const uri = newReviews.GetSubjectUri();
const cached = MangroveReviews._reviewsCache[uri];
if (cached !== undefined) {
return cached;
}
MangroveReviews._reviewsCache[uri] = newReviews;
return newReviews;
}
/**
* Gets an URI which represents the item in a mangrove-compatible way
* @constructor
@ -111,10 +112,10 @@ export default class MangroveReviews {
* Note: rating is between 1 and 100
*/
public GetReviews(): UIEventSource<Review[]> {
if(this._lastUpdate !== undefined && this._reviews.data !== undefined &&
if (this._lastUpdate !== undefined && this._reviews.data !== undefined &&
(new Date().getTime() - this._lastUpdate.getTime()) < 15000
){
) {
// Last update was pretty recent
return this._reviews;
}
@ -140,7 +141,6 @@ export default class MangroveReviews {
rating: r.rating // percentage points
};
(rev.made_by_user ? reviewsByUser : reviews).push(rev);
}

View File

@ -2,7 +2,7 @@ import { Utils } from "../Utils";
export default class Constants {
public static vNumber = "0.6.11a";
public static vNumber = "0.6.11b";
// The user journey states thresholds when a new feature gets unlocked
public static userJourney = {

View File

@ -1,4 +1,3 @@
import {UIElement} from "../UIElement";
import Combine from "../Base/Combine";
import Translations from "../i18n/Translations";
import Attribution from "./Attribution";
@ -8,9 +7,8 @@ import LayoutConfig from "../../Customizations/JSON/LayoutConfig";
import {FixedUiElement} from "../Base/FixedUiElement";
import * as licenses from "../../assets/generated/license_info.json"
import SmallLicense from "../../Models/smallLicense";
import {Icon} from "leaflet";
import Img from "../Base/Img";
import {Utils} from "../../Utils";
import Link from "../Base/Link";
/**
* The attribution panel shown on mobile
@ -48,12 +46,25 @@ export default class AttributionPanel extends Combine {
return undefined;
}
const sources =Utils.NoNull(Utils.NoEmpty(license.sources))
return new Combine([
`<img src='${iconPath}' style="width: 50px; height: 50px; margin-right: 0.5em;">`,
new Combine([
new FixedUiElement(license.authors.join("; ")).SetClass("font-bold"),
new Combine([license.license, license.sources.length > 0 ? " - " : "",
...license.sources.map(link => `<a href='${link}' target="_blank">${new URL(link).hostname}</a> `)]).SetClass("block")
new Combine([license.license,
sources.length > 0 ? " - " : "",
... sources.map(lnk => {
let sourceLinkContent = lnk;
try{
sourceLinkContent = new URL(lnk).hostname
}catch{
console.error("Not a valid URL:", lnk)
}
return new Link(sourceLinkContent, lnk, true);
})
]
).SetClass("block")
]).SetClass("flex flex-col")
]).SetClass("flex")
}

View File

@ -117,6 +117,12 @@ export class SubstitutedTranslation extends UIElement {
}
}
// Let's to a small sanity check to help the theme designers:
if(template.search(/{[^}]+\([^}]*\)}/) >= 0){
// Hmm, we might have found an invalid rendering name
console.warn("Found a suspicious special rendering value in: ", template, " did you mean one of: ", SpecialVisualizations.specialVisualizations.map(sp => sp.funcName+"()").join(", "))
}
// IF we end up here, no changes have to be made - except to remove any resting {}
return [new FixedUiElement(template.replace(/{.*}/g, ""))];
}

View File

@ -20,6 +20,7 @@ export class Translation extends UIElement {
for (const translationsKey in translations) {
count++;
if (typeof (translations[translationsKey]) != "string") {
console.error("Non-string object in translation: ", translations[translationsKey])
throw "Error in an object depicting a translation: a non-string object was found. (" + context + ")\n You probably put some other section accidentally in the translation"
}
}

View File

@ -32,7 +32,7 @@
]
},
"icon": "./assets/themes/playgrounds/playground.svg",
"iconSize": "40,40,bottom",
"iconSize": "40,40,center",
"width": "1",
"color": "#0f0",
"wayHandling": 2,

View File

@ -335,7 +335,8 @@
{
"#": "Surface area",
"render": {
"en": "Surface area: {_surface:ha}Ha"
"en": "Surface area: {_surface:ha}Ha",
"nl": "Totale oppervlakte: {_surface:ha}Ha"
},
"mappings":[ {
"if": "_surface:ha=0",

View File

@ -13,6 +13,9 @@
]
}
},
"calculatedTags": [
"_size_classification=Number(feat.properties._surface) < 10 ? 'small' : (Number(feat.properties._surface) < 100 ? 'medium' : 'large') "
],
"description": {
"nl": "Speeltuinen",
"en": "Playgrounds"
@ -331,7 +334,25 @@
"render": "1"
},
"iconSize": {
"render": "40,40,center"
"render": "40,40,center",
"mappings": [
{
"if": "id~node/.*",
"then": "40,40,center"
},
{
"if": "_size_classification=small",
"then": "25,25,center"
},
{
"if": "_size_classification=medium",
"then": "40,40,center"
},
{
"if": "_size_classification=large",
"then": "60,60,center"
}
]
},
"color": {
"render": "#0c3"

View File

@ -1,13 +1,112 @@
[
{
"authors": [
"@fontawesome"
"Gitte Loos (Createlli) in opdracht van Provincie Antwerpen "
],
"path": "tabletennis.svg",
"license": "CC-BY 4.0",
"path": "baseball.svg",
"license": "CC-BY-SA 4.0",
"sources": [
"https://commons.wikimedia.org/wiki/File:Font_Awesome_5_solid_table-tennis.svg",
" https://fontawesome.com"
"https://createlli.com/",
"https://www.provincieantwerpen.be/"
]
},
{
"authors": [
"Gitte Loos (Createlli) in opdracht van Provincie Antwerpen "
],
"path": "basketball.svg",
"license": "CC-BY-SA 4.0",
"sources": [
"https://createlli.com/",
"https://www.provincieantwerpen.be/"
]
},
{
"authors": [
"Gitte Loos (Createlli) in opdracht van Provincie Antwerpen "
],
"path": "beachvolleyball.svg",
"license": "CC-BY-SA 4.0",
"sources": [
"https://createlli.com/",
"https://www.provincieantwerpen.be/"
]
},
{
"authors": [
"Gitte Loos (Createlli) in opdracht van Provincie Antwerpen "
],
"path": "boules.svg",
"license": "CC-BY-SA 4.0",
"sources": [
"https://createlli.com/",
"https://www.provincieantwerpen.be/"
]
},
{
"authors": [
"Gitte Loos (Createlli) in opdracht van Provincie Antwerpen "
],
"path": "skateboard.svg",
"license": "CC-BY-SA 4.0",
"sources": [
"https://createlli.com/",
"https://www.provincieantwerpen.be/"
]
},
{
"authors": [
"Gitte Loos (Createlli) in opdracht van Provincie Antwerpen "
],
"path": ".svg",
"license": "CC-BY-SA 4.0",
"sources": [
"https://createlli.com/",
"https://www.provincieantwerpen.be/"
]
},
{
"authors": [
"Gitte Loos (Createlli) in opdracht van Provincie Antwerpen "
],
"path": "soccer.svg",
"license": "CC-BY-SA 4.0",
"sources": [
"https://createlli.com/",
"https://www.provincieantwerpen.be/"
]
},
{
"authors": [
"Gitte Loos (Createlli) in opdracht van Provincie Antwerpen "
],
"path": "table_tennis.svg",
"license": "CC-BY-SA 4.0",
"sources": [
"https://createlli.com/",
"https://www.provincieantwerpen.be/"
]
},
{
"authors": [
"Gitte Loos (Createlli) in opdracht van Provincie Antwerpen "
],
"path": "tennis.svg",
"license": "CC-BY-SA 4.0",
"sources": [
"https://createlli.com/",
"https://www.provincieantwerpen.be/"
]
},
{
"authors": [
"Gitte Loos (Createlli) in opdracht van Provincie Antwerpen "
],
"path": "volleyball.svg",
"license": "CC-BY-SA 4.0",
"sources": [
"https://createlli.com/",
"https://www.provincieantwerpen.be/"
]
}
]

View File

@ -4,7 +4,7 @@
"nl": "Sportterrein",
"en": "Sport pitches"
},
"wayHandling": 2,
"wayHandling": 1,
"minzoom": 12,
"source": {
"osmTags": {
@ -13,6 +13,9 @@
]
}
},
"calculatedTags": [
"_size_classification=Number(feat.properties._surface) < 200 ? 'small' : (Number(feat.properties._surface) < 750 ? 'medium' : 'large') "
],
"title": {
"render": {
"nl": "Sportterrein",
@ -264,7 +267,7 @@
"nl": "Wanneer is dit sportveld toegankelijk?",
"en": "When is this pitch accessible?"
},
"render": "{opening_hours()}",
"render": "Openingsuren: {opening_hours_table()}",
"freeform": {
"key": "opening_hours",
"type": "opening_hours"
@ -292,7 +295,25 @@
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "circle:white;./assets/layers/sport_pitch/tabletennis.svg"
"render": "./assets/layers/sport_pitch/basketball.svg",
"mappings": [
{
"if": {
"or": [
"sport=baseball",
"sport=basketball",
"sport=beachvolleyball",
"sport=boules",
"sport=skateboard",
"sport=soccer",
"sport=table_tennis",
"sport=tennis",
"sport=volleyball"
]
},
"then": "./assets/layers/sport_pitch/{sport}.svg"
}
]
},
"iconOverlays": [
{
@ -310,7 +331,24 @@
"render": "1"
},
"iconSize": {
"render": "25,25,center"
"render": "25,25,center",
"mappings": [
{
"if": {
"or": ["_size_classification=medium","id~node/.*"]
},
"then": "40,40,center"
},
{
"if": "_size_classification=small",
"then": "25,25,center"
},
{
"if": "_size_classification=large",
"then": "50,50,center"
}
]
},
"color": {
"render": "#009"

View File

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M496.2 296.5C527.7 218.7 512 126.2 449 63.1 365.1-21 229-21 145.1 63.1l-56 56.1 211.5 211.5c46.1-62.1 131.5-77.4 195.6-34.2zm-217.9 79.7L57.9 155.9c-27.3 45.3-21.7 105 17.3 144.1l34.5 34.6L6.7 424c-8.6 7.5-9.1 20.7-1 28.8l53.4 53.5c8 8.1 21.2 7.6 28.7-1L177.1 402l35.7 35.7c19.7 19.7 44.6 30.5 70.3 33.3-7.1-17-11-35.6-11-55.1-.1-13.8 2.5-27 6.2-39.7zM416 320c-53 0-96 43-96 96s43 96 96 96 96-43 96-96-43-96-96-96z"/></svg>
<!--
Font Awesome Free 5.2.0 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->

Before

Width:  |  Height:  |  Size: 669 B

View File

@ -21,7 +21,7 @@
]
},
"icon": "./assets/themes/playgrounds/playground.svg",
"iconSize": "40,40,bottom",
"iconSize": "40,40,center",
"width": "1",
"color": "#0f0",
"wayHandling": 2,

View File

@ -33,9 +33,7 @@
],
"path": "social_image_front.png",
"license": "CC-BY-SA",
"sources": [
""
]
"sources": []
},
{
"authors": [

View File

@ -6,7 +6,7 @@
"path": "SocialImageForeground.svg",
"license": "CC-BY-SA",
"sources": [
""
"https://mapcomplete.osm.be"
]
},
{
@ -15,9 +15,7 @@
],
"path": "add.svg",
"license": "CC0",
"sources": [
""
]
"sources": []
},
{
"authors": [
@ -354,7 +352,7 @@
"path": "mapcomplete_logo.svg",
"license": "Logo; CC-BY-SA",
"sources": [
""
"https://mapcomplete.osm.be"
]
},
{

View File

@ -30,58 +30,39 @@
"source": {
"geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{z}_{x}_{y}.geojson",
"geoJsonZoomLevel": 14
}
},
"icon": "./assets/themes/speelplekken/speelbos.svg"
}
},
{
"builtin": "playground",
"override": {
"source": {
"geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{z}_{x}_{y}.geojson",
"geoJsonZoomLevel": 14
}
}
},
{
"builtin": "sport_pitch",
"override": {
"minzoom": 15,
"source": {
"geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{z}_{x}_{y}.geojson",
"geoJsonZoomLevel": 14
}
}
},
{
"builtin": "slow_roads",
"override": {
"source": {
"geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{z}_{x}_{y}.geojson",
"geoJsonZoomLevel": 14
},
"calculatedTags": [
"_part_of_walking_routes=feat.memberships().map(r => \"<a href='#relation/\"+r.relation.id+\"'>\" + r.relation.tags.name + \"</a>\").join(', ')"
]
}
},
{
"builtin": "grass_in_parks",
"override": {
"source": {
"geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{z}_{x}_{y}.geojson",
"geoJsonZoomLevel": 14
}
"icon": "./assets/themes/speelplekken/speeltuin.svg"
}
},
{
"builtin": "village_green",
"override": {
"source": {
"geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{z}_{x}_{y}.geojson",
"geoJsonZoomLevel": 14
}
"icon": "./assets/themes/speelplekken/speelweide.svg"
}
},
{
"builtin": "grass_in_parks",
"override": {
"icon": "./assets/themes/speelplekken/speelweide.svg"
}
},
"sport_pitch",
{
"builtin": "slow_roads",
"override": {
"calculatedTags": [
"_part_of_walking_routes=feat.memberships().map(r => \"<a href='#relation/\"+r.relation.id+\"'>\" + r.relation.tags.name + \"</a>\").join(', ')"
]
}
},
{
"id": "walking_routes",
"name": {
@ -190,6 +171,12 @@
}
}
],
"overrideAll": {
"source": {
"geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{z}_{x}_{y}.geojson",
"geoJsonZoomLevel": 14
}
},
"roamingRenderings": [
{
"render": "Maakt deel uit van {_part_of_walking_routes}",

View File

@ -13,6 +13,9 @@ Utils.runningFromConsole = true;
function generateLicenseInfos(paths: string[]): SmallLicense[] {
const licenses = []
for (const path of paths) {
try{
const parsed = JSON.parse(readFileSync(path, "UTF-8"))
if (Array.isArray(parsed)) {
const l: SmallLicense[] = parsed
@ -30,6 +33,8 @@ function generateLicenseInfos(paths: string[]): SmallLicense[] {
smallLicens.path = path.substring(0, 1 + path.lastIndexOf("/")) + smallLicens.path
licenses.push(smallLicens)
}}catch(e){
console.error("Error: ",e, "while handling",path)
}
}