"use client"; import { useEffect, useRef, useState } from "react"; import { formatTimeCode, parseTimeCode } from "@/lib/time"; import type { TTimeCode } from "@/lib/time"; import { cn } from "@/utils/ui"; interface EditableTimecodeProps { time: number; duration: number; format?: TTimeCode; fps: number; onTimeChange?: ({ time }: { time: number }) => void; className?: string; disabled?: boolean; } export function EditableTimecode({ time, duration, format = "HH:MM:SS:FF", fps, onTimeChange, className, disabled = false, }: EditableTimecodeProps) { const [isEditing, setIsEditing] = useState(false); const [inputValue, setInputValue] = useState(""); const [hasError, setHasError] = useState(false); const inputRef = useRef(null); const enterPressedRef = useRef(false); const formattedTime = formatTimeCode({ timeInSeconds: time, format, fps }); const startEditing = () => { if (disabled) return; setIsEditing(true); setInputValue(formattedTime); setHasError(false); enterPressedRef.current = false; }; const cancelEditing = () => { setIsEditing(false); setInputValue(""); setHasError(false); enterPressedRef.current = false; }; const applyEdit = () => { const parsedTime = parseTimeCode({ timeCode: inputValue, format, fps }); if (parsedTime === null) { setHasError(true); return; } const clampedTime = Math.max( 0, duration ? Math.min(duration, parsedTime) : parsedTime, ); onTimeChange?.({ time: clampedTime }); setIsEditing(false); setInputValue(""); setHasError(false); enterPressedRef.current = false; }; const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === "Enter") { event.preventDefault(); enterPressedRef.current = true; applyEdit(); } else if (event.key === "Escape") { event.preventDefault(); cancelEditing(); } }; const handleInputChange = ({ target, }: React.ChangeEvent) => { setInputValue(target.value); setHasError(false); }; const handleBlur = () => { if (!enterPressedRef.current && isEditing) { applyEdit(); } }; const handleDisplayKeyDown = ( event: React.KeyboardEvent, ) => { if (disabled) return; if (event.key === "Enter" || event.key === " ") { event.preventDefault(); startEditing(); } }; useEffect(() => { if (isEditing && inputRef.current) { inputRef.current.focus(); inputRef.current.select(); } }, [isEditing]); if (isEditing) { return ( ); } return ( ); }