dylanebert commited on
Commit
5679415
·
1 Parent(s): 160a21b

support alternative display names

Browse files
src/routes/+page.svelte CHANGED
@@ -12,14 +12,14 @@
12
  }
13
 
14
  let currentView: "Leaderboard" | "Vote" | "ModelDetails" | "Viewer" | "About" = "Vote";
15
- let selectedEntry: { name: string; path: string } | null = null;
16
  let selectedScene: Scene | null = null;
17
 
18
  function goHome() {
19
  window.location.href = "/";
20
  }
21
 
22
- function showModelDetails(entry: { name: string; path: string }) {
23
  selectedEntry = entry;
24
  currentView = "ModelDetails";
25
  }
@@ -55,7 +55,6 @@
55
  {:else if currentView === "ModelDetails" && selectedEntry}
56
  <ModelDetails
57
  modelName={selectedEntry.name}
58
- modelPath={selectedEntry.path}
59
  onBack={() => (currentView = "Leaderboard")}
60
  onSceneClick={showScene}
61
  />
 
12
  }
13
 
14
  let currentView: "Leaderboard" | "Vote" | "ModelDetails" | "Viewer" | "About" = "Vote";
15
+ let selectedEntry: { name: string } | null = null;
16
  let selectedScene: Scene | null = null;
17
 
18
  function goHome() {
19
  window.location.href = "/";
20
  }
21
 
22
+ function showModelDetails(entry: { name: string }) {
23
  selectedEntry = entry;
24
  currentView = "ModelDetails";
25
  }
 
55
  {:else if currentView === "ModelDetails" && selectedEntry}
56
  <ModelDetails
57
  modelName={selectedEntry.name}
 
58
  onBack={() => (currentView = "Leaderboard")}
59
  onSceneClick={showScene}
60
  />
src/routes/Leaderboard.svelte CHANGED
@@ -1,12 +1,14 @@
1
  <script lang="ts">
2
  import { onMount } from "svelte";
3
  import { ProgressBarRound } from "carbon-icons-svelte";
 
4
 
5
  interface Entry {
6
  name: string;
7
  rank: number;
8
  score: number;
9
  votes: number;
 
10
  }
11
 
12
  export let onEntryClick: (entry: Entry) => void;
@@ -23,9 +25,15 @@
23
  },
24
  });
25
  const data = (await response.json()) as Entry[];
26
- data.sort((a, b) => a.rank - b.rank);
 
 
 
 
 
 
27
 
28
- leaderboard = data;
29
  };
30
 
31
  onMount(async () => {
@@ -39,7 +47,7 @@
39
  <button class="grid-item" on:click={() => onEntryClick(entry)}>
40
  <img src={`${baseUrl}/${entry.name}/thumbnail.png`} alt={entry.name} class="thumbnail" />
41
  <div class="ranking">{entry.rank}</div>
42
- <div class="title">{entry.name}</div>
43
  <div class="score-container">
44
  <div class="score">
45
  <span class="label">Score:</span>
 
1
  <script lang="ts">
2
  import { onMount } from "svelte";
3
  import { ProgressBarRound } from "carbon-icons-svelte";
4
+ import { getConfig } from "./utils/getConfig";
5
 
6
  interface Entry {
7
  name: string;
8
  rank: number;
9
  score: number;
10
  votes: number;
11
+ displayName?: string;
12
  }
13
 
14
  export let onEntryClick: (entry: Entry) => void;
 
25
  },
26
  });
27
  const data = (await response.json()) as Entry[];
28
+ const entriesWithDisplayNames = await Promise.all(
29
+ data.map(async (entry) => {
30
+ const config = await getConfig(entry.name);
31
+ return { ...entry, displayName: config.DisplayName || entry.name };
32
+ }),
33
+ );
34
+ entriesWithDisplayNames.sort((a, b) => a.rank - b.rank);
35
 
36
+ leaderboard = entriesWithDisplayNames;
37
  };
38
 
39
  onMount(async () => {
 
47
  <button class="grid-item" on:click={() => onEntryClick(entry)}>
48
  <img src={`${baseUrl}/${entry.name}/thumbnail.png`} alt={entry.name} class="thumbnail" />
49
  <div class="ranking">{entry.rank}</div>
50
+ <div class="title">{entry.displayName}</div>
51
  <div class="score-container">
52
  <div class="score">
53
  <span class="label">Score:</span>
src/routes/ModelDetails.svelte CHANGED
@@ -1,6 +1,8 @@
1
  <script lang="ts">
2
  import { onMount } from "svelte";
3
  import { ProgressBarRound, ArrowLeft } from "carbon-icons-svelte";
 
 
4
 
5
  interface Scene {
6
  name: string;
@@ -8,18 +10,13 @@
8
  thumbnail: string;
9
  }
10
 
11
- interface Config {
12
- Model: string;
13
- Space: string;
14
- Paper: string;
15
- }
16
-
17
  export let modelName: string;
18
  export let onBack: () => void;
19
  export let onSceneClick: (scene: Scene) => void;
20
 
21
  let scenes: Scene[] = [];
22
  let config: Config;
 
23
 
24
  async function fetchScenes() {
25
  scenes = [];
@@ -44,14 +41,14 @@
44
  return acc;
45
  }, []);
46
 
47
- const configUrl = `https://huggingface.co/datasets/dylanebert/3d-arena/resolve/main/outputs/${modelName}/config.json`;
48
- const configResponse = await fetch(configUrl);
49
- config = (await configResponse.json()) as Config;
50
 
51
  scenes = [...scenes];
52
  }
