Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Sync from GitHub via hub-sync
Browse files
src/app/[org]/[dataset]/[episode]/episode-viewer.tsx
CHANGED
|
@@ -52,6 +52,41 @@ type ActiveTab =
|
|
| 52 |
| "doctor"
|
| 53 |
| "urdf";
|
| 54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
export default function EpisodeViewer({
|
| 56 |
org,
|
| 57 |
dataset,
|
|
@@ -483,54 +518,32 @@ function EpisodeViewerInner({
|
|
| 483 |
}
|
| 484 |
};
|
| 485 |
|
| 486 |
-
const
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
|
| 494 |
-
}) => {
|
| 495 |
-
const active = activeTab === tab;
|
| 496 |
-
return (
|
| 497 |
-
<button
|
| 498 |
-
onClick={() => handleTabChange(tab)}
|
| 499 |
-
title={title}
|
| 500 |
-
className={`relative px-5 py-3 text-xs font-medium tracking-wide uppercase transition-colors ${
|
| 501 |
-
active ? "text-cyan-300" : "text-slate-400 hover:text-slate-100"
|
| 502 |
-
}`}
|
| 503 |
-
>
|
| 504 |
-
{label}
|
| 505 |
-
<span
|
| 506 |
-
className={`pointer-events-none absolute bottom-0 left-3 right-3 h-px transition-all ${
|
| 507 |
-
active
|
| 508 |
-
? "bg-cyan-400 shadow-[0_0_8px_rgba(56,189,248,0.55)]"
|
| 509 |
-
: "bg-transparent"
|
| 510 |
-
}`}
|
| 511 |
-
/>
|
| 512 |
-
</button>
|
| 513 |
-
);
|
| 514 |
-
};
|
| 515 |
|
| 516 |
return (
|
| 517 |
<div className="flex flex-col h-screen max-h-screen bg-[var(--bg)] text-[var(--text-primary)]">
|
| 518 |
{/* Top tab bar */}
|
| 519 |
<div className="flex items-center border-b border-white/5 bg-[var(--surface-0)] shrink-0">
|
| 520 |
-
|
| 521 |
{hasURDFSupport(datasetInfo.robot_type) &&
|
| 522 |
-
datasetInfo.codebase_version >= "v3.0" &&
|
| 523 |
-
|
| 524 |
-
|
| 525 |
-
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
/>
|
| 534 |
<div className="ml-auto">
|
| 535 |
<HfAuthButton variant="tab" />
|
| 536 |
</div>
|
|
|
|
| 52 |
| "doctor"
|
| 53 |
| "urdf";
|
| 54 |
|
| 55 |
+
// Hoisted to module scope. Defining inside EpisodeViewerInner created a new
|
| 56 |
+
// component type on every parent render — and the parent re-renders ~12.5×/s
|
| 57 |
+
// during playback because it consumes `currentTime` from useTime. React
|
| 58 |
+
// would unmount and remount every tab on every tick.
|
| 59 |
+
function TabButton({
|
| 60 |
+
active,
|
| 61 |
+
onClick,
|
| 62 |
+
label,
|
| 63 |
+
title,
|
| 64 |
+
}: {
|
| 65 |
+
active: boolean;
|
| 66 |
+
onClick: () => void;
|
| 67 |
+
label: string;
|
| 68 |
+
title?: string;
|
| 69 |
+
}) {
|
| 70 |
+
return (
|
| 71 |
+
<button
|
| 72 |
+
onClick={onClick}
|
| 73 |
+
title={title}
|
| 74 |
+
className={`relative px-5 py-3 text-xs font-medium tracking-wide uppercase transition-colors ${
|
| 75 |
+
active ? "text-cyan-300" : "text-slate-400 hover:text-slate-100"
|
| 76 |
+
}`}
|
| 77 |
+
>
|
| 78 |
+
{label}
|
| 79 |
+
<span
|
| 80 |
+
className={`pointer-events-none absolute bottom-0 left-3 right-3 h-px transition-all ${
|
| 81 |
+
active
|
| 82 |
+
? "bg-cyan-400 shadow-[0_0_8px_rgba(56,189,248,0.55)]"
|
| 83 |
+
: "bg-transparent"
|
| 84 |
+
}`}
|
| 85 |
+
/>
|
| 86 |
+
</button>
|
| 87 |
+
);
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
export default function EpisodeViewer({
|
| 91 |
org,
|
| 92 |
dataset,
|
|
|
|
| 518 |
}
|
| 519 |
};
|
| 520 |
|
| 521 |
+
const renderTab = (tab: ActiveTab, label: string, title?: string) => (
|
| 522 |
+
<TabButton
|
| 523 |
+
active={activeTab === tab}
|
| 524 |
+
onClick={() => handleTabChange(tab)}
|
| 525 |
+
label={label}
|
| 526 |
+
title={title}
|
| 527 |
+
/>
|
| 528 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 529 |
|
| 530 |
return (
|
| 531 |
<div className="flex flex-col h-screen max-h-screen bg-[var(--bg)] text-[var(--text-primary)]">
|
| 532 |
{/* Top tab bar */}
|
| 533 |
<div className="flex items-center border-b border-white/5 bg-[var(--surface-0)] shrink-0">
|
| 534 |
+
{renderTab("episodes", "Episodes")}
|
| 535 |
{hasURDFSupport(datasetInfo.robot_type) &&
|
| 536 |
+
datasetInfo.codebase_version >= "v3.0" &&
|
| 537 |
+
renderTab("urdf", "3D Replay")}
|
| 538 |
+
{renderTab("statistics", "Statistics")}
|
| 539 |
+
{renderTab("filtering", "Filtering")}
|
| 540 |
+
{renderTab("frames", "Frames")}
|
| 541 |
+
{renderTab("insights", "Action Insights")}
|
| 542 |
+
{renderTab(
|
| 543 |
+
"doctor",
|
| 544 |
+
"Doctor",
|
| 545 |
+
"Dataset quality diagnostics (powered by lerobot-doctor)",
|
| 546 |
+
)}
|
|
|
|
| 547 |
<div className="ml-auto">
|
| 548 |
<HfAuthButton variant="tab" />
|
| 549 |
</div>
|