/* * Copyright (c) 2021 - 2023, Ludvig Lundgren and the autobrr contributors. * SPDX-License-Identifier: GPL-2.0-or-later */ import { Fragment, useRef, useState, useMemo } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { Menu, Switch, Transition } from "@headlessui/react"; import { toast } from "react-hot-toast"; import { ArrowsRightLeftIcon, DocumentTextIcon, EllipsisHorizontalIcon, PencilSquareIcon, TrashIcon } from "@heroicons/react/24/outline"; import { APIClient } from "@api/APIClient"; import { useToggle } from "@hooks/hooks"; import { baseUrl, classNames, IsEmptyDate, simplifyDate } from "@utils"; import Toast from "@components/notifications/Toast"; import { DeleteModal } from "@components/modals"; import { FeedUpdateForm } from "@forms/settings/FeedForms"; import { EmptySimple } from "@components/emptystates"; import { ImplementationBadges } from "./Indexer"; export const feedKeys = { all: ["feeds"] as const, lists: () => [...feedKeys.all, "list"] as const, // list: (indexers: string[], sortOrder: string) => [...feedKeys.lists(), { indexers, sortOrder }] as const, details: () => [...feedKeys.all, "detail"] as const, detail: (id: number) => [...feedKeys.details(), id] as const }; interface SortConfig { key: keyof ListItemProps["feed"] | "enabled"; direction: "ascending" | "descending"; } function useSort(items: ListItemProps["feed"][], config?: SortConfig) { const [sortConfig, setSortConfig] = useState(config); const sortedItems = useMemo(() => { if (!sortConfig) { return items; } const sortableItems = [...items]; sortableItems.sort((a, b) => { const aValue = sortConfig.key === "enabled" ? (a[sortConfig.key] ?? false) as number | boolean | string : a[sortConfig.key] as number | boolean | string; const bValue = sortConfig.key === "enabled" ? (b[sortConfig.key] ?? false) as number | boolean | string : b[sortConfig.key] as number | boolean | string; if (aValue < bValue) { return sortConfig.direction === "ascending" ? -1 : 1; } if (aValue > bValue) { return sortConfig.direction === "ascending" ? 1 : -1; } return 0; }); return sortableItems; }, [items, sortConfig]); const requestSort = (key: keyof ListItemProps["feed"] | "enabled") => { let direction: "ascending" | "descending" = "ascending"; if ( sortConfig && sortConfig.key === key && sortConfig.direction === "ascending" ) { direction = "descending"; } setSortConfig({ key, direction }); }; const getSortIndicator = (key: keyof ListItemProps["feed"]) => { if (!sortConfig || sortConfig.key !== key) { return ""; } return sortConfig.direction === "ascending" ? "↑" : "↓"; }; return { items: sortedItems, requestSort, sortConfig, getSortIndicator }; } function FeedSettings() { const { data } = useQuery({ queryKey: feedKeys.lists(), queryFn: APIClient.feeds.find, refetchOnWindowFocus: false }); const sortedFeeds = useSort(data || []); return (
Manage RSS, Newznab, and Torznab feeds.