From efad0f44f5e440f4741872fbfbbfcac9c81f39f0 Mon Sep 17 00:00:00 2001 From: enes Date: Tue, 29 Oct 2024 13:38:13 +0100 Subject: [PATCH] refactor: use filter storage state, separate profile page filter --- src/components/ModsFilter.tsx | 18 ++-- src/hooks/useFilteredMods.ts | 7 +- src/pages/game.tsx | 29 +++--- src/pages/mods.tsx | 27 ++--- src/pages/profile.tsx | 28 ++--- src/pages/search.tsx | 186 +++++++++++++++------------------- src/types/modsFilter.ts | 1 - 7 files changed, 126 insertions(+), 170 deletions(-) diff --git a/src/components/ModsFilter.tsx b/src/components/ModsFilter.tsx index 755ff95..292f3a6 100644 --- a/src/components/ModsFilter.tsx +++ b/src/components/ModsFilter.tsx @@ -1,16 +1,20 @@ -import { useAppSelector } from 'hooks' +import { useAppSelector, useLocalStorage } from 'hooks' import React from 'react' -import { Dispatch, SetStateAction } from 'react' import { FilterOptions, ModeratedFilter, NSFWFilter, SortBy } from 'types' +import { DEFAULT_FILTER_OPTIONS } from 'utils' type Props = { - filterOptions: FilterOptions - setFilterOptions: Dispatch> + author?: string | undefined + filterKey?: string | undefined } export const ModFilter = React.memo( - ({ filterOptions, setFilterOptions }: Props) => { + ({ author, filterKey = 'filter' }: Props) => { const userState = useAppSelector((state) => state.user) + const [filterOptions, setFilterOptions] = useLocalStorage( + filterKey, + DEFAULT_FILTER_OPTIONS + ) return (
@@ -62,9 +66,9 @@ export const ModFilter = React.memo( import.meta.env.VITE_REPORTING_NPUB const isOwnProfile = - filterOptions.author && + author && userState.auth && - userState.user?.pubkey === filterOptions.author + userState.user?.pubkey === author if (!(isAdmin || isOwnProfile)) return null } diff --git a/src/hooks/useFilteredMods.ts b/src/hooks/useFilteredMods.ts index 7514be7..7f1da40 100644 --- a/src/hooks/useFilteredMods.ts +++ b/src/hooks/useFilteredMods.ts @@ -18,7 +18,8 @@ export const useFilteredMods = ( muteLists: { admin: MuteLists user: MuteLists - } + }, + author?: string | undefined ) => { return useMemo(() => { const nsfwFilter = (mods: ModDetails[]) => { @@ -50,7 +51,7 @@ export const useFilteredMods = ( const isAdmin = userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB const isOwner = userState.user?.npub && - npubToHex(userState.user.npub as string) === filterOptions.author + npubToHex(userState.user.npub as string) === author const isUnmoderatedFully = filterOptions.moderated === ModeratedFilter.Unmoderated_Fully @@ -84,7 +85,7 @@ export const useFilteredMods = ( filterOptions.sort, filterOptions.moderated, filterOptions.nsfw, - filterOptions.author, + author, mods, muteLists, nsfwList diff --git a/src/pages/game.tsx b/src/pages/game.tsx index 62c65ba..6f82493 100644 --- a/src/pages/game.tsx +++ b/src/pages/game.tsx @@ -11,20 +11,20 @@ import { MAX_MODS_PER_PAGE, T_TAG_VALUE } from 'constants.ts' import { useAppSelector, useFilteredMods, + useLocalStorage, useMuteLists, useNDKContext, useNSFWList } from 'hooks' import { useEffect, useMemo, useRef, useState } from 'react' import { useParams, useSearchParams } from 'react-router-dom' +import { FilterOptions, ModDetails } from 'types' import { - FilterOptions, - ModDetails, - ModeratedFilter, - NSFWFilter, - SortBy -} from 'types' -import { extractModData, isModDataComplete, scrollIntoView } from 'utils' + DEFAULT_FILTER_OPTIONS, + extractModData, + isModDataComplete, + scrollIntoView +} from 'utils' export const GamePage = () => { const scrollTargetRef = useRef(null) @@ -34,12 +34,10 @@ export const GamePage = () => { const muteLists = useMuteLists() const nsfwList = useNSFWList() - const [filterOptions, setFilterOptions] = useState({ - sort: SortBy.Latest, - nsfw: NSFWFilter.Hide_NSFW, - source: window.location.host, - moderated: ModeratedFilter.Moderated - }) + const [filterOptions] = useLocalStorage( + 'filter', + DEFAULT_FILTER_OPTIONS + ) const [mods, setMods] = useState([]) const [currentPage, setCurrentPage] = useState(1) @@ -186,10 +184,7 @@ export const GamePage = () => { />
- +
{currentMods.map((mod) => ( diff --git a/src/pages/mods.tsx b/src/pages/mods.tsx index a5115f7..31dd301 100644 --- a/src/pages/mods.tsx +++ b/src/pages/mods.tsx @@ -8,6 +8,7 @@ import { MOD_FILTER_LIMIT } from '../constants' import { useAppSelector, useFilteredMods, + useLocalStorage, useMuteLists, useNDKContext, useNSFWList @@ -17,14 +18,8 @@ import '../styles/filters.css' import '../styles/pagination.css' import '../styles/search.css' import '../styles/styles.css' -import { - FilterOptions, - ModDetails, - ModeratedFilter, - NSFWFilter, - SortBy -} from '../types' -import { scrollIntoView } from 'utils' +import { FilterOptions, ModDetails } from '../types' +import { DEFAULT_FILTER_OPTIONS, scrollIntoView } from 'utils' import { SearchInput } from 'components/SearchInput' export const ModsPage = () => { @@ -32,12 +27,11 @@ export const ModsPage = () => { const { fetchMods } = useNDKContext() const [isFetching, setIsFetching] = useState(false) const [mods, setMods] = useState([]) - const [filterOptions, setFilterOptions] = useState({ - sort: SortBy.Latest, - nsfw: NSFWFilter.Hide_NSFW, - source: window.location.host, - moderated: ModeratedFilter.Moderated - }) + + const [filterOptions] = useLocalStorage( + 'filter', + DEFAULT_FILTER_OPTIONS + ) const muteLists = useMuteLists() const nsfwList = useNSFWList() @@ -113,10 +107,7 @@ export const ModsPage = () => { ref={scrollTargetRef} > - +
diff --git a/src/pages/profile.tsx b/src/pages/profile.tsx index b69f597..0a1965b 100644 --- a/src/pages/profile.tsx +++ b/src/pages/profile.tsx @@ -9,6 +9,7 @@ import { MOD_FILTER_LIMIT } from '../constants' import { useAppSelector, useFilteredMods, + useLocalStorage, useMuteLists, useNDKContext, useNSFWList @@ -18,16 +19,10 @@ import { useCallback, useEffect, useRef, useState } from 'react' import { useParams, Navigate, Link } from 'react-router-dom' import { toast } from 'react-toastify' import { appRoutes, getProfilePageRoute } from 'routes' -import { - FilterOptions, - ModDetails, - ModeratedFilter, - NSFWFilter, - SortBy, - UserRelaysType -} from 'types' +import { FilterOptions, ModDetails, UserRelaysType } from 'types' import { copyTextToClipboard, + DEFAULT_FILTER_OPTIONS, now, npubToHex, scrollIntoView, @@ -230,12 +225,9 @@ export const ProfilePage = () => { // Mods const [mods, setMods] = useState([]) - const [filterOptions, setFilterOptions] = useState({ - sort: SortBy.Latest, - nsfw: NSFWFilter.Hide_NSFW, - source: window.location.host, - moderated: ModeratedFilter.Moderated, - author: profilePubkey + const filterKey = 'filter-profile' + const [filterOptions] = useLocalStorage(filterKey, { + ...DEFAULT_FILTER_OPTIONS }) const muteLists = useMuteLists() const nsfwList = useNSFWList() @@ -304,7 +296,8 @@ export const ProfilePage = () => { userState, filterOptions, nsfwList, - muteLists + muteLists, + profilePubkey ) // Redirect route @@ -470,10 +463,7 @@ export const ProfilePage = () => { {/* Tabs Content */} {tab === 0 && ( <> - +
{filteredModList.map((mod) => ( diff --git a/src/pages/search.tsx b/src/pages/search.tsx index 47022d2..935b8e3 100644 --- a/src/pages/search.tsx +++ b/src/pages/search.tsx @@ -23,28 +23,16 @@ import { useAppSelector, useFilteredMods, useGames, + useLocalStorage, useMuteLists, useNDKContext, useNSFWList } from 'hooks' -import React, { - Dispatch, - SetStateAction, - useEffect, - useMemo, - useRef, - useState -} from 'react' +import React, { useEffect, useMemo, useRef, useState } from 'react' import { useSearchParams } from 'react-router-dom' +import { FilterOptions, ModDetails, ModeratedFilter, MuteLists } from 'types' import { - FilterOptions, - ModDetails, - ModeratedFilter, - MuteLists, - NSFWFilter, - SortBy -} from 'types' -import { + DEFAULT_FILTER_OPTIONS, extractModData, isModDataComplete, log, @@ -69,12 +57,10 @@ export const SearchPage = () => { const searchKind = (searchParams.get('kind') as SearchKindEnum) || SearchKindEnum.Mods - const [filterOptions, setFilterOptions] = useState({ - sort: SortBy.Latest, - nsfw: NSFWFilter.Hide_NSFW, - source: window.location.host, - moderated: ModeratedFilter.Moderated - }) + const [filterOptions] = useLocalStorage( + 'filter', + DEFAULT_FILTER_OPTIONS + ) const [searchTerm, setSearchTerm] = useState(searchParams.get('q') || '') @@ -124,10 +110,7 @@ export const SearchPage = () => { />
- + {searchKind === SearchKindEnum.Mods && ( { ) } -type FiltersProps = { - filterOptions: FilterOptions - setFilterOptions: Dispatch> -} +const Filters = React.memo(() => { + const [filterOptions, setFilterOptions] = useLocalStorage( + 'filter', + DEFAULT_FILTER_OPTIONS + ) -const Filters = React.memo( - ({ filterOptions, setFilterOptions }: FiltersProps) => { - const userState = useAppSelector((state) => state.user) - const [searchParams, setSearchParams] = useSearchParams() - const searchKind = - (searchParams.get('kind') as SearchKindEnum) || SearchKindEnum.Mods - const handleChangeSearchKind = (kind: SearchKindEnum) => { - searchParams.set('kind', kind) - setSearchParams(searchParams, { - replace: true - }) - } + const userState = useAppSelector((state) => state.user) + const [searchParams, setSearchParams] = useSearchParams() + const searchKind = + (searchParams.get('kind') as SearchKindEnum) || SearchKindEnum.Mods + const handleChangeSearchKind = (kind: SearchKindEnum) => { + searchParams.set('kind', kind) + setSearchParams(searchParams, { + replace: true + }) + } - return ( -
-
- {searchKind === SearchKindEnum.Mods && ( - - )} - - {searchKind === SearchKindEnum.Users && ( -
-
- -
- {Object.values(ModeratedFilter).map((item, index) => { - if (item === ModeratedFilter.Unmoderated_Fully) { - const isAdmin = - userState.user?.npub === - import.meta.env.VITE_REPORTING_NPUB - - if (!isAdmin) return null - } - - return ( -
- setFilterOptions((prev) => ({ - ...prev, - moderated: item - })) - } - > - {item} -
- ) - })} -
-
-
- )} + return ( +
+
+ {searchKind === SearchKindEnum.Mods && } + {searchKind === SearchKindEnum.Users && (
- {Object.values(SearchKindEnum).map((item, index) => ( -
handleChangeSearchKind(item)} - > - {item} -
- ))} + {Object.values(ModeratedFilter).map((item, index) => { + if (item === ModeratedFilter.Unmoderated_Fully) { + const isAdmin = + userState.user?.npub === + import.meta.env.VITE_REPORTING_NPUB + + if (!isAdmin) return null + } + + return ( +
+ setFilterOptions((prev) => ({ + ...prev, + moderated: item + })) + } + > + {item} +
+ ) + })}
+ )} + +
+
+ +
+ {Object.values(SearchKindEnum).map((item, index) => ( +
handleChangeSearchKind(item)} + > + {item} +
+ ))} +
+
- ) - } -) +
+ ) +}) type ModsResultProps = { filterOptions: FilterOptions diff --git a/src/types/modsFilter.ts b/src/types/modsFilter.ts index a10542d..8d724ec 100644 --- a/src/types/modsFilter.ts +++ b/src/types/modsFilter.ts @@ -22,5 +22,4 @@ export interface FilterOptions { nsfw: NSFWFilter source: string moderated: ModeratedFilter - author?: string }