diff --git a/src/hooks/widgets/dashDot/api.ts b/src/hooks/widgets/dashDot/api.ts index 09342e32e..612380eef 100644 --- a/src/hooks/widgets/dashDot/api.ts +++ b/src/hooks/widgets/dashDot/api.ts @@ -1,9 +1,8 @@ -import { useMutation, useQuery } from '@tanstack/react-query'; +import { useQuery } from '@tanstack/react-query'; import axios from 'axios'; -import { Results } from 'sabnzbd-api'; import { useConfigContext } from '~/config/provider'; import { RouterInputs, api } from '~/utils/api'; -import { UsenetInfoRequestParams, UsenetInfoResponse } from '../../../pages/api/modules/usenet'; +import { UsenetInfoRequestParams } from '../../../pages/api/modules/usenet'; import type { UsenetHistoryRequestParams } from '../../../pages/api/modules/usenet/history'; import { UsenetPauseRequestParams } from '../../../pages/api/modules/usenet/pause'; import type { @@ -11,7 +10,6 @@ import type { UsenetQueueResponse, } from '../../../pages/api/modules/usenet/queue'; import { UsenetResumeRequestParams } from '../../../pages/api/modules/usenet/resume'; -import { queryClient } from '../../../tools/server/configurations/tanstack/queryClient.tool'; const POLLING_INTERVAL = 2000; @@ -65,7 +63,7 @@ export const useGetUsenetHistory = (params: UsenetHistoryRequestParams) => { export const usePauseUsenetQueueMutation = (params: UsenetPauseRequestParams) => { const { name: configName } = useConfigContext(); - const { mutateAsync, mutate, ...mutation } = api.usenet.pause.useMutation(); + const { mutateAsync } = api.usenet.pause.useMutation(); const utils = api.useContext(); return async (variables: Omit) => { await mutateAsync( @@ -82,46 +80,21 @@ export const usePauseUsenetQueueMutation = (params: UsenetPauseRequestParams) => }; }; -export const useResumeUsenetQueue = (params: UsenetResumeRequestParams) => - useMutation( - ['usenetResume', ...Object.values(params)], - async () => - ( - await axios.post( - '/api/modules/usenet/resume', - {}, - { - params, - } - ) - ).data, - { - async onMutate() { - await queryClient.cancelQueries(['usenetInfo', params.appId]); - const previousInfo = queryClient.getQueryData([ - 'usenetInfo', - params.appId, - ]); - - if (previousInfo) { - queryClient.setQueryData(['usenetInfo', params.appId], { - ...previousInfo, - paused: false, - }); - } - - return { previousInfo }; +export const useResumeUsenetQueueMutation = (params: UsenetResumeRequestParams) => { + const { name: configName } = useConfigContext(); + const { mutateAsync } = api.usenet.resume.useMutation(); + const utils = api.useContext(); + return async (variables: Omit) => { + await mutateAsync( + { + configName: configName!, + ...variables, }, - onError(err, _, context) { - if (context?.previousInfo) { - queryClient.setQueryData( - ['usenetInfo', params.appId], - context.previousInfo - ); - } - }, - onSettled() { - queryClient.invalidateQueries(['usenetInfo', params.appId]); - }, - } - ); + { + onSettled() { + utils.usenet.info.invalidate({ appId: params.appId }); + }, + } + ); + }; +}; diff --git a/src/server/api/routers/usenet/route.ts b/src/server/api/routers/usenet/route.ts index b6d86127c..5e41b6a92 100644 --- a/src/server/api/routers/usenet/route.ts +++ b/src/server/api/routers/usenet/route.ts @@ -216,6 +216,53 @@ export const usenetRouter = createTRPCRouter({ return new Client(origin, apiKey).queuePause(); }), + resume: publicProcedure + .input( + z.object({ + configName: z.string(), + appId: z.string(), + }) + ) + .mutation(async ({ input }) => { + const config = getConfig(input.configName); + + const app = config.apps.find((x) => x.id === input.appId); + + if (!app || (app.integration?.type !== 'nzbGet' && app.integration?.type !== 'sabnzbd')) { + throw new Error(`App with ID "${input.appId}" could not be found.`); + } + + if (app.integration.type === 'nzbGet') { + const url = new URL(app.url); + const options = { + host: url.hostname, + port: url.port || (url.protocol === 'https:' ? '443' : '80'), + login: app.integration.properties.find((x) => x.field === 'username')?.value ?? undefined, + hash: app.integration.properties.find((x) => x.field === 'password')?.value ?? undefined, + }; + + const nzbGet = NzbgetClient(options); + + return new Promise((resolve, reject) => { + nzbGet.resumeDownload(false, (err: any, result: any) => { + if (!err) { + resolve(result); + } else { + reject(err); + } + }); + }); + } + + const apiKey = app.integration.properties.find((x) => x.field === 'apiKey')?.value; + if (!apiKey) { + throw new Error(`API Key for app "${app.name}" is missing`); + } + + const { origin } = new URL(app.url); + + return new Client(origin, apiKey).queueResume(); + }), }); export interface UsenetInfoResponse { diff --git a/src/widgets/useNet/UseNetTile.tsx b/src/widgets/useNet/UseNetTile.tsx index e1741006c..79aee3136 100644 --- a/src/widgets/useNet/UseNetTile.tsx +++ b/src/widgets/useNet/UseNetTile.tsx @@ -11,7 +11,7 @@ import { MIN_WIDTH_MOBILE } from '../../constants/constants'; import { useGetUsenetInfo, usePauseUsenetQueueMutation, - useResumeUsenetQueue, + useResumeUsenetQueueMutation, } from '../../hooks/widgets/dashDot/api'; import { humanFileSize } from '../../tools/humanFileSize'; import { AppIntegrationType } from '../../types/app'; @@ -61,7 +61,7 @@ function UseNetTile({ widget }: UseNetTileProps) { }, [downloadApps, selectedAppId]); const pauseAsync = usePauseUsenetQueueMutation({ appId: selectedAppId! }); - const { mutate: resume } = useResumeUsenetQueue({ appId: selectedAppId! }); + const resumeAsync = useResumeUsenetQueueMutation({ appId: selectedAppId! }); if (downloadApps.length === 0) { return ( @@ -107,7 +107,14 @@ function UseNetTile({ widget }: UseNetTileProps) { {!data ? null : data.paused ? ( - ) : (