forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			68 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			68 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { Store, UIEventSource } from "../UIEventSource"
 | 
						|
import BaseUIElement from "../../UI/BaseUIElement"
 | 
						|
import { LicenseInfo } from "./LicenseInfo"
 | 
						|
import { Utils } from "../../Utils"
 | 
						|
 | 
						|
export interface ProvidedImage {
 | 
						|
    url: string
 | 
						|
    key: string
 | 
						|
    provider: ImageProvider
 | 
						|
}
 | 
						|
 | 
						|
export default abstract class ImageProvider {
 | 
						|
    public abstract readonly defaultKeyPrefixes: string[]
 | 
						|
 | 
						|
    public abstract SourceIcon(backlinkSource?: string): BaseUIElement
 | 
						|
 | 
						|
    /**
 | 
						|
     * Given a properies object, maps it onto _all_ the available pictures for this imageProvider
 | 
						|
     */
 | 
						|
    public GetRelevantUrls(
 | 
						|
        allTags: Store<any>,
 | 
						|
        options?: {
 | 
						|
            prefixes?: string[]
 | 
						|
        }
 | 
						|
    ): UIEventSource<ProvidedImage[]> {
 | 
						|
        const prefixes = options?.prefixes ?? this.defaultKeyPrefixes
 | 
						|
        if (prefixes === undefined) {
 | 
						|
            throw "No `defaultKeyPrefixes` defined by this image provider"
 | 
						|
        }
 | 
						|
        const relevantUrls = new UIEventSource<
 | 
						|
            { url: string; key: string; provider: ImageProvider }[]
 | 
						|
        >([])
 | 
						|
        const seenValues = new Set<string>()
 | 
						|
        allTags.addCallbackAndRunD((tags) => {
 | 
						|
            for (const key in tags) {
 | 
						|
                if (!prefixes.some((prefix) => key.startsWith(prefix))) {
 | 
						|
                    continue
 | 
						|
                }
 | 
						|
                const values = Utils.NoEmpty(tags[key]?.split(";")?.map((v) => v.trim()) ?? [])
 | 
						|
                for (const value of values) {
 | 
						|
                    if (seenValues.has(value)) {
 | 
						|
                        continue
 | 
						|
                    }
 | 
						|
                    seenValues.add(value)
 | 
						|
                    this.ExtractUrls(key, value).then((promises) => {
 | 
						|
                        for (const promise of promises ?? []) {
 | 
						|
                            if (promise === undefined) {
 | 
						|
                                continue
 | 
						|
                            }
 | 
						|
                            promise.then((providedImage) => {
 | 
						|
                                if (providedImage === undefined) {
 | 
						|
                                    return
 | 
						|
                                }
 | 
						|
                                relevantUrls.data.push(providedImage)
 | 
						|
                                relevantUrls.ping()
 | 
						|
                            })
 | 
						|
                        }
 | 
						|
                    })
 | 
						|
                }
 | 
						|
            }
 | 
						|
        })
 | 
						|
        return relevantUrls
 | 
						|
    }
 | 
						|
 | 
						|
    public abstract ExtractUrls(key: string, value: string): Promise<Promise<ProvidedImage>[]>
 | 
						|
 | 
						|
    public abstract DownloadAttribution(url: string): Promise<LicenseInfo>
 | 
						|
}
 |