Merge develop

This commit is contained in:
Pieter Vander Vennet 2025-06-18 21:08:26 +02:00
commit 002acd53c9
368 changed files with 19807 additions and 22271 deletions

View file

@ -23,6 +23,8 @@
import ThemeViewState from "../../Models/ThemeViewState"
import Panorama360 from "../../assets/svg/Panorama360.svelte"
import { ExternalLinkIcon } from "@rgossiaux/svelte-heroicons/solid"
import { ExclamationTriangle as TriangleOutline } from "@babeard/svelte-heroicons/outline/ExclamationTriangle"
import LoginToggle from "../Base/LoginToggle.svelte"
export let image: Partial<ProvidedImage> & { id: string; url: string }
let fallbackImage: string = undefined
@ -41,21 +43,55 @@
| Store<Feature<Geometry, HotspotProperties>[]> = []
let loaded = false
let error = false
let notFound = false
let ignoreHidden = false
let isInStrictMode = new UIEventSource(false)
async function detectErrorReason() {
try {
const response = await fetch(
image.url,
{
headers: {
"Accept": "image/avif,image/webp,*/*",
},
},
)
if (response.status === 404) {
notFound = true
}
} catch
(e) {
console.log("Could not load image while trying to remediate", e)
}
}
async function onError() {
Mapillary.isInStrictMode().addCallbackAndRunD(isStrict => {
isInStrictMode.set(isStrict)
return true // unregister
})
await detectErrorReason()
error = true
}
let visitUrl = image.provider?.visitUrl(image)
let showBigPreview = new UIEventSource(false)
onDestroy(
showBigPreview.addCallbackAndRun((shown) => {
state?.guistate?.setPreviewedImage(shown ? image : undefined)
})
}),
)
if (previewedImage) {
onDestroy(
previewedImage.addCallbackAndRun((previewedImage) => {
showBigPreview.set(
previewedImage !== undefined &&
(previewedImage?.id ?? previewedImage?.url) === (image.id ?? image.url)
(previewedImage?.id ?? previewedImage?.url) === (image.id ?? image.url),
)
})
}),
)
}
@ -98,14 +134,36 @@
/>
</div>
</Popup>
{#if image.status !== undefined && image.status !== "ready" && image.status !== "hidden"}
<div class="flex h-full flex-col justify-center p-4">
{#if error}
<div class="h-80 w-60 interactive flex flex-col justify-center items-center p-4 text-center">
{#if notFound}
<div class="alert flex items-center">
<TriangleOutline class="shrink-0 h-8 w-8" />
Not found
</div>
This image is probably incorrect or deleted.
<slot name="not-found-extra" />
{:else}
<div class="alert flex items-center">
<TriangleOutline class="shrink-0 h-8 w-8" />
<Tr t={Translations.t.image.loadingFailed} />
</div>
{#if image.provider.name.toLowerCase() === "mapillary" && $isInStrictMode}
<Tr t={Translations.t.image.mapillaryTrackingProtection} />
{:else if $isInStrictMode}
<Tr t={Translations.t.image.strictProtectionDetected} />
{image.provider.name}
<div class="subtle text-sm mt-8">{image.url}</div>
{/if}
{/if}
</div>
{:else if image.status !== undefined && image.status !== "ready" && image.status !== "hidden"}
<div class="flex h-80 w-60 flex-col justify-center p-4">
<Loading>
<Tr t={Translations.t.image.processing} />
</Loading>
</div>
{:else if image.status !== "hidden"}
{:else if image.status !== "hidden" || ignoreHidden}
<div class="relative shrink-0">
<div
class={"relative w-fit"}
@ -136,9 +194,7 @@
previewedImage?.set(image)
}}
on:error={() => {
if (fallbackImage) {
imgEl.src = fallbackImage
}
onError()
}}
src={image.url}
/>
@ -169,5 +225,11 @@
</div>
</div>
{:else if image.status === "hidden"}
<div class="subtle">This image has been reported</div>
<div class="h-80 w-60 flex flex-col justify-center items-center break-words p-4 text-center">
<TriangleOutline class="w-8 h-8 subtle" />
<Tr t={Translations.t.image.reported} />
<button class="text-sm" on:click={() => ignoreHidden = true}>
<Tr t={Translations.t.image.showAnyway} />
</button>
</div>
{/if}

View file

@ -39,6 +39,8 @@
let reportFreeText = new UIEventSource<string>(undefined)
let reported = new UIEventSource<boolean>(false)
let canBeUnlinked = image.originalAttribute !== undefined
async function requestDeletion() {
if (reportReason.data === "other" && !reportFreeText.data) {
return
@ -63,31 +65,20 @@
}
async function unlink() {
console.log("Unlinking image", image.key, image.id)
if (image.id.length < 10) {
console.error("Suspicious value, not deleting ", image.id)
return
}
// The "key" is the provider key, but not necessarely the actual key that should be reset
// We iterate over all tags. *Every* tag for which the value contains the id will be deleted
const tgs = tags.data
for (const key in tgs) {
if (typeof tgs[key] !== "string" || tgs[key].indexOf(image.id) < 0) {
continue
}
await state?.changes?.applyAction(
new ChangeTagAction(tgs.id, new Tag(key, ""), tgs, {
changeType: "delete-image",
theme: state.theme.id,
})
)
}
const {key} = image.originalAttribute
await state?.changes?.applyAction(
new ChangeTagAction(tags.data.id, new Tag(key, ""), tags.data, {
changeType: "delete-image",
theme: state.theme.id,
})
)
}
const t = Translations.t.image.panoramax
const tu = Translations.t.image.unlink
const placeholder = t.placeholder.current
let showTags = state.userRelatedState?.showTagsB
</script>
<Popup shown={showDeleteDialog}>
@ -103,7 +94,9 @@
{:else if image.provider.name === "panoramax"}
<div class="my-4">
<AccordionSingle noBorder>
<div slot="header" class="flex text-sm">Report inappropriate picture</div>
<div slot="header" class="flex text-sm">
<Tr t={t.requestDeletion}/>
</div>
<div class="interactive flex flex-col p-2">
<h3>
<Tr t={t.title} />
@ -145,6 +138,11 @@
</AccordionSingle>
</div>
{/if}
{#if $showTags}
<div class="subtle line-through">
{image.originalAttribute.key}={image.originalAttribute.value}
</div>
{/if}
</div>
</div>
</div>
@ -169,10 +167,24 @@
<DownloadIcon />
<Tr t={Translations.t.general.download.downloadImage} />
</button>
<button on:click={() => showDeleteDialog.set(true)} class="flex items-center">
<TrashIcon />
<Tr t={tu.button} />
</button>
{#if canBeUnlinked}
<button on:click={() => showDeleteDialog.set(true)} class="flex items-center">
<TrashIcon />
<Tr t={tu.button} />
</button>
{/if}
</svelte:fragment>
<svelte:fragment slot="not-found-extra">
{#if canBeUnlinked}
<button on:click={() => unlink()}>
<Tr t={tu.button} />
</button>
{#if $showTags}
<div class="subtle line-through">
{image.originalAttribute.key}={image.originalAttribute.value}
</div>
{/if}
{/if}
</svelte:fragment>
</AttributedImage>
</div>