File size: 2,708 Bytes
31a2d08
 
 
5679415
31a2d08
 
 
c99cc8d
 
 
5e88463
5679415
31a2d08
 
 
5e88463
31a2d08
c99cc8d
31a2d08
5e88463
31a2d08
 
c4d103b
c99cc8d
 
 
 
 
 
 
5679415
 
 
 
 
 
 
c99cc8d
5679415
5e88463
31a2d08
 
5e88463
 
 
 
 
 
 
 
 
31a2d08
 
 
 
 
5e88463
31a2d08
5e88463
31a2d08
c99cc8d
5e88463
5679415
c99cc8d
 
 
 
 
 
 
 
 
 
31a2d08
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<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}