Leaderboard avatar+level+XP bar; mobile table overlap fixes
Leaderboard: each row now shows the player avatar (photo or emoji) with a level badge ring and a progress-to-next-level bar (LeaderboardEntry gained levelProgress + avatarImage; mock fills real XP for you, random for others). Mobile table: the played-card pile now scales inward on narrow screens so it no longer overlaps the opponents' side stacks (trickScale by viewport); seat avatars render above the stacks (z-20) so the side player isn't hidden; side hands nudged to the edges + top hand raised slightly on phones. Verified: tsc + next build clean; web image rebuilt on :1500. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
STICKER_PACKS,
|
||||
applyMatchResult,
|
||||
dailyRewardFor,
|
||||
xpNeededForLevel,
|
||||
} from "./gamification";
|
||||
import {
|
||||
CreateRoomOptions,
|
||||
@@ -820,14 +821,17 @@ export class MockOnlineService implements OnlineService {
|
||||
avatar: pick(AVATARS).id,
|
||||
level: randInt(5, 60),
|
||||
rating: randInt(1000, 2200),
|
||||
levelProgress: Math.random(),
|
||||
isYou: false,
|
||||
}));
|
||||
const you = {
|
||||
id: p.id,
|
||||
displayName: p.displayName,
|
||||
avatar: p.avatar,
|
||||
avatarImage: p.avatarImage,
|
||||
level: p.level,
|
||||
rating: p.rating,
|
||||
levelProgress: Math.min(1, p.xp / xpNeededForLevel(p.level)),
|
||||
isYou: true,
|
||||
};
|
||||
const all = [...others, you].sort((a, b) => b.rating - a.rating);
|
||||
|
||||
@@ -364,8 +364,11 @@ export interface LeaderboardEntry {
|
||||
id: string;
|
||||
displayName: string;
|
||||
avatar: string;
|
||||
avatarImage?: string; // custom uploaded photo (overrides avatar)
|
||||
level: number;
|
||||
rating: number;
|
||||
/** progress 0..1 toward the next level (for the XP bar) */
|
||||
levelProgress: number;
|
||||
isYou: boolean;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user