Fix catalog search issues

This commit is contained in:
Bill 2022-09-22 00:07:28 -04:00
parent a3212f8a16
commit 71e8d8a3a1
2 changed files with 66 additions and 83 deletions

View File

@ -1,6 +1,6 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { IFurnitureData } from '@nitrots/nitro-renderer'; import { IFurnitureData } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { CatalogPage, CatalogType, FilterCatalogNode, FurnitureOffer, GetOfferNodes, GetSessionDataManager, ICatalogNode, ICatalogPage, IPurchasableOffer, LocalizeText, PageLocalization, SearchResult } from '../../../../../api'; import { CatalogPage, CatalogType, FilterCatalogNode, FurnitureOffer, GetOfferNodes, GetSessionDataManager, ICatalogNode, ICatalogPage, IPurchasableOffer, LocalizeText, PageLocalization, SearchResult } from '../../../../../api';
import { Button, Flex } from '../../../../../common'; import { Button, Flex } from '../../../../../common';
import { useCatalog } from '../../../../../hooks'; import { useCatalog } from '../../../../../hooks';
@ -8,104 +8,87 @@ import { useCatalog } from '../../../../../hooks';
export const CatalogSearchView: FC<{}> = props => export const CatalogSearchView: FC<{}> = props =>
{ {
const [ searchValue, setSearchValue ] = useState(''); const [ searchValue, setSearchValue ] = useState('');
const [ needsProcessing, setNeedsProcessing ] = useState(false);
const { currentType = null, rootNode = null, offersToNodes = null, searchResult = null, setSearchResult = null, setCurrentPage = null } = useCatalog(); const { currentType = null, rootNode = null, offersToNodes = null, searchResult = null, setSearchResult = null, setCurrentPage = null } = useCatalog();
const updateSearchValue = (value: string) =>
{
if(!value || !value.length)
{
setSearchValue('');
if(searchResult) setSearchResult(null);
}
else
{
setSearchValue(value);
setNeedsProcessing(true);
}
}
const processSearch = useCallback((search: string) =>
{
setNeedsProcessing(false);
search = search.toLocaleLowerCase().replace(' ', '');
if(!search || !search.length) return;
const furnitureDatas = GetSessionDataManager().getAllFurnitureData({
loadFurnitureData: null
});
if(!furnitureDatas || !furnitureDatas.length) return;
const foundFurniture: IFurnitureData[] = [];
const foundFurniLines: string[] = [];
for(const furniture of furnitureDatas)
{
if((currentType === CatalogType.BUILDER) && !furniture.availableForBuildersClub) continue;
if((currentType === CatalogType.NORMAL) && furniture.excludeDynamic) continue;
const searchValues = [ furniture.className, furniture.name, furniture.description ].join(' ').replace(/ /gi, '').toLowerCase();
if((currentType === CatalogType.BUILDER) && (furniture.purchaseOfferId === -1) && (furniture.rentOfferId === -1))
{
if((furniture.furniLine !== '') && (foundFurniLines.indexOf(furniture.furniLine) < 0))
{
if(searchValues.indexOf(search) >= 0) foundFurniLines.push(furniture.furniLine);
}
}
else
{
const foundNodes = [
...GetOfferNodes(offersToNodes, furniture.purchaseOfferId),
...GetOfferNodes(offersToNodes, furniture.rentOfferId)
];
if(foundNodes.length)
{
if(searchValues.indexOf(search) >= 0) foundFurniture.push(furniture);
if(foundFurniture.length === 250) break;
}
}
}
const offers: IPurchasableOffer[] = [];
for(const furniture of foundFurniture) offers.push(new FurnitureOffer(furniture));
let nodes: ICatalogNode[] = [];
FilterCatalogNode(search, foundFurniLines, rootNode, nodes);
setCurrentPage((new CatalogPage(-1, 'default_3x3', new PageLocalization([], []), offers, false, 1) as ICatalogPage));
setSearchResult(new SearchResult(search, offers, nodes.filter(node => (node.isVisible))));
}, [ offersToNodes, currentType, rootNode, setCurrentPage, setSearchResult ]);
useEffect(() => useEffect(() =>
{ {
if(!needsProcessing) return; let search = searchValue?.toLocaleLowerCase().replace(' ', '');
const timeout = setTimeout(() => processSearch(searchValue), 300); if(!search || !search.length)
{
setSearchResult(null);
return;
}
const timeout = setTimeout(() =>
{
const furnitureDatas = GetSessionDataManager().getAllFurnitureData({
loadFurnitureData: null
});
if(!furnitureDatas || !furnitureDatas.length) return;
const foundFurniture: IFurnitureData[] = [];
const foundFurniLines: string[] = [];
for(const furniture of furnitureDatas)
{
if((currentType === CatalogType.BUILDER) && !furniture.availableForBuildersClub) continue;
if((currentType === CatalogType.NORMAL) && furniture.excludeDynamic) continue;
const searchValues = [ furniture.className, furniture.name, furniture.description ].join(' ').replace(/ /gi, '').toLowerCase();
if((currentType === CatalogType.BUILDER) && (furniture.purchaseOfferId === -1) && (furniture.rentOfferId === -1))
{
if((furniture.furniLine !== '') && (foundFurniLines.indexOf(furniture.furniLine) < 0))
{
if(searchValues.indexOf(search) >= 0) foundFurniLines.push(furniture.furniLine);
}
}
else
{
const foundNodes = [
...GetOfferNodes(offersToNodes, furniture.purchaseOfferId),
...GetOfferNodes(offersToNodes, furniture.rentOfferId)
];
if(foundNodes.length)
{
if(searchValues.indexOf(search) >= 0) foundFurniture.push(furniture);
if(foundFurniture.length === 250) break;
}
}
}
const offers: IPurchasableOffer[] = [];
for(const furniture of foundFurniture) offers.push(new FurnitureOffer(furniture));
let nodes: ICatalogNode[] = [];
FilterCatalogNode(search, foundFurniLines, rootNode, nodes);
setSearchResult(new SearchResult(search, offers, nodes.filter(node => (node.isVisible))));
setCurrentPage((new CatalogPage(-1, 'default_3x3', new PageLocalization([], []), offers, false, 1) as ICatalogPage));
}, 300);
return () => clearTimeout(timeout); return () => clearTimeout(timeout);
}, [ searchValue, needsProcessing, processSearch ]); }, [ offersToNodes, currentType, rootNode, searchValue, setCurrentPage, setSearchResult ]);
return ( return (
<Flex gap={ 1 }> <Flex gap={ 1 }>
<Flex fullWidth alignItems="center" position="relative"> <Flex fullWidth alignItems="center" position="relative">
<input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('generic.search') } value={ searchValue } onChange={ event => updateSearchValue(event.target.value) } onKeyDown={ event => ((event.code === 'Enter') || (event.code === 'NumpadEnter')) && processSearch(searchValue) } /> <input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('generic.search') } value={ searchValue } onChange={ event => setSearchValue(event.target.value) } />
</Flex> </Flex>
{ (!searchValue || !searchValue.length) && { (!searchValue || !searchValue.length) &&
<Button variant="primary" className="catalog-search-button"> <Button variant="primary" className="catalog-search-button">
<FontAwesomeIcon icon="search" /> <FontAwesomeIcon icon="search" />
</Button> } </Button> }
{ searchValue && !!searchValue.length && { searchValue && !!searchValue.length &&
<Button variant="primary" className="catalog-search-button" onClick={ event => updateSearchValue('') }> <Button variant="primary" className="catalog-search-button" onClick={ event => setSearchValue('') }>
<FontAwesomeIcon icon="times" /> <FontAwesomeIcon icon="times" />
</Button> } </Button> }
</Flex> </Flex>

View File

@ -357,7 +357,7 @@ const useCatalogState = () =>
const openPageById = useCallback((id: number) => const openPageById = useCallback((id: number) =>
{ {
setSearchResult(null); if(id !== -1) setSearchResult(null);
if(!isVisible) if(!isVisible)
{ {