53
 
54
- function isValidUrl(url: string): boolean {
 
55
  try {
56
  new URL(url);
57
  return true;
@@ -69,7 +66,7 @@
69
  </div>
70
  <div class="spacer" />
71
  <button class="title-button" on:click={fetchScenes}>
72
- <h2 class="muted">{modelName}</h2>
73
  </button>
74
  <div class="desktop-spacer" />
75
  </div>
@@ -99,7 +96,7 @@
99
  <a class="muted" href={config.Paper} target="_blank">
100
  {config.Paper.replace("https://huggingface.co/papers/", "").replace(
101
  "https://arxiv.org/abs/",
102
- ""
103
  )}
104
  </a>
105
  </div>
 
1
  <script lang="ts">
2
  import { onMount } from "svelte";
3
  import { ProgressBarRound, ArrowLeft } from "carbon-icons-svelte";
4
+ import { getConfig } from "./utils/getConfig";
5
+ import type { Config } from "./utils/Config";
6
 
7
  interface Scene {
8
  name: string;
 
10
  thumbnail: string;
11
  }
12
 
 
 
 
 
 
 
13
  export let modelName: string;
14
  export let onBack: () => void;
15
  export let onSceneClick: (scene: Scene) => void;
16
 
17
  let scenes: Scene[] = [];
18
  let config: Config;
19
+ let displayName: string;
20
 
21
  async function fetchScenes() {
22
  scenes = [];
 
41
  return acc;
42
  }, []);
43
 
44
+ config = await getConfig(modelName);
45
+ displayName = config.DisplayName || modelName;
 
46
 
47
  scenes = [...scenes];
48
  }
49
 
