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>
This commit is contained in:
47
app/lib/profile-bootstrap.tsx
Normal file
47
app/lib/profile-bootstrap.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user