File size: 2,437 Bytes
abcf568 | 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 | import { useMemo, useState } from 'react'
import { useStudioSession } from '../../hooks/use-studio-session'
import { areSameIds, computeMaxHistorySlots, orderWorkSummaries } from '../utils/work-order'
export function usePlotStudioShell() {
const studio = useStudioSession({
studioKind: 'plot',
title: 'Plot Studio'
})
const [selectedWorkId, setSelectedWorkId] = useState<string | null>(null)
const [orderedWorkIds, setOrderedWorkIds] = useState<string[]>([])
const [confirmExitOpen, setConfirmExitOpen] = useState(false)
const [interruptArmedUntil, setInterruptArmedUntil] = useState<number | null>(null)
const orderedWorkSummaries = useMemo(
() => orderWorkSummaries(studio.workSummaries, orderedWorkIds),
[orderedWorkIds, studio.workSummaries]
)
const effectiveSelectedWorkId =
selectedWorkId && orderedWorkSummaries.some((entry) => entry.work.id === selectedWorkId)
? selectedWorkId
: orderedWorkSummaries[0]?.work.id ?? null
const selected = studio.selectWork(effectiveSelectedWorkId)
const historyCount = orderedWorkSummaries.length
const historyCountLabel = String(historyCount).padStart(2, '0')
const maxHistorySlots = computeMaxHistorySlots(historyCount)
const interruptHintActive = interruptArmedUntil !== null && interruptArmedUntil > Date.now()
const handleReorderWorks = (nextWorkIds: string[]) => {
setOrderedWorkIds((current) => (areSameIds(current, nextWorkIds) ? current : nextWorkIds))
}
const handleEscapePress = () => {
const activeRun = studio.latestRun
const runIsInterruptible = activeRun && (activeRun.status === 'pending' || activeRun.status === 'running')
if (!runIsInterruptible) {
setInterruptArmedUntil(null)
return
}
const now = Date.now()
if (interruptArmedUntil && interruptArmedUntil > now) {
setInterruptArmedUntil(null)
void studio.cancelCurrentRun('Cancelled by double-escape in Plot Studio')
return
}
setInterruptArmedUntil(now + 3000)
window.setTimeout(() => {
setInterruptArmedUntil((current) => (current && current <= Date.now() ? null : current))
}, 3100)
}
return {
studio,
selected,
orderedWorkSummaries,
effectiveSelectedWorkId,
historyCountLabel,
maxHistorySlots,
confirmExitOpen,
setConfirmExitOpen,
interruptHintActive,
setSelectedWorkId,
handleReorderWorks,
handleEscapePress,
}
}
|