More CSS improvements and cleanups

This commit is contained in:
Pieter Vander Vennet 2020-09-13 00:53:24 +02:00
parent 6d5f4ade25
commit 257194c063
7 changed files with 128 additions and 287 deletions

View file

@ -32,11 +32,9 @@ export class WikipediaLink extends TagRenderingOptions {
key: "wikipedia", key: "wikipedia",
template: "$$$", template: "$$$",
renderTemplate: renderTemplate:
"<span style='position: absolute;right: 24px;width: 24px;height: 24px;padding-right: 12px;'>" +
"<a href='{wikipedia}' target='_blank'>" + "<a href='{wikipedia}' target='_blank'>" +
"<img style='width: 24px;height: 24px;' src='./assets/wikipedia.svg' alt='wikipedia'>" + "<img style='width: 24px;height: 24px;' src='./assets/wikipedia.svg' alt='wikipedia'>" +
"</a></span>", "</a>",
placeholder: "" placeholder: ""

View file

@ -24,8 +24,6 @@ export class FeatureInfoBox extends UIElement {
private readonly _tagsES: UIEventSource<any>; private readonly _tagsES: UIEventSource<any>;
private readonly _changes: Changes; private readonly _changes: Changes;
private readonly _title: UIElement; private readonly _title: UIElement;
private readonly _osmLink: UIElement;
private readonly _wikipedialink: UIElement;
private readonly _infoboxes: TagDependantUIElement[]; private readonly _infoboxes: TagDependantUIElement[];
private readonly _oneSkipped = Translations.t.general.oneSkippedQuestion.Clone(); private readonly _oneSkipped = Translations.t.general.oneSkippedQuestion.Clone();
@ -65,22 +63,36 @@ export class FeatureInfoBox extends UIElement {
this._oneSkipped.onClick(initTags) this._oneSkipped.onClick(initTags)
let renderedTitle: UIElement;
title = title ?? new TagRenderingOptions( title = title ?? new TagRenderingOptions(
{ {
mappings: [{k: new And([]), txt: ""}] mappings: [{k: new And([]), txt: ""}]
} }
) )
if (typeof (title) == "string") { if (typeof (title) == "string") {
this._title = new FixedUiElement(title); renderedTitle = new FixedUiElement(title);
} else if (title instanceof UIElement) { } else if (title instanceof UIElement) {
this._title = title; renderedTitle = title;
} else { } else {
this._title = title.construct(deps); renderedTitle = title.construct(deps);
} }
this._osmLink = new OsmLink().construct(deps);
this._wikipedialink = new WikipediaLink().construct(deps);
renderedTitle
.SetStyle("width: calc(100% - 50px - 0.2em);")
.SetClass("title-font")
const osmLink = new OsmLink()
.construct(deps)
.SetStyle("width: 24px; display:block;")
const wikipedialink = new WikipediaLink()
.construct(deps)
.SetStyle("width: 24px; display:block;")
this._title = new Combine([
renderedTitle,
wikipedialink,
osmLink]).SetStyle("display:flex;");
} }
InnerRender(): string { InnerRender(): string {
@ -134,22 +146,15 @@ export class FeatureInfoBox extends UIElement {
questionElement = this._someSkipped; questionElement = this._someSkipped;
} }
const title = new Combine([
this._title,
this._wikipedialink,
this._osmLink]);
const infoboxcontents = new Combine( const infoboxcontents = new Combine(
[ new VerticalCombine(info, "infobox-information "), questionElement ?? ""]); [new VerticalCombine(info, "infobox-information "), questionElement ?? ""]);
return "<div class='featureinfobox'>" + return new Combine([
new Combine([ this._title,
"<div class='featureinfoboxtitle'>", "<div class='infoboxcontents'>",
title, infoboxcontents,
"</div>", "</div>"]).SetClass("featureinfobox")
"<div class='infoboxcontents'>", .Render();
infoboxcontents,
"</div>"]).Render() + "</div>";
} }

View file

