diff --git a/src/assets/categories/categories.json b/src/assets/categories/categories.json index 2948280..eaa4079 100644 --- a/src/assets/categories/categories.json +++ b/src/assets/categories/categories.json @@ -3,7 +3,10 @@ "name": "audio", "sub": [ { "name": "music", "sub": ["background", "ambient"] }, - { "name": "sound effects", "sub": ["footsteps", "weapons"] }, + { + "name": "sound effects", + "sub": ["footsteps", "weapons"] + }, "voice" ] }, diff --git a/src/components/Filters/CategoryFilterPopup.tsx b/src/components/Filters/CategoryFilterPopup.tsx index 8e6fcc8..252f73d 100644 --- a/src/components/Filters/CategoryFilterPopup.tsx +++ b/src/components/Filters/CategoryFilterPopup.tsx @@ -1,10 +1,14 @@ import React, { useEffect, useState } from 'react' import { createPortal } from 'react-dom' import { Category } from 'types' -import categoriesData from './../../assets/categories/categories.json' -import { capitalizeEachWord } from 'utils' - +import { + addToUserCategories, + capitalizeEachWord, + deleteFromUserCategories +} from 'utils' +import { useLocalStorage } from 'hooks' import styles from './CategoryFilterPopup.module.scss' +import categoriesData from './../../assets/categories/categories.json' interface CategoryFilterPopupProps { categories: string[] @@ -21,6 +25,9 @@ export const CategoryFilterPopup = ({ setHierarchies, handleClose }: CategoryFilterPopupProps) => { + const [userHierarchies, setUserHierarchies] = useLocalStorage< + (string | Category)[] + >('user-hierarchies', []) const [filterCategories, setFilterCategories] = useState(categories) const [filterHierarchies, setFilterHierarchies] = useState(hierarchies) const handleApply = () => { @@ -54,15 +61,28 @@ export const CategoryFilterPopup = ({ } const handleAddNew = () => { if (inputValue) { - const values = inputValue + const value = inputValue.toLowerCase() + const values = value .trim() .split('>') .map((s) => s.trim()) - if (values.length > 1) { - setFilterHierarchies([...filterHierarchies, values.join(':')]) - } else { - setFilterCategories([...filterCategories, values[0]]) - } + + setUserHierarchies((prev) => { + addToUserCategories(prev, value) + return [...prev] + }) + + const path = values.join(':') + + // Add new hierarchy to current selection and active selection + setFilterHierarchies((prev) => { + prev.push(path) + return [...prev] + }) + setHierarchies((prev) => { + prev.push(path) + return [...prev] + }) setInputValue('') } } @@ -104,23 +124,67 @@ export const CategoryFilterPopup = ({ - {true && ( -
-
+ )}
- Search for "{inputValue}" category -
- {(categoriesData as Category[]).map((category) => ( + {(categoriesData as Category[]).map((category, i) => ( void } const CategoryCheckbox: React.FC = ({ @@ -231,7 +300,8 @@ const CategoryCheckbox: React.FC = ({ handleCombinationSelection, selectedSingles, selectedCombinations, - indentLevel = 0 + indentLevel = 0, + handleRemove }) => { const name = typeof category === 'string' ? category : category.name const isMatching = path @@ -330,6 +400,24 @@ const CategoryCheckbox: React.FC = ({ checked={isSingleChecked} onChange={handleSingleChange} /> + {typeof handleRemove === 'function' && ( + + )} )} @@ -350,6 +438,11 @@ const CategoryCheckbox: React.FC = ({ selectedSingles={selectedSingles} selectedCombinations={selectedCombinations} indentLevel={indentLevel + 1} + {...(typeof handleRemove === 'function' + ? { + handleRemove + } + : {})} /> ) } else { @@ -364,6 +457,11 @@ const CategoryCheckbox: React.FC = ({ selectedSingles={selectedSingles} selectedCombinations={selectedCombinations} indentLevel={indentLevel + 1} + {...(typeof handleRemove === 'function' + ? { + handleRemove + } + : {})} /> ) } diff --git a/src/components/ModForm.tsx b/src/components/ModForm.tsx index 56ec6b1..efcf475 100644 --- a/src/components/ModForm.tsx +++ b/src/components/ModForm.tsx @@ -1,7 +1,6 @@ import _ from 'lodash' import { Event, kinds, nip19, UnsignedEvent } from 'nostr-tools' import React, { - CSSProperties, Fragment, useCallback, useEffect, @@ -11,7 +10,7 @@ import React, { } from 'react' import { Link, useLocation, useNavigate } from 'react-router-dom' import { toast } from 'react-toastify' -import { VariableSizeList, FixedSizeList } from 'react-window' +import { FixedSizeList } from 'react-window' import { v4 as uuidv4 } from 'uuid' import { T_TAG_VALUE } from '../constants' import { useAppSelector, useGames, useNDKContext } from '../hooks' @@ -73,9 +72,10 @@ export const ModForm = ({ existingModData }: ModFormProps) => { useEffect(() => { if (location.pathname === appRoutes.submitMod) { + // Only trigger when the pathname changes to submit-mod setFormState(initializeFormState()) } - }, [location.pathname]) // Only trigger when the pathname changes to submit-mod + }, [location.pathname]) useEffect(() => { if (existingModData) { @@ -974,7 +974,7 @@ export const CategoryAutocomplete = ({ } const handleAddNew = () => { if (inputValue) { - const value = inputValue.trim() + const value = inputValue.trim().toLowerCase() const newOption: Categories = { name: value, hierarchy: value, @@ -993,44 +993,11 @@ export const CategoryAutocomplete = ({ })) }, [selectedCategories, setFormState]) - const listRef = useRef(null) - const rowHeights = useRef<{ [index: number]: number }>({}) - const setRowHeight = (index: number, size: number) => { - rowHeights.current = { ...rowHeights.current, [index]: size } - if (listRef.current) { - listRef.current.resetAfterIndex(index) - } - } - const getRowHeight = (index: number) => { - return (rowHeights.current[index] || 35) + 8 - } - - const Row = ({ index, style }: { index: number; style: CSSProperties }) => { - const rowRef = useRef(null) - - useEffect(() => { - const rowElement = rowRef.current - if (!rowElement) return - const updateHeight = () => { - const height = Math.max(rowElement.scrollHeight, 35) - setRowHeight(index, height) - } - const observer = new ResizeObserver(() => { - updateHeight() - }) - observer.observe(rowElement) - updateHeight() - return () => { - observer.disconnect() - } - }, [index]) - + const Row = ({ index }: { index: number }) => { if (!filteredOptions) return null return (
handleSelect(filteredOptions[index])} > @@ -1039,6 +1006,7 @@ export const CategoryAutocomplete = ({ (cat) => cat.hierarchy === filteredOptions[index].hierarchy ) && ( -
+
{filteredOptions && filteredOptions.length > 0 ? ( - - {Row} - + filteredOptions.map((c, i) => ) ) : (
Add "{inputValue}" -