From 6687e4435f83aa82917778558e5fe20ffa1f6891 Mon Sep 17 00:00:00 2001 From: scheinriese Date: Thu, 14 May 2026 15:05:04 +0200 Subject: [PATCH] fix(icon-picker): render avatar/image page-icons on cold reload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On a fresh session, page entities carry icon metadata (asset-uuid) before their referenced asset blocks have transacted into the main-thread DataScript DB. The render bodies of avatar-image-cp / image-icon-cp were gating the loaded blob URL on (db/entity [:block/uuid uuid]) — which returned nil during this hydration window, flipping asset-missing? true and masking a working URL with the image-error / initials fallback. The workaround was to visit #Asset, whose table query hydrated the blocks via db.async/ --- src/main/frontend/components/icon.cljs | 123 ++++++++++++++++--------- 1 file changed, 80 insertions(+), 43 deletions(-) diff --git a/src/main/frontend/components/icon.cljs b/src/main/frontend/components/icon.cljs index c3fed77e3a..3927341dda 100644 --- a/src/main/frontend/components/icon.cljs +++ b/src/main/frontend/components/icon.cljs @@ -362,13 +362,32 @@ state) :did-update (fn [state] (let [[asset-uuid asset-type-arg _opts] (:rum/args state) + *url (::url state) + *error (::error state) *loaded-uuid (::loaded-uuid state)] - (when (and asset-uuid (not= @*loaded-uuid asset-uuid)) + (cond + ;; New uuid → fresh load. + (and asset-uuid (not= @*loaded-uuid asset-uuid)) (let [asset-type (or asset-type-arg - (get-asset-type-from-db asset-uuid)) - *url (::url state) - *error (::error state)] + (get-asset-type-from-db asset-uuid))] (reset! *loaded-uuid asset-uuid) + ( @(get @state/state :db/latest-transacted-entity-uuids) + :deleted-ids)] + (and uuid-val deleted (contains? deleted uuid-val)))) + (let [asset-type (or asset-type-arg + (get-asset-type-from-db asset-uuid))] + (reset! *url nil) + (reset! *error false) ( @(get @state/state :db/latest-transacted-entity-uuids) + :deleted-ids)] + (and uuid-val deleted (contains? deleted uuid-val)))) + (do (reset! *url nil) + (reset! *error false) + ( missing. + {;; Force-remount when the URL transitions absent <-> present. ;; Radix's Avatar primitive tracks image-loading status in ;; context. Once Avatar.Image reports "loaded", that status ;; sticks even after Avatar.Image unmounts — Avatar.Fallback ;; reads the status and stays hidden because it thinks the - ;; image is still loaded. Toggling the key on `asset-missing?` + ;; image is still loaded. Toggling the key on URL presence ;; forces a fresh mount with a clean status machine, so the - ;; fallback renders the moment the asset disappears (and the - ;; image is shown afresh if the asset is re-created or hydrates - ;; lazily later). - :key (if asset-missing? "no-image" "with-image") + ;; fallback renders the moment the URL clears (e.g. retraction + ;; clears `*url`) and the image renders afresh when a new URL + ;; lands. + :key (if url "with-image" "no-image") :style {:width size :height size} :data-shape (name shape)} ;; Image (shows when loaded, circular with cover fit)