Remove images in overview, fix #2007

This commit is contained in:
Pieter Vander Vennet 2024-07-08 23:35:40 +02:00
parent eb184ed882
commit c8b87e92f7

View file

@ -31,6 +31,8 @@ import PointRenderingConfig from "../src/Models/ThemeConfig/PointRenderingConfig
import { ConversionContext } from "../src/Models/ThemeConfig/Conversion/ConversionContext" import { ConversionContext } from "../src/Models/ThemeConfig/Conversion/ConversionContext"
import { GenerateFavouritesLayer } from "./generateFavouritesLayer" import { GenerateFavouritesLayer } from "./generateFavouritesLayer"
import LayoutConfig from "../src/Models/ThemeConfig/LayoutConfig" import LayoutConfig from "../src/Models/ThemeConfig/LayoutConfig"
import Translations from "../src/UI/i18n/Translations"
import { Translatable } from "../src/Models/ThemeConfig/Json/Translatable"
// This scripts scans 'src/assets/layers/*.json' for layer definition files and 'src/assets/themes/*.json' for theme definition files. // This scripts scans 'src/assets/layers/*.json' for layer definition files and 'src/assets/themes/*.json' for theme definition files.
// It spits out an overview of those to be used to load them // It spits out an overview of those to be used to load them
@ -53,7 +55,7 @@ class ParseLayer extends Conversion<
convert( convert(
path: string, path: string,
context: ConversionContext context: ConversionContext,
): { ): {
parsed: LayerConfig parsed: LayerConfig
raw: LayerConfigJson raw: LayerConfigJson
@ -108,7 +110,7 @@ class AddIconSummary extends DesugaringStep<{ raw: LayerConfigJson; parsed: Laye
const fixed = json.raw const fixed = json.raw
const layerConfig = json.parsed const layerConfig = json.parsed
const pointRendering: PointRenderingConfig = layerConfig.mapRendering.find((pr) => const pointRendering: PointRenderingConfig = layerConfig.mapRendering.find((pr) =>
pr.location.has("point") pr.location.has("point"),
) )
const defaultTags = layerConfig.GetBaseTags() const defaultTags = layerConfig.GetBaseTags()
fixed["_layerIcon"] = Utils.NoNull( fixed["_layerIcon"] = Utils.NoNull(
@ -123,7 +125,7 @@ class AddIconSummary extends DesugaringStep<{ raw: LayerConfigJson; parsed: Laye
result["color"] = c result["color"] = c
} }
return result return result
}) }),
) )
return { raw: fixed, parsed: layerConfig } return { raw: fixed, parsed: layerConfig }
} }
@ -145,7 +147,7 @@ class LayerOverviewUtils extends Script {
private static extractLayerIdsFrom( private static extractLayerIdsFrom(
themeFile: LayoutConfigJson, themeFile: LayoutConfigJson,
includeInlineLayers = true includeInlineLayers = true,
): string[] { ): string[] {
const publicLayerIds: string[] = [] const publicLayerIds: string[] = []
if (!Array.isArray(themeFile.layers)) { if (!Array.isArray(themeFile.layers)) {
@ -177,6 +179,10 @@ class LayerOverviewUtils extends Script {
return publicLayerIds return publicLayerIds
} }
public static cleanTranslation(t: Record<string, string> | Translation): Translatable {
return Translations.T(t).OnEveryLanguage((s) => parse_html(s).textContent).translations
}
shouldBeUpdated(sourcefile: string | string[], targetfile: string): boolean { shouldBeUpdated(sourcefile: string | string[], targetfile: string): boolean {
if (!existsSync(targetfile)) { if (!existsSync(targetfile)) {
return true return true
@ -208,10 +214,10 @@ class LayerOverviewUtils extends Script {
| LayerConfigJson | LayerConfigJson
| string | string
| { | {
builtin builtin
} }
)[] )[]
}[] }[],
) { ) {
const perId = new Map<string, any>() const perId = new Map<string, any>()
for (const theme of themes) { for (const theme of themes) {
@ -226,7 +232,7 @@ class LayerOverviewUtils extends Script {
const data = { const data = {
id: theme.id, id: theme.id,
title: theme.title, title: theme.title,
shortDescription: theme.shortDescription, shortDescription: LayerOverviewUtils.cleanTranslation(theme.shortDescription),
icon: theme.icon, icon: theme.icon,
hideFromOverview: theme.hideFromOverview, hideFromOverview: theme.hideFromOverview,
mustHaveLanguage: theme.mustHaveLanguage, mustHaveLanguage: theme.mustHaveLanguage,
@ -252,7 +258,7 @@ class LayerOverviewUtils extends Script {
writeFileSync( writeFileSync(
"./src/assets/generated/theme_overview.json", "./src/assets/generated/theme_overview.json",
JSON.stringify(sorted, null, " "), JSON.stringify(sorted, null, " "),
{ encoding: "utf8" } { encoding: "utf8" },
) )
} }
@ -264,7 +270,7 @@ class LayerOverviewUtils extends Script {
writeFileSync( writeFileSync(
`${LayerOverviewUtils.themePath}${theme.id}.json`, `${LayerOverviewUtils.themePath}${theme.id}.json`,
JSON.stringify(theme, null, " "), JSON.stringify(theme, null, " "),
{ encoding: "utf8" } { encoding: "utf8" },
) )
} }
@ -275,12 +281,12 @@ class LayerOverviewUtils extends Script {
writeFileSync( writeFileSync(
`${LayerOverviewUtils.layerPath}${layer.id}.json`, `${LayerOverviewUtils.layerPath}${layer.id}.json`,
JSON.stringify(layer, null, " "), JSON.stringify(layer, null, " "),
{ encoding: "utf8" } { encoding: "utf8" },
) )
} }
static asDict( static asDict(
trs: QuestionableTagRenderingConfigJson[] trs: QuestionableTagRenderingConfigJson[],
): Map<string, QuestionableTagRenderingConfigJson> { ): Map<string, QuestionableTagRenderingConfigJson> {
const d = new Map<string, QuestionableTagRenderingConfigJson>() const d = new Map<string, QuestionableTagRenderingConfigJson>()
for (const tr of trs) { for (const tr of trs) {
@ -293,12 +299,12 @@ class LayerOverviewUtils extends Script {
getSharedTagRenderings( getSharedTagRenderings(
doesImageExist: DoesImageExist, doesImageExist: DoesImageExist,
bootstrapTagRenderings: Map<string, QuestionableTagRenderingConfigJson>, bootstrapTagRenderings: Map<string, QuestionableTagRenderingConfigJson>,
bootstrapTagRenderingsOrder: string[] bootstrapTagRenderingsOrder: string[],
): QuestionableTagRenderingConfigJson[] ): QuestionableTagRenderingConfigJson[]
getSharedTagRenderings( getSharedTagRenderings(
doesImageExist: DoesImageExist, doesImageExist: DoesImageExist,
bootstrapTagRenderings: Map<string, QuestionableTagRenderingConfigJson> = null, bootstrapTagRenderings: Map<string, QuestionableTagRenderingConfigJson> = null,
bootstrapTagRenderingsOrder: string[] = [] bootstrapTagRenderingsOrder: string[] = [],
): QuestionableTagRenderingConfigJson[] { ): QuestionableTagRenderingConfigJson[] {
const prepareLayer = new PrepareLayer( const prepareLayer = new PrepareLayer(
{ {
@ -309,7 +315,7 @@ class LayerOverviewUtils extends Script {
}, },
{ {
addTagRenderingsToContext: true, addTagRenderingsToContext: true,
} },
) )
const path = "assets/layers/questions/questions.json" const path = "assets/layers/questions/questions.json"
@ -329,7 +335,7 @@ class LayerOverviewUtils extends Script {
return this.getSharedTagRenderings( return this.getSharedTagRenderings(
doesImageExist, doesImageExist,
dict, dict,
sharedQuestions.tagRenderings.map((tr) => tr["id"]) sharedQuestions.tagRenderings.map((tr) => tr["id"]),
) )
} }
@ -369,8 +375,8 @@ class LayerOverviewUtils extends Script {
if (contents.indexOf("<text") > 0) { if (contents.indexOf("<text") > 0) {
console.warn( console.warn(
"The SVG at " + "The SVG at " +
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" " 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++ errCount++
} }
@ -386,14 +392,14 @@ class LayerOverviewUtils extends Script {
args args
.find((a) => a.startsWith("--themes=")) .find((a) => a.startsWith("--themes="))
?.substring("--themes=".length) ?.substring("--themes=".length)
?.split(",") ?? [] ?.split(",") ?? [],
) )
const layerWhitelist = new Set( const layerWhitelist = new Set(
args args
.find((a) => a.startsWith("--layers=")) .find((a) => a.startsWith("--layers="))
?.substring("--layers=".length) ?.substring("--layers=".length)
?.split(",") ?? [] ?.split(",") ?? [],
) )
const forceReload = args.some((a) => a == "--force") const forceReload = args.some((a) => a == "--force")
@ -422,11 +428,11 @@ class LayerOverviewUtils extends Script {
sharedLayers, sharedLayers,
recompiledThemes, recompiledThemes,
forceReload, forceReload,
themeWhitelist themeWhitelist,
) )
new ValidateThemeEnsemble().convertStrict( new ValidateThemeEnsemble().convertStrict(
Array.from(sharedThemes.values()).map((th) => new LayoutConfig(th, true)) Array.from(sharedThemes.values()).map((th) => new LayoutConfig(th, true)),
) )
if (recompiledThemes.length > 0) { if (recompiledThemes.length > 0) {
@ -434,7 +440,7 @@ class LayerOverviewUtils extends Script {
"./src/assets/generated/known_layers.json", "./src/assets/generated/known_layers.json",
JSON.stringify({ JSON.stringify({
layers: Array.from(sharedLayers.values()).filter((l) => l.id !== "favourite"), layers: Array.from(sharedLayers.values()).filter((l) => l.id !== "favourite"),
}) }),
) )
} }
@ -455,7 +461,7 @@ class LayerOverviewUtils extends Script {
const proto: LayoutConfigJson = JSON.parse( const proto: LayoutConfigJson = JSON.parse(
readFileSync("./assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json", { readFileSync("./assets/themes/mapcomplete-changes/mapcomplete-changes.proto.json", {
encoding: "utf8", encoding: "utf8",
}) }),
) )
const protolayer = <LayerConfigJson>( const protolayer = <LayerConfigJson>(
proto.layers.filter((l) => l["id"] === "mapcomplete-changes")[0] proto.layers.filter((l) => l["id"] === "mapcomplete-changes")[0]
@ -472,12 +478,12 @@ class LayerOverviewUtils extends Script {
layers: ScriptUtils.getLayerFiles().map((f) => f.parsed), layers: ScriptUtils.getLayerFiles().map((f) => f.parsed),
themes: ScriptUtils.getThemeFiles().map((f) => f.parsed), themes: ScriptUtils.getThemeFiles().map((f) => f.parsed),
}, },
ConversionContext.construct([], []) ConversionContext.construct([], []),
) )
for (const [_, theme] of sharedThemes) { for (const [_, theme] of sharedThemes) {
theme.layers = theme.layers.filter( theme.layers = theme.layers.filter(
(l) => Constants.added_by_default.indexOf(l["id"]) < 0 (l) => Constants.added_by_default.indexOf(l["id"]) < 0,
) )
} }
@ -486,7 +492,7 @@ class LayerOverviewUtils extends Script {
"./src/assets/generated/known_themes.json", "./src/assets/generated/known_themes.json",
JSON.stringify({ JSON.stringify({
themes: Array.from(sharedThemes.values()), themes: Array.from(sharedThemes.values()),
}) }),
) )
} }
@ -498,7 +504,7 @@ class LayerOverviewUtils extends Script {
private parseLayer( private parseLayer(
doesImageExist: DoesImageExist, doesImageExist: DoesImageExist,
prepLayer: PrepareLayer, prepLayer: PrepareLayer,
sharedLayerPath: string sharedLayerPath: string,
): { ): {
raw: LayerConfigJson raw: LayerConfigJson
parsed: LayerConfig parsed: LayerConfig
@ -509,7 +515,7 @@ class LayerOverviewUtils extends Script {
const parsed = parser.convertStrict(sharedLayerPath, context) const parsed = parser.convertStrict(sharedLayerPath, context)
const result = AddIconSummary.singleton.convertStrict( const result = AddIconSummary.singleton.convertStrict(
parsed, parsed,
context.inOperation("AddIconSummary") context.inOperation("AddIconSummary"),
) )
return { ...result, context } return { ...result, context }
} }
@ -517,7 +523,7 @@ class LayerOverviewUtils extends Script {
private buildLayerIndex( private buildLayerIndex(
doesImageExist: DoesImageExist, doesImageExist: DoesImageExist,
forceReload: boolean, forceReload: boolean,
whitelist: Set<string> whitelist: Set<string>,
): Map<string, LayerConfigJson> { ): Map<string, LayerConfigJson> {
// First, we expand and validate all builtin layers. These are written to src/assets/generated/layers // First, we expand and validate all builtin layers. These are written to src/assets/generated/layers
// At the same time, an index of available layers is built. // At the same time, an index of available layers is built.
@ -572,17 +578,17 @@ class LayerOverviewUtils extends Script {
console.log( console.log(
"Recompiled layers " + "Recompiled layers " +
recompiledLayers.join(", ") + recompiledLayers.join(", ") +
" and skipped " + " and skipped " +
skippedLayers.length + skippedLayers.length +
" layers. Detected " + " layers. Detected " +
warningCount + warningCount +
" warnings" " warnings",
) )
// We always need the calculated tags of 'usersettings', so we export them separately // We always need the calculated tags of 'usersettings', so we export them separately
this.extractJavascriptCodeForLayer( this.extractJavascriptCodeForLayer(
state.sharedLayers.get("usersettings"), state.sharedLayers.get("usersettings"),
"./src/Logic/State/UserSettingsMetaTagging.ts" "./src/Logic/State/UserSettingsMetaTagging.ts",
) )
return sharedLayers return sharedLayers
@ -599,8 +605,8 @@ class LayerOverviewUtils extends Script {
private extractJavascriptCode(themeFile: LayoutConfigJson) { private extractJavascriptCode(themeFile: LayoutConfigJson) {
const allCode = [ const allCode = [
"import {Feature} from 'geojson'", "import {Feature} from 'geojson'",
'import { ExtraFuncType } from "../../../Logic/ExtraFunctions";', "import { ExtraFuncType } from \"../../../Logic/ExtraFunctions\";",
'import { Utils } from "../../../Utils"', "import { Utils } from \"../../../Utils\"",
"export class ThemeMetaTagging {", "export class ThemeMetaTagging {",
" public static readonly themeName = " + JSON.stringify(themeFile.id), " public static readonly themeName = " + JSON.stringify(themeFile.id),
"", "",
@ -612,8 +618,8 @@ class LayerOverviewUtils extends Script {
allCode.push( allCode.push(
" public metaTaggging_for_" + " public metaTaggging_for_" +
id + id +
"(feat: Feature, helperFunctions: Record<ExtraFuncType, (feature: Feature) => Function>) {" "(feat: Feature, helperFunctions: Record<ExtraFuncType, (feature: Feature) => Function>) {",
) )
allCode.push(" const {" + ExtraFunctions.types.join(", ") + "} = helperFunctions") allCode.push(" const {" + ExtraFunctions.types.join(", ") + "} = helperFunctions")
for (const line of code) { for (const line of code) {
@ -624,10 +630,10 @@ class LayerOverviewUtils extends Script {
if (!isStrict) { if (!isStrict) {
allCode.push( allCode.push(
" Utils.AddLazyProperty(feat.properties, '" + " Utils.AddLazyProperty(feat.properties, '" +
attributeName + attributeName +
"', () => " + "', () => " +
expression + expression +
" ) " " ) ",
) )
} else { } else {
attributeName = attributeName.substring(0, attributeName.length - 1).trim() attributeName = attributeName.substring(0, attributeName.length - 1).trim()
@ -672,7 +678,7 @@ class LayerOverviewUtils extends Script {
const code = l.calculatedTags ?? [] const code = l.calculatedTags ?? []
allCode.push( allCode.push(
" public metaTaggging_for_" + l.id + "(feat: {properties: Record<string, string>}) {" " public metaTaggging_for_" + l.id + "(feat: {properties: Record<string, string>}) {",
) )
for (const line of code) { for (const line of code) {
const firstEq = line.indexOf("=") const firstEq = line.indexOf("=")
@ -682,10 +688,10 @@ class LayerOverviewUtils extends Script {
if (!isStrict) { if (!isStrict) {
allCode.push( allCode.push(
" Utils.AddLazyProperty(feat.properties, '" + " Utils.AddLazyProperty(feat.properties, '" +
attributeName + attributeName +
"', () => " + "', () => " +
expression + expression +
" ) " " ) ",
) )
} else { } else {
attributeName = attributeName.substring(0, attributeName.length - 2).trim() attributeName = attributeName.substring(0, attributeName.length - 2).trim()
@ -710,14 +716,14 @@ class LayerOverviewUtils extends Script {
sharedLayers: Map<string, LayerConfigJson>, sharedLayers: Map<string, LayerConfigJson>,
recompiledThemes: string[], recompiledThemes: string[],
forceReload: boolean, forceReload: boolean,
whitelist: Set<string> whitelist: Set<string>,
): Map<string, LayoutConfigJson> { ): Map<string, LayoutConfigJson> {
console.log(" ---------- VALIDATING BUILTIN THEMES ---------") console.log(" ---------- VALIDATING BUILTIN THEMES ---------")
const themeFiles = ScriptUtils.getThemeFiles() const themeFiles = ScriptUtils.getThemeFiles()
const fixed = new Map<string, LayoutConfigJson>() const fixed = new Map<string, LayoutConfigJson>()
const publicLayers = LayerOverviewUtils.publicLayerIdsFrom( const publicLayers = LayerOverviewUtils.publicLayerIdsFrom(
themeFiles.map((th) => th.parsed) themeFiles.map((th) => th.parsed),
) )
const trs = this.getSharedTagRenderings(new DoesImageExist(licensePaths, existsSync)) const trs = this.getSharedTagRenderings(new DoesImageExist(licensePaths, existsSync))
@ -757,15 +763,15 @@ class LayerOverviewUtils extends Script {
LayerOverviewUtils.themePath + "/" + themePath.substring(themePath.lastIndexOf("/")) LayerOverviewUtils.themePath + "/" + themePath.substring(themePath.lastIndexOf("/"))
const usedLayers = Array.from( const usedLayers = Array.from(
LayerOverviewUtils.extractLayerIdsFrom(themeFile, false) LayerOverviewUtils.extractLayerIdsFrom(themeFile, false),
).map((id) => LayerOverviewUtils.layerPath + id + ".json") ).map((id) => LayerOverviewUtils.layerPath + id + ".json")
if (!forceReload && !this.shouldBeUpdated([themePath, ...usedLayers], targetPath)) { if (!forceReload && !this.shouldBeUpdated([themePath, ...usedLayers], targetPath)) {
fixed.set( fixed.set(
themeFile.id, themeFile.id,
JSON.parse( JSON.parse(
readFileSync(LayerOverviewUtils.themePath + themeFile.id + ".json", "utf8") readFileSync(LayerOverviewUtils.themePath + themeFile.id + ".json", "utf8"),
) ),
) )
ScriptUtils.erasableLog("Skipping", themeFile.id) ScriptUtils.erasableLog("Skipping", themeFile.id)
skippedThemes.push(themeFile.id) skippedThemes.push(themeFile.id)
@ -776,23 +782,23 @@ class LayerOverviewUtils extends Script {
new PrevalidateTheme().convertStrict( new PrevalidateTheme().convertStrict(
themeFile, themeFile,
ConversionContext.construct([themePath], ["PrepareLayer"]) ConversionContext.construct([themePath], ["PrepareLayer"]),
) )
try { try {
themeFile = new PrepareTheme(convertState, { themeFile = new PrepareTheme(convertState, {
skipDefaultLayers: true, skipDefaultLayers: true,
}).convertStrict( }).convertStrict(
themeFile, themeFile,
ConversionContext.construct([themePath], ["PrepareLayer"]) ConversionContext.construct([themePath], ["PrepareLayer"]),
) )
new ValidateThemeAndLayers( new ValidateThemeAndLayers(
new DoesImageExist(licensePaths, existsSync, knownTagRenderings), new DoesImageExist(licensePaths, existsSync, knownTagRenderings),
themePath, themePath,
true, true,
knownTagRenderings knownTagRenderings,
).convertStrict( ).convertStrict(
themeFile, themeFile,
ConversionContext.construct([themePath], ["PrepareLayer"]) ConversionContext.construct([themePath], ["PrepareLayer"]),
) )
if (themeFile.icon.endsWith(".svg")) { if (themeFile.icon.endsWith(".svg")) {
@ -841,22 +847,19 @@ class LayerOverviewUtils extends Script {
...t, ...t,
hideFromOverview: t.hideFromOverview ?? false, hideFromOverview: t.hideFromOverview ?? false,
shortDescription: shortDescription:
t.shortDescription ?? t.shortDescription ?? new Translation(t.description).FirstSentence(),
new Translation(t.description)
.FirstSentence()
.OnEveryLanguage((s) => parse_html(s).textContent).translations,
mustHaveLanguage: t.mustHaveLanguage?.length > 0, mustHaveLanguage: t.mustHaveLanguage?.length > 0,
} }
}) }),
) )
} }
console.log( console.log(
"Recompiled themes " + "Recompiled themes " +
recompiledThemes.join(", ") + recompiledThemes.join(", ") +
" and skipped " + " and skipped " +
skippedThemes.length + skippedThemes.length +
" themes" " themes",
) )
return fixed return fixed