feat: add filtering, split mods and blog filters

This commit is contained in:
enes 2024-11-28 16:47:10 +01:00
parent 376164cbf4
commit b1d578c329
15 changed files with 510 additions and 323 deletions

View File

@ -0,0 +1,165 @@
import { useAppSelector, useLocalStorage } from 'hooks'
import React from 'react'
import {
FilterOptions,
ModeratedFilter,
NSFWFilter,
SortBy,
WOTFilterOptions
} from 'types'
import { DEFAULT_FILTER_OPTIONS } from 'utils'
import { Dropdown } from './Dropdown'
import { Option } from './Option'
import { Filter } from '.'
type Props = {
author?: string | undefined
filterKey?: string | undefined
}
export const BlogsFilter = React.memo(
({ author, filterKey = 'filter-blog' }: Props) => {
const userState = useAppSelector((state) => state.user)
const [filterOptions, setFilterOptions] = useLocalStorage<FilterOptions>(
filterKey,
DEFAULT_FILTER_OPTIONS
)
return (
<Filter>
{/* sort filter options */}
<Dropdown label={filterOptions.sort}>
{Object.values(SortBy).map((item, index) => (
<div
key={`sortByItem-${index}`}
className='dropdown-item dropdownMainMenuItem'
onClick={() =>
setFilterOptions((prev) => ({
...prev,
sort: item
}))
}
>
{item}
</div>
))}
</Dropdown>
{/* moderation filter options */}
<Dropdown label={filterOptions.moderated}>
{Object.values(ModeratedFilter).map((item) => {
if (item === ModeratedFilter.Unmoderated_Fully) {
const isAdmin =
userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB
const isOwnProfile =
author && userState.auth && userState.user?.pubkey === author
if (!(isAdmin || isOwnProfile)) return null
}
return (
<Option
key={`sort-${item}`}
onClick={() =>
setFilterOptions((prev) => ({
...prev,
moderated: item
}))
}
>
{item}
</Option>
)
})}
</Dropdown>
{/* wot filter options */}
<Dropdown label={<>Trust: {filterOptions.wot}</>}>
{Object.values(WOTFilterOptions).map((item, index) => {
// when user is not logged in
if (item === WOTFilterOptions.Site_And_Mine && !userState.auth) {
return null
}
// when logged in user not admin
if (
item === WOTFilterOptions.None ||
item === WOTFilterOptions.Mine_Only ||
item === WOTFilterOptions.Exclude
) {
const isWoTNpub =
userState.user?.npub === import.meta.env.VITE_SITE_WOT_NPUB
const isOwnProfile =
author && userState.auth && userState.user?.pubkey === author
if (!(isWoTNpub || isOwnProfile)) return null
}
return (
<Option
key={`wotFilterOption-${index}`}
onClick={() =>
setFilterOptions((prev) => ({
...prev,
wot: item
}))
}
>
{item}
</Option>
)
})}
</Dropdown>
{/* nsfw filter options */}
<Dropdown label={filterOptions.nsfw}>
{Object.values(NSFWFilter).map((item, index) => (
<Option
key={`nsfwFilterItem-${index}`}
onClick={() =>
setFilterOptions((prev) => ({
...prev,
nsfw: item
}))
}
>
{item}
</Option>
))}
</Dropdown>
{/* source filter options */}
<Dropdown
label={
filterOptions.source === window.location.host
? `Show From: ${filterOptions.source}`
: 'Show All'
}
>
<Option
onClick={() =>
setFilterOptions((prev) => ({
...prev,
source: window.location.host
}))
}
>
Show From: {window.location.host}
</Option>
<Option
onClick={() =>
setFilterOptions((prev) => ({
...prev,
source: 'Show All'
}))
}
>
Show All
</Option>
</Dropdown>
</Filter>
)
}
)

View File

