import * as React from "react" import clsx from "clsx" import type { SearchParams } from "../types/SearchParams" import BulletIcon from "../icons/Bullet" import EnglishIcon from "../icons/English" import SortIcon from "../icons/Sort" import KnightIcon from "../icons/Knight" import LightningIcon from "../icons/Lightning" import PawnIcon from "../icons/Pawn" import RabbitIcon from "../icons/Rabbit" import RightArrowIcon from "../icons/RightArrow" import RisingGraphIcon from "../icons/RisingGraph" import TrophyIcon from "../icons/Trophy" import { Button } from "./Button" import { Mode } from "../types/Mode" import { Site } from "../types/Site" import { Title } from "../types/Title" interface SortOption { title: string Icon: ({ ...props }: { [x: string]: any }) => React.JSX.Element enable: (p: SearchParams) => SearchParams isEnabled: (p: SearchParams) => boolean } const filters: SortOption[] = [ { title: "On Lichess", Icon: KnightIcon, enable: (p) => { p.sites.push(Site.LICHESS) return p }, isEnabled: (p) => p.sites.includes(Site.LICHESS), }, { title: "On Chess.com", Icon: PawnIcon, enable: (p) => { p.sites.push(Site.CHESSCOM) return p }, isEnabled: (p) => p.sites.includes(Site.CHESSCOM), }, { title: "English Speaking", Icon: EnglishIcon, enable: (p) => { for (const lang of ["en-US", "en-GB"]) { if (!p.languages.includes(lang)) { p.languages.push(lang) } } return p }, // Using `||` doesn't match how `enable` works but this is probably closer // to how people would expect the filter to operate. isEnabled: (p) => p.languages.includes("en-US") || p.languages.includes("en-GB"), }, { title: "ELO 2000+", Icon: RisingGraphIcon, enable: (p) => { p.rating[0] = Math.max(2000, p.rating[0]) return p }, isEnabled: (p) => p.rating[0] >= 2000, }, { title: "Rapid Specialty", Icon: RabbitIcon, enable: (p) => { p.modes = [Mode.RAPID] return p }, isEnabled: (p) => p.modes.length === 1 && p.modes.includes(Mode.RAPID), }, { title: "Blitz Specialty", Icon: LightningIcon, enable: (p) => { p.modes = [Mode.BLITZ] return p }, isEnabled: (p) => p.modes.length === 1 && p.modes.includes(Mode.BLITZ), }, { title: "Bullet Specialty", Icon: BulletIcon, enable: (p) => { p.modes = [Mode.BULLET] return p }, isEnabled: (p) => p.modes.length === 1 && p.modes.includes(Mode.BULLET), }, { title: "Titled Player", Icon: TrophyIcon, enable: (p) => { p.titles = Object.keys(Title) as Title[] return p }, isEnabled: (p) => p.titles.length > 0, }, ] enum Direction { LEFT, RIGHT, } interface SortScrollProps { params: SearchParams onModal: () => void onSelect: (p: SearchParams) => void } export function SortScroll({ params, onModal, onSelect }: SortScrollProps) { const viewport = React.useRef(null) const [isFlush, setIsFlush] = React.useState([true, false]) const scrollDir = (dir: Direction) => { const v = viewport.current if (!v) { return } const delta = v.clientWidth / 2 const left = v.scrollLeft + (dir == Direction.RIGHT ? delta : -delta) v.scroll({ left, behavior: "smooth" }) const isFlushLeft = left <= 1 const isFlushRight = left + v.clientWidth >= v.scrollWidth setIsFlush([isFlushLeft, isFlushRight]) } return (
{[...filters].map((e) => (
onSelect(e.enable({ ...params }))} > {e.title}
))}
) }