feature(usersettings): Add option to show all questions at once

This commit is contained in:
Pieter Vander Vennet 2023-03-08 01:36:27 +01:00
parent 7bd3fcd490
commit 60f3499eb0
10 changed files with 72 additions and 26 deletions

View file

@ -161,9 +161,12 @@ export class OsmConnection {
public GetPreference( public GetPreference(
key: string, key: string,
defaultValue: string = undefined, defaultValue: string = undefined,
prefix: string = "mapcomplete-" options?: {
documentation?: string
prefix?: string
}
): UIEventSource<string> { ): UIEventSource<string> {
return this.preferencesHandler.GetPreference(key, defaultValue, prefix) return this.preferencesHandler.GetPreference(key, defaultValue, options)
} }
public GetLongPreference(key: string, prefix: string = "mapcomplete-"): UIEventSource<string> { public GetLongPreference(key: string, prefix: string = "mapcomplete-"): UIEventSource<string> {

View file

@ -33,8 +33,9 @@ export class OsmPreferences {
this.longPreferences[prefix + key] = source this.longPreferences[prefix + key] = source
const allStartWith = prefix + key + "-combined" const allStartWith = prefix + key + "-combined"
const subOptions = { prefix: "" }
// Gives the number of combined preferences // Gives the number of combined preferences
const length = this.GetPreference(allStartWith + "-length", "", "") const length = this.GetPreference(allStartWith + "-length", "", subOptions)
if ((allStartWith + "-length").length > 255) { if ((allStartWith + "-length").length > 255) {
throw ( throw (
@ -56,9 +57,9 @@ export class OsmPreferences {
let count = parseInt(length.data) let count = parseInt(length.data)
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
// Delete all the preferences // 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 return
} }
@ -70,7 +71,9 @@ export class OsmPreferences {
if (i > 100) { if (i > 100) {
throw "This long preference is getting very long... " 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) str = str.substr(255)
i++ i++
} }
@ -116,8 +119,12 @@ export class OsmPreferences {
public GetPreference( public GetPreference(
key: string, key: string,
defaultValue: string = undefined, defaultValue: string = undefined,
prefix: string = "mapcomplete-" options?: {
documentation?: string
prefix?: string
}
): UIEventSource<string> { ): UIEventSource<string> {
const prefix: string = options?.prefix ?? "mapcomplete-"
if (key.startsWith(prefix) && prefix !== "") { if (key.startsWith(prefix) && prefix !== "") {
console.trace( console.trace(
"A preference was requested which has a duplicate prefix in its key. This is probably a bug" "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)) const matches = prefixes.some((prefix) => key.startsWith(prefix))
if (matches) { if (matches) {
console.log("Clearing ", key) console.log("Clearing ", key)
self.GetPreference(key, "", "").setData("") self.GetPreference(key, "", { prefix: "" }).setData("")
} }
} }
isRunning = false isRunning = false

View file

@ -34,10 +34,10 @@ export default class UserRelatedState extends ElementsState {
*/ */
public maprouletteConnection: Maproulette public maprouletteConnection: Maproulette
public readonly isTranslator: Store<boolean>
public readonly installedUserThemes: Store<string[]> public readonly installedUserThemes: Store<string[]>
public readonly showAllQuestionsAtOnce: UIEventSource<boolean>
constructor(layoutToUse: LayoutConfig, options?: { attemptLogin: true | boolean }) { constructor(layoutToUse: LayoutConfig, options?: { attemptLogin: true | boolean }) {
super(layoutToUse) super(layoutToUse)
@ -73,7 +73,12 @@ export default class UserRelatedState extends ElementsState {
} }
this.changes = new Changes(this, layoutToUse?.isLeftRightSensitive() ?? false) 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 ChangeToElementsActor(this.changes, this.allElements)
new PendingChangesUploader(this.changes, this.selectedElement) new PendingChangesUploader(this.changes, this.selectedElement)

View file

@ -754,4 +754,12 @@ export class UIEventSource<T> extends Store<T> {
} }
return this return this
} }
static asBoolean(stringUIEventSource: UIEventSource<string>) {
return stringUIEventSource.sync(
(str) => str === "true",
[],
(b) => "" + b
)
}
} }

View file

@ -40,10 +40,8 @@ export class QueryParameters {
deflt: boolean, deflt: boolean,
documentation?: string documentation?: string
): UIEventSource<boolean> { ): UIEventSource<boolean> {
return QueryParameters.GetQueryParameter(key, "" + deflt, documentation).sync( return UIEventSource.asBoolean(
(str) => str === "true", QueryParameters.GetQueryParameter(key, "" + deflt, documentation)
[],
(b) => "" + b
) )
} }

View file

@ -1,7 +1,7 @@
import { Utils } from "../Utils" import { Utils } from "../Utils"
export default class Constants { export default class Constants {
public static vNumber = "0.26.2" public static vNumber = "0.26.3"
public static ImgurApiKey = "7070e7167f0a25a" public static ImgurApiKey = "7070e7167f0a25a"
public static readonly mapillary_client_token_v4 = public static readonly mapillary_client_token_v4 =

View file

@ -74,7 +74,7 @@ class SingleUserSettingsPanel extends EditableTagRendering {
if (kv.k.startsWith("_")) { if (kv.k.startsWith("_")) {
continue continue
} }
osmConnection.GetPreference(kv.k, "", "").setData(kv.v) osmConnection.GetPreference(kv.k, "", {prefix: ""}).setData(kv.v)
} }
editMode.setData(false) editMode.setData(false)

View file

@ -1,4 +1,4 @@
import { UIEventSource } from "../../Logic/UIEventSource" import { Store, UIEventSource } from "../../Logic/UIEventSource"
import EditableTagRendering from "./EditableTagRendering" import EditableTagRendering from "./EditableTagRendering"
import QuestionBox from "./QuestionBox" import QuestionBox from "./QuestionBox"
import Combine from "../Base/Combine" import Combine from "../Base/Combine"
@ -35,9 +35,13 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
if (state === undefined) { if (state === undefined) {
throw "State is undefined!" throw "State is undefined!"
} }
const showAllQuestions = state.featureSwitchShowAllQuestions.map(
(fsShow) => fsShow || state.showAllQuestionsAtOnce.data,
[state.showAllQuestionsAtOnce]
)
super( super(
() => FeatureInfoBox.GenerateTitleBar(tags, layerConfig, state), () => FeatureInfoBox.GenerateTitleBar(tags, layerConfig, state),
() => FeatureInfoBox.GenerateContent(tags, layerConfig, state), () => FeatureInfoBox.GenerateContent(tags, layerConfig, state, showAllQuestions),
options?.hashToShow ?? tags.data.id ?? "item", options?.hashToShow ?? tags.data.id ?? "item",
options?.isShown, options?.isShown,
options options
@ -79,21 +83,23 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
public static GenerateContent( public static GenerateContent(
tags: UIEventSource<any>, tags: UIEventSource<any>,
layerConfig: LayerConfig, layerConfig: LayerConfig,
state: FeaturePipelineState state: FeaturePipelineState,
showAllQuestions?: Store<boolean>
): BaseUIElement { ): BaseUIElement {
return new Toggle( return new Toggle(
new Combine([ new Combine([
Svg.delete_icon_svg().SetClass("w-8 h-8"), Svg.delete_icon_svg().SetClass("w-8 h-8"),
Translations.t.delete.isDeleted, Translations.t.delete.isDeleted,
]).SetClass("flex justify-center font-bold items-center"), ]).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") tags.map((t) => t["_deleted"] == "yes")
) )
} }
private static GenerateMainContent( private static GenerateMainContent(
tags: UIEventSource<any>, tags: UIEventSource<any>,
layerConfig: LayerConfig, layerConfig: LayerConfig,
state: FeaturePipelineState state: FeaturePipelineState,
showAllQuestions?: Store<boolean>
): BaseUIElement { ): BaseUIElement {
let questionBoxes: Map<string, QuestionBox> = new Map<string, QuestionBox>() let questionBoxes: Map<string, QuestionBox> = new Map<string, QuestionBox>()
const t = Translations.t.general const t = Translations.t.general
@ -108,8 +114,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
tagRenderings: questions, tagRenderings: questions,
units: layerConfig.units, units: layerConfig.units,
showAllQuestionsAtOnce: showAllQuestionsAtOnce:
questionSpec?.freeform?.helperArgs["showAllQuestions"] ?? questionSpec?.freeform?.helperArgs["showAllQuestions"] ?? showAllQuestions,
state.featureSwitchShowAllQuestions,
}) })
questionBoxes.set(groupName, questionBox) questionBoxes.set(groupName, questionBox)
} }

View file

@ -22,7 +22,7 @@ export default class QuestionBox extends VariableUiElement {
tagsSource: UIEventSource<any> tagsSource: UIEventSource<any>
tagRenderings: TagRenderingConfig[] tagRenderings: TagRenderingConfig[]
units: Unit[] units: Unit[]
showAllQuestionsAtOnce?: boolean | UIEventSource<boolean> showAllQuestionsAtOnce?: boolean | Store<boolean>
} }
) { ) {
const skippedQuestions: UIEventSource<number[]> = new UIEventSource<number[]>([]) const skippedQuestions: UIEventSource<number[]> = new UIEventSource<number[]>([])

View file

@ -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", "id": "translations-title",
"group": "translations", "group": "translations",
@ -297,4 +317,4 @@
} }
], ],
"mapRendering": null "mapRendering": null
} }