From e46ea51d4412f496c4a734852650d6b3fccac796 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Fri, 25 Sep 2020 17:57:01 +0200 Subject: [PATCH] Fix bug with multiple image uploads, refactoring of TextField --- UI/CustomGenerator/GeneralSettings.ts | 5 ++- UI/CustomGenerator/SavePanel.ts | 4 --- UI/CustomGenerator/TagRenderingPanel.ts | 9 +++--- UI/ImageUploadFlow.ts | 14 +++++---- UI/Input/InputElementMap.ts | 2 +- UI/Input/InputElementWrapper.ts | 42 ------------------------- UI/Input/MultiLingualTextFields.ts | 20 ++++++------ UI/Input/MultiTagInput.ts | 5 --- UI/Input/SingleTagInput.ts | 7 ++--- UI/Input/TextField.ts | 19 ++++++++--- UI/Input/ValidatedTextField.ts | 1 - UI/ShareScreen.ts | 2 +- UI/i18n/Translations.ts | 14 ++++----- 13 files changed, 53 insertions(+), 91 deletions(-) delete mode 100644 UI/Input/InputElementWrapper.ts diff --git a/UI/CustomGenerator/GeneralSettings.ts b/UI/CustomGenerator/GeneralSettings.ts index fc11fdf..b37fb31 100644 --- a/UI/CustomGenerator/GeneralSettings.ts +++ b/UI/CustomGenerator/GeneralSettings.ts @@ -20,7 +20,10 @@ export default class GeneralSettingsPanel extends UIElement { const languagesField = ValidatedTextField.Mapped( - str => str?.split(";")?.map(str => str.trim().toLowerCase()), + str => { + console.log("Language from str", str); + return str?.split(";")?.map(str => str.trim().toLowerCase()); + }, languages => languages.join(";")); this.languages = languagesField.GetValue(); diff --git a/UI/CustomGenerator/SavePanel.ts b/UI/CustomGenerator/SavePanel.ts index 5893514..eacb383 100644 --- a/UI/CustomGenerator/SavePanel.ts +++ b/UI/CustomGenerator/SavePanel.ts @@ -7,7 +7,6 @@ import {OsmConnection} from "../../Logic/Osm/OsmConnection"; import {FixedUiElement} from "../Base/FixedUiElement"; import {TextField} from "../Input/TextField"; import {SubtleButton} from "../Base/SubtleButton"; -import {LayerConfigJson} from "../../Customizations/JSON/LayerConfigJson"; export default class SavePanel extends UIElement { private json: UIElement; @@ -35,10 +34,7 @@ export default class SavePanel extends UIElement { const jsonTextField = new TextField({ placeholder: "JSON Config", - fromString: str => str, - toString: str => str, value: jsonStr, - startValidated: false, textArea: true, textAreaRows: 20 }); diff --git a/UI/CustomGenerator/TagRenderingPanel.ts b/UI/CustomGenerator/TagRenderingPanel.ts index 23a6172..203de00 100644 --- a/UI/CustomGenerator/TagRenderingPanel.ts +++ b/UI/CustomGenerator/TagRenderingPanel.ts @@ -3,7 +3,7 @@ import {UIEventSource} from "../../Logic/UIEventSource"; import {InputElement} from "../Input/InputElement"; import SingleSetting from "./SingleSetting"; import SettingsTable from "./SettingsTable"; -import {TextField, ValidatedTextField} from "../Input/TextField"; +import {TextField} from "../Input/TextField"; import Combine from "../Base/Combine"; import MultiLingualTextFields from "../Input/MultiLingualTextFields"; import {AndOrTagInput} from "../Input/AndOrTagInput"; @@ -16,6 +16,7 @@ import {UserDetails} from "../../Logic/Osm/OsmConnection"; import {State} from "../../State"; import {VariableUiElement} from "../Base/VariableUIElement"; import {FromJSON} from "../../Customizations/JSON/FromJSON"; +import ValidatedTextField from "../Input/ValidatedTextField"; export default class TagRenderingPanel extends InputElement { @@ -62,11 +63,11 @@ export default class TagRenderingPanel extends InputElementFreeform key", - setting(TextField.KeyInput(true), ["freeform", "key"], "Freeform key
", + setting(ValidatedTextField.KeyInput(true), ["freeform", "key"], "Freeform key
", "If specified, the rendering will search if this key is present." + "If it is, the rendering above will be used to display the element.
" + "The rendering will go into question mode if
  • this key is not present
  • No single mapping matches
  • A question is given
  • "), @@ -80,7 +81,7 @@ export default class TagRenderingPanel extends InputElement)[] = [ setting( - options?.noLanguage ? TextField.StringInput() : + options?.noLanguage ? new TextField({placeholder:"Rendering"}) : new MultiLingualTextFields(languages), "render", "Value to show", " Renders this value. Note that {key}-parts are substituted by the corresponding values of the element. If neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value."), questionsNotUnlocked ? `You need at least ${State.userJourney.themeGeneratorFullUnlock} changesets to unlock the 'question'-field and to use your theme to edit OSM data` : "", diff --git a/UI/ImageUploadFlow.ts b/UI/ImageUploadFlow.ts index 0095c8e..1731627 100644 --- a/UI/ImageUploadFlow.ts +++ b/UI/ImageUploadFlow.ts @@ -6,6 +6,7 @@ import Combine from "./Base/Combine"; import {State} from "../State"; import {UIEventSource} from "../Logic/UIEventSource"; import {Imgur} from "../Logic/Web/Imgur"; +import {FixedUiElement} from "./Base/FixedUiElement"; export class ImageUploadFlow extends UIElement { private _licensePicker: UIElement; @@ -69,7 +70,7 @@ export class ImageUploadFlow extends UIElement { if (this._isUploading.data == 1) { currentState.push(t.uploadingPicture); } else if (this._isUploading.data > 0) { - currentState.push(t.uploadingMultiple.Subs({count: this._isUploading.data})); + currentState.push(t.uploadingMultiple.Subs({count: ""+this._isUploading.data})); } if (this._didFail.data) { @@ -80,14 +81,15 @@ export class ImageUploadFlow extends UIElement { currentState.push(t.uploadDone) } - let currentStateHtml = ""; + let currentStateHtml : UIElement = new FixedUiElement(""); if (currentState.length > 0) { - currentStateHtml = new Combine(currentState).Render(); + currentStateHtml = new Combine(currentState); if (!this._allDone.data) { - currentStateHtml = "" + - currentStateHtml + - ""; + currentStateHtml.SetClass("alert"); + }else{ + currentStateHtml.SetClass("thanks"); } + currentStateHtml.SetStyle("display:block ruby") } const extraInfo = new Combine([ diff --git a/UI/Input/InputElementMap.ts b/UI/Input/InputElementMap.ts index 7a0286b..96d6038 100644 --- a/UI/Input/InputElementMap.ts +++ b/UI/Input/InputElementMap.ts @@ -35,7 +35,7 @@ export default class InputElementMap extends InputElement { }), extraSources, x => { return fromX(x); }); - } + }w GetValue(): UIEventSource { return this._value; diff --git a/UI/Input/InputElementWrapper.ts b/UI/Input/InputElementWrapper.ts deleted file mode 100644 index b01d2fa..0000000 --- a/UI/Input/InputElementWrapper.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {InputElement} from "./InputElement"; -import {UIElement} from "../UIElement"; -import Translations from "../i18n/Translations"; -import {UIEventSource} from "../../Logic/UIEventSource"; - -export class InputElementWrapper extends InputElement{ - private pre: UIElement ; - private input: InputElement; - private post: UIElement ; - - IsSelected: UIEventSource - - - constructor( - pre: UIElement | string, - input: InputElement, - post: UIElement | string - - ) { - super(undefined); - // this.pre = typeof(pre) === 'string' ? new FixedUiElement(pre) : pre - this.pre = Translations.W(pre) - this.input = input; - // this.post =typeof(post) === 'string' ? new FixedUiElement(post) : post - this.post = Translations.W(post) - this.IsSelected = input.IsSelected; - } - - - GetValue(): UIEventSource { - return this.input.GetValue(); - } - - InnerRender(): string { - return this.pre.Render() + this.input.Render() + this.post.Render(); - } - - IsValid(t: T): boolean { - return this.input.IsValid(t); - } - -} \ No newline at end of file diff --git a/UI/Input/MultiLingualTextFields.ts b/UI/Input/MultiLingualTextFields.ts index 7d864a0..5e83ff5 100644 --- a/UI/Input/MultiLingualTextFields.ts +++ b/UI/Input/MultiLingualTextFields.ts @@ -3,19 +3,19 @@ import {UIEventSource} from "../../Logic/UIEventSource"; import {TextField} from "./TextField"; export default class MultiLingualTextFields extends InputElement { - private _fields: Map> = new Map>(); - private _value: UIEventSource; - IsSelected: UIEventSource = new UIEventSource(false); + private _fields: Map = new Map(); + private readonly _value: UIEventSource; + public readonly IsSelected: UIEventSource = new UIEventSource(false); - constructor(languages: UIEventSource, + constructor(languages: UIEventSource, textArea: boolean = false, value: UIEventSource>> = undefined) { super(undefined); this._value = value ?? new UIEventSource({}); - - this._value.addCallbackAndRun(latestData => { - if(typeof(latestData) === "string"){ - console.warn("Refusing string for multilingual input",latestData); + + this._value.addCallbackAndRun(latestData => { + if (typeof (latestData) === "string") { + console.warn("Refusing string for multilingual input", latestData); self._value.setData({}); } }) @@ -26,7 +26,7 @@ export default class MultiLingualTextFields extends InputElement { if (languages === undefined) { return; } - const newFields = new Map>(); + const newFields = new Map(); for (const language of languages) { if (language.length != 2) { continue; @@ -34,7 +34,7 @@ export default class MultiLingualTextFields extends InputElement { let oldField = self._fields.get(language); if (oldField === undefined) { - oldField = TextField.StringInput(textArea); + oldField = new TextField({textArea: textArea}); oldField.GetValue().addCallback(str => { self._value.data[language] = str; self._value.ping(); diff --git a/UI/Input/MultiTagInput.ts b/UI/Input/MultiTagInput.ts index cae2f1d..20bd3e2 100644 --- a/UI/Input/MultiTagInput.ts +++ b/UI/Input/MultiTagInput.ts @@ -1,10 +1,5 @@ -import {InputElement} from "./InputElement"; import {UIEventSource} from "../../Logic/UIEventSource"; -import {UIElement} from "../UIElement"; -import Combine from "../Base/Combine"; -import {SubtleButton} from "../Base/SubtleButton"; import TagInput from "./SingleTagInput"; -import {FixedUiElement} from "../Base/FixedUiElement"; import {MultiInput} from "./MultiInput"; export class MultiTagInput extends MultiInput { diff --git a/UI/Input/SingleTagInput.ts b/UI/Input/SingleTagInput.ts index 6e773e0..e3a6d5a 100644 --- a/UI/Input/SingleTagInput.ts +++ b/UI/Input/SingleTagInput.ts @@ -7,6 +7,7 @@ import {Utils} from "../../Utils"; import {UIElement} from "../UIElement"; import {VariableUiElement} from "../Base/VariableUIElement"; import {FromJSON} from "../../Customizations/JSON/FromJSON"; +import ValidatedTextField from "./ValidatedTextField"; export default class SingleTagInput extends InputElement { @@ -32,12 +33,10 @@ export default class SingleTagInput extends InputElement { } )); - this.key = TextField.KeyInput(); + this.key = ValidatedTextField.KeyInput(); - this.value = new TextField({ + this.value = new TextField({ placeholder: "value - if blank, matches if key is NOT present", - fromString: str => str, - toString: str => str, value: new UIEventSource("") } ); diff --git a/UI/Input/TextField.ts b/UI/Input/TextField.ts index 7eae970..d6f1a3e 100644 --- a/UI/Input/TextField.ts +++ b/UI/Input/TextField.ts @@ -51,6 +51,8 @@ export class TextField extends InputElement { // @ts-ignore field.value = t; }); + this.dumbMode = false; + this.SetClass("deadbeef") } GetValue(): UIEventSource { @@ -60,17 +62,24 @@ export class TextField extends InputElement { InnerRender(): string { if (this._isArea) { - return `` + return `` } const placeholder = this._placeholder.InnerRender().replace("'", "'"); - return `
    ` + - `` + - `
    `; + return `
    ` + + `` + + `
    `; + } + + Update() { + console.log("Updating TF") + super.Update(); } - InnerUpdate(field) { + InnerUpdate() { + console.log("Inner Updating TF") + const field = document.getElementById("txt-" + this.id); const self = this; field.oninput = () => { // @ts-ignore diff --git a/UI/Input/ValidatedTextField.ts b/UI/Input/ValidatedTextField.ts index b222363..e007465 100644 --- a/UI/Input/ValidatedTextField.ts +++ b/UI/Input/ValidatedTextField.ts @@ -186,7 +186,6 @@ export default class ValidatedTextField { isValid?: ((string: string) => boolean) }): InputElement { const textField = new TextField(options); - return new InputElementMap( textField, (a, b) => a === b, fromString, toString diff --git a/UI/ShareScreen.ts b/UI/ShareScreen.ts index c7f5176..590cc9e 100644 --- a/UI/ShareScreen.ts +++ b/UI/ShareScreen.ts @@ -157,7 +157,7 @@ export class ShareScreen extends UIElement { }, optionParts); - this.iframe = url.map(url => `<iframe src="${url}" width="100%" height="100%" title="${layout.title.InnerRender()} with MapComplete"></iframe>`); + this.iframe = url.map(url => `<iframe src="${url}" width="100%" height="100%" title="${layout.title?.InnerRender()??""} with MapComplete"></iframe>`); this._iframeCode = new VariableUiElement( url.map((url) => { diff --git a/UI/i18n/Translations.ts b/UI/i18n/Translations.ts index 0e0a35c..2958e05 100644 --- a/UI/i18n/Translations.ts +++ b/UI/i18n/Translations.ts @@ -34,13 +34,13 @@ export default class Translations { }), uploadingMultiple: new T({ - en: 'Uploading {count} of your picture...', - nl: 'Bezig met {count} foto\'s te uploaden...', - ca: 'Pujant {count} de la teva imatge...', - es: 'Subiendo {count} de tus fotos...', - fr: 'Mettre votre {count} photos en ligne', - gl: 'Subindo {count} das tĂșas imaxes...', - de: '{count} Ihrer Bilder hochgeladen...' + en: "Uploading {count} of your picture...", + nl: "Bezig met {count} foto's te uploaden...", + ca: "Pujant {count} de la teva imatge...", + es: "Subiendo {count} de tus fotos...", + fr: "Mettre votre {count} photos en ligne", + gl: "Subindo {count} das tĂșas imaxes...", + de: "{count} Ihrer Bilder hochgeladen..." }), pleaseLogin: new T({