import type { TorrentFile } from '../bindings/TorrentFile'; import type { TorrentFileSelectionEntry } from '../bindings/TorrentFileSelectionEntry'; import { normalizeTorrentWebSeedDrafts, type TorrentWebSeedDraft } from '../utils/downloads'; import { useEffect, useRef } from 'react'; import { useTranslation } from 'react-i18next'; type TorrentWebSeedFile = Pick | Pick; type Props = { files: readonly TorrentWebSeedFile[]; rows: readonly TorrentWebSeedDraft[]; onChange: (rows: TorrentWebSeedDraft[]) => void; disabled?: boolean; idPrefix: string; }; const filePath = (file: TorrentWebSeedFile): string => 'path' in file ? file.path : file.relativePath; export const TorrentWebSeedEditor = ({ files, rows, onChange, disabled = false, idPrefix }: Props) => { const { t } = useTranslation(); const uriRefs = useRef>([]); const addButtonRef = useRef(null); const focusAfterRemoveRef = useRef(null); const filesForValidation = files.map(file => ({ index: file.index })); const rowsAreValid = normalizeTorrentWebSeedDrafts(rows, filesForValidation) !== null; useEffect(() => { const rowIndex = focusAfterRemoveRef.current; focusAfterRemoveRef.current = null; if (rowIndex === -1) { addButtonRef.current?.focus(); } else if (rowIndex !== null) { uriRefs.current[rowIndex]?.focus(); } }, [rows]); const addRow = () => onChange([...rows, { fileIndex: files[0]?.index ?? null, uri: '' }]); const updateRow = (rowIndex: number, update: Partial) => onChange( rows.map((row, index) => index === rowIndex ? { ...row, ...update } : row) ); const removeRow = (rowIndex: number) => { const nextRows = rows.filter((_, index) => index !== rowIndex); focusAfterRemoveRef.current = nextRows.length > 0 ? Math.min(rowIndex, nextRows.length - 1) : -1; onChange(nextRows); }; return (
{rows.length === 0 && (

{t($ => $.properties.torrentWebSeedsEmpty)}

)} {rows.map((row, rowIndex) => { const rowId = `${idPrefix}-${rowIndex}`; const rowIsValid = normalizeTorrentWebSeedDrafts([row], filesForValidation) !== null; return (
{files.length === 1 ? ( ) : ( )}
{ uriRefs.current[rowIndex] = element; }} value={row.uri} onChange={event => updateRow(rowIndex, { uri: event.currentTarget.value })} disabled={disabled} dir="ltr" aria-invalid={!rowIsValid} placeholder="https://mirror.example/torrent/" className="app-control w-full min-h-[30px] px-2 py-1.5 text-xs font-mono disabled:opacity-50" />
); })} {rows.length > 0 && !rowsAreValid && (

{t($ => $.properties.torrentWebSeedsInvalid)}

)}
); };