Route beatleader profile requests through ssr

This commit is contained in:
pleb 2025-11-04 13:32:39 -08:00
parent 846387e2f7
commit 5e9433563b
4 changed files with 37 additions and 50 deletions

View File

@ -2,7 +2,7 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { browser } from '$app/environment'; import { browser } from '$app/environment';
import PlayerCard from '$lib/components/PlayerCard.svelte'; import PlayerCard from '$lib/components/PlayerCard.svelte';
import type { BeatLeaderPlayerProfile } from '$lib/utils/plebsaber-utils'; import { fetchBeatLeaderPlayerProfile, type BeatLeaderPlayerProfile } from '$lib/utils/plebsaber-utils';
export let playerA = ''; export let playerA = '';
export let playerB = ''; export let playerB = '';
@ -69,23 +69,13 @@
history.replaceState(null, '', url); history.replaceState(null, '', url);
} }
async function fetchPlayerProfile(playerId: string): Promise<BeatLeaderPlayerProfile | null> {
try {
const res = await fetch(`https://api.beatleader.xyz/player/${encodeURIComponent(playerId)}`);
if (!res.ok) return null;
return (await res.json()) as BeatLeaderPlayerProfile;
} catch {
return null;
}
}
async function loadDefaultPlayerCards(a: string, b: string): Promise<void> { async function loadDefaultPlayerCards(a: string, b: string): Promise<void> {
playerAProfile = null; playerAProfile = null;
playerBProfile = null; playerBProfile = null;
if (!a || !b) return; if (!a || !b) return;
const [pa, pb] = await Promise.all([ const [pa, pb] = await Promise.all([
fetchPlayerProfile(a), fetchBeatLeaderPlayerProfile(a),
fetchPlayerProfile(b) fetchBeatLeaderPlayerProfile(b)
]); ]);
playerAProfile = pa; playerAProfile = pa;
playerBProfile = pb; playerBProfile = pb;
@ -110,7 +100,7 @@
} }
try { try {
const profile = await fetchPlayerProfile(trimmed); const profile = await fetchBeatLeaderPlayerProfile(trimmed);
// Only update if this is still the current player ID // Only update if this is still the current player ID
const currentId = player === 'A' ? playerA.trim() : playerB.trim(); const currentId = player === 'A' ? playerA.trim() : playerB.trim();
if (currentId === trimmed) { if (currentId === trimmed) {

View File

@ -225,6 +225,33 @@ export async function fetchBeatLeaderStarsByHash(
} }
} }
export async function fetchBeatLeaderPlayerProfile(
playerId: string,
fetcher?: typeof fetch,
authMode: 'steam' | 'oauth' | 'session' | 'auto' | 'none' = 'auto'
): Promise<BeatLeaderPlayerProfile | null> {
const trimmed = playerId?.trim?.();
if (!trimmed) return null;
const callFetch = (fetcher ?? globalThis.fetch) as typeof fetch | undefined;
if (!callFetch) return null;
const search = new URLSearchParams();
if (authMode) {
search.set('auth', authMode);
}
const url = `/api/beatleader/player/${encodeURIComponent(trimmed)}${search.size ? `?${search.toString()}` : ''}`;
try {
const res = await callFetch(url);
if (!res.ok) return null;
return (await res.json()) as BeatLeaderPlayerProfile;
} catch {
return null;
}
}
/** /**
* Load metadata for a list of items with unique hashes * Load metadata for a list of items with unique hashes
* Only loads metadata that isn't already in the cache * Only loads metadata that isn't already in the cache

View File

@ -8,6 +8,7 @@
type BeatLeaderPlayerProfile, type BeatLeaderPlayerProfile,
fetchAllPlayerScores, fetchAllPlayerScores,
fetchBeatSaverMeta, fetchBeatSaverMeta,
fetchBeatLeaderPlayerProfile,
type MapMeta type MapMeta
} from '$lib/utils/plebsaber-utils'; } from '$lib/utils/plebsaber-utils';
@ -154,7 +155,7 @@
loadingPreview = true; loadingPreview = true;
try { try {
const profile = await fetchPlayerProfile(id); const profile = await fetchBeatLeaderPlayerProfile(id);
// Only update if this is still the current player ID // Only update if this is still the current player ID
if (playerId.trim() === id) { if (playerId.trim() === id) {
previewPlayerProfile = profile; previewPlayerProfile = profile;
@ -330,16 +331,6 @@
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
} }
async function fetchPlayerProfile(id: string): Promise<BeatLeaderPlayerProfile | null> {
try {
const res = await fetch(`https://api.beatleader.xyz/player/${encodeURIComponent(id)}`);
if (!res.ok) return null;
return (await res.json()) as BeatLeaderPlayerProfile;
} catch {
return null;
}
}
async function onAnalyze(ev: SubmitEvent) { async function onAnalyze(ev: SubmitEvent) {
ev.preventDefault(); ev.preventDefault();
errorMsg = null; errorMsg = null;
@ -359,7 +350,7 @@
try { try {
const [scores, profile] = await Promise.all([ const [scores, profile] = await Promise.all([
fetchAllPlayerScores(playerId.trim(), 150), fetchAllPlayerScores(playerId.trim(), 150),
fetchPlayerProfile(playerId.trim()) fetchBeatLeaderPlayerProfile(playerId.trim())
]); ]);
analyzedPlayerProfile = profile; analyzedPlayerProfile = profile;
hasAnalyzed = true; hasAnalyzed = true;

View File

@ -1,6 +1,6 @@
import { error, redirect } from '@sveltejs/kit'; import { error, redirect } from '@sveltejs/kit';
import { getAllSessions, getSession } from '$lib/server/sessionStore'; import { getAllSessions, getSession } from '$lib/server/sessionStore';
import { PLEB_BEATLEADER_ID } from '$lib/utils/plebsaber-utils'; import { PLEB_BEATLEADER_ID, fetchBeatLeaderPlayerProfile } from '$lib/utils/plebsaber-utils';
import type { PageServerLoad } from './$types'; import type { PageServerLoad } from './$types';
type StatsUser = { type StatsUser = {
@ -16,28 +16,7 @@ type StatsUser = {
lastSeenIso: string; lastSeenIso: string;
}; };
type BeatLeaderPlayer = { export const load: PageServerLoad = async ({ cookies, fetch }) => {
id: string;
name: string;
avatar?: string;
country?: string;
rank?: number;
techPp?: number;
accPp?: number;
passPp?: number;
};
async function fetchBeatLeaderProfile(playerId: string): Promise<BeatLeaderPlayer | null> {
try {
const response = await fetch(`https://api.beatleader.xyz/player/${playerId}`);
if (!response.ok) return null;
return (await response.json()) as BeatLeaderPlayer;
} catch {
return null;
}
}
export const load: PageServerLoad = async ({ cookies }) => {
const currentSession = getSession(cookies); const currentSession = getSession(cookies);
if (!currentSession) { if (!currentSession) {
throw redirect(302, '/auth/beatleader/login?redirect_uri=%2Ftools%2Fstats'); throw redirect(302, '/auth/beatleader/login?redirect_uri=%2Ftools%2Fstats');
@ -59,7 +38,7 @@ export const load: PageServerLoad = async ({ cookies }) => {
// Fetch all player profiles in parallel // Fetch all player profiles in parallel
const userPromises = Array.from(aggregated.values()).map(async ({ session }) => { const userPromises = Array.from(aggregated.values()).map(async ({ session }) => {
const profile = await fetchBeatLeaderProfile(session.beatleaderId); const profile = await fetchBeatLeaderPlayerProfile(session.beatleaderId, fetch);
return { return {
beatleaderId: session.beatleaderId, beatleaderId: session.beatleaderId,
name: profile?.name ?? session.name, name: profile?.name ?? session.name,