diff --git a/src/components/modules/downloads/DownloadsModule.tsx b/src/components/modules/downloads/DownloadsModule.tsx index 03eefef29..4aa3fbb19 100644 --- a/src/components/modules/downloads/DownloadsModule.tsx +++ b/src/components/modules/downloads/DownloadsModule.tsx @@ -15,6 +15,7 @@ import { useEffect, useState } from 'react'; import axios from 'axios'; import { NormalizedTorrent } from '@ctrl/shared-torrent'; import { useViewportSize } from '@mantine/hooks'; +import { showNotification } from '@mantine/notifications'; import { IModule } from '../modules'; import { useConfig } from '../../../tools/state'; import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem'; @@ -52,12 +53,28 @@ export default function DownloadComponent() { useEffect(() => { setIsLoading(true); if (downloadServices.length === 0) return; - setSafeInterval(() => { + const interval = setSafeInterval(() => { // Send one request with each download service inside - axios.post('/api/modules/downloads', { config }).then((response) => { - setTorrents(response.data); - setIsLoading(false); - }); + axios + .post('/api/modules/downloads') + .then((response) => { + setTorrents(response.data); + setIsLoading(false); + }) + .catch((error) => { + setTorrents([]); + // eslint-disable-next-line no-console + console.error('Error while fetching torrents', error.response.data); + setIsLoading(false); + clearInterval(interval); + showNotification({ + title: 'Error fetching torrents', + autoClose: false, + color: 'red', + message: + 'Please check your config for any potential errors, check the console for more info', + }); + }); }, 5000); }, []); diff --git a/src/components/modules/downloads/TotalDownloadsModule.tsx b/src/components/modules/downloads/TotalDownloadsModule.tsx index 55f9be34d..af8830614 100644 --- a/src/components/modules/downloads/TotalDownloadsModule.tsx +++ b/src/components/modules/downloads/TotalDownloadsModule.tsx @@ -6,6 +6,7 @@ import { NormalizedTorrent } from '@ctrl/shared-torrent'; import { linearGradientDef } from '@nivo/core'; import { Datum, ResponsiveLine } from '@nivo/line'; import { useListState } from '@mantine/hooks'; +import { showNotification } from '@mantine/notifications'; import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem'; import { useConfig } from '../../../tools/state'; import { humanFileSize } from '../../../tools/humanFileSize'; @@ -43,10 +44,25 @@ export default function TotalDownloadsComponent() { const totalUploadSpeed = torrents.reduce((acc, torrent) => acc + torrent.uploadSpeed, 0); useEffect(() => { if (downloadServices.length === 0) return; - setSafeInterval(() => { - axios.post('/api/modules/downloads', { config }).then((response) => { - setTorrents(response.data); - }); + const interval = setSafeInterval(() => { + axios + .post('/api/modules/downloads') + .then((response) => { + setTorrents(response.data); + }) + .catch((error) => { + setTorrents([]); + // eslint-disable-next-line no-console + console.error('Error while fetching torrents', error.response.data); + clearInterval(interval); + showNotification({ + title: 'Error fetching torrents', + autoClose: false, + color: 'red', + message: + 'Please check your config for any potential errors, check the console for more info', + }); + }); }, 1000); }, [config.services]); diff --git a/src/components/modules/modules.tsx b/src/components/modules/modules.tsx index e1303ae33..5ba0c6373 100644 --- a/src/components/modules/modules.tsx +++ b/src/components/modules/modules.tsx @@ -1,11 +1,14 @@ // This interface is to be used in all the modules of the project // Each module should have its own interface and call the following function: // TODO: Add a function to register a module + +import { TablerIcon } from '@tabler/icons'; + // Note: Maybe use context to keep track of the modules export interface IModule { title: string; description: string; - icon: React.ReactNode; + icon: TablerIcon; component: React.ComponentType; options?: Option; } diff --git a/src/pages/api/modules/downloads.ts b/src/pages/api/modules/downloads.ts index a38dd55f8..736f8f672 100644 --- a/src/pages/api/modules/downloads.ts +++ b/src/pages/api/modules/downloads.ts @@ -2,12 +2,15 @@ import { Deluge } from '@ctrl/deluge'; import { QBittorrent } from '@ctrl/qbittorrent'; import { NormalizedTorrent } from '@ctrl/shared-torrent'; import { Transmission } from '@ctrl/transmission'; +import { getCookie } from 'cookies-next'; import { NextApiRequest, NextApiResponse } from 'next'; +import { getConfig } from '../../../tools/getConfig'; import { Config } from '../../../tools/types'; async function Post(req: NextApiRequest, res: NextApiResponse) { // Get the type of service from the request url - const { config }: { config: Config } = req.body; + const configName = getCookie('config-name', { req }); + const { config }: { config: Config } = getConfig(configName?.toString() ?? 'default').props; const qBittorrentServices = config.services.filter((service) => service.type === 'qBittorrent'); const delugeServices = config.services.filter((service) => service.type === 'Deluge'); const transmissionServices = config.services.filter((service) => service.type === 'Transmission'); @@ -20,40 +23,44 @@ async function Post(req: NextApiRequest, res: NextApiResponse) { message: 'Missing services', }); } - await Promise.all( - qBittorrentServices.map((service) => - new QBittorrent({ - baseUrl: service.url, - username: service.username, - password: service.password, - }) - .getAllData() - .then((e) => torrents.push(...e.torrents)) - ) - ); - await Promise.all( - delugeServices.map((service) => - new Deluge({ - baseUrl: service.url, - password: 'password' in service ? service.password : '', - }) - .getAllData() - .then((e) => torrents.push(...e.torrents)) - ) - ); - // Map transmissionServices - await Promise.all( - transmissionServices.map((service) => - new Transmission({ - baseUrl: service.url, - username: 'username' in service ? service.username : '', - password: 'password' in service ? service.password : '', - }) - .getAllData() - .then((e) => torrents.push(...e.torrents)) - ) - ); - res.status(200).json(torrents); + try { + await Promise.all( + qBittorrentServices.map((service) => + new QBittorrent({ + baseUrl: service.url, + username: service.username, + password: service.password, + }) + .getAllData() + .then((e) => torrents.push(...e.torrents)) + ) + ); + await Promise.all( + delugeServices.map((service) => + new Deluge({ + baseUrl: service.url, + password: 'password' in service ? service.password : '', + }) + .getAllData() + .then((e) => torrents.push(...e.torrents)) + ) + ); + // Map transmissionServices + await Promise.all( + transmissionServices.map((service) => + new Transmission({ + baseUrl: service.url, + username: 'username' in service ? service.username : '', + password: 'password' in service ? service.password : '', + }) + .getAllData() + .then((e) => torrents.push(...e.torrents)) + ) + ); + } catch (e: any) { + return res.status(401).json(e); + } + return res.status(200).json(torrents); } export default async (req: NextApiRequest, res: NextApiResponse) => { diff --git a/src/tools/getConfig.ts b/src/tools/getConfig.ts index 64082af04..b2a5559fa 100644 --- a/src/tools/getConfig.ts +++ b/src/tools/getConfig.ts @@ -14,7 +14,11 @@ export function getConfig(name: string) { settings: { searchUrl: 'https://www.google.com/search?q=', }, - modules: {}, + modules: { + 'Search Bar': { + enabled: true, + }, + }, }, }, };