Merge develop
This commit is contained in:
commit
ee77dd0fc9
288 changed files with 7485 additions and 28619 deletions
|
@ -1,6 +1,10 @@
|
|||
import { Store, UIEventSource } from "../UIEventSource"
|
||||
import { Utils } from "../../Utils"
|
||||
import { RasterLayerPolygon, RasterLayerUtils } from "../../Models/RasterLayers"
|
||||
import {
|
||||
AvailableRasterLayers,
|
||||
RasterLayerPolygon,
|
||||
RasterLayerUtils,
|
||||
} from "../../Models/RasterLayers"
|
||||
|
||||
/**
|
||||
* When a user pans around on the map, they might pan out of the range of the current background raster layer.
|
||||
|
@ -9,12 +13,32 @@ import { RasterLayerPolygon, RasterLayerUtils } from "../../Models/RasterLayers"
|
|||
export default class BackgroundLayerResetter {
|
||||
constructor(
|
||||
currentBackgroundLayer: UIEventSource<RasterLayerPolygon | undefined>,
|
||||
availableLayers: Store<RasterLayerPolygon[]>
|
||||
availableLayers: { store: Store<RasterLayerPolygon[]> }
|
||||
) {
|
||||
if (Utils.runningFromConsole) {
|
||||
return
|
||||
}
|
||||
|
||||
currentBackgroundLayer.addCallbackAndRunD((l) => {
|
||||
if (
|
||||
l.geometry !== undefined &&
|
||||
AvailableRasterLayers.globalLayers.find(
|
||||
(global) => global.properties.id !== l.properties.id
|
||||
)
|
||||
) {
|
||||
BackgroundLayerResetter.installHandler(
|
||||
currentBackgroundLayer,
|
||||
availableLayers.store
|
||||
)
|
||||
return true // unregister
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private static installHandler(
|
||||
currentBackgroundLayer: UIEventSource<RasterLayerPolygon | undefined>,
|
||||
availableLayers: Store<RasterLayerPolygon[]>
|
||||
) {
|
||||
// Change the baseLayer back to OSM if we go out of the current range of the layer
|
||||
availableLayers.addCallbackAndRunD((availableLayers) => {
|
||||
// We only check on move/on change of the availableLayers
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Store, UIEventSource } from "../UIEventSource"
|
||||
import { RasterLayerPolygon } from "../../Models/RasterLayers"
|
||||
import { AvailableRasterLayers, RasterLayerPolygon } from "../../Models/RasterLayers"
|
||||
|
||||
/**
|
||||
* Selects the appropriate raster layer as background for the given query parameter, theme setting, user preference or default value.
|
||||
|
@ -8,7 +8,7 @@ import { RasterLayerPolygon } from "../../Models/RasterLayers"
|
|||
*/
|
||||
export class PreferredRasterLayerSelector {
|
||||
private readonly _rasterLayerSetting: UIEventSource<RasterLayerPolygon>
|
||||
private readonly _availableLayers: Store<RasterLayerPolygon[]>
|
||||
private readonly _availableLayers: { store: Store<RasterLayerPolygon[]> }
|
||||
private readonly _preferredBackgroundLayer: UIEventSource<
|
||||
string | "photo" | "map" | "osmbasedmap" | undefined
|
||||
>
|
||||
|
@ -16,7 +16,7 @@ export class PreferredRasterLayerSelector {
|
|||
|
||||
constructor(
|
||||
rasterLayerSetting: UIEventSource<RasterLayerPolygon>,
|
||||
availableLayers: Store<RasterLayerPolygon[]>,
|
||||
availableLayers: { store: Store<RasterLayerPolygon[]> },
|
||||
queryParameter: UIEventSource<string>,
|
||||
preferredBackgroundLayer: UIEventSource<
|
||||
string | "photo" | "map" | "osmbasedmap" | undefined
|
||||
|
@ -47,7 +47,13 @@ export class PreferredRasterLayerSelector {
|
|||
|
||||
this._preferredBackgroundLayer.addCallbackD((_) => self.updateLayer())
|
||||
|
||||
this._availableLayers.addCallbackD((_) => self.updateLayer())
|
||||
rasterLayerSetting.addCallbackAndRunD((layer) => {
|
||||
if (AvailableRasterLayers.globalLayers.find((l) => l.id === layer.properties.id)) {
|
||||
return
|
||||
}
|
||||
this._availableLayers.store.addCallbackD((_) => self.updateLayer())
|
||||
return true // unregister
|
||||
})
|
||||
self.updateLayer()
|
||||
}
|
||||
|
||||
|
@ -58,9 +64,19 @@ export class PreferredRasterLayerSelector {
|
|||
private updateLayer() {
|
||||
// What is the ID of the layer we have to (try to) load?
|
||||
const targetLayerId = this._queryParameter.data ?? this._preferredBackgroundLayer.data
|
||||
const available = this._availableLayers.data
|
||||
if (targetLayerId === undefined || targetLayerId === "default") {
|
||||
return
|
||||
}
|
||||
const global = AvailableRasterLayers.globalLayers.find(
|
||||
(l) => l.properties.id === targetLayerId
|
||||
)
|
||||
if (global) {
|
||||
this._rasterLayerSetting.setData(global)
|
||||
return
|
||||
}
|
||||
const isCategory =
|
||||
targetLayerId === "photo" || targetLayerId === "osmbasedmap" || targetLayerId === "map"
|
||||
const available = this._availableLayers.store.data
|
||||
const foundLayer = isCategory
|
||||
? available.find((l) => l.properties.category === targetLayerId)
|
||||
: available.find((l) => l.properties.id === targetLayerId)
|
||||
|
|
|
@ -14,12 +14,13 @@ import licenses from "../assets/generated/license_info.json"
|
|||
import TagRenderingConfig from "../Models/ThemeConfig/TagRenderingConfig"
|
||||
import { FixImages } from "../Models/ThemeConfig/Conversion/FixImages"
|
||||
import questions from "../assets/generated/layers/questions.json"
|
||||
import { DoesImageExist, PrevalidateTheme, ValidateThemeAndLayers } from "../Models/ThemeConfig/Conversion/Validation"
|
||||
import { DoesImageExist, PrevalidateTheme } from "../Models/ThemeConfig/Conversion/Validation"
|
||||
import { DesugaringContext } from "../Models/ThemeConfig/Conversion/Conversion"
|
||||
import { TagRenderingConfigJson } from "../Models/ThemeConfig/Json/TagRenderingConfigJson"
|
||||
import Hash from "./Web/Hash"
|
||||
import { QuestionableTagRenderingConfigJson } from "../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson"
|
||||
import { LayoutConfigJson } from "../Models/ThemeConfig/Json/LayoutConfigJson"
|
||||
import { ValidateThemeAndLayers } from "../Models/ThemeConfig/Conversion/ValidateThemeAndLayers"
|
||||
|
||||
export default class DetermineLayout {
|
||||
private static readonly _knownImages = new Set(Array.from(licenses).map((l) => l.path))
|
||||
|
@ -107,9 +108,18 @@ export default class DetermineLayout {
|
|||
).data
|
||||
const id = layoutId?.toLowerCase()
|
||||
const layouts = AllKnownLayouts.allKnownLayouts
|
||||
if (layouts.size() == 0) {
|
||||
throw "Build failed or running, no layouts are known at all"
|
||||
}
|
||||
if (layouts.getConfig(id) === undefined) {
|
||||
const alternatives = Utils.sortedByLevenshteinDistance(id, Array.from(layouts.keys()), i => i).slice(0, 3)
|
||||
const msg = (`No builtin map theme with name ${layoutId} exists. Perhaps you meant one of ${alternatives.join(", ")}`)
|
||||
const alternatives = Utils.sortedByLevenshteinDistance(
|
||||
id,
|
||||
Array.from(layouts.keys()),
|
||||
(i) => i
|
||||
).slice(0, 3)
|
||||
const msg = `No builtin map theme with name ${layoutId} exists. Perhaps you meant one of ${alternatives.join(
|
||||
", "
|
||||
)}`
|
||||
throw msg
|
||||
}
|
||||
return layouts.get(id)
|
||||
|
@ -200,11 +210,11 @@ export default class DetermineLayout {
|
|||
id: json.id,
|
||||
description: json.description,
|
||||
descriptionTail: {
|
||||
en: "<div class='alert'>Layer only mode.</div> The loaded custom theme actually isn't a custom theme, but only contains a layer."
|
||||
en: "<div class='alert'>Layer only mode.</div> The loaded custom theme actually isn't a custom theme, but only contains a layer.",
|
||||
},
|
||||
icon,
|
||||
title: json.name,
|
||||
layers: [json]
|
||||
layers: [json],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,7 +227,7 @@ export default class DetermineLayout {
|
|||
tagRenderings: DetermineLayout.getSharedTagRenderings(),
|
||||
tagRenderingOrder: DetermineLayout.getSharedTagRenderingOrder(),
|
||||
sharedLayers: knownLayersDict,
|
||||
publicLayers: new Set<string>()
|
||||
publicLayers: new Set<string>(),
|
||||
}
|
||||
json = new FixLegacyTheme().convertStrict(json)
|
||||
const raw = json
|
||||
|
@ -241,7 +251,7 @@ export default class DetermineLayout {
|
|||
}
|
||||
return new LayoutConfig(json, false, {
|
||||
definitionRaw: JSON.stringify(raw, null, " "),
|
||||
definedAtUrl: sourceUrl
|
||||
definedAtUrl: sourceUrl,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -55,12 +55,11 @@ export default class LayoutSource extends FeatureSourceMerger {
|
|||
mapProperties,
|
||||
{
|
||||
isActive: isDisplayed(layer.id),
|
||||
maxAge: layer.maxAgeOfCache
|
||||
maxAge: layer.maxAgeOfCache,
|
||||
}
|
||||
)
|
||||
fromCache.set(layer.id, src)
|
||||
}
|
||||
|
||||
}
|
||||
const mvtSources: UpdatableFeatureSource[] = osmLayers
|
||||
.filter((f) => mvtAvailableLayers.has(f.id))
|
||||
|
@ -170,7 +169,7 @@ export default class LayoutSource extends FeatureSourceMerger {
|
|||
backend,
|
||||
isActive,
|
||||
patchRelations: true,
|
||||
fullNodeDatabase
|
||||
fullNodeDatabase,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -202,11 +201,11 @@ export default class LayoutSource extends FeatureSourceMerger {
|
|||
widenFactor: featureSwitches.layoutToUse.widenFactor,
|
||||
overpassUrl: featureSwitches.overpassUrl,
|
||||
overpassTimeout: featureSwitches.overpassTimeout,
|
||||
overpassMaxZoom: featureSwitches.overpassMaxZoom
|
||||
overpassMaxZoom: featureSwitches.overpassMaxZoom,
|
||||
},
|
||||
{
|
||||
padToTiles: zoom.map((zoom) => Math.min(15, zoom + 1)),
|
||||
isActive
|
||||
isActive,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ export default class MetaTagging {
|
|||
state.featureProperties,
|
||||
{
|
||||
includeDates: !lightUpdate,
|
||||
evaluateStrict: !lightUpdate
|
||||
evaluateStrict: !lightUpdate,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ export default class MetaTagging {
|
|||
return []
|
||||
}
|
||||
return [state.perLayer.get(layerId).GetFeaturesWithin(bbox)]
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -350,8 +350,8 @@ export default class MetaTagging {
|
|||
if (MetaTagging.errorPrintCount < MetaTagging.stopErrorOutputAt) {
|
||||
console.warn(
|
||||
"Could not calculate a " +
|
||||
(isStrict ? "strict " : "") +
|
||||
"calculated tag for key",
|
||||
(isStrict ? "strict " : "") +
|
||||
"calculated tag for key",
|
||||
key,
|
||||
"for feature",
|
||||
feat.properties.id,
|
||||
|
@ -359,9 +359,9 @@ export default class MetaTagging {
|
|||
code,
|
||||
"(in layer",
|
||||
layerId +
|
||||
") due to \n" +
|
||||
e +
|
||||
"\n. Are you the theme creator? Doublecheck your code. Note that the metatags might not be stable on new features",
|
||||
") due to \n" +
|
||||
e +
|
||||
"\n. Are you the theme creator? Doublecheck your code. Note that the metatags might not be stable on new features",
|
||||
e,
|
||||
e.stack,
|
||||
{ feat }
|
||||
|
|
|
@ -440,7 +440,13 @@ export class Changes {
|
|||
}
|
||||
})
|
||||
|
||||
if(!(result.newObjects.length === 0 && result.modifiedObjects.length === 0 && result.deletedObjects.length === 0)) {
|
||||
if (
|
||||
!(
|
||||
result.newObjects.length === 0 &&
|
||||
result.modifiedObjects.length === 0 &&
|
||||
result.deletedObjects.length === 0
|
||||
)
|
||||
) {
|
||||
console.debug(
|
||||
"Calculated the pending changes: ",
|
||||
result.newObjects.length,
|
||||
|
@ -589,7 +595,13 @@ export class Changes {
|
|||
if (matchFound) {
|
||||
toUpload.push(c)
|
||||
} else {
|
||||
console.log("Refusing change about "+c.type+"/"+ c.id+" as not in the objects. No internet?")
|
||||
console.log(
|
||||
"Refusing change about " +
|
||||
c.type +
|
||||
"/" +
|
||||
c.id +
|
||||
" as not in the objects. No internet?"
|
||||
)
|
||||
refused.push(c)
|
||||
}
|
||||
})
|
||||
|
@ -711,7 +723,7 @@ export class Changes {
|
|||
|
||||
let { toUpload, refused } = this.fragmentChanges(pending, objects)
|
||||
|
||||
if(toUpload.length === 0){
|
||||
if (toUpload.length === 0) {
|
||||
return refused
|
||||
}
|
||||
await this._changesetHandler.UploadChangeset(
|
||||
|
|
|
@ -154,7 +154,7 @@ export class ChangesetHandler {
|
|||
if (this._reportError) {
|
||||
this._reportError(e)
|
||||
}
|
||||
if((<XMLHttpRequest> e).status === 400){
|
||||
if ((<XMLHttpRequest>e).status === 400) {
|
||||
// This request is invalid. We simply drop the changes and hope that someone will analyze what went wrong with it in the upload; we pretend everything went fine
|
||||
return
|
||||
}
|
||||
|
|
|
@ -107,7 +107,8 @@ export class OsmConnection {
|
|||
ud.name = "Fake user"
|
||||
ud.totalMessages = 42
|
||||
ud.languages = ["en"]
|
||||
ud.description = "The 'fake-user' is a URL-parameter which allows to test features without needing an OSM account or even internet connection."
|
||||
ud.description =
|
||||
"The 'fake-user' is a URL-parameter which allows to test features without needing an OSM account or even internet connection."
|
||||
this.loadingStatus.setData("logged-in")
|
||||
}
|
||||
this.UpdateCapabilities()
|
||||
|
|
|
@ -184,7 +184,6 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
|
|||
"Enable/disable caching from localStorage"
|
||||
)
|
||||
|
||||
|
||||
let testingDefaultValue = false
|
||||
if (
|
||||
!Utils.runningFromConsole &&
|
||||
|
|
|
@ -57,7 +57,8 @@ export class GeoLocationState {
|
|||
* If the user denies the geolocation this time, we unset this flag
|
||||
* @private
|
||||
*/
|
||||
private readonly _previousLocationGrant: UIEventSource<boolean> = LocalStorageSource.GetParsed<boolean>("geolocation-permissions", false)
|
||||
private readonly _previousLocationGrant: UIEventSource<boolean> =
|
||||
LocalStorageSource.GetParsed<boolean>("geolocation-permissions", false)
|
||||
|
||||
/**
|
||||
* Used to detect a permission retraction
|
||||
|
@ -67,8 +68,8 @@ export class GeoLocationState {
|
|||
/**
|
||||
* A human explanation of the current gps state, to be shown on the home screen or as tooltip
|
||||
*/
|
||||
public readonly gpsStateExplanation : Store<Translation>
|
||||
constructor() {
|
||||
public readonly gpsStateExplanation: Store<Translation>
|
||||
constructor() {
|
||||
const self = this
|
||||
|
||||
this.permission.addCallbackAndRunD(async (state) => {
|
||||
|
@ -103,33 +104,33 @@ export class GeoLocationState {
|
|||
this.requestPermission()
|
||||
}
|
||||
|
||||
this.gpsStateExplanation = this.gpsAvailable.map(
|
||||
(available) => {
|
||||
if (this.currentGPSLocation.data !== undefined) {
|
||||
if (!this.allowMoving.data) {
|
||||
return Translations.t.general.visualFeedback.islocked
|
||||
}
|
||||
|
||||
this.gpsStateExplanation = this.gpsAvailable.map(available => {
|
||||
if (!available) {
|
||||
return Translations.t.general.labels.locationNotAvailable
|
||||
}
|
||||
if (this.permission.data === "denied") {
|
||||
return Translations.t.general.geopermissionDenied
|
||||
}
|
||||
if (this.permission.data === "prompt") {
|
||||
return Translations.t.general.labels.jumpToLocation
|
||||
}
|
||||
if (this.permission.data === "requested") {
|
||||
return Translations.t.general.waitingForGeopermission
|
||||
}
|
||||
return Translations.t.general.labels.jumpToLocation
|
||||
}
|
||||
|
||||
|
||||
if (!this.allowMoving.data) {
|
||||
return Translations.t.general.visualFeedback.islocked
|
||||
}
|
||||
|
||||
if (this.currentGPSLocation.data !== undefined) {
|
||||
return Translations.t.general.labels.jumpToLocation
|
||||
}
|
||||
return Translations.t.general.waitingForLocation
|
||||
}, [this.allowMoving, this.permission, this.currentGPSLocation])
|
||||
|
||||
}
|
||||
if (!available) {
|
||||
return Translations.t.general.labels.locationNotAvailable
|
||||
}
|
||||
if (this.permission.data === "denied") {
|
||||
return Translations.t.general.geopermissionDenied
|
||||
}
|
||||
if (this.permission.data === "prompt") {
|
||||
return Translations.t.general.labels.jumpToLocation
|
||||
}
|
||||
if (this.permission.data === "requested") {
|
||||
return Translations.t.general.waitingForGeopermission
|
||||
}
|
||||
return Translations.t.general.waitingForLocation
|
||||
},
|
||||
[this.allowMoving, this.permission, this.currentGPSLocation]
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the user to allow access to their position.
|
||||
|
@ -208,12 +209,12 @@ export class GeoLocationState {
|
|||
self._previousLocationGrant.setData(true)
|
||||
},
|
||||
function (e) {
|
||||
if(e.code === 2 || e.code === 3){
|
||||
if (e.code === 2 || e.code === 3) {
|
||||
self._gpsAvailable.set(false)
|
||||
return
|
||||
}
|
||||
self._gpsAvailable.set(true) // We go back to the default assumption that the location is physically available
|
||||
if(e.code === 1) {
|
||||
if (e.code === 1) {
|
||||
self.permission.set("denied")
|
||||
self._grantedThisSession.setData(false)
|
||||
return
|
||||
|
|
|
@ -420,11 +420,13 @@ export default class UserRelatedState {
|
|||
amendedPrefs.data["_" + k] = "" + userDetails[k]
|
||||
}
|
||||
if (userDetails.description) {
|
||||
amendedPrefs.data["_description_html"] = Utils.purify(new Showdown.Converter()
|
||||
.makeHtml(userDetails.description)
|
||||
?.replace(/>/g, ">")
|
||||
?.replace(/</g, "<")
|
||||
?.replace(/\n/g, ""))
|
||||
amendedPrefs.data["_description_html"] = Utils.purify(
|
||||
new Showdown.Converter()
|
||||
.makeHtml(userDetails.description)
|
||||
?.replace(/>/g, ">")
|
||||
?.replace(/</g, "<")
|
||||
?.replace(/\n/g, "")
|
||||
)
|
||||
}
|
||||
|
||||
usersettingMetaTagging.metaTaggging_for_usersettings({ properties: amendedPrefs.data })
|
||||
|
|
|
@ -1,14 +1,42 @@
|
|||
import { Utils } from "../../Utils"
|
||||
/** This code is autogenerated - do not edit. Edit ./assets/layers/usersettings/usersettings.json instead */
|
||||
export class ThemeMetaTagging {
|
||||
public static readonly themeName = "usersettings"
|
||||
public static readonly themeName = "usersettings"
|
||||
|
||||
public metaTaggging_for_usersettings(feat: {properties: Record<string, string>}) {
|
||||
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_md', () => feat.properties._description.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)?.at(1) )
|
||||
Utils.AddLazyProperty(feat.properties, '_d', () => feat.properties._description?.replace(/</g,'<')?.replace(/>/g,'>') ?? '' )
|
||||
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_a', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.href.match(/mastodon|en.osm.town/) !== null)[0]?.href }) (feat) )
|
||||
Utils.AddLazyProperty(feat.properties, '_mastodon_link', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.getAttribute("rel")?.indexOf('me') >= 0)[0]?.href})(feat) )
|
||||
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate', () => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a )
|
||||
feat.properties['__current_backgroun'] = 'initial_value'
|
||||
}
|
||||
}
|
||||
public metaTaggging_for_usersettings(feat: { properties: Record<string, string> }) {
|
||||
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_md", () =>
|
||||
feat.properties._description
|
||||
.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)
|
||||
?.at(1)
|
||||
)
|
||||
Utils.AddLazyProperty(
|
||||
feat.properties,
|
||||
"_d",
|
||||
() => feat.properties._description?.replace(/</g, "<")?.replace(/>/g, ">") ?? ""
|
||||
)
|
||||
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_a", () =>
|
||||
((feat) => {
|
||||
const e = document.createElement("div")
|
||||
e.innerHTML = feat.properties._d
|
||||
return Array.from(e.getElementsByTagName("a")).filter(
|
||||
(a) => a.href.match(/mastodon|en.osm.town/) !== null
|
||||
)[0]?.href
|
||||
})(feat)
|
||||
)
|
||||
Utils.AddLazyProperty(feat.properties, "_mastodon_link", () =>
|
||||
((feat) => {
|
||||
const e = document.createElement("div")
|
||||
e.innerHTML = feat.properties._d
|
||||
return Array.from(e.getElementsByTagName("a")).filter(
|
||||
(a) => a.getAttribute("rel")?.indexOf("me") >= 0
|
||||
)[0]?.href
|
||||
})(feat)
|
||||
)
|
||||
Utils.AddLazyProperty(
|
||||
feat.properties,
|
||||
"_mastodon_candidate",
|
||||
() => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a
|
||||
)
|
||||
feat.properties["__current_backgroun"] = "initial_value"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -218,7 +218,7 @@ export class TagUtils {
|
|||
*
|
||||
* TagUtils.KVtoProperties([new Tag("a","b"), new Tag("c","d")] // => {a: "b", c: "d"}
|
||||
*/
|
||||
static KVtoProperties(tags: {key: string, value: string}[]): Record<string, string> {
|
||||
static KVtoProperties(tags: { key: string; value: string }[]): Record<string, string> {
|
||||
const properties: Record<string, string> = {}
|
||||
for (const tag of tags) {
|
||||
properties[tag.key] = tag.value
|
||||
|
@ -226,7 +226,7 @@ export class TagUtils {
|
|||
return properties
|
||||
}
|
||||
|
||||
static KVObjtoProperties(tags: {k: string, v: string}[]): Record<string, string> {
|
||||
static KVObjtoProperties(tags: { k: string; v: string }[]): Record<string, string> {
|
||||
const properties: Record<string, string> = {}
|
||||
for (const tag of tags) {
|
||||
properties[tag.k] = tag.v
|
||||
|
|
|
@ -10,7 +10,7 @@ export class IdbLocalStorage {
|
|||
|
||||
public static Get<T>(
|
||||
key: string,
|
||||
options?: { defaultValue?: T; whenLoaded?: (t: T | null) => void },
|
||||
options?: { defaultValue?: T; whenLoaded?: (t: T | null) => void }
|
||||
): UIEventSource<T> {
|
||||
if (IdbLocalStorage._sourceCache[key] !== undefined) {
|
||||
return IdbLocalStorage._sourceCache[key]
|
||||
|
|
|
@ -143,14 +143,14 @@ export default class NameSuggestionIndex {
|
|||
tags: Record<string, string>,
|
||||
country: string[],
|
||||
location?: [number, number],
|
||||
options?:{
|
||||
options?: {
|
||||
/**
|
||||
* If set, sort by frequency instead of alphabetically
|
||||
*/
|
||||
sortByFrequency: boolean
|
||||
}
|
||||
): Promise<Mapping[]> {
|
||||
const mappings: (Mapping & {frequency: number})[] = []
|
||||
const mappings: (Mapping & { frequency: number })[] = []
|
||||
const frequencies = await NameSuggestionIndex.fetchFrequenciesFor(type, country)
|
||||
for (const key in tags) {
|
||||
if (key.startsWith("_")) {
|
||||
|
@ -196,11 +196,11 @@ export default class NameSuggestionIndex {
|
|||
// As such, it should be "true" but this is not supported
|
||||
priorityIf: frequency > 0 ? new RegexTag("id", /.*/) : undefined,
|
||||
searchTerms: { "*": [nsiItem.displayName, nsiItem.id] },
|
||||
frequency: frequency ?? -1
|
||||
frequency: frequency ?? -1,
|
||||
})
|
||||
}
|
||||
}
|
||||
if(options?.sortByFrequency){
|
||||
if (options?.sortByFrequency) {
|
||||
mappings.sort((a, b) => b.frequency - a.frequency)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ export default class ThemeViewStateHashActor {
|
|||
"The possible hashes are:",
|
||||
"",
|
||||
MenuState._menuviewTabs.map((tab) => "`menu:" + tab + "`").join(","),
|
||||
MenuState._themeviewTabs.map((tab) => "`theme-menu:" + tab + "`").join(",")
|
||||
MenuState._themeviewTabs.map((tab) => "`theme-menu:" + tab + "`").join(","),
|
||||
]
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue