setOpened(false)}
padding="xl"
position="right"
diff --git a/src/modules/Docker/DockerTable.tsx b/src/modules/Docker/DockerTable.tsx
index 2925e3990..70f597d23 100644
--- a/src/modules/Docker/DockerTable.tsx
+++ b/src/modules/Docker/DockerTable.tsx
@@ -7,6 +7,7 @@ import {
ScrollArea,
TextInput,
useMantineTheme,
+ Text,
} from '@mantine/core';
import { useElementSize } from '@mantine/hooks';
import { IconSearch } from '@tabler/icons';
@@ -78,8 +79,16 @@ export default function DockerTable({
transitionDuration={0}
/>
- | {element.Names[0].replace('/', '')} |
- {width > MIN_WIDTH_MOBILE && {element.Image} | }
+
+
+ {element.Names[0].replace('/', '')}
+
+ |
+ {width > MIN_WIDTH_MOBILE && (
+
+ {element.Image}
+ |
+ )}
{width > MIN_WIDTH_MOBILE && (
@@ -111,12 +120,13 @@ export default function DockerTable({
});
return (
-
+
}
value={search}
+ autoFocus
onChange={handleSearchChange}
/>
From a16866b269d3e9ee879a9ada5dcba9e30c3488e5 Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Mon, 23 Jan 2023 20:35:59 +0100
Subject: [PATCH 05/26] =?UTF-8?q?=F0=9F=90=9B=20Fix=20incorrect=20wrapper?=
=?UTF-8?q?=20position=20increment=20#630=20#621?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Components/Overview/AvailableElementsOverview.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/Dashboard/Modals/SelectElement/Components/Overview/AvailableElementsOverview.tsx b/src/components/Dashboard/Modals/SelectElement/Components/Overview/AvailableElementsOverview.tsx
index edb689821..d746ae334 100644
--- a/src/components/Dashboard/Modals/SelectElement/Components/Overview/AvailableElementsOverview.tsx
+++ b/src/components/Dashboard/Modals/SelectElement/Components/Overview/AvailableElementsOverview.tsx
@@ -50,7 +50,7 @@ export const AvailableElementTypes = ({
{
id: uuidv4(),
// Thank you ChatGPT ;)
- position: previousConfig.wrappers.length + 1,
+ position: previousConfig.categories.length + 1,
},
],
categories: [
From b94488175ed73424759e485455c2da406625008e Mon Sep 17 00:00:00 2001
From: ajnart
Date: Thu, 26 Jan 2023 23:23:11 +0900
Subject: [PATCH 06/26] Rework media display for Overseerr
Looks a lot better on mobile, fixes #502
---
src/components/layout/header/Search.tsx | 43 ++++++++++++++++---------
src/modules/common/MediaDisplay.tsx | 4 +--
2 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/src/components/layout/header/Search.tsx b/src/components/layout/header/Search.tsx
index 0cb7755d2..f927e2dd4 100644
--- a/src/components/layout/header/Search.tsx
+++ b/src/components/layout/header/Search.tsx
@@ -13,6 +13,7 @@ import {
import { useDebouncedValue, useHotkeys } from '@mantine/hooks';
import { showNotification } from '@mantine/notifications';
import { IconBrandYoutube, IconDownload, IconMovie, IconSearch } from '@tabler/icons';
+import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
import { useTranslation } from 'next-i18next';
import React, { forwardRef, useEffect, useRef, useState } from 'react';
@@ -142,13 +143,25 @@ export function Search() {
const [OverseerrResults, setOverseerrResults] = useState([]);
const [opened, setOpened] = useState(false);
- useEffect(() => {
- if (debounced !== '' && selectedSearchEngine.value === 'overseerr' && searchQuery.length > 3) {
- axios.get(`/api/modules/overseerr?query=${searchQuery}`).then((res) => {
- setOverseerrResults(res.data.results ?? []);
- });
+ const { data, isLoading, error } = useQuery(
+ ['overseerr', debounced],
+ async () => {
+ if (debounced !== '' && selectedSearchEngine.value === 'overseerr' && debounced.length > 3) {
+ const res = await axios.get(`/api/modules/overseerr?query=${debounced}`);
+ return res.data.results ?? [];
+ }
+ return [];
+ },
+ {
+ refetchOnWindowFocus: false,
+ refetchOnMount: false,
+ refetchInterval: false,
}
- }, [debounced]);
+ );
+
+ useEffect(() => {
+ setOverseerrResults(data ?? []);
+ }, [data]);
const isModuleEnabled = config?.settings.customization.layout.enabledSearchbar;
if (!isModuleEnabled) {
@@ -207,16 +220,14 @@ export function Search() {
/>
-
-
- {OverseerrResults.slice(0, 5).map((result, index) => (
-
-
- {index < OverseerrResults.length - 1 && }
-
- ))}
-
-
+
+ {OverseerrResults.slice(0, 4).map((result, index) => (
+
+
+ {index < OverseerrResults.length - 1 && index < 3 && }
+
+ ))}
+
diff --git a/src/modules/common/MediaDisplay.tsx b/src/modules/common/MediaDisplay.tsx
index 7c3631b18..7fea14508 100644
--- a/src/modules/common/MediaDisplay.tsx
+++ b/src/modules/common/MediaDisplay.tsx
@@ -180,7 +180,7 @@ export function MediaDisplay({ media }: { media: IMedia }) {
const { t } = useTranslation('modules/common-media-cards');
return (
-
+
@@ -223,7 +223,7 @@ export function MediaDisplay({ media }: { media: IMedia }) {
{media.overview}
-
+
{media.plexUrl && (
- {!data.allSuccess && (
+ {data.apps.some((x) => !x.success) && (
{t('card.footer.error')}
diff --git a/src/widgets/torrentNetworkTraffic/TorrentNetworkTrafficTile.tsx b/src/widgets/torrentNetworkTraffic/TorrentNetworkTrafficTile.tsx
deleted file mode 100644
index 3b494d130..000000000
--- a/src/widgets/torrentNetworkTraffic/TorrentNetworkTrafficTile.tsx
+++ /dev/null
@@ -1,198 +0,0 @@
-import { NormalizedTorrent } from '@ctrl/shared-torrent';
-import { Text, Title, Group, useMantineTheme, Box, Card, ColorSwatch, Stack } from '@mantine/core';
-import { useListState } from '@mantine/hooks';
-import { showNotification } from '@mantine/notifications';
-import { linearGradientDef } from '@nivo/core';
-import { Datum, ResponsiveLine } from '@nivo/line';
-import { IconArrowsUpDown } from '@tabler/icons';
-import axios from 'axios';
-import { useTranslation } from 'next-i18next';
-import { useEffect, useState } from 'react';
-import { useConfigContext } from '../../config/provider';
-import { useSetSafeInterval } from '../../hooks/useSetSafeInterval';
-import { humanFileSize } from '../../tools/humanFileSize';
-import { NormalizedTorrentListResponse } from '../../types/api/NormalizedTorrentListResponse';
-import { defineWidget } from '../helper';
-import { IWidget } from '../widgets';
-
-const definition = defineWidget({
- id: 'dlspeed',
- icon: IconArrowsUpDown,
- options: {},
-
- gridstack: {
- minWidth: 2,
- minHeight: 2,
- maxWidth: 12,
- maxHeight: 6,
- },
- component: TorrentNetworkTrafficTile,
-});
-
-export type ITorrentNetworkTraffic = IWidget;
-
-interface TorrentNetworkTrafficTileProps {
- widget: ITorrentNetworkTraffic;
-}
-
-function TorrentNetworkTrafficTile({ widget }: TorrentNetworkTrafficTileProps) {
- const { t } = useTranslation(`modules/${definition.id}`);
- const { colors } = useMantineTheme();
- const setSafeInterval = useSetSafeInterval();
- const { configVersion, config } = useConfigContext();
-
- const [torrentHistory, torrentHistoryHandlers] = useListState([]);
- const [torrents, setTorrents] = useState([]);
-
- const downloadServices =
- config?.apps.filter(
- (app) =>
- app.integration.type === 'qBittorrent' ||
- app.integration.type === 'transmission' ||
- app.integration.type === 'deluge'
- ) ?? [];
- const totalDownloadSpeed = torrents.reduce((acc, torrent) => acc + torrent.downloadSpeed, 0);
- const totalUploadSpeed = torrents.reduce((acc, torrent) => acc + torrent.uploadSpeed, 0);
-
- useEffect(() => {
- if (downloadServices.length === 0) return;
- const interval = setSafeInterval(() => {
- // Send one request with each download service inside
- axios
- .post('/api/modules/torrents')
- .then((response) => {
- const responseData: NormalizedTorrentListResponse = response.data;
- setTorrents(responseData.torrents.flatMap((x) => x.torrents));
- })
- .catch((error) => {
- if (error.status === 401) return;
- setTorrents([]);
- // eslint-disable-next-line no-console
- console.error('Error while fetching torrents', error.response.data);
- showNotification({
- title: 'Torrent speed module failed to fetch torrents',
- autoClose: 1000,
- disallowClose: true,
- id: 'fail-torrent-speed-module',
- color: 'red',
- message:
- 'Error fetching torrents, please check your config for any potential errors, check the console for more info',
- });
- clearInterval(interval);
- });
- }, 1000);
- }, [configVersion]);
-
- useEffect(() => {
- torrentHistoryHandlers.append({
- x: Date.now(),
- down: totalDownloadSpeed,
- up: totalUploadSpeed,
- });
- }, [totalDownloadSpeed, totalUploadSpeed]);
-
- const history = torrentHistory.slice(-10);
- const chartDataUp = history.map((load, i) => ({
- x: load.x,
- y: load.up,
- })) as Datum[];
- const chartDataDown = history.map((load, i) => ({
- x: load.x,
- y: load.down,
- })) as Datum[];
-
- return (
-
- {t('card.lineChart.title')}
-
-
-
-
- {t('card.lineChart.totalDownload', { download: humanFileSize(totalDownloadSpeed) })}
-
-
-
-
-
- {t('card.lineChart.totalUpload', { upload: humanFileSize(totalUploadSpeed) })}
-
-
-
-
- {
- const Download = slice.points[0].data.y as number;
- const Upload = slice.points[1].data.y as number;
- // Get the number of seconds since the last update.
- const seconds = (Date.now() - (slice.points[0].data.x as number)) / 1000;
- // Round to the nearest second.
- const roundedSeconds = Math.round(seconds);
- return (
-
- {t('card.lineChart.timeSpan', { seconds: roundedSeconds })}
-
-
-
-
-
- {t('card.lineChart.download', { download: humanFileSize(Download) })}
-
-
-
-
-
- {t('card.lineChart.upload', { upload: humanFileSize(Upload) })}
-
-
-
-
-
- );
- }}
- data={[
- {
- id: 'downloads',
- data: chartDataUp,
- },
- {
- id: 'uploads',
- data: chartDataDown,
- },
- ]}
- curve="monotoneX"
- yFormat=" >-.2f"
- axisTop={null}
- axisRight={null}
- enablePoints={false}
- animate={false}
- enableGridX={false}
- enableGridY={false}
- enableArea
- defs={[
- linearGradientDef('gradientA', [
- { offset: 0, color: 'inherit' },
- { offset: 100, color: 'inherit', opacity: 0 },
- ]),
- ]}
- fill={[{ match: '*', id: 'gradientA' }]}
- colors={[colors.blue[5], colors.green[5]]}
- />
-
-
- );
-}
-
-export default definition;
-
-interface TorrentHistory {
- x: number;
- up: number;
- down: number;
-}
diff --git a/src/widgets/useNet/UsenetQueueList.tsx b/src/widgets/useNet/UsenetQueueList.tsx
index 5fec4f842..aa3dc99e6 100644
--- a/src/widgets/useNet/UsenetQueueList.tsx
+++ b/src/widgets/useNet/UsenetQueueList.tsx
@@ -1,13 +1,11 @@
import {
ActionIcon,
Alert,
- Button,
Center,
Code,
Group,
Pagination,
Progress,
- ScrollArea,
Skeleton,
Stack,
Table,
From 2d3169682011d515cec65adab046744f3d2297ac Mon Sep 17 00:00:00 2001
From: Thomas Camlong <49837342+ajnart@users.noreply.github.com>
Date: Sun, 29 Jan 2023 04:52:54 +0900
Subject: [PATCH 12/26] =?UTF-8?q?=E2=9C=A8=20Add=20autocomplete=20to=20the?=
=?UTF-8?q?=20icon=20selection=20screen=20(#647)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Tabs/AppereanceTab/AppereanceTab.tsx | 10 +++++--
src/pages/api/getLocalImages.ts | 27 +++++++++++++++++++
2 files changed, 35 insertions(+), 2 deletions(-)
create mode 100644 src/pages/api/getLocalImages.ts
diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx
index 8e46d0f51..461bcef8a 100644
--- a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx
+++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx
@@ -1,5 +1,6 @@
-import { createStyles, Flex, Tabs, TextInput } from '@mantine/core';
+import { Autocomplete, createStyles, Flex, Tabs, TextInput } from '@mantine/core';
import { UseFormReturnType } from '@mantine/form';
+import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'next-i18next';
import { AppType } from '../../../../../../types/app';
import { DebouncedAppIcon } from '../Shared/DebouncedAppIcon';
@@ -18,16 +19,21 @@ export const AppearanceTab = ({
}: AppearanceTabProps) => {
const { t } = useTranslation('layout/modals/add-app');
const { classes } = useStyles();
+ const { isLoading, error, data } = useQuery({
+ queryKey: ['autocompleteLocale'],
+ queryFn: () => fetch('/api/getLocalImages').then((res) => res.json()),
+ });
return (
- }
label={t('appearance.icon.label')}
description={t('appearance.icon.description')}
variant="default"
+ data={isLoading ? [] : data.files}
withAsterisk
required
{...form.getInputProps('appearance.iconUrl')}
diff --git a/src/pages/api/getLocalImages.ts b/src/pages/api/getLocalImages.ts
new file mode 100644
index 000000000..94fea61c0
--- /dev/null
+++ b/src/pages/api/getLocalImages.ts
@@ -0,0 +1,27 @@
+import { NextApiRequest, NextApiResponse } from 'next';
+import fs from 'fs';
+
+function Get(req: NextApiRequest, res: NextApiResponse) {
+ // Get the name of all the files in the /public/icons folder handle if the folder doesn't exist
+ if (!fs.existsSync('./public/icons')) {
+ return res.status(200).json({
+ files: [],
+ });
+ }
+ const files = fs.readdirSync('./public/icons');
+ // Return the list of files with the /public/icons prefix
+ return res.status(200).json({
+ files: files.map((file) => `/icons/${file}`),
+ });
+}
+
+export default async (req: NextApiRequest, res: NextApiResponse) => {
+ // Filter out if the reuqest is a POST or a GET
+ if (req.method === 'GET') {
+ return Get(req, res);
+ }
+ return res.status(405).json({
+ statusCode: 405,
+ message: 'Method not allowed',
+ });
+};
From 118e3108845b0b9a05ee06ae5059f12e18e74210 Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Sat, 28 Jan 2023 20:56:18 +0100
Subject: [PATCH 13/26] =?UTF-8?q?=F0=9F=94=96=20Bump=20version=20from=200.?=
=?UTF-8?q?11.2=20to=200.11.3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
data/constants.ts | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/constants.ts b/data/constants.ts
index 5556a8966..b1ff95a49 100644
--- a/data/constants.ts
+++ b/data/constants.ts
@@ -1,3 +1,3 @@
export const REPO_URL = 'ajnart/homarr';
-export const CURRENT_VERSION = 'v0.11.2';
+export const CURRENT_VERSION = 'v0.11.3';
export const ICON_PICKER_SLICE_LIMIT = 36;
diff --git a/package.json b/package.json
index 41ffd4c40..ea144ed3e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "homarr",
- "version": "0.11.2",
+ "version": "0.11.3",
"description": "Homarr - A homepage for your server.",
"license": "MIT",
"repository": {
From 52a1dc552311fb33c96b23a084091722ddec3946 Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Sat, 28 Jan 2023 21:03:57 +0100
Subject: [PATCH 14/26] =?UTF-8?q?=F0=9F=92=84=20Fix=20margin=20for=20categ?=
=?UTF-8?q?ory=20accordeon?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/Dashboard/Wrappers/Category/Category.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/Dashboard/Wrappers/Category/Category.tsx b/src/components/Dashboard/Wrappers/Category/Category.tsx
index ff8ed886b..f2fda5028 100644
--- a/src/components/Dashboard/Wrappers/Category/Category.tsx
+++ b/src/components/Dashboard/Wrappers/Category/Category.tsx
@@ -30,7 +30,7 @@ export const DashboardCategory = ({ category }: DashboardCategoryProps) => {
classNames={{
item: cardClasses.card,
}}
- mx={0}
+ mx={10}
chevronPosition="left"
multiple
value={isEditMode ? categoryList : toggledCategories}
From dabb7c2409d74ab9c47ef9869fc0197fb4f6310e Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Sat, 28 Jan 2023 23:01:15 +0100
Subject: [PATCH 15/26] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Pull=20request=20fee?=
=?UTF-8?q?dback?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Tabs/AppereanceTab/AppereanceTab.tsx | 2 +-
.../Wrappers/Category/useCategoryActions.tsx | 2 +-
src/components/layout/header/Search.tsx | 19 ++++++++++---------
3 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx
index 461bcef8a..94da0611a 100644
--- a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx
+++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx
@@ -33,7 +33,7 @@ export const AppearanceTab = ({
label={t('appearance.icon.label')}
description={t('appearance.icon.description')}
variant="default"
- data={isLoading ? [] : data.files}
+ data={data.files ?? []}
withAsterisk
required
{...form.getInputProps('appearance.iconUrl')}
diff --git a/src/components/Dashboard/Wrappers/Category/useCategoryActions.tsx b/src/components/Dashboard/Wrappers/Category/useCategoryActions.tsx
index 925f825be..2ea0698ee 100644
--- a/src/components/Dashboard/Wrappers/Category/useCategoryActions.tsx
+++ b/src/components/Dashboard/Wrappers/Category/useCategoryActions.tsx
@@ -184,7 +184,7 @@ export const useCategoryActions = (configName: string | undefined, category: Cat
if (!configName) return;
updateConfig(
configName,
- (previous): ConfigType => {
+ (previous) => {
const currentItem = previous.categories.find((x) => x.id === category.id);
if (!currentItem) return previous;
// Find the main wrapper
diff --git a/src/components/layout/header/Search.tsx b/src/components/layout/header/Search.tsx
index f927e2dd4..bf9753425 100644
--- a/src/components/layout/header/Search.tsx
+++ b/src/components/layout/header/Search.tsx
@@ -140,10 +140,13 @@ export function Search() {
const openInNewTab = config?.settings.common.searchEngine.properties.openInNewTab
? '_blank'
: '_self';
- const [OverseerrResults, setOverseerrResults] = useState([]);
const [opened, setOpened] = useState(false);
- const { data, isLoading, error } = useQuery(
+ const {
+ data: OverseerrResults,
+ isLoading,
+ error,
+ } = useQuery(
['overseerr', debounced],
async () => {
if (debounced !== '' && selectedSearchEngine.value === 'overseerr' && debounced.length > 3) {
@@ -159,10 +162,6 @@ export function Search() {
}
);
- useEffect(() => {
- setOverseerrResults(data ?? []);
- }, [data]);
-
const isModuleEnabled = config?.settings.customization.layout.enabledSearchbar;
if (!isModuleEnabled) {
return null;
@@ -172,7 +171,7 @@ export function Search() {
return (
0 && opened && searchQuery.length > 3}
+ opened={OverseerrResults && OverseerrResults.length > 0 && opened && searchQuery.length > 3}
position="bottom"
withinPortal
shadow="md"
@@ -221,10 +220,12 @@ export function Search() {
- {OverseerrResults.slice(0, 4).map((result, index) => (
+ {OverseerrResults && OverseerrResults.slice(0, 4).map((result: any, index: number) => (
- {index < OverseerrResults.length - 1 && index < 3 && }
+ {index < OverseerrResults.length - 1 && index < 3 && (
+
+ )}
))}
From 67ee1bfb9d4e62414fcd55cda9114fbd7dbf1e9e Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Sun, 29 Jan 2023 14:21:35 +0100
Subject: [PATCH 16/26] =?UTF-8?q?=F0=9F=90=9B=20Fix=20crash=20and=20missin?=
=?UTF-8?q?g=20translations=20with=20icon=20picker?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
public/locales/en/layout/modals/icon-picker.json | 7 +++++++
.../EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx | 2 +-
.../Tabs/AppereanceTab/IconSelector/IconSelector.tsx | 2 +-
src/tools/translation-namespaces.ts | 2 +-
4 files changed, 10 insertions(+), 3 deletions(-)
create mode 100644 public/locales/en/layout/modals/icon-picker.json
diff --git a/public/locales/en/layout/modals/icon-picker.json b/public/locales/en/layout/modals/icon-picker.json
new file mode 100644
index 000000000..84f17ce54
--- /dev/null
+++ b/public/locales/en/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "Search something...",
+ "searchLimitationTitle": "Limited to 30 results",
+ "searchLimitationMessage": "Search results were limited to 30 because there were too many matches"
+ }
+}
\ No newline at end of file
diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx
index 94da0611a..f74ab7d60 100644
--- a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx
+++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx
@@ -33,7 +33,7 @@ export const AppearanceTab = ({
label={t('appearance.icon.label')}
description={t('appearance.icon.description')}
variant="default"
- data={data.files ?? []}
+ data={data?.files ?? []}
withAsterisk
required
{...form.getInputProps('appearance.iconUrl')}
diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/IconSelector/IconSelector.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/IconSelector/IconSelector.tsx
index 8ec13cbb3..ee853678a 100644
--- a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/IconSelector/IconSelector.tsx
+++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/IconSelector/IconSelector.tsx
@@ -31,7 +31,7 @@ interface IconSelectorProps {
}
export const IconSelector = ({ onChange, allowAppNamePropagation, form }: IconSelectorProps) => {
- const { t } = useTranslation('layout/tools');
+ const { t } = useTranslation('layout/modals/icon-picker');
const { data, isLoading } = useRepositoryIconsQuery({
url: 'https://api.github.com/repos/walkxcode/Dashboard-Icons/contents/png',
diff --git a/src/tools/translation-namespaces.ts b/src/tools/translation-namespaces.ts
index facb3cbd4..6748c77dc 100644
--- a/src/tools/translation-namespaces.ts
+++ b/src/tools/translation-namespaces.ts
@@ -1,9 +1,9 @@
export const dashboardNamespaces = [
'common',
- 'layout/tools',
'layout/element-selector/selector',
'layout/modals/add-app',
'layout/modals/change-position',
+ 'layout/modals/icon-picker',
'layout/modals/about',
'layout/header/actions/toggle-edit-mode',
'layout/mobile/drawer',
From cf45b4c82c3c996e48ab36e6ac39a362833f9ca6 Mon Sep 17 00:00:00 2001
From: Thomas Camlong <49837342+ajnart@users.noreply.github.com>
Date: Mon, 30 Jan 2023 00:09:35 +0900
Subject: [PATCH 17/26] =?UTF-8?q?=F0=9F=8C=90=20New=20Crowdin=20updates=20?=
=?UTF-8?q?(#617)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
public/locales/da/layout/modals/icon-picker.json | 7 +++++++
public/locales/de/layout/modals/icon-picker.json | 7 +++++++
public/locales/el/layout/modals/icon-picker.json | 7 +++++++
public/locales/el/settings/common.json | 2 +-
public/locales/el/settings/general/config-changer.json | 2 +-
public/locales/es/layout/modals/icon-picker.json | 7 +++++++
public/locales/fr/layout/modals/icon-picker.json | 7 +++++++
public/locales/he/layout/modals/icon-picker.json | 7 +++++++
public/locales/it/layout/modals/icon-picker.json | 7 +++++++
public/locales/it/modules/torrents-status.json | 8 ++++----
public/locales/ja/layout/modals/icon-picker.json | 7 +++++++
public/locales/ko/layout/modals/icon-picker.json | 7 +++++++
public/locales/lol/layout/modals/icon-picker.json | 7 +++++++
public/locales/nl/layout/modals/icon-picker.json | 7 +++++++
public/locales/pl/layout/modals/icon-picker.json | 7 +++++++
public/locales/pt/layout/modals/icon-picker.json | 7 +++++++
public/locales/ru/layout/modals/icon-picker.json | 7 +++++++
public/locales/sl/layout/modals/icon-picker.json | 7 +++++++
public/locales/sv/layout/modals/about.json | 2 +-
public/locales/sv/layout/modals/add-app.json | 2 +-
public/locales/sv/layout/modals/change-position.json | 4 ++--
public/locales/sv/layout/modals/icon-picker.json | 7 +++++++
public/locales/sv/modules/dashdot.json | 2 +-
public/locales/uk/layout/modals/icon-picker.json | 7 +++++++
public/locales/uk/modules/torrents-status.json | 4 ++--
public/locales/vi/layout/modals/icon-picker.json | 7 +++++++
public/locales/zh/layout/modals/icon-picker.json | 7 +++++++
public/locales/zh/settings/common.json | 2 +-
28 files changed, 147 insertions(+), 14 deletions(-)
create mode 100644 public/locales/da/layout/modals/icon-picker.json
create mode 100644 public/locales/de/layout/modals/icon-picker.json
create mode 100644 public/locales/el/layout/modals/icon-picker.json
create mode 100644 public/locales/es/layout/modals/icon-picker.json
create mode 100644 public/locales/fr/layout/modals/icon-picker.json
create mode 100644 public/locales/he/layout/modals/icon-picker.json
create mode 100644 public/locales/it/layout/modals/icon-picker.json
create mode 100644 public/locales/ja/layout/modals/icon-picker.json
create mode 100644 public/locales/ko/layout/modals/icon-picker.json
create mode 100644 public/locales/lol/layout/modals/icon-picker.json
create mode 100644 public/locales/nl/layout/modals/icon-picker.json
create mode 100644 public/locales/pl/layout/modals/icon-picker.json
create mode 100644 public/locales/pt/layout/modals/icon-picker.json
create mode 100644 public/locales/ru/layout/modals/icon-picker.json
create mode 100644 public/locales/sl/layout/modals/icon-picker.json
create mode 100644 public/locales/sv/layout/modals/icon-picker.json
create mode 100644 public/locales/uk/layout/modals/icon-picker.json
create mode 100644 public/locales/vi/layout/modals/icon-picker.json
create mode 100644 public/locales/zh/layout/modals/icon-picker.json
diff --git a/public/locales/da/layout/modals/icon-picker.json b/public/locales/da/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/da/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/de/layout/modals/icon-picker.json b/public/locales/de/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/de/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/el/layout/modals/icon-picker.json b/public/locales/el/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/el/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/el/settings/common.json b/public/locales/el/settings/common.json
index 3576da775..d5ae45d91 100644
--- a/public/locales/el/settings/common.json
+++ b/public/locales/el/settings/common.json
@@ -2,7 +2,7 @@
"title": "Ρυθμίσεις",
"tooltip": "Ρυθμίσεις",
"tabs": {
- "common": "Συχνά",
+ "common": "Συχνές επιλογές",
"customizations": "Παραμετροποιήσεις"
},
"tips": {
diff --git a/public/locales/el/settings/general/config-changer.json b/public/locales/el/settings/general/config-changer.json
index 86b6a9a06..4fe61e49c 100644
--- a/public/locales/el/settings/general/config-changer.json
+++ b/public/locales/el/settings/general/config-changer.json
@@ -62,7 +62,7 @@
}
}
},
- "saveCopy": "Αποθήκευση αντιγράφου"
+ "saveCopy": "Αποθηκεύστε ένα αντίγραφο"
},
"dropzone": {
"notifications": {
diff --git a/public/locales/es/layout/modals/icon-picker.json b/public/locales/es/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/es/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/fr/layout/modals/icon-picker.json b/public/locales/fr/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/fr/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/he/layout/modals/icon-picker.json b/public/locales/he/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/he/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/it/layout/modals/icon-picker.json b/public/locales/it/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/it/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/it/modules/torrents-status.json b/public/locales/it/modules/torrents-status.json
index 4b20d52fe..7b5ea8e30 100644
--- a/public/locales/it/modules/torrents-status.json
+++ b/public/locales/it/modules/torrents-status.json
@@ -18,7 +18,7 @@
"card": {
"footer": {
"error": "Errore",
- "lastUpdated": "Ultimo aggiornamento {{time}} ago"
+ "lastUpdated": "Ultimo aggiornamento {{time}} fa"
},
"table": {
"header": {
@@ -30,7 +30,7 @@
"progress": "Avanzamento"
},
"item": {
- "text": "Gestito da {{appName}}, rapporto {{ratio}}"
+ "text": "Gestito da {{appName}}, {{ratio}} ratio"
},
"body": {
"nothingFound": "Nessun torrent trovato"
@@ -61,10 +61,10 @@
"introductionPrefix": "Gestito da",
"metrics": {
"queuePosition": "Posizione in coda - {{position}}",
- "progress": "Progressi - {{progress}}%",
+ "progress": "Progresso - {{progress}}%",
"totalSelectedSize": "Totale - {{totalSize}}",
"state": "Stato - {{state}}",
- "ratio": "Rapporto -",
+ "ratio": "Ratio -",
"completed": "Completato"
}
}
diff --git a/public/locales/ja/layout/modals/icon-picker.json b/public/locales/ja/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/ja/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/ko/layout/modals/icon-picker.json b/public/locales/ko/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/ko/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/lol/layout/modals/icon-picker.json b/public/locales/lol/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/lol/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/nl/layout/modals/icon-picker.json b/public/locales/nl/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/nl/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/pl/layout/modals/icon-picker.json b/public/locales/pl/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/pl/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/pt/layout/modals/icon-picker.json b/public/locales/pt/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/pt/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/ru/layout/modals/icon-picker.json b/public/locales/ru/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/ru/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/sl/layout/modals/icon-picker.json b/public/locales/sl/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/sl/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/sv/layout/modals/about.json b/public/locales/sv/layout/modals/about.json
index e35dbbfed..ffd97b0b8 100644
--- a/public/locales/sv/layout/modals/about.json
+++ b/public/locales/sv/layout/modals/about.json
@@ -3,5 +3,5 @@
"i18n": "Laddade namnområden för I18n-översättningar",
"locales": "Konfigurerade I18n lokalspråk",
"contact": "Har du problem eller frågor? Kontakta oss!",
- "addToDashboard": "Lägg till i instrumentpanel"
+ "addToDashboard": "Lägg till på instrumentpanel"
}
diff --git a/public/locales/sv/layout/modals/add-app.json b/public/locales/sv/layout/modals/add-app.json
index 923c67f0d..7f7c8b6e8 100644
--- a/public/locales/sv/layout/modals/add-app.json
+++ b/public/locales/sv/layout/modals/add-app.json
@@ -39,7 +39,7 @@
"appearance": {
"icon": {
"label": "Appikon",
- "description": "Ikonen som kommer att visas på instrumentpanelen."
+ "description": "Ikon som kommer att visas på instrumentpanelen."
}
},
"integration": {
diff --git a/public/locales/sv/layout/modals/change-position.json b/public/locales/sv/layout/modals/change-position.json
index 5d1714b75..2a358c34d 100644
--- a/public/locales/sv/layout/modals/change-position.json
+++ b/public/locales/sv/layout/modals/change-position.json
@@ -1,8 +1,8 @@
{
- "xPosition": "X axel position",
+ "xPosition": "Position X-axel",
"width": "Bredd",
"height": "Höjd",
- "yPosition": "Y axel position",
+ "yPosition": "Position Y-axel",
"zeroOrHigher": "0 eller högre",
"betweenXandY": "Mellan {{min}} och {{max}}"
}
\ No newline at end of file
diff --git a/public/locales/sv/layout/modals/icon-picker.json b/public/locales/sv/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/sv/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/sv/modules/dashdot.json b/public/locales/sv/modules/dashdot.json
index 2ae7fa75a..d6a019e56 100644
--- a/public/locales/sv/modules/dashdot.json
+++ b/public/locales/sv/modules/dashdot.json
@@ -8,7 +8,7 @@
"label": "Flerkärnig CPU vy"
},
"storageMultiView": {
- "label": "Visning av flera lagrings enheter"
+ "label": "Visning av flera lagringsenheter"
},
"useCompactView": {
"label": "Använd kompakt vy"
diff --git a/public/locales/uk/layout/modals/icon-picker.json b/public/locales/uk/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/uk/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/uk/modules/torrents-status.json b/public/locales/uk/modules/torrents-status.json
index f6df37230..69e8e03bc 100644
--- a/public/locales/uk/modules/torrents-status.json
+++ b/public/locales/uk/modules/torrents-status.json
@@ -58,12 +58,12 @@
"title": "Завантаження..."
},
"popover": {
- "introductionPrefix": "Під керівництвом",
+ "introductionPrefix": "Керується",
"metrics": {
"queuePosition": "Позиція в черзі - {{position}}",
"progress": "Прогрес - {{progress}}%.",
"totalSelectedSize": "Всього - {{totalSize}}",
- "state": "Держава - {{state}}",
+ "state": "Стан - {{state}}",
"ratio": "Коефіцієнт -",
"completed": "Завершено"
}
diff --git a/public/locales/vi/layout/modals/icon-picker.json b/public/locales/vi/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/vi/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/zh/layout/modals/icon-picker.json b/public/locales/zh/layout/modals/icon-picker.json
new file mode 100644
index 000000000..349810cb9
--- /dev/null
+++ b/public/locales/zh/layout/modals/icon-picker.json
@@ -0,0 +1,7 @@
+{
+ "iconPicker": {
+ "textInputPlaceholder": "",
+ "searchLimitationTitle": "",
+ "searchLimitationMessage": ""
+ }
+}
\ No newline at end of file
diff --git a/public/locales/zh/settings/common.json b/public/locales/zh/settings/common.json
index f8d028289..fffc224de 100644
--- a/public/locales/zh/settings/common.json
+++ b/public/locales/zh/settings/common.json
@@ -22,7 +22,7 @@
"enablelsidebar": "启用左边的侧边栏",
"enablesearchbar": "启用搜索栏",
"enabledocker": "启用docker集成",
- "enableping": "启用平移功能",
+ "enableping": "启用Ping功能",
"enablelsidebardesc": "可选的。只能用于应用程序和集成",
"enablersidebardesc": "可选的。只能用于应用程序和集成"
}
From 1ffd984eb3215eb57664a2a1229201071bed5922 Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Sun, 29 Jan 2023 20:30:10 +0100
Subject: [PATCH 18/26] =?UTF-8?q?=F0=9F=A5=85=20Add=20error=20handling=20f?=
=?UTF-8?q?or=20download=20queue=20API?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/pages/api/modules/downloads/index.ts | 29 ++++++++++++++++---
.../queue/NormalizedDownloadQueueResponse.ts | 3 +-
2 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/src/pages/api/modules/downloads/index.ts b/src/pages/api/modules/downloads/index.ts
index 58c584a55..099669738 100644
--- a/src/pages/api/modules/downloads/index.ts
+++ b/src/pages/api/modules/downloads/index.ts
@@ -1,5 +1,6 @@
import { Deluge } from '@ctrl/deluge';
import { AllClientData } from '@ctrl/shared-torrent';
+import Consola from 'consola';
import { getCookie } from 'cookies-next';
import dayjs from 'dayjs';
import { NextApiRequest, NextApiResponse } from 'next';
@@ -18,16 +19,36 @@ const Get = async (request: NextApiRequest, response: NextApiResponse) => {
const configName = getCookie('config-name', { req: request });
const config = getConfig(configName?.toString() ?? 'default');
- const clientData: Promise[] = config.apps.map((app) =>
- GetDataFromClient(app)
- );
+ const failedClients: string[] = [];
+
+ const clientData: Promise[] = config.apps.map(async (app) => {
+ try {
+ const response = await GetDataFromClient(app);
+
+ if (!response) {
+ return {
+ success: false,
+ } as NormalizedDownloadAppStat;
+ }
+
+ return response;
+ } catch (err) {
+ Consola.error(
+ `Error communicating with your download client '${app.name}' (${app.id}): ${err}`
+ );
+ failedClients.push(app.id);
+ return {
+ success: false,
+ } as NormalizedDownloadAppStat;
+ }
+ });
const settledPromises = await Promise.allSettled(clientData);
const data: NormalizedDownloadAppStat[] = settledPromises
.filter((x) => x.status === 'fulfilled')
.map((promise) => (promise as PromiseFulfilledResult).value)
- .filter((x) => x !== undefined);
+ .filter((x) => x !== undefined && x.type !== undefined);
const responseBody = { apps: data } as NormalizedDownloadQueueResponse;
diff --git a/src/types/api/downloads/queue/NormalizedDownloadQueueResponse.ts b/src/types/api/downloads/queue/NormalizedDownloadQueueResponse.ts
index 853c756ad..06a38fe22 100644
--- a/src/types/api/downloads/queue/NormalizedDownloadQueueResponse.ts
+++ b/src/types/api/downloads/queue/NormalizedDownloadQueueResponse.ts
@@ -8,16 +8,17 @@ export type NormalizedDownloadQueueResponse = {
export type NormalizedDownloadAppStat = {
success: boolean;
appId: string;
- totalDownload: number;
} & (TorrentTotalDownload | UsenetTotalDownloas);
export type TorrentTotalDownload = {
type: 'torrent';
torrents: NormalizedTorrent[];
+ totalDownload: number;
totalUpload: number;
};
export type UsenetTotalDownloas = {
type: 'usenet';
+ totalDownload: number;
nzbs: UsenetQueueItem[];
};
From 1977c7478e9a1af5192d0112f1a6a7662e77e49f Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Mon, 30 Jan 2023 12:51:54 +0100
Subject: [PATCH 19/26] =?UTF-8?q?=F0=9F=90=9B=20Fix=20mismatched=20torrent?=
=?UTF-8?q?=20clients?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/pages/api/modules/downloads/index.ts | 16 ++++++++++++----
.../queue/NormalizedDownloadQueueResponse.ts | 1 +
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/pages/api/modules/downloads/index.ts b/src/pages/api/modules/downloads/index.ts
index 099669738..22c33a9ba 100644
--- a/src/pages/api/modules/downloads/index.ts
+++ b/src/pages/api/modules/downloads/index.ts
@@ -1,4 +1,6 @@
import { Deluge } from '@ctrl/deluge';
+import { QBittorrent } from '@ctrl/qbittorrent';
+import { Transmission } from '@ctrl/transmission';
import { AllClientData } from '@ctrl/shared-torrent';
import Consola from 'consola';
import { getCookie } from 'cookies-next';
@@ -32,7 +34,7 @@ const Get = async (request: NextApiRequest, response: NextApiResponse) => {
}
return response;
- } catch (err) {
+ } catch (err: any) {
Consola.error(
`Error communicating with your download client '${app.name}' (${app.id}): ${err}`
);
@@ -50,7 +52,11 @@ const Get = async (request: NextApiRequest, response: NextApiResponse) => {
.map((promise) => (promise as PromiseFulfilledResult).value)
.filter((x) => x !== undefined && x.type !== undefined);
- const responseBody = { apps: data } as NormalizedDownloadQueueResponse;
+ const responseBody = { apps: data, failedApps: failedClients } as NormalizedDownloadQueueResponse;
+
+ if (failedClients.length > 0) {
+ Consola.warn(`${failedClients.length} download clients failed. Please check your configuration and the above log`);
+ }
return response.status(200).json(responseBody);
};
@@ -85,7 +91,7 @@ const GetDataFromClient = async (
}
case 'transmission': {
return reduceTorrent(
- await new Deluge({
+ await new Transmission({
baseUrl: app.url,
username: findField(app, 'username'),
password: findField(app, 'password'),
@@ -94,7 +100,7 @@ const GetDataFromClient = async (
}
case 'qBittorrent': {
return reduceTorrent(
- await new Deluge({
+ await new QBittorrent({
baseUrl: app.url,
username: findField(app, 'username'),
password: findField(app, 'password'),
@@ -147,6 +153,7 @@ const GetDataFromClient = async (
if (!err) {
resolve(result);
} else {
+ Consola.error(`Error while listing groups: ${err}`);
reject(err);
}
});
@@ -160,6 +167,7 @@ const GetDataFromClient = async (
if (!err) {
resolve(result);
} else {
+ Consola.error(`Error while retrieving NZBGet stats: ${err}`);
reject(err);
}
});
diff --git a/src/types/api/downloads/queue/NormalizedDownloadQueueResponse.ts b/src/types/api/downloads/queue/NormalizedDownloadQueueResponse.ts
index 06a38fe22..476e7fe85 100644
--- a/src/types/api/downloads/queue/NormalizedDownloadQueueResponse.ts
+++ b/src/types/api/downloads/queue/NormalizedDownloadQueueResponse.ts
@@ -3,6 +3,7 @@ import { UsenetQueueItem } from '../../../../widgets/useNet/types';
export type NormalizedDownloadQueueResponse = {
apps: NormalizedDownloadAppStat[];
+ failedApps: string[];
};
export type NormalizedDownloadAppStat = {
From 561055d5d6e01d260289ff30d732b82d5c88b5f2 Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Mon, 30 Jan 2023 21:03:27 +0100
Subject: [PATCH 20/26] =?UTF-8?q?=F0=9F=90=9B=20Fix=20overwriting=20not=20?=
=?UTF-8?q?affected=20apps=20and=20widgets=20in=20categories=20#665?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Wrappers/Category/useCategoryActions.tsx | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/components/Dashboard/Wrappers/Category/useCategoryActions.tsx b/src/components/Dashboard/Wrappers/Category/useCategoryActions.tsx
index 2ea0698ee..7225f3b5d 100644
--- a/src/components/Dashboard/Wrappers/Category/useCategoryActions.tsx
+++ b/src/components/Dashboard/Wrappers/Category/useCategoryActions.tsx
@@ -200,7 +200,11 @@ export const useCategoryActions = (configName: string | undefined, category: Cat
return false;
}
- return app.area.properties.id !== mainWrapperId;
+ if (app.area.properties.id === mainWrapperId) {
+ return false;
+ }
+
+ return app.area.properties.id === currentItem.id;
};
const isWidgetAffectedFilter = (widget: IWidget): boolean => {
@@ -212,7 +216,11 @@ export const useCategoryActions = (configName: string | undefined, category: Cat
return false;
}
- return widget.area.properties.id !== mainWrapperId;
+ if (widget.area.properties.id === mainWrapperId) {
+ return false;
+ }
+
+ return widget.area.properties.id === currentItem.id;
};
return {
From 84a6c38d9c439171a83dc432c83b85a6981bded0 Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Mon, 30 Jan 2023 21:12:45 +0100
Subject: [PATCH 21/26] =?UTF-8?q?=F0=9F=90=9B=20Search=20bar=20not=20respe?=
=?UTF-8?q?cting=20the=20open=20target=20#666?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/layout/header/Search.tsx | 37 +++++++++++++++----------
1 file changed, 23 insertions(+), 14 deletions(-)
diff --git a/src/components/layout/header/Search.tsx b/src/components/layout/header/Search.tsx
index bf9753425..ba8d799d0 100644
--- a/src/components/layout/header/Search.tsx
+++ b/src/components/layout/header/Search.tsx
@@ -20,6 +20,7 @@ import React, { forwardRef, useEffect, useRef, useState } from 'react';
import { useConfigContext } from '../../../config/provider';
import { OverseerrMediaDisplay } from '../../../modules/common';
import { IModule } from '../../../modules/ModuleTypes';
+import { ConfigType } from '../../../types/config';
import { searchUrls } from '../../Settings/Common/SearchEngine/SearchEngineSelector';
import Tip from '../Tip';
import { useCardStyles } from '../useCardStyles';
@@ -137,9 +138,7 @@ export function Search() {
const textInput = useRef(null);
useHotkeys([['mod+K', () => textInput.current?.focus()]]);
const { classes } = useStyles();
- const openInNewTab = config?.settings.common.searchEngine.properties.openInNewTab
- ? '_blank'
- : '_self';
+ const openTarget = getOpenTarget(config);
const [opened, setOpened] = useState(false);
const {
@@ -166,6 +165,7 @@ export function Search() {
if (!isModuleEnabled) {
return null;
}
+
//TODO: Fix the bug where clicking anything inside the Modal to ask for a movie
// will close it (Because it closes the underlying Popover)
return (
@@ -194,7 +194,7 @@ export function Search() {
setOpened(false);
if (item.url) {
setSearchQuery('');
- window.open(item.openedUrl ? item.openedUrl : item.url, openInNewTab);
+ window.open(item.openedUrl ? item.openedUrl : item.url, openTarget);
}
}}
// Replace %s if it is in selectedSearchEngine.url with searchQuery, otherwise append searchQuery at the end of it
@@ -205,9 +205,9 @@ export function Search() {
autocompleteData.length === 0
) {
if (selectedSearchEngine.url.includes('%s')) {
- window.open(selectedSearchEngine.url.replace('%s', searchQuery), openInNewTab);
+ window.open(selectedSearchEngine.url.replace('%s', searchQuery), openTarget);
} else {
- window.open(selectedSearchEngine.url + searchQuery, openInNewTab);
+ window.open(selectedSearchEngine.url + searchQuery, openTarget);
}
}
}}
@@ -220,14 +220,15 @@ export function Search() {
- {OverseerrResults && OverseerrResults.slice(0, 4).map((result: any, index: number) => (
-
-
- {index < OverseerrResults.length - 1 && index < 3 && (
-
- )}
-
- ))}
+ {OverseerrResults &&
+ OverseerrResults.slice(0, 4).map((result: any, index: number) => (
+
+
+ {index < OverseerrResults.length - 1 && index < 3 && (
+
+ )}
+
+ ))}
@@ -299,3 +300,11 @@ export function Search() {
});
}
}
+
+const getOpenTarget = (config: ConfigType | undefined): '_blank' | '_self' => {
+ if (!config || config.settings.common.searchEngine.properties.openInNewTab === undefined) {
+ return '_blank';
+ }
+
+ return config.settings.common.searchEngine.properties.openInNewTab ? '_blank' : '_self';
+};
From f28f0b98a04c1e6dec2e301df7d02ce15ea11f94 Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Mon, 30 Jan 2023 21:41:16 +0100
Subject: [PATCH 22/26] =?UTF-8?q?=F0=9F=9A=B8=20Add=20hotkey=20for=20enter?=
=?UTF-8?q?ing=20and=20exiting=20edit=20mode=20#660?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/components/layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx b/src/components/layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx
index 4bfdc89a6..bee5be707 100644
--- a/src/components/layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx
+++ b/src/components/layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx
@@ -4,6 +4,7 @@ import { ActionIcon, Button, Group, Text, Title, Tooltip } from '@mantine/core';
import { IconEditCircle, IconEditCircleOff } from '@tabler/icons';
import { getCookie } from 'cookies-next';
import { Trans, useTranslation } from 'next-i18next';
+import { useHotkeys } from '@mantine/hooks';
import { hideNotification, showNotification } from '@mantine/notifications';
import { useConfigContext } from '../../../../../config/provider';
import { useScreenSmallerThan } from '../../../../../hooks/useScreenSmallerThan';
@@ -23,6 +24,8 @@ export const ToggleEditModeAction = () => {
const { config } = useConfigContext();
const { classes } = useCardStyles(true);
+ useHotkeys([['ctrl+E', toggleEditMode]]);
+
const toggleButtonClicked = () => {
toggleEditMode();
if (enabled || config === undefined || config?.schemaVersion === undefined) {
From e9eebadce62358bdaf71d318bd520f56524ad567 Mon Sep 17 00:00:00 2001
From: ajnart
Date: Tue, 31 Jan 2023 10:10:02 +0900
Subject: [PATCH 23/26] =?UTF-8?q?=F0=9F=A7=91=E2=80=8D=F0=9F=92=BB=20Add?=
=?UTF-8?q?=20react=20query=20dev=20tool?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
package.json | 1 +
src/pages/_app.tsx | 2 ++
yarn.lock | 57 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 60 insertions(+)
diff --git a/package.json b/package.json
index ea144ed3e..4cf737dd8 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,7 @@
"@nivo/line": "^0.79.1",
"@tabler/icons": "^1.106.0",
"@tanstack/react-query": "^4.2.1",
+ "@tanstack/react-query-devtools": "^4.24.4",
"axios": "^0.27.2",
"consola": "^2.15.3",
"cookies-next": "^2.1.1",
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 829fba3bd..088141e6c 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -9,6 +9,7 @@ import { appWithTranslation } from 'next-i18next';
import { AppProps } from 'next/app';
import Head from 'next/head';
import { useState } from 'react';
+import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { ChangeAppPositionModal } from '../components/Dashboard/Modals/ChangePosition/ChangeAppPositionModal';
import { ChangeWidgetPositionModal } from '../components/Dashboard/Modals/ChangePosition/ChangeWidgetPositionModal';
import { EditAppModal } from '../components/Dashboard/Modals/EditAppModal/EditAppModal';
@@ -102,6 +103,7 @@ function App(this: any, props: AppProps & { colorScheme: ColorScheme }) {
+
>
);
diff --git a/yarn.lock b/yarn.lock
index 08cd3cf7f..97cdc592e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1953,6 +1953,15 @@ __metadata:
languageName: node
linkType: hard
+"@tanstack/match-sorter-utils@npm:^8.7.0":
+ version: 8.7.6
+ resolution: "@tanstack/match-sorter-utils@npm:8.7.6"
+ dependencies:
+ remove-accents: 0.4.2
+ checksum: 3f3dda277e6e55ca1224a28b38a2deb3ac912c2f2f5263a32fa0d9126c6b6d05feb475539729fd248f1eb88b612109db90b847ec8fdfc05d0f4073c900a2d3f6
+ languageName: node
+ linkType: hard
+
"@tanstack/query-core@npm:4.19.1":
version: 4.19.1
resolution: "@tanstack/query-core@npm:4.19.1"
@@ -1960,6 +1969,21 @@ __metadata:
languageName: node
linkType: hard
+"@tanstack/react-query-devtools@npm:^4.24.4":
+ version: 4.24.4
+ resolution: "@tanstack/react-query-devtools@npm:4.24.4"
+ dependencies:
+ "@tanstack/match-sorter-utils": ^8.7.0
+ superjson: ^1.10.0
+ use-sync-external-store: ^1.2.0
+ peerDependencies:
+ "@tanstack/react-query": 4.24.4
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+ checksum: 8b8f1ae8e55f016f25b383baae0000f0b608ec0327ee4eccb0a7b3b1c596b12f68c848e429be84c8a6039bd0a7d5bd36a7232fd7818868f1a3ae3d0462898e26
+ languageName: node
+ linkType: hard
+
"@tanstack/react-query@npm:^4.2.1":
version: 4.19.1
resolution: "@tanstack/react-query@npm:4.19.1"
@@ -3239,6 +3263,15 @@ __metadata:
languageName: node
linkType: hard
+"copy-anything@npm:^3.0.2":
+ version: 3.0.3
+ resolution: "copy-anything@npm:3.0.3"
+ dependencies:
+ is-what: ^4.1.8
+ checksum: d456dc5ec98dee7c7cf87d809eac30dc2ac942acd4cf970fab394e280ceb6dd7a8a7a5a44fcbcc50e0206658de3cc20b92863562f5797930bb2619f164f4c182
+ languageName: node
+ linkType: hard
+
"core-js-pure@npm:^3.25.1":
version: 3.26.1
resolution: "core-js-pure@npm:3.26.1"
@@ -4916,6 +4949,7 @@ __metadata:
"@nivo/line": ^0.79.1
"@tabler/icons": ^1.106.0
"@tanstack/react-query": ^4.2.1
+ "@tanstack/react-query-devtools": ^4.24.4
"@types/dockerode": ^3.3.9
"@types/node": 17.0.1
"@types/ping": ^0.4.1
@@ -5447,6 +5481,13 @@ __metadata:
languageName: node
linkType: hard
+"is-what@npm:^4.1.8":
+ version: 4.1.8
+ resolution: "is-what@npm:4.1.8"
+ checksum: b9bec3acff102d14ad467f4c74c9886af310fa160e07a63292c8c181e6768c7c4c1054644e13d67185b963644e4a513bce8c6b8ce3d3ca6f9488a69fccad5f97
+ languageName: node
+ linkType: hard
+
"isarray@npm:0.0.1":
version: 0.0.1
resolution: "isarray@npm:0.0.1"
@@ -7410,6 +7451,13 @@ __metadata:
languageName: node
linkType: hard
+"remove-accents@npm:0.4.2":
+ version: 0.4.2
+ resolution: "remove-accents@npm:0.4.2"
+ checksum: 84a6988555dea24115e2d1954db99509588d43fe55a1590f0b5894802776f7b488b3151c37ceb9e4f4b646f26b80b7325dcea2fae58bc3865df146e1fa606711
+ languageName: node
+ linkType: hard
+
"require-directory@npm:^2.1.1":
version: 2.1.1
resolution: "require-directory@npm:2.1.1"
@@ -8044,6 +8092,15 @@ __metadata:
languageName: node
linkType: hard
+"superjson@npm:^1.10.0":
+ version: 1.12.2
+ resolution: "superjson@npm:1.12.2"
+ dependencies:
+ copy-anything: ^3.0.2
+ checksum: cf7735e172811ed87476a7c2f1bb0e83725a0e3c2d7a50a71303a973060b3c710288767fb767a7a7eee8e5625d3ccaee1176a93e27f43841627512c15c4cdf84
+ languageName: node
+ linkType: hard
+
"supports-color@npm:^5.3.0":
version: 5.5.0
resolution: "supports-color@npm:5.5.0"
From 2b76ae83b11b9907bd0339a78c15f00394e262f8 Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Mon, 30 Jan 2023 21:17:46 +0100
Subject: [PATCH 24/26] =?UTF-8?q?=F0=9F=92=84=20Fix=20overflowing=20text?=
=?UTF-8?q?=20wrap=20in=20header=20for=20page=20title=20#606?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/layout/header/Header.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/layout/header/Header.tsx b/src/components/layout/header/Header.tsx
index c70fa7128..45f432f34 100644
--- a/src/components/layout/header/Header.tsx
+++ b/src/components/layout/header/Header.tsx
@@ -30,7 +30,7 @@ export function Header(props: any) {
}, [CURRENT_VERSION]);
return (
-
+
From 2b20cecb797fdbc2ae87756426188a54a7564cac Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Tue, 31 Jan 2023 21:17:37 +0100
Subject: [PATCH 25/26] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Add=20version=20read?=
=?UTF-8?q?ing=20by=20package=20file?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
data/constants.ts | 1 -
src/components/About/AboutModal.tsx | 17 ++++++++++++++---
.../Tabs/AppereanceTab/AppereanceTab.tsx | 2 +-
.../Wrappers/Category/useCategoryActions.tsx | 1 -
src/components/layout/header/Header.tsx | 13 ++++++-------
src/pages/[slug].tsx | 4 ++--
src/pages/_app.tsx | 19 +++++++++++++++++--
src/pages/index.tsx | 15 +++++++++------
src/pages/login.tsx | 2 +-
src/tools/addToHomarr.ts | 11 +----------
src/tools/{ => client}/calculateEta.ts | 0
src/tools/{ => client}/parseDuration.ts | 0
.../zustands/usePackageAttributesStore.ts | 15 +++++++++++++++
src/tools/server/getPackageVersion.ts | 14 ++++++++++++++
.../{ => server}/getServerSideTranslations.ts | 0
.../{ => server}/translation-namespaces.ts | 0
src/types/dashboardPageType.ts | 1 +
src/widgets/torrent/TorrentQueueItem.tsx | 2 +-
src/widgets/useNet/UsenetHistoryList.tsx | 2 +-
19 files changed, 83 insertions(+), 36 deletions(-)
rename src/tools/{ => client}/calculateEta.ts (100%)
rename src/tools/{ => client}/parseDuration.ts (100%)
create mode 100644 src/tools/client/zustands/usePackageAttributesStore.ts
create mode 100644 src/tools/server/getPackageVersion.ts
rename src/tools/{ => server}/getServerSideTranslations.ts (100%)
rename src/tools/{ => server}/translation-namespaces.ts (100%)
diff --git a/data/constants.ts b/data/constants.ts
index b1ff95a49..b10f63d7e 100644
--- a/data/constants.ts
+++ b/data/constants.ts
@@ -1,3 +1,2 @@
export const REPO_URL = 'ajnart/homarr';
-export const CURRENT_VERSION = 'v0.11.3';
export const ICON_PICKER_SLICE_LIMIT = 36;
diff --git a/src/components/About/AboutModal.tsx b/src/components/About/AboutModal.tsx
index 8d258ebd3..56b6954a8 100644
--- a/src/components/About/AboutModal.tsx
+++ b/src/components/About/AboutModal.tsx
@@ -13,6 +13,7 @@ import {
Title,
} from '@mantine/core';
import {
+ IconAnchor,
IconBrandDiscord,
IconBrandGithub,
IconFile,
@@ -27,9 +28,9 @@ import { InitOptions } from 'i18next';
import { i18n, Trans, useTranslation } from 'next-i18next';
import Image from 'next/image';
import { ReactNode } from 'react';
-import { CURRENT_VERSION } from '../../../data/constants';
import { useConfigContext } from '../../config/provider';
import { useConfigStore } from '../../config/store';
+import { usePackageAttributesStore } from '../../tools/client/zustands/usePackageAttributesStore';
import { usePrimaryGradient } from '../layout/useGradient';
import Credits from '../Settings/Common/Credits';
@@ -132,6 +133,7 @@ interface ExtendedInitOptions extends InitOptions {
const useInformationTableItems = (newVersionAvailable?: string): InformationTableItem[] => {
// TODO: Fix this to not request. Pass it as a prop.
const colorGradiant = usePrimaryGradient();
+ const { attributes } = usePackageAttributesStore();
const { configVersion } = useConfigContext();
const { configs } = useConfigStore();
@@ -190,7 +192,7 @@ const useInformationTableItems = (newVersionAvailable?: string): InformationTabl
content: (
- {CURRENT_VERSION}
+ {attributes.packageVersion ?? 'Unknown'}
{newVersionAvailable && (
@@ -218,13 +220,22 @@ const useInformationTableItems = (newVersionAvailable?: string): InformationTabl
{newVersionAvailable}
{' '}
- is available ! Current version: {CURRENT_VERSION}
+ is available ! Current version: {attributes.packageVersion}
)}
),
},
+ {
+ icon: ,
+ label: 'Node environment',
+ content: (
+
+ {attributes.environment}
+
+ ),
+ },
...items,
];
diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx
index f74ab7d60..d8795d25f 100644
--- a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx
+++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/AppereanceTab.tsx
@@ -1,4 +1,4 @@
-import { Autocomplete, createStyles, Flex, Tabs, TextInput } from '@mantine/core';
+import { Autocomplete, createStyles, Flex, Tabs } from '@mantine/core';
import { UseFormReturnType } from '@mantine/form';
import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'next-i18next';
diff --git a/src/components/Dashboard/Wrappers/Category/useCategoryActions.tsx b/src/components/Dashboard/Wrappers/Category/useCategoryActions.tsx
index 7225f3b5d..6be7e99a4 100644
--- a/src/components/Dashboard/Wrappers/Category/useCategoryActions.tsx
+++ b/src/components/Dashboard/Wrappers/Category/useCategoryActions.tsx
@@ -3,7 +3,6 @@ import { useConfigStore } from '../../../../config/store';
import { openContextModalGeneric } from '../../../../tools/mantineModalManagerExtensions';
import { AppType } from '../../../../types/app';
import { CategoryType } from '../../../../types/category';
-import { ConfigType } from '../../../../types/config';
import { WrapperType } from '../../../../types/wrapper';
import { IWidget } from '../../../../widgets/widgets';
import { CategoryEditModalInnerProps } from './CategoryEditModal';
diff --git a/src/components/layout/header/Header.tsx b/src/components/layout/header/Header.tsx
index 45f432f34..ec7a9f33d 100644
--- a/src/components/layout/header/Header.tsx
+++ b/src/components/layout/header/Header.tsx
@@ -1,10 +1,10 @@
import { Box, createStyles, Group, Header as MantineHeader, Indicator } from '@mantine/core';
import { useEffect, useState } from 'react';
-import { CURRENT_VERSION, REPO_URL } from '../../../../data/constants';
-import { useConfigContext } from '../../../config/provider';
+import { REPO_URL } from '../../../../data/constants';
+import DockerMenuButton from '../../../modules/Docker/DockerModule';
+import { usePackageAttributesStore } from '../../../tools/client/zustands/usePackageAttributesStore';
import { Logo } from '../Logo';
import { useCardStyles } from '../useCardStyles';
-import DockerMenuButton from '../../../modules/Docker/DockerModule';
import { ToggleEditModeAction } from './Actions/ToggleEditMode/ToggleEditMode';
import { Search } from './Search';
import { SettingsMenu } from './SettingsMenu';
@@ -14,20 +14,19 @@ export const HeaderHeight = 64;
export function Header(props: any) {
const { classes } = useStyles();
const { classes: cardClasses } = useCardStyles(false);
-
- const { config } = useConfigContext();
+ const { attributes } = usePackageAttributesStore();
const [newVersionAvailable, setNewVersionAvailable] = useState('');
useEffect(() => {
// Fetch Data here when component first mounted
fetch(`https://api.github.com/repos/${REPO_URL}/releases/latest`).then((res) => {
res.json().then((data) => {
- if (data.tag_name > CURRENT_VERSION) {
+ if (data.tag_name > `v${attributes.packageVersion}`) {
setNewVersionAvailable(data.tag_name);
}
});
});
- }, [CURRENT_VERSION]);
+ }, []);
return (
diff --git a/src/pages/[slug].tsx b/src/pages/[slug].tsx
index 5a0876847..c3ac1b272 100644
--- a/src/pages/[slug].tsx
+++ b/src/pages/[slug].tsx
@@ -8,8 +8,8 @@ import Layout from '../components/layout/Layout';
import { useInitConfig } from '../config/init';
import { getFallbackConfig } from '../tools/config/getFallbackConfig';
import { getFrontendConfig } from '../tools/config/getFrontendConfig';
-import { getServerSideTranslations } from '../tools/getServerSideTranslations';
-import { dashboardNamespaces } from '../tools/translation-namespaces';
+import { getServerSideTranslations } from '../tools/server/getServerSideTranslations';
+import { dashboardNamespaces } from '../tools/server/translation-namespaces';
import { ConfigType } from '../types/config';
import { DashboardServerSideProps } from '../types/dashboardPageType';
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 088141e6c..b372436a0 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -8,7 +8,7 @@ import { GetServerSidePropsContext } from 'next';
import { appWithTranslation } from 'next-i18next';
import { AppProps } from 'next/app';
import Head from 'next/head';
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { ChangeAppPositionModal } from '../components/Dashboard/Modals/ChangePosition/ChangeAppPositionModal';
import { ChangeWidgetPositionModal } from '../components/Dashboard/Modals/ChangePosition/ChangeWidgetPositionModal';
@@ -22,8 +22,16 @@ import '../styles/global.scss';
import { ColorTheme } from '../tools/color';
import { queryClient } from '../tools/queryClient';
import { theme } from '../tools/theme';
+import {
+ getServiceSidePackageAttributes,
+ ServerSidePackageAttributesType,
+} from '../tools/server/getPackageVersion';
+import { usePackageAttributesStore } from '../tools/client/zustands/usePackageAttributesStore';
-function App(this: any, props: AppProps & { colorScheme: ColorScheme }) {
+function App(
+ this: any,
+ props: AppProps & { colorScheme: ColorScheme; packageAttributes: ServerSidePackageAttributesType }
+) {
const { Component, pageProps } = props;
const [primaryColor, setPrimaryColor] = useState('red');
const [secondaryColor, setSecondaryColor] = useState('orange');
@@ -46,6 +54,12 @@ function App(this: any, props: AppProps & { colorScheme: ColorScheme }) {
getInitialValueInEffect: true,
});
+ const { setInitialPackageAttributes } = usePackageAttributesStore();
+
+ useEffect(() => {
+ setInitialPackageAttributes(props.packageAttributes);
+ }, []);
+
const toggleColorScheme = (value?: ColorScheme) =>
setColorScheme(value || (colorScheme === 'dark' ? 'light' : 'dark'));
@@ -111,6 +125,7 @@ function App(this: any, props: AppProps & { colorScheme: ColorScheme }) {
App.getInitialProps = ({ ctx }: { ctx: GetServerSidePropsContext }) => ({
colorScheme: getCookie('color-scheme', ctx) || 'light',
+ packageAttributes: getServiceSidePackageAttributes(),
});
export default appWithTranslation(App);
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index dd416158b..5b1f60d8a 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -1,15 +1,15 @@
import { getCookie, setCookie } from 'cookies-next';
+import fs from 'fs';
import { GetServerSidePropsContext } from 'next';
-import fs from 'fs';
+import { LoadConfigComponent } from '../components/Config/LoadConfig';
import { Dashboard } from '../components/Dashboard/Dashboard';
import Layout from '../components/layout/Layout';
import { useInitConfig } from '../config/init';
import { getFrontendConfig } from '../tools/config/getFrontendConfig';
-import { getServerSideTranslations } from '../tools/getServerSideTranslations';
-import { dashboardNamespaces } from '../tools/translation-namespaces';
+import { getServerSideTranslations } from '../tools/server/getServerSideTranslations';
+import { dashboardNamespaces } from '../tools/server/translation-namespaces';
import { DashboardServerSideProps } from '../types/dashboardPageType';
-import { LoadConfigComponent } from '../components/Config/LoadConfig';
export async function getServerSideProps({
req,
@@ -47,11 +47,14 @@ export async function getServerSideProps({
}
const translations = await getServerSideTranslations(req, res, dashboardNamespaces, locale);
-
const config = getFrontendConfig(configName as string);
return {
- props: { configName: configName as string, config, ...translations },
+ props: {
+ configName: configName as string,
+ config,
+ ...translations,
+ },
};
}
diff --git a/src/pages/login.tsx b/src/pages/login.tsx
index 7587bbde0..bf414ed83 100644
--- a/src/pages/login.tsx
+++ b/src/pages/login.tsx
@@ -8,7 +8,7 @@ import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
import { useForm } from '@mantine/form';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
-import { loginNamespaces } from '../tools/translation-namespaces';
+import { loginNamespaces } from '../tools/server/translation-namespaces';
// TODO: Add links to the wiki articles about the login process.
export default function AuthenticationTitle() {
diff --git a/src/tools/addToHomarr.ts b/src/tools/addToHomarr.ts
index 5f97bf49d..bb340ba4e 100644
--- a/src/tools/addToHomarr.ts
+++ b/src/tools/addToHomarr.ts
@@ -1,14 +1,5 @@
import Dockerode from 'dockerode';
-import { Config, MatchingImages, ServiceType, tryMatchPort } from './types';
-
-async function MatchIcon(name: string) {
- const res = await fetch(
- `https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/${name
- .replace(/\s+/g, '-')
- .toLowerCase()}.png`
- );
- return res.ok ? res.url : '/imgs/favicon/favicon.png';
-}
+import { MatchingImages, ServiceType, tryMatchPort } from './types';
function tryMatchType(imageName: string): ServiceType {
// Try to find imageName inside MatchingImages
diff --git a/src/tools/calculateEta.ts b/src/tools/client/calculateEta.ts
similarity index 100%
rename from src/tools/calculateEta.ts
rename to src/tools/client/calculateEta.ts
diff --git a/src/tools/parseDuration.ts b/src/tools/client/parseDuration.ts
similarity index 100%
rename from src/tools/parseDuration.ts
rename to src/tools/client/parseDuration.ts
diff --git a/src/tools/client/zustands/usePackageAttributesStore.ts b/src/tools/client/zustands/usePackageAttributesStore.ts
new file mode 100644
index 000000000..6d710997d
--- /dev/null
+++ b/src/tools/client/zustands/usePackageAttributesStore.ts
@@ -0,0 +1,15 @@
+import create from 'zustand';
+
+import { ServerSidePackageAttributesType } from '../../server/getPackageVersion';
+
+interface PackageAttributesState {
+ attributes: ServerSidePackageAttributesType;
+ setInitialPackageAttributes: (attributes: ServerSidePackageAttributesType) => void;
+}
+
+export const usePackageAttributesStore = create((set) => ({
+ attributes: { packageVersion: undefined, environment: 'test' },
+ setInitialPackageAttributes(attributes) {
+ set((state) => ({ ...state, attributes }));
+ },
+}));
diff --git a/src/tools/server/getPackageVersion.ts b/src/tools/server/getPackageVersion.ts
new file mode 100644
index 000000000..0c74d56a7
--- /dev/null
+++ b/src/tools/server/getPackageVersion.ts
@@ -0,0 +1,14 @@
+const getServerPackageVersion = (): string | undefined => process.env.npm_package_version;
+
+const getServerNodeEnvironment = (): 'development' | 'production' | 'test' =>
+ process.env.NODE_ENV;
+
+export const getServiceSidePackageAttributes = (): ServerSidePackageAttributesType => ({
+ packageVersion: getServerPackageVersion(),
+ environment: getServerNodeEnvironment(),
+});
+
+export type ServerSidePackageAttributesType = {
+ packageVersion: string | undefined;
+ environment: 'development' | 'production' | 'test';
+};
diff --git a/src/tools/getServerSideTranslations.ts b/src/tools/server/getServerSideTranslations.ts
similarity index 100%
rename from src/tools/getServerSideTranslations.ts
rename to src/tools/server/getServerSideTranslations.ts
diff --git a/src/tools/translation-namespaces.ts b/src/tools/server/translation-namespaces.ts
similarity index 100%
rename from src/tools/translation-namespaces.ts
rename to src/tools/server/translation-namespaces.ts
diff --git a/src/types/dashboardPageType.ts b/src/types/dashboardPageType.ts
index 416c3b1bf..f361e449f 100644
--- a/src/types/dashboardPageType.ts
+++ b/src/types/dashboardPageType.ts
@@ -1,4 +1,5 @@
import { SSRConfig } from 'next-i18next';
+
import { ConfigType } from './config';
export type DashboardServerSideProps = {
diff --git a/src/widgets/torrent/TorrentQueueItem.tsx b/src/widgets/torrent/TorrentQueueItem.tsx
index 6ec0c1a71..6d7afd891 100644
--- a/src/widgets/torrent/TorrentQueueItem.tsx
+++ b/src/widgets/torrent/TorrentQueueItem.tsx
@@ -24,7 +24,7 @@ import {
IconUpload,
} from '@tabler/icons';
import { useTranslation } from 'next-i18next';
-import { calculateETA } from '../../tools/calculateEta';
+import { calculateETA } from '../../tools/client/calculateEta';
import { humanFileSize } from '../../tools/humanFileSize';
import { AppType } from '../../types/app';
diff --git a/src/widgets/useNet/UsenetHistoryList.tsx b/src/widgets/useNet/UsenetHistoryList.tsx
index 28ee10ccf..2578fdec6 100644
--- a/src/widgets/useNet/UsenetHistoryList.tsx
+++ b/src/widgets/useNet/UsenetHistoryList.tsx
@@ -20,7 +20,7 @@ import { useTranslation } from 'next-i18next';
import { FunctionComponent, useState } from 'react';
import { useGetUsenetHistory } from '../../hooks/widgets/dashDot/api';
import { humanFileSize } from '../../tools/humanFileSize';
-import { parseDuration } from '../../tools/parseDuration';
+import { parseDuration } from '../../tools/client/parseDuration';
dayjs.extend(duration);
From b459b0fe8958294e11feab5bacf9dd70a9edc8bd Mon Sep 17 00:00:00 2001
From: Manuel <30572287+manuel-rw@users.noreply.github.com>
Date: Tue, 31 Jan 2023 22:03:34 +0100
Subject: [PATCH 26/26] =?UTF-8?q?=F0=9F=90=9B=20Re-add=20missing=20filters?=
=?UTF-8?q?=20for=20torrent=20widget?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/widgets/torrent/TorrentTile.tsx | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/widgets/torrent/TorrentTile.tsx b/src/widgets/torrent/TorrentTile.tsx
index 41c0a3996..c55287ef2 100644
--- a/src/widgets/torrent/TorrentTile.tsx
+++ b/src/widgets/torrent/TorrentTile.tsx
@@ -1,3 +1,4 @@
+import { TorrentState } from '@ctrl/shared-torrent';
import {
Badge,
Center,
@@ -122,7 +123,14 @@ function TorrentTile({ widget }: TorrentTileProps) {
);
}
- const torrents = data.apps.flatMap((app) => (app.type === 'torrent' ? app.torrents : []));
+ const torrents = data.apps
+ .flatMap((app) => (app.type === 'torrent' ? app.torrents : []))
+ .filter((torrent) => (widget.properties.displayCompletedTorrents ? true : !torrent.isCompleted))
+ .filter((torrent) =>
+ widget.properties.displayStaleTorrents
+ ? true
+ : torrent.isCompleted || torrent.downloadSpeed > 0
+ );
const difference = new Date().getTime() - dataUpdatedAt;
const duration = dayjs.duration(difference, 'ms');
|