File size: 3,383 Bytes
94e1b2f | 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 | import { useState } from 'react'
import { StudioPermissionModeModal } from './controls/StudioPermissionModeModal'
import { StudioAssetsPanel } from './components/StudioAssetsPanel'
import { StudioCommandPanel } from './components/StudioCommandPanel'
import { StudioPipelinePanel } from './components/StudioPipelinePanel'
import { useStudioReview } from './hooks/use-studio-review'
import { useStudioSession } from './hooks/use-studio-session'
import type { StudioKind } from './protocol/studio-agent-types'
interface StudioShellProps {
onExit: () => void
isExiting?: boolean
studioKind?: StudioKind
}
export function StudioShell({ onExit, isExiting, studioKind = 'manim' }: StudioShellProps) {
const studio = useStudioSession({
studioKind,
title: studioKind === 'plot' ? 'Plot Studio' : 'Manim Studio'
})
const [selectedWorkId, setSelectedWorkId] = useState<string | null>(null)
const effectiveSelectedWorkId =
selectedWorkId && studio.works.some((work) => work.id === selectedWorkId)
? selectedWorkId
: studio.works[0]?.id ?? null
const selected = studio.selectWork(effectiveSelectedWorkId)
const review = useStudioReview(selected.result)
return (
<>
<div
className={`h-screen overflow-hidden bg-bg-primary text-text-primary studio-shell-root ${
isExiting ? 'animate-studio-exit' : 'animate-studio-entrance'
}`}
>
<div className="fixed inset-0 pointer-events-none opacity-40">
<div className="absolute left-[-5%] top-[-10%] h-[40%] w-[40%] rounded-full bg-accent-rgb/10 blur-[120px]" />
<div className="absolute bottom-[-5%] right-[-5%] h-[35%] w-[35%] rounded-full bg-accent-rgb/5 blur-[100px]" />
</div>
<div className="relative flex h-screen min-h-0 overflow-hidden backdrop-blur-[2px]">
<StudioAssetsPanel
session={studio.session}
works={studio.workSummaries}
selectedWorkId={effectiveSelectedWorkId}
work={selected.work}
result={selected.result}
latestRun={studio.latestRun}
onSelectWork={setSelectedWorkId}
/>
<StudioCommandPanel
session={studio.session}
messages={studio.messages}
latestAssistantText={studio.latestAssistantText}
isBusy={studio.isBusy}
disabled={studio.isBusy || studio.state.connection.snapshotStatus !== 'ready'}
onRun={studio.runCommand}
onExit={onExit}
/>
<StudioPipelinePanel
latestRun={studio.latestRun}
work={selected.work}
result={selected.result}
tasks={selected.tasks}
review={review}
requests={studio.pendingPermissions}
replyingPermissionIds={studio.replyingPermissionIds}
latestAssistantText={studio.latestAssistantText}
latestQuestion={studio.latestQuestion}
snapshotStatus={studio.state.connection.snapshotStatus}
eventStatus={studio.state.connection.eventStatus}
errorMessage={studio.state.error ?? studio.state.connection.eventError}
onReply={studio.replyPermission}
onRefresh={studio.refresh}
/>
</div>
</div>
<StudioPermissionModeModal {...studio.permissionModeModal} />
</>
)
}
|