62 行
2.2 KiB
TypeScript
62 行
2.2 KiB
TypeScript
import { useQuery } from '@tanstack/react-query'
|
|
import { useMemo } from 'react'
|
|
import ReactMarkdown from 'react-markdown'
|
|
import remarkGFM from 'remark-gfm'
|
|
|
|
import { useLocale } from '@/lib/useLocale'
|
|
import { useUITranslation } from '@/lib/useUITranslation'
|
|
import PrefetchLink from '@/components/PrefetchLink'
|
|
import { wikiKeys } from '@/lib/queryKeys'
|
|
import remarkWikiAutoLink from '@/lib/remark-wiki-autolink'
|
|
import { fetchWikiAutolinkCandidates } from '@/lib/wiki'
|
|
import { ainuMDXComponents, LocalisedDocument } from '@/mdx-components'
|
|
|
|
import type { FC } from 'react'
|
|
import type { Components } from 'react-markdown'
|
|
|
|
type Props = { title: string
|
|
body?: string
|
|
language?: string }
|
|
|
|
const mdComponents = { a: (({ href, children }) => (
|
|
['/', '.'].some (e => href?.startsWith (e))
|
|
? <PrefetchLink to={href!}>{children}</PrefetchLink>
|
|
: (
|
|
<a href={href}
|
|
target="_blank"
|
|
rel="noopener noreferrer">
|
|
{children}
|
|
</a>))) } as const satisfies Components
|
|
|
|
|
|
const WikiBody: FC<Props> = ({ title, body, language = 'und' }) => {
|
|
const { message } = useUITranslation ('wiki')
|
|
const locale = useLocale ()
|
|
const missingPage = message ('missingPage', {
|
|
url: `/wiki/new?title=${ encodeURIComponent (title) }` })
|
|
const contentLanguage = body ? language : missingPage.language
|
|
const matchLanguage = contentLanguage === 'und'
|
|
? 'ja' : (contentLanguage === 'ain-Kana' ? 'ain' : contentLanguage)
|
|
const { data } = useQuery ({
|
|
enabled: Boolean (body),
|
|
queryKey: wikiKeys.autolinkCandidates (matchLanguage, locale),
|
|
queryFn: () => fetchWikiAutolinkCandidates (matchLanguage, locale) })
|
|
|
|
const remarkPlugins = useMemo (
|
|
() => [() => remarkWikiAutoLink (data ?? [], matchLanguage, locale), remarkGFM],
|
|
[data, matchLanguage, locale])
|
|
const components = {
|
|
...((contentLanguage === 'ain' || contentLanguage === 'ain-Kana')
|
|
? ainuMDXComponents : { }),
|
|
...mdComponents }
|
|
|
|
return (
|
|
<LocalisedDocument language={contentLanguage}>
|
|
<ReactMarkdown components={components} remarkPlugins={remarkPlugins}>
|
|
{body || missingPage.text}
|
|
</ReactMarkdown>
|
|
</LocalisedDocument>)
|
|
}
|
|
|
|
export default WikiBody
|