refactor: use filter storage state, separate profile page filter
This commit is contained in:
parent
6e07f4b8be
commit
efad0f44f5
@ -1,16 +1,20 @@
|
|||||||
import { useAppSelector } from 'hooks'
|
import { useAppSelector, useLocalStorage } from 'hooks'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Dispatch, SetStateAction } from 'react'
|
|
||||||
import { FilterOptions, ModeratedFilter, NSFWFilter, SortBy } from 'types'
|
import { FilterOptions, ModeratedFilter, NSFWFilter, SortBy } from 'types'
|
||||||
|
import { DEFAULT_FILTER_OPTIONS } from 'utils'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
filterOptions: FilterOptions
|
author?: string | undefined
|
||||||
setFilterOptions: Dispatch<SetStateAction<FilterOptions>>
|
filterKey?: string | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ModFilter = React.memo(
|
export const ModFilter = React.memo(
|
||||||
({ filterOptions, setFilterOptions }: Props) => {
|
({ author, filterKey = 'filter' }: Props) => {
|
||||||
const userState = useAppSelector((state) => state.user)
|
const userState = useAppSelector((state) => state.user)
|
||||||
|
const [filterOptions, setFilterOptions] = useLocalStorage<FilterOptions>(
|
||||||
|
filterKey,
|
||||||
|
DEFAULT_FILTER_OPTIONS
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='IBMSecMain'>
|
<div className='IBMSecMain'>
|
||||||
@ -62,9 +66,9 @@ export const ModFilter = React.memo(
|
|||||||
import.meta.env.VITE_REPORTING_NPUB
|
import.meta.env.VITE_REPORTING_NPUB
|
||||||
|
|
||||||
const isOwnProfile =
|
const isOwnProfile =
|
||||||
filterOptions.author &&
|
author &&
|
||||||
userState.auth &&
|
userState.auth &&
|
||||||
userState.user?.pubkey === filterOptions.author
|
userState.user?.pubkey === author
|
||||||
|
|
||||||
if (!(isAdmin || isOwnProfile)) return null
|
if (!(isAdmin || isOwnProfile)) return null
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,8 @@ export const useFilteredMods = (
|
|||||||
muteLists: {
|
muteLists: {
|
||||||
admin: MuteLists
|
admin: MuteLists
|
||||||
user: MuteLists
|
user: MuteLists
|
||||||
}
|
},
|
||||||
|
author?: string | undefined
|
||||||
) => {
|
) => {
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
const nsfwFilter = (mods: ModDetails[]) => {
|
const nsfwFilter = (mods: ModDetails[]) => {
|
||||||
@ -50,7 +51,7 @@ export const useFilteredMods = (
|
|||||||
const isAdmin = userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB
|
const isAdmin = userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB
|
||||||
const isOwner =
|
const isOwner =
|
||||||
userState.user?.npub &&
|
userState.user?.npub &&
|
||||||
npubToHex(userState.user.npub as string) === filterOptions.author
|
npubToHex(userState.user.npub as string) === author
|
||||||
const isUnmoderatedFully =
|
const isUnmoderatedFully =
|
||||||
filterOptions.moderated === ModeratedFilter.Unmoderated_Fully
|
filterOptions.moderated === ModeratedFilter.Unmoderated_Fully
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ export const useFilteredMods = (
|
|||||||
filterOptions.sort,
|
filterOptions.sort,
|
||||||
filterOptions.moderated,
|
filterOptions.moderated,
|
||||||
filterOptions.nsfw,
|
filterOptions.nsfw,
|
||||||
filterOptions.author,
|
author,
|
||||||
mods,
|
mods,
|
||||||
muteLists,
|
muteLists,
|
||||||
nsfwList
|
nsfwList
|
||||||
|
@ -11,20 +11,20 @@ import { MAX_MODS_PER_PAGE, T_TAG_VALUE } from 'constants.ts'
|
|||||||
import {
|
import {
|
||||||
useAppSelector,
|
useAppSelector,
|
||||||
useFilteredMods,
|
useFilteredMods,
|
||||||
|
useLocalStorage,
|
||||||
useMuteLists,
|
useMuteLists,
|
||||||
useNDKContext,
|
useNDKContext,
|
||||||
useNSFWList
|
useNSFWList
|
||||||
} from 'hooks'
|
} from 'hooks'
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { useParams, useSearchParams } from 'react-router-dom'
|
import { useParams, useSearchParams } from 'react-router-dom'
|
||||||
|
import { FilterOptions, ModDetails } from 'types'
|
||||||
import {
|
import {
|
||||||
FilterOptions,
|
DEFAULT_FILTER_OPTIONS,
|
||||||
ModDetails,
|
extractModData,
|
||||||
ModeratedFilter,
|
isModDataComplete,
|
||||||
NSFWFilter,
|
scrollIntoView
|
||||||
SortBy
|
} from 'utils'
|
||||||
} from 'types'
|
|
||||||
import { extractModData, isModDataComplete, scrollIntoView } from 'utils'
|
|
||||||
|
|
||||||
export const GamePage = () => {
|
export const GamePage = () => {
|
||||||
const scrollTargetRef = useRef<HTMLDivElement>(null)
|
const scrollTargetRef = useRef<HTMLDivElement>(null)
|
||||||
@ -34,12 +34,10 @@ export const GamePage = () => {
|
|||||||
const muteLists = useMuteLists()
|
const muteLists = useMuteLists()
|
||||||
const nsfwList = useNSFWList()
|
const nsfwList = useNSFWList()
|
||||||
|
|
||||||
const [filterOptions, setFilterOptions] = useState<FilterOptions>({
|
const [filterOptions] = useLocalStorage<FilterOptions>(
|
||||||
sort: SortBy.Latest,
|
'filter',
|
||||||
nsfw: NSFWFilter.Hide_NSFW,
|
DEFAULT_FILTER_OPTIONS
|
||||||
source: window.location.host,
|
)
|
||||||
moderated: ModeratedFilter.Moderated
|
|
||||||
})
|
|
||||||
const [mods, setMods] = useState<ModDetails[]>([])
|
const [mods, setMods] = useState<ModDetails[]>([])
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(1)
|
const [currentPage, setCurrentPage] = useState(1)
|
||||||
@ -186,10 +184,7 @@ export const GamePage = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ModFilter
|
<ModFilter />
|
||||||
filterOptions={filterOptions}
|
|
||||||
setFilterOptions={setFilterOptions}
|
|
||||||
/>
|
|
||||||
<div className='IBMSecMain IBMSMListWrapper'>
|
<div className='IBMSecMain IBMSMListWrapper'>
|
||||||
<div className='IBMSMList'>
|
<div className='IBMSMList'>
|
||||||
{currentMods.map((mod) => (
|
{currentMods.map((mod) => (
|
||||||
|
@ -8,6 +8,7 @@ import { MOD_FILTER_LIMIT } from '../constants'
|
|||||||
import {
|
import {
|
||||||
useAppSelector,
|
useAppSelector,
|
||||||
useFilteredMods,
|
useFilteredMods,
|
||||||
|
useLocalStorage,
|
||||||
useMuteLists,
|
useMuteLists,
|
||||||
useNDKContext,
|
useNDKContext,
|
||||||
useNSFWList
|
useNSFWList
|
||||||
@ -17,14 +18,8 @@ import '../styles/filters.css'
|
|||||||
import '../styles/pagination.css'
|
import '../styles/pagination.css'
|
||||||
import '../styles/search.css'
|
import '../styles/search.css'
|
||||||
import '../styles/styles.css'
|
import '../styles/styles.css'
|
||||||
import {
|
import { FilterOptions, ModDetails } from '../types'
|
||||||
FilterOptions,
|
import { DEFAULT_FILTER_OPTIONS, scrollIntoView } from 'utils'
|
||||||
ModDetails,
|
|
||||||
ModeratedFilter,
|
|
||||||
NSFWFilter,
|
|
||||||
SortBy
|
|
||||||
} from '../types'
|
|
||||||
import { scrollIntoView } from 'utils'
|
|
||||||
import { SearchInput } from 'components/SearchInput'
|
import { SearchInput } from 'components/SearchInput'
|
||||||
|
|
||||||
export const ModsPage = () => {
|
export const ModsPage = () => {
|
||||||
@ -32,12 +27,11 @@ export const ModsPage = () => {
|
|||||||
const { fetchMods } = useNDKContext()
|
const { fetchMods } = useNDKContext()
|
||||||
const [isFetching, setIsFetching] = useState(false)
|
const [isFetching, setIsFetching] = useState(false)
|
||||||
const [mods, setMods] = useState<ModDetails[]>([])
|
const [mods, setMods] = useState<ModDetails[]>([])
|
||||||
const [filterOptions, setFilterOptions] = useState<FilterOptions>({
|
|
||||||
sort: SortBy.Latest,
|
const [filterOptions] = useLocalStorage<FilterOptions>(
|
||||||
nsfw: NSFWFilter.Hide_NSFW,
|
'filter',
|
||||||
source: window.location.host,
|
DEFAULT_FILTER_OPTIONS
|
||||||
moderated: ModeratedFilter.Moderated
|
)
|
||||||
})
|
|
||||||
const muteLists = useMuteLists()
|
const muteLists = useMuteLists()
|
||||||
const nsfwList = useNSFWList()
|
const nsfwList = useNSFWList()
|
||||||
|
|
||||||
@ -113,10 +107,7 @@ export const ModsPage = () => {
|
|||||||
ref={scrollTargetRef}
|
ref={scrollTargetRef}
|
||||||
>
|
>
|
||||||
<PageTitleRow />
|
<PageTitleRow />
|
||||||
<ModFilter
|
<ModFilter />
|
||||||
filterOptions={filterOptions}
|
|
||||||
setFilterOptions={setFilterOptions}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className='IBMSecMain IBMSMListWrapper'>
|
<div className='IBMSecMain IBMSMListWrapper'>
|
||||||
<div className='IBMSMList'>
|
<div className='IBMSMList'>
|
||||||
|
@ -9,6 +9,7 @@ import { MOD_FILTER_LIMIT } from '../constants'
|
|||||||
import {
|
import {
|
||||||
useAppSelector,
|
useAppSelector,
|
||||||
useFilteredMods,
|
useFilteredMods,
|
||||||
|
useLocalStorage,
|
||||||
useMuteLists,
|
useMuteLists,
|
||||||
useNDKContext,
|
useNDKContext,
|
||||||
useNSFWList
|
useNSFWList
|
||||||
@ -18,16 +19,10 @@ import { useCallback, useEffect, useRef, useState } from 'react'
|
|||||||
import { useParams, Navigate, Link } from 'react-router-dom'
|
import { useParams, Navigate, Link } from 'react-router-dom'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import { appRoutes, getProfilePageRoute } from 'routes'
|
import { appRoutes, getProfilePageRoute } from 'routes'
|
||||||
import {
|
import { FilterOptions, ModDetails, UserRelaysType } from 'types'
|
||||||
FilterOptions,
|
|
||||||
ModDetails,
|
|
||||||
ModeratedFilter,
|
|
||||||
NSFWFilter,
|
|
||||||
SortBy,
|
|
||||||
UserRelaysType
|
|
||||||
} from 'types'
|
|
||||||
import {
|
import {
|
||||||
copyTextToClipboard,
|
copyTextToClipboard,
|
||||||
|
DEFAULT_FILTER_OPTIONS,
|
||||||
now,
|
now,
|
||||||
npubToHex,
|
npubToHex,
|
||||||
scrollIntoView,
|
scrollIntoView,
|
||||||
@ -230,12 +225,9 @@ export const ProfilePage = () => {
|
|||||||
|
|
||||||
// Mods
|
// Mods
|
||||||
const [mods, setMods] = useState<ModDetails[]>([])
|
const [mods, setMods] = useState<ModDetails[]>([])
|
||||||
const [filterOptions, setFilterOptions] = useState<FilterOptions>({
|
const filterKey = 'filter-profile'
|
||||||
sort: SortBy.Latest,
|
const [filterOptions] = useLocalStorage<FilterOptions>(filterKey, {
|
||||||
nsfw: NSFWFilter.Hide_NSFW,
|
...DEFAULT_FILTER_OPTIONS
|
||||||
source: window.location.host,
|
|
||||||
moderated: ModeratedFilter.Moderated,
|
|
||||||
author: profilePubkey
|
|
||||||
})
|
})
|
||||||
const muteLists = useMuteLists()
|
const muteLists = useMuteLists()
|
||||||
const nsfwList = useNSFWList()
|
const nsfwList = useNSFWList()
|
||||||
@ -304,7 +296,8 @@ export const ProfilePage = () => {
|
|||||||
userState,
|
userState,
|
||||||
filterOptions,
|
filterOptions,
|
||||||
nsfwList,
|
nsfwList,
|
||||||
muteLists
|
muteLists,
|
||||||
|
profilePubkey
|
||||||
)
|
)
|
||||||
|
|
||||||
// Redirect route
|
// Redirect route
|
||||||
@ -470,10 +463,7 @@ export const ProfilePage = () => {
|
|||||||
{/* Tabs Content */}
|
{/* Tabs Content */}
|
||||||
{tab === 0 && (
|
{tab === 0 && (
|
||||||
<>
|
<>
|
||||||
<ModFilter
|
<ModFilter filterKey={filterKey} author={profilePubkey} />
|
||||||
filterOptions={filterOptions}
|
|
||||||
setFilterOptions={setFilterOptions}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className='IBMSMList IBMSMListAlt'>
|
<div className='IBMSMList IBMSMListAlt'>
|
||||||
{filteredModList.map((mod) => (
|
{filteredModList.map((mod) => (
|
||||||
|
@ -23,28 +23,16 @@ import {
|
|||||||
useAppSelector,
|
useAppSelector,
|
||||||
useFilteredMods,
|
useFilteredMods,
|
||||||
useGames,
|
useGames,
|
||||||
|
useLocalStorage,
|
||||||
useMuteLists,
|
useMuteLists,
|
||||||
useNDKContext,
|
useNDKContext,
|
||||||
useNSFWList
|
useNSFWList
|
||||||
} from 'hooks'
|
} from 'hooks'
|
||||||
import React, {
|
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
||||||
Dispatch,
|
|
||||||
SetStateAction,
|
|
||||||
useEffect,
|
|
||||||
useMemo,
|
|
||||||
useRef,
|
|
||||||
useState
|
|
||||||
} from 'react'
|
|
||||||
import { useSearchParams } from 'react-router-dom'
|
import { useSearchParams } from 'react-router-dom'
|
||||||
|
import { FilterOptions, ModDetails, ModeratedFilter, MuteLists } from 'types'
|
||||||
import {
|
import {
|
||||||
FilterOptions,
|
DEFAULT_FILTER_OPTIONS,
|
||||||
ModDetails,
|
|
||||||
ModeratedFilter,
|
|
||||||
MuteLists,
|
|
||||||
NSFWFilter,
|
|
||||||
SortBy
|
|
||||||
} from 'types'
|
|
||||||
import {
|
|
||||||
extractModData,
|
extractModData,
|
||||||
isModDataComplete,
|
isModDataComplete,
|
||||||
log,
|
log,
|
||||||
@ -69,12 +57,10 @@ export const SearchPage = () => {
|
|||||||
const searchKind =
|
const searchKind =
|
||||||
(searchParams.get('kind') as SearchKindEnum) || SearchKindEnum.Mods
|
(searchParams.get('kind') as SearchKindEnum) || SearchKindEnum.Mods
|
||||||
|
|
||||||
const [filterOptions, setFilterOptions] = useState<FilterOptions>({
|
const [filterOptions] = useLocalStorage<FilterOptions>(
|
||||||
sort: SortBy.Latest,
|
'filter',
|
||||||
nsfw: NSFWFilter.Hide_NSFW,
|
DEFAULT_FILTER_OPTIONS
|
||||||
source: window.location.host,
|
)
|
||||||
moderated: ModeratedFilter.Moderated
|
|
||||||
})
|
|
||||||
|
|
||||||
const [searchTerm, setSearchTerm] = useState(searchParams.get('q') || '')
|
const [searchTerm, setSearchTerm] = useState(searchParams.get('q') || '')
|
||||||
|
|
||||||
@ -124,10 +110,7 @@ export const SearchPage = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Filters
|
<Filters />
|
||||||
filterOptions={filterOptions}
|
|
||||||
setFilterOptions={setFilterOptions}
|
|
||||||
/>
|
|
||||||
{searchKind === SearchKindEnum.Mods && (
|
{searchKind === SearchKindEnum.Mods && (
|
||||||
<ModsResult
|
<ModsResult
|
||||||
searchTerm={searchTerm}
|
searchTerm={searchTerm}
|
||||||
@ -153,13 +136,12 @@ export const SearchPage = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
type FiltersProps = {
|
const Filters = React.memo(() => {
|
||||||
filterOptions: FilterOptions
|
const [filterOptions, setFilterOptions] = useLocalStorage<FilterOptions>(
|
||||||
setFilterOptions: Dispatch<SetStateAction<FilterOptions>>
|
'filter',
|
||||||
}
|
DEFAULT_FILTER_OPTIONS
|
||||||
|
)
|
||||||
|
|
||||||
const Filters = React.memo(
|
|
||||||
({ filterOptions, setFilterOptions }: FiltersProps) => {
|
|
||||||
const userState = useAppSelector((state) => state.user)
|
const userState = useAppSelector((state) => state.user)
|
||||||
const [searchParams, setSearchParams] = useSearchParams()
|
const [searchParams, setSearchParams] = useSearchParams()
|
||||||
const searchKind =
|
const searchKind =
|
||||||
@ -174,12 +156,7 @@ const Filters = React.memo(
|
|||||||
return (
|
return (
|
||||||
<div className='IBMSecMain'>
|
<div className='IBMSecMain'>
|
||||||
<div className='FiltersMain'>
|
<div className='FiltersMain'>
|
||||||
{searchKind === SearchKindEnum.Mods && (
|
{searchKind === SearchKindEnum.Mods && <ModFilter />}
|
||||||
<ModFilter
|
|
||||||
filterOptions={filterOptions}
|
|
||||||
setFilterOptions={setFilterOptions}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{searchKind === SearchKindEnum.Users && (
|
{searchKind === SearchKindEnum.Users && (
|
||||||
<div className='FiltersMainElement'>
|
<div className='FiltersMainElement'>
|
||||||
@ -248,8 +225,7 @@ const Filters = React.memo(
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
type ModsResultProps = {
|
type ModsResultProps = {
|
||||||
filterOptions: FilterOptions
|
filterOptions: FilterOptions
|
||||||
|
@ -22,5 +22,4 @@ export interface FilterOptions {
|
|||||||
nsfw: NSFWFilter
|
nsfw: NSFWFilter
|
||||||
source: string
|
source: string
|
||||||
moderated: ModeratedFilter
|
moderated: ModeratedFilter
|
||||||
author?: string
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user