Cleanup of the image carousel code and index.css code

This commit is contained in:
Pieter Vander Vennet 2020-09-11 19:14:32 +02:00
parent 21c71febca
commit c7f33a9490
14 changed files with 190 additions and 318 deletions

View file

@ -3,7 +3,6 @@ import {Layout} from "./Layout";
import {Groen} from "./Layouts/Groen"; import {Groen} from "./Layouts/Groen";
import Cyclofix from "./Layouts/Cyclofix"; import Cyclofix from "./Layouts/Cyclofix";
import {StreetWidth} from "./Layouts/StreetWidth"; import {StreetWidth} from "./Layouts/StreetWidth";
import {GRB} from "./Layouts/GRB";
import {MetaMap} from "./Layouts/MetaMap"; import {MetaMap} from "./Layouts/MetaMap";
import {Natuurpunt} from "./Layouts/Natuurpunt"; import {Natuurpunt} from "./Layouts/Natuurpunt";
import {FromJSON} from "./JSON/FromJSON"; import {FromJSON} from "./JSON/FromJSON";
@ -22,7 +21,6 @@ export class AllKnownLayouts {
public static layoutsList: Layout[] = [ public static layoutsList: Layout[] = [
new PersonalLayout(), new PersonalLayout(),
new Natuurpunt(), new Natuurpunt(),
new GRB(),
new Cyclofix(), new Cyclofix(),
FromJSON.LayoutFromJSON(bookcases), FromJSON.LayoutFromJSON(bookcases),
FromJSON.LayoutFromJSON(aed), FromJSON.LayoutFromJSON(aed),

View file

@ -392,7 +392,7 @@ export class FromJSON {
} }
); );
layer.maxAllowedOverlapPercentage = json.hideUnderlayingFeaturesMinPercentage; layer.maxAllowedOverlapPercentage = json.hideUnderlayingFeaturesMinPercentage ?? 0;
return layer; return layer;
} }

View file

@ -37,6 +37,6 @@ export default class Cyclofix extends Layout {
this.icon = "./assets/bike/logo.svg" this.icon = "./assets/bike/logo.svg"
this.description = "Easily search and contribute bicycle data nearby"; this.description = "Easily search and contribute bicycle data nearby";
this.socialImage = "./assets/bike/cyclofix.jpeg"; this.socialImage = "./assets/bike/cyclofix.jpeg";
this.widenFactor = 0.5; this.widenFactor = 0.05;
} }
} }

View file

