diff --git a/src/components/AppShelf/AppShelf.tsx b/src/components/AppShelf/AppShelf.tsx index 050857e23..97b028997 100644 --- a/src/components/AppShelf/AppShelf.tsx +++ b/src/components/AppShelf/AppShelf.tsx @@ -155,8 +155,9 @@ const AppShelf = (props: any) => { ) : null} - { ${(config.settings.appOpacity || 100) / 100}`, }} > + diff --git a/src/components/Settings/SettingsMenu.tsx b/src/components/Settings/SettingsMenu.tsx index 78b968634..e6bcb2bed 100644 --- a/src/components/Settings/SettingsMenu.tsx +++ b/src/components/Settings/SettingsMenu.tsx @@ -11,7 +11,7 @@ function SettingsMenu(props: any) { - + diff --git a/src/components/modules/calendar/CalendarModule.tsx b/src/components/modules/calendar/CalendarModule.tsx index f483c2f77..a0b6574d1 100644 --- a/src/components/modules/calendar/CalendarModule.tsx +++ b/src/components/modules/calendar/CalendarModule.tsx @@ -1,5 +1,13 @@ /* eslint-disable react/no-children-prop */ -import { Box, Divider, Indicator, Popover, ScrollArea, createStyles, useMantineTheme } from '@mantine/core'; +import { + Box, + Divider, + Indicator, + Popover, + ScrollArea, + createStyles, + useMantineTheme, +} from '@mantine/core'; import React, { useEffect, useState } from 'react'; import { Calendar } from '@mantine/dates'; import { IconCalendar as CalendarIcon } from '@tabler/icons'; @@ -28,7 +36,7 @@ export default function CalendarComponent(props: any) { const theme = useMantineTheme(); const { secondaryColor } = useColorTheme(); const useStyles = createStyles((theme) => ({ - weekend: { + weekend: { color: `${secondaryColor} !important`, }, })); @@ -101,12 +109,13 @@ export default function CalendarComponent(props: any) { onChange={(day: any) => {}} dayStyle={(date) => date.getDay() === today.getDay() && date.getDate() === today.getDate() - ? { backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[0] } + ? { + backgroundColor: + theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[0], + } : {} } - dayClassName={(date, modifiers) => - cx({ [classes.weekend]: modifiers.weekend }) - } + dayClassName={(date, modifiers) => cx({ [classes.weekend]: modifiers.weekend })} renderDay={(renderdate) => ( @@ -81,21 +84,40 @@ export default function DownloadComponent() { ); } - + const DEVICE_WIDTH = 576; const ths = ( Name - Download - Upload + Size + {width > 576 ? Down : ''} + {width > 576 ? Up : ''} + ETA Progress ); + // Convert Seconds to readable format. + function calculateETA(givenSeconds: number) { + // If its superior than one day return > 1 day + if (givenSeconds > 86400) { + return '> 1 day'; + } + // Transform the givenSeconds into a readable format. e.g. 1h 2m 3s + const hours = Math.floor(givenSeconds / 3600); + const minutes = Math.floor((givenSeconds % 3600) / 60); + const seconds = Math.floor(givenSeconds % 60); + // Only show hours if it's greater than 0. + const hoursString = hours > 0 ? `${hours}h ` : ''; + const minutesString = minutes > 0 ? `${minutes}m ` : ''; + const secondsString = seconds > 0 ? `${seconds}s` : ''; + return `${hoursString}${minutesString}${secondsString}`; + } // Loop over qBittorrent torrents merging with deluge torrents const rows = torrents .filter((torrent) => !(torrent.progress === 1 && hideComplete)) .map((torrent) => { const downloadSpeed = torrent.downloadSpeed / 1024 / 1024; const uploadSpeed = torrent.uploadSpeed / 1024 / 1024; + const size = torrent.totalSelected; return ( @@ -112,16 +134,32 @@ export default function DownloadComponent() { - {downloadSpeed > 0 ? `${downloadSpeed.toFixed(1)} Mb/s` : '-'} + {humanFileSize(size)} + {width > 576 ? ( + + {downloadSpeed > 0 ? `${downloadSpeed.toFixed(1)} Mb/s` : '-'} + + ) : ( + '' + )} + {width > 576 ? ( + + {uploadSpeed > 0 ? `${uploadSpeed.toFixed(1)} Mb/s` : '-'} + + ) : ( + '' + )} - {uploadSpeed > 0 ? `${uploadSpeed.toFixed(1)} Mb/s` : '-'} + {torrent.eta <= 0 ? '∞' : calculateETA(torrent.eta)} {(torrent.progress * 100).toFixed(1)}% diff --git a/src/components/modules/downloads/TotalDownloadsModule.tsx b/src/components/modules/downloads/TotalDownloadsModule.tsx index 41b5b5413..55f9be34d 100644 --- a/src/components/modules/downloads/TotalDownloadsModule.tsx +++ b/src/components/modules/downloads/TotalDownloadsModule.tsx @@ -8,41 +8,10 @@ import { Datum, ResponsiveLine } from '@nivo/line'; import { useListState } from '@mantine/hooks'; import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem'; import { useConfig } from '../../../tools/state'; +import { humanFileSize } from '../../../tools/humanFileSize'; import { IModule } from '../modules'; import { useSetSafeInterval } from '../../../tools/hooks/useSetSafeInterval'; -/** - * Format bytes as human-readable text. - * - * @param bytes Number of bytes. - * @param si True to use metric (SI) units, aka powers of 1000. False to use - * binary (IEC), aka powers of 1024. - * @param dp Number of decimal places to display. - * - * @return Formatted string. - */ -function humanFileSize(initialBytes: number, si = true, dp = 1) { - const thresh = si ? 1000 : 1024; - let bytes = initialBytes; - - if (Math.abs(bytes) < thresh) { - return `${bytes} B`; - } - - const units = si - ? ['kb', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] - : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; - let u = -1; - const r = 10 ** dp; - - do { - bytes /= thresh; - u += 1; - } while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1); - - return `${bytes.toFixed(dp)} ${units[u]}`; -} - export const TotalDownloadsModule: IModule = { title: 'Download Speed', description: 'Show the current download speed of supported services', diff --git a/src/tools/humanFileSize.ts b/src/tools/humanFileSize.ts new file mode 100644 index 000000000..dfd6c9c1f --- /dev/null +++ b/src/tools/humanFileSize.ts @@ -0,0 +1,31 @@ +/** + * Format bytes as human-readable text. + * + * @param bytes Number of bytes. + * @param si True to use metric (SI) units, aka powers of 1000. False to use + * binary (IEC), aka powers of 1024. + * @param dp Number of decimal places to display. + * + * @return Formatted string. + */ +export function humanFileSize(initialBytes: number, si = true, dp = 1) { + const thresh = si ? 1000 : 1024; + let bytes = initialBytes; + + if (Math.abs(bytes) < thresh) { + return `${bytes} B`; + } + + const units = si + ? ['kb', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] + : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; + let u = -1; + const r = 10 ** dp; + + do { + bytes /= thresh; + u += 1; + } while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1); + + return `${bytes.toFixed(dp)} ${units[u]}`; +}