From d120df3493969daa1e7db87660b51c8f0df926c5 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Wed, 4 Feb 2026 01:44:21 +0900 Subject: [PATCH] #140 --- frontend/src/lib/prefetchers.ts | 24 ++++++++++++++-- frontend/src/lib/queryKeys.ts | 2 +- frontend/src/pages/wiki/WikiDetailPage.tsx | 33 +++++++++------------- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/frontend/src/lib/prefetchers.ts b/frontend/src/lib/prefetchers.ts index d2ca3ec..a91c46d 100644 --- a/frontend/src/lib/prefetchers.ts +++ b/frontend/src/lib/prefetchers.ts @@ -3,11 +3,12 @@ import { match } from 'path-to-regexp' import { fetchPost, fetchPosts, fetchPostChanges } from '@/lib/posts' import { postsKeys, wikiKeys } from '@/lib/queryKeys' -import { fetchWikiPages } from '@/lib/wiki' +import { fetchWikiPageByTitle, fetchWikiPages } from '@/lib/wiki' type Prefetcher = (qc: QueryClient, url: URL) => Promise const mPost = match<{ id: string }> ('/posts/:id') +const mWiki = match<{ title: string }> ('/wiki/:title') 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 tags = url.searchParams.get ('tags') ?? '' 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 }[] = [ { 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))), run: prefetchPostShow }, { 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 => { diff --git a/frontend/src/lib/queryKeys.ts b/frontend/src/lib/queryKeys.ts index d1b1f90..b6723b6 100644 --- a/frontend/src/lib/queryKeys.ts +++ b/frontend/src/lib/queryKeys.ts @@ -10,4 +10,4 @@ export const postsKeys = { export const wikiKeys = { root: ['wiki'] 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 } diff --git a/frontend/src/pages/wiki/WikiDetailPage.tsx b/frontend/src/pages/wiki/WikiDetailPage.tsx index fb17f51..b950cea 100644 --- a/frontend/src/pages/wiki/WikiDetailPage.tsx +++ b/frontend/src/pages/wiki/WikiDetailPage.tsx @@ -1,3 +1,4 @@ +import { useQuery } from '@tanstack/react-query' import { useEffect, useState } from 'react' import { Helmet } from 'react-helmet-async' import { useLocation, useNavigate, useParams } from 'react-router-dom' @@ -12,10 +13,11 @@ import MainArea from '@/components/layout/MainArea' import { SITE_TITLE } from '@/config' import { WikiIdBus } from '@/lib/eventBus/WikiIdBus' import { fetchPosts } from '@/lib/posts' +import { wikiKeys } from '@/lib/queryKeys' import { fetchTagByName } from '@/lib/tags' import { fetchWikiPage, fetchWikiPageByTitle } from '@/lib/wiki' -import type { Post, Tag, WikiPage } from '@/types' +import type { Post, Tag } from '@/types' export default () => { @@ -29,16 +31,25 @@ export default () => { const [posts, setPosts] = useState ([]) const [tag, setTag] = useState (defaultTag) - const [wikiPage, setWikiPage] = useState (undefined) const query = new URLSearchParams (location.search) 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 (() => { if (/^\d+$/.test (title)) { void (async () => { - setWikiPage (undefined) try { const data = await fetchWikiPage (title, { }) @@ -53,22 +64,6 @@ export default () => { 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 ([]) void (async () => { try