forked from MapComplete/MapComplete
Chore: housekeeping
This commit is contained in:
parent
8178c5607b
commit
cd0d275965
73 changed files with 2105 additions and 2219 deletions
|
|
@ -84,18 +84,18 @@
|
|||
<Logo alt="MapComplete Logo" class="h-12 w-12 sm:h-24 sm:w-24" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col link-underline">
|
||||
<div class="link-underline flex flex-col">
|
||||
<h1 class="m-0 font-extrabold tracking-tight md:text-6xl">
|
||||
<Tr t={t.title} />
|
||||
</h1>
|
||||
<Tr
|
||||
cls="mr-4 text-base font-semibold sm:text-lg md:mt-5 md:text-xl lg:mx-0"
|
||||
t={Translations.t.index.intro}
|
||||
/>
|
||||
<a href="#about">
|
||||
<Tr t={Translations.t.index.learnMore} />
|
||||
<ChevronDoubleRight class="inline h-4 w-4" />
|
||||
</a>
|
||||
<Tr
|
||||
cls="mr-4 text-base font-semibold sm:text-lg md:mt-5 md:text-xl lg:mx-0"
|
||||
t={Translations.t.index.intro}
|
||||
/>
|
||||
<a href="#about">
|
||||
<Tr t={Translations.t.index.learnMore} />
|
||||
<ChevronDoubleRight class="inline h-4 w-4" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -146,48 +146,47 @@
|
|||
<UnofficialThemeList search={themeSearchText} {state} />
|
||||
</LoginToggle>
|
||||
|
||||
<h3 id="about">
|
||||
<Tr t={Translations.t.index.about} />
|
||||
</h3>
|
||||
<Tr cls="link-underline" t={Translations.t.general.aboutMapComplete.intro} />
|
||||
<h3 id="about">
|
||||
<Tr t={Translations.t.index.about} />
|
||||
</h3>
|
||||
<Tr cls="link-underline" t={Translations.t.general.aboutMapComplete.intro} />
|
||||
|
||||
<span class="link-underline flex flex-col gap-y-1">
|
||||
<a class="flex" href="https://github.com/pietervdvn/MapComplete/" target="_blank">
|
||||
<Github class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.general.attribution.gotoSourceCode} />
|
||||
</a>
|
||||
<a class="flex" href="https://github.com/pietervdvn/MapComplete/issues" target="_blank">
|
||||
<Bug class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.general.attribution.openIssueTracker} />
|
||||
</a>
|
||||
<span class="link-underline flex flex-col gap-y-1">
|
||||
<a class="flex" href="https://github.com/pietervdvn/MapComplete/" target="_blank">
|
||||
<Github class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.general.attribution.gotoSourceCode} />
|
||||
</a>
|
||||
<a class="flex" href="https://github.com/pietervdvn/MapComplete/issues" target="_blank">
|
||||
<Bug class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.general.attribution.openIssueTracker} />
|
||||
</a>
|
||||
|
||||
<a class="flex" href="https://en.osm.town/@MapComplete" target="_blank">
|
||||
<Mastodon class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.general.attribution.followOnMastodon} />
|
||||
</a>
|
||||
<a class="flex" href="https://en.osm.town/@MapComplete" target="_blank">
|
||||
<Mastodon class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.general.attribution.followOnMastodon} />
|
||||
</a>
|
||||
|
||||
<a class="flex" href="https://liberapay.com/pietervdvn/" target="_blank">
|
||||
<Liberapay class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.general.attribution.donate} />
|
||||
</a>
|
||||
<a class="flex" href="https://liberapay.com/pietervdvn/" target="_blank">
|
||||
<Liberapay class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.general.attribution.donate} />
|
||||
</a>
|
||||
|
||||
<a
|
||||
class="flex"
|
||||
href={window.location.protocol + "//" + window.location.host + "/studio.html"}
|
||||
>
|
||||
<Pencil class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.general.morescreen.createYourOwnTheme} />
|
||||
</a>
|
||||
|
||||
<a
|
||||
class="flex"
|
||||
href={window.location.protocol + "//" + window.location.host + "/privacy.html"}
|
||||
>
|
||||
<Eye class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.privacy.title} />
|
||||
</a>
|
||||
</span>
|
||||
<a
|
||||
class="flex"
|
||||
href={window.location.protocol + "//" + window.location.host + "/studio.html"}
|
||||
>
|
||||
<Pencil class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.general.morescreen.createYourOwnTheme} />
|
||||
</a>
|
||||
|
||||
<a
|
||||
class="flex"
|
||||
href={window.location.protocol + "//" + window.location.host + "/privacy.html"}
|
||||
>
|
||||
<Eye class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.privacy.title} />
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<Tr t={tr.streetcomplete} />
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,18 @@
|
|||
style="background-color: #00000088; z-index: 20"
|
||||
/>
|
||||
<!-- draw a _second_ absolute div, placed using 'bottom' which will be above the navigation bar on mobile browsers -->
|
||||
<div class="absolute bottom-0 right-0 h-full w-screen p-4 md:p-6 pointer-events-none" style="z-index: 21" on:click={() =>{
|
||||
console.log("Closing...")
|
||||
dispatch("close")}}>
|
||||
<div class="content normal-background h-full pointer-events-auto" on:click|stopPropagation={() => {}}>
|
||||
<div
|
||||
class="pointer-events-none absolute bottom-0 right-0 h-full w-screen p-4 md:p-6"
|
||||
style="z-index: 21"
|
||||
on:click={() => {
|
||||
console.log("Closing...")
|
||||
dispatch("close")
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class="content normal-background pointer-events-auto h-full"
|
||||
on:click|stopPropagation={() => {}}
|
||||
>
|
||||
<div class="h-full rounded-xl">
|
||||
<slot />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@
|
|||
function getStateFor(option: FilterConfig): UIEventSource<number | string> {
|
||||
return filteredLayer.appliedFilters.get(option.id)
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
{#if filteredLayer.layerDef.name}
|
||||
|
|
|
|||
|
|
@ -27,9 +27,8 @@ export default class MoreScreen {
|
|||
if (searchTerm === "osmcha" || searchTerm === "stats") {
|
||||
window.location.href = Utils.OsmChaLinkFor(7)
|
||||
}
|
||||
if (searchTerm === "studio" ) {
|
||||
if (searchTerm === "studio") {
|
||||
window.location.href = "./studio.html"
|
||||
|
||||
}
|
||||
// Enter pressed -> search the first _official_ matchin theme and open it
|
||||
const publicTheme = MoreScreen.officialThemes.find(
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
selectedElement.properties.id
|
||||
)
|
||||
|
||||
function getLayer(properties: Record<string, string>){
|
||||
if(properties.id === "settings"){
|
||||
return UserRelatedState.usersettingsConfig
|
||||
function getLayer(properties: Record<string, string>) {
|
||||
if (properties.id === "settings") {
|
||||
return UserRelatedState.usersettingsConfig
|
||||
}
|
||||
if (properties.id === "new_point_dialog") {
|
||||
return state.layout.layers.find((l) => l.id === "last_click")
|
||||
|
|
@ -36,7 +36,6 @@
|
|||
|
||||
let layer: LayerConfig = getLayer(selectedElement.properties)
|
||||
|
||||
|
||||
let stillMatches = tags.map(
|
||||
(tags) => !layer?.source?.osmTags || layer.source.osmTags?.matchesProperties(tags)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -86,12 +86,12 @@
|
|||
</script>
|
||||
|
||||
{#if theme.id !== personal.id || $unlockedPersonal}
|
||||
<a class={"flex w-full items-center text-ellipsis rounded my-2"} href={$href}>
|
||||
<Marker icons={theme.icon} size="m-1 block h-11 w-11 sm:mr-2 shrink-0"/>
|
||||
<a class={"my-2 flex w-full items-center text-ellipsis rounded"} href={$href}>
|
||||
<Marker icons={theme.icon} size="m-1 block h-11 w-11 sm:mr-2 shrink-0" />
|
||||
|
||||
<span class="flex flex-col overflow-hidden text-ellipsis font-bold text-xl">
|
||||
<span class="flex flex-col overflow-hidden text-ellipsis text-xl font-bold">
|
||||
<Tr cls="underline" t={title} />
|
||||
<Tr cls="subtle text-base" t={description}/>
|
||||
<Tr cls="subtle text-base" t={description} />
|
||||
|
||||
{#if selected}
|
||||
<span class="thanks hidden-on-mobile" aria-hidden="true">
|
||||
|
|
|
|||
|
|
@ -150,13 +150,12 @@
|
|||
</div>
|
||||
|
||||
<If condition={state.featureSwitches.featureSwitchBackToThemeOverview}>
|
||||
|
||||
<div class="link-underline w-full m-2 mx-4 flex">
|
||||
<!-- bottom buttons, a bit hidden away: switch layout -->
|
||||
<a class="flex justify-end items-center w-fit" href={Utils.HomepageLink()}>
|
||||
<ChevronDoubleLeft class="w-4 h-4" />
|
||||
<Tr t={Translations.t.general.backToIndex} />
|
||||
</a>
|
||||
</div>
|
||||
<div class="link-underline m-2 mx-4 flex w-full">
|
||||
<!-- bottom buttons, a bit hidden away: switch layout -->
|
||||
<a class="flex w-fit items-center justify-end" href={Utils.HomepageLink()}>
|
||||
<ChevronDoubleLeft class="h-4 w-4" />
|
||||
<Tr t={Translations.t.general.backToIndex} />
|
||||
</a>
|
||||
</div>
|
||||
</If>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<div>
|
||||
<div class:interactive={!readonly} class="flex flex-col items-end py-1 px-2">
|
||||
<div class="flex flex-col w-full">
|
||||
<div class="flex w-full flex-col">
|
||||
{#if renderingExternal}
|
||||
<TagRenderingAnswer
|
||||
tags={new UIEventSource(mockPropertiesExternal)}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ export class ComparisonState {
|
|||
public readonly knownImages: Store<Set<string>>
|
||||
|
||||
constructor(tags: UIEventSource<OsmTags>, externalProperties: Record<string, string>) {
|
||||
|
||||
externalProperties = { ...externalProperties }
|
||||
delete externalProperties["@context"]
|
||||
|
||||
|
|
@ -74,7 +73,7 @@ export class ComparisonState {
|
|||
)
|
||||
|
||||
this.hasDifferencesAtStart =
|
||||
this. different.data.length + this.missing.data.length + this.unknownImages.data.length > 0
|
||||
|
||||
this.different.data.length + this.missing.data.length + this.unknownImages.data.length >
|
||||
0
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@
|
|||
|
||||
export let readonly = false
|
||||
|
||||
export let comparisonState : ComparisonState
|
||||
export let comparisonState: ComparisonState
|
||||
let missing = comparisonState.missing
|
||||
let unknownImages = comparisonState.unknownImages
|
||||
let knownImages = comparisonState.knownImages
|
||||
let different =comparisonState.different
|
||||
let different = comparisonState.different
|
||||
|
||||
const t = Translations.t.external
|
||||
|
||||
|
|
@ -50,27 +50,50 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
|
||||
{#if $unknownImages.length === 0 && $missing.length === 0 && $different.length === 0}
|
||||
<div class="thanks m-0 flex items-center gap-x-2 px-2">
|
||||
<Party class="h-8 w-8 shrink-0" />
|
||||
<Tr t={t.allIncluded.Subs({ source: sourceUrl })} />
|
||||
</div>
|
||||
{:else}
|
||||
{#if !readonly}
|
||||
<Tr t={t.loadedFrom.Subs({ url: sourceUrl, source: sourceUrl })} />
|
||||
{#if !readonly}
|
||||
<Tr t={t.loadedFrom.Subs({ url: sourceUrl, source: sourceUrl })} />
|
||||
{/if}
|
||||
|
||||
<div class="flex flex-col" class:gap-y-8={!readonly}>
|
||||
{#if $different.length > 0}
|
||||
{#if !readonly}
|
||||
<h3>
|
||||
<Tr t={t.conflicting.title} />
|
||||
</h3>
|
||||
<Tr t={t.conflicting.intro} />
|
||||
{/if}
|
||||
{#each $different as key (key)}
|
||||
<div class="mx-2 rounded-2xl">
|
||||
<ComparisonAction
|
||||
{key}
|
||||
{state}
|
||||
{tags}
|
||||
{externalProperties}
|
||||
{layer}
|
||||
{feature}
|
||||
{readonly}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
<div class="flex flex-col" class:gap-y-8={!readonly}>
|
||||
{#if $different.length > 0}
|
||||
{#if !readonly}
|
||||
<h3>
|
||||
<Tr t={t.conflicting.title} />
|
||||
</h3>
|
||||
<Tr t={t.conflicting.intro} />
|
||||
{/if}
|
||||
{#each $different as key (key)}
|
||||
<div class="mx-2 rounded-2xl">
|
||||
{#if $missing.length > 0}
|
||||
{#if !readonly}
|
||||
<h3 class="m-0">
|
||||
<Tr t={t.missing.title} />
|
||||
</h3>
|
||||
|
||||
<Tr t={t.missing.intro} />
|
||||
{/if}
|
||||
{#if currentStep === "init"}
|
||||
{#each $missing as key (key)}
|
||||
<div class:focus={applyAllHovered} class="mx-2 rounded-2xl">
|
||||
<ComparisonAction
|
||||
{key}
|
||||
{state}
|
||||
|
|
@ -82,86 +105,66 @@
|
|||
/>
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
{#if $missing.length > 0}
|
||||
{#if !readonly}
|
||||
<h3 class="m-0">
|
||||
<Tr t={t.missing.title} />
|
||||
</h3>
|
||||
|
||||
<Tr t={t.missing.intro} />
|
||||
{#if !readonly && $missing.length > 1}
|
||||
<button
|
||||
on:click={() => applyAllMissing()}
|
||||
on:mouseover={() => (applyAllHovered = true)}
|
||||
on:focus={() => (applyAllHovered = true)}
|
||||
on:blur={() => (applyAllHovered = false)}
|
||||
on:mouseout={() => (applyAllHovered = false)}
|
||||
>
|
||||
<Tr t={t.applyAll} />
|
||||
</button>
|
||||
{/if}
|
||||
{#if currentStep === "init"}
|
||||
{#each $missing as key (key)}
|
||||
<div class:focus={applyAllHovered} class="mx-2 rounded-2xl">
|
||||
<ComparisonAction
|
||||
{key}
|
||||
{state}
|
||||
{tags}
|
||||
{externalProperties}
|
||||
{layer}
|
||||
{feature}
|
||||
{readonly}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
{#if !readonly && $missing.length > 1}
|
||||
<button
|
||||
on:click={() => applyAllMissing()}
|
||||
on:mouseover={() => (applyAllHovered = true)}
|
||||
on:focus={() => (applyAllHovered = true)}
|
||||
on:blur={() => (applyAllHovered = false)}
|
||||
on:mouseout={() => (applyAllHovered = false)}
|
||||
>
|
||||
<Tr t={t.applyAll} />
|
||||
</button>
|
||||
{/if}
|
||||
{:else if currentStep === "applying_all"}
|
||||
<Loading />
|
||||
{:else if currentStep === "all_applied"}
|
||||
<div class="thanks">
|
||||
<Tr t={t.allAreApplied} />
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if $unknownImages.length > 0}
|
||||
{#if readonly}
|
||||
<div class="w-full overflow-x-auto">
|
||||
<div class="flex h-32 w-max gap-x-2">
|
||||
{#each $unknownImages as image (image)}
|
||||
<AttributedImage
|
||||
imgClass="h-32 w-max shrink-0"
|
||||
image={{ url: image }}
|
||||
previewedImage={state.previewedImage}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
{:else if currentStep === "applying_all"}
|
||||
<Loading />
|
||||
{:else if currentStep === "all_applied"}
|
||||
<div class="thanks">
|
||||
<Tr t={t.allAreApplied} />
|
||||
</div>
|
||||
{:else}
|
||||
{#each $unknownImages as image (image)}
|
||||
<LinkableImage
|
||||
{tags}
|
||||
{state}
|
||||
image={{
|
||||
pictureUrl: image,
|
||||
provider: "Velopark",
|
||||
thumbUrl: image,
|
||||
details: undefined,
|
||||
coordinates: undefined,
|
||||
osmTags: { image },
|
||||
}}
|
||||
{feature}
|
||||
{layer}
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
{/if}
|
||||
{#if externalProperties["_last_edit_timestamp"] !== undefined}
|
||||
<span class="subtle text-sm flex flex-end justify-end mt-2 mr-4">
|
||||
<Tr t={t.lastModified.Subs({date: new Date(externalProperties["_last_edit_timestamp"]).toLocaleString() })}/>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{#if $unknownImages.length > 0}
|
||||
{#if readonly}
|
||||
<div class="w-full overflow-x-auto">
|
||||
<div class="flex h-32 w-max gap-x-2">
|
||||
{#each $unknownImages as image (image)}
|
||||
<AttributedImage
|
||||
imgClass="h-32 w-max shrink-0"
|
||||
image={{ url: image }}
|
||||
previewedImage={state.previewedImage}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
{#each $unknownImages as image (image)}
|
||||
<LinkableImage
|
||||
{tags}
|
||||
{state}
|
||||
image={{
|
||||
pictureUrl: image,
|
||||
provider: "Velopark",
|
||||
thumbUrl: image,
|
||||
details: undefined,
|
||||
coordinates: undefined,
|
||||
osmTags: { image },
|
||||
}}
|
||||
{feature}
|
||||
{layer}
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
{/if}
|
||||
{#if externalProperties["_last_edit_timestamp"] !== undefined}
|
||||
<span class="subtle flex-end mt-2 mr-4 flex justify-end text-sm">
|
||||
<Tr
|
||||
t={t.lastModified.Subs({
|
||||
date: new Date(externalProperties["_last_edit_timestamp"]).toLocaleString(),
|
||||
})}
|
||||
/>
|
||||
</span>
|
||||
{/if}
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -32,17 +32,16 @@
|
|||
export let collapsed: boolean
|
||||
const t = Translations.t.external
|
||||
|
||||
let comparisonState: Store<ComparisonState | undefined> = externalData.mapD(external => {
|
||||
let comparisonState: Store<ComparisonState | undefined> = externalData.mapD((external) => {
|
||||
if (external["success"]) {
|
||||
return new ComparisonState(tags, external["success"])
|
||||
}
|
||||
return undefined
|
||||
})
|
||||
let unknownImages = comparisonState.bindD(ct => ct.unknownImages)
|
||||
let knownImages = comparisonState.bindD(ct => ct.knownImages)
|
||||
let propertyKeysExternal = comparisonState.mapD(ct => ct.propertyKeysExternal)
|
||||
let hasDifferencesAtStart = comparisonState.mapD(ct => ct.hasDifferencesAtStart)
|
||||
|
||||
let unknownImages = comparisonState.bindD((ct) => ct.unknownImages)
|
||||
let knownImages = comparisonState.bindD((ct) => ct.knownImages)
|
||||
let propertyKeysExternal = comparisonState.mapD((ct) => ct.propertyKeysExternal)
|
||||
let hasDifferencesAtStart = comparisonState.mapD((ct) => ct.hasDifferencesAtStart)
|
||||
</script>
|
||||
|
||||
{#if !$sourceUrl}
|
||||
|
|
@ -50,7 +49,7 @@
|
|||
{:else if $externalData === undefined}
|
||||
<Loading />
|
||||
{:else if $externalData["error"] !== undefined}
|
||||
<div class="subtle italic low-interaction p-2 px-4 rounded">
|
||||
<div class="subtle low-interaction rounded p-2 px-4 italic">
|
||||
<Tr t={Translations.t.external.error} />
|
||||
</div>
|
||||
{:else if $propertyKeysExternal.length === 0 && $knownImages.size + $unknownImages.length === 0}
|
||||
|
|
@ -62,7 +61,7 @@
|
|||
{:else if $comparisonState !== undefined}
|
||||
<AccordionSingle expanded={!collapsed}>
|
||||
<span slot="header" class="flex">
|
||||
<GlobeAlt class="w-6 h-6" />
|
||||
<GlobeAlt class="h-6 w-6" />
|
||||
<Tr t={Translations.t.external.title} />
|
||||
</span>
|
||||
<ComparisonTable
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@
|
|||
|
||||
<Accordion>
|
||||
<AccordionItem open={expanded} paddingDefault="p-0" inactiveClass="text-black">
|
||||
<span slot="header" class="text-base p-2 ">
|
||||
<span slot="header" class="p-2 text-base">
|
||||
<slot name="header" />
|
||||
</span>
|
||||
<div class="low-interaction p-2 rounded-b">
|
||||
<div class="low-interaction rounded-b p-2">
|
||||
<slot />
|
||||
</div>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
lon,
|
||||
lat,
|
||||
allowSpherical: new UIEventSource<boolean>(false),
|
||||
blacklist: AllImageProviders.LoadImagesFor(tags)
|
||||
blacklist: AllImageProviders.LoadImagesFor(tags),
|
||||
},
|
||||
state.indexedFeatures
|
||||
)
|
||||
|
|
@ -39,7 +39,6 @@
|
|||
let allDone = imagesProvider.allDone
|
||||
</script>
|
||||
|
||||
|
||||
<div class="flex justify-between">
|
||||
<h4>
|
||||
<Tr t={Translations.t.image.nearby.title} />
|
||||
|
|
@ -53,9 +52,9 @@
|
|||
{:else}
|
||||
<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} {feature} {layer} {linkable} />
|
||||
</span>
|
||||
<span class="w-fit shrink-0" style="scroll-snap-align: start">
|
||||
<LinkableImage {tags} {image} {state} {feature} {layer} {linkable} />
|
||||
</span>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,8 @@
|
|||
</script>
|
||||
|
||||
<AccordionSingle>
|
||||
<span slot="header" class="text-base p-2">
|
||||
<Tr t={t.seeNearby} />
|
||||
</span>
|
||||
<span slot="header" class="p-2 text-base">
|
||||
<Tr t={t.seeNearby} />
|
||||
</span>
|
||||
<NearbyImages {tags} {state} {lon} {lat} {feature} {linkable} {layer} />
|
||||
</AccordionSingle>
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export default class IconValidator extends Validator {
|
|||
}
|
||||
|
||||
getFeedback(s: string, getCountry, sloppy?: boolean): Translation | undefined {
|
||||
if(Utils.isEmoji(s)){
|
||||
if (Utils.isEmoji(s)) {
|
||||
return undefined
|
||||
}
|
||||
s = this.reformat(s)
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
$: iconItem = icon.icon?.GetRenderValue($tags)?.Subs($tags)?.txt
|
||||
let color = icon.color?.GetRenderValue($tags)?.txt ?? "#000000"
|
||||
$: color = icon.color?.GetRenderValue($tags)?.txt ?? "#000000"
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
{#if iconItem?.startsWith("<")}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
readonly allowMoving: UIEventSource<true | boolean | undefined>
|
||||
readonly allowRotating: UIEventSource<true | boolean | undefined>
|
||||
readonly allowZooming: UIEventSource<true | boolean | undefined>
|
||||
readonly lastClickLocation: Store<undefined | { lon: number; lat: number, mode : "left" | "right" | "middle" }>
|
||||
readonly lastClickLocation: Store<
|
||||
undefined | { lon: number; lat: number; mode: "left" | "right" | "middle" }
|
||||
>
|
||||
readonly minzoom: UIEventSource<number>
|
||||
readonly maxzoom: UIEventSource<number>
|
||||
readonly rotation: UIEventSource<number>
|
||||
|
|
@ -70,7 +72,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
this.location.setData({ ...this.location.data })
|
||||
}
|
||||
this.zoom = state?.zoom ?? new UIEventSource(1)
|
||||
this.minzoom = state?.minzoom ?? new UIEventSource(0.5)// 0.5 is the maplibre minzoom
|
||||
this.minzoom = state?.minzoom ?? new UIEventSource(0.5) // 0.5 is the maplibre minzoom
|
||||
this.maxzoom = state?.maxzoom ?? new UIEventSource(24)
|
||||
this.zoom.addCallbackAndRunD((z) => {
|
||||
if (z < this.minzoom.data) {
|
||||
|
|
@ -92,13 +94,17 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
this.rasterLayer =
|
||||
state?.rasterLayer ?? new UIEventSource<RasterLayerPolygon | undefined>(undefined)
|
||||
|
||||
const lastClickLocation = new UIEventSource<{lat:number,lon:number,mode: "left" | "right" | "middle"}>(undefined)
|
||||
const lastClickLocation = new UIEventSource<{
|
||||
lat: number
|
||||
lon: number
|
||||
mode: "left" | "right" | "middle"
|
||||
}>(undefined)
|
||||
this.lastClickLocation = lastClickLocation
|
||||
const self = this
|
||||
|
||||
new RasterLayerHandler(this._maplibreMap, this.rasterLayer)
|
||||
|
||||
const clickmodes = ["left" , "middle", "right"] as const
|
||||
const clickmodes = ["left", "middle", "right"] as const
|
||||
function handleClick(e: maplibregl.MapMouseEvent, mode?: "left" | "right" | "middle") {
|
||||
if (e.originalEvent["consumed"]) {
|
||||
// Workaround, 'ShowPointLayer' sets this flag
|
||||
|
|
@ -148,8 +154,8 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
})
|
||||
|
||||
map._container.addEventListener("contextmenu", (e) => {
|
||||
const lngLat = map.unproject([e.x, e.y])
|
||||
lastClickLocation.setData({lon: lngLat.lng, lat: lngLat.lat, mode: "right"})
|
||||
const lngLat = map.unproject([e.x, e.y])
|
||||
lastClickLocation.setData({ lon: lngLat.lng, lat: lngLat.lat, mode: "right" })
|
||||
})
|
||||
map.on("dblclick", (e) => {
|
||||
handleClick(e, "left")
|
||||
|
|
@ -675,5 +681,4 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
let _map: Map
|
||||
onMount(() => {
|
||||
|
||||
const { lon, lat } = mapProperties?.location?.data ?? { lon: 0, lat: 0 }
|
||||
|
||||
const rasterLayer: RasterLayerProperties = mapProperties?.rasterLayer?.data?.properties
|
||||
|
|
@ -73,11 +72,10 @@
|
|||
})
|
||||
onDestroy(async () => {
|
||||
await Utils.waitFor(250)
|
||||
try{
|
||||
|
||||
if (_map) _map.remove()
|
||||
map = null
|
||||
}catch (e) {
|
||||
try {
|
||||
if (_map) _map.remove()
|
||||
map = null
|
||||
} catch (e) {
|
||||
console.error("Could not destroy map")
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -8,19 +8,21 @@
|
|||
export let icons: string | { icon: string; color: string }[]
|
||||
|
||||
let iconsParsed: { icon: string; color: string }[]
|
||||
if(typeof icons === "string") {
|
||||
iconsParsed = icons.split(";").map(subspec => {
|
||||
if(subspec.startsWith("http://") || subspec.startsWith("https://")){
|
||||
if (typeof icons === "string") {
|
||||
iconsParsed = icons.split(";").map((subspec) => {
|
||||
if (subspec.startsWith("http://") || subspec.startsWith("https://")) {
|
||||
return {
|
||||
icon: subspec, color: "black"
|
||||
icon: subspec,
|
||||
color: "black",
|
||||
}
|
||||
}
|
||||
const [icon, color] = subspec.split(":")
|
||||
return {
|
||||
icon, color: color ?? "black"
|
||||
icon,
|
||||
color: color ?? "black",
|
||||
}
|
||||
})
|
||||
}else{
|
||||
} else {
|
||||
iconsParsed = icons
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,10 +97,10 @@ class SingleBackgroundHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private tryEnableSafe(): boolean{
|
||||
private tryEnableSafe(): boolean {
|
||||
try {
|
||||
return this.tryEnable()
|
||||
}catch (e) {
|
||||
} catch (e) {
|
||||
console.log("Error: could not enable due to error", e)
|
||||
return false
|
||||
}
|
||||
|
|
@ -119,11 +119,7 @@ class SingleBackgroundHandler {
|
|||
console.debug("Enabling", background.id)
|
||||
let addLayerBeforeId = "transit_pier" // this is the first non-landuse item in the stylesheet, we add the raster layer before the roads but above the landuse
|
||||
if (!map.getLayer(addLayerBeforeId)) {
|
||||
console.warn(
|
||||
"Layer",
|
||||
addLayerBeforeId,
|
||||
"not found"
|
||||
)
|
||||
console.warn("Layer", addLayerBeforeId, "not found")
|
||||
addLayerBeforeId = undefined
|
||||
}
|
||||
if (background.category === "osmbasedmap" || background.category === "map") {
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
deleteConfig.softDeletionTags,
|
||||
{
|
||||
theme: state?.layout?.id ?? "unknown",
|
||||
specialMotivation: deleteReason
|
||||
specialMotivation: deleteReason,
|
||||
},
|
||||
canBeDeleted.data
|
||||
)
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
// no _delete_reason is given, which implies that this is _not_ a deletion but merely a retagging via a nonDeleteMapping
|
||||
actionToTake = new ChangeTagAction(featureId, selectedTags, tags.data, {
|
||||
theme: state?.layout?.id ?? "unkown",
|
||||
changeType: "special-delete"
|
||||
changeType: "special-delete",
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -87,81 +87,74 @@
|
|||
|
||||
<LoginToggle ignoreLoading={true} {state}>
|
||||
{#if $canBeDeleted === false && !hasSoftDeletion}
|
||||
<div class="low-interaction rounded text-sm flex p-2 italic subtle gap-x-1">
|
||||
<div class="low-interaction subtle flex gap-x-1 rounded p-2 text-sm italic">
|
||||
<div class="relative h-fit">
|
||||
<Trash class="w-8 h-8 pb-1" />
|
||||
<Invalid class="absolute bottom-0 right-0 w-5 h-5"/>
|
||||
<Trash class="h-8 w-8 pb-1" />
|
||||
<Invalid class="absolute bottom-0 right-0 h-5 w-5" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
|
||||
<Tr t={t.cannotBeDeleted} />
|
||||
<Tr t={$canBeDeletedReason} />
|
||||
<Tr t={t.useSomethingElse} />
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
|
||||
|
||||
<AccordionSingle>
|
||||
<span slot="header" class="flex">
|
||||
|
||||
<TrashIcon class="h-6 w-6" />
|
||||
<Tr t={t.delete} />
|
||||
<TrashIcon class="h-6 w-6" />
|
||||
<Tr t={t.delete} />
|
||||
</span>
|
||||
<span>
|
||||
{#if currentState === "confirm"}
|
||||
<TagRenderingQuestion
|
||||
bind:selectedTags
|
||||
clss=""
|
||||
{tags}
|
||||
config={deleteConfig.constructTagRendering()}
|
||||
{state}
|
||||
selectedElement={feature}
|
||||
{layer}
|
||||
>
|
||||
<button
|
||||
slot="save-button"
|
||||
on:click={onDelete}
|
||||
class={twJoin(
|
||||
selectedTags === undefined && "disabled",
|
||||
"primary flex items-center bg-red-600"
|
||||
)}
|
||||
>
|
||||
<TrashIcon
|
||||
class={twJoin(
|
||||
"ml-1 mr-2 h-6 w-6 rounded-full p-1",
|
||||
selectedTags !== undefined && "bg-red-600"
|
||||
)}
|
||||
/>
|
||||
<Tr t={t.delete} />
|
||||
</button>
|
||||
{#if currentState === "confirm"}
|
||||
<TagRenderingQuestion
|
||||
bind:selectedTags
|
||||
clss=""
|
||||
{tags}
|
||||
config={deleteConfig.constructTagRendering()}
|
||||
{state}
|
||||
selectedElement={feature}
|
||||
{layer}
|
||||
>
|
||||
<button
|
||||
slot="save-button"
|
||||
on:click={onDelete}
|
||||
class={twJoin(
|
||||
selectedTags === undefined && "disabled",
|
||||
"primary flex items-center bg-red-600"
|
||||
)}
|
||||
>
|
||||
<TrashIcon
|
||||
class={twJoin(
|
||||
"ml-1 mr-2 h-6 w-6 rounded-full p-1",
|
||||
selectedTags !== undefined && "bg-red-600"
|
||||
)}
|
||||
/>
|
||||
<Tr t={t.delete} />
|
||||
</button>
|
||||
|
||||
<div slot="under-buttons" class="subtle italic">
|
||||
{#if selectedTags !== undefined}
|
||||
{#if canBeDeleted && isHardDelete}
|
||||
<!-- This is a hard delete - explain that this is a hard delete...-->
|
||||
<Tr t={t.explanations.hardDelete} />
|
||||
{:else}
|
||||
<!-- This is a soft deletion: we explain _why_ the deletion is soft -->
|
||||
<Tr t={t.explanations.softDelete.Subs({ reason: $canBeDeletedReason })} />
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</TagRenderingQuestion>
|
||||
{:else if currentState === "applying"}
|
||||
<Loading />
|
||||
{:else}
|
||||
<!-- currentState === 'deleted' -->
|
||||
|
||||
<div slot="under-buttons" class="italic subtle">
|
||||
{#if selectedTags !== undefined}
|
||||
{#if canBeDeleted && isHardDelete}
|
||||
<!-- This is a hard delete - explain that this is a hard delete...-->
|
||||
<Tr t={t.explanations.hardDelete} />
|
||||
{:else}
|
||||
<!-- This is a soft deletion: we explain _why_ the deletion is soft -->
|
||||
<Tr t={t.explanations.softDelete.Subs({ reason: $canBeDeletedReason })} />
|
||||
{/if}
|
||||
<div class="low-interaction flex">
|
||||
<TrashIcon class="h-6 w-6" />
|
||||
<Tr t={t.isDeleted} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</TagRenderingQuestion>
|
||||
{:else if currentState === "applying"}
|
||||
<Loading />
|
||||
{:else}
|
||||
<!-- currentState === 'deleted' -->
|
||||
|
||||
<div class="low-interaction flex">
|
||||
<TrashIcon class="h-6 w-6" />
|
||||
<Tr t={t.isDeleted} />
|
||||
</div>
|
||||
{/if}
|
||||
</span>
|
||||
</AccordionSingle>
|
||||
|
||||
{/if}
|
||||
|
||||
</LoginToggle>
|
||||
|
|
|
|||
|
|
@ -26,23 +26,22 @@
|
|||
<LoginToggle ignoreLoading={true} {state}>
|
||||
{#if $isFavourite}
|
||||
<div class="flex h-fit items-start">
|
||||
<button class="w-full" on:click={() => markFavourite(false)}>
|
||||
<HeartSolidIcon class="mr-2 w-16 shrink-0" on:click={() => markFavourite(false)} />
|
||||
<div class="flex flex-col items-start">
|
||||
<button class="w-full" on:click={() => markFavourite(false)}>
|
||||
<HeartSolidIcon class="mr-2 w-16 shrink-0" on:click={() => markFavourite(false)} />
|
||||
<div class="flex flex-col items-start">
|
||||
<Tr t={t.button.unmark} />
|
||||
<Tr cls="normal-font subtle" t={t.button.unmarkNotDeleted} />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<Tr cls="font-bold thanks m-2 p-2 block" t={t.button.isFavourite} />
|
||||
{:else}
|
||||
<button class="w-full" on:click={() => markFavourite(true)}>
|
||||
<HeartOutlineIcon class="mr-2 w-16 shrink-0" on:click={() => markFavourite(true)} />
|
||||
<div class="flex w-full flex-col items-start">
|
||||
|
||||
<Tr t={t.button.markAsFavouriteTitle} />
|
||||
<Tr cls="normal-font subtle" t={t.button.markDescription} />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<Tr cls="font-bold thanks m-2 p-2 block" t={t.button.isFavourite} />
|
||||
{:else}
|
||||
<button class="w-full" on:click={() => markFavourite(true)}>
|
||||
<HeartOutlineIcon class="mr-2 w-16 shrink-0" on:click={() => markFavourite(true)} />
|
||||
<div class="flex w-full flex-col items-start">
|
||||
<Tr t={t.button.markAsFavouriteTitle} />
|
||||
<Tr cls="normal-font subtle" t={t.button.markDescription} />
|
||||
</div>
|
||||
</button>
|
||||
{/if}
|
||||
</LoginToggle>
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@
|
|||
location: new UIEventSource({ lon, lat }),
|
||||
minzoom: new UIEventSource($reason.minZoom),
|
||||
rasterLayer: state.mapProperties.rasterLayer,
|
||||
zoom: new UIEventSource($reason?.startZoom ?? 16)
|
||||
zoom: new UIEventSource($reason?.startZoom ?? 16),
|
||||
}
|
||||
}
|
||||
|
||||
let moveWizardState = new MoveWizardState(id, layer.allowMove, state)
|
||||
if(moveWizardState.reasons.length === 1){
|
||||
if (moveWizardState.reasons.length === 1) {
|
||||
reason.setData(moveWizardState.reasons[0])
|
||||
}
|
||||
let notAllowed = moveWizardState.moveDisallowedReason
|
||||
|
|
@ -78,8 +78,8 @@
|
|||
/>
|
||||
<Tr t={Translations.T(moveWizardState.reasons[0].invitingText)} />
|
||||
{:else}
|
||||
<Move class="h-6 w-6" />
|
||||
<Tr t={t.inviteToMove.generic} />
|
||||
<Move class="h-6 w-6" />
|
||||
<Tr t={t.inviteToMove.generic} />
|
||||
{/if}
|
||||
</span>
|
||||
<span class="flex flex-col p-2">
|
||||
|
|
@ -88,9 +88,9 @@
|
|||
{#each moveWizardState.reasons as reasonSpec}
|
||||
<button
|
||||
on:click={() => {
|
||||
reason.setData(reasonSpec)
|
||||
currentStep = "pick_location"
|
||||
}}
|
||||
reason.setData(reasonSpec)
|
||||
currentStep = "pick_location"
|
||||
}}
|
||||
>
|
||||
<ToSvelte construct={reasonSpec.icon.SetClass("w-16 h-16 pr-2")} />
|
||||
<Tr t={Translations.T(reasonSpec.text)} />
|
||||
|
|
@ -115,15 +115,15 @@
|
|||
<div class="flex flex-wrap">
|
||||
<If
|
||||
condition={currentMapProperties.zoom.mapD(
|
||||
(zoom) => zoom >= Constants.minZoomLevelToAddNewPoint
|
||||
)}
|
||||
(zoom) => zoom >= Constants.minZoomLevelToAddNewPoint
|
||||
)}
|
||||
>
|
||||
<button
|
||||
class="primary w-full"
|
||||
class="primary w-full"
|
||||
on:click={() => {
|
||||
moveWizardState.moveFeature(newLocation.data, reason.data, featureToMove)
|
||||
currentStep = "moved"
|
||||
}}
|
||||
moveWizardState.moveFeature(newLocation.data, reason.data, featureToMove)
|
||||
currentStep = "moved"
|
||||
}}
|
||||
>
|
||||
<Tr t={t.confirmMove} />
|
||||
</button>
|
||||
|
|
@ -133,19 +133,24 @@
|
|||
</div>
|
||||
</If>
|
||||
{#if moveWizardState.reasons.length > 1}
|
||||
<button class="w-full" on:click={() => {currentStep = "reason"}}>
|
||||
<ChevronLeft class="w-6 h-6" />
|
||||
<button
|
||||
class="w-full"
|
||||
on:click={() => {
|
||||
currentStep = "reason"
|
||||
}}
|
||||
>
|
||||
<ChevronLeft class="h-6 w-6" />
|
||||
<Tr t={t.cancel} />
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{:else if currentStep === "moved"}
|
||||
<div class="flex flex-col">
|
||||
<Tr cls="thanks" t={t.pointIsMoved} />
|
||||
<button
|
||||
on:click={() => {
|
||||
currentStep = "reason"
|
||||
}}
|
||||
currentStep = "reason"
|
||||
}}
|
||||
>
|
||||
<Move class="h-6 w-6 pr-2" />
|
||||
<Tr t={t.inviteToMoveAgain} />
|
||||
|
|
|
|||
|
|
@ -134,16 +134,15 @@ export class MoveWizardState {
|
|||
// This is a new point. Check if it was snapped to an existing way due to the '_referencing_ways'-tag
|
||||
const store = this._state.featureProperties.getStore(id)
|
||||
store?.addCallbackAndRunD((tags) => {
|
||||
try{
|
||||
|
||||
try {
|
||||
if (tags._referencing_ways !== undefined && tags._referencing_ways !== "[]") {
|
||||
console.log("Got referencing ways according to the tags")
|
||||
this.moveDisallowedReason.setData(t.partOfAWay)
|
||||
return true // unregister
|
||||
}
|
||||
}catch (e) {
|
||||
console.error("Could not get '_referencing_ways'-attribute of tags due to", e)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Could not get '_referencing_ways'-attribute of tags due to", e)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,13 +11,12 @@
|
|||
export let layer: LayerConfig
|
||||
export let text: string
|
||||
export let cssClasses: string = ""
|
||||
let knowableRenderings = layer.tagRenderings.filter(tr => tr.question !== undefined)
|
||||
let hasKnownQuestion = tags.mapD(t => knowableRenderings.some(tr => tr.IsKnown(t)))
|
||||
|
||||
let knowableRenderings = layer.tagRenderings.filter((tr) => tr.question !== undefined)
|
||||
let hasKnownQuestion = tags.mapD((t) => knowableRenderings.some((tr) => tr.IsKnown(t)))
|
||||
</script>
|
||||
|
||||
{#if !$hasKnownQuestion}
|
||||
<span class={cssClasses}>
|
||||
{text}
|
||||
{text}
|
||||
</span>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@
|
|||
|
||||
<button
|
||||
on:click
|
||||
class="h-8 w-8 shrink-0 self-start rounded-full p-1 as-link"
|
||||
class="as-link h-8 w-8 shrink-0 self-start rounded-full p-1"
|
||||
aria-labelledby={arialabel === undefined ? ariaLabelledBy : undefined}
|
||||
use:ariaLabel={arialabel}
|
||||
>
|
||||
<Pencil class="h-4 w-4 hover-alert" />
|
||||
<Pencil class="hover-alert h-4 w-4" />
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -49,7 +49,9 @@
|
|||
function createVisualisation(specpart: Exclude<RenderingSpecification, string>): BaseUIElement {
|
||||
{
|
||||
try {
|
||||
return specpart.func.constr(state, tags, specpart.args, feature, layer)?.SetClass(specpart.style)
|
||||
return specpart.func
|
||||
.constr(state, tags, specpart.args, feature, layer)
|
||||
?.SetClass(specpart.style)
|
||||
} catch (e) {
|
||||
console.error(
|
||||
"Could not construct a special visualisation with specification",
|
||||
|
|
|
|||
|
|
@ -28,12 +28,18 @@
|
|||
</script>
|
||||
|
||||
{#if config !== undefined && (config?.condition === undefined || config.condition.matchesProperties($tags))}
|
||||
<div {id} class={twMerge("link-underline flex flex-col w-full", extraClasses)}>
|
||||
<div {id} class={twMerge("link-underline flex w-full flex-col", extraClasses)}>
|
||||
{#if $trs.length === 1}
|
||||
<TagRenderingMapping mapping={$trs[0]} {tags} {state} {selectedElement} {layer}
|
||||
clss={config?.classes?.join(" ") ?? ""} />
|
||||
<TagRenderingMapping
|
||||
mapping={$trs[0]}
|
||||
{tags}
|
||||
{state}
|
||||
{selectedElement}
|
||||
{layer}
|
||||
clss={config?.classes?.join(" ") ?? ""}
|
||||
/>
|
||||
{/if}
|
||||
{#if $trs.length > 1}
|
||||
{#if $trs.length > 1}
|
||||
<ul>
|
||||
{#each $trs as mapping}
|
||||
<li>
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@
|
|||
Utils.focusOnFocusableChild(htmlElem)
|
||||
} else {
|
||||
htmlElem.classList.remove("focus")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,14 +31,19 @@
|
|||
| "large-height"
|
||||
| string
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
{#if mapping.icon !== undefined}
|
||||
<div class="inline-flex items-center">
|
||||
<Marker
|
||||
icons={mapping.icon}
|
||||
size={twJoin(`mapping-icon-${mapping.iconClass ?? "small"}-height mapping-icon-${mapping.iconClass ?? "small"}-width`, "mr-2", "shrink-0 mx-2")}
|
||||
size={twJoin(
|
||||
`mapping-icon-${mapping.iconClass ?? "small"}-height mapping-icon-${
|
||||
mapping.iconClass ?? "small"
|
||||
}-width`,
|
||||
"mr-2",
|
||||
"shrink-0 mx-2"
|
||||
)}
|
||||
clss={`mapping-icon-${mapping.iconClass ?? "small"}`}
|
||||
/>
|
||||
<SpecialTranslation t={mapping.then} {tags} {state} {layer} feature={selectedElement} {clss} />
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@
|
|||
</script>
|
||||
|
||||
{#if question !== undefined}
|
||||
<div class={clss} >
|
||||
<div class={clss}>
|
||||
<form
|
||||
class="relative flex flex-col overflow-y-auto px-2"
|
||||
style="max-height: 75vh"
|
||||
|
|
@ -326,20 +326,19 @@
|
|||
|
||||
{#if config.questionhint}
|
||||
<span class="italic">
|
||||
|
||||
{#if config.questionHintIsMd}
|
||||
<Markdown srcWritable={config.questionhint.current} />
|
||||
{:else}
|
||||
<div class="max-h-60 overflow-y-auto">
|
||||
<SpecialTranslation
|
||||
t={config.questionhint}
|
||||
{tags}
|
||||
{state}
|
||||
{layer}
|
||||
feature={selectedElement}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{#if config.questionHintIsMd}
|
||||
<Markdown srcWritable={config.questionhint.current} />
|
||||
{:else}
|
||||
<div class="max-h-60 overflow-y-auto">
|
||||
<SpecialTranslation
|
||||
t={config.questionhint}
|
||||
{tags}
|
||||
{state}
|
||||
{layer}
|
||||
feature={selectedElement}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</span>
|
||||
{/if}
|
||||
</legend>
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@
|
|||
<SingleReview {review} />
|
||||
{/each}
|
||||
{:else}
|
||||
<div class="subtle italic m-2">
|
||||
<Tr t={Translations.t.reviews.no_reviews_yet} />
|
||||
<div class="subtle m-2 italic">
|
||||
<Tr t={Translations.t.reviews.no_reviews_yet} />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="flex justify-end">
|
||||
|
|
|
|||
|
|
@ -80,7 +80,12 @@
|
|||
|
||||
<LoginToggle {state}>
|
||||
<div class="m-1 flex flex-col">
|
||||
<FileSelector cls="button w-fit" accept="application/json" multiple={false} on:submit={(e) => onImport(e.detail)}>
|
||||
<FileSelector
|
||||
cls="button w-fit"
|
||||
accept="application/json"
|
||||
multiple={false}
|
||||
on:submit={(e) => onImport(e.detail)}
|
||||
>
|
||||
{text}
|
||||
</FileSelector>
|
||||
{#if error}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
{:else}
|
||||
<button
|
||||
use:ariaLabel={Translations.t.reviews.rate.Subs({ n: i + 1 })}
|
||||
class="rounded-full as-link"
|
||||
class="as-link rounded-full"
|
||||
style="padding: 0; border: none;"
|
||||
bind:this={container}
|
||||
on:click={(e) => {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -27,13 +27,13 @@
|
|||
Bug: Region received empty list as configuration at {path.join(".")}
|
||||
{:else if title}
|
||||
<AccordionSingle>
|
||||
<div slot="header">{title}</div>
|
||||
<div class="flex w-full flex-col gap-y-1 border border-black pl-2">
|
||||
<slot name="description" />
|
||||
{#each configsFiltered as config}
|
||||
<SchemaBasedInput {state} path={config.path} schema={config} />
|
||||
{/each}
|
||||
</div>
|
||||
<div slot="header">{title}</div>
|
||||
<div class="flex w-full flex-col gap-y-1 border border-black pl-2">
|
||||
<slot name="description" />
|
||||
{#each configsFiltered as config}
|
||||
<SchemaBasedInput {state} path={config.path} schema={config} />
|
||||
{/each}
|
||||
</div>
|
||||
</AccordionSingle>
|
||||
{:else}
|
||||
<div class="flex w-full flex-col gap-y-1 pl-2">
|
||||
|
|
|
|||
|
|
@ -143,63 +143,64 @@
|
|||
{/if}
|
||||
</span>
|
||||
<div class="normal-background p-2">
|
||||
|
||||
{#if isTagRenderingBlock}
|
||||
<QuestionPreview {state} path={fusePath(i, [])} {schema}>
|
||||
<button
|
||||
on:click={() => {
|
||||
del(i)
|
||||
}}
|
||||
>
|
||||
<TrashIcon class="h-4 w-4" />
|
||||
Delete this question
|
||||
</button>
|
||||
|
||||
{#if i > 0}
|
||||
{#if isTagRenderingBlock}
|
||||
<QuestionPreview {state} path={fusePath(i, [])} {schema}>
|
||||
<button
|
||||
on:click={() => {
|
||||
moveTo(i, 0)
|
||||
del(i)
|
||||
}}
|
||||
>
|
||||
Move to front
|
||||
<TrashIcon class="h-4 w-4" />
|
||||
Delete this question
|
||||
</button>
|
||||
|
||||
<button
|
||||
on:click={() => {
|
||||
swap(i, i - 1)
|
||||
}}
|
||||
>
|
||||
Move up
|
||||
</button>
|
||||
{/if}
|
||||
{#if i + 1 < $currentValue.length}
|
||||
<button
|
||||
on:click={() => {
|
||||
swap(i, i + 1)
|
||||
}}
|
||||
>
|
||||
Move down
|
||||
</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
moveTo(i, $currentValue.length - 1)
|
||||
}}
|
||||
>
|
||||
Move to back
|
||||
</button>
|
||||
{/if}
|
||||
</QuestionPreview>
|
||||
{:else if schema.hints.types}
|
||||
<SchemaBasedMultiType {state} path={fusePath(i, [])} schema={schemaForMultitype()} />
|
||||
{:else}
|
||||
{#each subparts as subpart}
|
||||
<SchemaBasedInput {state} path={fusePath(i, [subpart.path.at(-1)])} schema={subpart} />
|
||||
{/each}
|
||||
{/if}
|
||||
{#if i > 0}
|
||||
<button
|
||||
on:click={() => {
|
||||
moveTo(i, 0)
|
||||
}}
|
||||
>
|
||||
Move to front
|
||||
</button>
|
||||
|
||||
<button
|
||||
on:click={() => {
|
||||
swap(i, i - 1)
|
||||
}}
|
||||
>
|
||||
Move up
|
||||
</button>
|
||||
{/if}
|
||||
{#if i + 1 < $currentValue.length}
|
||||
<button
|
||||
on:click={() => {
|
||||
swap(i, i + 1)
|
||||
}}
|
||||
>
|
||||
Move down
|
||||
</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
moveTo(i, $currentValue.length - 1)
|
||||
}}
|
||||
>
|
||||
Move to back
|
||||
</button>
|
||||
{/if}
|
||||
</QuestionPreview>
|
||||
{:else if schema.hints.types}
|
||||
<SchemaBasedMultiType {state} path={fusePath(i, [])} schema={schemaForMultitype()} />
|
||||
{:else}
|
||||
{#each subparts as subpart}
|
||||
<SchemaBasedInput
|
||||
{state}
|
||||
path={fusePath(i, [subpart.path.at(-1)])}
|
||||
schema={subpart}
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
</AccordionSingle>
|
||||
|
||||
{/each}
|
||||
{/if}
|
||||
<div class="flex">
|
||||
|
|
|
|||
|
|
@ -3,11 +3,9 @@ import StudioGUI from "./StudioGUI.svelte"
|
|||
|
||||
export default class StudioGui {
|
||||
public setup() {
|
||||
new StudioGUI(
|
||||
{
|
||||
target: document.getElementById("main")
|
||||
}
|
||||
)
|
||||
new StudioGUI({
|
||||
target: document.getElementById("main"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
</script>
|
||||
|
||||
<main>
|
||||
<div class="flex-col flex gap-y-2">
|
||||
<div class="flex flex-col gap-y-2">
|
||||
<h1>Stylesheet testing grounds</h1>
|
||||
|
||||
This document exists to explore the style hierarchy.
|
||||
|
|
@ -65,9 +65,7 @@
|
|||
<Community class="h-6 w-6" />
|
||||
Secondary action (disabled)
|
||||
</button>
|
||||
<button class="as-link">
|
||||
Mimick link
|
||||
</button>
|
||||
<button class="as-link">Mimick link</button>
|
||||
</div>
|
||||
<input type="text" />
|
||||
|
||||
|
|
|
|||
|
|
@ -255,11 +255,11 @@
|
|||
htmlElem={openMapButton}
|
||||
>
|
||||
<div class="m-0.5 mx-1 flex cursor-pointer items-center max-[480px]:w-full sm:mx-1 md:mx-2">
|
||||
<Marker icons={layout.icon} size="h-4 w-4 md:h-8 md:w-8 mr-0.5 sm:mr-1 md:mr-2" ></Marker>
|
||||
<Marker icons={layout.icon} size="h-4 w-4 md:h-8 md:w-8 mr-0.5 sm:mr-1 md:mr-2" />
|
||||
<b class="mr-1">
|
||||
<Tr t={layout.title} />
|
||||
</b>
|
||||
<ChevronRight class="w-4 h-4"/>
|
||||
<ChevronRight class="h-4 w-4" />
|
||||
</div>
|
||||
</MapControlButton>
|
||||
<MapControlButton
|
||||
|
|
@ -347,13 +347,16 @@
|
|||
/>
|
||||
</If>
|
||||
<a
|
||||
class="self-center bg-black-transparent pointer-events-auto h-fit max-h-12 cursor-pointer self-end overflow-hidden rounded-2xl px-1 ml-1 text-white opacity-50 hover:opacity-100"
|
||||
class="bg-black-transparent pointer-events-auto ml-1 h-fit max-h-12 cursor-pointer self-end self-center overflow-hidden rounded-2xl px-1 text-white opacity-50 hover:opacity-100"
|
||||
on:click={() => {
|
||||
state.guistate.themeViewTab.setData("copyright")
|
||||
state.guistate.themeIsOpened.setData(true)
|
||||
}}
|
||||
>
|
||||
© <span class="hidden sm:inline sm:pr-2 "> OpenStreetMap<span class="hidden md:inline md:pr-2 w-24">, {rasterLayerName}</span></span>
|
||||
© <span class="hidden sm:inline sm:pr-2">
|
||||
OpenStreetMap
|
||||
<span class="hidden w-24 md:inline md:pr-2">, {rasterLayerName}</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -485,7 +488,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex" slot="title0">
|
||||
<Marker icons={layout.icon} size="h-4 w-4"/>
|
||||
<Marker icons={layout.icon} size="h-4 w-4" />
|
||||
|
||||
<Tr t={layout.title} />
|
||||
</div>
|
||||
|
|
@ -583,9 +586,19 @@
|
|||
<Tr t={Translations.t.general.attribution.openIssueTracker} />
|
||||
</a>
|
||||
|
||||
<a class="flex" href={"https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Themes/"+layout.id+".md"} target="_blank">
|
||||
<DocumentChartBar class="h-6 w-6"/>
|
||||
<Tr t={Translations.t.general.attribution.openThemeDocumentation.Subs({name: layout.title})}/>
|
||||
<a
|
||||
class="flex"
|
||||
href={"https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Themes/" +
|
||||
layout.id +
|
||||
".md"}
|
||||
target="_blank"
|
||||
>
|
||||
<DocumentChartBar class="h-6 w-6" />
|
||||
<Tr
|
||||
t={Translations.t.general.attribution.openThemeDocumentation.Subs({
|
||||
name: layout.title,
|
||||
})}
|
||||
/>
|
||||
</a>
|
||||
|
||||
<a class="flex" href="https://en.osm.town/@MapComplete" target="_blank">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue