import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; export type DuplicateReason = { type: 'url', msg: string } | { type: 'file', msg: string }; type DuplicateResolution = 'rename' | 'replace' | 'skip'; export interface DuplicateConflict { id: string; // id of the pending item fileName: string; reason: DuplicateReason; resolution: DuplicateResolution; replaceAllowed?: boolean; existingDownloadId?: string; } interface Props { conflicts: DuplicateConflict[]; onConfirm: (resolutions: { id: string, resolution: DuplicateResolution }[]) => void; onCancel: () => void; } export const DuplicateResolutionModal = ({ conflicts: initialConflicts, onConfirm, onCancel }: Props) => { const { t } = useTranslation(); const [conflicts, setConflicts] = useState(initialConflicts); useEffect(() => { const handleEscape = (event: KeyboardEvent) => { if (event.key === 'Escape') onCancel(); }; window.addEventListener('keydown', handleEscape); return () => window.removeEventListener('keydown', handleEscape); }, [onCancel]); const updateResolution = (id: string, resolution: DuplicateResolution) => { setConflicts(conflicts.map(c => c.id === id ? { ...c, resolution } : c)); }; return (
{ if (event.target === event.currentTarget) onCancel(); }} role="dialog" aria-modal="true" >

{t($ => $.dialogs.duplicateDownloads.title)}

{t($ => $.dialogs.duplicateDownloads.description)}

{conflicts.map(conflict => (
{conflict.fileName} {conflict.reason.msg}
))}
); };