diff --git a/assets/layers/usersettings/usersettings.json b/assets/layers/usersettings/usersettings.json index fd54a5fda..141189360 100644 --- a/assets/layers/usersettings/usersettings.json +++ b/assets/layers/usersettings/usersettings.json @@ -738,6 +738,14 @@ } ] }, + { + "id": "disabled-questions", + "render": { + "special": { + "type": "disabled_questions" + } + } + }, { "id": "title-privacy-legal", "render": { diff --git a/src/Logic/State/UserRelatedState.ts b/src/Logic/State/UserRelatedState.ts index e7ac6c931..7228ae61e 100644 --- a/src/Logic/State/UserRelatedState.ts +++ b/src/Logic/State/UserRelatedState.ts @@ -545,4 +545,14 @@ export default class UserRelatedState { return amendedPrefs } + + + /** + * The disabled questions for this theme and layer + */ + public getThemeDisabled(themeId: string, layerId: string): UIEventSource { + const flatSource = this.osmConnection.getPreference("disabled-questions-" + themeId + "-" + layerId, "[]") + return UIEventSource.asObject(flatSource, []) + } + } diff --git a/src/UI/Base/DotMenu.svelte b/src/UI/Base/DotMenu.svelte index 05d41c7ff..a600f2db3 100644 --- a/src/UI/Base/DotMenu.svelte +++ b/src/UI/Base/DotMenu.svelte @@ -9,17 +9,17 @@ export let open = new UIEventSource(false) export let dotsSize = `w-6 h-6` export let dotsPosition = `top-0 right-0` - export let hideBackground= false + export let hideBackground: boolean = false let menuPosition = `` - if(dotsPosition.indexOf("left-0") >= 0){ + if (dotsPosition.indexOf("left-0") >= 0) { menuPosition = "left-0" - }else{ + } else { menuPosition = `right-0` } - if(dotsPosition.indexOf("top-0") > 0){ + if (dotsPosition.indexOf("top-0") > 0) { menuPosition += " bottom-0" - }else{ + } else { menuPosition += ` top-0` } @@ -49,7 +49,7 @@ } :global(.dots-menu > path) { - fill: var(--interactive-background); + fill: var(--button-background-hover); transition: fill 350ms linear; cursor: pointer; @@ -74,7 +74,7 @@ } .transition-background { - transition: background-color 150ms linear; + transition: background-color 150ms linear; } .transition-background.collapsed { diff --git a/src/UI/Popup/DisabledQuestions.svelte b/src/UI/Popup/DisabledQuestions.svelte new file mode 100644 index 000000000..4e9a5f006 --- /dev/null +++ b/src/UI/Popup/DisabledQuestions.svelte @@ -0,0 +1,23 @@ + + +

Disabled questions

+{#if $allDisabled.length === 0} + To disable a question, click the three dots in the upper-right corner +{:else} + To enable a question again, click it + {#each layers as layer (layer.id)} + + {/each} +{/if} diff --git a/src/UI/Popup/DisabledQuestionsLayer.svelte b/src/UI/Popup/DisabledQuestionsLayer.svelte new file mode 100644 index 000000000..82912b4dc --- /dev/null +++ b/src/UI/Popup/DisabledQuestionsLayer.svelte @@ -0,0 +1,45 @@ + + +{#if $disabledQuestions.length > 0} +
+ +

+
+ layer.defaultIcon()} /> +
+ +

+
+ {#each $disabledQuestions as id} + + {/each} +
+
+{/if} diff --git a/src/UI/Popup/TagRendering/Questionbox.svelte b/src/UI/Popup/TagRendering/Questionbox.svelte index 20a02d158..002e13c88 100644 --- a/src/UI/Popup/TagRendering/Questionbox.svelte +++ b/src/UI/Popup/TagRendering/Questionbox.svelte @@ -43,11 +43,20 @@ } return true } + const baseQuestions = (layer?.tagRenderings ?? [])?.filter( - (tr) => allowed(tr.labels) && tr.question !== undefined + (tr) => allowed(tr.labels) && tr.question !== undefined, ) + + /** + * Ids of skipped questions + */ let skippedQuestions = new UIEventSource>(new Set()) + let layerDisabledForTheme = state.userRelatedState.getThemeDisabled(state.layout.id, layer.id) + layerDisabledForTheme.addCallbackAndRunD(disabled => { + skippedQuestions.set(new Set(disabled.concat(Array.from(skippedQuestions.data)))) + }) let questionboxElem: HTMLDivElement let questionsToAsk = tags.map( (tags) => { @@ -69,10 +78,10 @@ } return questionsToAsk }, - [skippedQuestions] + [skippedQuestions], ) let firstQuestion: UIEventSource = new UIEventSource( - undefined + undefined, ) let allQuestionsToAsk: UIEventSource = new UIEventSource< TagRenderingConfig[] @@ -95,6 +104,8 @@ let skipped: number = 0 let loginEnabled = state.featureSwitches.featureSwitchEnableLogin + let debug = state.featureSwitches.featureSwitchIsDebugging + function skip(question: { id: string }, didAnswer: boolean = false) { skippedQuestions.data.add(question.id) // Must use ID, the config object might be a copy of the original @@ -117,43 +128,84 @@ class="marker-questionbox-root" class:hidden={$questionsToAsk.length === 0 && skipped === 0 && answered === 0} > + {#if $showAllQuestionsAtOnce} +
+ {#each $allQuestionsToAsk as question (question.id)} + + {/each} +
+ {:else if $firstQuestion !== undefined} + { + skip($firstQuestion, true) + }} + > + + + {/if} + {#if $allQuestionsToAsk.length === 0} +
+ +
+ {/if} + +
+ {#if skipped + answered > 0} -
- -
- {#if answered === 0} - {#if skipped === 1} - - {:else} - - {/if} - {:else if answered === 1} - {#if skipped === 0} - +
+ {#if answered === 0} + {#if skipped === 1} + + {:else} + + {/if} + {:else if answered === 1} + {#if skipped === 0} + + {:else if skipped === 1} + + {:else} + + {/if} + {:else if skipped === 0} + {:else if skipped === 1} - - {:else} - {/if} - {:else if skipped === 0} - - {:else if skipped === 1} - - {:else} - - {/if} + /> + {/if} +
- {#if skipped > 0} + {#if skipped + $skippedQuestions.size > 0} + {/if} {/if} - {:else} -
- {#if $showAllQuestionsAtOnce} -
- {#each $allQuestionsToAsk as question (question.id)} - - {/each} -
- {:else if $firstQuestion !== undefined} - { - skip($firstQuestion, true) + + {#if $skippedQuestions.size - skipped > 0} + - - {/if} -
- {/if} + > + Show the disabled questions for this object + + + {/if} + {#if $debug} + Skipped questions are {Array.from($skippedQuestions).join(", ")} + {/if} +
{/if} diff --git a/src/UI/Popup/TagRendering/TagRenderingQuestion.svelte b/src/UI/Popup/TagRendering/TagRenderingQuestion.svelte index 4d87e56cb..092f49e74 100644 --- a/src/UI/Popup/TagRendering/TagRenderingQuestion.svelte +++ b/src/UI/Popup/TagRendering/TagRenderingQuestion.svelte @@ -36,6 +36,8 @@ import { Modal } from "flowbite-svelte" import Popup from "../../Base/Popup.svelte" import If from "../../Base/If.svelte" + import DotMenu from "../../Base/DotMenu.svelte" + import SidebarUnit from "../../Base/SidebarUnit.svelte" export let config: TagRenderingConfig export let tags: UIEventSource> @@ -338,10 +340,41 @@ .then((changes) => state.changes.applyChanges(changes)) .catch(console.error) } + + let disabledInTheme = state.userRelatedState.getThemeDisabled(state.layout.id, layer?.id) + let menuIsOpened = new UIEventSource(false) + + function disableQuestion() { + const newList = Utils.Dedup([config.id, ...disabledInTheme.data]) + disabledInTheme.set(newList) + menuIsOpened.set(false) + } + + function enableQuestion() { + const newList = disabledInTheme.data?.filter(id => id !== config.id) + disabledInTheme.set(newList) + menuIsOpened.set(false) + } {#if question !== undefined}
+ + {#if layer.isNormal()} + + + {#if $disabledInTheme.indexOf(config.id) >= 0} + + {:else} + + {/if} + + + {/if}
v === "yes" || v === "full" || v === "always")}>
- + {#each $settableKeys as key} diff --git a/src/UI/SpecialVisualizations.ts b/src/UI/SpecialVisualizations.ts index ee038b399..b075ea49b 100644 --- a/src/UI/SpecialVisualizations.ts +++ b/src/UI/SpecialVisualizations.ts @@ -97,6 +97,7 @@ import ClearCaches from "./Popup/ClearCaches.svelte" import GroupedView from "./Popup/GroupedView.svelte" import { QuestionableTagRenderingConfigJson } from "../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson" import NoteCommentElement from "./Popup/Notes/NoteCommentElement.svelte" +import DisabledQuestions from "./Popup/DisabledQuestions.svelte" class NearbyImageVis implements SpecialVisualization { // Class must be in SpecialVisualisations due to weird cyclical import that breaks the tests @@ -2113,6 +2114,16 @@ export default class SpecialVisualizations { }) }, }, + { + funcName: "disabled_questions", + docs: "Shows which questions are disabled for every layer. Used in 'settings'", + needsUrls: [], + args: [], + constr(state) { + return new SvelteUIElement(DisabledQuestions, { state }) + }, + + }, ] specialVisualizations.push(new AutoApplyButton(specialVisualizations))