forked from MapComplete/MapComplete
Merge master
This commit is contained in:
commit
08461f70d3
119 changed files with 2810 additions and 1164 deletions
File diff suppressed because it is too large
Load diff
|
@ -29,7 +29,15 @@ export default class Table extends BaseUIElement {
|
|||
const header = Utils.NoNull(headerMarkdownParts).join(" | ")
|
||||
const headerSep = headerMarkdownParts.map((part) => "-".repeat(part.length + 2)).join(" | ")
|
||||
const table = this._contents
|
||||
.map((row) => row.map((el) => el?.AsMarkdown()?.replaceAll("\\","\\\\")?.replaceAll("|", "\\|") ?? " ").join(" | "))
|
||||
.map((row) =>
|
||||
row
|
||||
.map(
|
||||
(el) =>
|
||||
el?.AsMarkdown()?.replaceAll("\\", "\\\\")?.replaceAll("|", "\\|") ??
|
||||
" "
|
||||
)
|
||||
.join(" | ")
|
||||
)
|
||||
.join("\n")
|
||||
|
||||
return "\n\n" + [header, headerSep, table, ""].join("\n")
|
||||
|
|
|
@ -35,7 +35,12 @@
|
|||
src={`https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/community_index/${resource.type}.svg`}
|
||||
/>
|
||||
<div class="flex flex-col">
|
||||
<a href={resource.resolved.url} target="_blank" rel="noreferrer nofollow noopener" class="font-bold">
|
||||
<a
|
||||
href={resource.resolved.url}
|
||||
target="_blank"
|
||||
rel="noreferrer nofollow noopener"
|
||||
class="font-bold"
|
||||
>
|
||||
{resource.resolved.name ?? resource.resolved.url}
|
||||
</a>
|
||||
{resource.resolved?.description}
|
||||
|
|
|
@ -102,7 +102,11 @@ export default class CopyrightPanel extends Combine {
|
|||
let bgAttr: BaseUIElement | string = undefined
|
||||
if (attrText && attrUrl) {
|
||||
bgAttr =
|
||||
"<a href='" + attrUrl + "' target='_blank' rel='noopener'>" + attrText + "</a>"
|
||||
"<a href='" +
|
||||
attrUrl +
|
||||
"' target='_blank' rel='noopener'>" +
|
||||
attrText +
|
||||
"</a>"
|
||||
} else if (attrUrl) {
|
||||
bgAttr = attrUrl
|
||||
} else {
|
||||
|
|
|
@ -72,10 +72,7 @@ export class ImageUploadFlow extends Toggle {
|
|||
labelContent,
|
||||
]).SetClass("w-full flex justify-center items-center")
|
||||
|
||||
const licenseStore = state?.osmConnection?.GetPreference(
|
||||
"pictures-license",
|
||||
"CC0"
|
||||
)
|
||||
const licenseStore = state?.osmConnection?.GetPreference("pictures-license", "CC0")
|
||||
|
||||
const fileSelector = new FileSelectorButton(label, {
|
||||
acceptType: "image/*",
|
||||
|
|
|
@ -1,28 +1,30 @@
|
|||
<script lang="ts">
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
import type { OsmTags } from "../../Models/OsmFeature"
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import type { P4CPicture } from "../../Logic/Web/NearbyImagesSearch"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import { AttributedImage } from "../Image/AttributedImage"
|
||||
import AllImageProviders from "../../Logic/ImageProviders/AllImageProviders"
|
||||
import LinkPicture from "../../Logic/Osm/Actions/LinkPicture"
|
||||
import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction"
|
||||
import { Tag } from "../../Logic/Tags/Tag"
|
||||
import { GeoOperations } from "../../Logic/GeoOperations"
|
||||
import type { Feature } from "geojson"
|
||||
import Translations from "../i18n/Translations"
|
||||
import SpecialTranslation from "./TagRendering/SpecialTranslation.svelte"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
|
||||
import { Store } from "../../Logic/UIEventSource";
|
||||
import type { OsmTags } from "../../Models/OsmFeature";
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization";
|
||||
import type { P4CPicture } from "../../Logic/Web/NearbyImagesSearch";
|
||||
import ToSvelte from "../Base/ToSvelte.svelte";
|
||||
import { AttributedImage } from "../Image/AttributedImage";
|
||||
import AllImageProviders from "../../Logic/ImageProviders/AllImageProviders";
|
||||
import LinkPicture from "../../Logic/Osm/Actions/LinkPicture";
|
||||
import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction";
|
||||
import { Tag } from "../../Logic/Tags/Tag";
|
||||
import { GeoOperations } from "../../Logic/GeoOperations";
|
||||
import type { Feature } from "geojson";
|
||||
import Translations from "../i18n/Translations";
|
||||
import SpecialTranslation from "./TagRendering/SpecialTranslation.svelte";
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
||||
export let tags: Store<OsmTags>
|
||||
export let lon: number
|
||||
export let lat: number
|
||||
export let state: SpecialVisualizationState
|
||||
export let image: P4CPicture
|
||||
export let feature: Feature
|
||||
export let layer: LayerConfig
|
||||
|
||||
export let tags: Store<OsmTags>;
|
||||
export let lon: number;
|
||||
export let lat: number;
|
||||
export let state: SpecialVisualizationState;
|
||||
export let image: P4CPicture;
|
||||
export let feature: Feature;
|
||||
export let layer: LayerConfig;
|
||||
export let linkable = true
|
||||
let isLinked = false
|
||||
|
||||
export let linkable = true;
|
||||
let isLinked = Object.values(tags.data).some(v => image.pictureUrl === v);
|
||||
|
@ -37,37 +39,35 @@
|
|||
let distance = Math.round(GeoOperations.distanceBetween([image.coordinates.lng, image.coordinates.lat], c));
|
||||
|
||||
$: {
|
||||
const currentTags = tags.data;
|
||||
const key = Object.keys(image.osmTags)[0];
|
||||
const url = image.osmTags[key];
|
||||
const currentTags = tags.data
|
||||
const key = Object.keys(image.osmTags)[0]
|
||||
const url = image.osmTags[key]
|
||||
if (isLinked) {
|
||||
const action = new LinkPicture(
|
||||
currentTags.id,
|
||||
key,
|
||||
url,
|
||||
currentTags,
|
||||
{
|
||||
theme: state.layout.id,
|
||||
changeType: "link-image"
|
||||
}
|
||||
);
|
||||
state.changes.applyAction(action);
|
||||
const action = new LinkPicture(currentTags.id, key, url, currentTags, {
|
||||
theme: state.layout.id,
|
||||
changeType: "link-image",
|
||||
})
|
||||
state.changes.applyAction(action)
|
||||
} else {
|
||||
for (const k in currentTags) {
|
||||
const v = currentTags[k];
|
||||
const v = currentTags[k]
|
||||
if (v === url) {
|
||||
const action = new ChangeTagAction(currentTags.id, new Tag(k, ""), currentTags, { theme: state.layout.id, changeType: "remove-image" });
|
||||
state.changes.applyAction(action);
|
||||
const action = new ChangeTagAction(currentTags.id, new Tag(k, ""), currentTags, {
|
||||
theme: state.layout.id,
|
||||
changeType: "remove-image",
|
||||
})
|
||||
state.changes.applyAction(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<div class="flex flex-col w-fit shrink-0">
|
||||
|
||||
<div class="flex w-fit shrink-0 flex-col">
|
||||
<ToSvelte construct={attributedImage.SetClass("h-48 w-fit")} />
|
||||
{#if linkable}
|
||||
<label>
|
||||
<input bind:checked={isLinked} type="checkbox">
|
||||
<input bind:checked={isLinked} type="checkbox" />
|
||||
<SpecialTranslation t={t.link} {tags} {state} {layer} {feature} />
|
||||
</label>
|
||||
{/if}
|
||||
|
|
|
@ -1,40 +1,44 @@
|
|||
<script lang="ts">/**
|
||||
* Show nearby images which can be clicked
|
||||
*/
|
||||
import type { OsmTags } from "../../Models/OsmFeature";
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource";
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization";
|
||||
import type { P4CPicture } from "../../Logic/Web/NearbyImagesSearch";
|
||||
import NearbyImagesSearch from "../../Logic/Web/NearbyImagesSearch";
|
||||
import LinkableImage from "./LinkableImage.svelte";
|
||||
import type { Feature } from "geojson";
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
||||
import Loading from "../Base/Loading.svelte";
|
||||
import AllImageProviders from "../../Logic/ImageProviders/AllImageProviders";
|
||||
import Tr from "../Base/Tr.svelte";
|
||||
import Translations from "../i18n/Translations";
|
||||
<script lang="ts">
|
||||
/**
|
||||
* Show nearby images which can be clicked
|
||||
*/
|
||||
import type { OsmTags } from "../../Models/OsmFeature"
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import type { P4CPicture } from "../../Logic/Web/NearbyImagesSearch"
|
||||
import NearbyImagesSearch from "../../Logic/Web/NearbyImagesSearch"
|
||||
import LinkableImage from "./LinkableImage.svelte"
|
||||
import type { Feature } from "geojson"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import Loading from "../Base/Loading.svelte"
|
||||
import AllImageProviders from "../../Logic/ImageProviders/AllImageProviders"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
|
||||
export let tags: Store<OsmTags>;
|
||||
export let state: SpecialVisualizationState;
|
||||
export let lon: number;
|
||||
export let lat: number;
|
||||
export let feature: Feature;
|
||||
export let tags: Store<OsmTags>
|
||||
export let state: SpecialVisualizationState
|
||||
export let lon: number
|
||||
export let lat: number
|
||||
export let feature: Feature
|
||||
|
||||
export let linkable: boolean = true;
|
||||
export let layer: LayerConfig;
|
||||
export let linkable: boolean = true
|
||||
export let layer: LayerConfig
|
||||
|
||||
let imagesProvider = new NearbyImagesSearch({
|
||||
lon, lat, allowSpherical: new UIEventSource<boolean>(false),
|
||||
blacklist: AllImageProviders.LoadImagesFor(tags)
|
||||
}, state.indexedFeatures);
|
||||
|
||||
let images: Store<P4CPicture[]> = imagesProvider.store.map(images => images.slice(0, 20));
|
||||
let imagesProvider = new NearbyImagesSearch(
|
||||
{
|
||||
lon,
|
||||
lat,
|
||||
allowSpherical: new UIEventSource<boolean>(false),
|
||||
blacklist: AllImageProviders.LoadImagesFor(tags),
|
||||
},
|
||||
state.indexedFeatures
|
||||
)
|
||||
|
||||
let images: Store<P4CPicture[]> = imagesProvider.store.map((images) => images.slice(0, 20))
|
||||
</script>
|
||||
|
||||
<div class="interactive rounded-2xl border-interactive p-2">
|
||||
<div class="interactive border-interactive rounded-2xl p-2">
|
||||
<div class="flex justify-between">
|
||||
|
||||
<h4>
|
||||
<Tr t={Translations.t.image.nearby.title} />
|
||||
</h4>
|
||||
|
@ -43,7 +47,7 @@ let images: Store<P4CPicture[]> = imagesProvider.store.map(images => images.slic
|
|||
{#if $images.length === 0}
|
||||
<Loading />
|
||||
{:else}
|
||||
<div class="overflow-x-auto w-full flex space-x-1" style="scroll-snap-type: x proximity">
|
||||
<div class="flex w-full space-x-1 overflow-x-auto" style="scroll-snap-type: x proximity">
|
||||
{#each $images as image (image.pictureUrl)}
|
||||
<span class="w-fit shrink-0" style="scroll-snap-align: start">
|
||||
<LinkableImage {tags} {image} {state} {lon} {lat} {feature} {layer} {linkable} />
|
||||
|
|
|
@ -1,36 +1,48 @@
|
|||
<script lang="ts">
|
||||
import { Store } from "../../Logic/UIEventSource";
|
||||
import type { OsmTags } from "../../Models/OsmFeature";
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization";
|
||||
import type { Feature } from "geojson";
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
|
||||
import Translations from "../i18n/Translations";
|
||||
import Tr from "../Base/Tr.svelte";
|
||||
import NearbyImages from "./NearbyImages.svelte";
|
||||
import Svg from "../../Svg";
|
||||
import ToSvelte from "../Base/ToSvelte.svelte";
|
||||
import { XCircleIcon } from "@babeard/svelte-heroicons/solid";
|
||||
import exp from "constants";
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
import type { OsmTags } from "../../Models/OsmFeature"
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import type { Feature } from "geojson"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import Translations from "../i18n/Translations"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import NearbyImages from "./NearbyImages.svelte"
|
||||
import Svg from "../../Svg"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import { XCircleIcon } from "@babeard/svelte-heroicons/solid"
|
||||
import exp from "constants"
|
||||
|
||||
export let tags: Store<OsmTags>;
|
||||
export let state: SpecialVisualizationState;
|
||||
export let lon: number;
|
||||
export let lat: number;
|
||||
export let feature: Feature;
|
||||
export let tags: Store<OsmTags>
|
||||
export let state: SpecialVisualizationState
|
||||
export let lon: number
|
||||
export let lat: number
|
||||
export let feature: Feature
|
||||
|
||||
export let linkable: boolean = true;
|
||||
export let layer: LayerConfig;
|
||||
const t = Translations.t.image.nearby;
|
||||
export let linkable: boolean = true
|
||||
export let layer: LayerConfig
|
||||
const t = Translations.t.image.nearby
|
||||
|
||||
let expanded = false;
|
||||
let expanded = false
|
||||
</script>
|
||||
|
||||
{#if expanded}
|
||||
<NearbyImages {tags} {state} {lon} {lat} {feature} {linkable}>
|
||||
<XCircleIcon slot="corner" class="w-6 h-6 cursor-pointer" on:click={() => {expanded = false}}/>
|
||||
<XCircleIcon
|
||||
slot="corner"
|
||||
class="h-6 w-6 cursor-pointer"
|
||||
on:click={() => {
|
||||
expanded = false
|
||||
}}
|
||||
/>
|
||||
</NearbyImages>
|
||||
{:else}
|
||||
<button class="w-full flex items-center" on:click={() => { expanded = true; }}>
|
||||
<ToSvelte construct={ Svg.camera_plus_svg().SetClass("block w-8 h-8 p-1 mr-2 ")}/>
|
||||
<Tr t={t.seeNearby}/></button>
|
||||
<button
|
||||
class="flex w-full items-center"
|
||||
on:click={() => {
|
||||
expanded = true
|
||||
}}
|
||||
>
|
||||
<ToSvelte construct={Svg.camera_plus_svg().SetClass("block w-8 h-8 p-1 mr-2 ")} />
|
||||
<Tr t={t.seeNearby} />
|
||||
</button>
|
||||
{/if}
|
||||
|
|
|
@ -1,22 +1,18 @@
|
|||
<script lang="ts">
|
||||
|
||||
import type { OsmTags } from "../../Models/OsmFeature";
|
||||
import Svg from "../../Svg";
|
||||
import ToSvelte from "../Base/ToSvelte.svelte";
|
||||
import { Utils } from "../../Utils";
|
||||
import type { OsmTags } from "../../Models/OsmFeature"
|
||||
import Svg from "../../Svg"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import { Utils } from "../../Utils"
|
||||
|
||||
export let tags: Store<OsmTags>
|
||||
export let args: string[]
|
||||
|
||||
let [to, subject, body, button_text] = args.map(a => Utils.SubstituteKeys(a, $tags))
|
||||
let url = "mailto:" +
|
||||
to +
|
||||
"?subject=" +
|
||||
encodeURIComponent(subject) +
|
||||
"&body=" +
|
||||
encodeURIComponent(body)
|
||||
let [to, subject, body, button_text] = args.map((a) => Utils.SubstituteKeys(a, $tags))
|
||||
let url =
|
||||
"mailto:" + to + "?subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(body)
|
||||
</script>
|
||||
<a class="button flex items-center w-full" href={url}>
|
||||
<ToSvelte construct={Svg.envelope_svg().SetClass("w-8 h-8 mr-4 shrink-0")}/>
|
||||
|
||||
<a class="button flex w-full items-center" href={url}>
|
||||
<ToSvelte construct={Svg.envelope_svg().SetClass("w-8 h-8 mr-4 shrink-0")} />
|
||||
{button_text}
|
||||
</a>
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
<script lang="ts">
|
||||
import { UIEventSource } from "../../../Logic/UIEventSource";
|
||||
import type { SpecialVisualizationState } from "../../SpecialVisualization";
|
||||
import Tr from "../../Base/Tr.svelte";
|
||||
import type { Feature } from "geojson";
|
||||
import type { Mapping } from "../../../Models/ThemeConfig/TagRenderingConfig";
|
||||
import TagRenderingConfig from "../../../Models/ThemeConfig/TagRenderingConfig";
|
||||
import { TagsFilter } from "../../../Logic/Tags/TagsFilter";
|
||||
import FreeformInput from "./FreeformInput.svelte";
|
||||
import Translations from "../../i18n/Translations.js";
|
||||
import ChangeTagAction from "../../../Logic/Osm/Actions/ChangeTagAction";
|
||||
import { createEventDispatcher, onDestroy } from "svelte";
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig";
|
||||
import SpecialTranslation from "./SpecialTranslation.svelte";
|
||||
import TagHint from "../TagHint.svelte";
|
||||
import LoginToggle from "../../Base/LoginToggle.svelte";
|
||||
import SubtleButton from "../../Base/SubtleButton.svelte";
|
||||
import Loading from "../../Base/Loading.svelte";
|
||||
import TagRenderingMappingInput from "./TagRenderingMappingInput.svelte";
|
||||
import { Translation } from "../../i18n/Translation";
|
||||
import Constants from "../../../Models/Constants";
|
||||
import { Unit } from "../../../Models/Unit";
|
||||
import UserRelatedState from "../../../Logic/State/UserRelatedState";
|
||||
import { twJoin } from "tailwind-merge";
|
||||
import { TagUtils } from "../../../Logic/Tags/TagUtils";
|
||||
import { UIEventSource } from "../../../Logic/UIEventSource"
|
||||
import type { SpecialVisualizationState } from "../../SpecialVisualization"
|
||||
import Tr from "../../Base/Tr.svelte"
|
||||
import type { Feature } from "geojson"
|
||||
import type { Mapping } from "../../../Models/ThemeConfig/TagRenderingConfig"
|
||||
import TagRenderingConfig from "../../../Models/ThemeConfig/TagRenderingConfig"
|
||||
import { TagsFilter } from "../../../Logic/Tags/TagsFilter"
|
||||
import FreeformInput from "./FreeformInput.svelte"
|
||||
import Translations from "../../i18n/Translations.js"
|
||||
import ChangeTagAction from "../../../Logic/Osm/Actions/ChangeTagAction"
|
||||
import { createEventDispatcher, onDestroy } from "svelte"
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
|
||||
import SpecialTranslation from "./SpecialTranslation.svelte"
|
||||
import TagHint from "../TagHint.svelte"
|
||||
import LoginToggle from "../../Base/LoginToggle.svelte"
|
||||
import SubtleButton from "../../Base/SubtleButton.svelte"
|
||||
import Loading from "../../Base/Loading.svelte"
|
||||
import TagRenderingMappingInput from "./TagRenderingMappingInput.svelte"
|
||||
import { Translation } from "../../i18n/Translation"
|
||||
import Constants from "../../../Models/Constants"
|
||||
import { Unit } from "../../../Models/Unit"
|
||||
import UserRelatedState from "../../../Logic/State/UserRelatedState"
|
||||
import { twJoin } from "tailwind-merge"
|
||||
import { TagUtils } from "../../../Logic/Tags/TagUtils"
|
||||
|
||||
export let config: TagRenderingConfig;
|
||||
export let tags: UIEventSource<Record<string, string>>;
|
||||
export let selectedElement: Feature;
|
||||
export let state: SpecialVisualizationState;
|
||||
export let layer: LayerConfig;
|
||||
export let config: TagRenderingConfig
|
||||
export let tags: UIEventSource<Record<string, string>>
|
||||
export let selectedElement: Feature
|
||||
export let state: SpecialVisualizationState
|
||||
export let layer: LayerConfig
|
||||
|
||||
let feedback: UIEventSource<Translation> = new UIEventSource<Translation>(undefined);
|
||||
let feedback: UIEventSource<Translation> = new UIEventSource<Translation>(undefined)
|
||||
|
||||
let unit: Unit = layer.units?.find((unit) => unit.appliesToKeys.has(config.freeform?.key));
|
||||
let unit: Unit = layer.units?.find((unit) => unit.appliesToKeys.has(config.freeform?.key))
|
||||
|
||||
// Will be bound if a freeform is available
|
||||
let freeformInput = new UIEventSource<string>(tags?.[config.freeform?.key]);
|
||||
let selectedMapping: number = undefined;
|
||||
let checkedMappings: boolean[];
|
||||
let freeformInput = new UIEventSource<string>(tags?.[config.freeform?.key])
|
||||
let selectedMapping: number = undefined
|
||||
let checkedMappings: boolean[]
|
||||
|
||||
/**
|
||||
* Prepares and fills the checkedMappings
|
||||
|
@ -45,38 +45,39 @@
|
|||
function initialize(tgs: Record<string, string>, confg: TagRenderingConfig) {
|
||||
mappings = confg.mappings?.filter((m) => {
|
||||
if (typeof m.hideInAnswer === "boolean") {
|
||||
return !m.hideInAnswer;
|
||||
return !m.hideInAnswer
|
||||
}
|
||||
return !m.hideInAnswer.matchesProperties(tgs);
|
||||
});
|
||||
return !m.hideInAnswer.matchesProperties(tgs)
|
||||
})
|
||||
// We received a new config -> reinit
|
||||
unit = layer.units.find((unit) => unit.appliesToKeys.has(confg.freeform?.key));
|
||||
unit = layer.units.find((unit) => unit.appliesToKeys.has(confg.freeform?.key))
|
||||
|
||||
if (
|
||||
confg.mappings?.length > 0 &&
|
||||
(checkedMappings === undefined || checkedMappings?.length < confg.mappings.length + (confg.freeform ? 1 : 0))
|
||||
(checkedMappings === undefined ||
|
||||
checkedMappings?.length < confg.mappings.length + (confg.freeform ? 1 : 0))
|
||||
) {
|
||||
const seenFreeforms = [];
|
||||
const seenFreeforms = []
|
||||
TagUtils.FlattenMultiAnswer()
|
||||
checkedMappings = [
|
||||
...confg.mappings.map((mapping) => {
|
||||
const matches = TagUtils.MatchesMultiAnswer(mapping.if, tgs)
|
||||
const matches = TagUtils.MatchesMultiAnswer(mapping.if, tgs)
|
||||
if (matches && confg.freeform) {
|
||||
const newProps = TagUtils.changeAsProperties(mapping.if.asChange());
|
||||
seenFreeforms.push(newProps[confg.freeform.key]);
|
||||
const newProps = TagUtils.changeAsProperties(mapping.if.asChange())
|
||||
seenFreeforms.push(newProps[confg.freeform.key])
|
||||
}
|
||||
return matches;
|
||||
})
|
||||
];
|
||||
|
||||
if(tgs !== undefined && confg.freeform){
|
||||
return matches
|
||||
}),
|
||||
]
|
||||
|
||||
if (tgs !== undefined && confg.freeform) {
|
||||
const unseenFreeformValues = tgs[confg.freeform.key]?.split(";") ?? []
|
||||
for (const seenFreeform of seenFreeforms) {
|
||||
if(!seenFreeform){
|
||||
if (!seenFreeform) {
|
||||
continue
|
||||
}
|
||||
const index = unseenFreeformValues.indexOf(seenFreeform)
|
||||
if(index < 0){
|
||||
if (index < 0) {
|
||||
continue
|
||||
}
|
||||
unseenFreeformValues.splice(index, 1)
|
||||
|
@ -85,29 +86,27 @@
|
|||
freeformInput.setData(unseenFreeformValues.join(";"))
|
||||
checkedMappings.push(unseenFreeformValues.length > 0)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (confg.freeform?.key) {
|
||||
if (!confg.multiAnswer) {
|
||||
// Somehow, setting multi-answer freeform values is broken if this is not set
|
||||
freeformInput.setData(tgs[confg.freeform.key]);
|
||||
freeformInput.setData(tgs[confg.freeform.key])
|
||||
}
|
||||
} else {
|
||||
freeformInput.setData(undefined);
|
||||
freeformInput.setData(undefined)
|
||||
}
|
||||
feedback.setData(undefined);
|
||||
feedback.setData(undefined)
|
||||
}
|
||||
|
||||
$: {
|
||||
// Even though 'config' is not declared as a store, Svelte uses it as one to update the component
|
||||
// We want to (re)-initialize whenever the 'tags' or 'config' change - but not when 'checkedConfig' changes
|
||||
initialize($tags, config);
|
||||
initialize($tags, config)
|
||||
}
|
||||
export let selectedTags: TagsFilter = undefined;
|
||||
export let selectedTags: TagsFilter = undefined
|
||||
|
||||
let mappings: Mapping[] = config?.mappings;
|
||||
let searchTerm: UIEventSource<string> = new UIEventSource("");
|
||||
let mappings: Mapping[] = config?.mappings
|
||||
let searchTerm: UIEventSource<string> = new UIEventSource("")
|
||||
|
||||
$: {
|
||||
try {
|
||||
|
@ -116,10 +115,10 @@
|
|||
selectedMapping,
|
||||
checkedMappings,
|
||||
tags.data
|
||||
);
|
||||
)
|
||||
} catch (e) {
|
||||
console.error("Could not calculate changeSpecification:", e);
|
||||
selectedTags = undefined;
|
||||
console.error("Could not calculate changeSpecification:", e)
|
||||
selectedTags = undefined
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,53 +127,53 @@
|
|||
config: TagRenderingConfig
|
||||
applied: TagsFilter
|
||||
}
|
||||
}>();
|
||||
}>()
|
||||
|
||||
function onSave() {
|
||||
if (selectedTags === undefined) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
if (layer.source === null) {
|
||||
/**
|
||||
* This is a special, priviliged layer.
|
||||
* We simply apply the tags onto the records
|
||||
*/
|
||||
const kv = selectedTags.asChange(tags.data);
|
||||
const kv = selectedTags.asChange(tags.data)
|
||||
for (const { k, v } of kv) {
|
||||
if (v === undefined) {
|
||||
delete tags.data[k];
|
||||
delete tags.data[k]
|
||||
} else {
|
||||
tags.data[k] = v;
|
||||
tags.data[k] = v
|
||||
}
|
||||
}
|
||||
tags.ping();
|
||||
return;
|
||||
tags.ping()
|
||||
return
|
||||
}
|
||||
|
||||
dispatch("saved", { config, applied: selectedTags });
|
||||
dispatch("saved", { config, applied: selectedTags })
|
||||
const change = new ChangeTagAction(tags.data.id, selectedTags, tags.data, {
|
||||
theme: state.layout.id,
|
||||
changeType: "answer"
|
||||
});
|
||||
freeformInput.setData(undefined);
|
||||
selectedMapping = undefined;
|
||||
selectedTags = undefined;
|
||||
changeType: "answer",
|
||||
})
|
||||
freeformInput.setData(undefined)
|
||||
selectedMapping = undefined
|
||||
selectedTags = undefined
|
||||
|
||||
change
|
||||
.CreateChangeDescriptions()
|
||||
.then((changes) => state.changes.applyChanges(changes))
|
||||
.catch(console.error);
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
let featureSwitchIsTesting = state.featureSwitchIsTesting;
|
||||
let featureSwitchIsDebugging = state.featureSwitches.featureSwitchIsDebugging;
|
||||
let showTags = state.userRelatedState.showTags;
|
||||
let numberOfCs = state.osmConnection.userDetails.data.csCount;
|
||||
let featureSwitchIsTesting = state.featureSwitchIsTesting
|
||||
let featureSwitchIsDebugging = state.featureSwitches.featureSwitchIsDebugging
|
||||
let showTags = state.userRelatedState.showTags
|
||||
let numberOfCs = state.osmConnection.userDetails.data.csCount
|
||||
onDestroy(
|
||||
state.osmConnection.userDetails.addCallbackAndRun((ud) => {
|
||||
numberOfCs = ud.csCount;
|
||||
numberOfCs = ud.csCount
|
||||
})
|
||||
);
|
||||
)
|
||||
</script>
|
||||
|
||||
{#if config.question !== undefined}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import Svg from "../Svg";
|
||||
import Loading from "./Base/Loading.svelte";
|
||||
import ToSvelte from "./Base/ToSvelte.svelte";
|
||||
import Svg from "../Svg"
|
||||
import Loading from "./Base/Loading.svelte"
|
||||
import ToSvelte from "./Base/ToSvelte.svelte"
|
||||
</script>
|
||||
|
||||
<div>
|
||||
|
@ -43,12 +43,8 @@
|
|||
Main action (disabled)
|
||||
</button>
|
||||
|
||||
<button class="small primary">
|
||||
Small button
|
||||
</button>
|
||||
<button class="small primary disabled">
|
||||
Small, disabled button
|
||||
</button>
|
||||
<button class="small primary">Small button</button>
|
||||
<button class="small primary disabled">Small, disabled button</button>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<button>
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
<script lang="ts">
|
||||
import type { FullWikipediaDetails } from "../../Logic/Web/Wikipedia";
|
||||
import { Store } from "../../Logic/UIEventSource";
|
||||
import FromHtml from "../Base/FromHtml.svelte";
|
||||
import Loading from "../Base/Loading.svelte";
|
||||
import { Disclosure, DisclosureButton, DisclosurePanel } from "@rgossiaux/svelte-headlessui";
|
||||
import { ChevronRightIcon } from "@rgossiaux/svelte-heroicons/solid";
|
||||
import ToSvelte from "../Base/ToSvelte.svelte";
|
||||
import WikidataPreviewBox from "./WikidataPreviewBox";
|
||||
import Tr from "../Base/Tr.svelte";
|
||||
import Translations from "../i18n/Translations";
|
||||
import type { FullWikipediaDetails } from "../../Logic/Web/Wikipedia"
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
import FromHtml from "../Base/FromHtml.svelte"
|
||||
import Loading from "../Base/Loading.svelte"
|
||||
import { Disclosure, DisclosureButton, DisclosurePanel } from "@rgossiaux/svelte-headlessui"
|
||||
import { ChevronRightIcon } from "@rgossiaux/svelte-heroicons/solid"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import WikidataPreviewBox from "./WikidataPreviewBox"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
|
||||
/**
|
||||
* Shows a wikipedia-article + wikidata preview for the given item
|
||||
*/
|
||||
export let wikipediaDetails: Store<FullWikipediaDetails>;
|
||||
export let wikipediaDetails: Store<FullWikipediaDetails>
|
||||
</script>
|
||||
|
||||
{#if $wikipediaDetails.articleUrl}
|
||||
|
||||
<a class="flex" href={$wikipediaDetails.articleUrl} rel="noreferrer" target="_blank">
|
||||
<img class="h-6 w-6" src="./assets/svg/wikipedia.svg" />
|
||||
<Tr t={Translations.t.general.wikipedia.fromWikipedia} />
|
||||
|
@ -29,7 +28,6 @@
|
|||
{/if}
|
||||
|
||||
{#if $wikipediaDetails.articleUrl}
|
||||
|
||||
{#if $wikipediaDetails.firstParagraph === "" || $wikipediaDetails.firstParagraph === undefined}
|
||||
<Loading>
|
||||
<Tr t={Translations.t.general.wikipedia.loading} />
|
||||
|
|
|
@ -2,28 +2,28 @@
|
|||
/**
|
||||
* Shows one or more wikidata info boxes or wikipedia articles in a tabbed component.
|
||||
*/
|
||||
import type { FullWikipediaDetails } from "../../Logic/Web/Wikipedia";
|
||||
import Wikipedia from "../../Logic/Web/Wikipedia";
|
||||
import Locale from "../i18n/Locale";
|
||||
import { Store } from "../../Logic/UIEventSource";
|
||||
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from "@rgossiaux/svelte-headlessui";
|
||||
import WikipediaTitle from "./WikipediaTitle.svelte";
|
||||
import WikipediaArticle from "./WikipediaArticle.svelte";
|
||||
import { onDestroy } from "svelte";
|
||||
import type { FullWikipediaDetails } from "../../Logic/Web/Wikipedia"
|
||||
import Wikipedia from "../../Logic/Web/Wikipedia"
|
||||
import Locale from "../i18n/Locale"
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from "@rgossiaux/svelte-headlessui"
|
||||
import WikipediaTitle from "./WikipediaTitle.svelte"
|
||||
import WikipediaArticle from "./WikipediaArticle.svelte"
|
||||
import { onDestroy } from "svelte"
|
||||
|
||||
/**
|
||||
* Either a wikidata item or a '<language>:<article>' link
|
||||
*/
|
||||
export let wikiIds: Store<string[]>;
|
||||
export let wikiIds: Store<string[]>
|
||||
let wikipediaStores: Store<Store<FullWikipediaDetails>[]> = Locale.language.bind((language) =>
|
||||
wikiIds?.map((wikiIds) => wikiIds?.map((id) => Wikipedia.fetchArticleAndWikidata(id, language)))
|
||||
);
|
||||
let _wikipediaStores;
|
||||
let _wikipediaStores
|
||||
onDestroy(
|
||||
wikipediaStores.addCallbackAndRunD((wikipediaStores) => {
|
||||
_wikipediaStores = wikipediaStores;
|
||||
_wikipediaStores = wikipediaStores
|
||||
})
|
||||
);
|
||||
)
|
||||
</script>
|
||||
|
||||
{#if _wikipediaStores !== undefined}
|
||||
|
@ -50,15 +50,15 @@
|
|||
{/if}
|
||||
|
||||
<style>
|
||||
/* Actually used, don't remove*/
|
||||
.tab-selected {
|
||||
background-color: rgb(59 130 246);
|
||||
color: rgb(255 255 255);
|
||||
}
|
||||
/* Actually used, don't remove*/
|
||||
.tab-selected {
|
||||
background-color: rgb(59 130 246);
|
||||
color: rgb(255 255 255);
|
||||
}
|
||||
|
||||
/* Actually used, don't remove*/
|
||||
.tab-unselected {
|
||||
background-color: rgb(255 255 255);
|
||||
color: rgb(0 0 0);
|
||||
}
|
||||
/* Actually used, don't remove*/
|
||||
.tab-unselected {
|
||||
background-color: rgb(255 255 255);
|
||||
color: rgb(0 0 0);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"contributors": [
|
||||
{
|
||||
"commits": 5914,
|
||||
"commits": 5961,
|
||||
"contributor": "Pieter Vander Vennet"
|
||||
},
|
||||
{
|
||||
"commits": 393,
|
||||
"commits": 408,
|
||||
"contributor": "Robin van der Linde"
|
||||
},
|
||||
{
|
||||
|
@ -33,12 +33,12 @@
|
|||
"contributor": "paunofu"
|
||||
},
|
||||
{
|
||||
"commits": 27,
|
||||
"contributor": "riQQ"
|
||||
"commits": 28,
|
||||
"contributor": "Hosted Weblate"
|
||||
},
|
||||
{
|
||||
"commits": 26,
|
||||
"contributor": "Hosted Weblate"
|
||||
"commits": 27,
|
||||
"contributor": "riQQ"
|
||||
},
|
||||
{
|
||||
"commits": 26,
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"contributors": [
|
||||
{
|
||||
"commits": 299,
|
||||
"commits": 300,
|
||||
"contributor": "kjon"
|
||||
},
|
||||
{
|
||||
"commits": 281,
|
||||
"commits": 285,
|
||||
"contributor": "Pieter Vander Vennet"
|
||||
},
|
||||
{
|
||||
"commits": 151,
|
||||
"commits": 160,
|
||||
"contributor": "paunofu"
|
||||
},
|
||||
{
|
||||
|
@ -348,6 +348,10 @@
|
|||
"commits": 3,
|
||||
"contributor": "SiegbjornSitumeang"
|
||||
},
|
||||
{
|
||||
"commits": 2,
|
||||
"contributor": "Peter Brodersen"
|
||||
},
|
||||
{
|
||||
"commits": 2,
|
||||
"contributor": "nilocram"
|
||||
|
|
10
src/land.ts
10
src/land.ts
|
@ -1,10 +1,10 @@
|
|||
import {OsmConnection} from "./Logic/Osm/OsmConnection";
|
||||
import { OsmConnection } from "./Logic/Osm/OsmConnection"
|
||||
|
||||
console.log("Authorizing...");
|
||||
new OsmConnection().finishLogin(previousURL => {
|
||||
const fallback = window.location.protocol+"//"+window.location.host+"/index.html"
|
||||
console.log("Authorizing...")
|
||||
new OsmConnection().finishLogin((previousURL) => {
|
||||
const fallback = window.location.protocol + "//" + window.location.host + "/index.html"
|
||||
previousURL ??= fallback
|
||||
if(previousURL.indexOf("/land") > 0){
|
||||
if (previousURL.indexOf("/land") > 0) {
|
||||
previousURL = fallback
|
||||
}
|
||||
console.log("Redirecting to", previousURL)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue