diff --git a/src/hooks/widgets/dashDot/api.ts b/src/hooks/widgets/dashDot/api.ts index 6c9b5380e..09342e32e 100644 --- a/src/hooks/widgets/dashDot/api.ts +++ b/src/hooks/widgets/dashDot/api.ts @@ -2,7 +2,7 @@ import { useMutation, useQuery } from '@tanstack/react-query'; import axios from 'axios'; import { Results } from 'sabnzbd-api'; import { useConfigContext } from '~/config/provider'; -import { api } from '~/utils/api'; +import { RouterInputs, api } from '~/utils/api'; import { UsenetInfoRequestParams, UsenetInfoResponse } from '../../../pages/api/modules/usenet'; import type { UsenetHistoryRequestParams } from '../../../pages/api/modules/usenet/history'; import { UsenetPauseRequestParams } from '../../../pages/api/modules/usenet/pause'; @@ -63,49 +63,24 @@ export const useGetUsenetHistory = (params: UsenetHistoryRequestParams) => { ); }; -export const usePauseUsenetQueue = (params: UsenetPauseRequestParams) => - useMutation( - ['usenetPause', ...Object.values(params)], - async () => - ( - await axios.post( - '/api/modules/usenet/pause', - {}, - { - 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: true, - }); - } - - return { previousInfo }; +export const usePauseUsenetQueueMutation = (params: UsenetPauseRequestParams) => { + const { name: configName } = useConfigContext(); + const { mutateAsync, mutate, ...mutation } = api.usenet.pause.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 }); + }, + } + ); + }; +}; export const useResumeUsenetQueue = (params: UsenetResumeRequestParams) => useMutation( diff --git a/src/server/api/routers/usenet/route.ts b/src/server/api/routers/usenet/route.ts index 914a4dfe7..b6d86127c 100644 --- a/src/server/api/routers/usenet/route.ts +++ b/src/server/api/routers/usenet/route.ts @@ -170,6 +170,52 @@ export const usenetRouter = createTRPCRouter({ total: history.noofslots, }; }), + pause: 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.pauseDownload(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).queuePause(); + }), }); export interface UsenetInfoResponse { diff --git a/src/widgets/useNet/UseNetTile.tsx b/src/widgets/useNet/UseNetTile.tsx index 0fac00916..e1741006c 100644 --- a/src/widgets/useNet/UseNetTile.tsx +++ b/src/widgets/useNet/UseNetTile.tsx @@ -10,7 +10,7 @@ import { useConfigContext } from '../../config/provider'; import { MIN_WIDTH_MOBILE } from '../../constants/constants'; import { useGetUsenetInfo, - usePauseUsenetQueue, + usePauseUsenetQueueMutation, useResumeUsenetQueue, } from '../../hooks/widgets/dashDot/api'; import { humanFileSize } from '../../tools/humanFileSize'; @@ -60,7 +60,7 @@ function UseNetTile({ widget }: UseNetTileProps) { } }, [downloadApps, selectedAppId]); - const { mutate: pause } = usePauseUsenetQueue({ appId: selectedAppId! }); + const pauseAsync = usePauseUsenetQueueMutation({ appId: selectedAppId! }); const { mutate: resume } = useResumeUsenetQueue({ appId: selectedAppId! }); if (downloadApps.length === 0) { @@ -111,7 +111,14 @@ function UseNetTile({ widget }: UseNetTileProps) { {t('info.paused')} ) : ( -