diff --git a/tools/sprite-generation/gui/src/App.tsx b/tools/sprite-generation/gui/src/App.tsx
index 02d1a529..df0b402d 100644
--- a/tools/sprite-generation/gui/src/App.tsx
+++ b/tools/sprite-generation/gui/src/App.tsx
@@ -17,6 +17,9 @@ function DashboardOrTheater(): ReactElement {
}
export function App(): ReactElement {
+ const [params] = useSearchParams()
+ const isTheater = params.get('spriteTheater') === 'true'
+
return (
-
+
+
+ Theater
+
+
+ Review
+
+
+
+ )}
} />
} />
diff --git a/tools/sprite-generation/gui/src/SpriteStream.tsx b/tools/sprite-generation/gui/src/SpriteStream.tsx
index d0999a6b..37ea49f8 100644
--- a/tools/sprite-generation/gui/src/SpriteStream.tsx
+++ b/tools/sprite-generation/gui/src/SpriteStream.tsx
@@ -7,7 +7,6 @@ import { colors } from './pages/theme'
const MAX_SPRITES = 60
const STREAM_HEIGHT = 110
const SPRITE_SIZE = 80
-const THEATER_SPRITE_SIZE = 120
const CARD_GAP = 16
const CARD_TOTAL = SPRITE_SIZE + CARD_GAP
const SSE_RETRY_DELAYS = [5000, 10000, 20000, 30000]
@@ -309,110 +308,6 @@ function ControlButton({
)
}
-function TheaterMode({
- sprites,
- newIds,
- scoredIds,
- onNavigate,
- onClose,
-}: {
- sprites: RecentVariant[]
- newIds: Set
- scoredIds: Set
- onNavigate: (id: string) => void
- onClose: () => void
-}): ReactNode {
- useEffect((): (() => void) => {
- const handler = (e: KeyboardEvent): void => {
- if (e.key === 'Escape') onClose()
- }
- window.addEventListener('keydown', handler)
- return (): void => window.removeEventListener('keydown', handler)
- }, [onClose])
-
- return (
-
-
-
- Sprite Theater
-
- {sprites.length} sprites
-
-
-
-
-
-
-
- {sprites.map((variant, i) => (
-
- onNavigate(variant.sprite_id)}
- size={THEATER_SPRITE_SIZE}
- />
-
- ))}
-
-
-
- )
-}
export function SpriteStream(): ReactNode {
const navigate = useNavigate()
@@ -642,22 +537,10 @@ export function SpriteStream(): ReactNode {
}
`
+ // When theater mode is active, SpriteTheaterPage handles the full view.
+ // SpriteStream hides itself to avoid rendering on top.
if (theater) {
- return (
- <>
-
- {
- toggleTheater(false)
- navigate(`/sprite/${id}`)
- }}
- onClose={(): void => toggleTheater(false)}
- />
- >
- )
+ return null
}
// Sprites are newest-first. Reverse so oldest is left, newest is right.
diff --git a/tools/sprite-generation/gui/src/api.ts b/tools/sprite-generation/gui/src/api.ts
index 3a5bf5f4..c487d340 100644
--- a/tools/sprite-generation/gui/src/api.ts
+++ b/tools/sprite-generation/gui/src/api.ts
@@ -110,6 +110,10 @@ export async function skipSprite(spriteId: string): Promise {
return requestVoid(`${API_BASE}/sprites/${spriteId}/skip`, { method: 'POST' })
}
+export async function rejectVariant(variantId: number): Promise {
+ return requestVoid(`${API_BASE}/variants/${variantId}/reject`, { method: 'POST' })
+}
+
export async function regenerateSprite(spriteId: string, prompt?: string, dimensionId?: number): Promise {
const body: Record = {}
if (prompt !== undefined) body.prompt = prompt
diff --git a/tools/sprite-generation/gui/src/global.css b/tools/sprite-generation/gui/src/global.css
new file mode 100644
index 00000000..ec0e8c05
--- /dev/null
+++ b/tools/sprite-generation/gui/src/global.css
@@ -0,0 +1,5 @@
+html, body {
+ margin: 0;
+ padding: 0;
+ background: #0a0a14;
+}
diff --git a/tools/sprite-generation/gui/src/main.tsx b/tools/sprite-generation/gui/src/main.tsx
index 59d7b2a3..5ebccd1b 100644
--- a/tools/sprite-generation/gui/src/main.tsx
+++ b/tools/sprite-generation/gui/src/main.tsx
@@ -1,3 +1,4 @@
+import './global.css'
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'