@ -0,0 +1,25 @@
import { PropsWithChildren } from 'react'
interface DropdownProps {
label: React.ReactNode
}
export const Dropdown = ({
label,
children
}: PropsWithChildren<DropdownProps>) => {
return (
<div className='FiltersMainElement'>
<div className='dropdown dropdownMain'>
<button
className='btn dropdown-toggle btnMain btnMainDropdown'
aria-expanded='false'
data-bs-toggle='dropdown'
type='button'
>
{label}
</button>
<div className='dropdown-menu dropdownMainMenu'>{children}</div>
</div>
</div>
)
}

View File

@ -0,0 +1,182 @@
import { useAppSelector, useLocalStorage } from 'hooks'
import React from 'react'
import {
FilterOptions,
SortBy,
ModeratedFilter,
WOTFilterOptions,
NSFWFilter,
RepostFilter
} from 'types'
import { DEFAULT_FILTER_OPTIONS } from 'utils'
import { Filter } from '.'
import { Dropdown } from './Dropdown'
import { Option } from './Option'
type Props = {
author?: string | undefined
filterKey?: string | undefined
}
export const ModFilter = React.memo(
({ author, filterKey = 'filter' }: Props) => {
const userState = useAppSelector((state) => state.user)
const [filterOptions, setFilterOptions] = useLocalStorage<FilterOptions>(
filterKey,
DEFAULT_FILTER_OPTIONS
)
return (
<Filter>
{/* sort filter options */}
<Dropdown label={filterOptions.sort}>
{Object.values(SortBy).map((item, index) => (
<Option
key={`sortByItem-${index}`}
onClick={() =>
setFilterOptions((prev) => ({
...prev,
sort: item
}))
}
>
{item}
</Option>
))}
</Dropdown>
{/* moderation filter options */}
<Dropdown label={filterOptions.moderated}>
{Object.values(ModeratedFilter).map((item, index) => {
if (item === ModeratedFilter.Unmoderated_Fully) {
const isAdmin =
userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB
const isOwnProfile =
author && userState.auth && userState.user?.pubkey === author
if (!(isAdmin || isOwnProfile)) return null
}
return (
<Option
key={`moderatedFilterItem-${index}`}
onClick={() =>
setFilterOptions((prev) => ({
...prev,
moderated: item
}))
}
>
{item}
</Option>
)
})}
</Dropdown>
{/* wot filter options */}
<Dropdown label={<>Trust: {filterOptions.wot}</>}>
{Object.values(WOTFilterOptions).map((item, index) => {
// when user is not logged in
if (item === WOTFilterOptions.Site_And_Mine && !userState.auth) {
return null
}
// when logged in user not admin
if (
item === WOTFilterOptions.None ||
item === WOTFilterOptions.Mine_Only ||
item === WOTFilterOptions.Exclude
) {
const isWoTNpub =
userState.user?.npub === import.meta.env.VITE_SITE_WOT_NPUB
const isOwnProfile =
author && userState.auth && userState.user?.pubkey === author
if (!(isWoTNpub || isOwnProfile)) return null
}
return (
<Option
key={`wotFilterOption-${index}`}
onClick={() =>
setFilterOptions((prev) => ({
...prev,
wot: item
}))
}
>
{item}
</Option>
)
})}
</Dropdown>
{/* nsfw filter options */}
<Dropdown label={filterOptions.nsfw}>
{Object.values(NSFWFilter).map((item, index) => (
<Option
key={`nsfwFilterItem-${index}`}
onClick={() =>
setFilterOptions((prev) => ({
...prev,
nsfw: item
}))
}
>
{item}
</Option>
))}
</Dropdown>
{/* repost filter options */}
<Dropdown label={filterOptions.repost}>
{Object.values(RepostFilter).map((item, index) => (
<Option
key={`repostFilterItem-${index}`}
onClick={() =>
setFilterOptions((prev) => ({
...prev,
repost: item
}))
}
>
{item}
</Option>
))}
</Dropdown>
{/* source filter options */}
<Dropdown
label={
filterOptions.source === window.location.host
? `Show From: ${filterOptions.source}`
: 'Show All'
}
>
<Option
onClick={() =>
setFilterOptions((prev) => ({
...prev,
source: window.location.host
}))
}
>
Show From: {window.location.host}
</Option>
<Option
onClick={() =>
setFilterOptions((prev) => ({
...prev,
source: 'Show All'
}))
}
>
Show All
</Option>
</Dropdown>
</Filter>
)
}
)