@ -19,7 +19,7 @@ export class UserDetails {
} }
export class OsmConnection { export class OsmConnection {
public auth; public auth;
public userDetails: UIEventSource<UserDetails>; public userDetails: UIEventSource<UserDetails>;
private _dryRun: boolean; private _dryRun: boolean;

View file

@ -37,10 +37,6 @@ export class PersonalLayersPanel extends UIElement {
if (layout.id === PersonalLayout.NAME) { if (layout.id === PersonalLayout.NAME) {
continue; continue;
} }
if (layout.hideFromOverview &&
State.state.osmConnection.userDetails.data.name !== "Pieter Vander Vennet") {
continue
}
const header = const header =
new Combine([ new Combine([

View file

@ -3,7 +3,6 @@ import {ImageSearcher} from "../../Logic/ImageSearcher";
import {SlideShow} from "../SlideShow"; import {SlideShow} from "../SlideShow";
import {FixedUiElement} from "../Base/FixedUiElement"; import {FixedUiElement} from "../Base/FixedUiElement";
import {VariableUiElement} from "../Base/VariableUIElement"; import {VariableUiElement} from "../Base/VariableUIElement";
import {ConfirmDialog} from "../ConfirmDialog";
import {UIEventSource} from "../../Logic/UIEventSource"; import {UIEventSource} from "../../Logic/UIEventSource";
import { import {
Dependencies, Dependencies,
@ -12,8 +11,12 @@ import {
} from "../../Customizations/UIElementConstructor"; } from "../../Customizations/UIElementConstructor";
import {State} from "../../State"; 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 {
return true; return true;
} }
@ -46,12 +49,12 @@ export class ImageCarousel extends TagDependantUIElement {
private readonly _uiElements: UIEventSource<UIElement[]>; private readonly _uiElements: UIEventSource<UIElement[]>;
private readonly _deleteButton: UIElement; private readonly _deleteButton: UIElement;
private readonly _isDeleted: UIElement;
constructor(tags: UIEventSource<any>, osmConnection: OsmConnection = undefined) {
constructor(tags: UIEventSource<any>) {
super(tags); super(tags);
const self = this; const self = this;
osmConnection = osmConnection ?? State.state?.osmConnection;
this.searcher = new ImageSearcher(tags); this.searcher = new ImageSearcher(tags);
this._uiElements = this.searcher.map((imageURLS: string[]) => { this._uiElements = this.searcher.map((imageURLS: string[]) => {
@ -68,12 +71,17 @@ export class ImageCarousel extends TagDependantUIElement {
new FixedUiElement("")).HideOnEmpty(true); new FixedUiElement("")).HideOnEmpty(true);
const showDeleteButton = this.slideshow._currentSlide.map((i) => { const showDeleteButton = this.slideshow._currentSlide.map((i: number) => {
if(!State.state.osmConnection.userDetails.data.loggedIn){ if (!osmConnection?.userDetails?.data?.loggedIn) {
return false; return false;
} }
return self.searcher.IsDeletable(self.searcher.data[i]); return self.searcher.IsDeletable(self.searcher.data[i]);
}, [this.searcher, State.state.osmConnection.userDetails]); }, [this.searcher, osmConnection?.userDetails]);
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(() => { this.slideshow._currentSlide.addCallback(() => {
showDeleteButton.ping(); // This pings the showDeleteButton, which indicates that it has to hide it's subbuttons showDeleteButton.ping(); // This pings the showDeleteButton, which indicates that it has to hide it's subbuttons
}) })
@ -84,43 +92,66 @@ export class ImageCarousel extends TagDependantUIElement {
} }
this._deleteButton = new ConfirmDialog(showDeleteButton, const style = ";padding:0.4em;height:2em;padding: 0.4em; font-weight:bold;";
"<img src='./assets/delete.svg' alt='Afbeelding verwijderen' class='delete-image'>", const backButton = Translations.t.image.dontDelete
"<span>Afbeelding verwijderen</span>", .SetStyle("background:black;border-radius:0.4em 0.4em 0 0" + style)
"<span>Terug</span>",
deleteCurrent,
() => { },
'delete-image-confirm',
'delete-image-cancel');
const deleteButton = Translations.t.image.doDelete
.SetStyle("background:#ff8c8c;border-radius:0 0 0.4em 0.4em" + style)
.onClick(deleteCurrent);
const mapping = this.slideshow._currentSlide.map((i) => { const deleteButtonCheckbox = new CheckBox(
if (this.searcher._deletedImages.data.indexOf( new Combine([
this.searcher.data[i] backButton,
) >= 0) { deleteButton]
return "<div class='image-is-removed'>Deze afbeelding is verwijderd</div>" ).SetStyle("display:flex;" +
} "flex-direction:column;" +
"background:black;" +
"color:white;" +
"border-radius:0.5em;" +
"width:max-content;" +
"height:min-content;"),
new VariableUiElement(
showDeleteButton.map(showDelete => {
return ""; if (isDeleted.data) {
}); return Translations.t.image.isDeleted
this._isDeleted = new VariableUiElement( .SetStyle("display:block;" +
mapping "background-color: black;color:white;padding:0.4em;border-radius:0.4em").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();
}, [this.searcher._deletedImages, isDeleted]
)));
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.searcher._deletedImages.addCallback(() => {
this.slideshow._currentSlide.ping(); this.slideshow._currentSlide.ping();
}) })
} }
InnerRender(): string { InnerRender(): string {
return "<span class='image-carousel-container'>" + return new Combine([
"<div class='image-delete-container'>" + this._deleteButton,
this._deleteButton.Render() + this.slideshow
this._isDeleted.Render() + ]).SetStyle("position:relative").Render();
"</div>" +
this.slideshow.Render() +
"</span>";
} }
IsKnown(): boolean { IsKnown(): boolean {
@ -139,12 +170,6 @@ export class ImageCarousel extends TagDependantUIElement {
return 0; return 0;
} }
InnerUpdate(htmlElement: HTMLElement) {
super.InnerUpdate(htmlElement);
this._deleteButton.Update();
this._isDeleted.Update();
}
Activate() { Activate() {
super.Activate(); super.Activate();

View file

@ -44,13 +44,17 @@ export class ImageUploadFlow extends UIElement {
{value: "CC-BY 4.0", shown: Translations.t.image.ccb} {value: "CC-BY 4.0", shown: Translations.t.image.ccb}
], ],
preferedLicense preferedLicense
); const t = Translations.t.image; );
licensePicker.SetStyle("float:left");
const t = Translations.t.image;
this._licensePicker = licensePicker; this._licensePicker = licensePicker;
this._selectedLicence = licensePicker.GetValue(); this._selectedLicence = licensePicker.GetValue();
this._connectButton = new Combine([ t.pleaseLogin])
this._connectButton = new Combine([t.pleaseLogin])
.onClick(() => State.state.osmConnection.AttemptLogin()) .onClick(() => State.state.osmConnection.AttemptLogin())
.SetClass("login-button-friendly"); .SetClass("login-button-friendly");
} }
@ -91,29 +95,37 @@ export class ImageUploadFlow extends UIElement {
} }
} }
return "" + const extraInfo = new Combine([
"<div class='imageflow'>" + Translations.t.image.respectPrivacy,
"<br/>",
this._licensePicker,
"<br/>",
currentStateHtml,
"<br/>"
]);
"<label for='fileselector-" + this.id + "'>" + 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;"),
"<div class='imageflow-file-input-wrapper'>" + ]).SetStyle(" display: flex;cursor:pointer;padding: 0.5em;border-radius: 1em;border: 3px solid black;box-sizing:border-box;")
"<img src='./assets/camera-plus.svg' alt='upload image'/> " +
`<span class='imageflow-add-picture'>${Translations.t.image.addPicture.R()}</span>` + const actualInputElement =
"<div class='break'></div>" + `<input style='display: none' id='fileselector-${this.id}' type='file' accept='image/*' name='picField' multiple='multiple' alt=''/>`;
"</div>" +
currentStateHtml + const form = "<form id='fileselector-form-" + this.id + "'>" +
Translations.t.image.respectPrivacy.Render() + "<br/>" + `<label for='fileselector-${this.id}'>` +
this._licensePicker.Render() + "<br/>" + label.Render() +
"</label>" + "</label>" +
"<form id='fileselector-form-" + this.id + "'>" + actualInputElement+
"<input id='fileselector-" + this.id + "' " + "</form>";
"type='file' " +
"class='imageflow-file-input' " + return new Combine([
"accept='image/*' name='picField' size='24' multiple='multiple' alt=''" + form,
"/>" + extraInfo
"</form>" + ]).SetStyle("margin-top: 1em;margin-bottom: 2em;text-align: center;")
"</div>" .Render();
;
} }
InnerUpdate(htmlElement: HTMLElement) { InnerUpdate(htmlElement: HTMLElement) {

View file

@ -434,6 +434,18 @@ export default class Translations {
nl: "<span class='thanks'>Je afbeelding is toegevoegd. Bedankt om te helpen!</span>", nl: "<span class='thanks'>Je afbeelding is toegevoegd. Bedankt om te helpen!</span>",
fr: "<span class='thanks'>Votre photo est ajouté. Merci beaucoup!</span>", fr: "<span class='thanks'>Votre photo est ajouté. Merci beaucoup!</span>",
gl: "<span class='thanks'>A túa imaxe foi engadida. Grazas por axudar.</span>" gl: "<span class='thanks'>A túa imaxe foi engadida. Grazas por axudar.</span>"
}),
dontDelete: new T({
"nl":"Terug",
"en":"Cancel"
}),
doDelete: new T({
"nl":"Verwijder afbeelding",
"en":"Remove image"
}),
isDeleted: new T({
"nl":"Verwijderd",
"en":"Deleted"
}) })
}, },
centerMessage: { centerMessage: {

View file

@ -0,0 +1,57 @@
.tabs-header-bar {
padding-left: 1em;
padding-top: 10px; /* For the shadow */
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: start;
background-color: white;
}
.tab-single-header img {
height: 3em;
max-width: 3em;
padding: 0.5em;
display:block;
margin:auto;
}
.tab-content {
z-index: 5002;
background-color: white;
position: relative;
padding: 1em;
display: inline-block;
width: 100%;
box-sizing: border-box;
}
.tab-single-header {
border-top-left-radius: 1em;
border-top-right-radius: 1em;
z-index: 5000;
padding-bottom: 0;
margin-bottom: 0;
}
.tab-active {
background-color: white;
z-index: 5001;
box-shadow: 0 0 10px black;
border: 1px solid white;
min-width: 4em;
}
.tab-non-active {
background-color: #e5f5ff;
opacity: 0.5;
border-left: 1px solid gray;
border-right:1px solid gray;
border-top: 1px solid gray;
border-bottom: 1px solid lightgray;
min-width: 4em;
}

222
index.css
View file

@ -547,11 +547,8 @@
box-shadow: unset; box-shadow: unset;
overflow-y: unset; overflow-y: unset;
} }
} }
.to-the-map { .to-the-map {
display: block; display: block;
box-sizing: border-box; box-sizing: border-box;
@ -619,9 +616,6 @@
} }
.imgWithAttr { .imgWithAttr {
max-height: 20em; max-height: 20em;
@ -664,61 +658,12 @@
} }
/**************** Image upload flow ***************/
.imageflow {
margin-top: 1em;
margin-bottom: 2em;
text-align: center;
}
.imageflow-file-input-wrapper {
display: flex;
flex-wrap: wrap;
padding: 0.5em;
border-radius: 1em;
border: 3px solid black;
}
.imageflow-add-picture {
font-size: 28px;
font-weight: bold;
float: left;
margin-top: 4px;
padding-top: 4px;
padding-bottom: 4px;
padding-left: 13px;
}
.imageflow-file-input-wrapper img {
width: 36px;
height: 36px;
padding: 0.1em;
margin-top: 5px;
border-radius: 0;
float: left;
}
.license-picker {
float: left;
}
.imageflow > input {
display: none;
}
/***************** Info box (box containing features and questions ******************/ /***************** Info box (box containing features and questions ******************/
.leaflet-popup-content { .leaflet-popup-content {
width: 40em !important; width: 40em !important;
} }
#messagesboxmobile .featureinfobox { #messagesboxmobile .featureinfobox {
max-height: unset; max-height: unset;
overflow-y: unset; overflow-y: unset;
@ -842,103 +787,6 @@
display: inline-block display: inline-block
} }
/******* THe remove image buttons ****/
.image-carousel-container {
position: relative;
}
.image-is-removed{
display: inline-block;
left: 0;
top: 2.5em;
padding: 0.5em;
padding-left: 0.75em;
height: 3em;
width: 14em;
border-radius: 1em;
background-color: black;
color: white;
font-weight: bold;
height: 1.5em; /* same as .delete-image */
z-index: 7000;
}
.image-delete-container {
position: absolute;
left: 6em;
top: 1.5em;
display: inline-block;
z-index: 7000;
}
.delete-image {
width: 1.5em;
height: 1.5em;
padding: 0.5em;
border-radius: 3em;
background-color: black;
}
.delete-image-confirm {
position: absolute;
display: inline-block;
left: 0;
top: 2.5em;
padding: 0.5em;
padding-left: 0.75em;
width: 14em;
border-radius: 1em;
border-top-left-radius: 0;
border-top-right-radius: 0;
background-color: #ff8c8c;
color: white;
height: 1.5em; /* same as .delete-image */
z-index: 7000;
}
.delete-image-confirm span {
font-size: larger;
font-weight: bold;
}
.delete-image-cancel {
display: inline-block;
position: absolute;
left: 0em;
padding: 0.5em;
padding-left: 0.75em;
border-radius: 1em;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
height: 1.5em; /* same as .delete-image */
width: 14em; /* Same as delete-image-confirm */
background-color: black;
color: white;
z-index: 7000;
}
.delete-image-cancel span {
font-size: larger;
font-weight: bold;
}
/**** The save button *****/ /**** The save button *****/
.save { .save {
@ -946,9 +794,7 @@
border: solid white 2px; border: solid white 2px;
background-color: #3a3aeb; background-color: #3a3aeb;
color: white; color: white;
padding: 0.2em; padding: 0.2em 0.6em;
padding-left: 0.6em;
padding-right: 0.6em;
font-size: x-large; font-size: x-large;
font-weight: bold; font-weight: bold;
border-radius: 1.5em; border-radius: 1.5em;
@ -991,66 +837,6 @@
} }
/******** TabbedElement ****/
.tabs-header-bar {
padding-left: 1em;
padding-top: 10px; /* For the shadow */
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: start;
background-color: white;
}
.tab-single-header img {
height: 3em;
max-width: 3em;
padding: 0.5em;
display:block;
margin:auto;
}
.tab-content {
z-index: 5002;
background-color: white;
position: relative;
padding: 1em;
display: inline-block;
width: 100%;
box-sizing: border-box;
}
.tab-single-header {
border-top-left-radius: 1em;
border-top-right-radius: 1em;
z-index: 5000;
padding-bottom: 0;
margin-bottom: 0;
}
.tab-active {
background-color: white;
z-index: 5001;
box-shadow: 0 0 10px black;
border: 1px solid white;
min-width: 4em;
}
.tab-non-active {
background-color: #e5f5ff;
opacity: 0.5;
border-left: 1px solid gray;
border-right:1px solid gray;
border-top: 1px solid gray;
border-bottom: 1px solid lightgray;
min-width: 4em;
}
/****** ShareScreen *****/ /****** ShareScreen *****/
.literal-code { .literal-code {
@ -1127,12 +913,6 @@
font-size: large; font-size: large;
} }
.custom-layer-panel {
}
.custom-layer-panel-header { .custom-layer-panel-header {
display: flex; display: flex;
flex-wrap: nowrap; flex-wrap: nowrap;

View file

@ -8,6 +8,7 @@
<link rel="stylesheet" href="./vendor/leaflet.css"/> <link rel="stylesheet" href="./vendor/leaflet.css"/>
<link rel="stylesheet" href="./index.css"/> <link rel="stylesheet" href="./index.css"/>
<link rel="stylesheet" href="./css/userbadge.css"/> <link rel="stylesheet" href="./css/userbadge.css"/>
<link rel="stylesheet" href="./css/tabbedComponent.css"/>
<link rel="stylesheet" href="./css/slideshow.css"/> <link rel="stylesheet" href="./css/slideshow.css"/>
<link rel="manifest" href="./manifest.manifest"> <link rel="manifest" href="./manifest.manifest">
<link rel="icon" href="assets/add.svg" sizes="any" type="image/svg+xml"> <link rel="icon" href="assets/add.svg" sizes="any" type="image/svg+xml">

View file

@ -37,9 +37,9 @@ let defaultLayout = "bookcases"
let hash = window.location.hash; let hash = window.location.hash;
const path = window.location.pathname.split("/").slice(-1)[0]; const path = window.location.pathname.split("/").slice(-1)[0];
if (path !== "index.html") { if (path !== "index.html" && path !== "") {
defaultLayout = path.substr(0, path.length - 5); defaultLayout = path.substr(0, path.length - 5);
console.log("Using layout", defaultLayout) console.log("Using layout", defaultLayout);
} }
// Run over all questsets. If a part of the URL matches a searched-for part in the layout, it'll take that as the default // Run over all questsets. If a part of the URL matches a searched-for part in the layout, it'll take that as the default

View file

@ -4,6 +4,8 @@
<head> <head>
<title>Small tests</title> <title>Small tests</title>
<link href="index.css" rel="stylesheet"/> <link href="index.css" rel="stylesheet"/>
<link href="css/slideshow.css" rel="stylesheet"/>
<link href="css/tabbedComponent.css" rel="stylesheet"/>
<style> <style>
.tag-input-row { .tag-input-row {
display: block ruby; display: block ruby;

33
test.ts
View file

@ -1,25 +1,14 @@
import {CheckBoxes} from "./UI/Input/Checkboxes"; import {ImageCarousel} from "./UI/Image/ImageCarousel";
import {FixedInputElement} from "./UI/Input/FixedInputElement"; import {UIEventSource} from "./Logic/UIEventSource";
import {VariableUiElement} from "./UI/Base/VariableUIElement"; import {OsmConnection} from "./Logic/Osm/OsmConnection";
const connection = new OsmConnection(true, new UIEventSource<string>(undefined), "qsdf");
connection.AttemptLogin();
const cb = new CheckBoxes( const imageCarousel = new ImageCarousel(new UIEventSource<any>({
[ new FixedInputElement("One", 1), "image": "https://i.imgur.com/kX3rl3v.jpg"
new FixedInputElement("Two",2), }), connection);
new FixedInputElement("Thee",3)]
)
cb.AttachTo("maindiv"); imageCarousel.AttachTo("maindiv")
new VariableUiElement(cb.GetValue().map(ts => ts?.join(", "))).AttachTo("extradiv") imageCarousel.Activate();
window.setTimeout(() => {
cb.GetValue().setData([2,3]);
}, 2500)
window.setTimeout(() => {
cb.GetValue().setData([2]);
}, 3000)
window.setTimeout(() => {
cb.GetValue().setData([1, 2]);
}, 3500)