3d-arena / src /routes /Leaderboard.svelte
dylanebert
open source filter option
5e88463
<script lang="ts">
import { onMount } from "svelte";
import { ProgressBarRound } from "carbon-icons-svelte";
import { getConfig } from "./utils/getConfig";
interface Entry {
name: string;
rank: number;
score: number;
votes: number;
open_source: boolean;
displayName?: string;
}
export let onEntryClick: (entry: Entry) => void;
export let showOnlyOpenSource: boolean;
const baseUrl = "https://huggingface.co/datasets/dylanebert/3d-arena/resolve/main/outputs";
let leaderboard: Entry[] = [];
let filteredLeaderboard: Entry[] = [];
const fetchLeaderboardData = async () => {
const url = "/api/leaderboard";
const response = await fetch(url, {
method: "GET",
headers: {
"Cache-Control": "no-cache",
},
});
const data = (await response.json()) as Entry[];
const entriesWithDisplayNames = await Promise.all(
data.map(async (entry) => {
const config = await getConfig(entry.name);
return { ...entry, displayName: config.DisplayName || entry.name };
}),
);
entriesWithDisplayNames.sort((a, b) => a.rank - b.rank);
leaderboard = entriesWithDisplayNames;
updateFilteredLeaderboard();
};
const updateFilteredLeaderboard = () => {
filteredLeaderboard = showOnlyOpenSource ? leaderboard.filter((entry) => entry.open_source) : leaderboard;
};
$: {
showOnlyOpenSource;
updateFilteredLeaderboard();
}
onMount(async () => {
await fetchLeaderboardData();
});
</script>
{#if filteredLeaderboard.length > 0}
<div class="grid">
{#each filteredLeaderboard as entry, index}
<button class="grid-item" on:click={() => onEntryClick(entry)}>
<img src={`${baseUrl}/${entry.name}/thumbnail.png`} alt={entry.name} class="thumbnail" />
<div class="ranking">{index + 1}</div>
<div class="title">{entry.displayName}</div>
<div class="score-container">
<div class="score">
<span class="label">Score:</span>
{entry.score}
</div>
<div class="votes">
<span class="label">Votes:</span>
{entry.votes}
</div>
</div>
</button>
{/each}
</div>
{:else}
<div class="loading-container">
<ProgressBarRound class="loading-icon" />
<div class="loading-text">Loading...</div>
</div>
{/if}