| <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} | |