From aca0defa7334c5187b944df62621d99e8beb3646 Mon Sep 17 00:00:00 2001 From: qu1ck Date: Mon, 1 Apr 2024 14:45:43 -0700 Subject: [PATCH] Implement preconfigured labels These labels always are shown in filters panel and in suggestions for torrents, regardless if they are present on the server. Issue #175 --- src/components/filters.tsx | 3 +- src/components/modals/common.tsx | 7 ++-- src/components/modals/interfacepanel.tsx | 41 ++++++++++++++++++------ src/config.ts | 2 ++ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/components/filters.tsx b/src/components/filters.tsx index 6c35330..6dd0e7c 100644 --- a/src/components/filters.tsx +++ b/src/components/filters.tsx @@ -331,6 +331,7 @@ export const Filters = React.memo(function Filters({ torrents, currentFilters, s const [labels, trackers] = useMemo(() => { const labels: Record = {}; const trackers: Record = {}; + config.values.interface.preconfiguredLabels.forEach((label) => { labels[label] = 0; }); torrents.forEach((t) => t.labels?.forEach((l: string) => { if (!(l in labels)) labels[l] = 0; @@ -343,7 +344,7 @@ export const Filters = React.memo(function Filters({ torrents, currentFilters, s }); return [labels, trackers]; - }, [torrents]); + }, [config, torrents]); const [sections, setSections] = useReducer( (_: SectionsVisibility, sections: SectionsVisibility) => { diff --git a/src/components/modals/common.tsx b/src/components/modals/common.tsx index 03658f6..241e55c 100644 --- a/src/components/modals/common.tsx +++ b/src/components/modals/common.tsx @@ -208,7 +208,7 @@ export function TorrentLocation(props: LocationData) { ); } -function Label({ +export function Label({ label, onRemove, classNames, @@ -243,14 +243,15 @@ interface TorrentLabelsProps { } export function TorrentLabels(props: TorrentLabelsProps) { + const config = useContext(ConfigContext); const serverData = useServerTorrentData(); const initialLabelset = useMemo(() => { - const labels = new Set(); + const labels = new Set(config.values.interface.preconfiguredLabels); serverData.torrents.forEach((t) => t.labels?.forEach((l: string) => labels.add(l))); return Array.from(labels).sort(); - }, [serverData.torrents]); + }, [config, serverData.torrents]); const [data, setData] = useState(initialLabelset); diff --git a/src/components/modals/interfacepanel.tsx b/src/components/modals/interfacepanel.tsx index 5464557..6d90a94 100644 --- a/src/components/modals/interfacepanel.tsx +++ b/src/components/modals/interfacepanel.tsx @@ -18,12 +18,13 @@ import React, { useCallback, useEffect, useState } from "react"; import type { ColorScheme } from "@mantine/core"; -import { Checkbox, Grid, NativeSelect, NumberInput, Textarea, useMantineTheme } from "@mantine/core"; +import { Checkbox, Grid, MultiSelect, NativeSelect, NumberInput, Textarea, useMantineTheme } from "@mantine/core"; import type { UseFormReturnType } from "@mantine/form"; import ColorChooser from "components/colorchooser"; import { useGlobalStyleOverrides } from "themehooks"; import { DeleteTorrentDataOptions, type ColorSetting, type DeleteTorrentDataOption, type StyleOverrides } from "config"; import { ColorSchemeToggle } from "components/miscbuttons"; +import { Label } from "./common"; const { TAURI, invoke } = await import(/* webpackChunkName: "taurishim" */"taurishim"); export interface InterfaceFormValues { @@ -33,6 +34,7 @@ export interface InterfaceFormValues { skipAddDialog: boolean, deleteTorrentData: DeleteTorrentDataOption, numLastSaveDirs: number, + preconfiguredLabels: string[], defaultTrackers: string[], }, } @@ -91,6 +93,10 @@ export function InterfaceSettigsPanel(props: { fo ? { color: "dark", shade: 7, computed: theme.colors.dark[7] } : { color: "gray", shade: 0, computed: theme.colors.gray[0] }; + const setPreconfiguredLabels = useCallback((labels: string[]) => { + setFieldValue("interface.preconfiguredLabels", labels); + }, [setFieldValue]); + return ( @@ -114,11 +120,7 @@ export function InterfaceSettigsPanel(props: { fo - - - - + Delete torrent data @@ -126,16 +128,37 @@ export function InterfaceSettigsPanel(props: { fo value={props.form.values.interface.deleteTorrentData} onChange={(e) => { setFieldValue("interface.deleteTorrentData", e.target.value); }} /> - Max number of saved download directories + + + + Max number of saved download directories - + + + `+ Add ${query}`} + onCreate={(query) => { + setPreconfiguredLabels([...props.form.values.interface.preconfiguredLabels, query]); + return query; + }} + valueComponent={Label} + /> + -