diff --git a/src/Logic/ImageProviders/Mapillary.ts b/src/Logic/ImageProviders/Mapillary.ts index a555aade9..1d4e02a38 100644 --- a/src/Logic/ImageProviders/Mapillary.ts +++ b/src/Logic/ImageProviders/Mapillary.ts @@ -16,7 +16,7 @@ export class Mapillary extends ImageProvider { "http://mapillary.com", "https://mapillary.com", "http://www.mapillary.com", - "https://www.mapillary.com", + "https://www.mapillary.com" ] defaultKeyPrefixes = ["mapillary", "image"] @@ -69,7 +69,7 @@ export class Mapillary extends ImageProvider { lat: location?.lat, lng: location?.lon, z: location === undefined ? undefined : Math.max((zoom ?? 2) - 1, 1), - pKey, + pKey } const baselink = `https://www.mapillary.com/app/?` const paramsStr = Utils.NoNull( @@ -82,6 +82,8 @@ export class Mapillary extends ImageProvider { /** * Returns the correct key for API v4.0 + * + * Mapillary.ExtractKeyFromURL("999924810651016") // => 999924810651016 */ private static ExtractKeyFromURL(value: string): number { let key: string @@ -144,7 +146,9 @@ export class Mapillary extends ImageProvider { mapillaryId + "?fields=thumb_1024_url,thumb_original_url,captured_at,creator&access_token=" + Constants.mapillary_client_token_v4 - const response = await Utils.downloadJsonCached(metadataUrl, 60 * 60) + const response = await Utils.downloadJsonCached<{ + thumb_1024_url: string, thumb_original_url: string, captured_at, creator: string + }>(metadataUrl, 60 * 60) const license = new LicenseInfo() license.artist = response["creator"]["username"] @@ -164,9 +168,13 @@ export class Mapillary extends ImageProvider { const metadataUrl = "https://graph.mapillary.com/" + mapillaryId + - "?fields=thumb_1024_url,thumb_original_url,captured_at,compass_angle,geometry,creator&access_token=" + + "?fields=thumb_1024_url,thumb_original_url,captured_at,compass_angle,geometry,creator,camera_type&access_token=" + Constants.mapillary_client_token_v4 - const response = await Utils.downloadJsonCached(metadataUrl, 60 * 60) + const response = await Utils.downloadJsonCached<{ + thumb_1024_url: string, thumb_original_url: string, captured_at, + compass_angle: number, + creator: string + }>(metadataUrl, 60 * 60) const url = response["thumb_1024_url"] const url_hd = response["thumb_original_url"] const date = new Date() diff --git a/src/Logic/ImageProviders/Panoramax.ts b/src/Logic/ImageProviders/Panoramax.ts index c00b86871..68b35a88b 100644 --- a/src/Logic/ImageProviders/Panoramax.ts +++ b/src/Logic/ImageProviders/Panoramax.ts @@ -131,7 +131,8 @@ export default class PanoramaxImageProvider extends ImageProvider { } public async getInfo(hash: string): Promise { - return await this.getInfoFor(hash).then((r) => this.featureToImage(r)) + const r: { data: ImageData; url: string } = await this.getInfoFor(hash) + return this.featureToImage(r) } getRelevantUrls(tags: Record, prefixes: string[]): Store { diff --git a/src/Logic/ImageProviders/WikidataImageProvider.ts b/src/Logic/ImageProviders/WikidataImageProvider.ts index 3bee532a8..9ef77be37 100644 --- a/src/Logic/ImageProviders/WikidataImageProvider.ts +++ b/src/Logic/ImageProviders/WikidataImageProvider.ts @@ -5,7 +5,6 @@ import Wikidata from "../Web/Wikidata" import SvelteUIElement from "../../UI/Base/SvelteUIElement" import * as Wikidata_icon from "../../assets/svg/Wikidata.svelte" import { Utils } from "../../Utils" -import { ImmutableStore, Store, Stores, UIEventSource } from "../UIEventSource" export class WikidataImageProvider extends ImageProvider { public static readonly singleton = new WikidataImageProvider() @@ -64,7 +63,7 @@ export class WikidataImageProvider extends ImageProvider { return [].concat(...resolved) } - public DownloadAttribution(_): Promise { + public DownloadAttribution(): Promise { throw new Error("Method not implemented; shouldn't be needed!") } } diff --git a/src/Logic/UIEventSource.ts b/src/Logic/UIEventSource.ts index 965dccd17..391e9e6f2 100644 --- a/src/Logic/UIEventSource.ts +++ b/src/Logic/UIEventSource.ts @@ -37,8 +37,10 @@ export class Stores { */ public static FromPromise(promise: Promise): Store { const src = new UIEventSource(undefined) - promise?.then((d) => src.setData(d)) - promise?.catch((err) => console.warn("Promise failed:", err)) + promise?.catch((err): undefined => { + console.warn("Promise failed:", err) + return undefined + })?.then((d) => src.setData(d)) return src } @@ -108,7 +110,6 @@ export class Stores { public static fromArray(sources: ReadonlyArray>): UIEventSource { const src = new UIEventSource(sources.map(s => s.data)) - for (let i = 0; i < sources.length; i++) { sources[i].addCallback(content => { src.data[i] = content @@ -120,7 +121,17 @@ export class Stores { sources[i].setData(contents[i]) } }) + return src + } + public static fromStoresArray(sources: ReadonlyArray>): Store { + const src = new UIEventSource(sources.map(s => s.data)) + for (let i = 0; i < sources.length; i++) { + sources[i].addCallback(content => { + src.data[i] = content + src.ping() + }) + } return src } } @@ -388,7 +399,8 @@ export class ImmutableStore extends Store { this.data = data } - private static readonly pass: () => void = () => {} + private static readonly pass: () => void = () => { + } addCallback(_: (data: T) => void): () => void { // pass: data will never change @@ -666,7 +678,8 @@ class MappedStore extends Store { } export class UIEventSource extends Store implements Writable { - private static readonly pass: () => void = () => {} + private static readonly pass: () => void = () => { + } public data: T _callbacks: ListenerTracker = new ListenerTracker() diff --git a/src/Utils.ts b/src/Utils.ts index ef7033373..23f31da24 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -332,9 +332,12 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be * @param toKey * @constructor */ - public static DedupOnId(arr: T[], toKey: (t: T) => string): T[] { + public static DedupOnId(arr: T[], toKey?: (t: T) => string): T[] { const uniq: T[] = [] const seen = new Set() + if (toKey === undefined) { + toKey = (item) => item["id"] + } for (const img of arr) { if (!img) { continue