From 1f198db16d362b0c639e7c74ddaf00fe37929f92 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Sun, 3 Aug 2025 08:09:46 +0900 Subject: [PATCH 01/43] #89 --- frontend/src/components/WikiBody.tsx | 69 +++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/WikiBody.tsx b/frontend/src/components/WikiBody.tsx index 30727c7..06bc39e 100644 --- a/frontend/src/components/WikiBody.tsx +++ b/frontend/src/components/WikiBody.tsx @@ -1,14 +1,69 @@ +import axios from 'axios' +import toCamel from 'camelcase-keys' +import { useEffect, useState } from 'react' import ReactMarkdown from 'react-markdown' import { Link } from 'react-router-dom' +import { API_BASE_URL } from '@/config' + +import type { WikiPage } from '@/types' + type Props = { title: string body?: string } -export default ({ title, body }: Props) => ( - (['/', '.'].some (e => href?.startsWith (e)) - ? {children} - : {children})) }}> - {body || `このページは存在しません。[新規作成してください](/wiki/new?title=${ encodeURIComponent (title) })。`} - ) +export default ({ title, body }: Props) => { + const [pageNames, setPageNames] = useState ([]) + const [realBody, setRealBody] = useState ('') + + useEffect (() => { + const matchIndices = (target: string, keyword: string) => { + const indices: number[] = [] + let pos = 0 + + while (true) + { + const idx = target.indexOf (keyword, pos) + if (idx < 0) + break + indices.push (idx) + pos = idx + keyword.length + } + + return indices + } + + void (async () => { + try + { + const res = await axios.get (`${ API_BASE_URL }/wiki`) + const data = toCamel (res.data as any, { deep: true }) as WikiPage[] + setPageNames (data.map (page => page.title).sort ((a, b) => b.length - a.length)) + } + catch + { + setPageNames ([]) + } + }) () + + const linkIndices: [string, [number, number]][] = [] + pageNames.forEach (name => { + matchIndices (body ?? '', name).map (idx => [idx, idx + name.length]).forEach (([start, end]) => { + if (linkIndices.every (([, [st, ed]]) => (start < st || ed <= start) && (end < st || ed <= end))) + linkIndices.push ([name, [start, end]]) + }) + }) + linkIndices.sort (([, [a]], [, [b]]) => b - a) + linkIndices.forEach (([name, [start, end]]) => { + setRealBody (prev => `${ prev.slice (0, start) }[${ name }](/wiki/${ encodeURIComponent (name) })${ prev.slice (end) }`) + }) + }, []) + + return ( + (['/', '.'].some (e => href?.startsWith (e)) + ? {children} + : {children})) }}> + {realBody || `このページは存在しません。[新規作成してください](/wiki/new?title=${ encodeURIComponent (title) })。`} + ) +} From 419f46dfdaeeb94839c6249a31d206c6277d2d96 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Sun, 3 Aug 2025 15:49:56 +0900 Subject: [PATCH 02/43] #89 --- frontend/src/components/WikiBody.tsx | 67 +++++++++++++++++----------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/WikiBody.tsx b/frontend/src/components/WikiBody.tsx index 06bc39e..e3f2fdb 100644 --- a/frontend/src/components/WikiBody.tsx +++ b/frontend/src/components/WikiBody.tsx @@ -17,21 +17,8 @@ export default ({ title, body }: Props) => { const [realBody, setRealBody] = useState ('') useEffect (() => { - const matchIndices = (target: string, keyword: string) => { - const indices: number[] = [] - let pos = 0 - - while (true) - { - const idx = target.indexOf (keyword, pos) - if (idx < 0) - break - indices.push (idx) - pos = idx + keyword.length - } - - return indices - } + if (!(body)) + return void (async () => { try @@ -45,19 +32,47 @@ export default ({ title, body }: Props) => { setPageNames ([]) } }) () + }, []) + + useEffect (() => { + if (!(body)) + return + + const matchIndices = (target: string, keyword: string) => { + const indices: number[] = [] + let pos = 0 + let idx + while ((idx = target.indexOf (keyword, pos)) >= 0) + { + indices.push (idx) + pos = idx + keyword.length + } - const linkIndices: [string, [number, number]][] = [] - pageNames.forEach (name => { - matchIndices (body ?? '', name).map (idx => [idx, idx + name.length]).forEach (([start, end]) => { - if (linkIndices.every (([, [st, ed]]) => (start < st || ed <= start) && (end < st || ed <= end))) - linkIndices.push ([name, [start, end]]) + return indices + } + + const linkIndices = (text: string, names: string[]): [string, [number, number]][] => { + const result: [string, [number, number]][] = [] + + names.forEach (name => { + matchIndices (text, name).forEach (idx => { + const start = idx + const end = idx + name.length + const overlaps = result.some (([, [st, ed]]) => start < ed && end > st) + if (!(overlaps)) + result.push ([name, [start, end]]) + }) }) - }) - linkIndices.sort (([, [a]], [, [b]]) => b - a) - linkIndices.forEach (([name, [start, end]]) => { - setRealBody (prev => `${ prev.slice (0, start) }[${ name }](/wiki/${ encodeURIComponent (name) })${ prev.slice (end) }`) - }) - }, []) + + return result.sort (([, [a]], [, [b]]) => b - a) + } + + setRealBody ( + linkIndices (body, pageNames).reduce ((acc, [name, [start, end]]) => ( + acc.slice (0, start) + + `[${ name }](/wiki/${ encodeURIComponent (name) })` + + acc.slice (end)), body)) + }, [pageNames]) return ( Date: Sun, 3 Aug 2025 16:01:08 +0900 Subject: [PATCH 03/43] #89 --- frontend/src/components/WikiBody.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/WikiBody.tsx b/frontend/src/components/WikiBody.tsx index e3f2fdb..f127cc6 100644 --- a/frontend/src/components/WikiBody.tsx +++ b/frontend/src/components/WikiBody.tsx @@ -72,7 +72,7 @@ export default ({ title, body }: Props) => { acc.slice (0, start) + `[${ name }](/wiki/${ encodeURIComponent (name) })` + acc.slice (end)), body)) - }, [pageNames]) + }, [body, pageNames]) return ( Date: Sun, 3 Aug 2025 16:25:22 +0900 Subject: [PATCH 04/43] #89 --- frontend/src/components/WikiBody.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/components/WikiBody.tsx b/frontend/src/components/WikiBody.tsx index f127cc6..187b52e 100644 --- a/frontend/src/components/WikiBody.tsx +++ b/frontend/src/components/WikiBody.tsx @@ -34,6 +34,10 @@ export default ({ title, body }: Props) => { }) () }, []) + useEffect (() => { + setRealBody ('') + }, [body]) + useEffect (() => { if (!(body)) return From cc6d50cf173a1865309f092963e3995dae814b64 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Sun, 3 Aug 2025 19:08:25 +0900 Subject: [PATCH 05/43] #89 --- frontend/src/components/WikiBody.tsx | 23 ++++++++++++++++++---- frontend/src/pages/posts/PostListPage.tsx | 2 +- frontend/src/pages/wiki/WikiDetailPage.tsx | 5 +++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/WikiBody.tsx b/frontend/src/components/WikiBody.tsx index e3f2fdb..851c427 100644 --- a/frontend/src/components/WikiBody.tsx +++ b/frontend/src/components/WikiBody.tsx @@ -4,13 +4,31 @@ import { useEffect, useState } from 'react' import ReactMarkdown from 'react-markdown' import { Link } from 'react-router-dom' +import SectionTitle from '@/components/common/SectionTitle' +import SubsectionTitle from '@/components/common/SubsectionTitle' import { API_BASE_URL } from '@/config' +import type { Components } from 'react-markdown' + import type { WikiPage } from '@/types' type Props = { title: string body?: string } +const mdComponents = { h1: ({ children }) => {children}, + h2: ({ children }) => {children}, + ol: ({ children }) =>
    {children}
