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:
sucupira
2026-07-16 21:58:32 -04:00
parent e41a508d77
commit d52034712d
13 changed files with 875 additions and 24 deletions
+17 -1
View File
@@ -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;
+44 -2
View File
@@ -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;