From a751add4156059ba78c9be8bda02ecf8c6f1029d Mon Sep 17 00:00:00 2001 From: miteruzo Date: Fri, 6 Feb 2026 02:26:53 +0900 Subject: [PATCH] #140 --- frontend/src/lib/api.ts | 8 ++- frontend/src/lib/queryKeys.ts | 4 ++ frontend/src/pages/wiki/WikiDetailPage.tsx | 65 ++++++++-------------- 3 files changed, 34 insertions(+), 43 deletions(-) diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 0911a6e..8227c51 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -3,10 +3,10 @@ import toCamel from 'camelcase-keys' import { API_BASE_URL } from '@/config' -import type { AxiosError } from 'axios' +import type { AxiosError, AxiosRequestConfig } from 'axios' type Opt = { - params?: Record + params?: AxiosRequestConfig['params'] headers?: Record responseType?: 'blob' } @@ -26,6 +26,8 @@ const apiP = async ( opt?: Opt, ): Promise => { const res = await client[method] (path, body ?? { }, withUserCode (opt)) + if (opt?.responseType === 'blob') + return res.data as T return toCamel (res.data as any, { deep: true }) as T } @@ -35,6 +37,8 @@ export const apiGet = async ( opt?: Opt, ): Promise => { const res = await client.get (path, withUserCode (opt)) + if (opt?.responseType === 'blob') + return res.data as T return toCamel (res.data as any, { deep: true }) as T } diff --git a/frontend/src/lib/queryKeys.ts b/frontend/src/lib/queryKeys.ts index b6723b6..a6816be 100644 --- a/frontend/src/lib/queryKeys.ts +++ b/frontend/src/lib/queryKeys.ts @@ -7,6 +7,10 @@ export const postsKeys = { changes: (p: { id?: string; page: number; limit: number }) => ['posts', 'changes', p] as const } +export const tagsKeys = { + root: ['tags'] as const, + show: (name: string) => ['tags', name] as const } + export const wikiKeys = { root: ['wiki'] as const, index: (p: { title: string }) => ['wiki', 'index', p] as const, diff --git a/frontend/src/pages/wiki/WikiDetailPage.tsx b/frontend/src/pages/wiki/WikiDetailPage.tsx index 999a91f..08c4a5f 100644 --- a/frontend/src/pages/wiki/WikiDetailPage.tsx +++ b/frontend/src/pages/wiki/WikiDetailPage.tsx @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query' -import { useEffect, useState } from 'react' +import { useEffect, useMemo } from 'react' import { Helmet } from 'react-helmet-async' import { useLocation, useNavigate, useParams } from 'react-router-dom' @@ -13,11 +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 { postsKeys, tagsKeys, wikiKeys } from '@/lib/queryKeys' import { fetchTagByName } from '@/lib/tags' import { fetchWikiPage, fetchWikiPageByTitle } from '@/lib/wiki' -import type { Post, Tag } from '@/types' +import type { Tag } from '@/types' export default () => { @@ -27,10 +27,7 @@ export default () => { const location = useLocation () const navigate = useNavigate () - const defaultTag = { name: title, category: 'general' } as Tag - - const [posts, setPosts] = useState ([]) - const [tag, setTag] = useState (defaultTag) + const defaultTag = useMemo (() => ({ name: title, category: 'general' } as Tag), [title]) const query = new URLSearchParams (location.search) const version = query.get ('version') @@ -40,6 +37,19 @@ export default () => { queryKey: wikiKeys.show (title ?? '', version ? { version } : { }), queryFn: () => fetchWikiPageByTitle (title ?? '', version ? { version } : { }) }) + const effectiveTitle = wikiPage?.title ?? title + + const { data: tag } = useQuery ({ + enabled: Boolean (effectiveTitle), + queryKey: tagsKeys.show (effectiveTitle), + queryFn: () => fetchTagByName (effectiveTitle) }) + + const { data } = useQuery ({ + enabled: Boolean (effectiveTitle) && !(version), + queryKey: postsKeys.index ({ tags: effectiveTitle, match: 'all', page: 1, limit: 8 }), + queryFn: () => fetchPosts ({ tags: effectiveTitle, match: 'all', page: 1, limit: 8 }) }) + const posts = data?.posts || [] + useEffect (() => { if (!(wikiPage)) return @@ -53,48 +63,20 @@ export default () => { }, [wikiPage, title, navigate]) useEffect (() => { - if (/^\d+$/.test (title)) - { - void (async () => { - try - { - const data = await fetchWikiPage (title, { }) - navigate (`/wiki/${ encodeURIComponent(data.title) }`, { replace: true }) - } - catch - { - ; - } - }) () - - return - } + if (!(/^\d+$/.test (title))) + return - setPosts ([]) void (async () => { try { - const data = await fetchPosts ({ tags: title, match: 'all', limit: 8 }) - setPosts (data.posts) + const data = await fetchWikiPage (title, { }) + navigate (`/wiki/${ encodeURIComponent(data.title) }`, { replace: true }) } catch { ; } }) () - - void (async () => { - try - { - setTag (await fetchTagByName (title)) - } - catch - { - setTag (defaultTag) - } - }) () - - return () => WikiIdBus.set (null) }, [title, version]) return ( @@ -105,7 +87,8 @@ export default () => { {(wikiPage && version) && ( -
+
{wikiPage.pred ? ( < 古 @@ -120,7 +103,7 @@ export default () => {
)} -