diff --git a/src/components/Filters.tsx b/src/components/Filters.tsx
index 24bc707..8f5e72c 100644
--- a/src/components/Filters.tsx
+++ b/src/components/Filters.tsx
@@ -51,9 +51,15 @@ export function useFilterState(): useFilterStateReturn {
export const FilterHeading = ({
disclosure,
indicator,
+ title = "Filters",
+ icon = ,
+ ...props
}: {
disclosure: UseDisclosureReturn;
indicator?: number;
+ title?: string;
+ icon?: React.ReactElement;
+ [key: string]: any;
}) => (
- Filters
+ {title}
{indicator ? (
@@ -75,7 +82,7 @@ export const FilterHeading = ({
) : null}
- {disclosure.isOpen ? : }
+ {disclosure.isOpen ? : icon}
);
diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx
index 122fe7c..047e9dc 100644
--- a/src/pages/Home.tsx
+++ b/src/pages/Home.tsx
@@ -16,8 +16,9 @@ import {
Switch,
VStack,
IconButton,
+ StepSeparator
} from "@chakra-ui/react";
-import { IoDocumentAttach, IoPause, IoPlay } from "react-icons/io5";
+import { IoDocumentAttach, IoPause, IoPlay, IoSwapVertical } from "react-icons/io5";
import { useMutation, useQuery } from "react-query";
import { TorrClient } from "../utils/TorrClient";
import { useEffect, useMemo, useRef, useState } from "react";
@@ -35,6 +36,19 @@ import { useFontSizeContext } from "../components/FontSizeProvider";
import { List, WindowScroller } from "react-virtualized";
+type SortKey =
+ | "added_on"
+ | "name"
+ | "size"
+ | "progress"
+ | "dlspeed"
+ | "upspeed";
+type SortDirection = "asc" | "desc";
+interface SortConfig {
+ key: SortKey;
+ direction: SortDirection;
+}
+
const Home = () => {
const { mutate: resumeAll } = useMutation("resumeAll", TorrClient.resumeAll);
@@ -135,6 +149,7 @@ const Home = () => {
const isLarge = useIsLargeScreen();
const filterDisclosure = useDisclosure();
+ const sortDisclosure = useDisclosure();
const [filterSearch, setFilterSearch] = useLocalStorage(
"home-filter-search",
""
@@ -147,6 +162,10 @@ const Home = () => {
"home-filter-status",
"Show All"
);
+ const [sortConfig, setSortConfig] = useLocalStorage(
+ "home-sort-config",
+ { key: "added_on", direction: "desc" }
+ );
const resetFilters = () => {
setFilterStatus("Show All");
@@ -172,7 +191,26 @@ const Home = () => {
}
return Object.entries(torrentsTx)
- ?.sort((a, b) => b[1]?.added_on - a[1]?.added_on)
+ ?.sort(([, a], [, b]) => {
+ if (!a || !b) return 0;
+ const aVal = a[sortConfig.key as keyof TorrTorrentInfo];
+ const bVal = b[sortConfig.key as keyof TorrTorrentInfo];
+
+ if (aVal === bVal) return 0;
+ if (aVal === undefined || aVal === null)
+ return sortConfig.direction === "asc" ? -1 : 1;
+ if (bVal === undefined || bVal === null)
+ return sortConfig.direction === "asc" ? 1 : -1;
+
+ let compare = 0;
+ if (typeof aVal === "string" && typeof bVal === "string") {
+ compare = aVal.localeCompare(bVal);
+ } else if (typeof aVal === "number" && typeof bVal === "number") {
+ compare = aVal - bVal;
+ }
+
+ return sortConfig.direction === "asc" ? compare : -compare;
+ })
?.filter(([hash]) => !removedTorrs.includes(hash))
?.filter(([hash, torr]) =>
filterCategory !== "Show All" ? torr.category === filterCategory : true
@@ -181,7 +219,14 @@ const Home = () => {
filterStatus !== "Show All" ? torr.state === filterStatus : true
)
?.filter(([hash, torr]) => torr.name.includes(filterSearch));
- }, [torrentsTx, removedTorrs, filterCategory, filterStatus, filterSearch]);
+ }, [
+ torrentsTx,
+ removedTorrs,
+ filterCategory,
+ filterStatus,
+ filterSearch,
+ sortConfig,
+ ]);
const Categories = useMemo(() => {
return Object.values(categories || {}).map((c) => ({
@@ -384,10 +429,32 @@ const Home = () => {
-
+
+ {
+ if (sortDisclosure.isOpen) {
+ sortDisclosure.onClose();
+ }
+ filterDisclosure.onToggle();
+ }}
+ roundedRight={0}
+ />
+
+ }
+ onClick={() => {
+ if (filterDisclosure.isOpen) {
+ filterDisclosure.onClose();
+ }
+ sortDisclosure.onToggle();
+ }}
+ roundedLeft={0}
+ />
+
{filterDisclosure.isOpen && (
@@ -425,6 +492,44 @@ const Home = () => {
)}
+ {sortDisclosure.isOpen && (
+
+
+ Sort by
+
+
+
+ Direction
+
+
+
+ )}
@@ -501,4 +606,4 @@ const Home = () => {
);
};
-export default Home;
+export default Home;
\ No newline at end of file