import {useFieldArray, useFormContext} from 'react-hook-form'; import {CreateVideoPayload} from '@app/admin/videos/requests/use-create-video'; import {Trans} from '@common/i18n/trans'; import {DialogTrigger} from '@common/ui/overlays/dialog/dialog-trigger'; import {Button} from '@common/ui/buttons/button'; import {AddIcon} from '@common/icons/material/Add'; import {CrupdateCaptionDialog} from '@app/admin/videos/crupdate/crupdate-caption-dialog'; import {IllustratedMessage} from '@common/ui/images/illustrated-message'; import {SubtitlesIcon} from '@common/icons/material/Subtitles'; import {IconButton} from '@common/ui/buttons/icon-button'; import {DragHandleIcon} from '@common/icons/material/DragHandle'; import {Tooltip} from '@common/ui/tooltip/tooltip'; import {CloseIcon} from '@common/icons/material/Close'; import React, {useRef} from 'react'; import {useIsTouchDevice} from '@common/utils/hooks/is-touch-device'; import {DragPreviewRenderer} from '@common/ui/interactions/dnd/use-draggable'; import {DragPreview} from '@common/ui/interactions/dnd/drag-preview'; import {Video, VideoCaption} from '@app/titles/models/video'; import {SettingsIcon} from '@common/icons/material/Settings'; import {useSortable} from '@common/ui/interactions/dnd/sortable/use-sortable'; export function CaptionsPanel() { const {watch} = useFormContext(); const {fields, append, remove, swap, update} = useFieldArray< CreateVideoPayload, 'captions', 'key' >({ name: 'captions', keyName: 'key', }); const sourceType = watch('type'); const supportsCaptions = sourceType === 'video'; return (
{ if (values) { append(values); } }} >
{!supportsCaptions || !fields?.length ? ( } imageHeight="h-24" imageMargin="mb-12" title={} /> ) : null} {supportsCaptions && fields.map((caption, index) => ( swap(oldIndex, newIndex)} onRemove={() => remove(index)} onUpdate={values => update(index, values)} /> ))}
); } interface CaptionItemProps { caption: VideoCaption; captions: VideoCaption[]; onSort: (oldIndex: number, newIndex: number) => void; onRemove: () => void; onUpdate: (caption: VideoCaption) => void; } function CaptionItem({ caption, captions, onSort, onRemove, onUpdate, }: CaptionItemProps) { const domRef = useRef(null); const previewRef = useRef(null); const isTouchDevice = useIsTouchDevice(); const {sortableProps, dragHandleRef} = useSortable({ ref: domRef, disabled: isTouchDevice ?? false, item: caption, items: captions, type: 'captionItem', preview: previewRef, strategy: 'line', onSortEnd: (oldIndex, newIndex) => onSort(oldIndex, newIndex), }); return (
{caption.name}
{caption.language}
{ if (values) { onUpdate(values); } }} > }> onRemove()} className="text-muted"> }> onRemove()} className="text-danger">
); } interface CaptionItemDragPreviewProps { caption: VideoCaption; } const CaptionItemDragPreview = React.forwardRef< DragPreviewRenderer, CaptionItemDragPreviewProps >(({caption}, ref) => { return ( {() => (
{caption.name}
)}
); }); interface NoCaptionsMessageProps { sourceType: Video['type']; } function NoCaptionsMessage({sourceType}: NoCaptionsMessageProps) { switch (sourceType) { case 'video': return ; case 'stream': return ( ); default: return ; } }