forked from MapComplete/MapComplete
		
	Graciously handle multiple entries in wikidata for fetching images and showing articles, verious bug fixes
This commit is contained in:
		
							parent
							
								
									8d52ef1106
								
							
						
					
					
						commit
						a996ba2a7c
					
				
					 14 changed files with 231 additions and 90 deletions
				
			
		| 
						 | 
					@ -1,9 +1,12 @@
 | 
				
			||||||
import {UIEventSource} from "../UIEventSource";
 | 
					import {UIEventSource} from "../UIEventSource";
 | 
				
			||||||
import BaseUIElement from "../../UI/BaseUIElement";
 | 
					import BaseUIElement from "../../UI/BaseUIElement";
 | 
				
			||||||
import {LicenseInfo} from "./LicenseInfo";
 | 
					import {LicenseInfo} from "./LicenseInfo";
 | 
				
			||||||
 | 
					import {Utils} from "../../Utils";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface ProvidedImage {
 | 
					export interface ProvidedImage {
 | 
				
			||||||
    url: string, key: string, provider: ImageProvider
 | 
					    url: string,
 | 
				
			||||||
 | 
					    key: string,
 | 
				
			||||||
 | 
					    provider: ImageProvider
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default abstract class ImageProvider {
 | 
					export default abstract class ImageProvider {
 | 
				
			||||||
| 
						 | 
					@ -44,12 +47,15 @@ export default abstract class ImageProvider {
 | 
				
			||||||
                if (!prefixes.some(prefix => key.startsWith(prefix))) {
 | 
					                if (!prefixes.some(prefix => key.startsWith(prefix))) {
 | 
				
			||||||
                    continue
 | 
					                    continue
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                const value = tags[key]
 | 
					                const values = Utils.NoEmpty(tags[key]?.split(";")?.map(v => v.trim()) ?? [])
 | 
				
			||||||
 | 
					                for (const value of values) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (seenValues.has(value)) {
 | 
					                    if (seenValues.has(value)) {
 | 
				
			||||||
                        continue
 | 
					                        continue
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    seenValues.add(value)
 | 
					                    seenValues.add(value)
 | 
				
			||||||
                    this.ExtractUrls(key, value).then(promises => {
 | 
					                    this.ExtractUrls(key, value).then(promises => {
 | 
				
			||||||
 | 
					                        console.log("Got ", promises.length, "promises for", value,"by",self.constructor.name)
 | 
				
			||||||
                        for (const promise of promises ?? []) {
 | 
					                        for (const promise of promises ?? []) {
 | 
				
			||||||
                            if (promise === undefined) {
 | 
					                            if (promise === undefined) {
 | 
				
			||||||
                                continue
 | 
					                                continue
 | 
				
			||||||
| 
						 | 
					@ -64,6 +70,9 @@ export default abstract class ImageProvider {
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    })
 | 
					                    })
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        return relevantUrls
 | 
					        return relevantUrls
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
export class LicenseInfo {
 | 
					export class LicenseInfo {
 | 
				
			||||||
 | 
					    title: string = ""
 | 
				
			||||||
    artist: string = "";
 | 
					    artist: string = "";
 | 
				
			||||||
    license: string = "";
 | 
					    license: string = "";
 | 
				
			||||||
    licenseShortName: string = "";
 | 
					    licenseShortName: string = "";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,12 +65,26 @@ export class WikimediaImageProvider extends ImageProvider {
 | 
				
			||||||
            "&format=json&origin=*";
 | 
					            "&format=json&origin=*";
 | 
				
			||||||
        const data = await Utils.downloadJson(url)
 | 
					        const data = await Utils.downloadJson(url)
 | 
				
			||||||
        const licenseInfo = new LicenseInfo();
 | 
					        const licenseInfo = new LicenseInfo();
 | 
				
			||||||
        const license = (data.query.pages[-1].imageinfo ?? [])[0]?.extmetadata;
 | 
					        const pageInfo = data.query.pages[-1]
 | 
				
			||||||
 | 
					        if(pageInfo === undefined){
 | 
				
			||||||
 | 
					            return undefined;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        const license = (pageInfo.imageinfo ?? [])[0]?.extmetadata;
 | 
				
			||||||
        if (license === undefined) {
 | 
					        if (license === undefined) {
 | 
				
			||||||
            console.warn("The file", filename ,"has no usable metedata or license attached... Please fix the license info file yourself!")
 | 
					            console.warn("The file", filename ,"has no usable metedata or license attached... Please fix the license info file yourself!")
 | 
				
			||||||
            return undefined;
 | 
					            return undefined;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let title = pageInfo.title
 | 
				
			||||||
 | 
					        if(title.startsWith("File:")){
 | 
				
			||||||
 | 
					            title=  title.substr("File:".length)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if(title.endsWith(".jpg") || title.endsWith(".png")){
 | 
				
			||||||
 | 
					            title = title.substring(0, title.length - 4)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        licenseInfo.title = title
 | 
				
			||||||
        licenseInfo.artist = license.Artist?.value;
 | 
					        licenseInfo.artist = license.Artist?.value;
 | 
				
			||||||
        licenseInfo.license = license.License?.value;
 | 
					        licenseInfo.license = license.License?.value;
 | 
				
			||||||
        licenseInfo.copyrighted = license.Copyrighted?.value;
 | 
					        licenseInfo.copyrighted = license.Copyrighted?.value;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,7 +47,7 @@ export default class Wikidata {
 | 
				
			||||||
            const claimsList: any[] = entity.claims[claimId]
 | 
					            const claimsList: any[] = entity.claims[claimId]
 | 
				
			||||||
            const values = new Set<string>()
 | 
					            const values = new Set<string>()
 | 
				
			||||||
            for (const claim of claimsList) {
 | 
					            for (const claim of claimsList) {
 | 
				
			||||||
                const value = claim.mainsnak?.datavalueq?.value;
 | 
					                const value = claim.mainsnak?.datavalue?.value;
 | 
				
			||||||
                if(value !== undefined){
 | 
					                if(value !== undefined){
 | 
				
			||||||
                    values.add(value)
 | 
					                    values.add(value)
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,10 @@ export default class Wikipedia {
 | 
				
			||||||
        "hatnote" // Often redirects
 | 
					        "hatnote" // Often redirects
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    private static readonly idsToRemove = [
 | 
				
			||||||
 | 
					        "sjabloon_zie"
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static readonly _cache = new Map<string, UIEventSource<{ success: string } | { error: any }>>()
 | 
					    private static readonly _cache = new Map<string, UIEventSource<{ success: string } | { error: any }>>()
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    public static GetArticle(options: {
 | 
					    public static GetArticle(options: {
 | 
				
			||||||
| 
						 | 
					@ -59,6 +63,13 @@ export default class Wikipedia {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (const forbiddenId of Wikipedia.idsToRemove) {
 | 
				
			||||||
 | 
					            const toRemove = content.querySelector("#"+forbiddenId)
 | 
				
			||||||
 | 
					            toRemove?.parentElement?.removeChild(toRemove)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const links = Array.from(content.getElementsByTagName("a"))
 | 
					        const links = Array.from(content.getElementsByTagName("a"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Rewrite relative links to absolute links + open them in a new tab
 | 
					        // Rewrite relative links to absolute links + open them in a new tab
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,11 +6,16 @@ import {VariableUiElement} from "./VariableUIElement";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class TabbedComponent extends Combine {
 | 
					export class TabbedComponent extends Combine {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(elements: { header: BaseUIElement | string, content: BaseUIElement | string }[], openedTab: (UIEventSource<number> | number) = 0) {
 | 
					    constructor(elements: { header: BaseUIElement | string, content: BaseUIElement | string }[], 
 | 
				
			||||||
 | 
					                openedTab: (UIEventSource<number> | number) = 0,
 | 
				
			||||||
 | 
					                options?: {
 | 
				
			||||||
 | 
					                    leftOfHeader?: BaseUIElement
 | 
				
			||||||
 | 
					                    styleHeader?: (header: BaseUIElement) => void
 | 
				
			||||||
 | 
					                }) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const openedTabSrc = typeof (openedTab) === "number" ? new UIEventSource(openedTab) : (openedTab ?? new UIEventSource<number>(0))
 | 
					        const openedTabSrc = typeof (openedTab) === "number" ? new UIEventSource(openedTab) : (openedTab ?? new UIEventSource<number>(0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const tabs: BaseUIElement[] = []
 | 
					        const tabs: BaseUIElement[] = [options?.leftOfHeader ]
 | 
				
			||||||
        const contentElements: BaseUIElement[] = [];
 | 
					        const contentElements: BaseUIElement[] = [];
 | 
				
			||||||
        for (let i = 0; i < elements.length; i++) {
 | 
					        for (let i = 0; i < elements.length; i++) {
 | 
				
			||||||
            let element = elements[i];
 | 
					            let element = elements[i];
 | 
				
			||||||
| 
						 | 
					@ -25,16 +30,19 @@ export class TabbedComponent extends Combine {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
            const content = Translations.W(element.content)
 | 
					            const content = Translations.W(element.content)
 | 
				
			||||||
            content.SetClass("relative p-4 w-full inline-block")
 | 
					            content.SetClass("relative w-full inline-block")
 | 
				
			||||||
            contentElements.push(content);
 | 
					            contentElements.push(content);
 | 
				
			||||||
            const tab = header.SetClass("block tab-single-header")
 | 
					            const tab = header.SetClass("block tab-single-header")
 | 
				
			||||||
            tabs.push(tab)
 | 
					            tabs.push(tab)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const header = new Combine(tabs).SetClass("tabs-header-bar")
 | 
					        const header = new Combine(tabs).SetClass("tabs-header-bar")
 | 
				
			||||||
 | 
					        if(options?.styleHeader){
 | 
				
			||||||
 | 
					            options.styleHeader(header)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        const actualContent = new VariableUiElement(
 | 
					        const actualContent = new VariableUiElement(
 | 
				
			||||||
            openedTabSrc.map(i => contentElements[i])
 | 
					            openedTabSrc.map(i => contentElements[i])
 | 
				
			||||||
        )
 | 
					        ).SetStyle("max-height: inherit; height: inherit")
 | 
				
			||||||
        super([header, actualContent])
 | 
					        super([header, actualContent])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,6 +73,9 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tabs.forEach(c => c.content.SetClass("p-4"))
 | 
				
			||||||
 | 
					        tabsWithAboutMc.forEach(c => c.content.SetClass("p-4"))
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        return new Toggle(
 | 
					        return new Toggle(
 | 
				
			||||||
            new TabbedComponent(tabsWithAboutMc, State.state.welcomeMessageOpenedTab),
 | 
					            new TabbedComponent(tabsWithAboutMc, State.state.welcomeMessageOpenedTab),
 | 
				
			||||||
            new TabbedComponent(tabs, State.state.welcomeMessageOpenedTab),
 | 
					            new TabbedComponent(tabs, State.state.welcomeMessageOpenedTab),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,10 +21,11 @@ export default class Attribution extends VariableUiElement {
 | 
				
			||||||
                    icon?.SetClass("block left").SetStyle("height: 2em; width: 2em; padding-right: 0.5em;"),
 | 
					                    icon?.SetClass("block left").SetStyle("height: 2em; width: 2em; padding-right: 0.5em;"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    new Combine([
 | 
					                    new Combine([
 | 
				
			||||||
                        Translations.W(license?.artist ?? ".").SetClass("block font-bold"),
 | 
					                        Translations.W(license?.title).SetClass("block"),
 | 
				
			||||||
 | 
					                        Translations.W(license?.artist ?? "").SetClass("block font-bold"),
 | 
				
			||||||
                        Translations.W((license?.license ?? "") === "" ? "CC0" : (license?.license ?? ""))
 | 
					                        Translations.W((license?.license ?? "") === "" ? "CC0" : (license?.license ?? ""))
 | 
				
			||||||
                    ]).SetClass("flex flex-col")
 | 
					                    ]).SetClass("flex flex-col")
 | 
				
			||||||
                ]).SetClass("flex flex-row bg-black text-white text-sm absolute bottom-0 left-0 p-0.5 pl-5 pr-3 rounded-lg")
 | 
					                ]).SetClass("flex flex-row bg-black text-white text-sm absolute bottom-0 left-0 p-0.5 pl-5 pr-3 rounded-lg no-images")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }));
 | 
					            }));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,7 +100,16 @@ export default class SpecialVisualizations {
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
                example: "`{wikipedia()}` is a basic example, `{wikipedia(name:etymology:wikidata)}` to show the wikipedia page of whom the feature was named after. Also remember that these can be styled, e.g. `{wikipedia():max-height: 10rem}` to limit the height",
 | 
					                example: "`{wikipedia()}` is a basic example, `{wikipedia(name:etymology:wikidata)}` to show the wikipedia page of whom the feature was named after. Also remember that these can be styled, e.g. `{wikipedia():max-height: 10rem}` to limit the height",
 | 
				
			||||||
                constr: (_, tagsSource, args) =>
 | 
					                constr: (_, tagsSource, args) =>
 | 
				
			||||||
                      new WikipediaBox( tagsSource.map(tags => tags[args[0]]))
 | 
					                    new VariableUiElement(
 | 
				
			||||||
 | 
					                        tagsSource.map(tags => tags[args[0]])
 | 
				
			||||||
 | 
					                            .map(wikidata => {
 | 
				
			||||||
 | 
					                                const wikidatas : string[] = 
 | 
				
			||||||
 | 
					                                    Utils.NoEmpty(wikidata?.split(";")?.map(wd => wd.trim()) ?? [])
 | 
				
			||||||
 | 
					                                return new WikipediaBox(wikidatas)
 | 
				
			||||||
 | 
					                            })
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                  
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                funcName: "minimap",
 | 
					                funcName: "minimap",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,27 +10,73 @@ import Translations from "./i18n/Translations";
 | 
				
			||||||
import Svg from "../Svg";
 | 
					import Svg from "../Svg";
 | 
				
			||||||
import Wikidata, {WikidataResponse} from "../Logic/Web/Wikidata";
 | 
					import Wikidata, {WikidataResponse} from "../Logic/Web/Wikidata";
 | 
				
			||||||
import Locale from "./i18n/Locale";
 | 
					import Locale from "./i18n/Locale";
 | 
				
			||||||
import Toggle from "./Input/Toggle";
 | 
					 | 
				
			||||||
import Link from "./Base/Link";
 | 
					import Link from "./Base/Link";
 | 
				
			||||||
 | 
					import {TabbedComponent} from "./Base/TabbedComponent";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class WikipediaBox extends Toggle {
 | 
					export default class WikipediaBox extends Combine {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(wikidataId: string | UIEventSource<string>) {
 | 
					    constructor(wikidataIds: string[]) {
 | 
				
			||||||
        const wp = Translations.t.general.wikipedia;
 | 
					
 | 
				
			||||||
        if (typeof wikidataId === "string") {
 | 
					        const mainContents = []
 | 
				
			||||||
            wikidataId = new UIEventSource(wikidataId)
 | 
					
 | 
				
			||||||
 | 
					        const pages = wikidataIds.map(wdId => WikipediaBox.createLinkedContent(wdId))
 | 
				
			||||||
 | 
					        if (wikidataIds.length == 1) {
 | 
				
			||||||
 | 
					            const page = pages[0]
 | 
				
			||||||
 | 
					            mainContents.push(
 | 
				
			||||||
 | 
					                new Combine([
 | 
				
			||||||
 | 
					                    new Combine([Svg.wikipedia_ui()
 | 
				
			||||||
 | 
					                        .SetStyle("width: 1.5rem").SetClass("inline-block mr-3"), page.titleElement])
 | 
				
			||||||
 | 
					                        .SetClass("flex"),
 | 
				
			||||||
 | 
					                    page.linkElement
 | 
				
			||||||
 | 
					                ]).SetClass("flex justify-between align-middle"),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            mainContents.push(page.contents)
 | 
				
			||||||
 | 
					        } else if (wikidataIds.length > 1) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const tabbed = new TabbedComponent(
 | 
				
			||||||
 | 
					                pages.map(page => {
 | 
				
			||||||
 | 
					                    const contents = page.contents.SetClass("block").SetStyle("max-height: inherit; height: inherit; padding-bottom: 3.3rem")
 | 
				
			||||||
 | 
					                    return {
 | 
				
			||||||
 | 
					                        header: page.titleElement.SetClass("pl-2 pr-2"),
 | 
				
			||||||
 | 
					                        content: new Combine([
 | 
				
			||||||
 | 
					                            page.linkElement
 | 
				
			||||||
 | 
					                                .SetStyle("top: 2rem; right: 2.5rem;")
 | 
				
			||||||
 | 
					                                .SetClass("absolute subtle-background rounded-full p-3 opacity-50 hover:opacity-100 transition-opacity"),
 | 
				
			||||||
 | 
					                            contents
 | 
				
			||||||
 | 
					                        ]).SetStyle("max-height: inherit; height: inherit").SetClass("relative")
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                }),
 | 
				
			||||||
 | 
					                0,
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    leftOfHeader: Svg.wikipedia_ui().SetStyle("width: 1.5rem; align-self: center;").SetClass("mr-4"),
 | 
				
			||||||
 | 
					                    styleHeader: header => header.SetClass("subtle-background").SetStyle("height: 3.3rem")
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            tabbed.SetStyle("height: inherit; max-height: inherit; overflow: hidden")
 | 
				
			||||||
 | 
					            mainContents.push(tabbed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        super(mainContents)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.SetClass("block rounded-xl subtle-background m-1 p-2 flex flex-col")
 | 
				
			||||||
 | 
					            .SetStyle("max-height: inherit")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static createLinkedContent(wikidataId: string): {
 | 
				
			||||||
 | 
					        titleElement: BaseUIElement,
 | 
				
			||||||
 | 
					        contents: BaseUIElement,
 | 
				
			||||||
 | 
					        linkElement: BaseUIElement
 | 
				
			||||||
 | 
					    } {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const wp = Translations.t.general.wikipedia;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const wikiLink: UIEventSource<[string, string] | "loading" | "failed" | "no page"> =
 | 
					        const wikiLink: UIEventSource<[string, string] | "loading" | "failed" | "no page"> =
 | 
				
			||||||
            wikidataId
 | 
					            Wikidata.LoadWikidataEntry(wikidataId)
 | 
				
			||||||
                .bind(id => {
 | 
					 | 
				
			||||||
                    if (id === undefined) {
 | 
					 | 
				
			||||||
                        return undefined
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    return Wikidata.LoadWikidataEntry(id);
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                .map(maybewikidata => {
 | 
					                .map(maybewikidata => {
 | 
				
			||||||
                    if (maybewikidata === undefined) {
 | 
					                    if (maybewikidata === undefined) {
 | 
				
			||||||
                        return "loading"
 | 
					                        return "loading"
 | 
				
			||||||
| 
						 | 
					@ -77,32 +123,33 @@ export default class WikipediaBox extends Toggle {
 | 
				
			||||||
        ).SetClass("overflow-auto normal-background rounded-lg")
 | 
					        ).SetClass("overflow-auto normal-background rounded-lg")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const titleElement = new VariableUiElement(wikiLink.map(state => {
 | 
				
			||||||
 | 
					            if (typeof state !== "string") {
 | 
				
			||||||
 | 
					                const [pagetitle, language] = state
 | 
				
			||||||
 | 
					                return new Title(pagetitle, 3)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            //return new Title(Translations.t.general.wikipedia.wikipediaboxTitle.Clone(), 2)
 | 
				
			||||||
 | 
					            return new Title(wikidataId,3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const linkElement = new VariableUiElement(wikiLink.map(state => {
 | 
					        const linkElement = new VariableUiElement(wikiLink.map(state => {
 | 
				
			||||||
            if (typeof state !== "string") {
 | 
					            if (typeof state !== "string") {
 | 
				
			||||||
                const [pagetitle, language] = state
 | 
					                const [pagetitle, language] = state
 | 
				
			||||||
                const url = `https://${language}.wikipedia.org/wiki/${pagetitle}`
 | 
					                const url = `https://${language}.wikipedia.org/wiki/${pagetitle}`
 | 
				
			||||||
                return new Link(Svg.pop_out_ui().SetStyle("width: 1.2rem").SetClass("block  "), url, true)
 | 
					                return new Link(Svg.pop_out_ui().SetStyle("width: 1.2rem").SetClass("block  "), url, true)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return undefined}))
 | 
					            return undefined
 | 
				
			||||||
 | 
					        }))
 | 
				
			||||||
            .SetClass("flex items-center")
 | 
					            .SetClass("flex items-center")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const mainContent = new Combine([
 | 
					        return {
 | 
				
			||||||
           new Combine([
 | 
					            contents: contents,
 | 
				
			||||||
               new Combine([
 | 
					            linkElement: linkElement,
 | 
				
			||||||
                Svg.wikipedia_ui().SetStyle("width: 1.5rem").SetClass("mr-3"),
 | 
					            titleElement: titleElement
 | 
				
			||||||
                new Title(Translations.t.general.wikipedia.wikipediaboxTitle.Clone(), 2),
 | 
					 | 
				
			||||||
               ]).SetClass("flex"),
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
               linkElement
 | 
					 | 
				
			||||||
            ]).SetClass("flex justify-between"),
 | 
					 | 
				
			||||||
            contents]).SetClass("block rounded-xl subtle-background m-1 p-2 flex flex-col")
 | 
					 | 
				
			||||||
            .SetStyle("max-height: inherit")
 | 
					 | 
				
			||||||
        super(
 | 
					 | 
				
			||||||
            mainContent,
 | 
					 | 
				
			||||||
            undefined,
 | 
					 | 
				
			||||||
            wikidataId.map(id => id !== undefined)
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns the actual content in a scrollable way
 | 
					     * Returns the actual content in a scrollable way
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -852,14 +852,14 @@ video {
 | 
				
			||||||
  margin-right: 0.75rem;
 | 
					  margin-right: 0.75rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mb-2 {
 | 
					 | 
				
			||||||
  margin-bottom: 0.5rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.mr-4 {
 | 
					.mr-4 {
 | 
				
			||||||
  margin-right: 1rem;
 | 
					  margin-right: 1rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.mb-2 {
 | 
				
			||||||
 | 
					  margin-bottom: 0.5rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mt-3 {
 | 
					.mt-3 {
 | 
				
			||||||
  margin-top: 0.75rem;
 | 
					  margin-top: 0.75rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1251,14 +1251,14 @@ video {
 | 
				
			||||||
  border-radius: 0.25rem;
 | 
					  border-radius: 0.25rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.rounded-lg {
 | 
					 | 
				
			||||||
  border-radius: 0.5rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.rounded-xl {
 | 
					.rounded-xl {
 | 
				
			||||||
  border-radius: 0.75rem;
 | 
					  border-radius: 0.75rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.rounded-lg {
 | 
				
			||||||
 | 
					  border-radius: 0.5rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.border {
 | 
					.border {
 | 
				
			||||||
  border-width: 1px;
 | 
					  border-width: 1px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1386,6 +1386,14 @@ video {
 | 
				
			||||||
  padding: 0px;
 | 
					  padding: 0px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pl-2 {
 | 
				
			||||||
 | 
					  padding-left: 0.5rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pr-2 {
 | 
				
			||||||
 | 
					  padding-right: 0.5rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pl-6 {
 | 
					.pl-6 {
 | 
				
			||||||
  padding-left: 1.5rem;
 | 
					  padding-left: 1.5rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1394,10 +1402,6 @@ video {
 | 
				
			||||||
  padding-top: 0.5rem;
 | 
					  padding-top: 0.5rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pl-2 {
 | 
					 | 
				
			||||||
  padding-left: 0.5rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.pt-3 {
 | 
					.pt-3 {
 | 
				
			||||||
  padding-top: 0.75rem;
 | 
					  padding-top: 0.75rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1458,10 +1462,6 @@ video {
 | 
				
			||||||
  padding-top: 0px;
 | 
					  padding-top: 0px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pr-2 {
 | 
					 | 
				
			||||||
  padding-right: 0.5rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.text-center {
 | 
					.text-center {
 | 
				
			||||||
  text-align: center;
 | 
					  text-align: center;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1582,6 +1582,10 @@ video {
 | 
				
			||||||
  text-decoration: underline;
 | 
					  text-decoration: underline;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.opacity-50 {
 | 
				
			||||||
 | 
					  opacity: 0.5;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.opacity-0 {
 | 
					.opacity-0 {
 | 
				
			||||||
  opacity: 0;
 | 
					  opacity: 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1628,6 +1632,12 @@ video {
 | 
				
			||||||
  transition-duration: 150ms;
 | 
					  transition-duration: 150ms;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.transition-opacity {
 | 
				
			||||||
 | 
					  transition-property: opacity;
 | 
				
			||||||
 | 
					  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
 | 
				
			||||||
 | 
					  transition-duration: 150ms;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.\!transition {
 | 
					.\!transition {
 | 
				
			||||||
  transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter !important;
 | 
					  transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter !important;
 | 
				
			||||||
  transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter !important;
 | 
					  transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter !important;
 | 
				
			||||||
| 
						 | 
					@ -1788,6 +1798,10 @@ svg, img {
 | 
				
			||||||
  height: 100%;
 | 
					  height: 100%;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.no-images img {
 | 
				
			||||||
 | 
					  display: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mapcontrol svg path {
 | 
					.mapcontrol svg path {
 | 
				
			||||||
  fill: var(--subtle-detail-color-contrast) !important;
 | 
					  fill: var(--subtle-detail-color-contrast) !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2189,6 +2203,10 @@ li::marker {
 | 
				
			||||||
  color: rgba(30, 64, 175, var(--tw-text-opacity));
 | 
					  color: rgba(30, 64, 175, var(--tw-text-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.hover\:opacity-100:hover {
 | 
				
			||||||
 | 
					  opacity: 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.hover\:shadow-xl:hover {
 | 
					.hover\:shadow-xl:hover {
 | 
				
			||||||
  --tw-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
 | 
					  --tw-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
 | 
				
			||||||
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
 | 
					  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@
 | 
				
			||||||
    justify-content: flex-start;
 | 
					    justify-content: flex-start;
 | 
				
			||||||
    align-items: start;
 | 
					    align-items: start;
 | 
				
			||||||
    background-color: var(--background-color);
 | 
					    background-color: var(--background-color);
 | 
				
			||||||
    max-width: 100vw;
 | 
					    max-width: 100%;
 | 
				
			||||||
    overflow-x: auto;
 | 
					    overflow-x: auto;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,6 +93,10 @@ svg, img {
 | 
				
			||||||
    height: 100%;
 | 
					    height: 100%;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.no-images img {
 | 
				
			||||||
 | 
					    display: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mapcontrol svg path {
 | 
					.mapcontrol svg path {
 | 
				
			||||||
    fill: var(--subtle-detail-color-contrast) !important;
 | 
					    fill: var(--subtle-detail-color-contrast) !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue