3d-arena / src /routes /ModelDetails.svelte
dylanebert's picture
dylanebert HF staff
vote layout
c99cc8d
raw
history blame
2.32 kB
<script lang="ts">
import { onMount } from "svelte";
import { ProgressBarRound, ArrowLeft } from "carbon-icons-svelte";
interface Scene {
name: string;
url: string;
thumbnail: string;
}
export let modelName: string;
export let onBack: () => void;
export let onSceneClick: (scene: Scene) => void;
let scenes: Scene[] = [];
async function fetchScenes() {
scenes = [];
const url = `https://huggingface.co/api/datasets/dylanebert/3d-arena`;
const response = await fetch(url);
const responseData = await response.json();
const directory = `outputs/${modelName}`;
const extensions = ["obj", "glb", "ply", "splat"];
scenes = responseData.siblings
.filter((scene: any) => {
const fileExtension = scene.rfilename.split(".").pop();
return scene.rfilename.startsWith(directory) && extensions.includes(fileExtension);
})
.reduce((acc: Scene[], scene: any) => {
const name = scene.rfilename.split("/").pop().split(".").slice(0, -1).join(".");
const url = `https://huggingface.co/datasets/dylanebert/3d-arena/resolve/main/${scene.rfilename}`;
const thumbnail = url.replace(/\.[^.]+$/, ".png");
acc.push({ name, url, thumbnail });
return acc;
}, []);
scenes = [...scenes];
}
onMount(fetchScenes);
</script>
<div class="header">
<div class="back" aria-label="Back" aria-hidden="true" on:click={onBack}>
<ArrowLeft size={24} />
</div>
<div class="spacer" />
<button class="title-button" on:click={fetchScenes}>
<h2 class="muted">{modelName}</h2>
</button>
<div class="desktop-spacer" />
</div>
{#if scenes.length > 0}
<div class="grid">
{#each scenes as scene}
<button class="grid-item" on:click={() => onSceneClick(scene)}>
<img src={scene.thumbnail} alt={scene.name} class="thumbnail" />
<div class="title">{scene.name}</div>
</button>
{/each}
</div>
{:else}
<div class="loading-container">
<ProgressBarRound class="loading-icon" />
<div class="loading-text">Loading...</div>
</div>
{/if}