+
diff --git a/src/UI/Studio/EditLayerState.ts b/src/UI/Studio/EditLayerState.ts
index 705e1e0f0..5183ea724 100644
--- a/src/UI/Studio/EditLayerState.ts
+++ b/src/UI/Studio/EditLayerState.ts
@@ -21,6 +21,7 @@ import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import { LayoutConfigJson } from "../../Models/ThemeConfig/Json/LayoutConfigJson"
import { PrepareTheme } from "../../Models/ThemeConfig/Conversion/PrepareTheme"
import { ConversionContext } from "../../Models/ThemeConfig/Conversion/ConversionContext"
+import { LocalStorageSource } from "../../Logic/Web/LocalStorageSource"
export interface HighlightedTagRendering {
path: ReadonlyArray
@@ -31,6 +32,9 @@ export abstract class EditJsonState {
public readonly schema: ConfigMeta[]
public readonly category: "layers" | "themes"
public readonly server: StudioServer
+ public readonly showIntro: UIEventSource<"no" | "intro" | "tagrenderings"> = (
+ LocalStorageSource.Get("studio-show-intro", "intro")
+ )
public readonly expertMode: UIEventSource
diff --git a/src/UI/Studio/TagRenderingInput.svelte b/src/UI/Studio/TagRenderingInput.svelte
index d74e69ca5..9fc1caf41 100644
--- a/src/UI/Studio/TagRenderingInput.svelte
+++ b/src/UI/Studio/TagRenderingInput.svelte
@@ -17,7 +17,10 @@ import { TrashIcon } from "@rgossiaux/svelte-heroicons/outline";
import questionableTagRenderingSchemaRaw from "../../assets/schemas/questionabletagrenderingconfigmeta.json";
import SchemaBasedField from "./SchemaBasedField.svelte";
import Region from "./Region.svelte";
-import exp from "constants";
+import NextButton from "../Base/NextButton.svelte";
+import { QuestionMarkCircleIcon } from "@rgossiaux/svelte-heroicons/solid";
+import { LocalStorageSource } from "../../Logic/Web/LocalStorageSource";
+import { onMount } from "svelte";
export let state: EditLayerState;
export let schema: ConfigMeta;
@@ -25,7 +28,13 @@ export let path: (string | number)[];
let expertMode = state.expertMode;
const store = state.getStoreFor(path);
let value = store.data;
-
+let hasSeenIntro = UIEventSource.asBoolean(LocalStorageSource.Get("studio-seen-tagrendering-tutorial", "false"))
+onMount(() => {
+if(!hasSeenIntro.data){
+ state.showIntro.setData("tagrenderings")
+ hasSeenIntro.setData(true)
+}
+})
/**
* Allows the theme builder to create 'writable' themes.
* Should only be enabled for 'tagrenderings' in the theme, if the source is OSM
@@ -99,7 +108,7 @@ const ignored = new Set(["labels", "description", "classes"]);
const freeformSchemaAll = questionableTagRenderingSchemaRaw
.filter(schema => schema.path.length == 2 && schema.path[0] === "freeform" && ($allowQuestions || schema.path[1] === "key"));
-let freeformSchema = $expertMode ? freeformSchemaAll : freeformSchemaAll.filter(schema => schema.hints?.group !== "expert")
+let freeformSchema = $expertMode ? freeformSchemaAll : freeformSchemaAll.filter(schema => schema.hints?.group !== "expert");
const missing: string[] = questionableTagRenderingSchemaRaw.filter(schema => schema.path.length >= 1 && !items.has(schema.path[0]) && !ignored.has(schema.path[0])).map(schema => schema.path.join("."));
console.log({ state });
@@ -112,7 +121,7 @@ console.log({ state });
{:else}
-
+
@@ -157,5 +166,8 @@ console.log({ state });
{#each missing as field}
{/each}
+
+
state.showIntro.setData("tagrenderings")}> Show the introduction again
+
{/if}
diff --git a/src/UI/StudioGUI.svelte b/src/UI/StudioGUI.svelte
index 62f8a2051..4a19d812c 100644
--- a/src/UI/StudioGUI.svelte
+++ b/src/UI/StudioGUI.svelte
@@ -21,12 +21,13 @@
import FloatOver from "./Base/FloatOver.svelte";
import Walkthrough from "./Walkthrough/Walkthrough.svelte";
import * as intro from "../assets/studio_introduction.json";
+ import * as intro_tagrenderings from "../assets/studio_tagrenderings_intro.json";
+
import { QuestionMarkCircleIcon } from "@babeard/svelte-heroicons/mini";
import type { ConfigMeta } from "./Studio/configMeta";
import EditTheme from "./Studio/EditTheme.svelte";
import * as meta from "../../package.json";
import Checkbox from "./Base/Checkbox.svelte";
- import exp from "constants";
export let studioUrl = window.location.hostname === "127.0.0.2" ? "http://127.0.0.1:1235" : "https://studio.mapcomplete.org";
@@ -61,13 +62,13 @@
const layerSchema: ConfigMeta[] =
layerSchemaRaw;
let editLayerState = new EditLayerState(layerSchema, studio, osmConnection, { expertMode });
+ let showIntro = editLayerState.showIntro
const layoutSchema: ConfigMeta[] = layoutSchemaRaw;
let editThemeState = new EditThemeState(layoutSchema, studio, { expertMode });
let layerId = editLayerState.configuration.map(layerConfig => layerConfig.id);
- let showIntro = UIEventSource.asBoolean(LocalStorageSource.Get("studio-show-intro", "true"));
const version = meta.version;
async function editLayer(event: Event) {
@@ -162,7 +163,7 @@
{editThemeState.configuration.setData({}); state = "editing_theme"}}>
Create a new theme
- {showIntro.setData(true)} }>
+ {showIntro.setData("intro")} }>
Show the introduction again
@@ -222,10 +223,10 @@
-{#if $showIntro}
- {showIntro.setData(false)}}>
+{#if {intro, tagrenderings: intro_tagrenderings}[$showIntro]?.sections}
+ {showIntro.setData("no")}}>
- {showIntro.setData(false)}} />
+ {showIntro.setData("no")}} />
diff --git a/src/assets/studio_tagrenderings_intro.json b/src/assets/studio_tagrenderings_intro.json
new file mode 100644
index 000000000..843b57db5
--- /dev/null
+++ b/src/assets/studio_tagrenderings_intro.json
@@ -0,0 +1 @@
+{"sections":["# How to work with TagRenderings\n\nThe information box shows various attributes of the selected feature in a human friendly way.\n\nThis is done by a **tagRendering** which converts attributes into text.\n\nThis can be done by using **predefined options** (mappings) or with a **render**-string\n","# Predefined options\n\nA predefined option states that, `if` a certain tag is present, `then` a certain text should be shown.\n\nFor example, a playground may be lit or not.\nIn OpenStreetMap, this is encoded with the tag `lit=yes` or `lit=no`. We might want to show `This playground is lit at night` and `This playground is not lit at night` to users of MapComplete.\n\nThis is what this will look like in the interface:\n\n\n","# Substituting attributes\n\nIf none of the predefined options match, the string given in the `render`-field is used (under the question _\"What text should be rendered?\"_).\n\nA special property about all shown texts is that, **if the name of a key appears between braces, this will be replaced by the corresponding value**.\n\nFor example, if the object has tags `min_age=3` and the text to display is `Accessible to kids older than {min_age} years`, then this will be displayed to the user as **Accessible to kids older than 3 years**\n\nNote that this also works withing predifined options\n","# Special values\n\nSpecial components can be summoned by calling them. For example, the relevant wikipedia will be displayed by entering the text `{wikipedia()}`. A table with opening hours is displayed with `{opening_hours()}`. For a full reference, [see the documentation](../SpecialRenderings.md).\n","# Requesting data with predefined options\n\nThese renderings can be turned into a way to contribute data easily. If a **question** is provided, then these renderings will be asked if unknown or gain the pencil to make changes. \n\nA predefined option will show up as an option that can be picked.\n\n","# Requesting data with an input field\n\nIt is also possible to have a text field. For this, the **key** to write into must be given (_What is the name of the attribute that should be written to?_), in this case `max_age`.\n\n","# Combining predefined options and freeform text\n\nA text field and predefined options can be combined. The contributor can then choose between a predefined option or filling out something.\n\n","# Selecting multiple values\n\nOne can set a question to allow multiple answers. This works with predefined options or a freeform text field.\n\n\n\nNote that these will be rendered as a list:\n\n\n"]}
\ No newline at end of file