From 900bf4eb061529e8768f3ed8cccf6398d36aacf6 Mon Sep 17 00:00:00 2001 From: Corey Blais Date: Thu, 26 Mar 2026 17:19:01 -0400 Subject: [PATCH] Fixing image url --- frontend/src/pages/Home.tsx | 56 +++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/Home.tsx b/frontend/src/pages/Home.tsx index c64accb..42bf0ed 100644 --- a/frontend/src/pages/Home.tsx +++ b/frontend/src/pages/Home.tsx @@ -189,6 +189,33 @@ const getCategorySilhouette = (category: string) => { return silhouettes[normalized] ?? silhouettes.other; }; +const resolveFirearmImageUrl = (imageUrl: string | null | undefined) => { + const trimmed = imageUrl?.trim(); + + if (!trimmed) { + return null; + } + + const normalized = trimmed.startsWith('//') ? `https:${trimmed}` : trimmed; + + try { + const parsed = new URL(normalized); + + if (!['http:', 'https:'].includes(parsed.protocol)) { + return null; + } + + if (parsed.hostname === 'commons.wikimedia.org' && parsed.pathname.startsWith('/wiki/File:')) { + const fileName = parsed.pathname.replace('/wiki/File:', ''); + return `https://commons.wikimedia.org/wiki/Special:FilePath/${fileName}`; + } + + return parsed.toString(); + } catch { + return null; + } +}; + export default function Home() { const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); @@ -206,6 +233,7 @@ export default function Home() { const [newFirearm, setNewFirearm] = useState(emptyFirearmForm); const [showNewFirearmForm, setShowNewFirearmForm] = useState(false); const [selectedFirearmCategory, setSelectedFirearmCategory] = useState(allFirearmCategoriesLabel); + const [failedFirearmImages, setFailedFirearmImages] = useState>({}); const [ammoAdjustments, setAmmoAdjustments] = useState({}); const [ammoPageCaliberIds, setAmmoPageCaliberIds] = useState(() => loadStoredAmmoPageSelection()); const [selectedAmmoCaliberId, setSelectedAmmoCaliberId] = useState(''); @@ -331,6 +359,7 @@ export default function Home() { setFirearmDrafts( Object.fromEntries(payload.firearms.map((firearm) => [firearm.id, buildFirearmForm(firearm)])), ); + setFailedFirearmImages({}); setAmmoAdjustments(buildAmmoAdjustments(payload.ammoInventory)); }; @@ -616,6 +645,18 @@ export default function Home() { }; const handleFirearmChange = (id: string, field: keyof FirearmForm, value: string) => { + if (field === 'imageUrl') { + setFailedFirearmImages((current) => { + if (!current[id]) { + return current; + } + + const next = { ...current }; + delete next[id]; + return next; + }); + } + setFirearmDrafts((current) => ({ ...current, [id]: { @@ -1043,14 +1084,25 @@ export default function Home() { ) : ( filteredFirearms.map((firearm) => { const draft = firearmDrafts[firearm.id] ?? buildFirearmForm(firearm); + const resolvedImageUrl = resolveFirearmImageUrl(draft.imageUrl); + const firearmImageSrc = !failedFirearmImages[firearm.id] && resolvedImageUrl + ? resolvedImageUrl + : getCategorySilhouette(draft.category); return (
{`${firearm.manufacturer} + setFailedFirearmImages((current) => + current[firearm.id] ? current : { ...current, [firearm.id]: true }, + ) + } + src={firearmImageSrc} />