mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-10 15:35:55 +01:00
🐛 Fix multiple bugs and reformat code
This commit is contained in:
@@ -164,8 +164,9 @@ const AppShelf = (props: any) => {
|
||||
</Accordion.Item>
|
||||
) : null}
|
||||
<Accordion.Item key="Downloads" label="Your downloads">
|
||||
<ModuleMenu module={DownloadsModule} />
|
||||
<Paper
|
||||
p="lg"
|
||||
radius="lg"
|
||||
style={{
|
||||
background: `rgba(${colorScheme === 'dark' ? '37, 38, 43,' : '255, 255, 255,'} \
|
||||
${(config.settings.appOpacity || 100) / 100}`,
|
||||
@@ -173,6 +174,7 @@ const AppShelf = (props: any) => {
|
||||
${(config.settings.appOpacity || 100) / 100}`,
|
||||
}}
|
||||
>
|
||||
<ModuleMenu module={DownloadsModule} />
|
||||
<DownloadComponent />
|
||||
</Paper>
|
||||
</Accordion.Item>
|
||||
|
||||
@@ -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) => (
|
||||
<DayComponent
|
||||
renderdate={renderdate}
|
||||
|
||||
@@ -14,11 +14,11 @@ import { IconDownload as Download } from '@tabler/icons';
|
||||
import { useEffect, useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import { NormalizedTorrent } from '@ctrl/shared-torrent';
|
||||
import { useViewportSize } from '@mantine/hooks';
|
||||
import { IModule } from '../modules';
|
||||
import { useConfig } from '../../../tools/state';
|
||||
import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem';
|
||||
import { useSetSafeInterval } from '../../../tools/hooks/useSetSafeInterval';
|
||||
import { useViewportSize } from '@mantine/hooks';
|
||||
import { humanFileSize } from '../../../tools/humanFileSize';
|
||||
|
||||
export const DownloadsModule: IModule = {
|
||||
@@ -84,17 +84,33 @@ export default function DownloadComponent() {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const DEVICE_WIDTH = 576;
|
||||
const ths = (
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size</th>
|
||||
{width > 576 ? <th>Down</th> : ``}
|
||||
{width > 576 ? <th>Up</th> : ``}
|
||||
{width > 576 ? <th>Down</th> : ''}
|
||||
{width > 576 ? <th>Up</th> : ''}
|
||||
<th>ETA</th>
|
||||
<th>Progress</th>
|
||||
</tr>
|
||||
);
|
||||
// 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))
|
||||
@@ -102,29 +118,6 @@ export default function DownloadComponent() {
|
||||
const downloadSpeed = torrent.downloadSpeed / 1024 / 1024;
|
||||
const uploadSpeed = torrent.uploadSpeed / 1024 / 1024;
|
||||
const size = torrent.totalSelected;
|
||||
// Convert Seconds to readable format.
|
||||
function calculateETA(givenSeconds: number) {
|
||||
if (givenSeconds > 86399) { // No
|
||||
return ">1d"
|
||||
}
|
||||
const time = new Date(givenSeconds * 1000).toISOString();
|
||||
const hours = parseInt(time.substring(11,13));
|
||||
const minutes = parseInt(time.substring(14,16));
|
||||
const seconds = parseInt(time.substring(17,19));
|
||||
var str = "";
|
||||
// If tree go brr
|
||||
if (hours > 0) {
|
||||
str = `${hours}h `;
|
||||
}
|
||||
if (minutes > 0) {
|
||||
str = `${str}${minutes}m `
|
||||
}
|
||||
if (seconds > 0) {
|
||||
str = `${str}${seconds}s`;
|
||||
}
|
||||
return str.trim();
|
||||
}
|
||||
|
||||
return (
|
||||
<tr key={torrent.id}>
|
||||
<td>
|
||||
@@ -141,19 +134,22 @@ export default function DownloadComponent() {
|
||||
</Tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<Text size="xs">{humanFileSize(size)}</Text>
|
||||
<Text size="xs">{humanFileSize(size)}</Text>
|
||||
</td>
|
||||
{width > 576 ?
|
||||
<td>
|
||||
<Text size="xs">{downloadSpeed > 0 ? `${downloadSpeed.toFixed(1)} Mb/s` : '-'}</Text>
|
||||
</td>
|
||||
:
|
||||
``}
|
||||
{width > 576 ?
|
||||
<td>
|
||||
<Text size="xs">{uploadSpeed > 0 ? `${uploadSpeed.toFixed(1)} Mb/s` : '-'}</Text>
|
||||
</td> :
|
||||
``}
|
||||
{width > 576 ? (
|
||||
<td>
|
||||
<Text size="xs">{downloadSpeed > 0 ? `${downloadSpeed.toFixed(1)} Mb/s` : '-'}</Text>
|
||||
</td>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{width > 576 ? (
|
||||
<td>
|
||||
<Text size="xs">{uploadSpeed > 0 ? `${uploadSpeed.toFixed(1)} Mb/s` : '-'}</Text>
|
||||
</td>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<td>
|
||||
<Text size="xs">{torrent.eta <= 0 ? '∞' : calculateETA(torrent.eta)}</Text>
|
||||
</td>
|
||||
@@ -161,7 +157,9 @@ export default function DownloadComponent() {
|
||||
<Text>{(torrent.progress * 100).toFixed(1)}%</Text>
|
||||
<Progress
|
||||
radius="lg"
|
||||
color={torrent.state === "paused" ? 'yellow' : (torrent.progress === 1 ? 'green' : 'blue')}
|
||||
color={
|
||||
torrent.state === 'paused' ? 'yellow' : torrent.progress === 1 ? 'green' : 'blue'
|
||||
}
|
||||
value={torrent.progress * 100}
|
||||
size="lg"
|
||||
/>
|
||||
|
||||
@@ -12,17 +12,6 @@ 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.
|
||||
*/
|
||||
|
||||
export const TotalDownloadsModule: IModule = {
|
||||
title: 'Download Speed',
|
||||
description: 'Show the current download speed of supported services',
|
||||
|
||||
@@ -1,21 +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]}`;
|
||||
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]}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user