Chore: housekeeping

This commit is contained in:
Pieter Vander Vennet 2024-06-20 04:21:29 +02:00
parent 8178c5607b
commit cd0d275965
73 changed files with 2105 additions and 2219 deletions

View file

@ -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} />

View file

@ -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>

View file

@ -38,8 +38,6 @@
function getStateFor(option: FilterConfig): UIEventSource<number | string> {
return filteredLayer.appliedFilters.get(option.id)
}
</script>
{#if filteredLayer.layerDef.name}

View file

@ -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(

View file

@ -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)
)

View file

@ -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">

View file

@ -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>

View file

@ -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)}

View file

@ -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
}
}

View file

@ -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}

View file

@ -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

View file

@ -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>

View file

@ -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}

View file

@ -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>

View file

@ -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)

View file

@ -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("<")}

View file

@ -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 {
}
}
}
}

View file

@ -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")
}
})

View file

@ -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
}

View file

@ -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") {

View file

@ -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>

View file

@ -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>

View file

@ -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} />

View file

@ -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)
}
})
}
}

View file

@ -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}

View file

@ -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>

View file

@ -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",

View file

@ -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>

View file

@ -66,7 +66,6 @@
Utils.focusOnFocusableChild(htmlElem)
} else {
htmlElem.classList.remove("focus")
}
}

View file

@ -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} />

View file

@ -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>

View file

@ -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">

View file

@ -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}

View file

@ -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

View file

@ -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">

View file

@ -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">

View file

@ -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"),
})
}
}

View file

@ -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" />

View file

@ -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">