From d5924ebf4b9ef75ab03af45874dfe9f12c095d9a Mon Sep 17 00:00:00 2001 From: en Date: Tue, 4 Feb 2025 10:23:57 +0100 Subject: [PATCH] refactor(search): apply normalization on user, blog and mod search --- src/pages/blogs/index.tsx | 16 +++++++++------- src/pages/search.tsx | 26 +++++++++++++------------- src/utils/utils.ts | 12 ++++++++++++ 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/pages/blogs/index.tsx b/src/pages/blogs/index.tsx index d4b4fab..64815d7 100644 --- a/src/pages/blogs/index.tsx +++ b/src/pages/blogs/index.tsx @@ -9,7 +9,7 @@ import '../../styles/pagination.css' import '../../styles/search.css' import '../../styles/styles.css' import { PaginationWithPageNumbers } from 'components/Pagination' -import { scrollIntoView } from 'utils' +import { normalizeSearchString, scrollIntoView } from 'utils' import { LoadingSpinner } from 'components/LoadingSpinner' import { Filter } from 'components/Filters' import { Dropdown } from 'components/Filters/Dropdown' @@ -63,15 +63,17 @@ export const BlogsPage = () => { } let filtered = blogs?.filter(filterNsfwFn) || [] - const lowerCaseSearchTerm = searchTerm.toLowerCase() + const normalizedSearchTerm = normalizeSearchString(searchTerm) - if (searchTerm !== '') { + if (normalizedSearchTerm !== '') { const filterSearchTermFn = (blog: Partial) => - (blog.title || '').toLowerCase().includes(lowerCaseSearchTerm) || - (blog.summary || '').toLowerCase().includes(lowerCaseSearchTerm) || - (blog.content || '').toLowerCase().includes(lowerCaseSearchTerm) || + normalizeSearchString(blog.title || '').includes( + normalizedSearchTerm + ) || + (blog.summary || '').toLowerCase().includes(normalizedSearchTerm) || + (blog.content || '').toLowerCase().includes(normalizedSearchTerm) || (blog.tTags || []).findIndex((tag) => - tag.toLowerCase().includes(lowerCaseSearchTerm) + tag.toLowerCase().includes(normalizedSearchTerm) ) > -1 filtered = filtered.filter(filterSearchTermFn) } diff --git a/src/pages/search.tsx b/src/pages/search.tsx index 78e44b0..018e2fb 100644 --- a/src/pages/search.tsx +++ b/src/pages/search.tsx @@ -38,6 +38,7 @@ import { isModDataComplete, memoizedNormalizeSearchString, normalizeSearchString, + normalizeUserSearchString, scrollIntoView } from 'utils' import { useCuratedSet } from 'hooks/useCuratedSet' @@ -295,18 +296,17 @@ const ModsResult = ({ }, [searchTerm]) const filteredMods = useMemo(() => { + const normalizedSearchTerm = normalizeSearchString(searchTerm) // Search page requires search term - if (searchTerm === '') return [] - - const lowerCaseSearchTerm = searchTerm.toLowerCase() + if (normalizedSearchTerm === '') return [] const filterFn = (mod: ModDetails) => - mod.title.toLowerCase().includes(lowerCaseSearchTerm) || - mod.game.toLowerCase().includes(lowerCaseSearchTerm) || - mod.summary.toLowerCase().includes(lowerCaseSearchTerm) || - mod.body.toLowerCase().includes(lowerCaseSearchTerm) || + normalizeSearchString(mod.title).includes(normalizedSearchTerm) || + memoizedNormalizeSearchString(mod.game).includes(normalizedSearchTerm) || + mod.summary.toLowerCase().includes(normalizedSearchTerm) || + mod.body.toLowerCase().includes(normalizedSearchTerm) || mod.tags.findIndex((tag) => - tag.toLowerCase().includes(lowerCaseSearchTerm) + tag.toLowerCase().includes(normalizedSearchTerm) ) > -1 const filterSourceFn = (mod: ModDetails) => { @@ -379,13 +379,14 @@ const UsersResult = ({ const userState = useAppSelector((state) => state.user) useEffect(() => { - if (searchTerm === '') { + const normalizedSearchTerm = normalizeUserSearchString(searchTerm) + if (normalizedSearchTerm === '') { setProfiles([]) } else { const sub = ndk.subscribe( { kinds: [NDKKind.Metadata], - search: searchTerm + search: normalizedSearchTerm }, { closeOnEose: true, @@ -397,7 +398,7 @@ const UsersResult = ({ // Stop the sub after 10 seconds if we are still searching the same term as before window.setTimeout(() => { - if (sub.filter.search === searchTerm) { + if (sub.filter.search === normalizedSearchTerm) { sub.stop() } }, 10000) @@ -502,9 +503,8 @@ const GamesResult = ({ searchTerm }: GamesResultProps) => { }, [searchTerm]) const filteredGames = useMemo(() => { - if (searchTerm === '') return [] - const normalizedSearchTerm = normalizeSearchString(searchTerm) + if (normalizedSearchTerm === '') return [] return games.filter((game) => memoizedNormalizeSearchString(game['Game Name']).includes( diff --git a/src/utils/utils.ts b/src/utils/utils.ts index ed2a3e1..5f75773 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -238,6 +238,7 @@ const romanRegex = new RegExp( ) export const normalizeSearchString = (str: string): string => { + str = str.trim() str = str.toLowerCase() str = str.replace(romanRegex, (match) => ROMAN_TO_ARABIC_MAP[match]) str = removeAccents(str) @@ -258,6 +259,17 @@ const memoizeNormalize = (func: (str: string) => string) => { } } +/** + * Memoize normalized search strings + * Should only be used for games (large list) + */ export const memoizedNormalizeSearchString = memoizeNormalize( normalizeSearchString ) + +export const normalizeUserSearchString = (str: string): string => { + str = str.trim() + str = str.toLowerCase() + str = removeAccents(str) + return str +}