forked from MapComplete/MapComplete
		
	More refactoring, still very broken
This commit is contained in:
		
							parent
							
								
									d5d90afc74
								
							
						
					
					
						commit
						62f471df1e
					
				
					 23 changed files with 428 additions and 356 deletions
				
			
		|  | @ -6,14 +6,15 @@ import Combine from "../Base/Combine"; | |||
| import State from "../../State"; | ||||
| import Svg from "../../Svg"; | ||||
| import {Tag} from "../../Logic/Tags/Tag"; | ||||
| import BaseUIElement from "../BaseUIElement"; | ||||
| 
 | ||||
| 
 | ||||
| export default class DeleteImage extends UIElement { | ||||
|     private readonly key: string; | ||||
|     private readonly tags: UIEventSource<any>; | ||||
| 
 | ||||
|     private readonly isDeletedBadge: UIElement; | ||||
|     private readonly deleteDialog: UIElement; | ||||
|     private readonly isDeletedBadge: BaseUIElement; | ||||
|     private readonly deleteDialog: BaseUIElement; | ||||
| 
 | ||||
|     constructor(key: string, tags: UIEventSource<any>) { | ||||
|         super(tags); | ||||
|  |  | |||
|  | @ -6,16 +6,17 @@ import DeleteImage from "./DeleteImage"; | |||
| import {WikimediaImage} from "./WikimediaImage"; | ||||
| import {ImgurImage} from "./ImgurImage"; | ||||
| import {MapillaryImage} from "./MapillaryImage"; | ||||
| import {SimpleImageElement} from "./SimpleImageElement"; | ||||
| import BaseUIElement from "../BaseUIElement"; | ||||
| import Img from "../Base/Img"; | ||||
| 
 | ||||
| export class ImageCarousel extends UIElement{ | ||||
| 
 | ||||
|     public readonly slideshow: UIElement; | ||||
|     public readonly slideshow: BaseUIElement; | ||||
| 
 | ||||
|     constructor(images: UIEventSource<{key: string, url:string}[]>, tags: UIEventSource<any>) { | ||||
|         super(images); | ||||
|         const uiElements = images.map((imageURLS: {key: string, url:string}[]) => { | ||||
|             const uiElements: UIElement[] = []; | ||||
|             const uiElements: BaseUIElement[] = []; | ||||
|             for (const url of imageURLS) { | ||||
|                 let image = ImageCarousel.CreateImageElement(url.url) | ||||
|                 if(url.key !== undefined){ | ||||
|  | @ -41,7 +42,7 @@ export class ImageCarousel extends UIElement{ | |||
|      * @param url | ||||
|      * @constructor | ||||
|      */ | ||||
|     private static CreateImageElement(url: string): UIElement { | ||||
|     private static CreateImageElement(url: string): BaseUIElement { | ||||
|         // @ts-ignore
 | ||||
|         if (url.startsWith("File:")) { | ||||
|             return new WikimediaImage(url); | ||||
|  | @ -53,11 +54,11 @@ export class ImageCarousel extends UIElement{ | |||
|         } else if (url.toLowerCase().startsWith("https://www.mapillary.com/map/im/")) { | ||||
|             return new MapillaryImage(url); | ||||
|         } else { | ||||
|             return new SimpleImageElement(new UIEventSource<string>(url)); | ||||
|             return new Img(url); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     InnerRender(): string { | ||||
|         return this.slideshow.Render(); | ||||
|     InnerRender() { | ||||
|         return this.slideshow; | ||||
|     } | ||||
| } | ||||
|  | @ -1,207 +1,119 @@ | |||
| import $ from "jquery" | ||||
| import {UIEventSource} from "../../Logic/UIEventSource"; | ||||
| import {UIElement} from "../UIElement"; | ||||
| import State from "../../State"; | ||||
| import Combine from "../Base/Combine"; | ||||
| import {FixedUiElement} from "../Base/FixedUiElement"; | ||||
| import {Imgur} from "../../Logic/Web/Imgur"; | ||||
| import {DropDown} from "../Input/DropDown"; | ||||
| import Translations from "../i18n/Translations"; | ||||
| import Svg from "../../Svg"; | ||||
| import {Tag} from "../../Logic/Tags/Tag"; | ||||
| import BaseUIElement from "../BaseUIElement"; | ||||
| import LicensePicker from "../BigComponents/LicensePicker"; | ||||
| import Toggle from "../Input/Toggle"; | ||||
| import FileSelectorButton from "../Base/FileSelectorButton"; | ||||
| import ImgurUploader from "../../Logic/Web/ImgurUploader"; | ||||
| import UploadFlowStateUI from "../BigComponents/UploadFlowStateUI"; | ||||
| import LayerConfig from "../../Customizations/JSON/LayerConfig"; | ||||
| 
 | ||||
| export class ImageUploadFlow extends UIElement { | ||||
|     private readonly _licensePicker: BaseUIElement; | ||||
| 
 | ||||
|     private readonly _element: BaseUIElement; | ||||
| 
 | ||||
| 
 | ||||
|     private readonly _tags: UIEventSource<any>; | ||||
|     private readonly _selectedLicence: UIEventSource<string>; | ||||
|     private readonly _isUploading: UIEventSource<number> = new UIEventSource<number>(0) | ||||
|     private readonly _didFail: UIEventSource<boolean> = new UIEventSource<boolean>(false); | ||||
|     private readonly _allDone: UIEventSource<boolean> = new UIEventSource<boolean>(false); | ||||
|     private readonly _connectButton: UIElement; | ||||
| 
 | ||||
| 
 | ||||
|     private readonly _imagePrefix: string; | ||||
| 
 | ||||
|     constructor(tags: UIEventSource<any>, imagePrefix: string = "image") { | ||||
|     constructor(tagsSource: UIEventSource<any>, imagePrefix: string = "image") { | ||||
|         super(State.state.osmConnection.userDetails); | ||||
|         this._tags = tags; | ||||
|         this._imagePrefix = imagePrefix; | ||||
| 
 | ||||
|         this.ListenTo(this._isUploading); | ||||
|         this.ListenTo(this._didFail); | ||||
|         this.ListenTo(this._allDone); | ||||
| 
 | ||||
|         const licensePicker = new DropDown(Translations.t.image.willBePublished, | ||||
|             [ | ||||
|                 {value: "CC0", shown: Translations.t.image.cco}, | ||||
|                 {value: "CC-BY-SA 4.0", shown: Translations.t.image.ccbs}, | ||||
|                 {value: "CC-BY 4.0", shown: Translations.t.image.ccb} | ||||
|             ], | ||||
|             State.state.osmConnection.GetPreference("pictures-license") | ||||
|         ).SetClass("flex flex-col sm:flex-row"); | ||||
|         licensePicker.SetStyle("float:left"); | ||||
|         const uploader = new ImgurUploader(url => { | ||||
|             // A file was uploaded - we add it to the tags of the object
 | ||||
| 
 | ||||
|         const t = Translations.t.image; | ||||
| 
 | ||||
|         this._licensePicker = licensePicker; | ||||
|         this._selectedLicence = licensePicker.GetValue(); | ||||
| 
 | ||||
|         this._connectButton = t.pleaseLogin.Clone() | ||||
|             .onClick(() => State.state.osmConnection.AttemptLogin()) | ||||
|             .SetClass("login-button-friendly"); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     InnerRender(): string { | ||||
|          | ||||
|         if(!State.state.featureSwitchUserbadge.data){ | ||||
|             return ""; | ||||
|         } | ||||
| 
 | ||||
|         const t = Translations.t.image; | ||||
|         if (State.state.osmConnection.userDetails === undefined) { | ||||
|             return ""; // No user details -> logging in is probably disabled or smthing
 | ||||
|         } | ||||
| 
 | ||||
|         if (!State.state.osmConnection.userDetails.data.loggedIn) { | ||||
|             return this._connectButton.Render(); | ||||
|         } | ||||
| 
 | ||||
|         let currentState: UIElement[] = []; | ||||
|         if (this._isUploading.data == 1) { | ||||
|             currentState.push(t.uploadingPicture); | ||||
|         } else if (this._isUploading.data > 0) { | ||||
|             currentState.push(t.uploadingMultiple.Subs({count: ""+this._isUploading.data})); | ||||
|         } | ||||
| 
 | ||||
|         if (this._didFail.data) { | ||||
|             currentState.push(t.uploadFailed); | ||||
|         } | ||||
| 
 | ||||
|         if (this._allDone.data) { | ||||
|             currentState.push(t.uploadDone) | ||||
|         } | ||||
| 
 | ||||
|         let currentStateHtml : UIElement = new FixedUiElement(""); | ||||
|         if (currentState.length > 0) { | ||||
|             currentStateHtml = new Combine(currentState); | ||||
|             if (!this._allDone.data) { | ||||
|                 currentStateHtml.SetClass("alert"); | ||||
|             }else{ | ||||
|                 currentStateHtml.SetClass("thanks"); | ||||
|             const tags = tagsSource.data | ||||
|             let key = imagePrefix | ||||
|             if (tags[imagePrefix] !== undefined) { | ||||
|                 let freeIndex = 0; | ||||
|                 while (tags[imagePrefix + ":" + freeIndex] !== undefined) { | ||||
|                     freeIndex++; | ||||
|                 } | ||||
|                 key = imagePrefix + ":" + freeIndex; | ||||
|             } | ||||
|             currentStateHtml.SetStyle("display:block ruby") | ||||
|         } | ||||
|             console.log("Adding image:" + key, url); | ||||
|             State.state.changes.addTag(tags.id, new Tag(key, url)); | ||||
|         }) | ||||
| 
 | ||||
|         const extraInfo = new Combine([ | ||||
|             Translations.t.image.respectPrivacy.SetStyle("font-size:small;"), | ||||
|             "<br/>", | ||||
|             this._licensePicker, | ||||
|             "<br/>", | ||||
|             currentStateHtml, | ||||
|             "<br/>" | ||||
|         ]); | ||||
| 
 | ||||
|         const licensePicker = new LicensePicker() | ||||
| 
 | ||||
|         const t = Translations.t.image; | ||||
|         const label = new Combine([ | ||||
|             Svg.camera_plus_svg().SetStyle("width: 36px;height: 36px;padding: 0.1em;margin-top: 5px;border-radius: 0;float: left;display:block"), | ||||
|             Translations.t.image.addPicture | ||||
|         ]).SetClass("image-upload-flow-button") | ||||
|      | ||||
|         const actualInputElement = | ||||
|             `<input style='display: none' id='fileselector-${this.id}' type='file' accept='image/*' name='picField' multiple='multiple' alt=''/>`; | ||||
|          | ||||
|         const form = "<form id='fileselector-form-" + this.id + "'>" + | ||||
|             `<label for='fileselector-${this.id}'>` + | ||||
|             label.Render() + | ||||
|             "</label>" + | ||||
|             actualInputElement + | ||||
|             "</form>"; | ||||
|         const fileSelector = new FileSelectorButton(label) | ||||
|         fileSelector.GetValue().addCallback(filelist => { | ||||
|             if (filelist === undefined) { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|         return new Combine([ | ||||
|             form, | ||||
|             extraInfo | ||||
|             console.log("Received images from the user, starting upload") | ||||
|             const license = this._selectedLicence.data ?? "CC0" | ||||
| 
 | ||||
|             const tags = this._tags.data; | ||||
| 
 | ||||
|             const layout = State.state.layoutToUse.data | ||||
|             let matchingLayer: LayerConfig = undefined | ||||
|             for (const layer of layout.layers) { | ||||
|                 if (layer.source.osmTags.matchesProperties(tags)) { | ||||
|                     matchingLayer = layer; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             const title = matchingLayer?.title?.GetRenderValue(tags)?.ConstructElement().innerText ?? tags.name ?? "Unknown area"; | ||||
|             const description = [ | ||||
|                 "author:" + State.state.osmConnection.userDetails.data.name, | ||||
|                 "license:" + license, | ||||
|                 "osmid:" + tags.id, | ||||
|             ].join("\n"); | ||||
| 
 | ||||
|             uploader.uploadMany(title, description, filelist) | ||||
| 
 | ||||
|         }) | ||||
| 
 | ||||
| 
 | ||||
|         const uploadStateUi = new UploadFlowStateUI(uploader.queue, uploader.failed, uploader.success) | ||||
| 
 | ||||
|         const uploadFlow: BaseUIElement = new Combine([ | ||||
|             fileSelector, | ||||
|             Translations.t.image.respectPrivacy.SetStyle("font-size:small;"), | ||||
|             licensePicker, | ||||
|             uploadStateUi | ||||
|         ]).SetClass("image-upload-flow") | ||||
|             .SetStyle("margin-top: 1em;margin-bottom: 2em;text-align: center;") | ||||
|             .Render(); | ||||
|     } | ||||
|             .SetStyle("margin-top: 1em;margin-bottom: 2em;text-align: center;"); | ||||
| 
 | ||||
| 
 | ||||
|     private handleSuccessfulUpload(url) { | ||||
|         const tags = this._tags.data; | ||||
|         let key = this._imagePrefix; | ||||
|         if (tags[this._imagePrefix] !== undefined) { | ||||
| 
 | ||||
|             let freeIndex = 0; | ||||
|             while (tags[this._imagePrefix + ":" + freeIndex] !== undefined) { | ||||
|                 freeIndex++; | ||||
|             } | ||||
|             key = this._imagePrefix + ":" + freeIndex; | ||||
|         } | ||||
|         console.log("Adding image:" + key, url); | ||||
|         State.state.changes.addTag(tags.id, new Tag(key, url)); | ||||
|     } | ||||
| 
 | ||||
|     private handleFiles(files) { | ||||
|         console.log("Received images from the user, starting upload") | ||||
|         this._isUploading.setData(files.length); | ||||
|         this._allDone.setData(false); | ||||
| 
 | ||||
|         if (this._selectedLicence.data === undefined) { | ||||
|             this._selectedLicence.setData("CC0"); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         const tags = this._tags.data; | ||||
|         const title = tags.name ?? "Unknown area"; | ||||
|         const description = [ | ||||
|             "author:" + State.state.osmConnection.userDetails.data.name, | ||||
|             "license:" + (this._selectedLicence.data ?? "CC0"), | ||||
|             "wikidata:" + tags.wikidata, | ||||
|             "osmid:" + tags.id, | ||||
|             "name:" + tags.name | ||||
|         ].join("\n"); | ||||
| 
 | ||||
|         const self = this; | ||||
| 
 | ||||
|         Imgur.uploadMultiple(title, | ||||
|             description, | ||||
|             files, | ||||
|             function (url) { | ||||
|                 console.log("File saved at", url); | ||||
|                 self._isUploading.setData(self._isUploading.data - 1); | ||||
|                 self.handleSuccessfulUpload(url); | ||||
|             }, | ||||
|             function () { | ||||
|                 console.log("All uploads completed"); | ||||
|                 self._allDone.setData(true); | ||||
|             }, | ||||
|             function (failReason) { | ||||
|                 console.log("Upload failed due to ", failReason) | ||||
|                 // No need to call something from the options -> we handle this here
 | ||||
|                 self._didFail.setData(true); | ||||
|                 self._isUploading.data--; | ||||
|                 self._isUploading.ping(); | ||||
|             }, 0 | ||||
|         const pleaseLoginButton = t.pleaseLogin.Clone() | ||||
|             .onClick(() => State.state.osmConnection.AttemptLogin()) | ||||
|             .SetClass("login-button-friendly"); | ||||
|         this._element = new Toggle( | ||||
|             new Toggle( | ||||
|                 /*We can show the actual upload button!*/ | ||||
|                 uploadFlow, | ||||
|                 /* User not logged in*/ pleaseLoginButton, | ||||
|                 State.state.osmConnection.userDetails.map(userinfo => userinfo.loggedIn) | ||||
|             ), | ||||
|             undefined /* Nothing as the user badge is disabled*/, State.state.featureSwitchUserbadge | ||||
|         ) | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     InnerUpdate(htmlElement: HTMLElement) { | ||||
|         this._licensePicker.Update() | ||||
|         const form = document.getElementById('fileselector-form-' + this.id) as HTMLFormElement | ||||
|         const selector = document.getElementById('fileselector-' + this.id) | ||||
|         const self = this | ||||
| 
 | ||||
|         function submitHandler() { | ||||
|             self.handleFiles($(selector).prop('files')) | ||||
|         } | ||||
| 
 | ||||
|         if (selector != null && form != null) { | ||||
|             selector.onchange = function () { | ||||
|                 submitHandler() | ||||
|             } | ||||
|             form.addEventListener('submit', e => { | ||||
|                 e.preventDefault() | ||||
|                 submitHandler() | ||||
|             }) | ||||
|         } | ||||
|     protected InnerRender(): string | BaseUIElement { | ||||
|         return this._element; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -4,7 +4,8 @@ import {LicenseInfo} from "../../Logic/Web/Wikimedia"; | |||
| import {Imgur} from "../../Logic/Web/Imgur"; | ||||
| import Combine from "../Base/Combine"; | ||||
| import Attribution from "./Attribution"; | ||||
| import {SimpleImageElement} from "./SimpleImageElement"; | ||||
| import BaseUIElement from "../BaseUIElement"; | ||||
| import Img from "../Base/Img"; | ||||
| 
 | ||||
| 
 | ||||
| export class ImgurImage extends UIElement { | ||||
|  | @ -35,11 +36,11 @@ export class ImgurImage extends UIElement { | |||
|        | ||||
|     } | ||||
| 
 | ||||
|     InnerRender(): string { | ||||
|         const image = new SimpleImageElement( new UIEventSource (this._imageLocation)); | ||||
|     InnerRender(): BaseUIElement { | ||||
|         const image = new Img( this._imageLocation); | ||||
|          | ||||
|         if(this._imageMeta.data === null){ | ||||
|             return image.Render(); | ||||
|             return image; | ||||
|         } | ||||
|          | ||||
|         const meta = this._imageMeta.data; | ||||
|  | @ -48,7 +49,7 @@ export class ImgurImage extends UIElement { | |||
|             new Attribution(meta.artist, meta.license, undefined), | ||||
|              | ||||
|         ]).SetClass('block relative') | ||||
|             .Render(); | ||||
|             ; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,9 +3,10 @@ import {UIEventSource} from "../../Logic/UIEventSource"; | |||
| import {LicenseInfo} from "../../Logic/Web/Wikimedia"; | ||||
| import {Mapillary} from "../../Logic/Web/Mapillary"; | ||||
| import Svg from "../../Svg"; | ||||
| import {SimpleImageElement} from "./SimpleImageElement"; | ||||
| import Combine from "../Base/Combine"; | ||||
| import Attribution from "./Attribution"; | ||||
| import Img from "../Base/Img"; | ||||
| import BaseUIElement from "../BaseUIElement"; | ||||
| 
 | ||||
| 
 | ||||
| export class MapillaryImage extends UIElement { | ||||
|  | @ -40,19 +41,19 @@ export class MapillaryImage extends UIElement { | |||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     InnerRender(): string { | ||||
|     InnerRender(): BaseUIElement { | ||||
|         const url = `https://images.mapillary.com/${this._imageLocation}/thumb-640.jpg?client_id=TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2`; | ||||
|         const image = new SimpleImageElement(new UIEventSource<string>(url)) | ||||
|         const image = new Img(url) | ||||
|          | ||||
|         const meta = this._imageMeta?.data; | ||||
|         if (!meta) { | ||||
|             return image.Render(); | ||||
|             return image; | ||||
|         } | ||||
| 
 | ||||
|         return new Combine([ | ||||
|             image, | ||||
|             new Attribution(meta.artist, meta.license, Svg.mapillary_svg()) | ||||
|         ]).SetClass("relative block").Render(); | ||||
|         ]).SetClass("relative block"); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,15 +0,0 @@ | |||
| import {UIElement} from "../UIElement"; | ||||
| import {UIEventSource} from "../../Logic/UIEventSource"; | ||||
| 
 | ||||
| 
 | ||||
| export class SimpleImageElement extends UIElement { | ||||
| 
 | ||||
|     constructor(source: UIEventSource<string>) { | ||||
|         super(source); | ||||
|     } | ||||
| 
 | ||||
|     InnerRender(): string { | ||||
|         return "<img src='" + this._source.data + "' alt='img'>"; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -1,46 +1,22 @@ | |||
| import {UIEventSource} from "../../Logic/UIEventSource"; | ||||
| import {UIElement} from "../UIElement"; | ||||
| import Combine from "../Base/Combine"; | ||||
| // @ts-ignore
 | ||||
| import $ from "jquery" | ||||
| import BaseUIElement from "../BaseUIElement"; | ||||
| 
 | ||||
| export class SlideShow extends UIElement { | ||||
| export class SlideShow extends BaseUIElement { | ||||
| 
 | ||||
|     private readonly _embeddedElements: UIEventSource<UIElement[]> | ||||
| 
 | ||||
|     private  readonly _element: HTMLElement; | ||||
|      | ||||
|     constructor( | ||||
|         embeddedElements: UIEventSource<UIElement[]>) { | ||||
|         super(embeddedElements); | ||||
|         this._embeddedElements = embeddedElements; | ||||
|         this._embeddedElements.addCallbackAndRun(elements => { | ||||
|             for (const element of elements ?? []) { | ||||
|                 element.SetClass("slick-carousel-content") | ||||
|             } | ||||
|         }) | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     InnerRender(): string { | ||||
|         return new Combine( | ||||
|                 this._embeddedElements.data, | ||||
|             ).SetClass("block slick-carousel") | ||||
|             .Render(); | ||||
|     } | ||||
| 
 | ||||
|     Update() { | ||||
|         super.Update(); | ||||
|         for (const uiElement of this._embeddedElements.data) { | ||||
|             uiElement.Update(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     protected InnerUpdate(htmlElement: HTMLElement) { | ||||
|         embeddedElements: UIEventSource<BaseUIElement[]>) { | ||||
|         super() | ||||
|          | ||||
|         const el = document.createElement("div") | ||||
|         this._element = el; | ||||
|          | ||||
|         el.classList.add("slick-carousel") | ||||
|         require("slick-carousel") | ||||
|         if(this._embeddedElements.data.length == 0){ | ||||
|             return; | ||||
|         } | ||||
|         // @ts-ignore
 | ||||
|         $('.slick-carousel').not('.slick-initialized').slick({ | ||||
|         el.slick({ | ||||
|             autoplay: true, | ||||
|             arrows: true, | ||||
|             dots: true, | ||||
|  | @ -48,8 +24,18 @@ export class SlideShow extends UIElement { | |||
|             variableWidth: true, | ||||
|             centerMode: true, | ||||
|             centerPadding: "60px", | ||||
|             adaptive: true   | ||||
|             adaptive: true | ||||
|         }); | ||||
|         embeddedElements.addCallbackAndRun(elements => { | ||||
|             for (const element of elements ?? []) { | ||||
|                 element.SetClass("slick-carousel-content") | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     protected InnerConstructElement(): HTMLElement { | ||||
|         return this._element; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -4,8 +4,9 @@ import {UIEventSource} from "../../Logic/UIEventSource"; | |||
| import Svg from "../../Svg"; | ||||
| import Link from "../Base/Link"; | ||||
| import Combine from "../Base/Combine"; | ||||
| import {SimpleImageElement} from "./SimpleImageElement"; | ||||
| import Attribution from "./Attribution"; | ||||
| import BaseUIElement from "../BaseUIElement"; | ||||
| import Img from "../Base/Img"; | ||||
| 
 | ||||
| 
 | ||||
| export class WikimediaImage extends UIElement { | ||||
|  | @ -34,14 +35,14 @@ export class WikimediaImage extends UIElement { | |||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     InnerRender(): string { | ||||
|     InnerRender(): BaseUIElement { | ||||
|         const url = Wikimedia.ImageNameToUrl(this._imageLocation, 500, 400) | ||||
|             .replace(/'/g, '%27'); | ||||
|         const image = new SimpleImageElement(new UIEventSource<string>(url)) | ||||
|         const image = new Img(url) | ||||
|         const meta = this._imageMeta?.data; | ||||
| 
 | ||||
|         if (!meta) { | ||||
|             return image.Render(); | ||||
|             return image; | ||||
|         } | ||||
|         new Link(Svg.wikimedia_commons_white_img, | ||||
|             `https://commons.wikimedia.org/wiki/${this._imageLocation}`, true) | ||||
|  | @ -50,7 +51,7 @@ export class WikimediaImage extends UIElement { | |||
|         return new Combine([ | ||||
|             image, | ||||
|             new Attribution(meta.artist, meta.license, Svg.wikimedia_commons_white_svg()) | ||||
|         ]).SetClass("relative block").Render() | ||||
|         ]).SetClass("relative block") | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue