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>
48 lines
1.4 KiB
TypeScript
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
|
|
}
|