View File

@ -0,0 +1,16 @@
import { PropsWithChildren } from 'react'
interface OptionProps {
onClick: React.MouseEventHandler<HTMLDivElement>
}
export const Option = ({
onClick,
children
}: PropsWithChildren<OptionProps>) => {
return (
<div className='dropdown-item dropdownMainMenuItem' onClick={onClick}>
{children}
</div>
)
}

View File

@ -0,0 +1,9 @@
import { PropsWithChildren } from 'react'
export const Filter = ({ children }: PropsWithChildren) => {
return (
<div className='IBMSecMain'>
<div className='FiltersMain'>{children}</div>
</div>
)
}

View File

@ -1,235 +0,0 @@
import { useAppSelector, useLocalStorage } from 'hooks'
import React from 'react'
import {
FilterOptions,
ModeratedFilter,
NSFWFilter,
SortBy,
WOTFilterOptions
} from 'types'
import { DEFAULT_FILTER_OPTIONS } from 'utils'
type Props = {
author?: string | undefined
filterKey?: string | undefined
}
export const ModFilter = React.memo(
({ author, filterKey = 'filter' }: Props) => {
const userState = useAppSelector((state) => state.user)
const [filterOptions, setFilterOptions] = useLocalStorage<FilterOptions>(
filterKey,
DEFAULT_FILTER_OPTIONS
)
return (
<div className='IBMSecMain'>
<div className='FiltersMain'>
{/* sort filter options */}
<div className='FiltersMainElement'>
<div className='dropdown dropdownMain'>
<button
className='btn dropdown-toggle btnMain btnMainDropdown'
aria-expanded='false'
data-bs-toggle='dropdown'
type='button'
>
{filterOptions.sort}
</button>
<div className='dropdown-menu dropdownMainMenu'>
{Object.values(SortBy).map((item, index) => (
<div
key={`sortByItem-${index}`}
className='dropdown-item dropdownMainMenuItem'
onClick={() =>
setFilterOptions((prev) => ({
...prev,
sort: item
}))
}
>
{item}
</div>
))}
</div>
</div>
</div>
{/* moderation filter options */}
<div className='FiltersMainElement'>
<div className='dropdown dropdownMain'>
<button
className='btn dropdown-toggle btnMain btnMainDropdown'
aria-expanded='false'
data-bs-toggle='dropdown'
type='button'
>
{filterOptions.moderated}
</button>
<div className='dropdown-menu dropdownMainMenu'>
{Object.values(ModeratedFilter).map((item, index) => {
if (item === ModeratedFilter.Unmoderated_Fully) {
const isAdmin =
userState.user?.npub ===
import.meta.env.VITE_REPORTING_NPUB
const isOwnProfile =
author &&
userState.auth &&
userState.user?.pubkey === author
if (!(isAdmin || isOwnProfile)) return null
}
return (
<div
key={`moderatedFilterItem-${index}`}
className='dropdown-item dropdownMainMenuItem'
onClick={() =>
setFilterOptions((prev) => ({
...prev,
moderated: item
}))
}
>
{item}
</div>
)
})}
</div>
</div>
</div>
{/* wot filter options */}
<div className='FiltersMainElement'>
<div className='dropdown dropdownMain'>
<button
className='btn dropdown-toggle btnMain btnMainDropdown'
aria-expanded='false'
data-bs-toggle='dropdown'
type='button'
>
Trust: {filterOptions.wot}
</button>
<div className='dropdown-menu dropdownMainMenu'>
{Object.values(WOTFilterOptions).map((item, index) => {
// when user is not logged in
if (
item === WOTFilterOptions.Site_And_Mine &&
!userState.auth
) {
return null
}
// when logged in user not admin
if (
item === WOTFilterOptions.None ||
item === WOTFilterOptions.Mine_Only ||
item === WOTFilterOptions.Exclude
) {
const isWoTNpub =
userState.user?.npub ===
import.meta.env.VITE_SITE_WOT_NPUB
const isOwnProfile =
author &&
userState.auth &&
userState.user?.pubkey === author
if (!(isWoTNpub || isOwnProfile)) return null
}
return (
<div
key={`wotFilterOption-${index}`}
className='dropdown-item dropdownMainMenuItem'
onClick={() =>
setFilterOptions((prev) => ({
...prev,
wot: item
}))
}
>
{item}
</div>
)
})}
</div>
</div>
</div>
{/* nsfw filter options */}
<div className='FiltersMainElement'>
<div className='dropdown dropdownMain'>
<button
className='btn dropdown-toggle btnMain btnMainDropdown'
aria-expanded='false'
data-bs-toggle='dropdown'
type='button'
>
{filterOptions.nsfw}
</button>
<div className='dropdown-menu dropdownMainMenu'>
{Object.values(NSFWFilter).map((item, index) => (
<div
key={`nsfwFilterItem-${index}`}
className='dropdown-item dropdownMainMenuItem'
onClick={() =>
setFilterOptions((prev) => ({
...prev,
nsfw: item
}))
}
>
{item}
</div>
))}
</div>
</div>
</div>
{/* source filter options */}
<div className='FiltersMainElement'>
<div className='dropdown dropdownMain'>
<button
className='btn dropdown-toggle btnMain btnMainDropdown'
aria-expanded='false'
data-bs-toggle='dropdown'
type='button'
>
{filterOptions.source === window.location.host
? `Show From: ${filterOptions.source}`
: 'Show All'}
</button>
<div className='dropdown-menu dropdownMainMenu'>
<div
className='dropdown-item dropdownMainMenuItem'
onClick={() =>
setFilterOptions((prev) => ({
...prev,
source: window.location.host
}))
}
>
Show From: {window.location.host}
</div>
<div
className='dropdown-item dropdownMainMenuItem'
onClick={() =>
setFilterOptions((prev) => ({
...prev,
source: 'Show All'
}))
}
>
Show All
</div>
</div>
</div>
</div>
</div>
</div>
)
}
)

