import { useEffect, useRef, useState } from 'react'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { AnimatePresence, motion } from 'framer-motion'; import { feedsApi } from '../api/feeds'; interface AddFeedModalProps { isOpen: boolean; onClose: () => void; } export function AddFeedModal({ isOpen, onClose }: AddFeedModalProps) { const [url, setUrl] = useState(''); const fileInputRef = useRef(null); const queryClient = useQueryClient(); const addFeedMutation = useMutation({ mutationFn: (u: string) => feedsApi.add({ url: u }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['feeds'] }); setUrl(''); onClose(); }, }); const importMutation = useMutation({ mutationFn: (file: File) => feedsApi.importOPML(file), onSuccess: (res) => { queryClient.invalidateQueries({ queryKey: ['feeds'] }); queryClient.invalidateQueries({ queryKey: ['articles'] }); window.alert(`${res.imported} flux importé(s), ${res.skipped} ignoré(s).`); onClose(); }, }); // Close on Escape useEffect(() => { if (!isOpen) return; const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, [isOpen, onClose]); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); addFeedMutation.mutate(url); }; const handleFile = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) importMutation.mutate(file); }; return ( {isOpen && ( e.stopPropagation()} >

Nouveau flux

Entrez l'URL d'un flux RSS ou Atom. FlowReader récupérera le titre et le contenu automatiquement.

setUrl(e.target.value)} className="input-field" placeholder="https://exemple.com/feed" required autoFocus />
{addFeedMutation.isError && (

Échec de l'ajout. Vérifiez l'URL du flux.

)}
{/* OPML import */}
)}
); }