File size: 2,759 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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | import { useEffect } from 'react'
import { debugStudioMessages } from '../../agent-response/debug'
import { shouldRedirectKeyToInput } from './studio-command-typing'
interface UseStudioCommandPanelShortcutsOptions {
composer: {
input: string
focusInput: () => void
handleInputChange: (value: string) => void
handleDocumentPaste: (event: ClipboardEvent) => Promise<void>
}
disabled: boolean
onEscapePress?: () => void
}
export function useStudioCommandPanelShortcuts({
composer,
disabled,
onEscapePress,
}: UseStudioCommandPanelShortcutsOptions) {
useEffect(() => {
const handleWindowKeyDown = (event: KeyboardEvent) => {
if (event.defaultPrevented || event.metaKey || event.ctrlKey || event.altKey) {
return
}
if (event.key === 'Escape' && onEscapePress) {
event.preventDefault()
onEscapePress()
return
}
if (disabled) {
return
}
const target = event.target as HTMLElement | null
if (
target instanceof HTMLInputElement
|| target instanceof HTMLTextAreaElement
|| target?.isContentEditable
) {
return
}
if (!shouldRedirectKeyToInput(event)) {
return
}
composer.focusInput()
if (event.key === 'Backspace') {
composer.handleInputChange(composer.input.slice(0, -1))
event.preventDefault()
return
}
if (event.key.length === 1) {
composer.handleInputChange(`${composer.input}${event.key}`)
event.preventDefault()
}
}
window.addEventListener('keydown', handleWindowKeyDown)
return () => window.removeEventListener('keydown', handleWindowKeyDown)
}, [composer, disabled, onEscapePress])
useEffect(() => {
const handleDocumentPaste = (event: ClipboardEvent) => {
if (disabled) {
return
}
const target = event.target as HTMLElement | null
const isInputTarget =
target instanceof HTMLInputElement
|| target instanceof HTMLTextAreaElement
|| target?.isContentEditable
if (isInputTarget) {
return
}
const imageCount = Array.from(event.clipboardData?.items ?? []).filter((item) => (
item.kind === 'file' && item.type.startsWith('image/')
)).length
debugStudioMessages('command-panel-document-paste', {
imageCount,
targetTag: target?.tagName ?? null,
})
if (imageCount === 0) {
return
}
event.preventDefault()
void composer.handleDocumentPaste(event)
}
document.addEventListener('paste', handleDocumentPaste)
return () => document.removeEventListener('paste', handleDocumentPaste)
}, [composer, disabled])
}
|