mapcomplete/UI/Popup/FeatureInfoBox.ts

151 lines
4.8 KiB
TypeScript
Raw Normal View History

2020-10-14 12:15:09 +02:00
import {VerticalCombine} from "../Base/VerticalCombine";
import {UIElement} from "../UIElement";
import Combine from "../Base/Combine";
import {WikipediaLink} from "../../Customizations/Questions/WikipediaLink";
import {OsmLink} from "../../Customizations/Questions/OsmLink";
import {UIEventSource} from "../../Logic/UIEventSource";
import {TagRenderingOptions} from "../../Customizations/TagRenderingOptions";
import State from "../../State";
import {And} from "../../Logic/Tags";
import {TagDependantUIElement, TagDependantUIElementConstructor} from "../../Customizations/UIElementConstructor";
import {FixedUiElement} from "../Base/FixedUiElement";
import Translations from "../i18n/Translations";
export class FeatureInfoBox extends UIElement {
/**
* The actual GEOJSON-object, with geometry and stuff
*/
private _feature: any;
/**
* The tags, wrapped in a global event source
*/
private readonly _tagsES: UIEventSource<any>;
private readonly _title: UIElement;
private readonly _infoboxes: TagDependantUIElement[];
private readonly _oneSkipped = Translations.t.general.oneSkippedQuestion.Clone();
private readonly _someSkipped = Translations.t.general.skippedQuestions.Clone();
constructor(
feature: any,
tagsES: UIEventSource<any>,
title: TagDependantUIElementConstructor | UIElement | string,
2020-07-21 00:07:04 +02:00
elementsToShow: TagDependantUIElementConstructor[],
) {
super(tagsES);
this._feature = feature;
2020-10-14 12:15:09 +02:00
this._tagsES = tagsES
if(tagsES === undefined){
throw "No Tags event source given"
}
this.ListenTo(State.state.osmConnection.userDetails);
2020-09-14 20:16:03 +02:00
this.SetClass("featureinfobox");
2020-10-14 12:15:09 +02:00
const tags = this._tagsES;
2020-07-05 18:59:47 +02:00
this._infoboxes = [];
elementsToShow = elementsToShow ?? []
const self = this;
2020-07-05 18:59:47 +02:00
for (const tagRenderingOption of elementsToShow) {
self._infoboxes.push(
2020-10-14 12:15:09 +02:00
tagRenderingOption.construct(tags));
}
function initTags() {
self._infoboxes.splice(0, self._infoboxes.length);
for (const tagRenderingOption of elementsToShow) {
self._infoboxes.push(
2020-10-14 12:15:09 +02:00
tagRenderingOption.construct(tags));
}
self.Update();
}
this._someSkipped.onClick(initTags)
this._oneSkipped.onClick(initTags)
2020-09-13 00:53:24 +02:00
let renderedTitle: UIElement;
2020-07-05 18:59:47 +02:00
title = title ?? new TagRenderingOptions(
{
mappings: [{k: new And([]), txt: ""}]
}
)
2020-07-30 09:59:30 +02:00
if (typeof (title) == "string") {
2020-09-13 00:53:24 +02:00
renderedTitle = new FixedUiElement(title);
2020-07-30 09:59:30 +02:00
} else if (title instanceof UIElement) {
2020-09-13 00:53:24 +02:00
renderedTitle = title;
} else {
2020-10-14 12:15:09 +02:00
renderedTitle = title.construct(tags);
}
2020-09-13 00:53:24 +02:00
renderedTitle
.SetStyle("width: calc(100% - 50px - 0.2em);")
.SetClass("title-font")
const osmLink = new OsmLink()
2020-10-14 12:15:09 +02:00
.construct(tags)
2020-09-13 00:53:24 +02:00
.SetStyle("width: 24px; display:block;")
const wikipedialink = new WikipediaLink()
2020-10-14 12:15:09 +02:00
.construct(tags)
2020-09-13 00:53:24 +02:00
.SetStyle("width: 24px; display:block;")
this._title = new Combine([
renderedTitle,
wikipedialink,
osmLink]).SetStyle("display:flex;");
}
InnerRender(): string {
2020-07-05 18:59:47 +02:00
const info = [];
const questions: TagDependantUIElement[] = [];
let skippedQuestions = 0;
2020-07-05 18:59:47 +02:00
for (const infobox of this._infoboxes) {
if (infobox.IsKnown()) {
info.push(infobox);
} else if (infobox.IsQuestioning()) {
questions.push(infobox);
} else if (infobox.IsSkipped()) {
// This question is neither known nor questioning -> it was skipped
skippedQuestions++;
2020-07-05 18:59:47 +02:00
}
}
let questionElement: UIElement;
2020-07-05 18:59:47 +02:00
2020-09-17 13:13:02 +02:00
if (questions.length > 0) {
2020-07-05 18:59:47 +02:00
// We select the most important question and render that one
let mostImportantQuestion;
for (const question of questions) {
2020-09-17 13:13:02 +02:00
if (mostImportantQuestion === undefined) {
2020-07-05 18:59:47 +02:00
mostImportantQuestion = question;
2020-09-17 13:13:02 +02:00
break;
2020-07-05 18:59:47 +02:00
}
}
questionElement = mostImportantQuestion;
} else if (skippedQuestions == 1) {
questionElement = this._oneSkipped;
} else if (skippedQuestions > 0) {
questionElement = this._someSkipped;
}
const infoboxcontents = new Combine(
[new VerticalCombine(info).SetClass("infobox-information")
, questionElement ?? ""]);
2020-09-13 00:53:24 +02:00
return new Combine([
this._title,
"<div class='infoboxcontents'>",
infoboxcontents,
2020-09-14 20:16:03 +02:00
"</div>"])
2020-09-13 00:53:24 +02:00
.Render();
}
2020-07-20 09:57:19 +02:00
2020-07-20 15:54:50 +02:00
}