♻️ Refactor hooks

This commit is contained in:
Manuel Ruwe
2022-12-23 17:29:58 +01:00
parent f3b601dc2d
commit c84d8b59fe
15 changed files with 17 additions and 17 deletions

154
src/hooks/api.ts Normal file
View File

@@ -0,0 +1,154 @@
import { useMutation, useQuery } from '@tanstack/react-query';
import axios from 'axios';
import { Results } from 'sabnzbd-api';
import {
UsenetQueueRequestParams,
UsenetQueueResponse,
} from '../pages/api/modules/usenet/queue';
import {
UsenetHistoryRequestParams,
UsenetHistoryResponse,
} from '../pages/api/modules/usenet/history';
import { UsenetInfoRequestParams, UsenetInfoResponse } from '../pages/api/modules/usenet';
import { UsenetPauseRequestParams } from '../pages/api/modules/usenet/pause';
import { queryClient } from '../tools/queryClient';
import { UsenetResumeRequestParams } from '../pages/api/modules/usenet/resume';
const POLLING_INTERVAL = 2000;
export const useGetUsenetInfo = (params: UsenetInfoRequestParams) =>
useQuery(
['usenetInfo', params.appId],
async () =>
(
await axios.get<UsenetInfoResponse>('/api/modules/usenet', {
params,
})
).data,
{
refetchInterval: POLLING_INTERVAL,
keepPreviousData: true,
retry: 2,
enabled: !!params.appId,
}
);
export const useGetUsenetDownloads = (params: UsenetQueueRequestParams) =>
useQuery(
['usenetDownloads', ...Object.values(params)],
async () =>
(
await axios.get<UsenetQueueResponse>('/api/modules/usenet/queue', {
params,
})
).data,
{
refetchInterval: POLLING_INTERVAL,
keepPreviousData: true,
retry: 2,
}
);
export const useGetUsenetHistory = (params: UsenetHistoryRequestParams) =>
useQuery(
['usenetHistory', ...Object.values(params)],
async () =>
(
await axios.get<UsenetHistoryResponse>('/api/modules/usenet/history', {
params,
})
).data,
{
refetchInterval: POLLING_INTERVAL,
keepPreviousData: true,
retry: 2,
}
);
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 };
},
onError(err, _, context) {
if (context?.previousInfo) {
queryClient.setQueryData<UsenetInfoResponse>(
['usenetInfo', params.appId],
context.previousInfo
);
}
},
onSettled() {
queryClient.invalidateQueries(['usenetInfo', params.appId]);
},
}
);
export const useResumeUsenetQueue = (params: UsenetResumeRequestParams) =>
useMutation(
['usenetResume', ...Object.values(params)],
async () =>
(
await axios.post<Results>(
'/api/modules/usenet/resume',
{},
{
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: false,
});
}
return { previousInfo };
},
onError(err, _, context) {
if (context?.previousInfo) {
queryClient.setQueryData<UsenetInfoResponse>(
['usenetInfo', params.appId],
context.previousInfo
);
}
},
onSettled() {
queryClient.invalidateQueries(['usenetInfo', params.appId]);
},
}
);

View File

@@ -0,0 +1,27 @@
import { useQuery } from '@tanstack/react-query';
import { IconSelectorItem } from '../types/iconSelector/iconSelectorItem';
export const useRepositoryIconsQuery = <TRepositoryIcon extends object>({
url,
converter,
}: {
url: string;
converter: (value: TRepositoryIcon) => IconSelectorItem;
}) =>
useQuery({
queryKey: ['repository-icons', { url }],
queryFn: async () => fetchRepositoryIcons<TRepositoryIcon>(url),
select(data) {
return data.map((x) => converter(x));
},
refetchOnWindowFocus: false,
});
const fetchRepositoryIcons = async <TRepositoryIcon extends object>(
url: string
): Promise<TRepositoryIcon[]> => {
const response = await fetch(
'https://api.github.com/repos/walkxcode/Dashboard-Icons/contents/png'
);
return response.json();
};

View File

@@ -0,0 +1,8 @@
import { MantineSize, useMantineTheme } from '@mantine/core';
import { useMediaQuery } from '@mantine/hooks';
export const useScreenLargerThan = (size: MantineSize | number) => {
const { breakpoints } = useMantineTheme();
const pixelCount = typeof size === 'string' ? breakpoints[size] : size;
return useMediaQuery(`(min-width: ${pixelCount}px)`);
};

View File

@@ -0,0 +1,8 @@
import { MantineSize, useMantineTheme } from '@mantine/core';
import { useMediaQuery } from '@mantine/hooks';
export const useScreenSmallerThan = (size: MantineSize | number) => {
const { breakpoints } = useMantineTheme();
const pixelCount = typeof size === 'string' ? breakpoints[size] : size;
return useMediaQuery(`(max-width: ${pixelCount}px)`);
};

View File

@@ -0,0 +1,22 @@
import { useEffect, useRef } from 'react';
export function useSetSafeInterval() {
const timers = useRef<NodeJS.Timer[]>([]);
function setSafeInterval(callback: () => void, delay: number) {
const newInterval = setInterval(callback, delay);
timers.current.push(newInterval);
return newInterval;
}
useEffect(
() => () => {
timers.current.forEach((t) => {
clearInterval(t);
});
},
[]
);
return setSafeInterval;
}