diff --git a/src/components/ContentWrapper.tsx b/src/components/ContentWrapper.tsx index a3265e9..e4232ec 100644 --- a/src/components/ContentWrapper.tsx +++ b/src/components/ContentWrapper.tsx @@ -234,7 +234,7 @@ const ContentWrapper = (mainProps: ContentWrapperProps) => { open={false} className={getPopupClass(os)} width="1000px" - height="540px" + height="620px" openFnRef={openAdvancedCollectionSearch} closeFnRef={closeAdvancedCollectionSearch} > diff --git a/src/components/ui/Section.tsx b/src/components/ui/Section.tsx index 650fa78..f202632 100644 --- a/src/components/ui/Section.tsx +++ b/src/components/ui/Section.tsx @@ -6,10 +6,13 @@ export type SectionProps = React.PropsWithChildren<{ style?: CSSProperties; onClick?: () => void; className?: string; + showIf?: boolean; }>; export default function Section(props: SectionProps): JSX.Element { - const { children, style, onClick, className } = props; + const { children, style, onClick, className, showIf } = props; + + if (showIf === false) return <>; return (
{ - if (f.id == "boosters") { + defaultFilters.forEach((f) => { + if (f.id == "booster" && f.type == "inbool") { const filter: InBoolFilter = f.value; if (filter.not == false) boostersMode = inBoostersMode[1]; if (filter.not == true) boostersMode = inBoostersMode[0]; @@ -98,13 +98,16 @@ export default function CollectionStatsPanel({ if (!stats) { return <>; } + const setStats = stats.complete; const wanted: { [key: string]: number } = {}; const missing: { [key: string]: number } = {}; + const filteredRarities = CARD_RARITIES.filter((rarity) => { const key = getRarityKey(rarity); return !!key && setStats[key].total > 0; }); + filteredRarities.forEach((rarity) => { const key = getRarityKey(rarity); if (key) { diff --git a/src/components/views/collection/SetsView.tsx b/src/components/views/collection/SetsView.tsx index 5132078..2cc8615 100644 --- a/src/components/views/collection/SetsView.tsx +++ b/src/components/views/collection/SetsView.tsx @@ -14,13 +14,12 @@ import SetCompletionStats from "./SetCompletionStats"; interface SetsViewProps { stats: CollectionStats; - filterSets: string[]; filters: Filters; setQuery: (query: string) => void; } export default function SetsView(props: SetsViewProps): JSX.Element { - const { stats, filterSets, filters, setQuery } = props; + const { stats, filters, setQuery } = props; const { futureBoosters, @@ -29,7 +28,16 @@ export default function SetsView(props: SetsViewProps): JSX.Element { boosterWinFactor, } = useSelector((state: AppState) => state.collection); - const firstSet = filterSets[0] ? filterSets[0].toLowerCase() : ""; + const setsFiltered: string[] = []; + filters.forEach((f) => { + if (f.type === "array" && f.id === "setCode") { + f.value.arr.forEach((setCode) => setsFiltered.push(setCode)); + } + }); + + const firstSet = setsFiltered.sort()[0] ?? ""; + + const setsSelectedNum = setsFiltered.length; const currentSetName = Object.keys(database.sets).filter( (s) => database.sets[s].arenacode.toLowerCase() == firstSet @@ -44,53 +52,56 @@ export default function SetsView(props: SetsViewProps): JSX.Element { return (
- {stats[firstSet] ? ( - <> -
- -
-
{currentSetName}
- - {database.sets[currentSetName]?.collation !== -1 ? ( - - ) : ( -
This set is not available for draft
- )} -
-
- -
- - ) : ( -
-
Select a set to see detailed statistics
-
- )} +
1} style={{ gridArea: "set" }}> +
+ Select only one set to see per-set statistics +
+
+ +
+ +
+
{currentSetName}
+ + {database.sets[currentSetName]?.collation !== -1 ? ( + + ) : ( +
This set is not available for draft
+ )} +
+ +
+ +
+ +
+
Select a set to see detailed statistics.
+
+
diff --git a/src/components/views/collection/ViewCollection.tsx b/src/components/views/collection/ViewCollection.tsx index b65944a..7c45b4e 100644 --- a/src/components/views/collection/ViewCollection.tsx +++ b/src/components/views/collection/ViewCollection.tsx @@ -6,11 +6,10 @@ import { useHistory, useRouteMatch } from "react-router-dom"; import usePagingControls from "../../../hooks/usePagingControls"; import reduxAction from "../../../redux/reduxAction"; -import store, { AppState } from "../../../redux/stores/rendererStore"; +import { AppState } from "../../../redux/stores/rendererStore"; import { CardsData } from "../../../types/collectionTypes"; import { Filters } from "../../../types/genericFilterTypes"; import doCollectionFilter from "../../../utils/tables/doCollectionFilter"; -import setFilter from "../../../utils/tables/filters/setFilter"; import InputContainer from "../../InputContainer"; import PagingControls from "../../PagingControls"; import SetsFilter from "../../SetsFilter"; @@ -19,7 +18,7 @@ import Button from "../../ui/Button"; import Section from "../../ui/Section"; import Toggle from "../../ui/Toggle"; import CardCollection from "./CardCollection"; -import getFiltersFromQuery from "./collectionQuery"; +import getFiltersFromQuery, { removeFilterFromQuery } from "./collectionQuery"; import { getCollectionStats } from "./collectionStats"; import makeExportSetForScryfallFn from "./exportSetForScryfall"; import SetsView from "./SetsView"; @@ -42,23 +41,29 @@ export default function ViewCollection(props: ViewCollectionProps) { makeExportSetForScryfallFn(collectionData); - const [filterSets, setFilterSets] = useState([]); - const [filters, setFilters] = useState>(); const [sortValue, setSortValue] = useState>({ key: "setCode", sort: -1, }); + const filterSets = useMemo(() => { + const sets: string[] = []; + if (filters) { + filters.forEach((f) => { + if (f.type === "array" && f.id === "setCode") { + f.value.arr.forEach((setCode) => sets.push(setCode)); + } + }); + } + return sets; + }, [filters]); + const toggleView = useCallback(() => { if (viewMode === "cards") setViewMode("set"); else if (viewMode === "set") setViewMode("cards"); }, [viewMode]); - const forceQuery = useSelector( - (state: AppState) => state.renderer.forceQuery - ); - const collectionQuery = useSelector( (state: AppState) => state.renderer.collectionQuery ); @@ -74,33 +79,16 @@ export default function ViewCollection(props: ViewCollectionProps) { const pagingControlProps = usePagingControls(filteredData.length, 24); useEffect(() => { - const newFilters = getFiltersFromQuery( - store.getState().renderer.collectionQuery - ); + const newFilters = getFiltersFromQuery(collectionQuery); setFilters(newFilters); - newFilters.forEach((f) => { - if (f.id === "setCode" && f.type === "array") { - setFilterSets(f.value.arr); - } - }); - }, [forceQuery]); - - useEffect(() => { - if (filters) { - filters.forEach((f) => { - if (f.id === "setCode" && f.type === "array") { - setFilterSets(f.value.arr); - } - }); - } - }, [filters]); + }, [collectionQuery]); useEffect(() => { if (match) { const { query } = match.params; reduxAction(dispatch, { type: "SET_COLLECTION_QUERY", - arg: { query, forceQuery: true }, + arg: { query }, }); } }, []); @@ -114,55 +102,33 @@ export default function ViewCollection(props: ViewCollectionProps) { (query: string) => { reduxAction(dispatch, { type: "SET_COLLECTION_QUERY", - arg: { query, forceQuery: true }, + arg: { query }, }); }, [dispatch] ); - const setFilterSetsPre = useCallback( + const setFilterSets = useCallback( (sets: string[]) => { - // if (filters) { - // const newFilters = setFilter(filters, { - // type: "array", - // id: "setCode", - // value: { - // mode: ":", - // arr: sets, - // not: false, - // }, - // }); - // setFilters(newFilters); - // } - + let newQuery = removeFilterFromQuery(collectionQuery, ["s", "set"]); + if (sets.length > 0) { + newQuery += ` s:${sets.join(",")}`; + } reduxAction(dispatch, { type: "SET_COLLECTION_QUERY", arg: { - query: sets.length > 0 ? `s:${sets.join(",")}` : "", - forceQuery: true, - }, - }); - - const newFilters: Filters = setFilter([], { - type: "array", - id: "setCode", - value: { - mode: ":", - arr: sets, - not: false, + query: newQuery, }, }); - - setFilters(newFilters); }, - [dispatch, filters] + [dispatch, filters, collectionQuery] ); const handleChange = useCallback( (e: React.ChangeEvent): void => { reduxAction(dispatch, { type: "SET_COLLECTION_QUERY", - arg: { query: e.currentTarget.value, forceQuery: false }, + arg: { query: e.currentTarget.value }, }); }, [dispatch] @@ -285,17 +251,12 @@ export default function ViewCollection(props: ViewCollectionProps) { text={viewMode === "set" ? "Cards view" : "Set view"} />
- +
{viewMode === "set" && ( - + )} {viewMode === "cards" && (
diff --git a/src/components/views/collection/advancedSearch.tsx b/src/components/views/collection/advancedSearch.tsx index 8fd8123..e1652a8 100644 --- a/src/components/views/collection/advancedSearch.tsx +++ b/src/components/views/collection/advancedSearch.tsx @@ -247,7 +247,7 @@ export default function AdvancedSearch( history.push(`/collection/${query}`); reduxAction(dispatch, { type: "SET_COLLECTION_QUERY", - arg: { query, forceQuery: true }, + arg: { query }, }); handleClose(); }, [history, handleClose, dispatch, query]); diff --git a/src/components/views/collection/collectionQuery.ts b/src/components/views/collection/collectionQuery.ts index 088577f..84a244c 100644 --- a/src/components/views/collection/collectionQuery.ts +++ b/src/components/views/collection/collectionQuery.ts @@ -37,7 +37,7 @@ const { WHITE, BLUE, RED, BLACK, GREEN, COLORLESS } = constants; * Matches a query string and returns an array to be used in the filters converter * @param filterValue Query string */ -function parseFilterValue(filterValue: string): ParsedToken[] { +export function parseFilterValue(filterValue: string): ParsedToken[] { const reg = /(([^\s"]+)(\b[>=|<=|:|=|!=|>|<]{1,2})([^\s"]+))|(([^\s"]+)(\b[>=|<=|:|=|!=|>|<]{1,2})("[^"]*"))|(([^\s"]+))|(("[^"]*"+))/; const filterPattern = new RegExp(reg, "g"); @@ -481,7 +481,7 @@ export default function getFiltersFromQuery(query: string): Filters { export function removeFilterFromQuery(query: string, keys: string[]): string { const results = parseFilterValue(query); const newQuery: string[] = []; - results.forEach((match: any) => { + results.forEach((match) => { const [tokenKey, separator, tokenVal] = match; const nKey = tokenKey.startsWith("-") ? tokenKey.slice(1) : tokenKey; if (!keys.includes(nKey)) { diff --git a/src/redux/slices/rendererSlice.ts b/src/redux/slices/rendererSlice.ts index 5cc3d62..5cdd06c 100644 --- a/src/redux/slices/rendererSlice.ts +++ b/src/redux/slices/rendererSlice.ts @@ -42,7 +42,6 @@ export const initialRendererState = { topArtist: "Thoughtseize by Aleksi Briclot", updateState: "", collectionQuery: "f:standard r>token", - forceQuery: 0, matchInProgress: false, draftInProgress: false, showPostSignup: null as null | string, @@ -168,12 +167,9 @@ const rendererSlice = createSlice({ }, setCollectionQuery: ( state: RendererState, - action: PayloadAction<{ query: string; forceQuery: boolean }> + action: PayloadAction<{ query: string }> ): void => { state.collectionQuery = action.payload.query; - if (action.payload.forceQuery) { - state.forceQuery = new Date().getTime(); - } }, setMatchInProgress: ( state: RendererState,