Spaces:
Running
Running
File size: 4,176 Bytes
31a2d08 48bc2fc 31a2d08 48bc2fc 31a2d08 c99cc8d 31a2d08 c99cc8d 31a2d08 c99cc8d 31a2d08 48bc2fc 31a2d08 5743069 31a2d08 48bc2fc 62c50cd 48bc2fc 62c50cd 48bc2fc 62c50cd 48bc2fc 62c50cd 48bc2fc 62c50cd 48bc2fc 0965b80 d10886e 48bc2fc |
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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
<script lang="ts">
import { onMount } from "svelte";
import { ProgressBarRound, ArrowLeft } from "carbon-icons-svelte";
interface Scene {
name: string;
url: string;
thumbnail: string;
}
interface Config {
Model: string;
Space: string;
Paper: string;
}
export let modelName: string;
export let onBack: () => void;
export let onSceneClick: (scene: Scene) => void;
let scenes: Scene[] = [];
let config: Config;
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;
}, []);
const configUrl = `https://huggingface.co/datasets/dylanebert/3d-arena/resolve/main/outputs/${modelName}/config.json`;
const configResponse = await fetch(configUrl);
config = (await configResponse.json()) as Config;
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>
<div class="model-details">
{#if config && (config.Model || config.Space || config.Paper)}
<div class="config-container">
{#if config.Model}
<div class="config-item">
<span class="config-label">Model:</span>
<a class="muted" href={config.Model} target="_blank">
{config.Model.replace("https://huggingface.co/", "")}
</a>
</div>
{/if}
{#if config.Space}
<div class="config-item">
<span class="config-label">Space:</span>
<a class="muted" href={config.Space} target="_blank">
{config.Space.replace("https://huggingface.co/spaces/", "")}
</a>
</div>
{/if}
{#if config.Paper}
<div class="config-item">
<span class="config-label">Paper:</span>
<a class="muted" href={config.Paper} target="_blank">
{config.Paper.replace("https://huggingface.co/papers/", "").replace(
"https://arxiv.org/abs/",
""
)}
</a>
</div>
{/if}
</div>
{/if}
{#if scenes.length > 0}
<div class="grid">
{#each scenes as scene}
<button class="grid-item" on:click={() => onSceneClick(scene)}>
<img loading="lazy" src={scene.thumbnail} alt={scene.name} class="thumbnail" />
<div class="title">{scene.name.length > 16 ? `${scene.name.slice(0, 16)}...` : scene.name}</div>
</button>
{/each}
</div>
{:else}
<div class="loading-container">
<ProgressBarRound class="loading-icon" />
<div class="loading-text">Loading...</div>
</div>
{/if}
</div>
|