50
+ function isValidUrl(url: string | undefined): boolean {
51
+ if (!url) return false;
52
  try {
53
  new URL(url);
54
  return true;
 
66
  </div>
67
  <div class="spacer" />
68
  <button class="title-button" on:click={fetchScenes}>
69
+ <h2 class="muted">{displayName || "Loading..."}</h2>
70
  </button>
71
  <div class="desktop-spacer" />
72
  </div>
 
96
  <a class="muted" href={config.Paper} target="_blank">
97
  {config.Paper.replace("https://huggingface.co/papers/", "").replace(
98
  "https://arxiv.org/abs/",
99
+ "",
100
  )}
101
  </a>
102
  </div>
src/routes/Viewer.svelte CHANGED
@@ -3,6 +3,8 @@
3
  import type { IViewer } from "./viewers/IViewer";
4
  import { createViewer } from "./viewers/ViewerFactory";
5
  import { ArrowLeft, Cube, WatsonHealth3DPrintMesh } from "carbon-icons-svelte";
 
 
6
 
7
  interface Scene {
8
  name: string;
@@ -20,9 +22,11 @@
20
  let loadingBarFill: HTMLDivElement;
21
 
22
  let viewer: IViewer;
 
23
 
24
  async function loadScene() {
25
  overlay.style.display = "flex";
 
26
  viewer = await createViewer(scene.url, canvas, (progress) => {
27
  loadingBarFill.style.width = `${progress * 100}%`;
28
  });
@@ -78,9 +82,13 @@
78
  <!-- svelte-ignore a11y-click-events-have-key-events -->
79
  <!-- svelte-ignore a11y-no-static-element-interactions -->
80
  <h2>
81
- <span class="muted" on:click={onBack}>{modelName}/</span>{scene.name.length > 16
82
- ? `${scene.name.slice(0, 16)}...`
83
- : scene.name}
 
 
 
 
84
  </h2>
85
  </button>
86
  <div class="desktop-spacer" />
 
3
  import type { IViewer } from "./viewers/IViewer";
4
  import { createViewer } from "./viewers/ViewerFactory";
5
  import { ArrowLeft, Cube, WatsonHealth3DPrintMesh } from "carbon-icons-svelte";
6
+ import type { Config } from "./utils/Config";
7
+ import { getConfig } from "./utils/getConfig";
8
 
9
  interface Scene {
10
  name: string;
 
22
  let loadingBarFill: HTMLDivElement;
23
 
24
  let viewer: IViewer;
25
+ let displayName: string;
26
 
27
  async function loadScene() {
28
  overlay.style.display = "flex";
29
+ displayName = (await getConfig(modelName)).DisplayName || modelName;
30
  viewer = await createViewer(scene.url, canvas, (progress) => {
31
  loadingBarFill.style.width = `${progress * 100}%`;
32
  });
 
82
  <!-- svelte-ignore a11y-click-events-have-key-events -->
83
  <!-- svelte-ignore a11y-no-static-element-interactions -->
84
  <h2>
85
+ {#if displayName}
86
+ <span class="muted" on:click={onBack}>{displayName}/</span>{scene.name.length > 16
87
+ ? `${scene.name.slice(0, 16)}...`
88
+ : scene.name}
89
+ {:else}
90
+ Loading...
91
+ {/if}
92
  </h2>
93
  </button>
94
  <div class="desktop-spacer" />
src/routes/Vote.svelte CHANGED
@@ -3,14 +3,17 @@
3
  import type { IViewer } from "./viewers/IViewer";
4
  import { createViewer } from "./viewers/ViewerFactory";
5
  import { Cube, WatsonHealth3DPrintMesh } from "carbon-icons-svelte";
 
6
 
7
  interface Data {
8
  input: string;
9
  input_path: string;
10
  model1: string;
11
  model1_path: string;
 
12
  model2: string;
13
  model2_path: string;
 
14
  }
15
 
16
  let viewerA: IViewer;
@@ -78,6 +81,12 @@
78
  const model1_path = `${baseUrl}${data.model1_path}`;
79
  const model2_path = `${baseUrl}${data.model2_path}`;
80
 
 
 
 
 
 
 
81
  try {
82
  [viewerA, viewerB] = await Promise.all([
83
  createViewer(model1_path, canvasA, (progress) => {
@@ -214,7 +223,7 @@
214
  <div bind:this={loadingBarFillA} class="loading-bar-fill" />
215
  </div>
216
  </div>
217
- <div bind:this={voteOverlayA} class="vote-overlay">{data.model1}</div>
218
  <canvas bind:this={canvasA} class="viewer-canvas" id="canvas1"> </canvas>
219
  <div class="stats">
220
  {#if viewerA}
@@ -253,7 +262,7 @@
253
  <div bind:this={loadingBarFillB} class="loading-bar-fill" />
254
  </div>
255
  </div>
256
- <div bind:this={voteOverlayB} class="vote-overlay">{data.model2}</div>
257
  <canvas bind:this={canvasB} class="viewer-canvas" id="canvas2"></canvas>
258
  <div class="stats">
259
  {#if viewerB}
 
3
  import type { IViewer } from "./viewers/IViewer";
4
  import { createViewer } from "./viewers/ViewerFactory";
5
  import { Cube, WatsonHealth3DPrintMesh } from "carbon-icons-svelte";
6
+ import { getConfig } from "./utils/getConfig";
7
 
8
  interface Data {
9
  input: string;
10
  input_path: string;
11
  model1: string;
12
  model1_path: string;
13
+ model1_displayName: string;
14
  model2: string;
15
  model2_path: string;
16
+ model2_displayName: string;
17
  }
18
 
19
  let viewerA: IViewer;
 
81
  const model1_path = `${baseUrl}${data.model1_path}`;
82
  const model2_path = `${baseUrl}${data.model2_path}`;
83
 
84
+ const config1 = await getConfig(data.model1);
85
+ const config2 = await getConfig(data.model2);
86
+
87
+ data.model1_displayName = config1.DisplayName || data.model1;
88
+ data.model2_displayName = config2.DisplayName || data.model2;
89
+
90
  try {
91
  [viewerA, viewerB] = await Promise.all([
92
  createViewer(model1_path, canvasA, (progress) => {
 
223
  <div bind:this={loadingBarFillA} class="loading-bar-fill" />
224
  </div>
225
  </div>
226
+ <div bind:this={voteOverlayA} class="vote-overlay">{data.model1_displayName}</div>
227
  <canvas bind:this={canvasA} class="viewer-canvas" id="canvas1"> </canvas>
228
  <div class="stats">
229
  {#if viewerA}
 
262
  <div bind:this={loadingBarFillB} class="loading-bar-fill" />
263
  </div>
264
  </div>
265
+ <div bind:this={voteOverlayB} class="vote-overlay">{data.model2_displayName}</div>
266
  <canvas bind:this={canvasB} class="viewer-canvas" id="canvas2"></canvas>
267
  <div class="stats">
268
  {#if viewerB}
src/routes/utils/Config.ts ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ export interface Config {
2
+ Model?: string;
3
+ Space?: string;
4
+ Paper?: string;
5
+ DisplayName?: string;
6
+ }
src/routes/utils/getConfig.ts ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ import type { Config } from "./Config";
2
+
3
+ export async function getConfig(modelName: string): Promise<Config> {
4
+ const configUrl = `https://huggingface.co/datasets/dylanebert/3d-arena/resolve/main/outputs/${modelName}/config.json`;
5
+ const configResponse = await fetch(configUrl);
6
+ const config = await configResponse.json();
7
+ return config;
8
+ }