♻️ Refactor torrent network traffic widget #616

This commit is contained in:
Manuel
2023-01-22 21:35:13 +01:00
parent 2c2f3ea5f4
commit 653f8c6fd8
12 changed files with 543 additions and 450 deletions

View File

@@ -1,4 +1,3 @@
import { NormalizedTorrent } from '@ctrl/shared-torrent';
import {
Badge,
Center,
@@ -18,10 +17,8 @@ import dayjs from 'dayjs';
import duration from 'dayjs/plugin/duration';
import relativeTime from 'dayjs/plugin/relativeTime';
import { useTranslation } from 'next-i18next';
import { useEffect, useState } from 'react';
import { useConfigContext } from '../../config/provider';
import { useGetTorrentData } from '../../hooks/widgets/torrents/useGetTorrentData';
import { NormalizedTorrentListResponse } from '../../types/api/NormalizedTorrentListResponse';
import { useGetDownloadClientsQueue } from '../../hooks/widgets/download-speed/useGetNetworkSpeed';
import { NormalizedDownloadQueueResponse } from '../../types/api/downloads/queue/NormalizedDownloadQueueResponse';
import { AppIntegrationType } from '../../types/app';
import { defineWidget } from '../helper';
import { IWidget } from '../widgets';
@@ -44,13 +41,6 @@ const definition = defineWidget({
type: 'switch',
defaultValue: true,
},
refreshInterval: {
type: 'slider',
defaultValue: 10,
min: 1,
max: 60,
step: 1,
},
},
gridstack: {
minWidth: 2,
@@ -72,43 +62,17 @@ function TorrentTile({ widget }: TorrentTileProps) {
const MIN_WIDTH_MOBILE = useMantineTheme().breakpoints.xs;
const { width } = useElementSize();
const { config } = useConfigContext();
const downloadApps =
config?.apps.filter((x) => x.integration && downloadAppTypes.includes(x.integration.type)) ??
[];
const [selectedAppId, setSelectedApp] = useState<string | null>(downloadApps[0]?.id);
const {
data,
isError,
isInitialLoading,
dataUpdatedAt,
}: {
data: NormalizedTorrentListResponse | undefined;
data: NormalizedDownloadQueueResponse | undefined;
isError: boolean;
isInitialLoading: boolean;
dataUpdatedAt: number;
} = useGetTorrentData({
appId: selectedAppId!,
refreshInterval: widget.properties.refreshInterval * 1000,
});
useEffect(() => {
if (!selectedAppId && downloadApps.length) {
setSelectedApp(downloadApps[0].id);
}
}, [downloadApps, selectedAppId]);
if (downloadApps.length === 0) {
return (
<Stack>
<Title order={3}>{t('card.errors.noDownloadClients.title')}</Title>
<Group>
<Text>{t('card.errors.noDownloadClients.text')}</Text>
</Group>
</Stack>
);
}
} = useGetDownloadClientsQueue();
if (isError) {
return (
@@ -121,7 +85,7 @@ function TorrentTile({ widget }: TorrentTileProps) {
);
}
if (isInitialLoading) {
if (isInitialLoading || !data) {
return (
<Stack
align="center"
@@ -139,7 +103,18 @@ function TorrentTile({ widget }: TorrentTileProps) {
);
}
if (!data || Object.values(data.torrents).length < 1) {
if (data.apps.length === 0) {
return (
<Stack>
<Title order={3}>{t('card.errors.noDownloadClients.title')}</Title>
<Group>
<Text>{t('card.errors.noDownloadClients.text')}</Text>
</Group>
</Stack>
);
}
if (!data || Object.values(data.apps).length < 1) {
return (
<Center style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<Title order={3}>{t('card.table.body.nothingFound')}</Title>
@@ -147,17 +122,7 @@ function TorrentTile({ widget }: TorrentTileProps) {
);
}
const filter = (torrent: NormalizedTorrent) => {
if (!widget.properties.displayCompletedTorrents && torrent.isCompleted) {
return false;
}
if (!widget.properties.displayStaleTorrents && !torrent.isCompleted && torrent.eta <= 0) {
return false;
}
return true;
};
const torrents = data.apps.flatMap((app) => (app.type === 'torrent' ? app.torrents : []));
const difference = new Date().getTime() - dataUpdatedAt;
const duration = dayjs.duration(difference, 'ms');
@@ -178,19 +143,14 @@ function TorrentTile({ widget }: TorrentTileProps) {
</tr>
</thead>
<tbody>
{data.torrents.map((concatenatedTorrentList) => {
const app = config?.apps.find((x) => x.id === concatenatedTorrentList.appId);
return concatenatedTorrentList.torrents
.filter(filter)
.map((item: NormalizedTorrent, index: number) => (
<BitTorrrentQueueItem key={index} torrent={item} app={app} />
));
})}
{torrents.map((torrent, index) => (
<BitTorrrentQueueItem key={index} torrent={torrent} app={undefined} />
))}
</tbody>
</Table>
</ScrollArea>
<Group spacing="sm">
{!data.allSuccess && (
{data.apps.some((x) => !x.success) && (
<Badge variant="dot" color="red">
{t('card.footer.error')}
</Badge>