avatar: render immediately + survive reload

The variant pipeline is async, so right after upload all four URLs in
profile.avatar_urls are still null. The first wiring attempt called
pickAvatarUrl() which returned null, and nothing visible changed even
though the upload + PATCH succeeded.

Fixes:
- pickAvatarUrl: use the actual backend keys (small/medium/large/
  original — there's no "thumbnail").
- After upload, when no variant URL is ready, fetch the raw object
  via /api/v1/digital_objects/:id/content as a blob URL for immediate
  display. Persist that URL to localStorage so the appbar's
  useProfile() picks it up via the storage event.
- ProfileBootstrap: detect stale blob: URLs cached from previous
  sessions, clear them, and refetch a fresh blob URL when variants
  still aren't ready. Eventually the persistent variant URLs land
  and overwrite.
- Force-remount AvatarImage via key={src} in the profile page and
  appbar — base-ui's Avatar.Image keeps internal load state that
  doesn't always reset on src change.
- Diagnostic logs in fetchDigitalObjectAsBlobUrl + the upload flow
  to make next debug round one step easier (kept; cheap).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
jules
2026-05-05 10:33:14 +10:00
parent 2ab183596c
commit c968ac0735
5 changed files with 154 additions and 14 deletions

View File

@@ -532,7 +532,11 @@ export function AppShell({
>
<Avatar className="size-7 cursor-pointer">
{profile.avatarUrl ? (
<AvatarImage src={profile.avatarUrl} alt={user.name} />
<AvatarImage
key={profile.avatarUrl}
src={profile.avatarUrl}
alt={user.name}
/>
) : null}
<AvatarFallback>{user.initials}</AvatarFallback>
</Avatar>