Files
electric-cherry/src/lib/leaderboard-navigation.ts
T

50 lines
2.2 KiB
TypeScript

import { leaderboardMetrics } from './leaderboard.js';
const origin = 'https://electric-cherry.invalid';
const contextKeys = ['game', 'map', 'players', 'metric', 'q', 'offset'] as const;
/** Only retain a local leaderboard destination and its supported view state. */
export function leaderboardReturnHref(value: string | null | undefined): string {
if (!value?.startsWith('/leaderboard')) return '/leaderboard';
try {
const url = new URL(value, origin);
if (url.origin !== origin || url.pathname !== '/leaderboard') return '/leaderboard';
const params = new URLSearchParams();
for (const key of contextKeys) {
const entry = url.searchParams.get(key);
if (entry || (key === 'map' && entry !== null)) params.set(key, entry!);
}
return `/leaderboard${params.size ? `?${params}` : ''}`;
} catch {
return '/leaderboard';
}
}
export function playerContextHref(guid: string, source: string): string {
const returnTo = leaderboardReturnHref(source);
const original = new URL(returnTo, origin).searchParams;
const params = new URLSearchParams({ returnTo });
// History pagination is independent of the originating leaderboard page.
const game = original.get('game');
const map = original.get('map');
const metric = original.get('metric');
const players = original.get('players');
// Match the leaderboard's displayed defaults for older or hand-edited URLs.
if (game === 't5' || game === 't6') params.set('game', game);
if (map !== null && map.length <= 1024) params.set('map', map);
if (players && /^[1-4]$/.test(players)) params.set('players', players);
if (metric && leaderboardMetrics.some((item) => item.key === metric))
params.set('metric', metric);
return `/leaderboard/players/${encodeURIComponent(guid)}?${params}`;
}
export function profileViewHref(current: URL, changes: Record<string, string>): string {
const params = new URLSearchParams(current.search);
params.delete('offset');
for (const [key, value] of Object.entries(changes)) {
if (value || key === 'map') params.set(key, value);
else params.delete(key);
}
return `${current.pathname}${params.size ? `?${params}` : ''}`;
}