forked from MapComplete/MapComplete
Feat: remove possibility to load a custom theme via the hash, no longer necessary with a theme server
This commit is contained in:
parent
9bf013cd47
commit
a016a8f771
2 changed files with 2 additions and 177 deletions
|
@ -3,8 +3,6 @@ import { QueryParameters } from "./Web/QueryParameters"
|
||||||
import { AllKnownLayouts } from "../Customizations/AllKnownLayouts"
|
import { AllKnownLayouts } from "../Customizations/AllKnownLayouts"
|
||||||
import { FixedUiElement } from "../UI/Base/FixedUiElement"
|
import { FixedUiElement } from "../UI/Base/FixedUiElement"
|
||||||
import { Utils } from "../Utils"
|
import { Utils } from "../Utils"
|
||||||
import { UIEventSource } from "./UIEventSource"
|
|
||||||
import { LocalStorageSource } from "./Web/LocalStorageSource"
|
|
||||||
import LZString from "lz-string"
|
import LZString from "lz-string"
|
||||||
import { FixLegacyTheme } from "../Models/ThemeConfig/Conversion/LegacyJsonConvert"
|
import { FixLegacyTheme } from "../Models/ThemeConfig/Conversion/LegacyJsonConvert"
|
||||||
import { LayerConfigJson } from "../Models/ThemeConfig/Json/LayerConfigJson"
|
import { LayerConfigJson } from "../Models/ThemeConfig/Json/LayerConfigJson"
|
||||||
|
@ -27,7 +25,7 @@ export default class DetermineTheme {
|
||||||
private static readonly loadCustomThemeParam = QueryParameters.GetQueryParameter(
|
private static readonly loadCustomThemeParam = QueryParameters.GetQueryParameter(
|
||||||
"userlayout",
|
"userlayout",
|
||||||
"false",
|
"false",
|
||||||
"If not 'false', a custom (non-official) theme is loaded. This custom layout can be done in multiple ways: \n\n- The hash of the URL contains a base64-encoded .json-file containing the theme definition\n- The hash of the URL contains a lz-compressed .json-file, as generated by the custom theme generator\n- The parameter itself is an URL, in which case that URL will be downloaded. It should point to a .json of a theme"
|
"If the parameter is an URL, it should point to a .json of a theme which will be loaded and used"
|
||||||
)
|
)
|
||||||
|
|
||||||
public static getCustomDefinition(): string {
|
public static getCustomDefinition(): string {
|
||||||
|
@ -37,18 +35,6 @@ export default class DetermineTheme {
|
||||||
return layoutFromBase64
|
return layoutFromBase64
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layoutFromBase64 !== "false") {
|
|
||||||
// We have to load something from the hash (or from disk)
|
|
||||||
const hash = Hash.hash.data
|
|
||||||
try {
|
|
||||||
JSON.parse(atob(hash))
|
|
||||||
return atob(hash)
|
|
||||||
} catch (e) {
|
|
||||||
// We try to decode with lz-string
|
|
||||||
JSON.parse(Utils.UnMinify(LZString.decompressFromBase64(hash)))
|
|
||||||
return Utils.UnMinify(LZString.decompressFromBase64(hash))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +53,7 @@ export default class DetermineTheme {
|
||||||
try {
|
try {
|
||||||
new URL(l)
|
new URL(l)
|
||||||
console.log("Downloading remote layer " + l)
|
console.log("Downloading remote layer " + l)
|
||||||
const layerConfig = <LayerConfigJson>await Utils.downloadJson(l)
|
layoutConfig.layers[i] = <LayerConfigJson>await Utils.downloadJson(l)
|
||||||
layoutConfig.layers[i] = layerConfig
|
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -86,11 +71,6 @@ export default class DetermineTheme {
|
||||||
return await DetermineTheme.LoadRemoteTheme(layoutFromBase64)
|
return await DetermineTheme.LoadRemoteTheme(layoutFromBase64)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layoutFromBase64 !== "false") {
|
|
||||||
// We have to load something from the hash (or from disk)
|
|
||||||
return await DetermineTheme.LoadLayoutFromHash(DetermineTheme.loadCustomThemeParam)
|
|
||||||
}
|
|
||||||
|
|
||||||
let layoutId: string = undefined
|
let layoutId: string = undefined
|
||||||
|
|
||||||
const path = window.location.pathname.split("/").slice(-1)[0]
|
const path = window.location.pathname.split("/").slice(-1)[0]
|
||||||
|
@ -125,43 +105,6 @@ export default class DetermineTheme {
|
||||||
return layouts.get(id)
|
return layouts.get(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async LoadLayoutFromHash(
|
|
||||||
userLayoutParam: UIEventSource<string>
|
|
||||||
): Promise<ThemeConfig | null> {
|
|
||||||
let hash = location.hash.substr(1)
|
|
||||||
let json: any
|
|
||||||
|
|
||||||
// layoutFromBase64 contains the name of the theme. This is partly to do tracking with goat counter
|
|
||||||
const dedicatedHashFromLocalStorage = LocalStorageSource.get(
|
|
||||||
"user-layout-" + userLayoutParam.data?.replace(" ", "_")
|
|
||||||
)
|
|
||||||
if (dedicatedHashFromLocalStorage.data?.length < 10) {
|
|
||||||
dedicatedHashFromLocalStorage.setData(undefined)
|
|
||||||
}
|
|
||||||
|
|
||||||
const hashFromLocalStorage = LocalStorageSource.get("last-loaded-user-layout")
|
|
||||||
if (hash.length < 10) {
|
|
||||||
hash = dedicatedHashFromLocalStorage.data ?? hashFromLocalStorage.data
|
|
||||||
} else {
|
|
||||||
console.log("Saving hash to local storage")
|
|
||||||
hashFromLocalStorage.setData(hash)
|
|
||||||
dedicatedHashFromLocalStorage.setData(hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
json = JSON.parse(atob(hash))
|
|
||||||
} catch (e) {
|
|
||||||
// We try to decode with lz-string
|
|
||||||
json = JSON.parse(Utils.UnMinify(LZString.decompressFromBase64(hash)))
|
|
||||||
}
|
|
||||||
|
|
||||||
json = await this.expandRemoteLayers(json)
|
|
||||||
|
|
||||||
const layoutToUse = DetermineTheme.prepCustomTheme(json)
|
|
||||||
userLayoutParam.setData(layoutToUse.id)
|
|
||||||
return layoutToUse
|
|
||||||
}
|
|
||||||
|
|
||||||
private static getSharedTagRenderings(): Map<string, QuestionableTagRenderingConfigJson> {
|
private static getSharedTagRenderings(): Map<string, QuestionableTagRenderingConfigJson> {
|
||||||
const dict = new Map<string, QuestionableTagRenderingConfigJson>()
|
const dict = new Map<string, QuestionableTagRenderingConfigJson>()
|
||||||
|
|
||||||
|
|
118
src/Utils.ts
118
src/Utils.ts
|
@ -46,95 +46,6 @@ There are also some technicalities in your theme to keep in mind:
|
||||||
The import button can be tested in an unofficial theme by adding \`test=true\` or \`backend=osm-test\` as [URL-paramter](URL_Parameters.md).
|
The import button can be tested in an unofficial theme by adding \`test=true\` or \`backend=osm-test\` as [URL-paramter](URL_Parameters.md).
|
||||||
The import button will show up then. If in testmode, you can read the changeset-XML directly in the web console.
|
The import button will show up then. If in testmode, you can read the changeset-XML directly in the web console.
|
||||||
In the case that MapComplete is pointed to the testing grounds, the edit will be made on https://master.apis.dev.openstreetmap.org`
|
In the case that MapComplete is pointed to the testing grounds, the edit will be made on https://master.apis.dev.openstreetmap.org`
|
||||||
private static knownKeys = [
|
|
||||||
"addExtraTags",
|
|
||||||
"and",
|
|
||||||
"calculatedTags",
|
|
||||||
"changesetmessage",
|
|
||||||
"clustering",
|
|
||||||
"color",
|
|
||||||
"condition",
|
|
||||||
"customCss",
|
|
||||||
"dashArray",
|
|
||||||
"defaultBackgroundId",
|
|
||||||
"description",
|
|
||||||
"descriptionTail",
|
|
||||||
"doNotDownload",
|
|
||||||
"enableAddNewPoints",
|
|
||||||
"enableBackgroundLayerSelection",
|
|
||||||
"enableGeolocation",
|
|
||||||
"enableLayers",
|
|
||||||
"enableMoreQuests",
|
|
||||||
"enableSearch",
|
|
||||||
"enableShareScreen",
|
|
||||||
"enableUserBadge",
|
|
||||||
"freeform",
|
|
||||||
"hideFromOverview",
|
|
||||||
"hideInAnswer",
|
|
||||||
"icon",
|
|
||||||
"iconOverlays",
|
|
||||||
"iconSize",
|
|
||||||
"id",
|
|
||||||
"if",
|
|
||||||
"ifnot",
|
|
||||||
"isShown",
|
|
||||||
"key",
|
|
||||||
"language",
|
|
||||||
"layers",
|
|
||||||
"lockLocation",
|
|
||||||
"maintainer",
|
|
||||||
"mappings",
|
|
||||||
"maxzoom",
|
|
||||||
"maxZoom",
|
|
||||||
"minNeededElements",
|
|
||||||
"minzoom",
|
|
||||||
"multiAnswer",
|
|
||||||
"name",
|
|
||||||
"or",
|
|
||||||
"osmTags",
|
|
||||||
"passAllFeatures",
|
|
||||||
"presets",
|
|
||||||
"question",
|
|
||||||
"render",
|
|
||||||
"roaming",
|
|
||||||
"roamingRenderings",
|
|
||||||
"rotation",
|
|
||||||
"shortDescription",
|
|
||||||
"socialImage",
|
|
||||||
"source",
|
|
||||||
"startLat",
|
|
||||||
"startLon",
|
|
||||||
"startZoom",
|
|
||||||
"tagRenderings",
|
|
||||||
"tags",
|
|
||||||
"then",
|
|
||||||
"title",
|
|
||||||
"titleIcons",
|
|
||||||
"type",
|
|
||||||
"version",
|
|
||||||
"wayHandling",
|
|
||||||
"widenFactor",
|
|
||||||
"width",
|
|
||||||
]
|
|
||||||
private static extraKeys = [
|
|
||||||
"nl",
|
|
||||||
"en",
|
|
||||||
"fr",
|
|
||||||
"de",
|
|
||||||
"pt",
|
|
||||||
"es",
|
|
||||||
"name",
|
|
||||||
"phone",
|
|
||||||
"email",
|
|
||||||
"amenity",
|
|
||||||
"leisure",
|
|
||||||
"highway",
|
|
||||||
"building",
|
|
||||||
"yes",
|
|
||||||
"no",
|
|
||||||
"true",
|
|
||||||
"false",
|
|
||||||
]
|
|
||||||
private static injectedDownloads = {}
|
private static injectedDownloads = {}
|
||||||
private static _download_cache = new Map<
|
private static _download_cache = new Map<
|
||||||
string,
|
string,
|
||||||
|
@ -942,28 +853,6 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
||||||
return dict.get(k)
|
return dict.get(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UnMinify(minified: string): string {
|
|
||||||
if (minified === undefined || minified === null) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
const parts = minified.split("|")
|
|
||||||
let result = parts.shift()
|
|
||||||
const keys = Utils.knownKeys.concat(Utils.extraKeys)
|
|
||||||
|
|
||||||
for (const part of parts) {
|
|
||||||
if (part == "") {
|
|
||||||
// Empty string => this was a || originally
|
|
||||||
result += "|"
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
const i = part.charCodeAt(0)
|
|
||||||
result += '"' + keys[i] + '":' + part.substring(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
public static injectJsonDownloadForTests(url: string, data) {
|
public static injectJsonDownloadForTests(url: string, data) {
|
||||||
Utils.injectedDownloads[url] = data
|
Utils.injectedDownloads[url] = data
|
||||||
}
|
}
|
||||||
|
@ -1784,13 +1673,6 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
||||||
return Utils.findParentWithScrolling(<HTMLBaseElement>element.parentElement)
|
return Utils.findParentWithScrolling(<HTMLBaseElement>element.parentElement)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static colorDiff(
|
|
||||||
c0: { r: number; g: number; b: number },
|
|
||||||
c1: { r: number; g: number; b: number }
|
|
||||||
) {
|
|
||||||
return Math.abs(c0.r - c1.r) + Math.abs(c0.g - c1.g) + Math.abs(c0.b - c1.b)
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly _metrixPrefixes = ["", "k", "M", "G", "T", "P", "E"]
|
private static readonly _metrixPrefixes = ["", "k", "M", "G", "T", "P", "E"]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue