1
0
Fork 0

feat(flappy): keep current pilot visible on leaderboard

This commit is contained in:
Jason Fraley 2026-08-21 00:26:52 -04:00
parent f69c7ca0b4
commit 643e282fe7

View file

@ -36,6 +36,7 @@ interface LeaderboardRow {
bestScore: number; bestScore: number;
xpEarned: number; xpEarned: number;
isCurrentUser: boolean; isCurrentUser: boolean;
isOutsideTopTen?: boolean;
} }
interface FlappyLeaderboardProps { interface FlappyLeaderboardProps {
@ -60,9 +61,10 @@ export function FlappyLeaderboard({ refreshKey = 0, currentUserId, activePilots
setFailed(false); setFailed(false);
const params = new URLSearchParams({ const params = new URLSearchParams({
"where[progression.minigames.flappyBird.bestScore][greater_than]": "0",
sort: "-progression.minigames.flappyBird.bestScore", sort: "-progression.minigames.flappyBird.bestScore",
limit: "10", // Fetch enough profiles to keep the current pilot visible even when
// they have not completed a scored run yet.
limit: "100",
depth: "1", depth: "1",
}); });
@ -73,8 +75,7 @@ export function FlappyLeaderboard({ refreshKey = 0, currentUserId, activePilots
}) })
.then((data) => { .then((data) => {
if (cancelled) return; if (cancelled) return;
setRows( const mapped: LeaderboardRow[] = (data.docs ?? []).map((doc) => {
(data.docs ?? []).map((doc) => {
const flappy = doc.progression?.minigames?.flappyBird ?? {}; const flappy = doc.progression?.minigames?.flappyBird ?? {};
const user = typeof doc.user === "object" && doc.user !== null ? doc.user : null; const user = typeof doc.user === "object" && doc.user !== null ? doc.user : null;
const name = const name =
@ -88,8 +89,14 @@ export function FlappyLeaderboard({ refreshKey = 0, currentUserId, activePilots
xpEarned: flappy.xpEarned ?? 0, xpEarned: flappy.xpEarned ?? 0,
isCurrentUser: user ? String(user.id) === String(currentUserId) : false, isCurrentUser: user ? String(user.id) === String(currentUserId) : false,
}; };
}), });
); const scored = mapped.filter((row) => row.bestScore > 0);
const visible = scored.slice(0, 10);
const current = mapped.find((row) => row.isCurrentUser);
if (current && !visible.some((row) => row.id === current.id)) {
visible.push({ ...current, isOutsideTopTen: true });
}
setRows(visible);
}) })
.catch(() => { .catch(() => {
if (!cancelled) setFailed(true); if (!cancelled) setFailed(true);
@ -141,9 +148,16 @@ export function FlappyLeaderboard({ refreshKey = 0, currentUserId, activePilots
</thead> </thead>
<tbody className="divide-y divide-border"> <tbody className="divide-y divide-border">
{rows.map((row, i) => ( {rows.map((row, i) => (
<tr key={row.id} className={cn(row.isCurrentUser && "bg-accent/40")}> <tr
key={row.id}
className={cn(
row.isCurrentUser && "bg-accent/40",
row.isOutsideTopTen && "text-muted-foreground opacity-70",
)}
title={row.isOutsideTopTen ? "Pilot status — not currently ranked in the top 10" : undefined}
>
<td className="px-4 py-2"> <td className="px-4 py-2">
<span className={rankClass(i)}>{i + 1}</span> <span className={rankClass(i)}>{row.isOutsideTopTen ? "—" : i + 1}</span>
</td> </td>
<td className="px-2 py-2 font-medium"> <td className="px-2 py-2 font-medium">
<span className="flex items-center gap-2"> <span className="flex items-center gap-2">
@ -151,6 +165,11 @@ export function FlappyLeaderboard({ refreshKey = 0, currentUserId, activePilots
{row.isCurrentUser && ( {row.isCurrentUser && (
<span className="shrink-0 text-xs text-muted-foreground">(you)</span> <span className="shrink-0 text-xs text-muted-foreground">(you)</span>
)} )}
{row.isOutsideTopTen && (
<span className="shrink-0 text-[10px] font-normal uppercase tracking-wide text-muted-foreground">
unranked
</span>
)}
{activePilots.some((pilot) => pilot.id === row.id) && ( {activePilots.some((pilot) => pilot.id === row.id) && (
<span className="size-2 rounded-full bg-emerald-400" title="Playing now" aria-label="Playing now" /> <span className="size-2 rounded-full bg-emerald-400" title="Playing now" aria-label="Playing now" />
)} )}