Many UI improvements

This commit is contained in:
Pieter Vander Vennet 2024-06-18 03:33:11 +02:00
parent ef158ec914
commit 1098d71aa6
30 changed files with 5601 additions and 569 deletions

View file

@ -10,16 +10,12 @@ import {
PrevalidateTheme,
ValidateLayer,
ValidateThemeAndLayers,
ValidateThemeEnsemble,
ValidateThemeEnsemble
} from "../src/Models/ThemeConfig/Conversion/Validation"
import { Translation } from "../src/UI/i18n/Translation"
import { PrepareLayer } from "../src/Models/ThemeConfig/Conversion/PrepareLayer"
import { PrepareTheme } from "../src/Models/ThemeConfig/Conversion/PrepareTheme"
import {
Conversion,
DesugaringContext,
DesugaringStep,
} from "../src/Models/ThemeConfig/Conversion/Conversion"
import { Conversion, DesugaringContext, DesugaringStep } from "../src/Models/ThemeConfig/Conversion/Conversion"
import { Utils } from "../src/Utils"
import Script from "./Script"
import { AllSharedLayers } from "../src/Customizations/AllSharedLayers"
@ -44,7 +40,6 @@ class ParseLayer extends Conversion<
> {
private readonly _prepareLayer: PrepareLayer
private readonly _doesImageExist: DoesImageExist
private readonly _options: { readonly addExpandedTagRenderingsToContext?: boolean }
constructor(prepareLayer: PrepareLayer, doesImageExist: DoesImageExist) {
super("Parsed a layer from file, validates it", [], "ParseLayer")
@ -104,7 +99,7 @@ class AddIconSummary extends DesugaringStep<{ raw: LayerConfigJson; parsed: Laye
super("Adds an icon summary for quick reference", ["_layerIcon"], "AddIconSummary")
}
convert(json: { raw: LayerConfigJson; parsed: LayerConfig }, context: ConversionContext) {
convert(json: { raw: LayerConfigJson; parsed: LayerConfig }) {
// Add a summary of the icon
const fixed = json.raw
const layerConfig = json.parsed
@ -148,7 +143,7 @@ class LayerOverviewUtils extends Script {
themeFile: LayoutConfigJson,
includeInlineLayers = true
): string[] {
const publicLayerIds = []
const publicLayerIds: string[] = []
if (!Array.isArray(themeFile.layers)) {
throw (
"Cannot iterate over 'layers' of " +
@ -163,12 +158,12 @@ class LayerOverviewUtils extends Script {
continue
}
if (publicLayer["builtin"] !== undefined) {
const bi = publicLayer["builtin"]
const bi : string | string[] = publicLayer["builtin"]
if (typeof bi === "string") {
publicLayerIds.push(bi)
continue
} else {
bi.forEach(id => publicLayerIds.push(id))
}
bi.forEach((id) => publicLayerIds.push(id))
continue
}
if (includeInlineLayers) {
@ -209,9 +204,9 @@ class LayerOverviewUtils extends Script {
| LayerConfigJson
| string
| {
builtin
}
)[]
builtin
}
)[]
}[]
) {
const perId = new Map<string, any>()
@ -231,7 +226,7 @@ class LayerOverviewUtils extends Script {
icon: theme.icon,
hideFromOverview: theme.hideFromOverview,
mustHaveLanguage: theme.mustHaveLanguage,
keywords: Utils.NoNull(keywords),
keywords: Utils.NoNull(keywords)
}
perId.set(theme.id, data)
}
@ -280,18 +275,36 @@ class LayerOverviewUtils extends Script {
)
}
static asDict(trs: QuestionableTagRenderingConfigJson[]): Map<string, QuestionableTagRenderingConfigJson> {
const d = new Map<string, QuestionableTagRenderingConfigJson>()
for (const tr of trs) {
d.set(tr.id, tr)
}
return d
}
getSharedTagRenderings(
doesImageExist: DoesImageExist
): QuestionableTagRenderingConfigJson[] ;
getSharedTagRenderings(
doesImageExist: DoesImageExist,
bootstrapTagRenderings: Map<string, QuestionableTagRenderingConfigJson> = null
): Map<string, QuestionableTagRenderingConfigJson> {
bootstrapTagRenderings: Map<string, QuestionableTagRenderingConfigJson>,
bootstrapTagRenderingsOrder: string[]
): QuestionableTagRenderingConfigJson[] ;
getSharedTagRenderings(
doesImageExist: DoesImageExist,
bootstrapTagRenderings: Map<string, QuestionableTagRenderingConfigJson> = null,
bootstrapTagRenderingsOrder: string[] = []
): QuestionableTagRenderingConfigJson[] {
const prepareLayer = new PrepareLayer(
{
tagRenderings: bootstrapTagRenderings,
tagRenderingOrder: bootstrapTagRenderingsOrder,
sharedLayers: null,
publicLayers: null,
publicLayers: null
},
{
addTagRenderingsToContext: true,
addTagRenderingsToContext: true
}
)
@ -306,10 +319,10 @@ class LayerOverviewUtils extends Script {
}
if (dict.size === bootstrapTagRenderings?.size) {
return dict
return <QuestionableTagRenderingConfigJson[]>sharedQuestions.tagRenderings
}
return this.getSharedTagRenderings(doesImageExist, dict)
return this.getSharedTagRenderings(doesImageExist, dict, sharedQuestions.tagRenderings.map(tr => tr["id"]))
}
checkAllSvgs() {
@ -323,7 +336,7 @@ class LayerOverviewUtils extends Script {
"src/assets/SocialImageBanner.svg",
"src/assets/SocialImageRepo.svg",
"src/assets/svg/osm-logo.svg",
"src/assets/templates/*",
"src/assets/templates/*"
]
for (const path of allSvgs) {
if (
@ -348,8 +361,8 @@ class LayerOverviewUtils extends Script {
if (contents.indexOf("<text") > 0) {
console.warn(
"The SVG at " +
path +
" contains a `text`-tag. This is highly discouraged. Every machine viewing your theme has their own font libary, and the font you choose might not be present, resulting in a different font being rendered. Solution: open your .svg in inkscape (or another program), select the text and convert it to a path"
path +
" contains a `text`-tag. This is highly discouraged. Every machine viewing your theme has their own font libary, and the font you choose might not be present, resulting in a different font being rendered. Solution: open your .svg in inkscape (or another program), select the text and convert it to a path"
)
errCount++
}
@ -412,7 +425,7 @@ class LayerOverviewUtils extends Script {
writeFileSync(
"./src/assets/generated/known_layers.json",
JSON.stringify({
layers: Array.from(sharedLayers.values()).filter((l) => l.id !== "favourite"),
layers: Array.from(sharedLayers.values()).filter((l) => l.id !== "favourite")
})
)
}
@ -429,11 +442,11 @@ class LayerOverviewUtils extends Script {
// mapcomplete-changes shows an icon for each corresponding mapcomplete-theme
const iconsPerTheme = Array.from(sharedThemes.values()).map((th) => ({
if: "theme=" + th.id,
then: th.icon,
then: th.icon
}))
const proto: LayoutConfigJson = JSON.parse(
readFileSync("./assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json", {
encoding: "utf8",
encoding: "utf8"
})
)
const protolayer = <LayerConfigJson>(
@ -449,7 +462,7 @@ class LayerOverviewUtils extends Script {
new DetectDuplicateFilters().convertStrict(
{
layers: ScriptUtils.getLayerFiles().map((f) => f.parsed),
themes: ScriptUtils.getThemeFiles().map((f) => f.parsed),
themes: ScriptUtils.getThemeFiles().map((f) => f.parsed)
},
ConversionContext.construct([], [])
)
@ -464,7 +477,7 @@ class LayerOverviewUtils extends Script {
writeFileSync(
"./src/assets/generated/known_themes.json",
JSON.stringify({
themes: Array.from(sharedThemes.values()),
themes: Array.from(sharedThemes.values())
})
)
}
@ -505,8 +518,9 @@ class LayerOverviewUtils extends Script {
console.log("Shared questions are:", Array.from(sharedTagRenderings.keys()).join(", "))
console.log(" ---------- VALIDATING BUILTIN LAYERS ---------")
const state: DesugaringContext = {
tagRenderings: sharedTagRenderings,
sharedLayers: AllSharedLayers.getSharedLayersConfigs(),
tagRenderings: LayerOverviewUtils.asDict(sharedTagRenderings),
tagRenderingOrder: sharedTagRenderings.map(tr => tr.id),
sharedLayers: AllSharedLayers.getSharedLayersConfigs()
}
const sharedLayers = new Map<string, LayerConfigJson>()
const prepLayer = new PrepareLayer(state)
@ -551,12 +565,12 @@ class LayerOverviewUtils extends Script {
console.log(
"Recompiled layers " +
recompiledLayers.join(", ") +
" and skipped " +
skippedLayers.length +
" layers. Detected " +
warningCount +
" warnings"
recompiledLayers.join(", ") +
" and skipped " +
skippedLayers.length +
" layers. Detected " +
warningCount +
" warnings"
)
// We always need the calculated tags of 'usersettings', so we export them separately
this.extractJavascriptCodeForLayer(
@ -578,11 +592,11 @@ class LayerOverviewUtils extends Script {
private extractJavascriptCode(themeFile: LayoutConfigJson) {
const allCode = [
"import {Feature} from 'geojson'",
'import { ExtraFuncType } from "../../../Logic/ExtraFunctions";',
'import { Utils } from "../../../Utils"',
"import { ExtraFuncType } from \"../../../Logic/ExtraFunctions\";",
"import { Utils } from \"../../../Utils\"",
"export class ThemeMetaTagging {",
" public static readonly themeName = " + JSON.stringify(themeFile.id),
"",
""
]
for (const layer of themeFile.layers) {
const l = <LayerConfigJson>layer
@ -591,8 +605,8 @@ class LayerOverviewUtils extends Script {
allCode.push(
" public metaTaggging_for_" +
id +
"(feat: Feature, helperFunctions: Record<ExtraFuncType, (feature: Feature) => Function>) {"
id +
"(feat: Feature, helperFunctions: Record<ExtraFuncType, (feature: Feature) => Function>) {"
)
allCode.push(" const {" + ExtraFunctions.types.join(", ") + "} = helperFunctions")
for (const line of code) {
@ -603,10 +617,10 @@ class LayerOverviewUtils extends Script {
if (!isStrict) {
allCode.push(
" Utils.AddLazyProperty(feat.properties, '" +
attributeName +
"', () => " +
expression +
" ) "
attributeName +
"', () => " +
expression +
" ) "
)
} else {
attributeName = attributeName.substring(0, attributeName.length - 1).trim()
@ -646,7 +660,7 @@ class LayerOverviewUtils extends Script {
`/** This code is autogenerated - do not edit. Edit ./assets/layers/${l?.id}/${l?.id}.json instead */`,
"export class ThemeMetaTagging {",
" public static readonly themeName = " + JSON.stringify(l.id),
"",
""
]
const code = l.calculatedTags ?? []
@ -661,10 +675,10 @@ class LayerOverviewUtils extends Script {
if (!isStrict) {
allCode.push(
" Utils.AddLazyProperty(feat.properties, '" +
attributeName +
"', () => " +
expression +
" ) "
attributeName +
"', () => " +
expression +
" ) "
)
} else {
attributeName = attributeName.substring(0, attributeName.length - 2).trim()
@ -699,12 +713,15 @@ class LayerOverviewUtils extends Script {
themeFiles.map((th) => th.parsed)
)
const trs = this.getSharedTagRenderings(
new DoesImageExist(licensePaths, existsSync)
)
const convertState: DesugaringContext = {
sharedLayers,
tagRenderings: this.getSharedTagRenderings(
new DoesImageExist(licensePaths, existsSync)
),
publicLayers,
tagRenderings: LayerOverviewUtils.asDict(trs),
tagRenderingOrder: trs.map(tr => tr.id),
publicLayers
}
const knownTagRenderings = new Set<string>()
convertState.tagRenderings.forEach((_, key) => knownTagRenderings.add(key))
@ -758,7 +775,7 @@ class LayerOverviewUtils extends Script {
)
try {
themeFile = new PrepareTheme(convertState, {
skipDefaultLayers: true,
skipDefaultLayers: true
}).convertStrict(
themeFile,
ConversionContext.construct([themePath], ["PrepareLayer"])
@ -776,8 +793,8 @@ class LayerOverviewUtils extends Script {
if (themeFile.icon.endsWith(".svg")) {
try {
ScriptUtils.ReadSvgSync(themeFile.icon, (svg) => {
const width: string = svg.$.width
const height: string = svg.$.height
const width: string = svg["$"].width
const height: string = svg["$"].height
const err = themeFile.hideFromOverview ? console.warn : console.error
if (width !== height) {
const e =
@ -792,7 +809,7 @@ class LayerOverviewUtils extends Script {
const e: string = [
`the icon for theme ${themeFile.id} is too small. Please rescale the icon at ${themeFile.icon}`,
`Even though an SVG is 'infinitely scaleable', the icon should be dimensioned bigger. One of the build steps of the theme does convert the image to a PNG (to serve as PWA-icon) and having a small dimension will cause blurry images.`,
` Width = ${width} height = ${height}; we recommend a size of at least 500px * 500px and to use a square aspect ratio.`,
` Width = ${width} height = ${height}; we recommend a size of at least 500px * 500px and to use a square aspect ratio.`
].join("\n")
err(e)
}
@ -823,7 +840,7 @@ class LayerOverviewUtils extends Script {
new Translation(t.description)
.FirstSentence()
.OnEveryLanguage((s) => parse_html(s).textContent).translations,
mustHaveLanguage: t.mustHaveLanguage?.length > 0,
mustHaveLanguage: t.mustHaveLanguage?.length > 0
}
})
)
@ -831,10 +848,10 @@ class LayerOverviewUtils extends Script {
console.log(
"Recompiled themes " +
recompiledThemes.join(", ") +
" and skipped " +
skippedThemes.length +
" themes"
recompiledThemes.join(", ") +
" and skipped " +
skippedThemes.length +
" themes"
)
return fixed