From 127c1fd8a63c3a38a9ecd1589fe8abcc91cbed38 Mon Sep 17 00:00:00 2001 From: enes Date: Thu, 5 Dec 2024 21:03:00 +0100 Subject: [PATCH] fix(category): use hierarchy links, visual indicator for link --- .../Filters/CategoryFilterPopup.tsx | 42 ++++--- src/components/ModForm.tsx | 26 ++-- src/pages/game.tsx | 115 ++++++++++++------ src/pages/mod/index.tsx | 34 +++--- 4 files changed, 134 insertions(+), 83 deletions(-) diff --git a/src/components/Filters/CategoryFilterPopup.tsx b/src/components/Filters/CategoryFilterPopup.tsx index 06f287e..8e6fcc8 100644 --- a/src/components/Filters/CategoryFilterPopup.tsx +++ b/src/components/Filters/CategoryFilterPopup.tsx @@ -9,44 +9,48 @@ import styles from './CategoryFilterPopup.module.scss' interface CategoryFilterPopupProps { categories: string[] setCategories: React.Dispatch> - heirarchies: string[] - setHeirarchies: React.Dispatch> + hierarchies: string[] + setHierarchies: React.Dispatch> handleClose: () => void - handleApply: () => void } export const CategoryFilterPopup = ({ categories, setCategories, - heirarchies, - setHeirarchies, - handleClose, - handleApply + hierarchies, + setHierarchies, + handleClose }: CategoryFilterPopupProps) => { + const [filterCategories, setFilterCategories] = useState(categories) + const [filterHierarchies, setFilterHierarchies] = useState(hierarchies) + const handleApply = () => { + setCategories(filterCategories) + setHierarchies(filterHierarchies) + } const [inputValue, setInputValue] = useState('') const handleInputChange = (e: React.ChangeEvent) => { setInputValue(e.target.value) } const handleSingleSelection = (category: string, isSelected: boolean) => { - let updatedCategories = [...categories] + let updatedCategories = [...filterCategories] if (isSelected) { updatedCategories.push(category) } else { updatedCategories = updatedCategories.filter((item) => item !== category) } - setCategories(updatedCategories) + setFilterCategories(updatedCategories) } const handleCombinationSelection = (path: string[], isSelected: boolean) => { const pathString = path.join(':') - let updatedHeirarchies = [...heirarchies] + let updatedHierarchies = [...filterHierarchies] if (isSelected) { - updatedHeirarchies.push(pathString) + updatedHierarchies.push(pathString) } else { - updatedHeirarchies = updatedHeirarchies.filter( + updatedHierarchies = updatedHierarchies.filter( (item) => item !== pathString ) } - setHeirarchies(updatedHeirarchies) + setFilterHierarchies(updatedHierarchies) } const handleAddNew = () => { if (inputValue) { @@ -55,9 +59,9 @@ export const CategoryFilterPopup = ({ .split('>') .map((s) => s.trim()) if (values.length > 1) { - setHeirarchies([...categories, values.join(':')]) + setFilterHierarchies([...filterHierarchies, values.join(':')]) } else { - setCategories([...categories, values[0]]) + setFilterCategories([...filterCategories, values[0]]) } setInputValue('') } @@ -157,8 +161,8 @@ export const CategoryFilterPopup = ({ path={[category.name]} handleSingleSelection={handleSingleSelection} handleCombinationSelection={handleCombinationSelection} - selectedSingles={categories} - selectedCombinations={heirarchies} + selectedSingles={filterCategories} + selectedCombinations={filterHierarchies} /> ))} @@ -181,8 +185,8 @@ export const CategoryFilterPopup = ({ className='btn btnMain btnMainPopup' type='button' onPointerDown={() => { - setCategories([]) - setHeirarchies([]) + setFilterCategories([]) + setFilterHierarchies([]) }} > Reset diff --git a/src/components/ModForm.tsx b/src/components/ModForm.tsx index 9711ac4..56ec6b1 100644 --- a/src/components/ModForm.tsx +++ b/src/components/ModForm.tsx @@ -235,7 +235,7 @@ export const ModForm = ({ existingModData }: ModFormProps) => { } // Prepend com.degmods to avoid leaking categories to 3rd party client's search - // Add heirarchical namespaces labels + // Add hierarchical namespaces labels if (formState.LTags.length > 0) { for (let i = 0; i < formState.LTags.length; i++) { tags.push(['L', `com.degmods:${formState.LTags[i]}`]) @@ -946,12 +946,12 @@ export const CategoryAutocomplete = ({ const concatenatedValue = Array.from(uniqueValues) return concatenatedValue } - const getSelectedHeirarchy = (cats: Categories[]) => { - const heirarchies = cats.reduce( + const getSelectedhierarchy = (cats: Categories[]) => { + const hierarchies = cats.reduce( (prev, cat) => [...prev, cat.hierarchy.replace(/ > /g, ':')], [] ) - const concatenatedValue = Array.from(heirarchies) + const concatenatedValue = Array.from(hierarchies) return concatenatedValue } const handleReset = () => { @@ -989,7 +989,7 @@ export const CategoryAutocomplete = ({ setFormState((prevState) => ({ ...prevState, ['lTags']: getSelectedCategories(selectedCategories), - ['LTags']: getSelectedHeirarchy(selectedCategories) + ['LTags']: getSelectedhierarchy(selectedCategories) })) }, [selectedCategories, setFormState]) @@ -1134,16 +1134,20 @@ export const CategoryAutocomplete = ({ {LTags.length > 0 && (
{LTags.map((hierarchy) => { - const heirarchicalCategories = hierarchy.split(`:`) - const categories = heirarchicalCategories - .map((c, i) => - game ? ( + const hierarchicalCategories = hierarchy.split(`:`) + const categories = hierarchicalCategories + .map((c, i) => { + const partialHierarchy = hierarchicalCategories + .slice(0, i + 1) + .join(':') + + return game ? ( @@ -1154,7 +1158,7 @@ export const CategoryAutocomplete = ({ {capitalizeEachWord(c)}

) - ) + }) .reduce((prev, curr, i) => [ prev,
{ const [searchTerm, setSearchTerm] = useState(searchParams.get('q') || '') // Categories filter - const [categories, setCategories] = useState(searchParams.getAll('l') || []) - const [heirarchies, setHeirarchies] = useState(searchParams.getAll('h') || []) + const [categories, setCategories] = useSessionStorage('l', []) + const [hierarchies, setHierarchies] = useSessionStorage('h', []) const [showCategoryPopup, setShowCategoryPopup] = useState(false) + const linkedHierarchy = searchParams.get('h') + const isCategoryFilterActive = categories.length + hierarchies.length > 0 const handleSearch = () => { const value = searchTermRef.current?.value || '' // Access the input value from the ref @@ -134,12 +137,17 @@ export const GamePage = () => { '#t': [T_TAG_VALUE] } - if (categories.length) { - filter['#l'] = categories.map((l) => `com.degmods:${l}`) - } + // Linked category will override the filter + if (linkedHierarchy && linkedHierarchy !== '') { + filter['#L'] = [`com.degmods:${linkedHierarchy}`] + } else { + if (categories.length) { + filter['#l'] = categories.map((l) => `com.degmods:${l}`) + } - if (heirarchies.length) { - filter['#L'] = heirarchies.map((L) => `com.degmods:${L}`) + if (hierarchies.length) { + filter['#L'] = hierarchies.map((L) => `com.degmods:${L}`) + } } const subscription = ndk.subscribe(filter, { @@ -165,7 +173,7 @@ export const GamePage = () => { return () => { subscription.stop() } - }, [gameName, ndk, categories, heirarchies]) + }, [gameName, ndk, linkedHierarchy, categories, hierarchies]) if (!gameName) return null @@ -203,26 +211,73 @@ export const GamePage = () => {
-
- -
+ {linkedHierarchy.replace(/:/g, ' > ')} + + + + + ) : ( +
+ +
+ )}
@@ -244,29 +299,11 @@ export const GamePage = () => { { setShowCategoryPopup(false) }} - handleApply={() => { - searchParams.delete('l') - searchParams.delete('h') - categories.forEach((l) => { - if (l) { - searchParams.delete('h') - searchParams.append('l', l) - } - }) - heirarchies.forEach((h) => { - if (h) { - searchParams.append('h', h) - } - }) - setSearchParams(searchParams, { - replace: true - }) - }} /> )} diff --git a/src/pages/mod/index.tsx b/src/pages/mod/index.tsx index 587beb2..dc94295 100644 --- a/src/pages/mod/index.tsx +++ b/src/pages/mod/index.tsx @@ -543,20 +543,26 @@ const Body = ({ {LTags.length > 0 && (
{LTags.map((hierarchy) => { - const heirarchicalCategories = hierarchy.split(`:`) - const categories = heirarchicalCategories - .map((c: string) => ( - -

{capitalizeEachWord(c)}

-
- )) + const hierarchicalCategories = hierarchy.split(`:`) + const categories = hierarchicalCategories + .map((c, i) => { + const partialHierarchy = hierarchicalCategories + .slice(0, i + 1) + .join(':') + + return ( + +

{capitalizeEachWord(c)}

+
+ ) + }) .reduce((prev, curr) => [ prev,