82 行
2.6 KiB
TypeScript
82 行
2.6 KiB
TypeScript
import { useQuery } from '@tanstack/react-query'
|
|
import { Helmet } from 'react-helmet-async'
|
|
import { useParams, useSearchParams } from 'react-router-dom'
|
|
|
|
import PrefetchLink from '@/components/PrefetchLink'
|
|
import PageTitle from '@/components/common/PageTitle'
|
|
import MainArea from '@/components/layout/MainArea'
|
|
import { SITE_TITLE } from '@/config'
|
|
import { getHelpDiff } from '@/lib/help'
|
|
import { helpKeys } from '@/lib/queryKeys'
|
|
import { cn } from '@/lib/utils'
|
|
import NotFound from '@/pages/NotFound'
|
|
|
|
import type { FC } from 'react'
|
|
|
|
const markers = { added: '+ ', removed: '- ', unchanged: ' ' }
|
|
|
|
|
|
const HelpDiffPage: FC = () => {
|
|
const { identifier = '' } = useParams ()
|
|
const [searchParams] = useSearchParams ()
|
|
const from = searchParams.get ('from') ?? ''
|
|
const to = searchParams.get ('to') ?? ''
|
|
const validParams = Boolean (identifier && from && to)
|
|
&& searchParams.getAll ('from').length === 1
|
|
&& searchParams.getAll ('to').length === 1
|
|
const { data: diff, isLoading, isError } = useQuery ({
|
|
enabled: validParams,
|
|
queryKey: helpKeys.diff (identifier, 'ja', from, to),
|
|
queryFn: () => getHelpDiff (identifier, 'ja', from, to),
|
|
staleTime: Infinity })
|
|
|
|
if (!(validParams) || isError || (!(isLoading) && diff == null))
|
|
return <NotFound/>
|
|
|
|
const title = `${ diff?.to.title ?? identifier } (${ from } → ${ to })`
|
|
const path = `/help/${ encodeURIComponent (identifier) }`
|
|
|
|
return (
|
|
<MainArea>
|
|
<Helmet>
|
|
<title>{`ヘルプ 差分: ${ title } | ${ SITE_TITLE }`}</title>
|
|
</Helmet>
|
|
<PageTitle>{title}</PageTitle>
|
|
|
|
{diff
|
|
? (
|
|
<>
|
|
<div className="flex flex-wrap items-center gap-3">
|
|
<PrefetchLink to={`${ path }?edition=${ encodeURIComponent (from) }`}>
|
|
{diff.from.title} ({from})
|
|
</PrefetchLink>
|
|
<span>→</span>
|
|
<PrefetchLink to={`${ path }?edition=${ encodeURIComponent (to) }`}>
|
|
{diff.to.title} ({to})
|
|
</PrefetchLink>
|
|
</div>
|
|
<pre className="mt-4 overflow-x-auto whitespace-pre">
|
|
<code>
|
|
{diff.lines.map ((line, index) => {
|
|
const colour = cn (
|
|
'block text-gray-900 dark:text-gray-100',
|
|
line.type === 'added' && 'bg-green-200 dark:bg-green-800',
|
|
line.type === 'added' && 'text-green-950 dark:text-green-50',
|
|
line.type === 'removed' && 'bg-red-200 dark:bg-red-800',
|
|
line.type === 'removed' && 'text-red-950 dark:text-red-50')
|
|
|
|
return (
|
|
<span key={index} className={colour}>
|
|
{markers[line.type]}{line.content.replace (/\r?\n$/, '')}
|
|
</span>)
|
|
})}
|
|
</code>
|
|
</pre>
|
|
</>)
|
|
: <div>Loading...</div>}
|
|
</MainArea>)
|
|
}
|
|
|
|
|
|
export default HelpDiffPage
|