Fixes and simplification of the CSS

This commit is contained in:
Pieter Vander Vennet 2020-09-12 23:15:17 +02:00
parent c7f33a9490
commit 6d5f4ade25
24 changed files with 191 additions and 344 deletions

View file

@ -88,23 +88,25 @@ export class FromJSON {
return layout;
}
public static Translation(json: string | any): string | Translation {
public static Translation(json: string | any): Translation {
if (json === undefined) {
return undefined;
}
if (typeof (json) === "string") {
return json;
return new Translation({"*": json});
}
const tr = {};
let keyCount = 0;
for (let key in json) {
keyCount ++;
keyCount++;
tr[key] = json[key]; // I'm doing this wrong, I know
}
if(keyCount == 0){
return undefined;
}
return new Translation(tr);
const transl = new Translation(tr);
transl.addCallback(latest => console.log("tr callback changed to", latest));
return transl;
}
public static TagRendering(json: TagRenderingConfigJson | string, propertyeName: string): TagDependantUIElementConstructor {

View file

@ -103,12 +103,4 @@ class OnlyShowIf extends UIElement implements TagDependantUIElement {
return this._embedded.IsQuestioning();
}
Activate(): UIElement {
this._embedded.Activate();
return this;
}
Update(): void {
this._embedded.Update();
}
}

View file

@ -199,6 +199,10 @@ export class InitUiElements {
new GeoLocationHandler().AttachTo("geolocate-button");
State.state.locationControl.ping();
// This 'leaks' the global state via the window object, useful for debugging
// @ts-ignore
window.mapcomplete_state = State.state;
}
@ -255,7 +259,8 @@ export class InitUiElements {
const tabs = [
{header: Img.AsImageElement(layoutToUse.icon), content: welcome},
{header: `<img src='./assets/osm-logo.svg'>`, content: Translations.t.general.openStreetMapIntro},
{header: `<img src='./assets/osm-logo.svg'>`, content:
Translations.t.general.openStreetMapIntro},
]
@ -289,9 +294,8 @@ export class InitUiElements {
);
const fullOptions = new TabbedComponent(tabs, State.state.welcomeMessageOpenedTab);
fullOptions.ListenTo(State.state.osmConnection.userDetails);
return fullOptions;
return new TabbedComponent(tabs, State.state.welcomeMessageOpenedTab)
.ListenTo(State.state.osmConnection.userDetails);
}
@ -313,7 +317,7 @@ export class InitUiElements {
const openedTime = new Date().getTime();
State.state.locationControl.addCallback(() => {
if (new Date().getTime() - openedTime < 15 * 1000) {
// Don't autoclose the first 15 secs
// Don't autoclose the first 15 secs when the map is moving
return;
}
checkbox.isEnabled.setData(false);

View file

@ -240,14 +240,12 @@ export class FilteredLayer {
let content = undefined;
marker.bindPopup(popup)
.on("popupopen", () => {
if (content === undefined) {
uiElement = self._showOnPopup(eventSource, feature);
// Lazily create the content
content = uiElement.Render();
}
popup.setContent(content);
uiElement.Activate();
uiElement.Update();
});
return marker;
@ -290,8 +288,6 @@ export class FilteredLayer {
.setLatLng(e.latlng)
.openOn(State.state.bm.map);
uiElement.Update();
uiElement.Activate();
L.DomEvent.stop(e); // Marks the event as consumed
});
}

View file

@ -27,7 +27,6 @@ export class ImageSearcher extends UIEventSource<string[]> {
private readonly _tags: UIEventSource<any>;
private readonly _wdItem = new UIEventSource<string>("");
private readonly _commons = new UIEventSource<string>("");
private _activated: boolean = false;
public _deletedImages = new UIEventSource<string[]>([]);
@ -81,7 +80,7 @@ export class ImageSearcher extends UIEventSource<string[]> {
}
}
});
this._tags.addCallbackAndRun(() => self.LoadImages());
}
@ -121,25 +120,14 @@ export class ImageSearcher extends UIEventSource<string[]> {
return;
}
console.log("Deleting image...", key, " --> ", url);
State.state.changes.addTag(this._tags.data.id, new Tag(key, ""));
this._deletedImages.data.push(url);
this._deletedImages.ping();
this.ping();
State.state?.changes?.addTag(this._tags.data.id, new Tag(key, ""));
}
public Activate() {
if (this._activated) {
return;
}
this._activated = true;
this.LoadImages();
const self = this;
this._tags.addCallback(() => self.LoadImages());
}
private LoadImages(): void {
if (!this._activated) {
return;
}
const imageTag = this._tags.data.image;
if (imageTag !== undefined) {
const bareImages = imageTag.split(";");

View file

@ -31,16 +31,12 @@ export class StrayClickHandler {
});
const uiElement = uiToShow();
const popup = L.popup().setContent(uiElement.Render());
uiElement.Update();
uiElement.Activate();
self._lastMarker.addTo(map);
self._lastMarker.bindPopup(popup);
self._lastMarker.on("click", () => {
State.state.fullScreenMessage.setData(self._uiToShow());
});
uiElement.Update();
uiElement.Activate();
});
State.state.selectedElement.addCallback(() => {

View file

@ -465,7 +465,6 @@ export class TagUtils {
let leftoverTag = undefined;
if (keyValues[freeformKey] !== undefined && keyValues[freeformKey].length !== 0) {
leftoverTag = new Tag(freeformKey, keyValues[freeformKey].join(";"));
console.log("Leftovers are ", leftoverTag)
if (freeformExtraTags !== undefined) {
leftoverTag = new And([
leftoverTag,

View file

@ -1,45 +1,23 @@
import {UIElement} from "../UIElement";
import Translations from "../i18n/Translations";
import {FixedUiElement} from "./FixedUiElement";
import {Utils} from "../../Utils";
export default class Combine extends UIElement {
private readonly uiElements: (string | UIElement)[];
private readonly className: string = undefined;
private readonly uiElements: UIElement[];
constructor(uiElements: (string | UIElement)[], className: string = undefined) {
super(undefined);
this.dumbMode = false;
this.className = className;
this.uiElements = uiElements;
if (className) {
console.error("Deprecated used of className")
}
constructor(uiElements: (string | UIElement)[]) {
super();
this.uiElements = Utils.NoNull(uiElements)
.map(el => {
if (typeof el === "string") {
return new FixedUiElement(el);
}
return el;
});
}
InnerRender(): string {
let elements = "";
for (const element of this.uiElements) {
if(element === undefined){
continue;
}
if (element instanceof UIElement) {
elements += element.Render();
} else {
elements += element;
}
}
if(this.className !== undefined){
elements = `<span class='${this.className}'>${elements}</span>`;
}
return elements;
return this.uiElements.map(ui => ui.Render()).join("");
}
InnerUpdate(htmlElement: HTMLElement) {
for (const element of this.uiElements) {
if (element instanceof UIElement) {
element.Update();
}
}
}
}

View file

@ -13,7 +13,9 @@ export class TabbedComponent extends UIElement {
for (let i = 0; i < elements.length; i++) {
let element = elements[i];
this.headers.push(Translations.W(element.header).onClick(() => self._source.setData(i)));
this.content.push(Translations.W(element.content));
const content = Translations.W(element.content)
this.ListenTo(content)
this.content.push(content);
}
}
@ -35,10 +37,4 @@ export class TabbedComponent extends UIElement {
return headerBar + "<div class='tab-content'>" + (content?.Render() ?? "") + "</div>";
}
protected InnerUpdate(htmlElement: HTMLElement) {
super.InnerUpdate(htmlElement);
this.content[this._source.data].Update();
}
}

View file

@ -3,13 +3,10 @@ import {UIEventSource} from "../../Logic/UIEventSource";
export class VariableUiElement extends UIElement {
private _html: UIEventSource<string>;
private _innerUpdate: (htmlElement: HTMLElement) => void;
constructor(html: UIEventSource<string>, innerUpdate : ((htmlElement : HTMLElement) => void) = undefined) {
constructor(html: UIEventSource<string>) {
super(html);
this._html = html;
this._innerUpdate = innerUpdate;
}
InnerRender(): string {

View file

@ -8,25 +8,40 @@ import Combine from "./Base/Combine";
*/
export class FullScreenMessageBox extends UIElement {
private static readonly _toTheMap_height : string = "5em";
private _uielement: UIElement;
private returnToTheMap: UIElement;
private readonly returnToTheMap: UIElement;
constructor(onClear: (() => void)) {
super(undefined);
const self = this;
State.state.fullScreenMessage.addCallback(uielement => {
return self._uielement = uielement?.SetClass("messagesboxmobile-scroll")?.Activate();
State.state.fullScreenMessage.addCallbackAndRun(uiElement => {
this._uielement = new Combine([State.state.fullScreenMessage.data]).SetStyle(
"display:block;"+
"padding: 1em;"+
"padding-bottom:5em;"+
`margin-bottom:${FullScreenMessageBox._toTheMap_height};`+
"box-sizing:border-box;"+
`height:calc(100vh - ${FullScreenMessageBox._toTheMap_height});`+
"overflow-y: auto;" +
"background:white;"
);
});
this._uielement = State.state.fullScreenMessage.data;
this.ListenTo(State.state.fullScreenMessage);
this.HideOnEmpty(true);
State.state.fullScreenMessage.addCallback(latestData => {
if (latestData === undefined) {
location.hash = "";
} else {
// The 'hash' makes sure a new piece of history is added. This makes the 'back-button' on android remove the popup
location.hash = "#element";
}
this.Update();
@ -42,8 +57,23 @@ export class FullScreenMessageBox extends UIElement {
}
}
this.returnToTheMap = Translations.t.general.returnToTheMap.Clone()
.SetClass("to-the-map")
this.returnToTheMap =
new Combine([Translations.t.general.returnToTheMap.Clone().SetStyle("font-size:xx-large")])
.SetStyle("background:#7ebc6f;" +
"position: fixed;" +
"z-index: 10000;" +
"bottom: 0;" +
"left: 0;" +
`height: ${FullScreenMessageBox._toTheMap_height};` +
"width: 100vw;" +
"color: white;" +
"font-weight: bold;" +
"pointer-events: all;" +
"cursor: pointer;" +
"padding-top: 1.2em;" +
"text-align: center;" +
"padding-bottom: 1.2em;" +
"box-sizing:border-box")
.onClick(() => {
console.log("Returning...")
State.state.fullScreenMessage.setData(undefined);
@ -55,10 +85,11 @@ export class FullScreenMessageBox extends UIElement {
InnerRender(): string {
if (this._uielement === undefined) {
if (State.state.fullScreenMessage.data === undefined) {
return "";
}
return new Combine([this._uielement, this.returnToTheMap]).Render();
return new Combine([this._uielement, this.returnToTheMap])
.Render();
}

View file

@ -49,6 +49,7 @@ export class ImageCarousel extends TagDependantUIElement {
private readonly _uiElements: UIEventSource<UIElement[]>;
private readonly _deleteButton: UIElement;
private readonly _confirmation: UIElement;
constructor(tags: UIEventSource<any>, osmConnection: OsmConnection = undefined) {
super(tags);
@ -76,74 +77,78 @@ export class ImageCarousel extends TagDependantUIElement {
return false;
}
return self.searcher.IsDeletable(self.searcher.data[i]);
}, [this.searcher, osmConnection?.userDetails]);
}, [this.searcher, osmConnection?.userDetails, this.slideshow._currentSlide]);
const isDeleted: UIEventSource<boolean> = this.slideshow._currentSlide.map((i: number) => {
return self.searcher._deletedImages.data.indexOf(self.searcher.data[i]) >= 0;
}, [this.searcher, this.searcher._deletedImages]);
this.slideshow._currentSlide.addCallback(() => {
showDeleteButton.ping(); // This pings the showDeleteButton, which indicates that it has to hide it's subbuttons
})
const deleteCurrent = () => {
self.searcher.Delete(self.searcher.data[self.slideshow._currentSlide.data]);
}
const isDeleted = self.searcher._deletedImages.data.indexOf(self.searcher.data[i]) >= 0;
console.log("Now deleted: ", i, isDeleted);
return isDeleted;
}, [this.searcher, this.searcher._deletedImages, this.slideshow._currentSlide]);
const style = ";padding:0.4em;height:2em;padding: 0.4em; font-weight:bold;";
const backButton = Translations.t.image.dontDelete
.SetStyle("background:black;border-radius:0.4em 0.4em 0 0" + style)
const deleteButton = Translations.t.image.doDelete
.SetStyle("background:#ff8c8c;border-radius:0 0 0.4em 0.4em" + style)
.onClick(deleteCurrent);
const deleteButton =
Translations.t.image.doDelete
.SetStyle("background:#ff8c8c;border-radius:0 0 0.4em 0.4em" + style);
this._confirmation = deleteButton;
const isDeletedBadge = Translations.t.image.isDeleted
.SetStyle("display:block;" +
"background-color: black;color:white;padding:0.4em;border-radius:0.4em");
const confirmDialog = new Combine([
backButton,
deleteButton]
).SetStyle("display:flex;" +
"flex-direction:column;" +
"background:black;" +
"color:white;" +
"border-radius:0.5em;" +
"width:max-content;" +
"height:min-content;");
const smallDeleteButton = new FixedUiElement("<img style='width:1.5em' src='./assets/delete.svg'>")
.SetStyle("display:block;" +
"width: 1.5em;" +
"height: 1.5em;" +
"padding: 0.5em;" +
"border-radius: 3em;" +
"background-color: black;")
const deleteButtonCheckbox = new CheckBox(
new Combine([
backButton,
deleteButton]
).SetStyle("display:flex;" +
"flex-direction:column;" +
"background:black;" +
"color:white;" +
"border-radius:0.5em;" +
"width:max-content;" +
"height:min-content;"),
confirmDialog,
new VariableUiElement(
showDeleteButton.map(showDelete => {
if (isDeleted.data) {
return Translations.t.image.isDeleted
.SetStyle("display:block;" +
"background-color: black;color:white;padding:0.4em;border-radius:0.4em").Render()
return isDeletedBadge.Render()
}
if (!showDelete) {
return "";
}
return new FixedUiElement("<img style='width:1.5em' src='./assets/delete.svg'>")
.SetStyle("display:block;" +
"width: 1.5em;" +
"height: 1.5em;" +
"padding: 0.5em;" +
"border-radius: 3em;" +
"background-color: black;").Render();
return smallDeleteButton.Render();
}, [this.searcher._deletedImages, isDeleted]
)));
deleteButton.onClick(() => {
console.log("Deleting image...");
deleteButtonCheckbox.isEnabled.setData(false);
deleteButtonCheckbox.Update();
self.searcher.Delete(self.searcher.data[self.slideshow._currentSlide.data]);
});
isDeleted.addCallback(isD => {
if(isD){
deleteButtonCheckbox.isEnabled.setData(false);
}
})
this._deleteButton = deleteButtonCheckbox;
this._deleteButton.SetStyle(
"position:absolute;display:block;top:1em;left:5em;z-index: 7000;width:min-content;height:min-content;"
)
this.slideshow._currentSlide.addCallback(() => {
deleteButtonCheckbox.isEnabled.setData(false)
})
this.searcher._deletedImages.addCallback(() => {
this.slideshow._currentSlide.ping();
})
}
@ -171,10 +176,5 @@ export class ImageCarousel extends TagDependantUIElement {
}
Activate() {
super.Activate();
this.searcher.Activate();
return this;
}
}

View file

@ -50,19 +50,6 @@ class ImageCarouselWithUpload extends TagDependantUIElement {
this._pictureUploader.Render();
}
Activate() {
super.Activate();
this._imageElement.Activate();
this._pictureUploader.Activate();
return this;
}
Update() {
super.Update();
this._imageElement.Update();
this._pictureUploader.Update();
}
IsKnown(): boolean {
return true;
}

View file

@ -1,16 +1,11 @@
import {UIElement} from "./UIElement";
import $ from "jquery"
import {UserDetails} from "../Logic/Osm/OsmConnection";
import {DropDown} from "./Input/DropDown";
import {VariableUiElement} from "./Base/VariableUIElement";
import Translations from "./i18n/Translations";
import {fail} from "assert";
import Combine from "./Base/Combine";
import {VerticalCombine} from "./Base/VerticalCombine";
import {State} from "../State";
import {UIEventSource} from "../Logic/UIEventSource";
import {Imgur} from "../Logic/Web/Imgur";
import {SubtleButton} from "./Base/SubtleButton";
export class ImageUploadFlow extends UIElement {
private _licensePicker: UIElement;
@ -107,9 +102,20 @@ export class ImageUploadFlow extends UIElement {
const label = new Combine([
"<img style='width: 36px;height: 36px;padding: 0.1em;margin-top: 5px;border-radius: 0;float: left;' src='./assets/camera-plus.svg'/> ",
Translations.t.image.addPicture
.SetStyle("width:max-content;font-size: 28px;font-weight: bold;float: left;margin-top: 4px;padding-top: 4px;padding-bottom: 4px;padding-left: 13px;"),
.SetStyle("width:max-content;font-size: 28px;" +
"font-weight: bold;" +
"float: left;" +
"margin-top: 4px;" +
"padding-top: 4px;" +
"padding-bottom: 4px;" +
"padding-left: 13px;"),
]).SetStyle(" display: flex;cursor:pointer;padding: 0.5em;border-radius: 1em;border: 3px solid black;box-sizing:border-box;")
]).SetStyle(" display: flex;" +
"cursor:pointer;" +
"padding: 0.5em;" +
"border-radius: 1em;" +
"border: 3px solid black;" +
"box-sizing:border-box;")
const actualInputElement =
`<input style='display: none' id='fileselector-${this.id}' type='file' accept='image/*' name='picField' multiple='multiple' alt=''/>`;

View file

@ -1,20 +1,19 @@
import {UIElement} from "../UIElement";
import { FilteredLayer } from "../../Logic/FilteredLayer";
import Translations from "../../UI/i18n/Translations";
import {UIEventSource} from "../../Logic/UIEventSource";
export class CheckBox extends UIElement{
public readonly isEnabled: UIEventSource<boolean>;
private readonly _showEnabled: string|UIElement;
private readonly _showDisabled: string|UIElement;
private readonly _showEnabled: UIElement;
private readonly _showDisabled: UIElement;
constructor(showEnabled: string | UIElement, showDisabled: string | UIElement, data: UIEventSource<boolean> | boolean = false) {
super(undefined);
this.isEnabled =
data instanceof UIEventSource ? data : new UIEventSource(data ?? false);
this.ListenTo(this.isEnabled);
this._showEnabled = showEnabled;
this._showDisabled = showDisabled;
this._showEnabled = Translations.W(showEnabled);
this._showDisabled =Translations.W(showDisabled);
const self = this;
this.onClick(() => {
self.isEnabled.setData(!self.isEnabled.data);

View file

@ -178,8 +178,10 @@ export class TextField<T> extends InputElement<T> {
return `<textarea id="text-${this.id}" class="form-text-field" rows="${this._textAreaRows}" cols="50" style="max-width: 100%; width: 100%; box-sizing: border-box"></textarea>`
}
const placeholder = this._placeholder.InnerRender().replace("'", "&#39");
return `<form onSubmit='return false' class='form-text-field'>` +
`<input type='text' placeholder='${this._placeholder.InnerRender()}' id='text-${this.id}'>` +
`<input type='text' placeholder='${placeholder}' id='text-${this.id}'>` +
`</form>`;
}
@ -246,11 +248,5 @@ export class TextField<T> extends InputElement<T> {
return result !== undefined && result !== null;
}
Clear() {
const field = document.getElementById('text-' + this.id);
if (field !== undefined) {
// @ts-ignore
field.value = "";
}
}
}
}

View file

@ -44,13 +44,13 @@ export class SearchAndGo extends UIElement {
// Triggered by 'enter' or onclick
private RunSearch() {
const searchString = this._searchField.GetValue().data;
this._searchField.Clear();
this._searchField.GetValue().setData("");
this._placeholder.setData(Translations.t.general.search.searching);
const self = this;
Geocoding.Search(searchString, (result) => {
if (result.length == 0) {
this._placeholder.setData(Translations.t.general.search.nothing);
self._placeholder.setData(Translations.t.general.search.nothing);
return;
}
@ -60,10 +60,11 @@ export class SearchAndGo extends UIElement {
[bb[1], bb[3]]
]
State.state.bm.map.fitBounds(bounds);
this._placeholder.setData(Translations.t.general.search.search);
self._placeholder.setData(Translations.t.general.search.search);
},
() => {
this._placeholder.setData(Translations.t.general.search.error);
self._searchField.GetValue().setData("");
self._placeholder.setData(Translations.t.general.search.error);
});
}
@ -74,15 +75,5 @@ export class SearchAndGo extends UIElement {
}
Update() {
super.Update();
this._searchField.Update();
this._goButton.Update();
}
Activate() {
super.Activate();
this._searchField.Activate();
this._goButton.Activate();
}
}

View file

@ -8,8 +8,8 @@ export class SlideShow extends UIElement {
public readonly _currentSlide: UIEventSource<number> = new UIEventSource<number>(0);
private readonly _noimages: UIElement;
private _prev: FixedUiElement;
private _next: FixedUiElement;
private _prev: UIElement;
private _next: UIElement;
constructor(
embeddedElements: UIEventSource<UIElement[]>,
@ -75,18 +75,4 @@ export class SlideShow extends UIElement {
this._currentSlide.setData(index);
}
InnerUpdate(htmlElement) {
this._next.Update();
this._prev.Update();
}
Activate() {
for (const embeddedElement of this._embeddedElements.data) {
embeddedElement.Activate();
}
this._next.Update();
this._prev.Update();
return this;
}
}
}

View file

@ -179,11 +179,11 @@ export class TagRendering extends UIElement implements TagDependantUIElement {
}
const cancelContents = this._editMode.map((isEditing) => {
if (isEditing) {
return "<span class='skip-button'>" + Translations.t.general.cancel.R() + "</span>";
} else {
return "<span class='skip-button'>" + Translations.t.general.skip.R() + "</span>";
}
const tr = Translations.t.general;
const text = isEditing ? tr.cancel : tr.skip;
return text
.SetStyle("display: inline-block;border: solid black 0.5px;padding: 0.2em 0.3em;border-radius: 1.5em;")
.Render();
}, [Locale.language]);
// And at last, set up the skip button
this._skipButton = new VariableUiElement(cancelContents).onClick(cancel);

View file

@ -28,6 +28,7 @@ export abstract class UIElement extends UIEventSource<string> {
this.id = "ui-element-" + UIElement.nextId;
this._source = source;
UIElement.nextId++;
this.dumbMode = true;
this.ListenTo(source);
}
@ -74,32 +75,18 @@ export abstract class UIElement extends UIEventSource<string> {
let element = document.getElementById(this.id);
if (element === undefined || element === null) {
// The element is not painted
// The element is not painted or, in the case of 'dumbmode' this UI-element is not explicitely present
if (this.dumbMode) {
// We update all the children anyway
for (const i in this) {
const child = this[i];
if (child instanceof UIElement) {
child.Update();
} else if (child instanceof Array) {
for (const ch of child) {
if (ch instanceof UIElement) {
ch.Update();
}
}
}
}
this.UpdateAllChildren();
}
return;
}
const newRender = this.InnerRender();
if (newRender !== this.lastInnerRender) {
this.lastInnerRender = newRender;
this.setData(this.InnerRender());
element.innerHTML = this.data;
this.lastInnerRender = newRender;
}
if (this._hideIfEmpty) {
@ -132,7 +119,11 @@ export abstract class UIElement extends UIEventSource<string> {
}
this.InnerUpdate(element);
this.UpdateAllChildren();
}
private UpdateAllChildren() {
for (const i in this) {
const child = this[i];
if (child instanceof UIElement) {
@ -146,27 +137,32 @@ export abstract class UIElement extends UIEventSource<string> {
}
}
}
HideOnEmpty(hide : boolean){
HideOnEmpty(hide: boolean) {
this._hideIfEmpty = hide;
this.Update();
return this;
}
// Called after the HTML has been replaced. Can be used for css tricks
protected InnerUpdate(htmlElement: HTMLElement) {
}
protected InnerUpdate(htmlElement: HTMLElement) {
}
Render(): string {
this.lastInnerRender = this.lastInnerRender ?? this.InnerRender();
this.lastInnerRender = this.InnerRender();
if (this.dumbMode) {
return this.lastInnerRender;
}
let style = "";
if (this.style !== undefined && this.style !== "") {
style = `style="${this.style}"`;
style = `style="${this.style}" `;
}
return `<span class='uielement ${this.clss.join(" ")}' ${style} id='${this.id}'>${this.lastInnerRender}</span>`
const clss = "";
if (this.clss.length > 0) {
`class='${this.clss.join(" ")}' `;
}
return `<span ${clss}${style}id='${this.id}'>${this.lastInnerRender}</span>`
}
AttachTo(divId: string) {
@ -182,32 +178,20 @@ export abstract class UIElement extends UIEventSource<string> {
public abstract InnerRender(): string;
public Activate(): UIElement {
for (const i in this) {
const child = this[i];
if (child instanceof UIElement) {
child.Activate();
} else if (child instanceof Array) {
for (const ch of child) {
if (ch instanceof UIElement) {
ch.Activate();
}
}
}
}
return this;
};
public IsEmpty(): boolean {
return this.InnerRender() === "";
}
public SetClass(clss: string): UIElement {
this.dumbMode = false;
if(clss === "" && this.clss.length > 0){
this.clss = [];
this.Update();
}
if (this.clss.indexOf(clss) < 0) {
this.clss.push(clss);
this.Update();
}
this.Update();
return this;
}

View file

@ -41,6 +41,9 @@ export default class Translation extends UIElement {
get txt(): string {
if(this.translations["*"]){
return this.translations["*"];
}
const txt = this.translations[Translation.forcedLanguage ?? Locale.language.data];
if (txt !== undefined) {
return txt;
@ -79,10 +82,6 @@ export default class Translation extends UIElement {
return result;
}
public R(): string {
return new Translation(this.translations).Render();
}
public Clone() {
return new Translation(this.translations)
}

View file

@ -2,6 +2,7 @@
<html lang="en">
<head>
<link href="index.css" rel="stylesheet"/>
<link href="css/tabbedComponent.css" rel="stylesheet"/>
<title>Custom Theme Generator for Mapcomplete</title>
<style type="text/css">

View file

@ -44,12 +44,6 @@
/**************** GENERIC ****************/
.uielement {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.alert {
background-color: #fee4d1;
@ -514,18 +508,7 @@
width: 100%;
}
.messagesboxmobile-scroll {
display: block;
width: 100vw;
box-sizing: border-box;
overflow-y: auto;
padding-left: 1em;
padding-right: 1em;
padding-top: 0;
padding-bottom: 0;
margin: 0;
height: calc(100vh - 5em); /*Height of to-the-map is 5em*/
}
#messagesboxmobile {
display: block;
@ -549,50 +532,12 @@
}
}
.to-the-map {
display: block;
box-sizing: border-box;
height: 2.5em;
margin: 0;
padding: 0.5em;
padding-top: 0.75em;
text-align: center;
color: white;
background-color: #7ebc6f;
cursor: pointer;
font-size: xx-large;
font-weight: bold;
border-top-left-radius: 0.5em;
border-top-right-radius: 0.5em;
}
@media only screen and (max-height: 400px) {
/* Landscape: small 'to the map' */
#hidden-on-mobile {
display: unset;
}
.to-the-map {
position: relative;
height: 100%;
width: 100%
}
.to-the-map span {
width: auto;
border-top-left-radius: 1.5em;
position: absolute;
z-index: 5;
right: 0;
bottom: 0;
margin: 0;
padding: 1em;
padding-bottom: 0.75em;
height: 3em;
font-size: x-large;
}
#messagesboxmobile {
position: absolute;
display: block;
@ -600,13 +545,6 @@
padding-bottom: 5em;
}
.messagesboxmobile-scroll {
display: block;
width: 100vw;
height: calc(100vh - 5em);
box-sizing: border-box;
overflow-y: scroll;
}
#welcomeMessage {
box-shadow: unset;
@ -670,7 +608,6 @@
}
#messagesboxmobile .featureinfobox > div {
width: 100%;
max-width: unset;
padding-left: unset;
}
@ -680,12 +617,6 @@
overflow-y: auto;
}
.featureinfobox > div {
width: calc(100% - 2em);
padding-left: 1em;
}
.featureinfoboxtitle {
position: relative;
}
@ -819,23 +750,12 @@
display: inline-block;
border: solid lightgrey 2px;
color: grey;
padding: 0.2em;
padding-left: 0.3em;
padding-right: 0.3em;
padding: 0.2em 0.3em;
font-size: x-large;
font-weight: bold;
border-radius: 1.5em;
}
.skip-button {
display: inline-block;
border: solid black 0.5px;
padding: 0.2em;
padding-left: 0.3em;
padding-right: 0.3em;
border-radius: 1.5em;
}
/****** ShareScreen *****/

View file

@ -10,5 +10,4 @@ const imageCarousel = new ImageCarousel(new UIEventSource<any>({
"image": "https://i.imgur.com/kX3rl3v.jpg"
}), connection);
imageCarousel.AttachTo("maindiv")
imageCarousel.Activate();
imageCarousel.AttachTo("maindiv")