Fixed part of the special renderings
This commit is contained in:
parent
eec762b71f
commit
e480c97676
11 changed files with 156 additions and 147 deletions
|
@ -3,9 +3,9 @@ import {Imgur} from "./Imgur";
|
||||||
|
|
||||||
export default class ImgurUploader {
|
export default class ImgurUploader {
|
||||||
|
|
||||||
public queue: UIEventSource<string[]>;
|
public readonly queue: UIEventSource<string[]> = new UIEventSource<string[]>([]);
|
||||||
public failed: UIEventSource<string[]>;
|
public readonly failed: UIEventSource<string[]> = new UIEventSource<string[]>([]);
|
||||||
public success: UIEventSource<string[]>
|
public readonly success: UIEventSource<string[]> = new UIEventSource<string[]>([]);
|
||||||
private readonly _handleSuccessUrl: (string) => void;
|
private readonly _handleSuccessUrl: (string) => void;
|
||||||
|
|
||||||
constructor(handleSuccessUrl: (string) => void) {
|
constructor(handleSuccessUrl: (string) => void) {
|
||||||
|
|
|
@ -15,8 +15,17 @@ export class TabbedComponent extends Combine {
|
||||||
for (let i = 0; i < elements.length; i++) {
|
for (let i = 0; i < elements.length; i++) {
|
||||||
let element = elements[i];
|
let element = elements[i];
|
||||||
const header = Translations.W(element.header).onClick(() => openedTabSrc.setData(i))
|
const header = Translations.W(element.header).onClick(() => openedTabSrc.setData(i))
|
||||||
|
openedTabSrc.addCallbackAndRun(selected => {
|
||||||
|
if(selected === i){
|
||||||
|
header.SetClass("tab-active")
|
||||||
|
header.RemoveClass("tab-non-active")
|
||||||
|
}else{
|
||||||
|
header.SetClass("tab-non-active")
|
||||||
|
header.RemoveClass("tab-active")
|
||||||
|
}
|
||||||
|
})
|
||||||
const content = Translations.W(element.content)
|
const content = Translations.W(element.content)
|
||||||
content.SetClass("tab-content")
|
content.SetClass("relative p-4 w-full inline-block")
|
||||||
contentElements.push(content);
|
contentElements.push(content);
|
||||||
const tab = header.SetClass("block tab-single-header")
|
const tab = header.SetClass("block tab-single-header")
|
||||||
tabs.push(tab)
|
tabs.push(tab)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import {DropDown} from "../Input/DropDown";
|
import {DropDown} from "../Input/DropDown";
|
||||||
import Translations from "../i18n/Translations";
|
import Translations from "../i18n/Translations";
|
||||||
import State from "../../State";
|
import State from "../../State";
|
||||||
|
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||||
|
|
||||||
export default class LicensePicker extends DropDown<string>{
|
export default class LicensePicker extends DropDown<string>{
|
||||||
|
|
||||||
|
@ -11,7 +12,7 @@ export default class LicensePicker extends DropDown<string>{
|
||||||
{value: "CC-BY-SA 4.0", shown: Translations.t.image.ccbs},
|
{value: "CC-BY-SA 4.0", shown: Translations.t.image.ccbs},
|
||||||
{value: "CC-BY 4.0", shown: Translations.t.image.ccb}
|
{value: "CC-BY 4.0", shown: Translations.t.image.ccb}
|
||||||
],
|
],
|
||||||
State.state.osmConnection.GetPreference("pictures-license")
|
State.state?.osmConnection?.GetPreference("pictures-license") ?? new UIEventSource<string>("CC0")
|
||||||
)
|
)
|
||||||
this.SetClass("flex flex-col sm:flex-row").SetStyle("float:left");
|
this.SetClass("flex flex-col sm:flex-row").SetStyle("float:left");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import {UIElement} from "../UIElement";
|
|
||||||
import {SlideShow} from "./SlideShow";
|
import {SlideShow} from "./SlideShow";
|
||||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||||
import Combine from "../Base/Combine";
|
import Combine from "../Base/Combine";
|
||||||
|
@ -8,33 +7,35 @@ import {ImgurImage} from "./ImgurImage";
|
||||||
import {MapillaryImage} from "./MapillaryImage";
|
import {MapillaryImage} from "./MapillaryImage";
|
||||||
import BaseUIElement from "../BaseUIElement";
|
import BaseUIElement from "../BaseUIElement";
|
||||||
import Img from "../Base/Img";
|
import Img from "../Base/Img";
|
||||||
|
import Toggle from "../Input/Toggle";
|
||||||
|
|
||||||
export class ImageCarousel extends UIElement{
|
export class ImageCarousel extends Toggle {
|
||||||
|
|
||||||
public readonly slideshow: BaseUIElement;
|
constructor(images: UIEventSource<{ key: string, url: string }[]>, tags: UIEventSource<any>) {
|
||||||
|
const uiElements = images.map((imageURLS: { key: string, url: string }[]) => {
|
||||||
constructor(images: UIEventSource<{key: string, url:string}[]>, tags: UIEventSource<any>) {
|
|
||||||
super(images);
|
|
||||||
const uiElements = images.map((imageURLS: {key: string, url:string}[]) => {
|
|
||||||
const uiElements: BaseUIElement[] = [];
|
const uiElements: BaseUIElement[] = [];
|
||||||
for (const url of imageURLS) {
|
for (const url of imageURLS) {
|
||||||
let image = ImageCarousel.CreateImageElement(url.url)
|
let image = ImageCarousel.CreateImageElement(url.url)
|
||||||
if(url.key !== undefined){
|
if (url.key !== undefined) {
|
||||||
image = new Combine([
|
image = new Combine([
|
||||||
image,
|
image,
|
||||||
new DeleteImage(url.key, tags).SetClass("delete-image-marker absolute top-0 left-0 pl-3")
|
new DeleteImage(url.key, tags).SetClass("delete-image-marker absolute top-0 left-0 pl-3")
|
||||||
]).SetClass("relative");
|
]).SetClass("relative");
|
||||||
}
|
}
|
||||||
image
|
image
|
||||||
.SetClass("w-full block")
|
.SetClass("w-full block")
|
||||||
|
.SetStyle("min-width: 50px; background: grey;")
|
||||||
uiElements.push(image);
|
uiElements.push(image);
|
||||||
}
|
}
|
||||||
return uiElements;
|
return uiElements;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.slideshow = new SlideShow(uiElements);
|
super(
|
||||||
|
new SlideShow(uiElements).SetClass("w-full"),
|
||||||
|
undefined,
|
||||||
|
uiElements.map(els => els.length > 0)
|
||||||
|
)
|
||||||
this.SetClass("block w-full");
|
this.SetClass("block w-full");
|
||||||
this.slideshow.SetClass("w-full");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
@ -57,8 +58,4 @@ export class ImageCarousel extends UIElement{
|
||||||
return new Img(url);
|
return new Img(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InnerRender() {
|
|
||||||
return this.slideshow;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||||
import {UIElement} from "../UIElement";
|
|
||||||
import State from "../../State";
|
import State from "../../State";
|
||||||
import Combine from "../Base/Combine";
|
import Combine from "../Base/Combine";
|
||||||
import Translations from "../i18n/Translations";
|
import Translations from "../i18n/Translations";
|
||||||
|
@ -13,22 +12,9 @@ import ImgurUploader from "../../Logic/Web/ImgurUploader";
|
||||||
import UploadFlowStateUI from "../BigComponents/UploadFlowStateUI";
|
import UploadFlowStateUI from "../BigComponents/UploadFlowStateUI";
|
||||||
import LayerConfig from "../../Customizations/JSON/LayerConfig";
|
import LayerConfig from "../../Customizations/JSON/LayerConfig";
|
||||||
|
|
||||||
export class ImageUploadFlow extends UIElement {
|
export class ImageUploadFlow extends Toggle {
|
||||||
|
|
||||||
private readonly _element: BaseUIElement;
|
|
||||||
|
|
||||||
|
|
||||||
private readonly _tags: UIEventSource<any>;
|
|
||||||
private readonly _selectedLicence: UIEventSource<string>;
|
|
||||||
|
|
||||||
|
|
||||||
private readonly _imagePrefix: string;
|
|
||||||
|
|
||||||
constructor(tagsSource: UIEventSource<any>, imagePrefix: string = "image") {
|
constructor(tagsSource: UIEventSource<any>, imagePrefix: string = "image") {
|
||||||
super(State.state.osmConnection.userDetails);
|
|
||||||
this._imagePrefix = imagePrefix;
|
|
||||||
|
|
||||||
|
|
||||||
const uploader = new ImgurUploader(url => {
|
const uploader = new ImgurUploader(url => {
|
||||||
// A file was uploaded - we add it to the tags of the object
|
// A file was uploaded - we add it to the tags of the object
|
||||||
|
|
||||||
|
@ -50,9 +36,10 @@ export class ImageUploadFlow extends UIElement {
|
||||||
|
|
||||||
const t = Translations.t.image;
|
const t = Translations.t.image;
|
||||||
const label = new Combine([
|
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"),
|
Svg.camera_plus_ui().SetClass("block w-12 h-12 p-1"),
|
||||||
Translations.t.image.addPicture
|
Translations.t.image.addPicture.Clone().SetClass("block align-middle mt-1 ml-3")
|
||||||
]).SetClass("image-upload-flow-button")
|
]).SetClass("p-2 border-4 border-black rounded-full text-4xl font-bold h-full align-middle w-full flex justify-center")
|
||||||
|
|
||||||
const fileSelector = new FileSelectorButton(label)
|
const fileSelector = new FileSelectorButton(label)
|
||||||
fileSelector.GetValue().addCallback(filelist => {
|
fileSelector.GetValue().addCallback(filelist => {
|
||||||
if (filelist === undefined) {
|
if (filelist === undefined) {
|
||||||
|
@ -60,13 +47,13 @@ export class ImageUploadFlow extends UIElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Received images from the user, starting upload")
|
console.log("Received images from the user, starting upload")
|
||||||
const license = this._selectedLicence.data ?? "CC0"
|
const license = licensePicker.GetValue().data ?? "CC0"
|
||||||
|
|
||||||
const tags = this._tags.data;
|
const tags = tagsSource.data;
|
||||||
|
|
||||||
const layout = State.state.layoutToUse.data
|
const layout = State.state?.layoutToUse?.data
|
||||||
let matchingLayer: LayerConfig = undefined
|
let matchingLayer: LayerConfig = undefined
|
||||||
for (const layer of layout.layers) {
|
for (const layer of layout?.layers ?? []) {
|
||||||
if (layer.source.osmTags.matchesProperties(tags)) {
|
if (layer.source.osmTags.matchesProperties(tags)) {
|
||||||
matchingLayer = layer;
|
matchingLayer = layer;
|
||||||
break;
|
break;
|
||||||
|
@ -90,30 +77,27 @@ export class ImageUploadFlow extends UIElement {
|
||||||
|
|
||||||
const uploadFlow: BaseUIElement = new Combine([
|
const uploadFlow: BaseUIElement = new Combine([
|
||||||
fileSelector,
|
fileSelector,
|
||||||
Translations.t.image.respectPrivacy.SetStyle("font-size:small;"),
|
Translations.t.image.respectPrivacy.Clone().SetStyle("font-size:small;"),
|
||||||
licensePicker,
|
licensePicker,
|
||||||
uploadStateUi
|
uploadStateUi
|
||||||
]).SetClass("image-upload-flow")
|
]).SetClass("flex flex-col image-upload-flow mt-4 mb-8 text-center")
|
||||||
.SetStyle("margin-top: 1em;margin-bottom: 2em;text-align: center;");
|
|
||||||
|
|
||||||
|
|
||||||
const pleaseLoginButton = t.pleaseLogin.Clone()
|
const pleaseLoginButton = t.pleaseLogin.Clone()
|
||||||
.onClick(() => State.state.osmConnection.AttemptLogin())
|
.onClick(() => State.state.osmConnection.AttemptLogin())
|
||||||
.SetClass("login-button-friendly");
|
.SetClass("login-button-friendly");
|
||||||
this._element = new Toggle(
|
super(
|
||||||
new Toggle(
|
new Toggle(
|
||||||
/*We can show the actual upload button!*/
|
/*We can show the actual upload button!*/
|
||||||
uploadFlow,
|
uploadFlow,
|
||||||
/* User not logged in*/ pleaseLoginButton,
|
/* User not logged in*/ pleaseLoginButton,
|
||||||
State.state.osmConnection.userDetails.map(userinfo => userinfo.loggedIn)
|
State.state?.osmConnection?.isLoggedIn
|
||||||
),
|
),
|
||||||
undefined /* Nothing as the user badge is disabled*/, State.state.featureSwitchUserbadge
|
undefined /* Nothing as the user badge is disabled*/,
|
||||||
|
State.state.featureSwitchUserbadge
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InnerRender(): string | BaseUIElement {
|
|
||||||
return this._element;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,41 +1,59 @@
|
||||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||||
import BaseUIElement from "../BaseUIElement";
|
import BaseUIElement from "../BaseUIElement";
|
||||||
|
import $ from "jquery"
|
||||||
|
|
||||||
export class SlideShow extends BaseUIElement {
|
export class SlideShow extends BaseUIElement {
|
||||||
|
|
||||||
|
|
||||||
private readonly _element: HTMLElement;
|
private readonly embeddedElements: UIEventSource<BaseUIElement[]>;
|
||||||
|
|
||||||
constructor(
|
|
||||||
embeddedElements: UIEventSource<BaseUIElement[]>) {
|
|
||||||
super()
|
|
||||||
|
|
||||||
const el = document.createElement("div")
|
|
||||||
this._element = el;
|
|
||||||
|
|
||||||
el.classList.add("slick-carousel")
|
|
||||||
require("slick-carousel")
|
|
||||||
// @ts-ignore
|
|
||||||
el.slick({
|
|
||||||
autoplay: true,
|
|
||||||
arrows: true,
|
|
||||||
dots: true,
|
|
||||||
lazyLoad: 'progressive',
|
|
||||||
variableWidth: true,
|
|
||||||
centerMode: true,
|
|
||||||
centerPadding: "60px",
|
|
||||||
adaptive: true
|
|
||||||
});
|
|
||||||
embeddedElements.addCallbackAndRun(elements => {
|
|
||||||
for (const element of elements ?? []) {
|
|
||||||
element.SetClass("slick-carousel-content")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
constructor(embeddedElements: UIEventSource<BaseUIElement[]>) {
|
||||||
|
super()
|
||||||
|
this.embeddedElements = embeddedElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InnerConstructElement(): HTMLElement {
|
protected InnerConstructElement(): HTMLElement {
|
||||||
return this._element;
|
const el = document.createElement("div")
|
||||||
|
el.classList.add("slic-carousel")
|
||||||
|
|
||||||
|
el.onchange = () => {
|
||||||
|
console.log("Parent is now ", el.parentElement)
|
||||||
|
}
|
||||||
|
|
||||||
|
const mutationObserver = new MutationObserver(mutations => {
|
||||||
|
console.log("Mutations are: ", mutations)
|
||||||
|
|
||||||
|
|
||||||
|
mutationObserver.disconnect()
|
||||||
|
require("slick-carousel")
|
||||||
|
// @ts-ignore
|
||||||
|
el.slick({
|
||||||
|
autoplay: true,
|
||||||
|
arrows: true,
|
||||||
|
dots: true,
|
||||||
|
lazyLoad: 'progressive',
|
||||||
|
variableWidth: true,
|
||||||
|
centerMode: true,
|
||||||
|
centerPadding: "60px",
|
||||||
|
adaptive: true
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
mutationObserver.observe(el, {
|
||||||
|
childList: true,
|
||||||
|
characterData: true,
|
||||||
|
subtree: true
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
this.embeddedElements.addCallbackAndRun(elements => {
|
||||||
|
for (const element of elements ?? []) {
|
||||||
|
element.SetClass("slick-carousel-content")
|
||||||
|
el.appendChild(element.ConstructElement())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
import BaseUIElement from "../BaseUIElement";
|
import BaseUIElement from "../BaseUIElement";
|
||||||
import {InputElement} from "../Input/InputElement";
|
import {InputElement} from "./InputElement";
|
||||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||||
|
|
||||||
export default class FileSelectorButton extends InputElement<FileList> {
|
export default class FileSelectorButton extends InputElement<FileList> {
|
||||||
|
|
||||||
|
private static _nextid;
|
||||||
IsSelected: UIEventSource<boolean>;
|
IsSelected: UIEventSource<boolean>;
|
||||||
private readonly _value = new UIEventSource(undefined);
|
private readonly _value = new UIEventSource(undefined);
|
||||||
private readonly _label: BaseUIElement;
|
private readonly _label: BaseUIElement;
|
||||||
|
@ -13,6 +14,8 @@ export default class FileSelectorButton extends InputElement<FileList> {
|
||||||
super();
|
super();
|
||||||
this._label = label;
|
this._label = label;
|
||||||
this._acceptType = acceptType;
|
this._acceptType = acceptType;
|
||||||
|
this.SetClass("block cursor-pointer")
|
||||||
|
label.SetClass("cursor-pointer")
|
||||||
}
|
}
|
||||||
|
|
||||||
GetValue(): UIEventSource<FileList> {
|
GetValue(): UIEventSource<FileList> {
|
||||||
|
@ -26,36 +29,37 @@ export default class FileSelectorButton extends InputElement<FileList> {
|
||||||
protected InnerConstructElement(): HTMLElement {
|
protected InnerConstructElement(): HTMLElement {
|
||||||
const self = this;
|
const self = this;
|
||||||
const el = document.createElement("form")
|
const el = document.createElement("form")
|
||||||
{
|
const label = document.createElement("label")
|
||||||
const label = document.createElement("label")
|
label.appendChild(this._label.ConstructElement())
|
||||||
label.appendChild(this._label.ConstructElement())
|
el.appendChild(label)
|
||||||
el.appendChild(label)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const actualInputElement = document.createElement("input");
|
|
||||||
actualInputElement.style.cssText = "display:none";
|
|
||||||
actualInputElement.type = "file";
|
|
||||||
actualInputElement.accept = this._acceptType;
|
|
||||||
actualInputElement.name = "picField";
|
|
||||||
actualInputElement.multiple = true;
|
|
||||||
|
|
||||||
actualInputElement.onchange = () => {
|
const actualInputElement = document.createElement("input");
|
||||||
if (actualInputElement.files !== null) {
|
actualInputElement.style.cssText = "display:none";
|
||||||
self._value.setData(actualInputElement.files)
|
actualInputElement.type = "file";
|
||||||
}
|
actualInputElement.accept = this._acceptType;
|
||||||
|
actualInputElement.name = "picField";
|
||||||
|
actualInputElement.multiple = true;
|
||||||
|
actualInputElement.id = "fileselector" + FileSelectorButton._nextid;
|
||||||
|
FileSelectorButton._nextid++;
|
||||||
|
|
||||||
|
label.htmlFor = actualInputElement.id;
|
||||||
|
|
||||||
|
actualInputElement.onchange = () => {
|
||||||
|
if (actualInputElement.files !== null) {
|
||||||
|
self._value.setData(actualInputElement.files)
|
||||||
}
|
}
|
||||||
|
|
||||||
el.addEventListener('submit', e => {
|
|
||||||
if (actualInputElement.files !== null) {
|
|
||||||
self._value.setData(actualInputElement.files)
|
|
||||||
}
|
|
||||||
e.preventDefault()
|
|
||||||
})
|
|
||||||
|
|
||||||
el.appendChild(actualInputElement)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
el.addEventListener('submit', e => {
|
||||||
|
if (actualInputElement.files !== null) {
|
||||||
|
self._value.setData(actualInputElement.files)
|
||||||
|
}
|
||||||
|
e.preventDefault()
|
||||||
|
})
|
||||||
|
|
||||||
|
el.appendChild(actualInputElement)
|
||||||
|
|
||||||
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,10 @@ import Svg from "../../Svg";
|
||||||
import {VariableUiElement} from "../Base/VariableUIElement";
|
import {VariableUiElement} from "../Base/VariableUIElement";
|
||||||
import {SaveButton} from "../Popup/SaveButton";
|
import {SaveButton} from "../Popup/SaveButton";
|
||||||
import CheckBoxes from "../Input/Checkboxes";
|
import CheckBoxes from "../Input/Checkboxes";
|
||||||
import UserDetails from "../../Logic/Osm/OsmConnection";
|
import UserDetails, {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
||||||
import BaseUIElement from "../BaseUIElement";
|
import BaseUIElement from "../BaseUIElement";
|
||||||
import Toggle from "../Input/Toggle";
|
import Toggle from "../Input/Toggle";
|
||||||
|
import State from "../../State";
|
||||||
|
|
||||||
export default class ReviewForm extends InputElement<Review> {
|
export default class ReviewForm extends InputElement<Review> {
|
||||||
|
|
||||||
|
@ -19,19 +20,19 @@ export default class ReviewForm extends InputElement<Review> {
|
||||||
private readonly _stars: BaseUIElement;
|
private readonly _stars: BaseUIElement;
|
||||||
private _saveButton: BaseUIElement;
|
private _saveButton: BaseUIElement;
|
||||||
private readonly _isAffiliated: BaseUIElement;
|
private readonly _isAffiliated: BaseUIElement;
|
||||||
private userDetails: UIEventSource<UserDetails>;
|
|
||||||
private readonly _postingAs: BaseUIElement;
|
private readonly _postingAs: BaseUIElement;
|
||||||
|
private readonly _osmConnection: OsmConnection;
|
||||||
|
|
||||||
|
|
||||||
constructor(onSave: ((r: Review, doneSaving: (() => void)) => void), userDetails: UIEventSource<UserDetails>) {
|
constructor(onSave: ((r: Review, doneSaving: (() => void)) => void), osmConnection: OsmConnection) {
|
||||||
super();
|
super();
|
||||||
this.userDetails = userDetails;
|
this._osmConnection = osmConnection;
|
||||||
const t = Translations.t.reviews;
|
const t = Translations.t.reviews;
|
||||||
this._value = new UIEventSource({
|
this._value = new UIEventSource({
|
||||||
made_by_user: new UIEventSource<boolean>(true),
|
made_by_user: new UIEventSource<boolean>(true),
|
||||||
rating: undefined,
|
rating: undefined,
|
||||||
comment: undefined,
|
comment: undefined,
|
||||||
author: userDetails.data.name,
|
author: osmConnection.userDetails.data.name,
|
||||||
affiliated: false,
|
affiliated: false,
|
||||||
date: new Date()
|
date: new Date()
|
||||||
});
|
});
|
||||||
|
@ -48,7 +49,7 @@ export default class ReviewForm extends InputElement<Review> {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
this._postingAs =
|
this._postingAs =
|
||||||
new Combine([t.posting_as, new VariableUiElement(userDetails.map((ud: UserDetails) => ud.name)).SetClass("review-author")])
|
new Combine([t.posting_as, new VariableUiElement(osmConnection.userDetails.map((ud: UserDetails) => ud.name)).SetClass("review-author")])
|
||||||
.SetStyle("display:flex;flex-direction: column;align-items: flex-end;margin-left: auto;")
|
.SetStyle("display:flex;flex-direction: column;align-items: flex-end;margin-left: auto;")
|
||||||
this._saveButton =
|
this._saveButton =
|
||||||
new SaveButton(this._value.map(r => self.IsValid(r)), undefined)
|
new SaveButton(this._value.map(r => self.IsValid(r)), undefined)
|
||||||
|
@ -100,10 +101,12 @@ export default class ReviewForm extends InputElement<Review> {
|
||||||
Translations.t.reviews.tos.SetClass("subtle")
|
Translations.t.reviews.tos.SetClass("subtle")
|
||||||
])
|
])
|
||||||
.SetClass("review-form")
|
.SetClass("review-form")
|
||||||
|
|
||||||
|
const connection = this._osmConnection;
|
||||||
|
const login = Translations.t.reviews.plz_login.Clone().onClick(() => connection.AttemptLogin())
|
||||||
|
|
||||||
|
return new Toggle(form,login ,
|
||||||
return new Toggle(form, Translations.t.reviews.plz_login.Clone(),
|
connection.isLoggedIn)
|
||||||
this.userDetails.map(userdetails => userdetails.loggedIn)).ToggleOnClick()
|
|
||||||
.ConstructElement()
|
.ConstructElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ export default class SpecialVisualizations {
|
||||||
state.mangroveIdentity,
|
state.mangroveIdentity,
|
||||||
state.osmConnection._dryRun
|
state.osmConnection._dryRun
|
||||||
);
|
);
|
||||||
const form = new ReviewForm((r, whenDone) => mangrove.AddReview(r, whenDone), state.osmConnection.userDetails);
|
const form = new ReviewForm((r, whenDone) => mangrove.AddReview(r, whenDone), state.osmConnection);
|
||||||
return new ReviewElement(mangrove.GetSubjectUri(), mangrove.GetReviews(), form);
|
return new ReviewElement(mangrove.GetSubjectUri(), mangrove.GetReviews(), form);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -160,7 +160,7 @@ export default class SpecialVisualizations {
|
||||||
],
|
],
|
||||||
constr: (state: State, tagSource: UIEventSource<any>, args) => {
|
constr: (state: State, tagSource: UIEventSource<any>, args) => {
|
||||||
if (window.navigator.share) {
|
if (window.navigator.share) {
|
||||||
const title = state.layoutToUse.data.title.txt;
|
const title = state?.layoutToUse?.data?.title?.txt ?? "MapComplete";
|
||||||
let name = tagSource.data.name;
|
let name = tagSource.data.name;
|
||||||
if (name) {
|
if (name) {
|
||||||
name = `${name} (${title})`
|
name = `${name} (${title})`
|
||||||
|
@ -174,7 +174,7 @@ export default class SpecialVisualizations {
|
||||||
return new ShareButton(Svg.share_ui(), {
|
return new ShareButton(Svg.share_ui(), {
|
||||||
title: name,
|
title: name,
|
||||||
url: url,
|
url: url,
|
||||||
text: state.layoutToUse.data.shortDescription.txt
|
text: state?.layoutToUse?.data?.shortDescription?.txt ?? "MapComplete"
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return new FixedUiElement("")
|
return new FixedUiElement("")
|
||||||
|
|
|
@ -30,17 +30,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.tab-content {
|
|
||||||
z-index: 5002;
|
|
||||||
background-color: var(--background-color);
|
|
||||||
color: var(--foreground-color);
|
|
||||||
position: relative;
|
|
||||||
padding: 1em;
|
|
||||||
display: inline-block;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-single-header {
|
.tab-single-header {
|
||||||
border-top-left-radius: 1em;
|
border-top-left-radius: 1em;
|
||||||
border-top-right-radius: 1em;
|
border-top-right-radius: 1em;
|
||||||
|
|
38
test.ts
38
test.ts
|
@ -1,27 +1,31 @@
|
||||||
import {RadioButton} from "./UI/Input/RadioButton";
|
|
||||||
import {FixedInputElement} from "./UI/Input/FixedInputElement";
|
|
||||||
import {SubstitutedTranslation} from "./UI/SubstitutedTranslation";
|
|
||||||
import {UIEventSource} from "./Logic/UIEventSource";
|
import {UIEventSource} from "./Logic/UIEventSource";
|
||||||
import {Translation} from "./UI/i18n/Translation";
|
import SpecialVisualizations from "./UI/SpecialVisualizations";
|
||||||
import TagRenderingAnswer from "./UI/Popup/TagRenderingAnswer";
|
import State from "./State";
|
||||||
import TagRenderingConfig from "./Customizations/JSON/TagRenderingConfig";
|
import Combine from "./UI/Base/Combine";
|
||||||
import EditableTagRendering from "./UI/Popup/EditableTagRendering";
|
import {FixedUiElement} from "./UI/Base/FixedUiElement";
|
||||||
|
|
||||||
|
|
||||||
const tagsSource = new UIEventSource({
|
const tagsSource = new UIEventSource({
|
||||||
id:'id',
|
id:'id',
|
||||||
name:'name',
|
name:'name',
|
||||||
surface:'asphalt'
|
surface:'asphalt',
|
||||||
|
image: "https://i.imgur.com/kX3rl3v.jpg",
|
||||||
|
"image:1": "https://i.imgur.com/kX3rl3v.jpg",
|
||||||
|
_country:"be",
|
||||||
|
// "opening_hours":"mo-fr 09:00-18:00"
|
||||||
})
|
})
|
||||||
|
|
||||||
const config = new TagRenderingConfig({
|
const state = new State(undefined)
|
||||||
render: "Rendering {name} {id} {surface}"
|
State.state = state
|
||||||
}, null, "test")
|
|
||||||
|
|
||||||
new EditableTagRendering(
|
const allSpecials = SpecialVisualizations.specialVisualizations.map(spec => {
|
||||||
tagsSource,
|
try{
|
||||||
config
|
|
||||||
).AttachTo("extradiv")
|
|
||||||
|
|
||||||
|
return new Combine([spec.funcName, spec.constr(state, tagsSource, spec.args.map(a => a.defaultValue ?? "")).SetClass("block")])
|
||||||
window.v = tagsSource
|
.SetClass("flex flex-col border border-black p-2 m-2");
|
||||||
|
}catch(e){
|
||||||
|
console.error(e)
|
||||||
|
return new FixedUiElement("Could not construct "+spec.funcName+" due to "+e).SetClass("alert")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
new Combine(allSpecials).AttachTo("maindiv")
|
Loading…
Reference in a new issue