From 29ff175e8967c5ee57dce0608127b351baf7bc4b Mon Sep 17 00:00:00 2001 From: webmaster Date: Tue, 3 Nov 2026 23:19:06 +0000 Subject: [PATCH] directory card photo: fetch the JSON envelope, decode the data URI, and bound every request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The endpoint answers 200 application/json with {"Image":"data:image/jpeg;base64,…"} — a JSON envelope, NOT image bytes. An pointed at it never settles: measured on the live page, complete=false · naturalWidth=0 for 20 s, so the fallback never fired and the card showed an empty slot. The card now FETCHES the route, reads `Image` and puts the data URI on an only when it passes the isImageSrc allowlist. - static/expert-image.js: `load(id)` replaces `url(id, rec)`. It fetches the route, reads `Image`, accepts the array shape n8n sometimes returns, and resolves to a usable image source or `null` on ANY failure. EVERY request is bounded by `timeoutMs` (8000): an AbortController is aborted by a setTimeout, the abort rejects the fetch and lands in the same catch that returns null — so a hang becomes the monogram, not an empty box. The timer is cleared on every completion. The decoded URI is cached by id (failures too), so a re-render or a shared id never re-fetches. Every non-success path — timeout, abort, non-2xx, {}, a blank/missing Image, a value that fails isImageSrc — ends in the monogram: never an empty box, never a broken-image icon, never alt text in the layout. - Directory card (odoo-community-developers/index.html): the monogram reserves the 72x72 box and stands until a real photo has DECODED; the photo is requested lazily, only when a card nears the viewport (IntersectionObserver, rootMargin 200px), so a 14-card page does not fire 1.4 MB on load. The monogram and the photo are the same 72x72 box, so the swap moves nothing (measured: head box 274.81x72 and ask-row tops byte-identical across a loaded photo and a monogram). - /freelancer-edit/: the photo preview makes the same fetch, so the form no longer points an at the JSON route either. Proved in a real browser against the repo served with the two webhook URLs stubbed: jpeg data URI -> photo (src prefix data:image/jpeg;base64,/, naturalWidth 800); {} / 404 / 500 / a bad value -> monogram, 0 broken-image icons, 0 cards with neither; a stub that never answers -> monogram after 8000 ms with the request ABORTED (client abort event at 8000.x ms, all 6 sockets disconnected server-side). No record created, no probe write. --- freelancer-edit/index.html | 35 ++++---- odoo-community-developers/index.html | 120 +++++++++++++++++--------- static/expert-image.js | 122 ++++++++++++++++++++------- 3 files changed, 191 insertions(+), 86 deletions(-) diff --git a/freelancer-edit/index.html b/freelancer-edit/index.html index 2f1ca69..4455981 100644 --- a/freelancer-edit/index.html +++ b/freelancer-edit/index.html @@ -149,7 +149,7 @@ - +