{hint}
} ++ The officer-transmission sidecar answered with an error. Check that the daemon is running and that + TRANSMISSION_URL points at it. +
++ {filters.isFiltered + ? 'Clear the filters in the sidebar to see everything again.' + : 'Add a magnet link or a .torrent file to get started.'} +
++ {torrent.metadataPercentComplete < 1 + ? 'Still fetching metadata — the file list appears once the magnet resolves.' + : 'This torrent has no files.'} +
+ ); + } + + const wantedCount = stats.filter((s) => s.wanted).length; + const wantedBytes = torrent.files.reduce((sum, f, i) => sum + (stats[i]?.wanted === false ? 0 : f.length), 0); + + const setWanted = (indices: number[], wanted: boolean) => + set.mutate({ ids: [torrent.id], [wanted ? 'files-wanted' : 'files-unwanted']: indices }); + + const setPriority = (indices: number[], priority: number) => { + const field = + priority === PRIORITY.High ? 'priority-high' : priority === PRIORITY.Low ? 'priority-low' : 'priority-normal'; + set.mutate({ ids: [torrent.id], [field]: indices }); + }; + + const toggleCollapsed = (key: string) => + setCollapsed((prev) => { + const next = new Set(prev); + if (next.has(key)) next.delete(key); + else next.add(key); + return next; + }); + + const renderNode = (node: FileNode, depth: number): React.ReactNode[] => { + const isDir = node.index == null; + const isCollapsed = collapsed.has(node.key); + const nodeStats = node.indices.map((i) => stats[i]).filter(Boolean); + const allWanted = nodeStats.length > 0 && nodeStats.every((s) => s!.wanted); + const someWanted = nodeStats.some((s) => s!.wanted); + const priorities = new Set(nodeStats.map((s) => s!.priority)); + const priority = priorities.size === 1 ? [...priorities][0]! : null; + const fraction = node.size > 0 ? node.completed / node.size : 0; + + const row = ( +{t.errorString}
+ )} + +No peers connected.
; + } + + return ( +| Address | +Client | +Progress | +Down | +Up | +Flags | +
|---|---|---|---|---|---|
|
+
+ {peer.isEncrypted && |
+ + {peer.clientName || '—'} + | +{formatPercent(peer.progress)} | +{formatSpeed(peer.rateToClient)} | +{formatSpeed(peer.rateToPeer)} | ++ {peer.flagStr} + | +
+ No trackers. This torrent relies on DHT and peer exchange. +
+ )} + +