View File

@ -6,6 +6,7 @@ import {
ModeratedFilter,
MuteLists,
NSFWFilter,
RepostFilter,
SortBy,
WOTFilterOptions
} from 'types'
@ -22,6 +23,7 @@ export const useFilteredMods = (
admin: MuteLists
user: MuteLists
},
repostList: string[],
author?: string | undefined
) => {
const { siteWot, siteWotLevel, userWot, userWotLevel } = useAppSelector(
@ -53,6 +55,30 @@ export const useFilteredMods = (
}
}
const repostFilter = (mods: ModDetails[]) => {
if (filterOptions.repost !== RepostFilter.Hide_Repost) {
// Add repost tag to mods included in repostList
mods = mods.map((mod) => {
return !mod.repost && repostList.includes(mod.aTag)
? { ...mod, repost: true }
: mod
})
}
// Determine the filtering logic based on the Repost filter option
switch (filterOptions.repost) {
case RepostFilter.Hide_Repost:
return mods.filter(
(mod) => !mod.repost && !repostList.includes(mod.aTag)
)
case RepostFilter.Show_Repost:
return mods
case RepostFilter.Only_Repost:
return mods.filter(
(mod) => mod.repost || repostList.includes(mod.aTag)
)
}
}
const wotFilter = (mods: ModDetails[]) => {
// Determine the filtering logic based on the WOT filter option and user state
// when user is not logged in use Site_Only
@ -93,7 +119,7 @@ export const useFilteredMods = (
}
let filtered = nsfwFilter(mods)
filtered = repostFilter(filtered)
filtered = wotFilter(filtered)
const isAdmin = userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB
@ -135,10 +161,12 @@ export const useFilteredMods = (
filterOptions.moderated,
filterOptions.wot,
filterOptions.nsfw,
filterOptions.repost,
author,
mods,
muteLists,
nsfwList,
repostList,
siteWot,
siteWotLevel,
userWot,

View File

@ -11,6 +11,9 @@ import '../../styles/styles.css'
import { PaginationWithPageNumbers } from 'components/Pagination'
import { scrollIntoView } from 'utils'
import { LoadingSpinner } from 'components/LoadingSpinner'
import { Filter } from 'components/Filters'
import { Dropdown } from 'components/Filters/Dropdown'
import { Option } from 'components/Filters/Option'
export const BlogsPage = () => {
const navigation = useNavigation()
@ -126,66 +129,39 @@ export const BlogsPage = () => {
</div>
</div>
<div className='IBMSecMain'>
<div className='FiltersMain'>
<div className='FiltersMainElement'>
<div className='dropdown dropdownMain'>
<button
className='btn dropdown-toggle btnMain btnMainDropdown'
aria-expanded='false'
data-bs-toggle='dropdown'
type='button'
>
{filterOptions.sort}
</button>
<div className='dropdown-menu dropdownMainMenu'>
{Object.values(SortBy).map((item, index) => (
<div
key={`sortByItem-${index}`}
className='dropdown-item dropdownMainMenuItem'
onClick={() =>
setFilterOptions((prev) => ({
...prev,
sort: item
}))
}
>
{item}
</div>
))}
</div>
</div>
</div>
<div className='FiltersMainElement'>
<div className='dropdown dropdownMain'>
<button
className='btn dropdown-toggle btnMain btnMainDropdown'
aria-expanded='false'
data-bs-toggle='dropdown'
type='button'
>
{filterOptions.nsfw}
</button>
<div className='dropdown-menu dropdownMainMenu'>
{Object.values(NSFWFilter).map((item, index) => (
<div
key={`nsfwFilterItem-${index}`}
className='dropdown-item dropdownMainMenuItem'
onClick={() =>
setFilterOptions((prev) => ({
...prev,
nsfw: item
}))
}
>
{item}
</div>
))}
</div>
</div>
</div>
</div>
</div>
<Filter>
<Dropdown label={filterOptions.sort}>
{Object.values(SortBy).map((item, index) => (
<Option
key={`sortByItem-${index}`}
onClick={() =>
setFilterOptions((prev) => ({
...prev,
sort: item
}))
}
>
{item}
</Option>
))}
</Dropdown>
<Dropdown label={filterOptions.nsfw}>
{Object.values(NSFWFilter).map((item, index) => (
<Option
key={`nsfwFilterItem-${index}`}
onClick={() =>
setFilterOptions((prev) => ({
...prev,
nsfw: item
}))
}
>
{item}
</Option>
))}
</Dropdown>
</Filter>
<div className='IBMSecMain IBMSMListWrapper'>
<div className='IBMSMList'>

View File

@ -4,7 +4,7 @@ import {
NDKSubscriptionCacheUsage
} from '@nostr-dev-kit/ndk'
import { ModCard } from 'components/ModCard'
import { ModFilter } from 'components/ModsFilter'
import { ModFilter } from 'components/Filters/ModsFilter'
import { PaginationWithPageNumbers } from 'components/Pagination'
import { SearchInput } from 'components/SearchInput'
import { MAX_MODS_PER_PAGE, T_TAG_VALUE } from 'constants.ts'
@ -20,11 +20,13 @@ import { useEffect, useMemo, useRef, useState } from 'react'
import { useParams, useSearchParams } from 'react-router-dom'
import { FilterOptions, ModDetails } from 'types'
import {
CurationSetIdentifiers,
DEFAULT_FILTER_OPTIONS,
extractModData,
isModDataComplete,
scrollIntoView
} from 'utils'
import { useCuratedSet } from 'hooks/useCuratedSet'
export const GamePage = () => {
const scrollTargetRef = useRef<HTMLDivElement>(null)
@ -33,6 +35,7 @@ export const GamePage = () => {
const { ndk } = useNDKContext()
const muteLists = useMuteLists()
const nsfwList = useNSFWList()
const repostList = useCuratedSet(CurationSetIdentifiers.Repost)
const [filterOptions] = useLocalStorage<FilterOptions>(
'filter',
@ -101,7 +104,8 @@ export const GamePage = () => {
userState,
filterOptions,
nsfwList,
muteLists
muteLists,
repostList
)
// Pagination logic

View File

@ -1,4 +1,4 @@
import { ModFilter } from 'components/ModsFilter'
import { ModFilter } from 'components/Filters/ModsFilter'
import { Pagination } from 'components/Pagination'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { createSearchParams, useNavigate } from 'react-router-dom'
@ -39,6 +39,7 @@ export const ModsPage = () => {
)
const muteLists = useMuteLists()
const nsfwList = useNSFWList()
const repostList = useCuratedSet(CurationSetIdentifiers.Repost)
const [page, setPage] = useState(1)
@ -99,17 +100,10 @@ export const ModsPage = () => {
userState,
filterOptions,
nsfwList,
muteLists
muteLists,
repostList
)
// Add repost tag to mods included in repostList
const repostList = useCuratedSet(CurationSetIdentifiers.Repost)
const filteredModListRepost = filteredModList.map((mod) => {
return !mod.repost && repostList.includes(mod.aTag)
? { ...mod, repost: true }
: mod
})
return (
<>
{isFetching && <LoadingSpinner desc='Fetching mod details from relays' />}
@ -124,7 +118,7 @@ export const ModsPage = () => {
<div className='IBMSecMain IBMSMListWrapper'>
<div className='IBMSMList'>
{filteredModListRepost.map((mod) => (
{filteredModList.map((mod) => (
<ModCard key={mod.id} {...mod} />
))}
</div>

View File

@ -1,7 +1,7 @@
import { NDKFilter, NDKKind } from '@nostr-dev-kit/ndk'
import { LoadingSpinner } from 'components/LoadingSpinner'
import { ModCard } from 'components/ModCard'
import { ModFilter } from 'components/ModsFilter'
import { ModFilter } from 'components/Filters/ModsFilter'
import { Pagination } from 'components/Pagination'
import { ProfileSection } from 'components/ProfileSection'
import { Tabs } from 'components/Tabs'
@ -39,6 +39,7 @@ import {
import { CheckboxField } from 'components/Inputs'
import { ProfilePageLoaderResult } from './loader'
import { BlogCard } from 'components/BlogCard'
import { BlogsFilter } from 'components/Filters/BlogsFilter'
export const ProfilePage = () => {
const {
@ -269,16 +270,10 @@ export const ProfilePage = () => {
filterOptions,
nsfwList,
muteLists,
repostList,
profilePubkey
)
// Add repost tag to mods included in repostList
const filteredModListRepost = filteredModList.map((mod) => {
return !mod.repost && repostList.includes(mod.aTag)
? { ...mod, repost: true }
: mod
})
return (
<div className='InnerBodyMain'>
<div className='ContainerMain'>
@ -429,7 +424,7 @@ export const ProfilePage = () => {
<ModFilter filterKey={filterKey} author={profilePubkey} />
<div className='IBMSMList IBMSMListAlt'>
{filteredModListRepost.map((mod) => (
{filteredModList.map((mod) => (
<ModCard key={mod.id} {...mod} />
))}
</div>
@ -831,7 +826,10 @@ const ProfileTabBlogs = () => {
<LoadingSpinner desc={'Loading...'} />
)}
<ModFilter filterKey={'filter-blog'} author={profile?.pubkey as string} />
<BlogsFilter
filterKey={'filter-blog'}
author={profile?.pubkey as string}
/>
<div className='IBMSMList IBMSMListAlt'>
{moderatedAndSortedBlogs.map((b) => (

View File

@ -10,7 +10,7 @@ import {
import { ErrorBoundary } from 'components/ErrorBoundary'
import { GameCard } from 'components/GameCard'
import { ModCard } from 'components/ModCard'
import { ModFilter } from 'components/ModsFilter'
import { ModFilter } from 'components/Filters/ModsFilter'
import { Pagination } from 'components/Pagination'
import { Profile } from 'components/ProfileSection'
import { SearchInput } from 'components/SearchInput'
@ -32,11 +32,13 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'
import { useSearchParams } from 'react-router-dom'
import { FilterOptions, ModDetails, ModeratedFilter, MuteLists } from 'types'
import {
CurationSetIdentifiers,
DEFAULT_FILTER_OPTIONS,
extractModData,
isModDataComplete,
scrollIntoView
} from 'utils'
import { useCuratedSet } from 'hooks/useCuratedSet'
enum SearchKindEnum {
Mods = 'Mods',
@ -50,6 +52,7 @@ export const SearchPage = () => {
const muteLists = useMuteLists()
const nsfwList = useNSFWList()
const repostList = useCuratedSet(CurationSetIdentifiers.Repost)
const searchTermRef = useRef<HTMLInputElement>(null)
const searchKind =
@ -115,6 +118,7 @@ export const SearchPage = () => {
filterOptions={filterOptions}
muteLists={muteLists}
nsfwList={nsfwList}
repostList={repostList}
el={scrollTargetRef.current}
/>
)}
@ -233,6 +237,7 @@ type ModsResultProps = {
user: MuteLists
}
nsfwList: string[]
repostList: string[]
el: HTMLElement | null
}
@ -241,6 +246,7 @@ const ModsResult = ({
searchTerm,
muteLists,
nsfwList,
repostList,
el
}: ModsResultProps) => {
const { ndk } = useNDKContext()
@ -313,7 +319,8 @@ const ModsResult = ({
userState,
filterOptions,
nsfwList,
muteLists
muteLists,
repostList
)
const handleNext = () => {

View File

@ -1,3 +1,5 @@
import { SortBy, NSFWFilter, ModeratedFilter } from './modsFilter'
export interface BlogForm {
title: string
content: string
@ -40,3 +42,10 @@ export interface BlogPageLoaderResult {
isAddedToNSFW: boolean
isBlocked: boolean
}
export interface BlogsFilterOptions {
sort: SortBy
nsfw: NSFWFilter
source: string
moderated: ModeratedFilter
}

View File

@ -25,10 +25,17 @@ export enum WOTFilterOptions {
Exclude = 'Exclude'
}
export enum RepostFilter {
Hide_Repost = 'Hide Repost',
Show_Repost = 'Show Repost',
Only_Repost = 'Only Repost'
}
export interface FilterOptions {
sort: SortBy
nsfw: NSFWFilter
source: string
moderated: ModeratedFilter
wot: WOTFilterOptions
repost: RepostFilter
}

View File

@ -3,7 +3,8 @@ import {
SortBy,
NSFWFilter,
ModeratedFilter,
WOTFilterOptions
WOTFilterOptions,
RepostFilter
} from 'types'
export const DEFAULT_FILTER_OPTIONS: FilterOptions = {
@ -11,5 +12,6 @@ export const DEFAULT_FILTER_OPTIONS: FilterOptions = {
nsfw: NSFWFilter.Hide_NSFW,
source: window.location.host,
moderated: ModeratedFilter.Moderated,
wot: WOTFilterOptions.Site_Only
wot: WOTFilterOptions.Site_Only,
repost: RepostFilter.Show_Repost
}