This commit is contained in:
@@ -3,11 +3,12 @@ import { match } from 'path-to-regexp'
|
|||||||
|
|
||||||
import { fetchPost, fetchPosts, fetchPostChanges } from '@/lib/posts'
|
import { fetchPost, fetchPosts, fetchPostChanges } from '@/lib/posts'
|
||||||
import { postsKeys, wikiKeys } from '@/lib/queryKeys'
|
import { postsKeys, wikiKeys } from '@/lib/queryKeys'
|
||||||
import { fetchWikiPages } from '@/lib/wiki'
|
import { fetchWikiPageByTitle, fetchWikiPages } from '@/lib/wiki'
|
||||||
|
|
||||||
type Prefetcher = (qc: QueryClient, url: URL) => Promise<void>
|
type Prefetcher = (qc: QueryClient, url: URL) => Promise<void>
|
||||||
|
|
||||||
const mPost = match<{ id: string }> ('/posts/:id')
|
const mPost = match<{ id: string }> ('/posts/:id')
|
||||||
|
const mWiki = match<{ title: string }> ('/wiki/:title')
|
||||||
|
|
||||||
|
|
||||||
const prefetchWikiPagesIndex: Prefetcher = async (qc, url) => {
|
const prefetchWikiPagesIndex: Prefetcher = async (qc, url) => {
|
||||||
@@ -18,6 +19,19 @@ const prefetchWikiPagesIndex: Prefetcher = async (qc, url) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const prefetchWikiPageShow: Prefetcher = async (qc, url) => {
|
||||||
|
const m = mWiki (url.pathname)
|
||||||
|
if (!(m))
|
||||||
|
return
|
||||||
|
|
||||||
|
const version = url.searchParams.get ('version')
|
||||||
|
const { title } = m.params
|
||||||
|
await qc.prefetchQuery ({
|
||||||
|
queryKey: wikiKeys.show (title, version ? { version } : { }),
|
||||||
|
queryFn: () => fetchWikiPageByTitle (title, version ? { version } : { }) })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const prefetchPostsIndex: Prefetcher = async (qc, url) => {
|
const prefetchPostsIndex: Prefetcher = async (qc, url) => {
|
||||||
const tags = url.searchParams.get ('tags') ?? ''
|
const tags = url.searchParams.get ('tags') ?? ''
|
||||||
const m = url.searchParams.get ('match') === 'any' ? 'any' : 'all'
|
const m = url.searchParams.get ('match') === 'any' ? 'any' : 'all'
|
||||||
@@ -53,11 +67,15 @@ const prefetchPostChanges: Prefetcher = async (qc, url) => {
|
|||||||
|
|
||||||
export const routePrefetchers: { test: (u: URL) => boolean; run: Prefetcher }[] = [
|
export const routePrefetchers: { test: (u: URL) => boolean; run: Prefetcher }[] = [
|
||||||
{ test: u => u.pathname === '/' || u.pathname === '/posts', run: prefetchPostsIndex },
|
{ test: u => u.pathname === '/' || u.pathname === '/posts', run: prefetchPostsIndex },
|
||||||
{ test: u => (['/posts/new', '/posts/changes'].includes(u.pathname)
|
{ test: u => (['/posts/new', '/posts/changes'].includes (u.pathname)
|
||||||
&& Boolean (mPost (u.pathname))),
|
&& Boolean (mPost (u.pathname))),
|
||||||
run: prefetchPostShow },
|
run: prefetchPostShow },
|
||||||
{ test: u => u.pathname === '/posts/changes', run: prefetchPostChanges },
|
{ test: u => u.pathname === '/posts/changes', run: prefetchPostChanges },
|
||||||
{ test: u => u.pathname === '/wiki', run: prefetchWikiPagesIndex }]
|
{ test: u => u.pathname === '/wiki', run: prefetchWikiPagesIndex },
|
||||||
|
{ test: u => (['/wiki/new', '/wiki/changes'].includes (u.pathname)
|
||||||
|
&& Boolean (mWiki (u.pathname))),
|
||||||
|
run: prefetchWikiPageShow },
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
export const prefetchForURL = async (qc: QueryClient, urlLike: string): Promise<void> => {
|
export const prefetchForURL = async (qc: QueryClient, urlLike: string): Promise<void> => {
|
||||||
|
|||||||
@@ -10,4 +10,4 @@ export const postsKeys = {
|
|||||||
export const wikiKeys = {
|
export const wikiKeys = {
|
||||||
root: ['wiki'] as const,
|
root: ['wiki'] as const,
|
||||||
index: (p: { title: string }) => ['wiki', 'index', p] as const,
|
index: (p: { title: string }) => ['wiki', 'index', p] as const,
|
||||||
show: (title: string, p: { version: string }) => ['wiki', title, p] as const }
|
show: (title: string, p: { version?: string }) => ['wiki', title, p] as const }
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
import { Helmet } from 'react-helmet-async'
|
||||||
import { useLocation, useNavigate, useParams } from 'react-router-dom'
|
import { useLocation, useNavigate, useParams } from 'react-router-dom'
|
||||||
@@ -12,10 +13,11 @@ import MainArea from '@/components/layout/MainArea'
|
|||||||
import { SITE_TITLE } from '@/config'
|
import { SITE_TITLE } from '@/config'
|
||||||
import { WikiIdBus } from '@/lib/eventBus/WikiIdBus'
|
import { WikiIdBus } from '@/lib/eventBus/WikiIdBus'
|
||||||
import { fetchPosts } from '@/lib/posts'
|
import { fetchPosts } from '@/lib/posts'
|
||||||
|
import { wikiKeys } from '@/lib/queryKeys'
|
||||||
import { fetchTagByName } from '@/lib/tags'
|
import { fetchTagByName } from '@/lib/tags'
|
||||||
import { fetchWikiPage, fetchWikiPageByTitle } from '@/lib/wiki'
|
import { fetchWikiPage, fetchWikiPageByTitle } from '@/lib/wiki'
|
||||||
|
|
||||||
import type { Post, Tag, WikiPage } from '@/types'
|
import type { Post, Tag } from '@/types'
|
||||||
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
@@ -29,16 +31,25 @@ export default () => {
|
|||||||
|
|
||||||
const [posts, setPosts] = useState<Post[]> ([])
|
const [posts, setPosts] = useState<Post[]> ([])
|
||||||
const [tag, setTag] = useState (defaultTag)
|
const [tag, setTag] = useState (defaultTag)
|
||||||
const [wikiPage, setWikiPage] = useState<WikiPage | null | undefined> (undefined)
|
|
||||||
|
|
||||||
const query = new URLSearchParams (location.search)
|
const query = new URLSearchParams (location.search)
|
||||||
const version = query.get ('version')
|
const version = query.get ('version')
|
||||||
|
|
||||||
|
const { data: wikiPage } = useQuery ({
|
||||||
|
enabled: Boolean (title) && !(/^\d+$/.test (title)),
|
||||||
|
queryKey: wikiKeys.show (title ?? '', version ? { version } : { }),
|
||||||
|
queryFn: () => fetchWikiPageByTitle (title ?? '', version ? { version } : { }) })
|
||||||
|
if (wikiPage)
|
||||||
|
{
|
||||||
|
if (wikiPage.title !== title)
|
||||||
|
navigate (`/wiki/${ encodeURIComponent(wikiPage.title) }`, { replace: true })
|
||||||
|
WikiIdBus.set (wikiPage.id)
|
||||||
|
}
|
||||||
|
|
||||||
useEffect (() => {
|
useEffect (() => {
|
||||||
if (/^\d+$/.test (title))
|
if (/^\d+$/.test (title))
|
||||||
{
|
{
|
||||||
void (async () => {
|
void (async () => {
|
||||||
setWikiPage (undefined)
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const data = await fetchWikiPage (title, { })
|
const data = await fetchWikiPage (title, { })
|
||||||
@@ -53,22 +64,6 @@ export default () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
void (async () => {
|
|
||||||
setWikiPage (undefined)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
const data = await fetchWikiPageByTitle (title, version ? { version } : { })
|
|
||||||
if (data.title !== title)
|
|
||||||
navigate (`/wiki/${ encodeURIComponent(data.title) }`, { replace: true })
|
|
||||||
setWikiPage (data)
|
|
||||||
WikiIdBus.set (data.id)
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
setWikiPage (null)
|
|
||||||
}
|
|
||||||
}) ()
|
|
||||||
|
|
||||||
setPosts ([])
|
setPosts ([])
|
||||||
void (async () => {
|
void (async () => {
|
||||||
try
|
try
|
||||||
|
|||||||
Reference in New Issue
Block a user