All checks were successful
Release to Staging / build_and_release (push) Successful in 46s
157 lines
4.3 KiB
TypeScript
157 lines
4.3 KiB
TypeScript
import { LoadingSpinner } from 'components/LoadingSpinner'
|
|
import { ModCard } from 'components/ModCard'
|
|
import { ModFilter } from 'components/ModsFilter'
|
|
import { PaginationWithPageNumbers } from 'components/Pagination'
|
|
import { MAX_MODS_PER_PAGE, T_TAG_VALUE } from 'constants.ts'
|
|
import { RelayController } from 'controllers'
|
|
import {
|
|
useAppSelector,
|
|
useFilteredMods,
|
|
useMuteLists,
|
|
useNSFWList
|
|
} from 'hooks'
|
|
import { Filter, kinds } from 'nostr-tools'
|
|
import { Subscription } from 'nostr-tools/abstract-relay'
|
|
import { useEffect, useRef, useState } from 'react'
|
|
import { useParams } from 'react-router-dom'
|
|
import { toast } from 'react-toastify'
|
|
import {
|
|
FilterOptions,
|
|
ModDetails,
|
|
ModeratedFilter,
|
|
NSFWFilter,
|
|
SortBy
|
|
} from 'types'
|
|
import { extractModData, isModDataComplete, log, LogType } from 'utils'
|
|
|
|
export const GamePage = () => {
|
|
const params = useParams()
|
|
const { name: gameName } = params
|
|
const muteLists = useMuteLists()
|
|
const nsfwList = useNSFWList()
|
|
|
|
const [filterOptions, setFilterOptions] = useState<FilterOptions>({
|
|
sort: SortBy.Latest,
|
|
nsfw: NSFWFilter.Hide_NSFW,
|
|
source: window.location.host,
|
|
moderated: ModeratedFilter.Moderated
|
|
})
|
|
const [mods, setMods] = useState<ModDetails[]>([])
|
|
|
|
const hasEffectRun = useRef(false)
|
|
const [isSubscribing, setIsSubscribing] = useState(false)
|
|
const [currentPage, setCurrentPage] = useState(1)
|
|
|
|
const userState = useAppSelector((state) => state.user)
|
|
|
|
const filteredMods = useFilteredMods(
|
|
mods,
|
|
userState,
|
|
filterOptions,
|
|
nsfwList,
|
|
muteLists
|
|
)
|
|
|
|
// Pagination logic
|
|
const totalGames = filteredMods.length
|
|
const totalPages = Math.ceil(totalGames / MAX_MODS_PER_PAGE)
|
|
const startIndex = (currentPage - 1) * MAX_MODS_PER_PAGE
|
|
const endIndex = startIndex + MAX_MODS_PER_PAGE
|
|
const currentMods = filteredMods.slice(startIndex, endIndex)
|
|
|
|
const handlePageChange = (page: number) => {
|
|
if (page >= 1 && page <= totalPages) {
|
|
setCurrentPage(page)
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (hasEffectRun.current) {
|
|
return
|
|
}
|
|
|
|
hasEffectRun.current = true // Set it so the effect doesn't run again
|
|
|
|
const filter: Filter = {
|
|
kinds: [kinds.ClassifiedListing],
|
|
'#t': [T_TAG_VALUE]
|
|
}
|
|
|
|
setIsSubscribing(true)
|
|
|
|
let subscriptions: Subscription[] = []
|
|
|
|
RelayController.getInstance()
|
|
.subscribeForEvents(filter, [], (event) => {
|
|
if (isModDataComplete(event)) {
|
|
const mod = extractModData(event)
|
|
if (mod.game === gameName) setMods((prev) => [...prev, mod])
|
|
}
|
|
})
|
|
.then((subs) => {
|
|
subscriptions = subs
|
|
})
|
|
.catch((err) => {
|
|
log(
|
|
true,
|
|
LogType.Error,
|
|
'An error occurred in subscribing to relays.',
|
|
err
|
|
)
|
|
toast.error(err.message || err)
|
|
})
|
|
.finally(() => {
|
|
setIsSubscribing(false)
|
|
})
|
|
|
|
// Cleanup function to stop all subscriptions
|
|
return () => {
|
|
subscriptions.forEach((sub) => sub.close()) // close each subscription
|
|
}
|
|
}, [gameName])
|
|
|
|
if (!gameName) return null
|
|
|
|
return (
|
|
<>
|
|
{isSubscribing && (
|
|
<LoadingSpinner desc='Subscribing to relays for mods' />
|
|
)}
|
|
<div className='InnerBodyMain'>
|
|
<div className='ContainerMain'>
|
|
<div className='IBMSecMainGroup IBMSecMainGroupAlt'>
|
|
<div className='IBMSecMain'>
|
|
<div className='SearchMainWrapper'>
|
|
<div className='IBMSMTitleMain'>
|
|
<h2 className='IBMSMTitleMainHeading'>
|
|
Game:
|
|
<span className='IBMSMTitleMainHeadingSpan'>
|
|
{gameName}
|
|
</span>
|
|
</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<ModFilter
|
|
filterOptions={filterOptions}
|
|
setFilterOptions={setFilterOptions}
|
|
/>
|
|
<div className='IBMSecMain IBMSMListWrapper'>
|
|
<div className='IBMSMList'>
|
|
{currentMods.map((mod) => (
|
|
<ModCard key={mod.id} {...mod} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
<PaginationWithPageNumbers
|
|
currentPage={currentPage}
|
|
totalPages={totalPages}
|
|
handlePageChange={handlePageChange}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|