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>
|
|
}
|