@ -1,20 +1,13 @@
import {UIElement} from "../UIElement"; import {UIElement} from "../UIElement";
import {ImageSearcher} from "../../Logic/ImageSearcher"; import {ImageSearcher} from "../../Logic/ImageSearcher";
import {SlideShow} from "../SlideShow"; import {SlideShow} from "../SlideShow";
import {FixedUiElement} from "../Base/FixedUiElement";
import {VariableUiElement} from "../Base/VariableUIElement";
import {UIEventSource} from "../../Logic/UIEventSource"; import {UIEventSource} from "../../Logic/UIEventSource";
import { import {
Dependencies, Dependencies,
TagDependantUIElement, TagDependantUIElement,
TagDependantUIElementConstructor TagDependantUIElementConstructor
} from "../../Customizations/UIElementConstructor"; } from "../../Customizations/UIElementConstructor";
import {State} from "../../State";
import Translation from "../i18n/Translation"; import Translation from "../i18n/Translation";
import {CheckBox} from "../Input/CheckBox";
import Combine from "../Base/Combine";
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
import Translations from "../i18n/Translations";
export class ImageCarouselConstructor implements TagDependantUIElementConstructor { export class ImageCarouselConstructor implements TagDependantUIElementConstructor {
IsKnown(properties: any): boolean { IsKnown(properties: any): boolean {
@ -41,24 +34,13 @@ export class ImageCarouselConstructor implements TagDependantUIElementConstructo
export class ImageCarousel extends TagDependantUIElement { export class ImageCarousel extends TagDependantUIElement {
public readonly searcher: ImageSearcher;
private readonly searcher: ImageSearcher;
public readonly slideshow: SlideShow; public readonly slideshow: SlideShow;
private readonly _uiElements: UIEventSource<UIElement[]>; constructor(tags: UIEventSource<any>) {
private readonly _deleteButton: UIElement;
private readonly _confirmation: UIElement;
constructor(tags: UIEventSource<any>, osmConnection: OsmConnection = undefined) {
super(tags); super(tags);
const self = this;
osmConnection = osmConnection ?? State.state?.osmConnection;
this.searcher = new ImageSearcher(tags); this.searcher = new ImageSearcher(tags);
const uiElements = this.searcher.map((imageURLS: string[]) => {
this._uiElements = this.searcher.map((imageURLS: string[]) => {
const uiElements: UIElement[] = []; const uiElements: UIElement[] = [];
for (const url of imageURLS) { for (const url of imageURLS) {
const image = ImageSearcher.CreateImageElement(url); const image = ImageSearcher.CreateImageElement(url);
@ -67,96 +49,12 @@ export class ImageCarousel extends TagDependantUIElement {
return uiElements; return uiElements;
}); });
this.slideshow = new SlideShow( this.slideshow = new SlideShow(uiElements).HideOnEmpty(true);
this._uiElements,
new FixedUiElement("")).HideOnEmpty(true);
const showDeleteButton = this.slideshow._currentSlide.map((i: number) => {
if (!osmConnection?.userDetails?.data?.loggedIn) {
return false;
}
return self.searcher.IsDeletable(self.searcher.data[i]);
}, [this.searcher, osmConnection?.userDetails, this.slideshow._currentSlide]);
const isDeleted: UIEventSource<boolean> = this.slideshow._currentSlide.map((i: number) => {
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);
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(
confirmDialog,
new VariableUiElement(
showDeleteButton.map(showDelete => {
if (isDeleted.data) {
return isDeletedBadge.Render()
}
if (!showDelete) {
return "";
}
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;"
)
} }
InnerRender(): string { InnerRender(): string {
return new Combine([ return this.slideshow.Render();
this._deleteButton,
this.slideshow
]).SetStyle("position:relative").Render();
} }
IsKnown(): boolean { IsKnown(): boolean {

View file

@ -7,17 +7,14 @@ export class SlideShow extends UIElement {
private readonly _embeddedElements: UIEventSource<UIElement[]> private readonly _embeddedElements: UIEventSource<UIElement[]>
public readonly _currentSlide: UIEventSource<number> = new UIEventSource<number>(0); public readonly _currentSlide: UIEventSource<number> = new UIEventSource<number>(0);
private readonly _noimages: UIElement;
private _prev: UIElement; private _prev: UIElement;
private _next: UIElement; private _next: UIElement;
constructor( constructor(
embeddedElements: UIEventSource<UIElement[]>, embeddedElements: UIEventSource<UIElement[]>) {
noImages: UIElement) {
super(embeddedElements); super(embeddedElements);
this._embeddedElements = embeddedElements; this._embeddedElements = embeddedElements;
this.ListenTo(this._currentSlide); this.ListenTo(this._currentSlide);
this._noimages = noImages;
const self = this; const self = this;
this._prev = new FixedUiElement("<div class='prev-button'>" + this._prev = new FixedUiElement("<div class='prev-button'>" +
@ -41,7 +38,7 @@ export class SlideShow extends UIElement {
InnerRender(): string { InnerRender(): string {
if (this._embeddedElements.data.length == 0) { if (this._embeddedElements.data.length == 0) {
return this._noimages.Render(); return "";
} }
if (this._embeddedElements.data.length == 1) { if (this._embeddedElements.data.length == 1) {

View file

@ -169,6 +169,7 @@ export class TagRendering extends UIElement implements TagDependantUIElement {
this._editButton = new FixedUiElement(""); this._editButton = new FixedUiElement("");
if (this._question !== undefined) { if (this._question !== undefined) {
// 2.3em total width
this._editButton = new FixedUiElement( this._editButton = new FixedUiElement(
"<img style='width: 1.3em;height: 1.3em;padding: 0.5em;border-radius: 0.65em;border: solid black 1px;font-size: medium;float: right;' " + "<img style='width: 1.3em;height: 1.3em;padding: 0.5em;border-radius: 0.65em;border: solid black 1px;font-size: medium;float: right;' " +
"src='./assets/pencil.svg' alt='edit'>") "src='./assets/pencil.svg' alt='edit'>")
@ -498,22 +499,27 @@ export class TagRendering extends UIElement implements TagDependantUIElement {
if (this.IsKnown()) { if (this.IsKnown()) {
const answer = this.RenderAnswer(); const answer = this.RenderAnswer();
if(answer.IsEmpty()){ if (answer.IsEmpty()) {
return ""; return "";
} }
let editButton;
const answerStyle = " display: inline-block;" +
" margin: 0.1em;" +
" width: 100%;" +
" font-size: large;"
if (State.state === undefined || // state undefined -> we are custom testing if (State.state === undefined || // state undefined -> we are custom testing
State.state?.osmConnection?.userDetails?.data?.loggedIn && this._question !== undefined) { State.state?.osmConnection?.userDetails?.data?.loggedIn && this._question !== undefined) {
editButton = this._editButton; answer.SetStyle("display:inline-block;width:calc(100% - 2.3em);")
return new Combine([
answer,
this._editButton])
.SetStyle(answerStyle)
.Render();
} }
return new Combine([ return answer.SetStyle(answerStyle).Render();
"<span class='answer'>",
"<span class='answer-text'>",
answer,
"</span>",
editButton ?? "",
"</span>"]).Render();
} }
return ""; return "";

View file

@ -158,9 +158,9 @@ export abstract class UIElement extends UIEventSource<string> {
if (this.style !== undefined && this.style !== "") { if (this.style !== undefined && this.style !== "") {
style = `style="${this.style}" `; style = `style="${this.style}" `;
} }
const clss = ""; let clss = "";
if (this.clss.length > 0) { if (this.clss.length > 0) {
`class='${this.clss.join(" ")}' `; clss = `class='${this.clss.join(" ")}' `;
} }
return `<span ${clss}${style}id='${this.id}'>${this.lastInnerRender}</span>` return `<span ${clss}${style}id='${this.id}'>${this.lastInnerRender}</span>`
} }
@ -184,14 +184,14 @@ export abstract class UIElement extends UIEventSource<string> {
public SetClass(clss: string): UIElement { public SetClass(clss: string): UIElement {
this.dumbMode = false; this.dumbMode = false;
if(clss === "" && this.clss.length > 0){ if (clss === "" && this.clss.length > 0) {
this.clss = []; this.clss = [];
this.Update(); this.Update();
} } else if (this.clss.indexOf(clss) < 0) {
if (this.clss.indexOf(clss) < 0) {
this.clss.push(clss); this.clss.push(clss);
this.Update(); this.Update();
} }
console.log(this.clss)
return this; return this;
} }

209
index.css
View file

@ -51,10 +51,10 @@
border-radius: 1em; border-radius: 1em;
padding: 0.3em; padding: 0.3em;
margin: 0.25em; margin: 0.25em;
text-align: center; text-align: center;
padding-top: 0.15em; padding-top: 0.15em;
padding-bottom: 0.15em; padding-bottom: 0.15em;
} }
form { form {
display: inline; display: inline;
@ -68,36 +68,41 @@
box-shadow: 0 0 10px #00000066; box-shadow: 0 0 10px #00000066;
} }
.soft { .title-font span {
background-color: #e5f5ff; font-size: xx-large !important;
font-weight: bold; font-weight: bold;
border-radius: 1em; }
padding: 0.3em;
margin: 0.25em; .soft {
text-align: center; background-color: #e5f5ff;
padding-top: 0.15em; font-weight: bold;
padding-bottom: 0.15em; border-radius: 1em;
} padding: 0.3em;
margin: 0.25em;
text-align: center;
padding-top: 0.15em;
padding-bottom: 0.15em;
}
.subtle { .subtle {
color: #999; color: #999;
} }
.bold { .bold {
font-weight: bold; font-weight: bold;
} }
.thanks { .thanks {
background-color: #43d904; background-color: #43d904;
font-weight: bold; font-weight: bold;
border-radius: 1em; border-radius: 1em;
padding: 0.3em; padding: 0.3em;
margin: 0.25em; margin: 0.25em;
text-align: center; text-align: center;
padding-top: 0.15em; padding-top: 0.15em;
padding-bottom: 0.15em; padding-bottom: 0.15em;
} }
.clickable { .clickable {
pointer-events: all; pointer-events: all;
@ -562,11 +567,6 @@
} }
.wikimedia-link {
/*The actual wikimedia logo*/
width: 1.5em !important;
}
.attribution { .attribution {
background-color: rgba(0, 0, 0, 0.5); background-color: rgba(0, 0, 0, 0.5);
color: white; color: white;
@ -600,25 +600,13 @@
.leaflet-popup-content { .leaflet-popup-content {
width: 40em !important; width: 40em !important;
}
#messagesboxmobile .featureinfobox {
max-height: unset;
overflow-y: unset;
}
#messagesboxmobile .featureinfobox > div {
max-width: unset;
padding-left: unset;
}
.featureinfobox {
max-height: 80vh; max-height: 80vh;
overflow-y: auto; overflow-y: auto;
} }
.featureinfoboxtitle {
position: relative; .featureinfoboxtitle span {
width: unset !important;
} }
.question .form-text-field > input { .question .form-text-field > input {
@ -626,49 +614,10 @@
box-sizing: border-box; box-sizing: border-box;
} }
.osmlink {
position: absolute;
right: 0;
}
.osm-logo path { .osm-logo path {
fill: #7ebc6f; fill: #7ebc6f;
} }
.featureinfoboxtitle .answer {
display: inline;
margin-right: 3em;
}
.featureinfoboxtitle .answer-text {
display: inline;
}
.featureinfoboxtitle .editbutton {
float: none;
width: 0.8em;
height: 0.8em;
padding: 0.3em;
border-radius: 0.35em;
border: solid black 1px;
margin-left: 0.5em;
top: 0.2em;
vertical-align: middle;
}
.featureinfoboxtitle span {
font-weight: bold;
font-size: x-large;
}
.featureinfoboxtitle a {
float: right;
margin-left: 1em;
}
.infoboxcontents { .infoboxcontents {
@ -706,17 +655,6 @@
font-weight: normal; font-weight: normal;
} }
.answer {
display: inline-block;
margin: 0.1em;
width: 100%;
font-size: large;
}
.answer-text {
width: 90%;
display: inline-block
}
/**** The save button *****/ /**** The save button *****/
@ -756,48 +694,47 @@
border-radius: 1.5em; border-radius: 1.5em;
} }
/****** ShareScreen *****/
/****** ShareScreen *****/ .literal-code {
display: inline-block;
.literal-code { background-color: lightgray;
display: inline-block; padding: 0.5em;
background-color: lightgray; word-break: break-all;
padding: 0.5em; color: black;
word-break: break-all; box-sizing: border-box;
color: black; }
box-sizing: border-box;
}
.iframe-escape { .iframe-escape {
background-color: white; background-color: white;
border-radius: 2em; border-radius: 2em;
display: block; display: block;
width: min-content; width: min-content;
} }
.iframe-escape img{ .iframe-escape img {
padding: 1em; padding: 1em;
width: 2em; width: 2em;
height: 2em; height: 2em;
} }
/** Switch layout **/
.subtle-button {
display: flex;
flex-wrap: nowrap;
flex-direction: row;
font-size: large;
margin: 0.5em;
background-color: #e5f5ff;
border-radius: 1em;
align-items: center;
text-decoration: none;
color: black;
}
/** Switch layout **/
.subtle-button{
display: flex;
flex-wrap: nowrap;
flex-direction: row;
font-size: large;
margin: 0.5em;
background-color: #e5f5ff;
border-radius: 1em;
align-items: center;
text-decoration: none;
color: black;
}
.subtle-button a { .subtle-button a {
text-decoration: unset !important; text-decoration: unset !important;
color: unset !important; color: unset !important;