|
import { useMakeKlips } from '@/lib/hooks/use-makeklips'; |
|
import { createTimeframe } from '@/lib/utils'; |
|
import { MakeKlipsRefType } from '@/types/makeklips'; |
|
import { |
|
ChangeEvent, |
|
KeyboardEvent, |
|
MouseEvent, |
|
SyntheticEvent, |
|
forwardRef, |
|
useEffect, |
|
useRef, |
|
useState, |
|
} from 'react'; |
|
import { KeyFrame } from '@/types'; |
|
|
|
interface CaptionContainerProps { |
|
keyFrames: KeyFrame[]; |
|
} |
|
|
|
//TODO: transform frames to timestamps, use createTimeframe() |
|
export const Captions = forwardRef<MakeKlipsRefType, CaptionContainerProps>( |
|
({ keyFrames, ...rest }, ref) => { |
|
//TODO: use the global hook to handle word change |
|
|
|
const { getKeyFrames } = useMakeKlips(); |
|
// setKeyFrames(keyFrames); |
|
|
|
const frames = getKeyFrames(); |
|
|
|
return ( |
|
//TODO: set height to only be the height of player, scroll overflow |
|
<div |
|
{...rest} |
|
ref={ref} |
|
className='flex-1 gap-2 overflow-scroll flex flex-col bg-zinc-950 text-white p-4 overflow-y-auto max-h-full' |
|
> |
|
{frames |
|
.sort((a, b) => a.timeFrom - b.timeFrom) // Sort keyFrames by timeFrom property |
|
.map((keyFrame, index) => ( |
|
<CaptionBox |
|
key={index} |
|
id={keyFrame.id} |
|
timeFrom={keyFrame.timeFrom} |
|
timeTo={keyFrame.timeTo} |
|
text={keyFrame.text} |
|
{...keyFrame.data} |
|
/> |
|
))} |
|
</div> |
|
); |
|
} |
|
); |
|
|
|
Captions.displayName = 'Captions'; |
|
|
|
function CaptionBox({ id, timeFrom, timeTo, text }: KeyFrame) { |
|
console.log(text); |
|
const [value, setValue] = useState(text); |
|
const textareaRef = useRef<HTMLTextAreaElement>(null); |
|
// const [cursorPosition, setCursorPosition] = useState(0); |
|
|
|
const { getKeyFrames, updateKeyFrame, setKeyFrames } = useMakeKlips(); |
|
|
|
// const handleCursorChange = (e: KeyboardEvent) => { |
|
// const input = textareaRef.current; |
|
// if (input) { |
|
// const cursorPosition = input.selectionStart; |
|
// const textBeforeCursor = input.value.substring(0, cursorPosition); |
|
// const lineCount = textBeforeCursor.split('\n').length; |
|
// setCursorPosition(lineCount); |
|
// console.log(cursorPosition); |
|
// } |
|
// }; |
|
|
|
//TODO: on backspace, pop the sentence and append to first if last character is the newline sequence (\r\n) |
|
//TODO: on enter, sentence into another array element |
|
const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => { |
|
//FIXME: text and other elements are a render behind |
|
|
|
console.log(e.target.value); |
|
setValue(e.target.value); |
|
console.log(e.target.value.includes('\n\n')); |
|
|
|
// if pushed a double new line, just cut at the end of double \n and create a new keyframe |
|
if (e.target.value.includes('\n\n')) { |
|
// can create an empty string. should this be prevented and alerted to the user? |
|
|
|
//FIXME: we see a new object in console but no new CaptionBox appears |
|
const valueCutIntoArray = e.target.value.split('\n\n'); |
|
setValue(valueCutIntoArray[0]); |
|
updateKeyFrame(String(id), { |
|
text: valueCutIntoArray[0], |
|
timeFrom, |
|
timeTo, |
|
id, |
|
}); |
|
//TODO: calculate % |
|
//TODO: set timeFrom to receive the amount of frames corresponding the the % that the text is of the full text |
|
//TODO: prevent user from infinitely pressing Enter |
|
console.log(valueCutIntoArray[0].length + valueCutIntoArray[1].length); |
|
setKeyFrames((prevKeyFrames) => { |
|
return prevKeyFrames.concat({ |
|
id: prevKeyFrames.length + 1, |
|
text: valueCutIntoArray[1], |
|
timeFrom: 160, |
|
timeTo: 180, |
|
}); |
|
}); |
|
|
|
console.log(valueCutIntoArray); |
|
} else { |
|
updateKeyFrame(String(id), { |
|
text: value, |
|
timeFrom, |
|
timeTo, |
|
id, |
|
}); |
|
} |
|
|
|
const frames = getKeyFrames(); |
|
console.log(frames); |
|
}; |
|
return ( |
|
<div className='p-4 hover:bg-zinc-900 w-full rounded-2xl flex justify-between items-center !bg-zinc-900 flex-row'> |
|
<div style={{ direction: 'ltr' }} className='w-full'> |
|
<span |
|
suppressHydrationWarning |
|
className='text-xs px-2 font-sans block text-slate-500 font-display' |
|
> |
|
{timeFrom}-{timeTo} |
|
</span> |
|
|
|
{/* TODO: stretch textarea infinitely */} |
|
<textarea |
|
ref={textareaRef} |
|
className='resize-none w-full text-white bg-transparent overflow-hidden p-2 font-inherit' |
|
value={value} |
|
onChange={(e) => handleChange(e)} |
|
// onKeyUp={handleCursorChange} |
|
// onClick={handleCursorChange} |
|
// onSelect={handleCursorChange} |
|
/> |
|
</div> |
|
</div> |
|
); |
|
} |
|
|
|
export default Captions; |