This commit is contained in:
2025-07-03 01:26:32 +09:00
parent 42cf25246f
commit f47d7bbb87
4 changed files with 81 additions and 31 deletions
+37 -11
View File
@@ -1,6 +1,6 @@
import axios from 'axios'
import toCamel from 'camelcase-keys'
import React, { useEffect, useState } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { Helmet } from 'react-helmet'
import { Link, useLocation } from 'react-router-dom'
@@ -16,6 +16,22 @@ import type { Post, Tag, WikiPage } from '@/types'
export default () => {
const [posts, setPosts] = useState<Post[] | null> (null)
const [wikiPage, setWikiPage] = useState<WikiPage | null> (null)
const [cursor, setCursor] = useState ('')
const [loading, setLoading] = useState (false)
const loaderRef = useRef<HTMLDivElement | null> (null)
const loadMore = async () => {
setLoading (true)
const res = await axios.get (`${ API_BASE_URL }/posts`, {
params: { tags: tags.join (' '),
match: (anyFlg ? 'any' : 'all'),
cursor } })
const data = toCamel (res.data, { deep: true })
setPosts (posts => [...(posts || []), ...data.posts])
setCursor (data.nextCursor)
setLoading (false)
}
const location = useLocation ()
const query = new URLSearchParams (location.search)
@@ -24,14 +40,22 @@ export default () => {
const tags = tagsQuery.split (' ').filter (e => e !== '')
useEffect(() => {
void (axios.get (`${ API_BASE_URL }/posts`, {
params: { tags: tags.join (','),
match: (anyFlg ? 'any' : 'all') } })
.then (res => setPosts (toCamel (res.data, { deep: true })))
.catch (err => {
console.error ('Failed to fetch posts:', err)
setPosts ([])
}))
const observer = new IntersectionObserver (entries => {
if (entries[0].isIntersecting && !(loading) && cursor)
loadMore ()
}, { threshold: 1 })
const target = loaderRef.current
target && observer.observe (target)
return () => target && observer.unobserve (target)
}, [loaderRef, loading])
useEffect (() => {
console.log ('test')
setCursor ('')
setPosts (null)
loadMore ()
setWikiPage (null)
if (tags.length === 1)
@@ -50,10 +74,10 @@ export default () => {
<title>
{tags.length
? `${ tags.join (anyFlg ? ' or ' : ' and ') } | ${ SITE_TITLE }`
: `${ SITE_TITLE } 〜 ぼざクリも、ぼざろ外も、外伝もあるんだよ`}
: `${ SITE_TITLE } 〜 ぼざクリ関聯綜合リンク集サイト`}
</title>
</Helmet>
<TagSidebar posts={posts || []} />
<TagSidebar posts={posts?.slice (0, 20) || []} />
<MainArea>
<TabGroup key={wikiPage}>
<Tab name="広場">
@@ -66,10 +90,12 @@ export default () => {
key={post.id}
className="w-40 h-40 overflow-hidden rounded-lg shadow-md hover:shadow-lg">
<img src={post.thumbnail ?? post.thumbnailBase}
alt={post.title || post.url}
className="object-none w-full h-full" />
</Link>))}
</div>)
: '広場には何もありませんよ.')}
<div ref={loaderRef} className="h-12"></div>
</Tab>
{(wikiPage && wikiPage.body) && (
<Tab name="Wiki" init={posts && !(posts.length)}>