fix(app): proxy photo opaque + EXIF strip + WebP (C4), radius_eff communes immenses (A1), variante no-frwiki (A3), cache wiki 24h
This commit is contained in:
@@ -7,10 +7,26 @@
|
||||
}
|
||||
|
||||
let { photo, revealed = false }: Props = $props();
|
||||
|
||||
// Proxy /api/photo : 3 largeurs disponibles, le navigateur choisit (C4).
|
||||
const srcset = $derived(
|
||||
photo.srcset
|
||||
? Object.entries(photo.srcset)
|
||||
.map(([w, u]) => `${u} ${w}w`)
|
||||
.join(', ')
|
||||
: undefined
|
||||
);
|
||||
</script>
|
||||
|
||||
<figure class="photo-panel">
|
||||
<img src={photo.url} alt={photo.alt} loading="lazy" decoding="async" />
|
||||
<img
|
||||
src={photo.url}
|
||||
{srcset}
|
||||
sizes="(min-width: 768px) 50vw, 100vw"
|
||||
alt={photo.alt}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
{#if revealed}
|
||||
<figcaption>{photo.credit}</figcaption>
|
||||
{/if}
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
</p>
|
||||
{#if result.distanceKm !== null}
|
||||
<p class="distance">{t().resultat.distance} : {result.distanceKm} {t().resultat.km}</p>
|
||||
{#if result.radiusEffKm !== null}
|
||||
<p class="rayon">{t().resultat.rayonScore} : {result.radiusEffKm} {t().resultat.km}</p>
|
||||
{/if}
|
||||
{/if}
|
||||
<p class="lieu">
|
||||
<strong>{result.nom}</strong>
|
||||
@@ -91,6 +94,12 @@
|
||||
color: var(--oki-encre-doux);
|
||||
}
|
||||
|
||||
.rayon {
|
||||
margin: 0.1rem 0 0;
|
||||
font-size: 0.82rem;
|
||||
color: var(--oki-encre-doux);
|
||||
}
|
||||
|
||||
.credit-photo {
|
||||
margin: 0;
|
||||
font-size: 0.72rem;
|
||||
|
||||
@@ -12,8 +12,11 @@
|
||||
|
||||
let { nom, wikidataId, tonPositif, tonNeutre }: Props = $props();
|
||||
|
||||
// undefined = chargement, null = pas de fiche (Cas B), WikiSummary = Cas A
|
||||
// undefined = chargement, null = pas de fiche, WikiSummary = Cas A
|
||||
let wiki = $state<WikiSummary | null | undefined>(undefined);
|
||||
// Cas intermédiaire (audit A3) : QID présent, fiche Wikidata existante,
|
||||
// mais pas d'article Wikipédia en français (404 {reason:'no-frwiki'}).
|
||||
let sansFrwiki = $state(false);
|
||||
|
||||
onMount(() => {
|
||||
if (!wikidataId) {
|
||||
@@ -25,7 +28,19 @@
|
||||
try {
|
||||
const res = await fetch(`/api/wiki/${wikidataId}`);
|
||||
if (annule) return;
|
||||
wiki = res.ok ? ((await res.json()) as WikiSummary) : null;
|
||||
if (res.ok) {
|
||||
wiki = (await res.json()) as WikiSummary;
|
||||
} else {
|
||||
if (res.status === 404) {
|
||||
try {
|
||||
const corps = (await res.json()) as { reason?: string };
|
||||
sansFrwiki = corps.reason === 'no-frwiki';
|
||||
} catch {
|
||||
sansFrwiki = false;
|
||||
}
|
||||
}
|
||||
wiki = null;
|
||||
}
|
||||
} catch {
|
||||
if (!annule) wiki = null;
|
||||
}
|
||||
@@ -38,6 +53,7 @@
|
||||
const lienContribution = $derived(
|
||||
`https://fr.wikipedia.org/w/index.php?search=${encodeURIComponent(nom)}&title=Sp%C3%A9cial:Recherche`
|
||||
);
|
||||
const lienWikidata = $derived(`https://www.wikidata.org/wiki/${wikidataId}`);
|
||||
</script>
|
||||
|
||||
{#if wiki === undefined}
|
||||
@@ -61,6 +77,20 @@
|
||||
{t().resultat.lireWiki} ↗
|
||||
</a>
|
||||
</article>
|
||||
{:else if sansFrwiki}
|
||||
<!-- Variante Cas B : fiche Wikidata OK mais pas d'article FR — appel à traduire/créer -->
|
||||
<article class="panneau cas-b">
|
||||
<h2><span class="icone" aria-hidden="true">◌</span> {t().lacuneFr.titre}</h2>
|
||||
<p class="texte">{t().lacuneFr.texte}</p>
|
||||
<div class="ctas">
|
||||
<a class="btn btn-cta" href={lienContribution} target="_blank" rel="noopener noreferrer">
|
||||
{t().lacuneFr.cta} ↗
|
||||
</a>
|
||||
<a class="lien-wikidata" href={lienWikidata} target="_blank" rel="noopener noreferrer">
|
||||
{t().lacuneFr.ctaWikidata} ↗
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
{:else}
|
||||
<!-- Cas B : lacune documentaire — panneau volontairement distinct (Peak-End) -->
|
||||
<article class="panneau cas-b">
|
||||
@@ -169,6 +199,18 @@
|
||||
background: #b98a2f;
|
||||
}
|
||||
|
||||
.ctas {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.9rem;
|
||||
}
|
||||
|
||||
.lien-wikidata {
|
||||
color: var(--oki-bleu);
|
||||
font-weight: 650;
|
||||
}
|
||||
|
||||
.guide {
|
||||
margin: 0.8rem 0 0;
|
||||
font-size: 0.88rem;
|
||||
|
||||
Reference in New Issue
Block a user