From 666c21b82f01fc6ebfaaf15ccadfe92aed74c046 Mon Sep 17 00:00:00 2001 From: iFwu Date: Tue, 8 Oct 2024 12:36:38 +0800 Subject: [PATCH] feat: Add changelog component and styling - Install vite-plugin-markdown for parsing markdown files - Add Changelog component to WelcomeModal - Implement changelog-related styles in app.css - Update vite config to use markdown plugin - Declare .md module type in vite-env.d.ts - Minor code cleanup in WelcomeModal component --- CHANGELOG.md | 8 ++ package.json | 3 +- pnpm-lock.yaml | 131 ++++++++++++++++++++++++++++++++ src/app.css | 72 +++++++++++++++++- src/components/Changelog.tsx | 23 ++++++ src/components/WelcomeModal.tsx | 11 ++- src/vite-env.d.ts | 5 ++ vite.config.ts | 2 + 8 files changed, 247 insertions(+), 8 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 src/components/Changelog.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3d874f7 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +### 2024-10-08 +- 增加 更新日志 显示 + +### 2024-10-07 +- 优化 **OpenCV.js** 库加载、使用 `cdn.jsdmirror.com` 替换 `jsdelivr.net` +- **Pikafish** 使用 `xiangqiai.com` 的 wasm 版本 +- 优化黑棋子识别 +- 新增欢迎提示和加载界面 diff --git a/package.json b/package.json index 07834fc..2297d6a 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "@preact/preset-vite": "^2.9.1", "typescript": "^5.6.2", "vite": "^5.4.8", - "vite-plugin-cdn2": "^1.1.0" + "vite-plugin-cdn2": "^1.1.0", + "vite-plugin-markdown": "^2.2.0" }, "packageManager": "pnpm@9.12.0", "homepage": "https://ifwu.github.io/xiangqi-analysis/", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96fd1e4..7b3fa35 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,6 +30,9 @@ importers: vite-plugin-cdn2: specifier: ^1.1.0 version: 1.1.0(rollup@4.24.0) + vite-plugin-markdown: + specifier: ^2.2.0 + version: 2.2.0(vite@5.4.8) packages: @@ -473,6 +476,12 @@ packages: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + babel-plugin-transform-hook-names@1.0.2: resolution: {integrity: sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==} peerDependencies: @@ -518,22 +527,38 @@ packages: supports-color: optional: true + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + domhandler@5.0.3: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + domutils@3.1.0: resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} electron-to-chromium@1.5.31: resolution: {integrity: sha512-QcDoBbQeYt0+3CWcK/rEbuHvwpbT/8SV9T3OSgs6cX1FlcUAkgrkqbg9zLnDrMM/rLamzQwal4LYFCiWk861Tg==} + entities@2.1.0: + resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -551,9 +576,17 @@ packages: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + front-matter@4.0.2: + resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -575,12 +608,19 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + htmlparser2@6.1.0: + resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} + is-any-array@2.0.1: resolution: {integrity: sha512-UtilS7hLRu++wb/WBAw9bNuP1Eg04Ivn1vERJck8zJthEvXCBEBpGR/33u/xLKWEQf95803oalHrVDptcAvFdQ==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + jsesc@3.0.2: resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} engines: {node: '>=6'} @@ -594,6 +634,9 @@ packages: kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + linkify-it@3.0.3: + resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -601,6 +644,13 @@ packages: resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} engines: {node: '>=12'} + markdown-it@12.3.2: + resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} + hasBin: true + + mdurl@1.0.1: + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + ml-array-max@1.2.4: resolution: {integrity: sha512-BlEeg80jI0tW6WaPyGxf5Sa4sqvcyY6lbSn5Vcv44lp1I2GR6AWojfUvLnGTNsIXrZ8uqWmo8VcG1WpkI2ONMQ==} @@ -680,6 +730,9 @@ packages: resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} engines: {node: '>= 8'} + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + stack-trace@1.0.0-pre2: resolution: {integrity: sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==} engines: {node: '>=16'} @@ -697,6 +750,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + uc.micro@1.0.6: + resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + update-browserslist-db@1.1.1: resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true @@ -706,6 +762,11 @@ packages: vite-plugin-cdn2@1.1.0: resolution: {integrity: sha512-mqz9frTLpwT7XVuJppb/OmsEaJOxcY5Xt/+VOeewQAJTsl91TZe1ySv+YyoQbVn+BQbamNHZbUteIuoQzRFdpQ==} + vite-plugin-markdown@2.2.0: + resolution: {integrity: sha512-eH2tXMZcx3EHb5okd+/0VIyoR8Gp9pGe24UXitOOcGkzObbJ1vl48aGOAbakoT88FBdzC8MXNkMfBIB9VK0Ndg==} + peerDependencies: + vite: '>= 2.0.0' + vite@5.4.8: resolution: {integrity: sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -1112,6 +1173,12 @@ snapshots: dependencies: color-convert: 1.9.3 + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + babel-plugin-transform-hook-names@1.0.2(@babel/core@7.25.7): dependencies: '@babel/core': 7.25.7 @@ -1155,6 +1222,12 @@ snapshots: dependencies: ms: 2.1.3 + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + dom-serializer@2.0.0: dependencies: domelementtype: 2.3.0 @@ -1163,10 +1236,20 @@ snapshots: domelementtype@2.3.0: {} + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + domhandler@5.0.3: dependencies: domelementtype: 2.3.0 + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils@3.1.0: dependencies: dom-serializer: 2.0.0 @@ -1175,6 +1258,10 @@ snapshots: electron-to-chromium@1.5.31: {} + entities@2.1.0: {} + + entities@2.2.0: {} + entities@4.5.0: {} esbuild@0.21.5: @@ -1207,8 +1294,14 @@ snapshots: escape-string-regexp@1.0.5: {} + esprima@4.0.1: {} + estree-walker@2.0.2: {} + front-matter@4.0.2: + dependencies: + js-yaml: 3.14.1 + fsevents@2.3.3: optional: true @@ -1220,16 +1313,32 @@ snapshots: he@1.2.0: {} + htmlparser2@6.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 2.2.0 + is-any-array@2.0.1: {} js-tokens@4.0.0: {} + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + jsesc@3.0.2: {} json5@2.2.3: {} kolorist@1.8.0: {} + linkify-it@3.0.3: + dependencies: + uc.micro: 1.0.6 + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -1238,6 +1347,16 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + markdown-it@12.3.2: + dependencies: + argparse: 2.0.1 + entities: 2.1.0 + linkify-it: 3.0.3 + mdurl: 1.0.1 + uc.micro: 1.0.6 + + mdurl@1.0.1: {} + ml-array-max@1.2.4: dependencies: is-any-array: 2.0.1 @@ -1343,6 +1462,8 @@ snapshots: source-map@0.7.4: {} + sprintf-js@1.0.3: {} + stack-trace@1.0.0-pre2: {} supports-color@5.5.0: @@ -1353,6 +1474,8 @@ snapshots: typescript@5.6.2: {} + uc.micro@1.0.6: {} + update-browserslist-db@1.1.1(browserslist@4.24.0): dependencies: browserslist: 4.24.0 @@ -1371,6 +1494,14 @@ snapshots: - rollup - supports-color + vite-plugin-markdown@2.2.0(vite@5.4.8): + dependencies: + domhandler: 4.3.1 + front-matter: 4.0.2 + htmlparser2: 6.1.0 + markdown-it: 12.3.2 + vite: 5.4.8 + vite@5.4.8: dependencies: esbuild: 0.21.5 diff --git a/src/app.css b/src/app.css index df48629..c3cc48d 100644 --- a/src/app.css +++ b/src/app.css @@ -546,4 +546,74 @@ dialog button:hover { 100% { transform: rotate(360deg); } -} \ No newline at end of file +} + +/* 更新 changelog 相关样式 */ +.changelog { + text-align: center; + margin-bottom: 15px; + font-size: 0.9rem; /* 减小整体字体大小 */ +} + +.changelog-title { + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 10px; + font-size: 1rem; /* 保持标题字体大小不变 */ +} + +.changelog-arrow { + margin-right: 10px; + font-size: 0.8em; +} + +.changelog-content { + text-align: left; + padding-left: 10px; + padding-right: 10px; +} + +.changelog-content ul { + list-style-type: disc; /* 恢复项目符号 */ + padding-left: 20px; /* 为项目符号留出空间 */ + margin-top: 5px; + margin-bottom: 5px; +} + +.changelog-content li { + margin-bottom: 3px; + position: relative; +} + +.changelog-content li::before { + content: '•'; /* 自定义项目符号 */ + position: absolute; + left: -15px; + color: #3498db; /* 使用主题色 */ +} + +.changelog-content p { + margin-top: 5px; + margin-bottom: 5px; +} + +.changelog-content h1, +.changelog-content h2, +.changelog-content h3, +.changelog-content h4, +.changelog-content h5, +.changelog-content h6 { + margin-top: 10px; + margin-bottom: 5px; + color: #2c3e50; /* 使用深色以增加对比度 */ +} + +/* 可以根据需要调整不同级别标题的大小 */ +.changelog-content h1 { font-size: 1.2rem; } +.changelog-content h2 { font-size: 1.1rem; } +.changelog-content h3 { font-size: 1rem; } +.changelog-content h4, +.changelog-content h5, +.changelog-content h6 { font-size: 0.9rem; } \ No newline at end of file diff --git a/src/components/Changelog.tsx b/src/components/Changelog.tsx new file mode 100644 index 0000000..2d00083 --- /dev/null +++ b/src/components/Changelog.tsx @@ -0,0 +1,23 @@ +import { FunctionComponent } from 'preact'; +import { useState } from 'preact/hooks'; +import { html } from '../../CHANGELOG.md'; + +export const Changelog: FunctionComponent = () => { + const [isExpanded, setIsExpanded] = useState(false); + + const toggleExpand = () => { + setIsExpanded(!isExpanded); + }; + + return ( +
+

