diff --git a/src/Logic/SimpleMetaTagger.ts b/src/Logic/SimpleMetaTagger.ts index 39ca1f6ec7..2d1a8688c2 100644 --- a/src/Logic/SimpleMetaTagger.ts +++ b/src/Logic/SimpleMetaTagger.ts @@ -593,8 +593,9 @@ export default class SimpleMetaTaggers { (feature: Feature, layer: LayerConfig, tagsStore: UIEventSource) => { Utils.AddLazyPropertyAsync(feature.properties, "_currency", async () => { // Wait until _country is actually set - await tagsStore.AsPromise((tags) => !!tags._country) + const tags = await tagsStore.AsPromise((tags) => !!tags._country) + const country = tags._country // Initialize a list of currencies const currencies = {} // Check if there are any currency:XXX tags, add them to the map @@ -609,7 +610,7 @@ export default class SimpleMetaTaggers { } // Determine the default currency for the country - const defaultCurrency = countryToCurrency[feature.properties._country.toUpperCase()] + const defaultCurrency = countryToCurrency[country.toUpperCase()] // If the default currency is not in the list, add it if (defaultCurrency && !currencies[defaultCurrency]) { diff --git a/src/Logic/UIEventSource.ts b/src/Logic/UIEventSource.ts index dd1171caa7..39db7dd4e5 100644 --- a/src/Logic/UIEventSource.ts +++ b/src/Logic/UIEventSource.ts @@ -255,8 +255,12 @@ export abstract class Store implements Readable { resolve(data) } else { self.addCallbackD((data) => { - resolve(data) - return true // return true to unregister as we only need to be called once + if (condition(data)) { + resolve(data) + return true // return true to unregister as we only need to be called once + } else { + return false // We didn't resolve yet, wait for the next ping + } }) } }) @@ -279,13 +283,13 @@ export abstract class Store implements Readable { export class ImmutableStore extends Store { public readonly data: T - private static readonly pass: () => void = () => {} - constructor(data: T) { super() this.data = data } + private static readonly pass: () => void = () => {} + addCallback(_: (data: T) => void): () => void { // pass: data will never change return ImmutableStore.pass @@ -322,9 +326,9 @@ export class ImmutableStore extends Store { * Keeps track of the callback functions */ class ListenerTracker { + public pingCount = 0 private readonly _callbacks: ((t: T) => boolean | void | any)[] = [] - public pingCount = 0 /** * Adds a callback which can be called; a function to unregister is returned */ @@ -386,18 +390,16 @@ class ListenerTracker { * The mapped store is a helper type which does the mapping of a function. */ class MappedStore extends Store { + private static readonly pass: () => {} private readonly _upstream: Store private readonly _upstreamCallbackHandler: ListenerTracker | undefined private _upstreamPingCount: number = -1 private _unregisterFromUpstream: () => void - private readonly _f: (t: TIn) => T private readonly _extraStores: Store[] | undefined private _unregisterFromExtraStores: (() => void)[] | undefined - private _callbacks: ListenerTracker = new ListenerTracker() - - private static readonly pass: () => {} + private _callbacksAreRegistered = false constructor( upstream: Store, @@ -421,7 +423,6 @@ class MappedStore extends Store { } private _data: T - private _callbacksAreRegistered = false /** * Gets the current data from the store @@ -468,33 +469,6 @@ class MappedStore extends Store { ) } - private unregisterFromUpstream() { - console.log("Unregistering callbacks for", this.tag) - this._callbacksAreRegistered = false - this._unregisterFromUpstream() - this._unregisterFromExtraStores?.forEach((unr) => unr()) - } - - private registerCallbacksToUpstream() { - const self = this - - this._unregisterFromUpstream = this._upstream.addCallback((_) => self.update()) - this._unregisterFromExtraStores = this._extraStores?.map((store) => - store?.addCallback((_) => self.update()) - ) - this._callbacksAreRegistered = true - } - - private update(): void { - const newData = this._f(this._upstream.data) - this._upstreamPingCount = this._upstreamCallbackHandler?.pingCount - if (this._data == newData) { - return - } - this._data = newData - this._callbacks.ping(this._data) - } - addCallback(callback: (data: T) => any | boolean | void): () => void { if (!this._callbacksAreRegistered) { // This is the first callback that is added @@ -535,14 +509,40 @@ class MappedStore extends Store { } }) } + + private unregisterFromUpstream() { + console.log("Unregistering callbacks for", this.tag) + this._callbacksAreRegistered = false + this._unregisterFromUpstream() + this._unregisterFromExtraStores?.forEach((unr) => unr()) + } + + private registerCallbacksToUpstream() { + const self = this + + this._unregisterFromUpstream = this._upstream.addCallback((_) => self.update()) + this._unregisterFromExtraStores = this._extraStores?.map((store) => + store?.addCallback((_) => self.update()) + ) + this._callbacksAreRegistered = true + } + + private update(): void { + const newData = this._f(this._upstream.data) + this._upstreamPingCount = this._upstreamCallbackHandler?.pingCount + if (this._data == newData) { + return + } + this._data = newData + this._callbacks.ping(this._data) + } } export class UIEventSource extends Store implements Writable { + private static readonly pass: () => {} public data: T _callbacks: ListenerTracker = new ListenerTracker() - private static readonly pass: () => {} - constructor(data: T, tag: string = "") { super(tag) this.data = data @@ -624,6 +624,24 @@ export class UIEventSource extends Store implements Writable { ) } + static asBoolean(stringUIEventSource: UIEventSource) { + return stringUIEventSource.sync( + (str) => str === "true", + [], + (b) => "" + b + ) + } + + /** + * Create a new UIEVentSource. Whenever 'source' changes, the returned UIEventSource will get this value as well. + * However, this value can be overriden without affecting source + */ + static feedFrom(store: Store): UIEventSource { + const src = new UIEventSource(store.data) + store.addCallback((t) => src.setData(t)) + return src + } + /** * Adds a callback * @@ -704,6 +722,7 @@ export class UIEventSource extends Store implements Writable { ): Store { return new MappedStore(this, f, extraSources, this._callbacks, f(this.data), onDestroy) } + /** * Monoidal map which results in a read-only store. 'undefined' is passed 'as is' * Given a function 'f', will construct a new UIEventSource where the contents will always be "f(this.data)' @@ -779,14 +798,6 @@ export class UIEventSource extends Store implements Writable { return this } - static asBoolean(stringUIEventSource: UIEventSource) { - return stringUIEventSource.sync( - (str) => str === "true", - [], - (b) => "" + b - ) - } - set(value: T): void { this.setData(value) } @@ -794,14 +805,4 @@ export class UIEventSource extends Store implements Writable { update(f: Updater & ((value: T) => T)): void { this.setData(f(this.data)) } - - /** - * Create a new UIEVentSource. Whenever 'source' changes, the returned UIEventSource will get this value as well. - * However, this value can be overriden without affecting source - */ - static feedFrom(store: Store): UIEventSource { - const src = new UIEventSource(store.data) - store.addCallback((t) => src.setData(t)) - return src - } }