🏗️ Migrate usenet pause to tRPC

This commit is contained in:
Meier Lukas
2023-06-10 17:38:57 +02:00
parent 9cefe5d3a3
commit 7f39accf4b
3 changed files with 74 additions and 46 deletions

View File

@@ -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<Results>(
'/api/modules/usenet/pause',
{},
{
params,
}
)
).data,
{
async onMutate() {
await queryClient.cancelQueries(['usenetInfo', params.appId]);
const previousInfo = queryClient.getQueryData<UsenetInfoResponse>([
'usenetInfo',
params.appId,
]);
if (previousInfo) {
queryClient.setQueryData<UsenetInfoResponse>(['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<RouterInputs['usenet']['pause'], 'configName'>) => {
await mutateAsync(
{
configName: configName!,
...variables,
},
onError(err, _, context) {
if (context?.previousInfo) {
queryClient.setQueryData<UsenetInfoResponse>(
['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(

View File

@@ -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 {

View File

@@ -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) {
<IconPlayerPlay size={12} style={{ marginRight: 5 }} /> {t('info.paused')}
</Button>
) : (
<Button uppercase onClick={() => pause()} radius="xl" size="xs" fullWidth mt="sm">
<Button
uppercase
onClick={async () => pauseAsync({ appId: selectedAppId })}
radius="xl"
size="xs"
fullWidth
mt="sm"
>
<IconPlayerPause size={12} style={{ marginRight: 5 }} />{' '}
{dayjs.duration(data.eta, 's').format('HH:mm')}
</Button>