+ {isExpanded ? '▼' : '▶'} + 更新日志 +

+ {isExpanded && ( +
+ )} +
+ ); +}; \ No newline at end of file diff --git a/src/components/WelcomeModal.tsx b/src/components/WelcomeModal.tsx index 227d72a..bafbc06 100644 --- a/src/components/WelcomeModal.tsx +++ b/src/components/WelcomeModal.tsx @@ -1,4 +1,5 @@ import { useState, useEffect } from 'preact/hooks'; +import { Changelog } from './Changelog'; // 使用环境变量作为版本号 const APP_VERSION = import.meta.env.VITE_GIT_COMMIT_HASH || 'development'; @@ -8,10 +9,8 @@ export function WelcomeModal() { useEffect(() => { const lastSeenVersion = localStorage.getItem('lastSeenVersion'); - const skipFutureModals = localStorage.getItem('skipFutureModals') === 'true'; - console.log('lastSeenVersion', lastSeenVersion); - console.log('APP_VERSION', APP_VERSION); - console.log('skipFutureModals', skipFutureModals); + const skipFutureModals = + localStorage.getItem('skipFutureModals') === 'true'; if (!skipFutureModals || lastSeenVersion !== APP_VERSION) { setIsOpen(true); @@ -24,7 +23,6 @@ export function WelcomeModal() { if (skip) { localStorage.setItem('skipFutureModals', 'true'); } else { - // 如果用户点击"我知道了",移除 skipFutureModals 标志 localStorage.removeItem('skipFutureModals'); } }; @@ -37,8 +35,9 @@ export function WelcomeModal() {

欢迎使用

该应用正在开发完善中

-

目前在 JJ象棋残局截图上进行了测试

+

目前在 JJ象棋 残局截图上进行了测试

请注意:需要在设置中关闭行棋提示

+