mirror of
https://github.com/Twigpine/openlaunch.git
synced 2026-11-09 18:08:17 -10:00
fix(profiles): only the newest profile lookup lands on the identity card (CodeRabbit)
A lookup is dropped unless it is the newest: each effect run clears its own alive flag on cleanup, so after a switch A -> B -> A the first lookup for A can no longer land after the second, and a save marks every lookup still in flight stale, so it cannot bring back the fields from before the save. (On /me the dashboard remounts per wallet and the buttons appear only after the first load, so neither case was reachable there; the card is now correct in any parent.)
This commit is contained in:
1 parent
e3039a46c3
commit
6c88cef618
1 file changed
+21
-4
@@ -27,22 +27,39 @@ export default function ProfileIdentity({ address, avatarClass, labelClass, addr
|
||||
useEffect(() => {
|
||||
current.current = me;
|
||||
}, [me]);
|
||||
// and only the newest lookup counts: a switch A → B → A (the effect's alive flag), or a save (this counter), makes
|
||||
// every lookup still in flight stale
|
||||
const latest = useRef(0);
|
||||
const keep = (wallet: string, p: PublicProfile | null) => {
|
||||
if (current.current === wallet) setLoaded({ wallet, profile: p });
|
||||
};
|
||||
useEffect(() => {
|
||||
let alive = true; // cleared when the wallet changes or the card unmounts: a lookup already sent can no longer land
|
||||
const ask = ++latest.current;
|
||||
const fresh = () => alive && latest.current === ask;
|
||||
const id = setTimeout(async () => {
|
||||
try {
|
||||
const r = await fetch(`/api/profile?wallet=${me}`, { cache: "no-store" });
|
||||
if (r.status === 404) return keep(me, null);
|
||||
if (r.status === 404) {
|
||||
if (fresh()) keep(me, null);
|
||||
return;
|
||||
}
|
||||
if (!r.ok) return;
|
||||
keep(me, ((await r.json()) as { profile: PublicProfile }).profile);
|
||||
const p = ((await r.json()) as { profile: PublicProfile }).profile;
|
||||
if (fresh()) keep(me, p);
|
||||
} catch {
|
||||
/* keep what we have */
|
||||
}
|
||||
}, 0);
|
||||
return () => clearTimeout(id);
|
||||
return () => {
|
||||
alive = false;
|
||||
clearTimeout(id);
|
||||
};
|
||||
}, [me]);
|
||||
const saved = (p: PublicProfile) => {
|
||||
latest.current++; // a lookup sent before the save would bring back the old fields
|
||||
keep(me, p);
|
||||
};
|
||||
|
||||
const xState = profile?.x_state ?? "none";
|
||||
return (
|
||||
@@ -81,7 +98,7 @@ export default function ProfileIdentity({ address, avatarClass, labelClass, addr
|
||||
<button type="button" onClick={() => setOpen("edit")} className="ml-1 inline-flex min-h-9 shrink-0 items-center gap-1.5 rounded-xl bg-brand px-3.5 text-[13px] font-semibold text-inverse hover:bg-brand-strong"><UserRound size={14} aria-hidden="true" />Create profile</button>
|
||||
)}
|
||||
</div>
|
||||
{open ? <ProfileSheet address={address} initial={profile ?? null} startOnVerify={open === "verify"} onClose={() => setOpen(null)} onSaved={(p) => keep(me, p)} /> : null}
|
||||
{open ? <ProfileSheet address={address} initial={profile ?? null} startOnVerify={open === "verify"} onClose={() => setOpen(null)} onSaved={saved} /> : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user