degmods.com/src/hooks/useFilteredMods.ts

120 lines
3.6 KiB
TypeScript
Raw Normal View History

2024-10-07 15:45:21 +05:00
import { useMemo } from 'react'
import { IUserState } from 'store/reducers/user'
import {
FilterOptions,
ModDetails,
ModeratedFilter,
MuteLists,
NSFWFilter,
2024-11-11 22:37:49 +05:00
SortBy,
WOTFilterOptions
2024-10-07 15:45:21 +05:00
} from 'types'
2024-10-23 17:49:45 +02:00
import { npubToHex } from 'utils'
2024-11-11 22:37:49 +05:00
import { useAppSelector } from './redux'
2024-10-07 15:45:21 +05:00
export const useFilteredMods = (
mods: ModDetails[],
userState: IUserState,
filterOptions: FilterOptions,
nsfwList: string[],
muteLists: {
admin: MuteLists
user: MuteLists
},
author?: string | undefined
2024-10-07 15:45:21 +05:00
) => {
2024-11-11 22:37:49 +05:00
const { siteWot, userWot } = useAppSelector((state) => state.wot)
2024-10-07 15:45:21 +05:00
return useMemo(() => {
const nsfwFilter = (mods: ModDetails[]) => {
// Add nsfw tag to mods included in nsfwList
if (filterOptions.nsfw !== NSFWFilter.Hide_NSFW) {
mods = mods.map((mod) => {
return !mod.nsfw && nsfwList.includes(mod.aTag)
? { ...mod, nsfw: true }
: mod
})
}
2024-10-07 15:45:21 +05:00
// Determine the filtering logic based on the NSFW filter option
switch (filterOptions.nsfw) {
case NSFWFilter.Hide_NSFW:
// If 'Hide_NSFW' is selected, filter out NSFW mods
return mods.filter((mod) => !mod.nsfw && !nsfwList.includes(mod.aTag))
case NSFWFilter.Show_NSFW:
// If 'Show_NSFW' is selected, return all mods (no filtering)
return mods
case NSFWFilter.Only_NSFW:
// If 'Only_NSFW' is selected, filter to show only NSFW mods
return mods.filter((mod) => mod.nsfw || nsfwList.includes(mod.aTag))
}
}
2024-11-11 22:37:49 +05:00
const wotFilter = (mods: ModDetails[]) => {
// Determine the filtering logic based on the WOT filter option
switch (filterOptions.wot) {
case WOTFilterOptions.None:
return mods
case WOTFilterOptions.Site_Only:
return mods.filter((mod) => siteWot.includes(mod.author))
case WOTFilterOptions.Mine_Only:
return mods.filter((mod) => userWot.includes(mod.author))
case WOTFilterOptions.Site_And_Mine:
return mods.filter(
(mod) =>
siteWot.includes(mod.author) || userWot.includes(mod.author)
)
}
}
2024-10-07 15:45:21 +05:00
let filtered = nsfwFilter(mods)
2024-11-11 22:37:49 +05:00
filtered = wotFilter(filtered)
2024-10-07 15:45:21 +05:00
const isAdmin = userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB
2024-10-23 17:49:45 +02:00
const isOwner =
userState.user?.npub &&
npubToHex(userState.user.npub as string) === author
2024-10-07 15:45:21 +05:00
const isUnmoderatedFully =
filterOptions.moderated === ModeratedFilter.Unmoderated_Fully
// Only apply filtering if the user is not an admin or the admin has not selected "Unmoderated Fully"
2024-10-23 17:49:45 +02:00
// Allow "Unmoderated Fully" when author visits own profile
if (!((isAdmin || isOwner) && isUnmoderatedFully)) {
2024-10-07 15:45:21 +05:00
filtered = filtered.filter(
(mod) =>
!muteLists.admin.authors.includes(mod.author) &&
!muteLists.admin.replaceableEvents.includes(mod.aTag)
)
}
if (filterOptions.moderated === ModeratedFilter.Moderated) {
filtered = filtered.filter(
(mod) =>
!muteLists.user.authors.includes(mod.author) &&
!muteLists.user.replaceableEvents.includes(mod.aTag)
)
}
if (filterOptions.sort === SortBy.Latest) {
filtered.sort((a, b) => b.published_at - a.published_at)
} else if (filterOptions.sort === SortBy.Oldest) {
filtered.sort((a, b) => a.published_at - b.published_at)
}
return filtered
}, [
userState.user?.npub,
filterOptions.sort,
filterOptions.moderated,
2024-11-11 22:37:49 +05:00
filterOptions.wot,
2024-10-07 15:45:21 +05:00
filterOptions.nsfw,
author,
2024-10-07 15:45:21 +05:00
mods,
muteLists,
2024-11-11 22:37:49 +05:00
nsfwList,
siteWot,
userWot
2024-10-07 15:45:21 +05:00
])
}