diff --git a/web/src/components/Item.tsx b/web/src/components/Item.tsx index 4cbddbb..2c5e1ef 100644 --- a/web/src/components/Item.tsx +++ b/web/src/components/Item.tsx @@ -5,20 +5,15 @@ import { ArrowsClockwiseIcon, CaretDownIcon, CaretUpIcon, - CheckCircleIcon, - DownloadSimpleIcon, TrashIcon, } from "@phosphor-icons/react"; -import { useDownloadTorrentMutation } from "../api/useDownloadTorrentMutation"; import { useDeleteItemMutation } from "../api/useDeleteItemMutation"; import { useQueryClient } from "@tanstack/react-query"; import dayjs from "dayjs"; import relativeTime from "dayjs/plugin/relativeTime"; -import { humanFileSize } from "../utils/humanFileSize"; -import { useDeleteTorrentMutation } from "../api/useDeleteTorrentMutation"; import { useRefreshItemMutation } from "../api/useRefreshItemMutation"; import { Loader } from "./Loader"; -import { categories } from "../lib/categories"; +import { Torrent } from "./Torrent"; dayjs.extend(relativeTime); @@ -34,9 +29,7 @@ export const Item = ({ item }: ItemProps) => { const { data: torrents } = useItemTorrentsQuery(item.id, open); const deleteMutation = useDeleteItemMutation(); - const downloadMutation = useDownloadTorrentMutation(); const refreshMutation = useRefreshItemMutation(); - const deleteTorrentMutation = useDeleteTorrentMutation(); const Icon = open ? CaretUpIcon : CaretDownIcon; @@ -61,10 +54,6 @@ export const Item = ({ item }: ItemProps) => { } }, [item]); - const handleDownloadTorrent = (torrentId: number) => { - downloadMutation.mutate({ torrentId }); - }; - const handleDelete = () => { if (!confirm("Do you want to delete this item?")) return; @@ -95,22 +84,6 @@ export const Item = ({ item }: ItemProps) => { ); }; - const handleDeleteTorrent = (torrentId: number) => { - deleteTorrentMutation.mutate( - { - id: torrentId, - }, - { - onSuccess() { - queryClient.invalidateQueries({ queryKey: ["items"] }); - queryClient.invalidateQueries({ - queryKey: ["items", item.id, "torrents"], - }); - }, - }, - ); - }; - return (
{
{filteredTorrents && filteredTorrents.length > 0 ? ( filteredTorrents.map((torrent) => ( -
-
- - - {torrent.title} - {" "} - [{formatCategory(torrent.category)}] [{torrent.indexer}] - - {torrent.downloaded && ( - - - - )} - -
-
- Seeds: {torrent.seeders} - Peers: {torrent.peers} - - PubDate: {dayjs(torrent.pubdate).format("DD.MM.YYYY")} at{" "} - {dayjs(torrent.pubdate).format("HH:mm")} - - - {humanFileSize(torrent.size)} -
-
+ )) ) : ( No torrents yet @@ -215,7 +146,3 @@ export const Item = ({ item }: ItemProps) => {
); }; - -const formatCategory = (category: number): string => { - return categories[category as keyof typeof categories] || ""; -}; diff --git a/web/src/components/Torrent.tsx b/web/src/components/Torrent.tsx new file mode 100644 index 0000000..b1db293 --- /dev/null +++ b/web/src/components/Torrent.tsx @@ -0,0 +1,116 @@ +import { useState } from "react"; +import type { ItemTorrent } from "../api/useItemTorrentsQuery"; +import { categories } from "../lib/categories"; +import { + ArrowSquareOutIcon, + CaretDownIcon, + CaretUpIcon, + CheckCircleIcon, + DownloadSimpleIcon, + TrashIcon, +} from "@phosphor-icons/react"; +import dayjs from "dayjs"; +import { humanFileSize } from "../utils/humanFileSize"; +import { useDeleteTorrentMutation } from "../api/useDeleteTorrentMutation"; +import { useDownloadTorrentMutation } from "../api/useDownloadTorrentMutation"; +import { useQueryClient } from "@tanstack/react-query"; + +export type TorrentProps = { + itemId: number; + torrent: ItemTorrent; +}; + +export const Torrent = ({ itemId, torrent }: TorrentProps) => { + const queryClient = useQueryClient(); + const downloadMutation = useDownloadTorrentMutation(); + const deleteMutation = useDeleteTorrentMutation(); + + const [open, setOpen] = useState(false); + + const ChevronIcon = open ? CaretUpIcon : CaretDownIcon; + + const handleDownload = () => { + downloadMutation.mutate({ torrentId: torrent.id }); + }; + + const handleDelete = () => { + deleteMutation.mutate( + { + id: torrent.id, + }, + { + onSuccess() { + queryClient.invalidateQueries({ queryKey: ["items"] }); + queryClient.invalidateQueries({ + queryKey: ["items", itemId, "torrents"], + }); + }, + }, + ); + }; + + return ( +
+
setOpen((prev) => !prev)} + > +

{torrent.title}

+ {torrent.downloaded && ( + + + + )} +
+ [{formatCategory(torrent.category)}] + {humanFileSize(torrent.size)} + + + +
+
+ + {open && ( +
+

Indexer: {torrent.indexer}

+

Seeders: {torrent.seeders}

+

Peers: {torrent.peers}

+

+ Published: {dayjs(torrent.pubdate).format("DD.MM.YYYY")} at{" "} + {dayjs(torrent.pubdate).format("HH:mm")} +

+
+ + Open + + + +
+
+ )} +
+ ); +}; + +const formatCategory = (category: number): string => { + return categories[category as keyof typeof categories] || ""; +};