, + ul: ({ children }) =>
    {children}
, + a: (({ href, children }) => ( + ['/', '.'].some (e => href?.startsWith (e)) + ? {children} + : ( + + {children} + ))) } as const satisfies Components + export default ({ title, body }: Props) => { const [pageNames, setPageNames] = useState ([]) @@ -75,10 +93,7 @@ export default ({ title, body }: Props) => { }, [pageNames]) return ( - (['/', '.'].some (e => href?.startsWith (e)) - ? {children} - : {children})) }}> + {realBody || `このページは存在しません。[新規作成してください](/wiki/new?title=${ encodeURIComponent (title) })。`} ) } diff --git a/frontend/src/pages/posts/PostListPage.tsx b/frontend/src/pages/posts/PostListPage.tsx index 95003b5..f1cdbed 100644 --- a/frontend/src/pages/posts/PostListPage.tsx +++ b/frontend/src/pages/posts/PostListPage.tsx @@ -131,7 +131,7 @@ export default () => { {tags.length === 1 && ( - +
Wiki を見る diff --git a/frontend/src/pages/wiki/WikiDetailPage.tsx b/frontend/src/pages/wiki/WikiDetailPage.tsx index be69f59..dbf1e5d 100644 --- a/frontend/src/pages/wiki/WikiDetailPage.tsx +++ b/frontend/src/pages/wiki/WikiDetailPage.tsx @@ -60,6 +60,7 @@ export default () => { } }) () + setPosts ([]) void (async () => { try { @@ -73,7 +74,7 @@ export default () => { } catch { - setPosts ([]) + ; } }) () @@ -123,7 +124,7 @@ export default () => {
{wikiPage === undefined ? 'Loading...' - : } + : }
{(!(version) && posts.length > 0) && ( From 1c10ac5d06d8c926c1cf601637d23a36e6dddf97 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Wed, 20 Aug 2025 06:20:33 +0900 Subject: [PATCH 06/43] #94 --- frontend/src/pages/wiki/WikiDetailPage.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/pages/wiki/WikiDetailPage.tsx b/frontend/src/pages/wiki/WikiDetailPage.tsx index dbf1e5d..d4f013f 100644 --- a/frontend/src/pages/wiki/WikiDetailPage.tsx +++ b/frontend/src/pages/wiki/WikiDetailPage.tsx @@ -98,6 +98,7 @@ export default () => { {`${ title } Wiki | ${ SITE_TITLE }`} + {!(wikiPage?.body) && } {(wikiPage && version) && ( From 7a3b2b165b456d24c47b53771c8cfd4ea0a9771c Mon Sep 17 00:00:00 2001 From: miteruzo Date: Thu, 21 Aug 2025 05:40:03 +0900 Subject: [PATCH 07/43] #89 --- frontend/package-lock.json | 294 +++++++++++++++++++++++++++ frontend/package.json | 1 + frontend/src/components/WikiBody.tsx | 3 +- 3 files changed, 297 insertions(+), 1 deletion(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 417dc54..06b8d4c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -25,6 +25,7 @@ "react-markdown": "^10.1.0", "react-markdown-editor-lite": "^1.3.4", "react-router-dom": "^6.30.0", + "remark-gfm": "^4.0.1", "tailwind-merge": "^3.3.0" }, "devDependencies": { @@ -4261,6 +4262,16 @@ "markdown-it": "bin/markdown-it.mjs" } }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -4270,6 +4281,34 @@ "node": ">= 0.4" } }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mdast-util-from-markdown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", @@ -4294,6 +4333,107 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-mdx-expression": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", @@ -4508,6 +4648,127 @@ "micromark-util-types": "^2.0.0" } }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", @@ -5674,6 +5935,24 @@ "node": ">=8.10.0" } }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-parse": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", @@ -5707,6 +5986,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", diff --git a/frontend/package.json b/frontend/package.json index 7986d56..76b5bba 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -27,6 +27,7 @@ "react-markdown": "^10.1.0", "react-markdown-editor-lite": "^1.3.4", "react-router-dom": "^6.30.0", + "remark-gfm": "^4.0.1", "tailwind-merge": "^3.3.0" }, "devDependencies": { diff --git a/frontend/src/components/WikiBody.tsx b/frontend/src/components/WikiBody.tsx index e041398..e19507a 100644 --- a/frontend/src/components/WikiBody.tsx +++ b/frontend/src/components/WikiBody.tsx @@ -3,6 +3,7 @@ import toCamel from 'camelcase-keys' import { useEffect, useState } from 'react' import ReactMarkdown from 'react-markdown' import { Link } from 'react-router-dom' +import remarkGFM from 'remark-gfm' import SectionTitle from '@/components/common/SectionTitle' import SubsectionTitle from '@/components/common/SubsectionTitle' @@ -97,7 +98,7 @@ export default ({ title, body }: Props) => { }, [body, pageNames]) return ( - + {realBody || `このページは存在しません。[新規作成してください](/wiki/new?title=${ encodeURIComponent (title) })。`} ) } From d026e9c270a63fe35fa0e905636cde10b6f91706 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Thu, 21 Aug 2025 05:43:48 +0900 Subject: [PATCH 08/43] =?UTF-8?q?#89=20=E8=AA=A4=E5=AD=97=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/WikiBody.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/WikiBody.tsx b/frontend/src/components/WikiBody.tsx index e19507a..62ffbc3 100644 --- a/frontend/src/components/WikiBody.tsx +++ b/frontend/src/components/WikiBody.tsx @@ -98,7 +98,7 @@ export default ({ title, body }: Props) => { }, [body, pageNames]) return ( - + {realBody || `このページは存在しません。[新規作成してください](/wiki/new?title=${ encodeURIComponent (title) })。`} ) } From e79688783ee8f11417ba3caf746e716d04655563 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Sat, 23 Aug 2025 18:01:23 +0900 Subject: [PATCH 09/43] #49 --- frontend/src/App.tsx | 34 +++---- frontend/src/components/ErrorScreen.tsx | 4 +- frontend/src/components/MenuSeparator.tsx | 2 +- frontend/src/components/NicoViewer.tsx | 2 +- frontend/src/components/PostEditForm.tsx | 4 +- frontend/src/components/TagDetailSidebar.tsx | 4 +- frontend/src/components/TagSearch.tsx | 4 +- frontend/src/components/TagSidebar.tsx | 4 +- frontend/src/components/TopNav.tsx | 10 +- frontend/src/components/TopNavUser.tsx | 2 +- frontend/src/components/common/Label.tsx | 2 +- frontend/src/components/common/TextArea.tsx | 2 +- .../src/components/users/InheritDialogue.tsx | 2 +- frontend/src/main.tsx | 2 +- frontend/src/pages/Forbidden.tsx | 2 +- frontend/src/pages/NotFound.tsx | 2 +- frontend/src/pages/ServiceUnavailable.tsx | 2 +- frontend/src/pages/posts/PostDetailPage.tsx | 16 +-- frontend/src/pages/posts/PostListPage.tsx | 6 +- frontend/src/pages/posts/PostNewPage.tsx | 12 +-- frontend/src/pages/tags/NicoTagListPage.tsx | 6 +- frontend/src/pages/users/SettingPage.tsx | 8 +- frontend/src/pages/wiki/WikiDetailPage.tsx | 8 +- frontend/src/pages/wiki/WikiDiffPage.tsx | 2 +- frontend/src/pages/wiki/WikiEditPage.tsx | 6 +- frontend/src/pages/wiki/WikiHistoryPage.tsx | 98 +++++++++---------- frontend/src/pages/wiki/WikiNewPage.tsx | 6 +- frontend/src/router.tsx | 5 - 28 files changed, 126 insertions(+), 131 deletions(-) delete mode 100644 frontend/src/router.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index d54981b..c402103 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -65,30 +65,30 @@ export default () => { switch (status) { case 503: - return + return } return (
- + - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + }/> + }/> + }/> + }/> + }/> + }/> + }/> + }/> + }/> + }/> + }/> + }/> + }/> + }/>
- +
) } diff --git a/frontend/src/components/ErrorScreen.tsx b/frontend/src/components/ErrorScreen.tsx index 651a81b..1398645 100644 --- a/frontend/src/components/ErrorScreen.tsx +++ b/frontend/src/components/ErrorScreen.tsx @@ -39,7 +39,7 @@ export default ({ status }: Props) => { return ( - + {title} | {SITE_TITLE}

{leftMsg}

- 逃げたギター + 逃げたギター

{rightMsg}

{message}

diff --git a/frontend/src/components/MenuSeparator.tsx b/frontend/src/components/MenuSeparator.tsx index 43b94a7..a482ae3 100644 --- a/frontend/src/components/MenuSeparator.tsx +++ b/frontend/src/components/MenuSeparator.tsx @@ -2,5 +2,5 @@ export default () => ( <> |
+ border-t border-black dark:border-white"/> ) diff --git a/frontend/src/components/NicoViewer.tsx b/frontend/src/components/NicoViewer.tsx index 71314f5..784ded5 100644 --- a/frontend/src/components/NicoViewer.tsx +++ b/frontend/src/components/NicoViewer.tsx @@ -107,5 +107,5 @@ export default (props: Props) => { height={height} style={margedStyle} allowFullScreen - allow="autoplay" />) + allow="autoplay"/>) } diff --git a/frontend/src/components/PostEditForm.tsx b/frontend/src/components/PostEditForm.tsx index b9a7adb..50d474a 100644 --- a/frontend/src/components/PostEditForm.tsx +++ b/frontend/src/components/PostEditForm.tsx @@ -39,14 +39,14 @@ export default ({ post, onSave }: Props) => { setTitle (e.target.value)} /> + onChange={e => setTitle (e.target.value)}/>
{/* タグ */}