From 56ddfbd16ef94f0dab1016eb7a33b078e08942e2 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Wed, 27 Mar 2024 22:23:24 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=B2=20Surfacing=20torrent=20progress?= =?UTF-8?q?=20in=20UI=20via=20scheduled=20job?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/ComicDetail/DownloadsPanel.tsx | 90 +++++++++++-------- .../ComicDetail/TorrentDownloads.tsx | 5 +- 2 files changed, 57 insertions(+), 38 deletions(-) diff --git a/src/client/components/ComicDetail/DownloadsPanel.tsx b/src/client/components/ComicDetail/DownloadsPanel.tsx index 5c13e0a..75d93e0 100644 --- a/src/client/components/ComicDetail/DownloadsPanel.tsx +++ b/src/client/components/ComicDetail/DownloadsPanel.tsx @@ -8,6 +8,7 @@ import axios from "axios"; import { LIBRARY_SERVICE_BASE_URI, QBITTORRENT_SERVICE_BASE_URI, + JOB_QUEUE_SERVICE_BASE_URI, } from "../../constants/endpoints"; import { useStore } from "../../store"; import { useShallow } from "zustand/react/shallow"; @@ -23,13 +24,26 @@ export const DownloadsPanel = ( const { comicObjectId } = useParams<{ comicObjectId: string }>(); const [bundles, setBundles] = useState([]); const [infoHashes, setInfoHashes] = useState([]); + const [torrentDetails, setTorrentDetails] = useState([]); const [activeTab, setActiveTab] = useState("torrents"); - const { airDCPPSocketInstance } = useStore( - useShallow((state) => ({ + const { airDCPPSocketInstance, socketIOInstance } = useStore( + useShallow((state: any) => ({ airDCPPSocketInstance: state.airDCPPSocketInstance, + socketIOInstance: state.socketIOInstance, })), ); + // React to torrent progress data sent over websockets + socketIOInstance.on("AS_TORRENT_DATA", (data) => { + const torrents = data.torrents + .flatMap(({ _id, details }) => { + if (_id === comicObjectId) { + return details; + } + }) + .filter((item) => item !== undefined); + setTorrentDetails(torrents); + }); // Fetch the downloaded files and currently-downloading file(s) from AirDC++ const { data: comicObject, isSuccess } = useQuery({ queryKey: ["bundles"], @@ -46,19 +60,19 @@ export const DownloadsPanel = ( }), }); - const { - data: torrentProperties, - isSuccess: torrentPropertiesFetched, - isFetching: torrentPropertiesFetching, - } = useQuery({ - queryFn: async () => - await axios({ - url: `${QBITTORRENT_SERVICE_BASE_URI}/getTorrentProperties`, - method: "POST", - data: { infoHashes }, - }), - queryKey: ["torrentProperties", infoHashes], - }); + // const { + // data: torrentProperties, + // isSuccess: torrentPropertiesFetched, + // isFetching: torrentPropertiesFetching, + // } = useQuery({ + // queryFn: async () => + // await axios({ + // url: `${QBITTORRENT_SERVICE_BASE_URI}/getTorrentProperties`, + // method: "POST", + // data: { infoHashes }, + // }), + // queryKey: ["torrentProperties", infoHashes], + // }); const getBundles = async (comicObject) => { if (comicObject?.data.acquisition.directconnect) { @@ -72,26 +86,24 @@ export const DownloadsPanel = ( } }; + // Call the scheduled job for fetching torrent data + // triggered by the active tab been set to "torrents" + const { data: torrentData } = useQuery({ + queryFn: () => + axios({ + url: `${JOB_QUEUE_SERVICE_BASE_URI}/getTorrentData`, + method: "GET", + params: { + trigger: activeTab, + }, + }), + queryKey: [activeTab], + }); + useEffect(() => { getBundles(comicObject).then((result) => { setBundles(result); }); - - if (comicObject?.data.acquisition.torrent.length !== 0) { - // Use the functional form of setInfoHashes to avoid race conditions - setInfoHashes(() => { - // Extract infoHashes from torrents and remove duplicates - const newInfoHashes: any = [ - ...new Set( - comicObject?.data.acquisition.torrent.map( - (torrent) => torrent.infoHash, - ), - ), - ]; - console.log(infoHashes); - return newInfoHashes; - }); - } }, [comicObject]); return ( @@ -116,7 +128,11 @@ export const DownloadsPanel = (