import { useState } from 'react'; import { Loader2, X } from 'lucide-react'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { statusLabel, statusTone, TONE_CLASSES } from './format'; import { useTorrentDetail } from './useTransmissionData'; import { GeneralTab } from './detail/GeneralTab'; import { FilesTab } from './detail/FilesTab'; import { PeersTab } from './detail/PeersTab'; import { TrackersTab } from './detail/TrackersTab'; import { TrackersDialog } from './dialogs/TrackersDialog'; // The bottom pane of the torrents section, driven by ?selected= in the URL. // // It fetches its own torrent rather than being handed the row from the list: the list poll deliberately // omits files, peers and peersFrom, and threading two shapes of the same object through the tree is how // you end up rendering a stale peer list. type TorrentDetailProps = { id: number; onClose: () => void }; export const TorrentDetail = ({ id, onClose }: TorrentDetailProps) => { const { torrent, isLoading } = useTorrentDetail(id); const [editingTrackers, setEditingTrackers] = useState(false); if (isLoading && !torrent) { return (
Loading…
); } if (!torrent) { return (
That torrent is gone.
); } const tone = TONE_CLASSES[statusTone(torrent)]; return (
{torrent.name} {statusLabel(torrent)}
General Files{torrent.files ? ` (${torrent.files.length})` : ''} Peers{torrent.peers ? ` (${torrent.peers.length})` : ''} Trackers{torrent.trackerStats ? ` (${torrent.trackerStats.length})` : ''} {/* mt-0 undoes the Tabs default spacing; these panes own their own scrolling. */} setEditingTrackers(true)} />
); };