From 60f3499eb08485f676a9befe871b708ae7dc1b3d Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Wed, 8 Mar 2023 01:36:27 +0100 Subject: [PATCH] feature(usersettings): Add option to show all questions at once --- Logic/Osm/OsmConnection.ts | 7 +++++-- Logic/Osm/OsmPreferences.ts | 19 +++++++++++------ Logic/State/UserRelatedState.ts | 11 +++++++--- Logic/UIEventSource.ts | 8 +++++++ Logic/Web/QueryParameters.ts | 6 ++---- Models/Constants.ts | 2 +- UI/BigComponents/UserInformation.ts | 2 +- UI/Popup/FeatureInfoBox.ts | 19 ++++++++++------- UI/Popup/QuestionBox.ts | 2 +- assets/layers/usersettings/usersettings.json | 22 +++++++++++++++++++- 10 files changed, 72 insertions(+), 26 deletions(-) diff --git a/Logic/Osm/OsmConnection.ts b/Logic/Osm/OsmConnection.ts index dece748dd..f4b5c323c 100644 --- a/Logic/Osm/OsmConnection.ts +++ b/Logic/Osm/OsmConnection.ts @@ -161,9 +161,12 @@ export class OsmConnection { public GetPreference( key: string, defaultValue: string = undefined, - prefix: string = "mapcomplete-" + options?: { + documentation?: string + prefix?: string + } ): UIEventSource { - return this.preferencesHandler.GetPreference(key, defaultValue, prefix) + return this.preferencesHandler.GetPreference(key, defaultValue, options) } public GetLongPreference(key: string, prefix: string = "mapcomplete-"): UIEventSource { diff --git a/Logic/Osm/OsmPreferences.ts b/Logic/Osm/OsmPreferences.ts index 794bba784..8a37690ab 100644 --- a/Logic/Osm/OsmPreferences.ts +++ b/Logic/Osm/OsmPreferences.ts @@ -33,8 +33,9 @@ export class OsmPreferences { this.longPreferences[prefix + key] = source const allStartWith = prefix + key + "-combined" + const subOptions = { prefix: "" } // Gives the number of combined preferences - const length = this.GetPreference(allStartWith + "-length", "", "") + const length = this.GetPreference(allStartWith + "-length", "", subOptions) if ((allStartWith + "-length").length > 255) { throw ( @@ -56,9 +57,9 @@ export class OsmPreferences { let count = parseInt(length.data) for (let i = 0; i < count; i++) { // Delete all the preferences - self.GetPreference(allStartWith + "-" + i, "", "").setData("") + self.GetPreference(allStartWith + "-" + i, "", subOptions).setData("") } - self.GetPreference(allStartWith + "-length", "", "").setData("") + self.GetPreference(allStartWith + "-length", "", subOptions).setData("") return } @@ -70,7 +71,9 @@ export class OsmPreferences { if (i > 100) { throw "This long preference is getting very long... " } - self.GetPreference(allStartWith + "-" + i, "", "").setData(str.substr(0, 255)) + self.GetPreference(allStartWith + "-" + i, "", subOptions).setData( + str.substr(0, 255) + ) str = str.substr(255) i++ } @@ -116,8 +119,12 @@ export class OsmPreferences { public GetPreference( key: string, defaultValue: string = undefined, - prefix: string = "mapcomplete-" + options?: { + documentation?: string + prefix?: string + } ): UIEventSource { + const prefix: string = options?.prefix ?? "mapcomplete-" if (key.startsWith(prefix) && prefix !== "") { console.trace( "A preference was requested which has a duplicate prefix in its key. This is probably a bug" @@ -173,7 +180,7 @@ export class OsmPreferences { const matches = prefixes.some((prefix) => key.startsWith(prefix)) if (matches) { console.log("Clearing ", key) - self.GetPreference(key, "", "").setData("") + self.GetPreference(key, "", { prefix: "" }).setData("") } } isRunning = false diff --git a/Logic/State/UserRelatedState.ts b/Logic/State/UserRelatedState.ts index ba5f4cab6..cbd0d889a 100644 --- a/Logic/State/UserRelatedState.ts +++ b/Logic/State/UserRelatedState.ts @@ -34,10 +34,10 @@ export default class UserRelatedState extends ElementsState { */ public maprouletteConnection: Maproulette - public readonly isTranslator: Store - public readonly installedUserThemes: Store + public readonly showAllQuestionsAtOnce: UIEventSource + constructor(layoutToUse: LayoutConfig, options?: { attemptLogin: true | boolean }) { super(layoutToUse) @@ -73,7 +73,12 @@ export default class UserRelatedState extends ElementsState { } this.changes = new Changes(this, layoutToUse?.isLeftRightSensitive() ?? false) - + this.showAllQuestionsAtOnce = UIEventSource.asBoolean( + this.osmConnection.GetPreference("show-all-questions", "false", { + documentation: + "Either 'true' or 'false'. If set, all questions will be shown all at once", + }) + ) new ChangeToElementsActor(this.changes, this.allElements) new PendingChangesUploader(this.changes, this.selectedElement) diff --git a/Logic/UIEventSource.ts b/Logic/UIEventSource.ts index f9d49b9a0..ac286171c 100644 --- a/Logic/UIEventSource.ts +++ b/Logic/UIEventSource.ts @@ -754,4 +754,12 @@ export class UIEventSource extends Store { } return this } + + static asBoolean(stringUIEventSource: UIEventSource) { + return stringUIEventSource.sync( + (str) => str === "true", + [], + (b) => "" + b + ) + } } diff --git a/Logic/Web/QueryParameters.ts b/Logic/Web/QueryParameters.ts index ac885184c..29726ae97 100644 --- a/Logic/Web/QueryParameters.ts +++ b/Logic/Web/QueryParameters.ts @@ -40,10 +40,8 @@ export class QueryParameters { deflt: boolean, documentation?: string ): UIEventSource { - return QueryParameters.GetQueryParameter(key, "" + deflt, documentation).sync( - (str) => str === "true", - [], - (b) => "" + b + return UIEventSource.asBoolean( + QueryParameters.GetQueryParameter(key, "" + deflt, documentation) ) } diff --git a/Models/Constants.ts b/Models/Constants.ts index 4043b75d2..cb4e1e64d 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -1,7 +1,7 @@ import { Utils } from "../Utils" export default class Constants { - public static vNumber = "0.26.2" + public static vNumber = "0.26.3" public static ImgurApiKey = "7070e7167f0a25a" public static readonly mapillary_client_token_v4 = diff --git a/UI/BigComponents/UserInformation.ts b/UI/BigComponents/UserInformation.ts index 7acc9110a..2b5ce8ed2 100644 --- a/UI/BigComponents/UserInformation.ts +++ b/UI/BigComponents/UserInformation.ts @@ -74,7 +74,7 @@ class SingleUserSettingsPanel extends EditableTagRendering { if (kv.k.startsWith("_")) { continue } - osmConnection.GetPreference(kv.k, "", "").setData(kv.v) + osmConnection.GetPreference(kv.k, "", {prefix: ""}).setData(kv.v) } editMode.setData(false) diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts index 45be26ad1..2f2c8a3de 100644 --- a/UI/Popup/FeatureInfoBox.ts +++ b/UI/Popup/FeatureInfoBox.ts @@ -1,4 +1,4 @@ -import { UIEventSource } from "../../Logic/UIEventSource" +import { Store, UIEventSource } from "../../Logic/UIEventSource" import EditableTagRendering from "./EditableTagRendering" import QuestionBox from "./QuestionBox" import Combine from "../Base/Combine" @@ -35,9 +35,13 @@ export default class FeatureInfoBox extends ScrollableFullScreen { if (state === undefined) { throw "State is undefined!" } + const showAllQuestions = state.featureSwitchShowAllQuestions.map( + (fsShow) => fsShow || state.showAllQuestionsAtOnce.data, + [state.showAllQuestionsAtOnce] + ) super( () => FeatureInfoBox.GenerateTitleBar(tags, layerConfig, state), - () => FeatureInfoBox.GenerateContent(tags, layerConfig, state), + () => FeatureInfoBox.GenerateContent(tags, layerConfig, state, showAllQuestions), options?.hashToShow ?? tags.data.id ?? "item", options?.isShown, options @@ -79,21 +83,23 @@ export default class FeatureInfoBox extends ScrollableFullScreen { public static GenerateContent( tags: UIEventSource, layerConfig: LayerConfig, - state: FeaturePipelineState + state: FeaturePipelineState, + showAllQuestions?: Store ): BaseUIElement { return new Toggle( new Combine([ Svg.delete_icon_svg().SetClass("w-8 h-8"), Translations.t.delete.isDeleted, ]).SetClass("flex justify-center font-bold items-center"), - FeatureInfoBox.GenerateMainContent(tags, layerConfig, state), + FeatureInfoBox.GenerateMainContent(tags, layerConfig, state, showAllQuestions), tags.map((t) => t["_deleted"] == "yes") ) } private static GenerateMainContent( tags: UIEventSource, layerConfig: LayerConfig, - state: FeaturePipelineState + state: FeaturePipelineState, + showAllQuestions?: Store ): BaseUIElement { let questionBoxes: Map = new Map() const t = Translations.t.general @@ -108,8 +114,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen { tagRenderings: questions, units: layerConfig.units, showAllQuestionsAtOnce: - questionSpec?.freeform?.helperArgs["showAllQuestions"] ?? - state.featureSwitchShowAllQuestions, + questionSpec?.freeform?.helperArgs["showAllQuestions"] ?? showAllQuestions, }) questionBoxes.set(groupName, questionBox) } diff --git a/UI/Popup/QuestionBox.ts b/UI/Popup/QuestionBox.ts index 669f9a432..245f84930 100644 --- a/UI/Popup/QuestionBox.ts +++ b/UI/Popup/QuestionBox.ts @@ -22,7 +22,7 @@ export default class QuestionBox extends VariableUiElement { tagsSource: UIEventSource tagRenderings: TagRenderingConfig[] units: Unit[] - showAllQuestionsAtOnce?: boolean | UIEventSource + showAllQuestionsAtOnce?: boolean | Store } ) { const skippedQuestions: UIEventSource = new UIEventSource([]) diff --git a/assets/layers/usersettings/usersettings.json b/assets/layers/usersettings/usersettings.json index 79dc51446..89e02ba2c 100644 --- a/assets/layers/usersettings/usersettings.json +++ b/assets/layers/usersettings/usersettings.json @@ -67,6 +67,26 @@ } ] }, + { + "id": "all-questions-at-once", + "question": { + "en": "Should questions for unknown data fields appear one-by-one or together?" + }, + "mappings": [ + { + "if": "mapcomplete-show-all-questions=true", + "then": { + "en": "Show all questions in the infobox together" + } + }, + { + "if": "mapcomplete-show-all-questions=false", + "then": { + "en": "Show questions one-by-one" + } + } + ] + }, { "id": "translations-title", "group": "translations", @@ -297,4 +317,4 @@ } ], "mapRendering": null -} \ No newline at end of file +}