Skip to content

Commit

Permalink
Adding filters to home page
Browse files Browse the repository at this point in the history
Signed-off-by: ntoporcov <[email protected]>
  • Loading branch information
ntoporcov committed Sep 28, 2022
1 parent bb1ed02 commit 25fd6c8
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 43 deletions.
6 changes: 6 additions & 0 deletions announcements.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
"newUser": "Show to all new users (should be false most times)"
},
"announcements": [
{
"id": "Sep272022",
"title": "Download Filters Update",
"body": "Added some filters to the download tab.",
"type": "info"
},
{
"id": "Sep262022",
"title": "Trending Tab Update",
Expand Down
6 changes: 3 additions & 3 deletions release/public/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"files": {
"main.css": "/static/css/main.5e6dcba8.css",
"main.js": "/static/js/main.6027d2ac.js",
"main.js": "/static/js/main.ca97e1fe.js",
"static/media/logo_round.png": "/static/media/logo_round.48e39dcc28e956965f9e.png",
"index.html": "/index.html",
"main.5e6dcba8.css.map": "/static/css/main.5e6dcba8.css.map",
"main.6027d2ac.js.map": "/static/js/main.6027d2ac.js.map"
"main.ca97e1fe.js.map": "/static/js/main.ca97e1fe.js.map"
},
"entrypoints": [
"static/css/main.5e6dcba8.css",
"static/js/main.6027d2ac.js"
"static/js/main.ca97e1fe.js"
]
}
2 changes: 1 addition & 1 deletion release/public/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="iQbit WebUI for qBitTorrent"/><link rel="manifest" href="/manifest.json"/><title>iQbit</title><meta name="mobile-web-app-capable" content="yes"/><meta name="apple-touch-fullscreen" content="yes"/><meta name="apple-mobile-web-app-title" content="iQbit"/><meta name="apple-mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"><link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-icon-180.jpg"><link rel="apple-touch-icon" sizes="167x167" href="/assets/apple-icon-167.jpg"><link rel="apple-touch-icon" sizes="152x152" href="/assets/apple-icon-152.jpg"><link rel="apple-touch-icon" sizes="120x120" href="/assets/apple-icon-120.jpg"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2048-2732.jpg" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2732-2048.jpg" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1668-2388.jpg" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2388-1668.jpg" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1536-2048.jpg" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2048-1536.jpg" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1668-2224.jpg" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2224-1668.jpg" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1620-2160.jpg" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2160-1620.jpg" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1242-2688.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2688-1242.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1125-2436.jpg" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2436-1125.jpg" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-828-1792.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1792-828.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1080-1920.jpg" media="(device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1920-1080.jpg" media="(device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-750-1334.jpg" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1334-750.jpg" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-640-1136.jpg" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1136-640.jpg" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><script defer="defer" src="/static/js/main.6027d2ac.js"></script><link href="/static/css/main.5e6dcba8.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="iQbit WebUI for qBitTorrent"/><link rel="manifest" href="/manifest.json"/><title>iQbit</title><meta name="mobile-web-app-capable" content="yes"/><meta name="apple-touch-fullscreen" content="yes"/><meta name="apple-mobile-web-app-title" content="iQbit"/><meta name="apple-mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"><link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-icon-180.jpg"><link rel="apple-touch-icon" sizes="167x167" href="/assets/apple-icon-167.jpg"><link rel="apple-touch-icon" sizes="152x152" href="/assets/apple-icon-152.jpg"><link rel="apple-touch-icon" sizes="120x120" href="/assets/apple-icon-120.jpg"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2048-2732.jpg" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2732-2048.jpg" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1668-2388.jpg" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2388-1668.jpg" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1536-2048.jpg" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2048-1536.jpg" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1668-2224.jpg" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2224-1668.jpg" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1620-2160.jpg" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2160-1620.jpg" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1242-2688.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2688-1242.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1125-2436.jpg" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-2436-1125.jpg" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-828-1792.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1792-828.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1080-1920.jpg" media="(device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1920-1080.jpg" media="(device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-750-1334.jpg" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1334-750.jpg" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-640-1136.jpg" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"><link rel="apple-touch-startup-image" href="/assets/apple-splash-1136-640.jpg" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"><script defer="defer" src="/static/js/main.ca97e1fe.js"></script><link href="/static/css/main.5e6dcba8.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

Large diffs are not rendered by default.

Large diffs are not rendered by default.

70 changes: 44 additions & 26 deletions src/components/Filters.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React, { Dispatch, SetStateAction, useState } from "react";
import {
Badge,
Box,
Button,
Flex,
Heading,
LightMode,
Select,
Text,
useColorModeValue,
useDisclosure,
UseDisclosureReturn,
} from "@chakra-ui/react";
import { IoClose, IoFilter } from "react-icons/io5";
import { smartMap } from "../utils/smartMap";
Expand Down Expand Up @@ -45,39 +48,54 @@ export function useFilterState(): useFilterStateReturn {
};
}

