'use client'; import { memo, type RefObject } from 'react'; import Link from 'next/link'; import { Image as ImageIcon, Loader2, Mic, Pause, Pencil, Play, Send, Tag, Trash2, X, } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import type { AnnotationStroke } from '@/components/annotation-canvas'; import { MentionTextarea } from '@/components/video-page/mention-textarea'; import type { CommentTag, VideoAsset } from '@/components/video-page/types'; interface CommentComposerProps { isRecording: boolean; recordingTime: number; stopRecording: () => void; cancelRecording: () => void; audioBlob: Blob | null; imageBlob: File | null; imageInputRef: RefObject; setImageBlob: (blob: File | null) => void; commentText: string; setCommentText: (value: string) => void; commentRangeStart: number | null; commentRangeEnd: number | null; toggleCommentRangeSelection: () => void; clearCommentRangeSelection: () => void; playVoice: (commentId: string, voiceUrl: string, knownDuration?: number) => void; playingVoiceId: string | null; voiceProgress: number; voiceCurrentTime: number; formatTime: (value: number) => string; toggleVoiceSpeed: () => void; voicePlaybackRate: number; submitCommentWithMedia: () => void; isUploadingAudio: boolean; isUploadingImage: boolean; annotationStrokes: AnnotationStroke[] | null; isAnnotating: boolean; setAnnotationStrokes: (strokes: AnnotationStroke[] | null) => void; setIsAnnotating: (value: boolean) => void; handleAddComment: () => void; isSubmittingComment: boolean; startRecording: () => void; handlePaste: (e: React.ClipboardEvent, isReply?: boolean) => void; handleImageSelect: (e: React.ChangeEvent, isReply?: boolean) => void; availableTags: CommentTag[]; selectedTagId: string | null; setSelectedTagId: (value: string | null) => void; canManageTags: boolean; projectId?: string; pauseVideoForAnnotation: () => void; assets: VideoAsset[]; } export const CommentComposer = memo(function CommentComposer({ isRecording, recordingTime, stopRecording, cancelRecording, audioBlob, imageBlob, imageInputRef, setImageBlob, commentText, setCommentText, commentRangeStart, commentRangeEnd, toggleCommentRangeSelection, clearCommentRangeSelection, playVoice, playingVoiceId, voiceProgress, voiceCurrentTime, formatTime, toggleVoiceSpeed, voicePlaybackRate, submitCommentWithMedia, isUploadingAudio, isUploadingImage, annotationStrokes, isAnnotating, setAnnotationStrokes, setIsAnnotating, handleAddComment, isSubmittingComment, startRecording, handlePaste, handleImageSelect, availableTags, selectedTagId, setSelectedTagId, canManageTags, projectId, pauseVideoForAnnotation, assets, }: CommentComposerProps) { const rangeButtonLabel = commentRangeStart === null || commentRangeEnd !== null ? 'Set In' : 'Set Out'; const hasCommentRange = commentRangeStart !== null; const commentRangeLabel = commentRangeStart !== null ? commentRangeEnd !== null ? `${formatTime(commentRangeStart)} - ${formatTime(commentRangeEnd)}` : `In ${formatTime(commentRangeStart)}` : null; return (
{isRecording ? (
Recording {formatTime(recordingTime)}
) : audioBlob ? (
{playingVoiceId === 'preview' ? `${formatTime(voiceCurrentTime)} / ${formatTime(recordingTime)}` : formatTime(recordingTime)} {playingVoiceId === 'preview' && ( )}
{imageBlob && (
{/* eslint-disable-next-line @next/next/no-img-element */} Preview
)}
{commentRangeLabel && ( {commentRangeLabel} )} {hasCommentRange && ( )}
) : ( <> {(annotationStrokes || isAnnotating) && (
Annotation attached
)} {imageBlob && (
{/* eslint-disable-next-line @next/next/no-img-element */} Preview
)}
{commentRangeLabel && ( {commentRangeLabel} )} {hasCommentRange && ( )}
{ if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) { handleAddComment(); } }} onPaste={(e) => handlePaste(e, false)} />
{availableTags.length > 0 && ( {availableTags.map((tag) => ( setSelectedTagId(tag.id)} className="gap-2" > {tag.name} {selectedTagId === tag.id && } ))} {canManageTags && ( <> Manage Tags )} )}

Cmd+Enter to submit

)}
); });