From e1da6ddcef21693edd2a4717d580568b421bc6fb Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Tue, 27 Feb 2024 22:15:32 -0500 Subject: [PATCH 1/9] =?UTF-8?q?=F0=9F=AA=A2=20Wiring=20up=20to=20addTorren?= =?UTF-8?q?t=20endpoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ComicDetail/TorrentSearchPanel.tsx | 74 +++++++++++++++++-- src/client/components/Search/Search.tsx | 6 +- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/src/client/components/ComicDetail/TorrentSearchPanel.tsx b/src/client/components/ComicDetail/TorrentSearchPanel.tsx index 983b561..05f6d40 100644 --- a/src/client/components/ComicDetail/TorrentSearchPanel.tsx +++ b/src/client/components/ComicDetail/TorrentSearchPanel.tsx @@ -3,12 +3,33 @@ import React, { useCallback, ReactElement, useEffect, useState } from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import axios from "axios"; import { Form, Field } from "react-final-form"; -import { PROWLARR_SERVICE_BASE_URI } from "../../constants/endpoints"; +import { + PROWLARR_SERVICE_BASE_URI, + QBITTORRENT_SERVICE_BASE_URI, +} from "../../constants/endpoints"; +import { isEmpty, isNil } from "lodash"; export const TorrentSearchPanel = (props): ReactElement => { const [prowlarrSettingsData, setProwlarrSettingsData] = useState({}); + const [searchTerm, setSearchTerm] = useState(""); + const [torrentToDownload, setTorrentToDownload] = useState([]); - const { data } = useQuery({ + const { data: qbittorrentConnectionResult } = useQuery({ + queryFn: async () => + axios({ + url: `${QBITTORRENT_SERVICE_BASE_URI}/connect`, + method: "POST", + data: { + hostname: "localhost", + protocol: "http", + port: "8080", + username: "admin", + password: "password", + }, + }), + queryKey: ["qbittorrentConnection"], + }); + const { data, isSuccess } = useQuery({ queryFn: async () => axios({ url: `${PROWLARR_SERVICE_BASE_URI}/search`, @@ -18,25 +39,46 @@ export const TorrentSearchPanel = (props): ReactElement => { apiKey: "c4f42e265fb044dc81f7e88bd41c3367", offset: 0, categories: [7030], - query: "the darkness", + query: searchTerm, host: "localhost", limit: 100, type: "search", indexerIds: [2], }, }), - queryKey: ["prowlarrSettingsData"], + queryKey: ["prowlarrSettingsData", searchTerm], + enabled: searchTerm !== "", }); - console.log(data?.data); + + const { data: addTorrentResult } = useQuery({ + queryFn: async () => + axios({ + url: `${QBITTORRENT_SERVICE_BASE_URI}/addTorrent`, + method: "POST", + data: { + torrentToDownload, + }, + }), + queryKey: ["addTorrentResult", torrentToDownload], + enabled: !isEmpty(torrentToDownload), + }); + console.log(addTorrentResult); + const searchProwlarrIndexer = (evt) => { + setSearchTerm(evt.searchTerm); + }; + const downloadTorrent = (evt) => { + console.log(evt); + setTorrentToDownload(evt); + }; return ( <>
{}} + onSubmit={searchProwlarrIndexer} initialValues={{}} render={({ handleSubmit, form, submitting, pristine, values }) => ( - + {({ input, meta }) => { return (
@@ -70,6 +112,24 @@ export const TorrentSearchPanel = (props): ReactElement => { )} />
+ {/* results */} +
    + {isSuccess && + data?.data.map((result, idx) => { + return ( +
  • +

    {result.fileName}

    +

    {result.indexer}

    + +
  • + ); + })} +
); }; diff --git a/src/client/components/Search/Search.tsx b/src/client/components/Search/Search.tsx index 07fe3db..ecc386d 100644 --- a/src/client/components/Search/Search.tsx +++ b/src/client/components/Search/Search.tsx @@ -1,9 +1,7 @@ import React, { useCallback, ReactElement, useState } from "react"; import { isNil, isEmpty } from "lodash"; import { IExtractedComicBookCoverFile, RootState } from "threetwo-ui-typings"; -import { importToDB } from "../../actions/fileops.actions"; -import { comicinfoAPICall } from "../../actions/comicinfo.actions"; -import { search } from "../../services/api/SearchApi"; + import { Form, Field } from "react-final-form"; import Card from "../shared/Carda"; import ellipsize from "ellipsize"; @@ -27,7 +25,6 @@ export const Search = ({}: ISearchProps): ReactElement => { const [comicVineMetadata, setComicVineMetadata] = useState({}); const getCVSearchResults = (searchQuery) => { setSearchQuery(searchQuery.search); - // queryClient.invalidateQueries({ queryKey: ["comicvineSearchResults"] }); }; const { @@ -146,6 +143,7 @@ export const Search = ({}: ISearchProps): ReactElement => { )} />
+ {isLoading && <>Loading kaka...} {!isNil(comicVineSearchResults?.data.results) && !isEmpty(comicVineSearchResults?.data.results) ? (
-- 2.49.1 From c89e4af32857c27968182b50b41bce94a9384d4d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Feb 2024 22:31:32 -0500 Subject: [PATCH 2/9] Bump es5-ext from 0.10.62 to 0.10.64 (#104) Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64. - [Release notes](https://github.com/medikoo/es5-ext/releases) - [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md) - [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64) --- updated-dependencies: - dependency-name: es5-ext dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1770293..cd65da9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5331,13 +5331,14 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es5-ext@^0.10.35, es5-ext@^0.10.50: - version "0.10.62" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" - integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== +es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@^0.10.62, es5-ext@~0.10.14: + version "0.10.64" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" + integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg== dependencies: es6-iterator "^2.0.3" es6-symbol "^3.1.3" + esniff "^2.0.1" next-tick "^1.1.0" es6-iterator@^2.0.3: @@ -5655,6 +5656,16 @@ eslint@^8.49.0: strip-ansi "^6.0.1" text-table "^0.2.0" +esniff@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" + integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== + dependencies: + d "^1.0.1" + es5-ext "^0.10.62" + event-emitter "^0.3.5" + type "^2.7.2" + espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" @@ -5708,6 +5719,14 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== + dependencies: + d "1" + es5-ext "~0.10.14" + events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" -- 2.49.1 From 41a94287291861de4bf78afd2892013c3a423bf6 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Thu, 7 Mar 2024 05:50:49 -0600 Subject: [PATCH 3/9] =?UTF-8?q?=F0=9F=A7=B2=20Added=20a=20torrent=20downlo?= =?UTF-8?q?ad=20sub-panel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/ComicDetail/AirDCPPBundles.tsx | 51 ++++++ .../components/ComicDetail/ComicDetail.tsx | 2 +- .../components/ComicDetail/DownloadsPanel.tsx | 147 +++++++++++------- .../ComicDetail/TorrentDownloads.tsx | 47 ++++++ .../ComicDetail/TorrentSearchPanel.tsx | 11 +- src/client/components/Library/Library.tsx | 2 +- 6 files changed, 200 insertions(+), 60 deletions(-) create mode 100644 src/client/components/ComicDetail/AirDCPPBundles.tsx create mode 100644 src/client/components/ComicDetail/TorrentDownloads.tsx diff --git a/src/client/components/ComicDetail/AirDCPPBundles.tsx b/src/client/components/ComicDetail/AirDCPPBundles.tsx new file mode 100644 index 0000000..66c47f1 --- /dev/null +++ b/src/client/components/ComicDetail/AirDCPPBundles.tsx @@ -0,0 +1,51 @@ +import React from "react"; +import prettyBytes from "pretty-bytes"; +import dayjs from "dayjs"; +import ellipsize from "ellipsize"; +import { map } from "lodash"; + +export const AirDCPPBundles = (props) => { + return ( +
+ + + + + + + + + + + {map(props.data, (bundle) => ( + + + + + + + ))} + +
+ Filename + + Size + + Download Time + + Bundle ID +
+
{ellipsize(bundle.name, 58)}
+ {ellipsize(bundle.target, 88)} +
+ {prettyBytes(bundle.size)} + + {dayjs + .unix(bundle.time_finished) + .format("h:mm on ddd, D MMM, YYYY")} + + {bundle.id} +
+
+ ); +}; diff --git a/src/client/components/ComicDetail/ComicDetail.tsx b/src/client/components/ComicDetail/ComicDetail.tsx index 4c52279..da1b4a7 100644 --- a/src/client/components/ComicDetail/ComicDetail.tsx +++ b/src/client/components/ComicDetail/ComicDetail.tsx @@ -351,7 +351,7 @@ export const ComicDetail = (data: ComicDetailProps): ReactElement => { ), name: "Torrent Search", - content: , + content: , shouldShow: true, }, { diff --git a/src/client/components/ComicDetail/DownloadsPanel.tsx b/src/client/components/ComicDetail/DownloadsPanel.tsx index 924e03c..8d1f796 100644 --- a/src/client/components/ComicDetail/DownloadsPanel.tsx +++ b/src/client/components/ComicDetail/DownloadsPanel.tsx @@ -1,12 +1,14 @@ import React, { useEffect, useContext, ReactElement, useState } from "react"; import { RootState } from "threetwo-ui-typings"; import { isEmpty, map } from "lodash"; -import prettyBytes from "pretty-bytes"; -import dayjs from "dayjs"; -import ellipsize from "ellipsize"; +import { AirDCPPBundles } from "./AirDCPPBundles"; +import { TorrentDownloads } from "./TorrentDownloads"; import { useQuery } from "@tanstack/react-query"; import axios from "axios"; -import { LIBRARY_SERVICE_BASE_URI } from "../../constants/endpoints"; +import { + LIBRARY_SERVICE_BASE_URI, + QBITTORRENT_SERVICE_BASE_URI, +} from "../../constants/endpoints"; import { useStore } from "../../store"; import { useShallow } from "zustand/react/shallow"; import { useParams } from "react-router-dom"; @@ -20,6 +22,8 @@ export const DownloadsPanel = ( ): ReactElement | null => { const { comicObjectId } = useParams<{ comicObjectId: string }>(); const [bundles, setBundles] = useState([]); + const [infoHashes, setInfoHashes] = useState([]); + const [activeTab, setActiveTab] = useState("torrents"); const { airDCPPSocketInstance } = useStore( useShallow((state) => ({ airDCPPSocketInstance: state.airDCPPSocketInstance, @@ -42,6 +46,36 @@ export const DownloadsPanel = ( }), }); + const { data: qbittorrentConnectionResult } = useQuery({ + queryFn: async () => + axios({ + url: `${QBITTORRENT_SERVICE_BASE_URI}/connect`, + method: "POST", + data: { + hostname: "localhost", + protocol: "http", + port: "8080", + username: "admin", + password: "password", + }, + }), + queryKey: ["qbittorrentConnection"], + }); + + const { + data: torrentProperties, + isSuccess: torrentPropertiesFetched, + isFetching: torrentPropertiesFetching, + } = useQuery({ + queryFn: async () => + await axios({ + url: `${QBITTORRENT_SERVICE_BASE_URI}/getTorrentDetails`, + method: "POST", + data: infoHashes, + }), + queryKey: ["torrentProperties", infoHashes], + }); + const getBundles = async (comicObject) => { if (comicObject?.data.acquisition.directconnect) { const filteredBundles = @@ -58,60 +92,65 @@ export const DownloadsPanel = ( getBundles(comicObject).then((result) => { setBundles(result); }); - }, [comicObject]); - const Bundles = (props) => { - return ( -
- - - - - - - - - - - {map(props.data, (bundle) => ( - - - - - - - ))} - -
- Filename - - Size - - Download Time - - Bundle ID -
-
{ellipsize(bundle.name, 58)}
- - {ellipsize(bundle.target, 88)} - -
- {prettyBytes(bundle.size)} - - {dayjs - .unix(bundle.time_finished) - .format("h:mm on ddd, D MMM, YYYY")} - - {bundle.id} -
-
- ); - }; + 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, + ), + ), + ]; + return newInfoHashes; + }); + } + }, [comicObject]); return (
- {!isEmpty(airDCPPSocketInstance) && !isEmpty(bundles) && ( - + {!isEmpty(airDCPPSocketInstance) && + !isEmpty(bundles) && + activeTab === "directconnect" && } + +
+
+ + + +
+ + +
+ + {activeTab === "torrents" && torrentPropertiesFetched && ( + )}
); diff --git a/src/client/components/ComicDetail/TorrentDownloads.tsx b/src/client/components/ComicDetail/TorrentDownloads.tsx new file mode 100644 index 0000000..b62f9e5 --- /dev/null +++ b/src/client/components/ComicDetail/TorrentDownloads.tsx @@ -0,0 +1,47 @@ +import React from "react"; +import dayjs from "dayjs"; +import prettyBytes from "pretty-bytes"; + +export const TorrentDownloads = (props) => { + const { data } = props; + console.log(data); + return ( + <> + {data.map((torrent) => { + return ( +
+
{torrent.name}
+

{torrent.hash}

+

+ Added on{" "} + {dayjs.unix(torrent.addition_date).format("ddd, D MMM, YYYY")} +

+
+ {/* Peers */} + + + + + + {torrent.peers_total} + + + + {/* Size */} + + + + + + {prettyBytes(torrent.total_size)} + + +
+
+ ); + })} + + ); +}; + +export default TorrentDownloads; diff --git a/src/client/components/ComicDetail/TorrentSearchPanel.tsx b/src/client/components/ComicDetail/TorrentSearchPanel.tsx index 05f6d40..af3eed9 100644 --- a/src/client/components/ComicDetail/TorrentSearchPanel.tsx +++ b/src/client/components/ComicDetail/TorrentSearchPanel.tsx @@ -10,9 +10,10 @@ import { import { isEmpty, isNil } from "lodash"; export const TorrentSearchPanel = (props): ReactElement => { + const { comicObjectId } = props; const [prowlarrSettingsData, setProwlarrSettingsData] = useState({}); const [searchTerm, setSearchTerm] = useState(""); - const [torrentToDownload, setTorrentToDownload] = useState([]); + const [torrentToDownload, setTorrentToDownload] = useState(""); const { data: qbittorrentConnectionResult } = useQuery({ queryFn: async () => @@ -29,6 +30,7 @@ export const TorrentSearchPanel = (props): ReactElement => { }), queryKey: ["qbittorrentConnection"], }); + const { data, isSuccess } = useQuery({ queryFn: async () => axios({ @@ -57,12 +59,13 @@ export const TorrentSearchPanel = (props): ReactElement => { method: "POST", data: { torrentToDownload, + comicObjectId, }, }), - queryKey: ["addTorrentResult", torrentToDownload], - enabled: !isEmpty(torrentToDownload), + queryKey: ["addTorrentResult"], + enabled: !isNil(torrentToDownload) && searchTerm !== "", }); - console.log(addTorrentResult); + console.log(torrentToDownload); const searchProwlarrIndexer = (evt) => { setSearchTerm(evt.searchTerm); }; diff --git a/src/client/components/Library/Library.tsx b/src/client/components/Library/Library.tsx index 6d1f299..3d4bde2 100644 --- a/src/client/components/Library/Library.tsx +++ b/src/client/components/Library/Library.tsx @@ -178,7 +178,7 @@ export const Library = (): ReactElement => { - Torrent: {info.getValue().torrent.downloads.length} + Torrent: {info.getValue().torrent.length}
-- 2.49.1 From f4408cd4930d40e870ad773f6899e0121dee8cc8 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Sat, 16 Mar 2024 18:34:41 -0400 Subject: [PATCH 4/9] =?UTF-8?q?=F0=9F=A7=B2=20Fixed=20the=20auto-populatio?= =?UTF-8?q?n=20of=20search=20box?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/ComicDetail/ComicDetail.tsx | 2 +- .../components/ComicDetail/DownloadsPanel.tsx | 16 -- .../ComicDetail/TorrentSearchPanel.tsx | 153 +++++++----------- .../QbittorrentConnectionForm.tsx | 12 +- 4 files changed, 60 insertions(+), 123 deletions(-) diff --git a/src/client/components/ComicDetail/ComicDetail.tsx b/src/client/components/ComicDetail/ComicDetail.tsx index da1b4a7..be36862 100644 --- a/src/client/components/ComicDetail/ComicDetail.tsx +++ b/src/client/components/ComicDetail/ComicDetail.tsx @@ -351,7 +351,7 @@ export const ComicDetail = (data: ComicDetailProps): ReactElement => { ), name: "Torrent Search", - content: , + content: , shouldShow: true, }, { diff --git a/src/client/components/ComicDetail/DownloadsPanel.tsx b/src/client/components/ComicDetail/DownloadsPanel.tsx index 8d1f796..618e78c 100644 --- a/src/client/components/ComicDetail/DownloadsPanel.tsx +++ b/src/client/components/ComicDetail/DownloadsPanel.tsx @@ -46,22 +46,6 @@ export const DownloadsPanel = ( }), }); - const { data: qbittorrentConnectionResult } = useQuery({ - queryFn: async () => - axios({ - url: `${QBITTORRENT_SERVICE_BASE_URI}/connect`, - method: "POST", - data: { - hostname: "localhost", - protocol: "http", - port: "8080", - username: "admin", - password: "password", - }, - }), - queryKey: ["qbittorrentConnection"], - }); - const { data: torrentProperties, isSuccess: torrentPropertiesFetched, diff --git a/src/client/components/ComicDetail/TorrentSearchPanel.tsx b/src/client/components/ComicDetail/TorrentSearchPanel.tsx index af3eed9..7a0c657 100644 --- a/src/client/components/ComicDetail/TorrentSearchPanel.tsx +++ b/src/client/components/ComicDetail/TorrentSearchPanel.tsx @@ -1,39 +1,23 @@ -import React, { useCallback, ReactElement, useEffect, useState } from "react"; - -import { useQuery, useQueryClient } from "@tanstack/react-query"; +import React, { useState } from "react"; +import { useQuery } from "@tanstack/react-query"; import axios from "axios"; import { Form, Field } from "react-final-form"; import { PROWLARR_SERVICE_BASE_URI, QBITTORRENT_SERVICE_BASE_URI, } from "../../constants/endpoints"; -import { isEmpty, isNil } from "lodash"; +import { isNil } from "lodash"; -export const TorrentSearchPanel = (props): ReactElement => { - const { comicObjectId } = props; - const [prowlarrSettingsData, setProwlarrSettingsData] = useState({}); - const [searchTerm, setSearchTerm] = useState(""); +export const TorrentSearchPanel = (props) => { + const { comicObjectId, issueName } = props; + // Initialize searchTerm with issueName from props + const [searchTerm, setSearchTerm] = useState({ issueName }); const [torrentToDownload, setTorrentToDownload] = useState(""); - const { data: qbittorrentConnectionResult } = useQuery({ - queryFn: async () => - axios({ - url: `${QBITTORRENT_SERVICE_BASE_URI}/connect`, - method: "POST", - data: { - hostname: "localhost", - protocol: "http", - port: "8080", - username: "admin", - password: "password", - }, - }), - queryKey: ["qbittorrentConnection"], - }); - const { data, isSuccess } = useQuery({ - queryFn: async () => - axios({ + queryKey: ["searchResults", searchTerm.issueName], + queryFn: async () => { + return await axios({ url: `${PROWLARR_SERVICE_BASE_URI}/search`, method: "POST", data: { @@ -41,97 +25,76 @@ export const TorrentSearchPanel = (props): ReactElement => { apiKey: "c4f42e265fb044dc81f7e88bd41c3367", offset: 0, categories: [7030], - query: searchTerm, + query: searchTerm.issueName, host: "localhost", limit: 100, type: "search", indexerIds: [2], }, - }), - queryKey: ["prowlarrSettingsData", searchTerm], - enabled: searchTerm !== "", + }); + }, + enabled: !isNil(searchTerm.issueName) && searchTerm.issueName.trim() !== "", // Make sure searchTerm is not empty }); - const { data: addTorrentResult } = useQuery({ - queryFn: async () => - axios({ - url: `${QBITTORRENT_SERVICE_BASE_URI}/addTorrent`, - method: "POST", - data: { - torrentToDownload, - comicObjectId, - }, - }), - queryKey: ["addTorrentResult"], - enabled: !isNil(torrentToDownload) && searchTerm !== "", - }); - console.log(torrentToDownload); - const searchProwlarrIndexer = (evt) => { - setSearchTerm(evt.searchTerm); - }; - const downloadTorrent = (evt) => { - console.log(evt); - setTorrentToDownload(evt); + const searchIndexer = (values) => { + setSearchTerm({ issueName: values.issueName }); // Update searchTerm based on the form submission }; + return ( <>
( + onSubmit={searchIndexer} + initialValues={searchTerm} + render={({ handleSubmit }) => ( - - {({ input, meta }) => { - return ( -
-
-
- -
- - - + + {({ input, meta }) => ( +
+
+
+ {/* Icon placeholder */} +
+ +
- ); - }} +
+ )}
)} />
- {/* results */}
    {isSuccess && - data?.data.map((result, idx) => { - return ( -
  • -

    {result.fileName}

    -

    {result.indexer}

    - -
  • - ); - })} + data?.data.map((result, idx) => ( +
  • +

    {result.fileName}

    +

    {result.indexer}

    + +
  • + ))}
); diff --git a/src/client/components/Settings/QbittorrentSettings/QbittorrentConnectionForm.tsx b/src/client/components/Settings/QbittorrentSettings/QbittorrentConnectionForm.tsx index 8b74121..e75ab4c 100644 --- a/src/client/components/Settings/QbittorrentSettings/QbittorrentConnectionForm.tsx +++ b/src/client/components/Settings/QbittorrentSettings/QbittorrentConnectionForm.tsx @@ -16,16 +16,7 @@ export const QbittorrentConnectionForm = (): ReactElement => { }); const hostDetails = data?.data?.bittorrent?.client?.host; // connect to qbittorrent client - const { data: connectionDetails } = useQuery({ - queryKey: [], - queryFn: async () => - await axios({ - url: "http://localhost:3060/api/qbittorrent/connect", - method: "POST", - data: hostDetails, - }), - enabled: !!hostDetails, - }); + // get qbittorrent client info const { data: qbittorrentClientInfo } = useQuery({ queryKey: ["qbittorrentClientInfo"], @@ -34,7 +25,6 @@ export const QbittorrentConnectionForm = (): ReactElement => { url: "http://localhost:3060/api/qbittorrent/getClientInfo", method: "GET", }), - enabled: !!connectionDetails, }); // Update action using a mutation const { mutate } = useMutation({ -- 2.49.1 From 173735da454886490c25e51b957c5ff61b9f66a6 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Sun, 24 Mar 2024 17:30:51 -0400 Subject: [PATCH 5/9] =?UTF-8?q?=F0=9F=A7=B2=20Added=20downloads=20panel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/ComicDetail/ComicDetail.tsx | 7 +- .../ComicDetail/ComicDetailContainer.tsx | 4 +- .../components/ComicDetail/DownloadsPanel.tsx | 5 +- .../ComicDetail/Tabs/ArchiveOperations.tsx | 11 +- .../ComicDetail/TorrentDownloads.tsx | 3 +- .../ComicDetail/TorrentSearchPanel.tsx | 140 +++++++++++++++--- 6 files changed, 139 insertions(+), 31 deletions(-) diff --git a/src/client/components/ComicDetail/ComicDetail.tsx b/src/client/components/ComicDetail/ComicDetail.tsx index be36862..293982c 100644 --- a/src/client/components/ComicDetail/ComicDetail.tsx +++ b/src/client/components/ComicDetail/ComicDetail.tsx @@ -357,7 +357,12 @@ export const ComicDetail = (data: ComicDetailProps): ReactElement => { { id: 6, name: "Downloads", - icon: <>{acquisition?.directconnect?.downloads?.length}, + icon: ( + <> + {acquisition?.directconnect?.downloads?.length + + acquisition?.torrent.length} + + ), content: !isNil(data.data) && !isEmpty(data.data) ? ( diff --git a/src/client/components/ComicDetail/ComicDetailContainer.tsx b/src/client/components/ComicDetail/ComicDetailContainer.tsx index 4701f3f..312def2 100644 --- a/src/client/components/ComicDetail/ComicDetailContainer.tsx +++ b/src/client/components/ComicDetail/ComicDetailContainer.tsx @@ -1,7 +1,5 @@ -import { isEmpty, isNil, isUndefined } from "lodash"; -import React, { ReactElement, useContext, useEffect, useState } from "react"; +import React, { ReactElement } from "react"; import { useParams } from "react-router-dom"; -import { getComicBookDetailById } from "../../actions/comicinfo.actions"; import { ComicDetail } from "../ComicDetail/ComicDetail"; import { useQuery } from "@tanstack/react-query"; import { LIBRARY_SERVICE_BASE_URI } from "../../constants/endpoints"; diff --git a/src/client/components/ComicDetail/DownloadsPanel.tsx b/src/client/components/ComicDetail/DownloadsPanel.tsx index 618e78c..5c13e0a 100644 --- a/src/client/components/ComicDetail/DownloadsPanel.tsx +++ b/src/client/components/ComicDetail/DownloadsPanel.tsx @@ -53,9 +53,9 @@ export const DownloadsPanel = ( } = useQuery({ queryFn: async () => await axios({ - url: `${QBITTORRENT_SERVICE_BASE_URI}/getTorrentDetails`, + url: `${QBITTORRENT_SERVICE_BASE_URI}/getTorrentProperties`, method: "POST", - data: infoHashes, + data: { infoHashes }, }), queryKey: ["torrentProperties", infoHashes], }); @@ -88,6 +88,7 @@ export const DownloadsPanel = ( ), ), ]; + console.log(infoHashes); return newInfoHashes; }); } diff --git a/src/client/components/ComicDetail/Tabs/ArchiveOperations.tsx b/src/client/components/ComicDetail/Tabs/ArchiveOperations.tsx index 6304884..d1edfc9 100644 --- a/src/client/components/ComicDetail/Tabs/ArchiveOperations.tsx +++ b/src/client/components/ComicDetail/Tabs/ArchiveOperations.tsx @@ -30,6 +30,8 @@ export const ArchiveOperations = (props): ReactElement => { const [currentImage, setCurrentImage] = useState([]); const [uncompressedArchive, setUncompressedArchive] = useState([]); const [imageAnalysisResult, setImageAnalysisResult] = useState({}); + const [shouldRefetchComicBookData, setShouldRefetchComicBookData] = + useState(false); const constructImagePaths = (data): Array => { return data?.map((path: string) => escapePoundSymbol(encodeURI(`${LIBRARY_SERVICE_HOST}/${path}`)), @@ -63,6 +65,7 @@ export const ArchiveOperations = (props): ReactElement => { if (isMounted) { setUncompressedArchive(uncompressedArchive); + setShouldRefetchComicBookData(true); } }, }); @@ -122,8 +125,9 @@ export const ArchiveOperations = (props): ReactElement => { enabled: false, }); - if (isSuccess) { + if (isSuccess && shouldRefetchComicBookData) { queryClient.invalidateQueries({ queryKey: ["comicBookMetadata"] }); + setShouldRefetchComicBookData(false); } // sliding panel init @@ -171,7 +175,8 @@ export const ArchiveOperations = (props): ReactElement => {
- {data.rawFileDetails.archive?.uncompressed ? ( + {data.rawFileDetails.archive?.uncompressed && + !isEmpty(uncompressedArchive) ? (
{ ) : null}
- {!data.rawFileDetails?.archive?.uncompressed ? ( + {isEmpty(uncompressedArchive) ? ( - - ))} - + +
+
+ The default search term is an auto-detected title; you may need to + change it to get better matches if the auto-detected one doesn't work. +
+
+ {!isEmpty(data?.data) ? ( +
+ + + + + + + + + + + {data?.data.map((result, idx) => ( + + + + + + + + ))} + +
+ Name + + Indexer + + Action +
+

{ellipsize(result.fileName, 90)}

+ {/* Seeders/Leechers */} +
+ + + + + + + {result.seeders} seeders + + + + + + + + + + {result.leechers} leechers + + + {/* Size */} + + + + + + + {prettyBytes(result.size)} + + + + {/* Files */} + + + + + + + {result.files} files + + +
+
+ {result.indexer} + + +
+
+ ) : null} ); }; -- 2.49.1 From 56ddfbd16ef94f0dab1016eb7a33b078e08942e2 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Wed, 27 Mar 2024 22:23:24 -0500 Subject: [PATCH 6/9] =?UTF-8?q?=F0=9F=A7=B2=20Surfacing=20torrent=20progre?= =?UTF-8?q?ss=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 = (
- {activeTab === "torrents" && torrentPropertiesFetched && ( - - )} + {activeTab === "torrents" && }
); }; diff --git a/src/client/components/ComicDetail/TorrentDownloads.tsx b/src/client/components/ComicDetail/TorrentDownloads.tsx index c952b48..b5aa0fe 100644 --- a/src/client/components/ComicDetail/TorrentDownloads.tsx +++ b/src/client/components/ComicDetail/TorrentDownloads.tsx @@ -4,10 +4,10 @@ import prettyBytes from "pretty-bytes"; export const TorrentDownloads = (props) => { const { data } = props; - console.log(data); + console.log(Object.values(data)); return ( <> - {data.map((torrent) => { + {data.map(({ torrent }) => { return (
{torrent.name}
@@ -15,6 +15,7 @@ export const TorrentDownloads = (props) => {

Added on {dayjs.unix(torrent.added_on).format("ddd, D MMM, YYYY")}

+

{torrent.progress}

{/* Peers */} -- 2.49.1 From aa3192bc1aff27ab67656efb6dc95f93f0a1d1c0 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Fri, 29 Mar 2024 19:35:57 -0400 Subject: [PATCH 7/9] =?UTF-8?q?=F0=9F=A7=B2=20Added=20visual=20indicators?= =?UTF-8?q?=20of=20torrent=20progress?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/ComicDetail/DownloadsPanel.tsx | 18 +------- .../ComicDetail/TorrentDownloads.tsx | 41 ++++++++++++++++--- .../ComicDetail/TorrentSearchPanel.tsx | 27 ++++++------ src/client/constants/endpoints.ts | 7 ++++ 4 files changed, 57 insertions(+), 36 deletions(-) diff --git a/src/client/components/ComicDetail/DownloadsPanel.tsx b/src/client/components/ComicDetail/DownloadsPanel.tsx index 75d93e0..8eb5d28 100644 --- a/src/client/components/ComicDetail/DownloadsPanel.tsx +++ b/src/client/components/ComicDetail/DownloadsPanel.tsx @@ -8,7 +8,7 @@ import axios from "axios"; import { LIBRARY_SERVICE_BASE_URI, QBITTORRENT_SERVICE_BASE_URI, - JOB_QUEUE_SERVICE_BASE_URI, + TORRENT_JOB_SERVICE_BASE_URI, } from "../../constants/endpoints"; import { useStore } from "../../store"; import { useShallow } from "zustand/react/shallow"; @@ -60,20 +60,6 @@ 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 getBundles = async (comicObject) => { if (comicObject?.data.acquisition.directconnect) { const filteredBundles = @@ -91,7 +77,7 @@ export const DownloadsPanel = ( const { data: torrentData } = useQuery({ queryFn: () => axios({ - url: `${JOB_QUEUE_SERVICE_BASE_URI}/getTorrentData`, + url: `${TORRENT_JOB_SERVICE_BASE_URI}/getTorrentData`, method: "GET", params: { trigger: activeTab, diff --git a/src/client/components/ComicDetail/TorrentDownloads.tsx b/src/client/components/ComicDetail/TorrentDownloads.tsx index b5aa0fe..d6e4b89 100644 --- a/src/client/components/ComicDetail/TorrentDownloads.tsx +++ b/src/client/components/ComicDetail/TorrentDownloads.tsx @@ -9,21 +9,52 @@ export const TorrentDownloads = (props) => { <> {data.map(({ torrent }) => { return ( -
+
{torrent.name}

{torrent.hash}

Added on {dayjs.unix(torrent.added_on).format("ddd, D MMM, YYYY")}

-

{torrent.progress}

+ +

+ {torrent.progress > 0 ? ( + <> + + + {Math.floor(torrent.progress * 100)}% + + {/* downloaded/left */} + + + + + + {prettyBytes(torrent.downloaded)} + + + {/* uploaded */} + + + + + {prettyBytes(torrent.uploaded)} + + + + ) : null} +

{/* Peers */} - - + + - {torrent.peers_total} + {torrent.trackers_count} diff --git a/src/client/components/ComicDetail/TorrentSearchPanel.tsx b/src/client/components/ComicDetail/TorrentSearchPanel.tsx index 96579a8..f296e6a 100644 --- a/src/client/components/ComicDetail/TorrentSearchPanel.tsx +++ b/src/client/components/ComicDetail/TorrentSearchPanel.tsx @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery } from "@tanstack/react-query"; import axios from "axios"; import { Form, Field } from "react-final-form"; import { @@ -37,25 +37,22 @@ export const TorrentSearchPanel = (props) => { }, enabled: !isNil(searchTerm.issueName) && searchTerm.issueName.trim() !== "", // Make sure searchTerm is not empty }); - const { data: addTorrentResult } = useQuery({ - queryFn: async () => - axios({ - url: `${QBITTORRENT_SERVICE_BASE_URI}/addTorrent`, - method: "POST", - data: { - comicObjectId, - torrentToDownload, - }, - }), - queryKey: ["addTorrentResult", torrentToDownload], - enabled: !isEmpty(torrentToDownload), + const mutation = useMutation({ + mutationFn: async (newTorrent) => + axios.post(`${QBITTORRENT_SERVICE_BASE_URI}/addTorrent`, newTorrent), + onSuccess: async (data) => { + console.log(data); + }, }); const searchIndexer = (values) => { setSearchTerm({ issueName: values.issueName }); // Update searchTerm based on the form submission }; const downloadTorrent = (evt) => { - console.log(evt); - setTorrentToDownload(evt); + const newTorrent = { + comicObjectId, + torrentToDownload: evt, + }; + mutation.mutate(newTorrent); }; return ( <> diff --git a/src/client/constants/endpoints.ts b/src/client/constants/endpoints.ts index 30600fa..2fc2125 100644 --- a/src/client/constants/endpoints.ts +++ b/src/client/constants/endpoints.ts @@ -97,3 +97,10 @@ export const PROWLARR_SERVICE_BASE_URI = hostURIBuilder({ port: "3060", apiPath: `/api/prowlarr`, }); + +export const TORRENT_JOB_SERVICE_BASE_URI = hostURIBuilder({ + protocol: "http", + host: import.meta.env.UNDERLYING_HOSTNAME || "localhost", + port: "3000", + apiPath: `/api/torrentjobs`, +}); -- 2.49.1 From b4d1b678b13cffbeb6a4a36c0c80dcd48e984ae7 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Fri, 29 Mar 2024 23:26:43 -0400 Subject: [PATCH 8/9] =?UTF-8?q?=F0=9F=92=85=F0=9F=8F=BC=20Formatting=20imp?= =?UTF-8?q?rovements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/ComicDetail/RawFileDetails.tsx | 2 +- .../components/ComicDetail/TabControls.tsx | 16 +++++++--------- .../components/ComicDetail/TorrentDownloads.tsx | 15 +++++++-------- src/client/components/shared/DatePicker.tsx | 1 - src/client/components/shared/MetadataPanel.tsx | 1 - 5 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/client/components/ComicDetail/RawFileDetails.tsx b/src/client/components/ComicDetail/RawFileDetails.tsx index 25fcf59..3811038 100644 --- a/src/client/components/ComicDetail/RawFileDetails.tsx +++ b/src/client/components/ComicDetail/RawFileDetails.tsx @@ -48,7 +48,7 @@ export const RawFileDetails = (props): ReactElement => {
{/* File extension */} - + diff --git a/src/client/components/ComicDetail/TabControls.tsx b/src/client/components/ComicDetail/TabControls.tsx index 636abce..984018c 100644 --- a/src/client/components/ComicDetail/TabControls.tsx +++ b/src/client/components/ComicDetail/TabControls.tsx @@ -1,15 +1,9 @@ -import React, { ReactElement, useEffect, useState } from "react"; +import React, { ReactElement, useState } from "react"; import { isNil } from "lodash"; export const TabControls = (props): ReactElement => { - // const comicBookDetailData = useSelector( - // (state: RootState) => state.comicInfo.comicBookDetail, - // ); const { filteredTabs, downloadCount } = props; const [active, setActive] = useState(filteredTabs[0].id); - // useEffect(() => { - // setActive(filteredTabs[0].id); - // }, [filteredTabs]); return ( <> @@ -19,7 +13,11 @@ export const TabControls = (props): ReactElement => { {filteredTabs.map(({ id, name, icon }) => ( setActive(id)} > @@ -28,7 +26,7 @@ export const TabControls = (props): ReactElement => { {id === 6 && !isNil(downloadCount) ? ( {/* download count */} - + {icon} diff --git a/src/client/components/ComicDetail/TorrentDownloads.tsx b/src/client/components/ComicDetail/TorrentDownloads.tsx index d6e4b89..4044157 100644 --- a/src/client/components/ComicDetail/TorrentDownloads.tsx +++ b/src/client/components/ComicDetail/TorrentDownloads.tsx @@ -20,7 +20,7 @@ export const TorrentDownloads = (props) => { {torrent.progress > 0 ? ( <> @@ -28,22 +28,21 @@ export const TorrentDownloads = (props) => { {Math.floor(torrent.progress * 100)}% {/* downloaded/left */} - - +

+ - + {prettyBytes(torrent.downloaded)} - {/* uploaded */} - + - + {prettyBytes(torrent.uploaded)} - +

) : null}

diff --git a/src/client/components/shared/DatePicker.tsx b/src/client/components/shared/DatePicker.tsx index 47b7436..221bd6a 100644 --- a/src/client/components/shared/DatePicker.tsx +++ b/src/client/components/shared/DatePicker.tsx @@ -6,7 +6,6 @@ import { DayPicker, SelectSingleEventHandler } from "react-day-picker"; import { usePopper } from "react-popper"; export const DatePickerDialog = (props) => { - console.log(props); const { setter, apiAction } = props; const [selected, setSelected] = useState(); const [isPopperOpen, setIsPopperOpen] = useState(false); diff --git a/src/client/components/shared/MetadataPanel.tsx b/src/client/components/shared/MetadataPanel.tsx index f339548..781658d 100644 --- a/src/client/components/shared/MetadataPanel.tsx +++ b/src/client/components/shared/MetadataPanel.tsx @@ -16,7 +16,6 @@ interface IMetadatPanelProps { containerStyle: any; } export const MetadataPanel = (props: IMetadatPanelProps): ReactElement => { - console.log(props); const { rawFileDetails, inferredMetadata, -- 2.49.1 From c6f719e78b12458335a2882b1962b3c736ffb3ab Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Sat, 30 Mar 2024 21:28:48 -0400 Subject: [PATCH 9/9] =?UTF-8?q?=F0=9F=92=85=F0=9F=8F=BC=20Formatting=20twe?= =?UTF-8?q?aks=20to=20tabs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/components/ComicDetail/DownloadsPanel.tsx | 6 +++--- src/client/components/ComicDetail/TabControls.tsx | 4 ++-- src/client/components/ComicDetail/TorrentDownloads.tsx | 8 ++++---- src/client/components/WantedComics/WantedComics.tsx | 4 +++- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/client/components/ComicDetail/DownloadsPanel.tsx b/src/client/components/ComicDetail/DownloadsPanel.tsx index 8eb5d28..eb385c3 100644 --- a/src/client/components/ComicDetail/DownloadsPanel.tsx +++ b/src/client/components/ComicDetail/DownloadsPanel.tsx @@ -116,8 +116,8 @@ export const DownloadsPanel = ( href="#" className={`shrink-0 rounded-lg p-2 text-sm font-medium hover:bg-gray-50 hover:text-gray-700 ${ activeTab === "directconnect" - ? "bg-slate-200 text-slate-800" - : "text-slate-200" + ? "bg-slate-200 dark:text-slate-200 dark:bg-slate-400 text-slate-800" + : "dark:text-slate-400 text-slate-800" }`} aria-current="page" onClick={() => setActiveTab("directconnect")} @@ -130,7 +130,7 @@ export const DownloadsPanel = ( className={`shrink-0 rounded-lg p-2 text-sm font-medium hover:bg-gray-50 hover:text-gray-700 ${ activeTab === "torrents" ? "bg-slate-200 text-slate-800" - : "text-slate-200" + : "dark:text-slate-400 text-slate-800" }`} onClick={() => setActiveTab("torrents")} > diff --git a/src/client/components/ComicDetail/TabControls.tsx b/src/client/components/ComicDetail/TabControls.tsx index 984018c..e3c5f15 100644 --- a/src/client/components/ComicDetail/TabControls.tsx +++ b/src/client/components/ComicDetail/TabControls.tsx @@ -13,9 +13,9 @@ export const TabControls = (props): ReactElement => { {filteredTabs.map(({ id, name, icon }) => (
{ <> {data.map(({ torrent }) => { return ( -
+
{torrent.name}

{torrent.hash}

@@ -28,7 +28,7 @@ export const TorrentDownloads = (props) => { {Math.floor(torrent.progress * 100)}% {/* downloaded/left */} -

+

@@ -48,7 +48,7 @@ export const TorrentDownloads = (props) => {

{/* Peers */} - + @@ -58,7 +58,7 @@ export const TorrentDownloads = (props) => { {/* Size */} - + diff --git a/src/client/components/WantedComics/WantedComics.tsx b/src/client/components/WantedComics/WantedComics.tsx index 48435b0..4f06343 100644 --- a/src/client/components/WantedComics/WantedComics.tsx +++ b/src/client/components/WantedComics/WantedComics.tsx @@ -10,6 +10,7 @@ export const WantedComics = (props): ReactElement => { const { data: wantedComics, isSuccess, + isFetched, isError, isLoading, } = useQuery({ @@ -41,6 +42,7 @@ export const WantedComics = (props): ReactElement => { minWidth: 350, accessorFn: (data) => data, cell: (value) => { + console.log("ASDASd", value); const row = value.getValue()._source; return row && ; }, @@ -172,7 +174,7 @@ export const WantedComics = (props): ReactElement => {
- {isSuccess ? ( + {isSuccess && wantedComics?.data.hits?.hits ? (