Skip to content

Commit

Permalink
New scrollbar
Browse files Browse the repository at this point in the history
Adjusted styling on filter buttons
Adjustments to clickable area on search result items
Fixed bug when switching between filter toggles
Fixed range numbers getting jumbled values
Enabled improved filter functionality
  • Loading branch information
dons20 committed Mar 25, 2021
1 parent df6efa4 commit e1c98a9
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 66 deletions.
1 change: 0 additions & 1 deletion src/components/SongDisplay/SongDisplay.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.songs > .container {
align-content: space-between;
display: grid;
grid-row: 1 / span 2;
grid-auto-rows: max-content;
Expand Down
14 changes: 12 additions & 2 deletions src/components/SongList/defaults.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
/**
* TODO: Sync these with local state
*/

export const DEFAULT_ALPHA_PROPS = {
enabled: false,
sortDescending: true,
sortDescending: false,
};

export const DEFAULT_NUM_PROPS = {
enabled: true,
sortDescending: true,
sortDescending: false,
};

export const DEFAULT_FILTER_PROPS = {
enabled: false,
currValue: null,
};
135 changes: 80 additions & 55 deletions src/components/SongList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState, useEffect, useContext, useCallback, useRef } from "react";
import { FaSortAlphaDown, FaSortAlphaDownAlt, FaSortNumericDown, FaSortNumericDownAlt } from "react-icons/fa";
import { DEFAULT_ALPHA_PROPS, DEFAULT_FILTER_PROPS, DEFAULT_NUM_PROPS } from "./defaults";
import { FixedSizeGrid, GridChildComponentProps } from "react-window";
import { DEFAULT_ALPHA_PROPS, DEFAULT_NUM_PROPS } from "./defaults";
import AutoSizer from "react-virtualized-auto-sizer";
import { useHistory } from "react-router-dom";
import { Helmet } from "react-helmet";
Expand Down Expand Up @@ -65,21 +65,21 @@ function SongList() {
// TODO: Sync all filter options with local storage as preferences

/** Local State to handle list behaviour */
const [filterAlphaProps, setFilterAlphaProps] = useState(DEFAULT_ALPHA_PROPS);
const [filterNumberProps, setFilterNumberProps] = useState(DEFAULT_NUM_PROPS);
const [sortAlphaProps, setSortAlphaProps] = useState(DEFAULT_ALPHA_PROPS);
const [sortNumberProps, setSortNumberProps] = useState(DEFAULT_NUM_PROPS);
const [filterLetterProps, setFilterLetterProps] = useState(DEFAULT_FILTER_PROPS);
const [filterNumberProps, setFilterNumberProps] = useState(DEFAULT_FILTER_PROPS);
const [finalList, setFinalList] = useState<Song[]>(
sortList(filterAlphaProps.enabled, filterNumberProps.sortDescending, songs, true)
sortList(sortAlphaProps.enabled, sortNumberProps.sortDescending, songs, true)
); // Contains a copy of songs from the context
// const [numbers, setNumbers] = useState<NumberP[]>([]); // An array of available song number categories
// const [letters, setLetters] = useState<LetterP[]>([]); // An array of available song letter categories

/** Virtualized list props */
const wrapperRef = useRef<HTMLDivElement>(null);
const [dualColumns] = useMediaQuery("(min-width: 951px)");
const numColumns = useRef(dualColumns ? 2 : 1);
const numColumns = dualColumns ? 2 : 1;
const numRows = useRef(0);

if (numColumns.current === 2) numRows.current = Math.ceil(finalList.length / 2);
if (numColumns === 2) numRows.current = Math.ceil(finalList.length / 2);
else numRows.current = finalList.length;

/** Handles Filter Drawer display */
Expand All @@ -104,12 +104,14 @@ function SongList() {
const createMenu = useCallback(() => {
let characters = [],
numbers = [];
for (let i = 0; i < finalList.length; i++) {
characters.push(finalList[i].title.charAt(0));
numbers.push(finalList[i].number);
// Ensure we're getting numbers in order for later
let songsCopy = [...songs!].sort((a, b) => a.number - b.number);
for (let i = 0; i < songsCopy.length; i++) {
characters.push(songsCopy[i].title.charAt(0));
numbers.push(songsCopy[i].number);
}
return { letters: String.prototype.concat(...new Set(characters)), numbers: numbers };
}, [finalList]);
}, [songs]);

const generateMenuOptions = useCallback((): MenuOptionsFnT => {
const menuValues = createMenu();
Expand Down Expand Up @@ -145,50 +147,54 @@ function SongList() {
function filterSongs(props: FilterSongT) {
let filtered: Song[] = [];
if (props.type === "numbers") {
if (!filterNumberProps.enabled) return;
filtered = songs!.filter(song => song.number === props.value);
} else if (props.type === "range") {
if (!filterNumberProps.enabled) return;
filtered = songs!.filter(song => song.number >= props.value[0] && song.number <= props.value[1]);
} else if (props.type === "letters") {
if (!filterLetterProps.enabled) return;
filtered = songs!.filter(song => song.title.charAt(0) === props.value);
}

const isAlphabetical = filterAlphaProps.enabled;
const sortDescending = isAlphabetical ? filterAlphaProps.sortDescending : filterNumberProps.sortDescending;
sortList(filterAlphaProps.enabled, sortDescending, filtered);
const isAlphabetical = sortAlphaProps.enabled;
const sortDescending = isAlphabetical ? sortAlphaProps.sortDescending : sortNumberProps.sortDescending;
sortList(sortAlphaProps.enabled, sortDescending, filtered);
}

/** [ASC/DESC] Handles list filter directional changes */
function handleFilterChange(value: string | number, filterType: FilterT) {
const sortDescending = value === "Descending";
console.log("Filter time: ", sortDescending);

if (filterType === FILTER_TYPES.NUM) {
setFilterNumberProps(props => ({ ...props, sortDescending: sortDescending }));
if (filterNumberProps.enabled) handleFilterToggle(filterType);
setSortNumberProps(props => ({ ...props, sortDescending }));
if (sortNumberProps.enabled) handleFilterToggle(filterType, sortDescending);
}

if (filterType === FILTER_TYPES.ALPHA) {
setFilterAlphaProps(props => ({ ...props, sortDescending: sortDescending }));
if (filterAlphaProps.enabled) handleFilterToggle(filterType);
setSortAlphaProps(props => ({ ...props, sortDescending }));
if (sortAlphaProps.enabled) handleFilterToggle(filterType, sortDescending);
}
}

/** [Enable Options] Handles list filter features enable / disable */
function handleFilterToggle(filterType: FilterT) {
console.log("Toggle called ", filterType);
function handleFilterToggle(filterType: FilterT, sortDesc?: boolean) {
console.log("Toggle called ", filterType, sortDesc);
if (filterType !== FILTER_TYPES.FAVE) {
const sortAlphabetical = filterType === FILTER_TYPES.ALPHA;
const sortDescending = sortAlphabetical
? filterAlphaProps.sortDescending
: filterNumberProps.sortDescending;
let sortDescending: boolean;
if (sortDesc !== undefined) sortDescending = sortDesc;
else sortDescending = sortAlphabetical ? sortAlphaProps.sortDescending : sortNumberProps.sortDescending;

console.log(sortDescending);
setFilterNumberProps(props => ({ ...props, enabled: !sortAlphabetical }));
setFilterAlphaProps(props => ({ ...props, enabled: sortAlphabetical }));
console.log("Filter toggle values: ", sortAlphabetical, sortDescending);
setSortNumberProps(props => ({ ...props, enabled: !sortAlphabetical }));
setSortAlphaProps(props => ({ ...props, enabled: sortAlphabetical }));
sortList(sortAlphabetical, sortDescending);
} else {
const isAlphabetical = filterAlphaProps.enabled;
const sortDescending = isAlphabetical ? filterAlphaProps.sortDescending : filterNumberProps.sortDescending;
sortList(filterAlphaProps.enabled, sortDescending, songs);
const isAlphabetical = sortAlphaProps.enabled;
const sortDescending = isAlphabetical ? sortAlphaProps.sortDescending : sortNumberProps.sortDescending;
sortList(sortAlphaProps.enabled, sortDescending, songs);
}
}

Expand All @@ -201,11 +207,14 @@ function SongList() {
): Song[] {
const newArray = sourceList ? [...sourceList] : [...finalList];

console.log(sortAlphabetically, sortDescending);

if (sortAlphabetically) {
if (sortDescending) newArray.sort((a, b) => a.title.localeCompare(b.title));
if (!sortDescending) newArray.sort((a, b) => a.title.localeCompare(b.title));
else newArray.sort((a, b) => b.title.localeCompare(a.title));
console.log(newArray[0]);
} else {
if (sortDescending) newArray.sort((a, b) => a.number - b.number);
if (!sortDescending) newArray.sort((a, b) => a.number - b.number);
else newArray.sort((a, b) => b.number - a.number);
}

Expand All @@ -224,9 +233,14 @@ function SongList() {
return (
<>
{values.map(number => (
<Radio value={number.start} key={number.start}>
<Button
key={number.start}
onClick={number.callback}
size="sm"
disabled={!filterNumberProps.enabled}
>
{number.start} - {number.end}
</Radio>
</Button>
))}
</>
);
Expand All @@ -237,17 +251,22 @@ function SongList() {
return (
<>
{values.map(letter => (
<Radio value={letter.value} key={letter.value}>
<Button
key={letter.value}
onClick={letter.callback}
size="sm"
disabled={!filterLetterProps.enabled}
>
{letter.value}
</Radio>
</Button>
))}
</>
);
};

/** Renders a single cell */
const Cell = ({ columnIndex, rowIndex, style, data }: GridChildComponentProps) => {
const itemIndex = rowIndex * numColumns.current + columnIndex;
const itemIndex = rowIndex * numColumns + columnIndex;
if (itemIndex >= finalList.length) return null;
return (
<Box
Expand All @@ -268,7 +287,7 @@ function SongList() {
<VStack pl={5} spacing={6}>
<RadioGroup
name="sorting-type"
value={filterAlphaProps.enabled ? FILTER_TYPES.ALPHA : FILTER_TYPES.NUM}
value={sortAlphaProps.enabled ? FILTER_TYPES.ALPHA : FILTER_TYPES.NUM}
onChange={nextValue => handleFilterToggle(nextValue as FILTER_TYPES)}
w="100%"
>
Expand All @@ -281,15 +300,15 @@ function SongList() {
</Radio>
<RadioGroup
name="sort-alpha"
value={filterAlphaProps.sortDescending ? "Descending" : "Ascending"}
value={sortAlphaProps.sortDescending ? "Descending" : "Ascending"}
onChange={nextValue => handleFilterChange(nextValue, FILTER_TYPES.ALPHA)}
>
<Stack>
<Radio value="Ascending">
Ascending <SortAlphaUpIcon />
Ascending <SortAlphaDownIcon />
</Radio>
<Radio value="Descending">
Descending <SortAlphaDownIcon />
Descending <SortAlphaUpIcon />
</Radio>
</Stack>
</RadioGroup>
Expand All @@ -303,15 +322,15 @@ function SongList() {
</Radio>
<RadioGroup
name="sort-numeric"
value={filterNumberProps.sortDescending ? "Descending" : "Ascending"}
value={sortNumberProps.sortDescending ? "Descending" : "Ascending"}
onChange={value => handleFilterChange(value, FILTER_TYPES.NUM)}
>
<Stack>
<Radio value="Ascending">
Ascending <SortNumericUpIcon />
Ascending <SortNumericDownIcon />
</Radio>
<Radio value="Descending">
Descending <SortNumericDownIcon />
Descending <SortNumericUpIcon />
</Radio>
</Stack>
</RadioGroup>
Expand All @@ -323,36 +342,42 @@ function SongList() {
<Heading fontSize="lg">Filter By Letter</Heading>
<Box mt={4}>
<Stack>
<Checkbox>Enable</Checkbox>
<RadioGroup
name="filter-letter"
defaultValue={FILTER_DIRS.DESCENDING}
onChange={value => handleFilterChange(value, FILTER_TYPES.NUM)}
<Checkbox
defaultChecked={filterLetterProps.enabled}
onChange={() => setFilterLetterProps(props => ({ ...props, enabled: !props.enabled }))}
>
Enable
</Checkbox>
<Flex flexWrap="wrap">
<Stack>
<LetterItems />
</Stack>
</RadioGroup>
</Flex>
</Stack>
</Box>
</Box>
<Box w="100%">
<Heading fontSize="lg">Filter By Range</Heading>
<Box mt={4}>
<Stack>
<Checkbox>Enable</Checkbox>
<RadioGroup name="filter-range" onChange={value => handleFilterChange(value, FILTER_TYPES.NUM)}>
<Checkbox
defaultChecked={filterNumberProps.enabled}
onChange={() => setFilterNumberProps(props => ({ ...props, enabled: !props.enabled }))}
>
Enable
</Checkbox>
<Flex flexWrap="wrap">
<Stack>
<NumberItems />
</Stack>
</RadioGroup>
</Flex>
</Stack>
</Box>
</Box>
<Box w="100%">
<Heading fontSize="lg">Favourites</Heading>
<Box mt={4}>
<Checkbox value="Favourites" onChange={() => handleFilterToggle(FILTER_TYPES.FAVE)}>
<Checkbox value="Favourites" onChange={() => handleFilterToggle(FILTER_TYPES.FAVE)} disabled>
Only favourites
</Checkbox>
</Box>
Expand Down Expand Up @@ -418,7 +443,7 @@ function SongList() {
width={width}
rowHeight={100}
columnWidth={window.innerWidth > 950 ? width / 2 - 8 : width - 8}
columnCount={numColumns.current}
columnCount={numColumns}
rowCount={numRows.current}
itemData={finalList}
style={{ overflowX: "hidden" }}
Expand Down
29 changes: 27 additions & 2 deletions src/index.css → src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,31 @@ button:-moz-focusring,
outline: 1px dotted ButtonText;
}

.ant-card-head-title {
font-weight: bold;
/* custom scrollbar */
::-webkit-scrollbar {
width: 20px;
}

::-webkit-scrollbar-track {
background-color: transparent;
}

::-webkit-scrollbar-thumb {
background-color: #d6dee1;
border-radius: 20px;
border: 6px solid transparent;
background-clip: content-box;
}

::-webkit-scrollbar-thumb:hover {
background-color: #a8aebf;
}

html[style="--chakra-ui-color-mode:light;"] {
& ::-webkit-scrollbar-thumb {
background-color: #a5acaf;
&:hover {
background-color: #888d9c;
}
}
}
2 changes: 1 addition & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ChakraProvider, ColorModeScript } from "@chakra-ui/react";
import { unregister } from "./serviceWorker";

import "focus-visible/dist/focus-visible";
import "./index.css";
import "./index.scss";

import { customTheme } from "theme";
import App from "./App";
Expand Down
4 changes: 1 addition & 3 deletions src/pages/Search/Search.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@

.gridItemWrapper {
align-items: center;
// border-bottom: 1px solid rgba(0, 0, 0, 0.12);
// border-right: 1px solid rgba(0, 0, 0, 0.12);
cursor: pointer;
text-align: left;
user-select: none;
}

.gridItem {
cursor: pointer;
transition: transform 0.1s ease-in-out;
will-change: transform;
&:hover {
Expand Down
Loading

0 comments on commit e1c98a9

Please sign in to comment.