export const FilterHeading = ({
disclosure,
indicator,
}: {
disclosure: UseDisclosureReturn;
indicator?: number;
}) => (
<Flex
p={5}
as={"button"}
onClick={disclosure.onToggle}
width={"100%"}
rounded={6}
alignItems={"center"}
justifyContent={"space-between"}
gap={2}
>
<Heading as={"span"} size={"sm"}>
Filters
<LightMode>
{indicator ? (
<Badge bgColor={"blue.500"} color={"white"} ml={3}>
{indicator}
</Badge>
) : null}
</LightMode>
</Heading>
{disclosure.isOpen ? <IoClose /> : <IoFilter />}
</Flex>
);

const Filters = (state: useFilterStateReturn) => {
const filterDisclosure = useDisclosure();
const backgroundColor = useColorModeValue("blackAlpha.50", "grayAlpha.400");

const heading = (
<Flex
as={"button"}
onClick={filterDisclosure.onToggle}
bgColor={filterDisclosure.isOpen ? undefined : backgroundColor}
width={"100%"}
p={filterDisclosure.isOpen ? undefined : 3}
rounded={6}
alignItems={"center"}
justifyContent={"space-between"}
gap={2}
>
<Heading as={"span"} size={"sm"}>
Filters
</Heading>
{filterDisclosure.isOpen ? <IoClose /> : <IoFilter />}
</Flex>
);

if (!filterDisclosure.isOpen) {
return heading;
}

const inputSizes = { base: "md", lg: "sm" };

return (
<Box bgColor={backgroundColor} p={3} rounded={6} width={"100%"}>
{heading}
<Flex mt={3} gap={5} wrap={{ base: "wrap", lg: "nowrap" }}>
<Box bgColor={backgroundColor} rounded={6} width={"100%"}>
<FilterHeading disclosure={filterDisclosure} />
<Flex
px={4}
pb={4}
hidden={!filterDisclosure.isOpen}
mt={3}
gap={5}
wrap={{ base: "wrap", lg: "nowrap" }}
>
<Flex width={"100%"}>
{smartMap([...qualities], (qual, { isLast, isFirst }) => (
<Button
Expand Down
12 changes: 7 additions & 5 deletions src/components/SegmentedPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { Button, SimpleGrid } from "@chakra-ui/react";
import { Button, SimpleGrid, useColorModeValue } from "@chakra-ui/react";

export interface SegmentedPickerProps {
options: string[];
Expand All @@ -8,9 +8,12 @@ export interface SegmentedPickerProps {
}

const SegmentedPicker = (props: SegmentedPickerProps) => {
const selectedBg = useColorModeValue("white", "blackAlpha.700");
const pickerBg = useColorModeValue("gray.100", "grayAlpha.400");

return (
<SimpleGrid
backgroundColor={"grayAlpha.400"}
backgroundColor={pickerBg}
columns={props.options.length}
mt={3}
mb={5}
Expand All @@ -23,12 +26,11 @@ const SegmentedPicker = (props: SegmentedPickerProps) => {
>
{props.options.map((option, index) => (
<Button
backgroundColor={
index === props.selected ? "grayAlpha.800" : undefined
}
backgroundColor={index === props.selected ? selectedBg : undefined}
key={option}
onClick={() => props.onSelect(index)}
variant={"unstyled"}
shadow={index === props.selected ? "xl" : undefined}
>
{option}
</Button>
Expand Down
76 changes: 73 additions & 3 deletions src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import PageHeader from "../components/PageHeader";
import {
Box,
Button,
ButtonGroup,
Flex,
Expand All @@ -10,6 +11,7 @@ import {
LightMode,
Select,
Textarea,
useColorModeValue,
useDisclosure,
VStack,
} from "@chakra-ui/react";
Expand All @@ -24,7 +26,9 @@ import { Input } from "@chakra-ui/input";
import { useIsLargeScreen } from "../utils/screenSize";
import { randomTorrent } from "../data";
import { List, WindowScroller } from "react-virtualized";
import "react-virtualized/styles.css"; // only needs to be imported once
import "react-virtualized/styles.css";
import { FilterHeading } from "../components/Filters";
import stateDictionary from "../utils/StateDictionary"; // only needs to be imported once

const Home = () => {
const { mutate: resumeAll } = useMutation("resumeAll", TorrClient.resumeAll);
Expand Down Expand Up @@ -111,11 +115,33 @@ const Home = () => {

const isLarge = useIsLargeScreen();

const filterDisclosure = useDisclosure();
const [filterSearch, setFilterSearch] = useState<string>("");
const [filterCategory, setFilterCategory] = useState<string>("Show All");
const [filterStatus, setFilterStatus] = useState<string>("Show All");
const bgColor = useColorModeValue("white", "gray.900");

const filterIndicator = useMemo(() => {
let indicator = 0;
if (filterSearch !== "") indicator++;
if (filterStatus !== "Show All") indicator++;
if (filterCategory !== "Show All") indicator++;

return indicator;
}, [filterCategory, filterSearch, filterStatus]);

const Torrents = useMemo(() => {
return Object.entries(torrentsTx)
?.sort((a, b) => b[1]?.added_on - a[1]?.added_on)
?.filter(([hash]) => !removedTorrs.includes(hash));
}, [torrentsTx, removedTorrs]);
?.filter(([hash]) => !removedTorrs.includes(hash))
?.filter(([hash, torr]) =>
filterCategory !== "Show All" ? torr.category === filterCategory : true
)
?.filter(([hash, torr]) =>
filterStatus !== "Show All" ? torr.state === filterStatus : true
)
?.filter(([hash, torr]) => torr.name.includes(filterSearch));
}, [torrentsTx, removedTorrs, filterCategory, filterStatus, filterSearch]);

const Categories = useMemo(() => {
return Object.values(categories || {}).map((c) => ({
Expand Down Expand Up @@ -267,6 +293,50 @@ const Home = () => {
</Button>
</ButtonGroup>

<Box bgColor={bgColor} rounded={"lg"} mb={5}>
<FilterHeading
indicator={filterIndicator}
disclosure={filterDisclosure}
/>
{filterDisclosure.isOpen && (
<Flex flexDirection={"column"} gap={5} px={5} pb={5}>
<FormControl>
<FormLabel>Search</FormLabel>
<Input
value={filterSearch}
onChange={(e) => setFilterSearch(e.target.value)}
/>
</FormControl>
<FormControl>
<FormLabel>Category</FormLabel>
<Select
value={filterCategory}
onChange={(e) => setFilterCategory(e.target.value)}
>
<option>Show All</option>
{Categories.map((cat) => (
<option key={cat.label}>{cat.label}</option>
))}
</Select>
</FormControl>
<FormControl>
<FormLabel>Status</FormLabel>
<Select
value={filterStatus}
onChange={(e) => setFilterStatus(e.target.value)}
>
<option>Show All</option>
{Object.entries(stateDictionary).map(([key, data]) => (
<option key={key} value={key}>
{data.short}
</option>
))}
</Select>
</FormControl>
</Flex>
)}
</Box>

<Flex flexDirection={"column"} gap={5}>
{isLoading &&
Array.from(Array(10).keys()).map((key) => (
Expand Down
Loading

0 comments on commit 25fd6c8

Please sign in to comment.