Files
arcadia-admin/app/lib/profile-bootstrap.tsx
jules 2ab183596c profile: bootstrap avatar URL on app boot
The appbar's <Avatar> reads avatarUrl from the localStorage profile
mirror. Without a global fetcher, that mirror only got populated when
the user navigated to /profile, so a fresh browser session showed
initials in the appbar until then.

- ProfileBootstrap component runs in root.tsx alongside
  LlmConfigBootstrap. On mount and on session change, fetches the
  arcadia profile and caches the resolved avatar URL.
- profile.tsx loadAccount now also persists the URL into localStorage
  on initial fetch (was in-memory only) so it survives reloads.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 09:56:40 +10:00

48 lines
1.4 KiB
TypeScript

// Fetches the arcadia profile on app boot (and after login) and caches
// the resolved avatar URL in localStorage so the appbar's <Avatar> shows
// immediately, without waiting for the user to navigate to /profile.
import { useEffect } from "react"
import { useArcadiaClient } from "@crema/arcadia-client"
import { getProfile, pickAvatarUrl } from "~/lib/arcadia/profiles"
import { loadProfile, saveProfile } from "~/lib/profile"
export function ProfileBootstrap() {
const arcadia = useArcadiaClient()
useEffect(() => {
let cancelled = false
const tryBootstrap = async () => {
const token =
typeof window !== "undefined"
? sessionStorage.getItem("arcadia_access_token")
: null
if (!token) return
try {
const p = await getProfile(arcadia)
if (cancelled) return
const url = pickAvatarUrl(p)
if (!url) return
const current = loadProfile()
if (current.avatarUrl === url) return
saveProfile({ ...current, avatarUrl: url })
} catch {
// 401 / network — silently skip; will retry on next session change.
}
}
void tryBootstrap()
const onSessionChange = () => void tryBootstrap()
window.addEventListener("crema:session-change", onSessionChange)
return () => {
cancelled = true
window.removeEventListener("crema:session-change", onSessionChange)
}
}, [arcadia])
return null
}