This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
|
import type { Post } from '@/types'
|
||||||
|
|
||||||
|
type Props = { posts: Post[] }
|
||||||
|
|
||||||
|
|
||||||
|
export default ({ posts }: Props) => (
|
||||||
|
<div className="flex flex-wrap gap-6 p-4">
|
||||||
|
{posts.map ((post, i) => (
|
||||||
|
<Link to={`/posts/${ post.id }`}
|
||||||
|
key={i}
|
||||||
|
className="w-40 h-40 overflow-hidden rounded-lg shadow-md hover:shadow-lg">
|
||||||
|
<img src={post.thumbnail || post.thumbnailBase || undefined}
|
||||||
|
alt={post.title || post.url}
|
||||||
|
title={post.title || post.url || undefined}
|
||||||
|
loading="eager"
|
||||||
|
fetchPriority="high"
|
||||||
|
decoding="async"
|
||||||
|
className="object-none w-full h-full" />
|
||||||
|
</Link>))}
|
||||||
|
</div>)
|
||||||
@@ -4,6 +4,7 @@ import { useEffect, useRef, useState } from 'react'
|
|||||||
import { Helmet } from 'react-helmet-async'
|
import { Helmet } from 'react-helmet-async'
|
||||||
import { Link, useLocation } from 'react-router-dom'
|
import { Link, useLocation } from 'react-router-dom'
|
||||||
|
|
||||||
|
import PostList from '@/components/PostList'
|
||||||
import TagSidebar from '@/components/TagSidebar'
|
import TagSidebar from '@/components/TagSidebar'
|
||||||
import WikiBody from '@/components/WikiBody'
|
import WikiBody from '@/components/WikiBody'
|
||||||
import TabGroup, { Tab } from '@/components/common/TabGroup'
|
import TabGroup, { Tab } from '@/components/common/TabGroup'
|
||||||
@@ -14,10 +15,10 @@ import type { Post, WikiPage } from '@/types'
|
|||||||
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [posts, setPosts] = useState<Post[]> ([])
|
|
||||||
const [wikiPage, setWikiPage] = useState<WikiPage | null> (null)
|
|
||||||
const [cursor, setCursor] = useState ('')
|
const [cursor, setCursor] = useState ('')
|
||||||
const [loading, setLoading] = useState (false)
|
const [loading, setLoading] = useState (false)
|
||||||
|
const [posts, setPosts] = useState<Post[]> ([])
|
||||||
|
const [wikiPage, setWikiPage] = useState<WikiPage | null> (null)
|
||||||
|
|
||||||
const loaderRef = useRef<HTMLDivElement | null> (null)
|
const loaderRef = useRef<HTMLDivElement | null> (null)
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ export default () => {
|
|||||||
setLoading (true)
|
setLoading (true)
|
||||||
const res = await axios.get (`${ API_BASE_URL }/posts`, {
|
const res = await axios.get (`${ API_BASE_URL }/posts`, {
|
||||||
params: { tags: tags.join (' '),
|
params: { tags: tags.join (' '),
|
||||||
match: (anyFlg ? 'any' : 'all'),
|
match: anyFlg ? 'any' : 'all',
|
||||||
...(withCursor ? { cursor } : { }) } })
|
...(withCursor ? { cursor } : { }) } })
|
||||||
const data = toCamel (res.data as any, { deep: true }) as { posts: Post[]
|
const data = toCamel (res.data as any, { deep: true }) as { posts: Post[]
|
||||||
nextCursor: string }
|
nextCursor: string }
|
||||||
@@ -92,21 +93,7 @@ export default () => {
|
|||||||
<TabGroup>
|
<TabGroup>
|
||||||
<Tab name="広場">
|
<Tab name="広場">
|
||||||
{posts.length
|
{posts.length
|
||||||
? (
|
? <PostList posts={posts} />
|
||||||
<div className="flex flex-wrap gap-6 p-4">
|
|
||||||
{posts.map ((post, i) => (
|
|
||||||
<Link to={`/posts/${ post.id }`}
|
|
||||||
key={i}
|
|
||||||
className="w-40 h-40 overflow-hidden rounded-lg shadow-md hover:shadow-lg">
|
|
||||||
<img src={post.thumbnail || post.thumbnailBase || undefined}
|
|
||||||
alt={post.title || post.url}
|
|
||||||
title={post.title || post.url || undefined}
|
|
||||||
loading="eager"
|
|
||||||
fetchPriority="high"
|
|
||||||
decoding="async"
|
|
||||||
className="object-none w-full h-full" />
|
|
||||||
</Link>))}
|
|
||||||
</div>)
|
|
||||||
: !(loading) && '広場には何もありませんよ.'}
|
: !(loading) && '広場には何もありませんよ.'}
|
||||||
{loading && 'Loading...'}
|
{loading && 'Loading...'}
|
||||||
<div ref={loaderRef} className="h-12"></div>
|
<div ref={loaderRef} className="h-12"></div>
|
||||||
|
|||||||
@@ -4,13 +4,16 @@ import { useEffect, useState } from 'react'
|
|||||||
import { Helmet } from 'react-helmet-async'
|
import { Helmet } from 'react-helmet-async'
|
||||||
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom'
|
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom'
|
||||||
|
|
||||||
|
import PostList from '@/components/PostList'
|
||||||
|
import TagLink from '@/components/TagLink'
|
||||||
import WikiBody from '@/components/WikiBody'
|
import WikiBody from '@/components/WikiBody'
|
||||||
import PageTitle from '@/components/common/PageTitle'
|
import PageTitle from '@/components/common/PageTitle'
|
||||||
|
import TabGroup, { Tab } from '@/components/common/TabGroup'
|
||||||
import MainArea from '@/components/layout/MainArea'
|
import MainArea from '@/components/layout/MainArea'
|
||||||
import { API_BASE_URL, SITE_TITLE } from '@/config'
|
import { API_BASE_URL, SITE_TITLE } from '@/config'
|
||||||
import { WikiIdBus } from '@/lib/eventBus/WikiIdBus'
|
import { WikiIdBus } from '@/lib/eventBus/WikiIdBus'
|
||||||
|
|
||||||
import type { WikiPage } from '@/types'
|
import type { Post, Tag, WikiPage } from '@/types'
|
||||||
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
@@ -20,6 +23,10 @@ export default () => {
|
|||||||
const location = useLocation ()
|
const location = useLocation ()
|
||||||
const navigate = useNavigate ()
|
const navigate = useNavigate ()
|
||||||
|
|
||||||
|
const defaultTag = { name: title, category: 'general' } as Tag
|
||||||
|
|
||||||
|
const [posts, setPosts] = useState<Post[]> ([])
|
||||||
|
const [tag, setTag] = useState (defaultTag)
|
||||||
const [wikiPage, setWikiPage] = useState<WikiPage | null | undefined> (undefined)
|
const [wikiPage, setWikiPage] = useState<WikiPage | null | undefined> (undefined)
|
||||||
|
|
||||||
const query = new URLSearchParams (location.search)
|
const query = new URLSearchParams (location.search)
|
||||||
@@ -33,14 +40,16 @@ export default () => {
|
|||||||
const data = res.data as WikiPage
|
const data = res.data as WikiPage
|
||||||
navigate (`/wiki/${ data.title }`, { replace: true })
|
navigate (`/wiki/${ data.title }`, { replace: true })
|
||||||
}) ()
|
}) ()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
void (async () => {
|
void (async () => {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const res = await axios.get (`${ API_BASE_URL }/wiki/title/${ encodeURIComponent (title) }`,
|
const res = await axios.get (
|
||||||
{ params: { ...(version ? { version } : { }) } })
|
`${ API_BASE_URL }/wiki/title/${ encodeURIComponent (title) }`,
|
||||||
|
{ params: version ? { version } : { } })
|
||||||
const data = toCamel (res.data as any, { deep: true }) as WikiPage
|
const data = toCamel (res.data as any, { deep: true }) as WikiPage
|
||||||
setWikiPage (data)
|
setWikiPage (data)
|
||||||
WikiIdBus.set (data.id)
|
WikiIdBus.set (data.id)
|
||||||
@@ -51,6 +60,36 @@ export default () => {
|
|||||||
}
|
}
|
||||||
}) ()
|
}) ()
|
||||||
|
|
||||||
|
void (async () => {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const res = await axios.get (
|
||||||
|
`${ API_BASE_URL }/posts?${ new URLSearchParams ({ tags: title,
|
||||||
|
limit: '8' }) }`)
|
||||||
|
const data = toCamel (res.data as any,
|
||||||
|
{ deep: true }) as { posts: Post[]
|
||||||
|
nextCursor: string }
|
||||||
|
setPosts (data.posts)
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
setPosts ([])
|
||||||
|
}
|
||||||
|
}) ()
|
||||||
|
|
||||||
|
void (async () => {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const res = await axios.get (
|
||||||
|
`${ API_BASE_URL }/tags/name/${ encodeURIComponent (title) }`)
|
||||||
|
setTag (toCamel (res.data as any, { deep: true }) as Tag)
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
setTag (defaultTag)
|
||||||
|
}
|
||||||
|
}) ()
|
||||||
|
|
||||||
return () => WikiIdBus.set (null)
|
return () => WikiIdBus.set (null)
|
||||||
}, [title, location.search])
|
}, [title, location.search])
|
||||||
|
|
||||||
@@ -59,6 +98,7 @@ export default () => {
|
|||||||
<Helmet>
|
<Helmet>
|
||||||
<title>{`${ title } Wiki | ${ SITE_TITLE }`}</title>
|
<title>{`${ title } Wiki | ${ SITE_TITLE }`}</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
|
|
||||||
{(wikiPage && version) && (
|
{(wikiPage && version) && (
|
||||||
<div className="text-sm flex gap-3 items-center justify-center border border-gray-700 rounded px-2 py-1 mb-4">
|
<div className="text-sm flex gap-3 items-center justify-center border border-gray-700 rounded px-2 py-1 mb-4">
|
||||||
{wikiPage.pred ? (
|
{wikiPage.pred ? (
|
||||||
@@ -73,11 +113,21 @@ export default () => {
|
|||||||
新 >
|
新 >
|
||||||
</Link>) : <>(最新)</>}
|
</Link>) : <>(最新)</>}
|
||||||
</div>)}
|
</div>)}
|
||||||
<PageTitle>{title}</PageTitle>
|
|
||||||
|
<PageTitle>
|
||||||
|
<TagLink tag={tag} withWiki={false} withCount={false} />
|
||||||
|
</PageTitle>
|
||||||
<div className="prose mx-auto p-4">
|
<div className="prose mx-auto p-4">
|
||||||
{wikiPage === undefined
|
{wikiPage === undefined
|
||||||
? 'Loading...'
|
? 'Loading...'
|
||||||
: <WikiBody body={wikiPage?.body || `このページは存在しません。[新規作成してください](/wiki/new?title=${ title })。`} />}
|
: <WikiBody body={wikiPage?.body || `このページは存在しません。[新規作成してください](/wiki/new?title=${ encodeURIComponent (title) })。`} />}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{posts.length > 0 && (
|
||||||
|
<TabGroup>
|
||||||
|
<Tab name="広場">
|
||||||
|
<PostList posts={posts} />
|
||||||
|
</Tab>
|
||||||
|
</TabGroup>)}
|
||||||
</MainArea>)
|
</MainArea>)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user