From e1d44586b94cb712292c7ec56a123b445130c215 Mon Sep 17 00:00:00 2001 From: cdn0x12 Date: Mon, 3 Feb 2025 20:58:21 +0800 Subject: [PATCH] feat: contents integration (artalk) + cleanup closes #8 --- package.json | 5 +- pnpm-lock.yaml | 254 +++++++++++++++++--------------- src/components/Comments.tsx | 71 +++++++++ src/components/UpdateDetail.tsx | 3 + src/pages/UpdateDetailPage.tsx | 16 -- src/utils/updates.ts | 5 - 6 files changed, 210 insertions(+), 144 deletions(-) create mode 100644 src/components/Comments.tsx diff --git a/package.json b/package.json index b3e95df..5bc54fc 100644 --- a/package.json +++ b/package.json @@ -13,18 +13,19 @@ "@ant-design/icons": "^5.6.0", "@tanstack/react-query": "^5.66.0", "antd": "^5.23.3", + "artalk": "^2.9.1", "clsx": "^2.1.1", "feed": "^4.2.2", "i18next": "^23.16.8", "i18next-browser-languagedetector": "^7.2.2", "lucide-react": "^0.344.0", - "marked": "^12.0.2", + "marked": "^15.0.6", "react": "^18.3.1", "react-dom": "^18.3.1", "react-helmet-async": "^2.0.5", "react-i18next": "^14.1.3", "react-icons": "^5.4.0", - "react-router-dom": "^6.28.2" + "react-router-dom": "^6.29.0" }, "devDependencies": { "@eslint/js": "^9.19.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fe57547..140910a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: antd: specifier: ^5.23.3 version: 5.23.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + artalk: + specifier: ^2.9.1 + version: 2.9.1(marked@15.0.6) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -33,8 +36,8 @@ importers: specifier: ^0.344.0 version: 0.344.0(react@18.3.1) marked: - specifier: ^12.0.2 - version: 12.0.2 + specifier: ^15.0.6 + version: 15.0.6 react: specifier: ^18.3.1 version: 18.3.1 @@ -51,8 +54,8 @@ importers: specifier: ^5.4.0 version: 5.4.0(react@18.3.1) react-router-dom: - specifier: ^6.28.2 - version: 6.28.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^6.29.0 + version: 6.29.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@eslint/js': specifier: ^9.19.0 @@ -543,8 +546,8 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.19.1': - resolution: {integrity: sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==} + '@eslint/config-array@0.19.2': + resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/core@0.10.0': @@ -559,8 +562,8 @@ packages: resolution: {integrity: sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/object-schema@2.1.5': - resolution: {integrity: sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==} + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/plugin-kit@0.2.5': @@ -680,102 +683,102 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - '@remix-run/router@1.21.1': - resolution: {integrity: sha512-KeBYSwohb8g4/wCcnksvKTYlg69O62sQeLynn2YE+5z7JWEj95if27kclW9QqbrlsQ2DINI8fjbV3zyuKfwjKg==} + '@remix-run/router@1.22.0': + resolution: {integrity: sha512-MBOl8MeOzpK0HQQQshKB7pABXbmyHizdTpqnrIseTbsv0nAepwC2ENZa1aaBExNQcpLoXmWthhak8SABLzvGPw==} engines: {node: '>=14.0.0'} - '@rollup/rollup-android-arm-eabi@4.32.1': - resolution: {integrity: sha512-/pqA4DmqyCm8u5YIDzIdlLcEmuvxb0v8fZdFhVMszSpDTgbQKdw3/mB3eMUHIbubtJ6F9j+LtmyCnHTEqIHyzA==} + '@rollup/rollup-android-arm-eabi@4.34.1': + resolution: {integrity: sha512-kwctwVlswSEsr4ljpmxKrRKp1eG1v2NAhlzFzDf1x1OdYaMjBYjDCbHkzWm57ZXzTwqn8stMXgROrnMw8dJK3w==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.32.1': - resolution: {integrity: sha512-If3PDskT77q7zgqVqYuj7WG3WC08G1kwXGVFi9Jr8nY6eHucREHkfpX79c0ACAjLj3QIWKPJR7w4i+f5EdLH5Q==} + '@rollup/rollup-android-arm64@4.34.1': + resolution: {integrity: sha512-4H5ZtZitBPlbPsTv6HBB8zh1g5d0T8TzCmpndQdqq20Ugle/nroOyDMf9p7f88Gsu8vBLU78/cuh8FYHZqdXxw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.32.1': - resolution: {integrity: sha512-zCpKHioQ9KgZToFp5Wvz6zaWbMzYQ2LJHQ+QixDKq52KKrF65ueu6Af4hLlLWHjX1Wf/0G5kSJM9PySW9IrvHA==} + '@rollup/rollup-darwin-arm64@4.34.1': + resolution: {integrity: sha512-f2AJ7Qwx9z25hikXvg+asco8Sfuc5NCLg8rmqQBIOUoWys5sb/ZX9RkMZDPdnnDevXAMJA5AWLnRBmgdXGEUiA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.32.1': - resolution: {integrity: sha512-sFvF+t2+TyUo/ZQqUcifrJIgznx58oFZbdHS9TvHq3xhPVL9nOp+yZ6LKrO9GWTP+6DbFtoyLDbjTpR62Mbr3Q==} + '@rollup/rollup-darwin-x64@4.34.1': + resolution: {integrity: sha512-+/2JBrRfISCsWE4aEFXxd+7k9nWGXA8+wh7ZUHn/u8UDXOU9LN+QYKKhd57sIn6WRcorOnlqPMYFIwie/OHXWw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.32.1': - resolution: {integrity: sha512-NbOa+7InvMWRcY9RG+B6kKIMD/FsnQPH0MWUvDlQB1iXnF/UcKSudCXZtv4lW+C276g3w5AxPbfry5rSYvyeYA==} + '@rollup/rollup-freebsd-arm64@4.34.1': + resolution: {integrity: sha512-SUeB0pYjIXwT2vfAMQ7E4ERPq9VGRrPR7Z+S4AMssah5EHIilYqjWQoTn5dkDtuIJUSTs8H+C9dwoEcg3b0sCA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.32.1': - resolution: {integrity: sha512-JRBRmwvHPXR881j2xjry8HZ86wIPK2CcDw0EXchE1UgU0ubWp9nvlT7cZYKc6bkypBt745b4bglf3+xJ7hXWWw==} + '@rollup/rollup-freebsd-x64@4.34.1': + resolution: {integrity: sha512-L3T66wAZiB/ooiPbxz0s6JEX6Sr2+HfgPSK+LMuZkaGZFAFCQAHiP3dbyqovYdNaiUXcl9TlgnIbcsIicAnOZg==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.32.1': - resolution: {integrity: sha512-PKvszb+9o/vVdUzCCjL0sKHukEQV39tD3fepXxYrHE3sTKrRdCydI7uldRLbjLmDA3TFDmh418XH19NOsDRH8g==} + '@rollup/rollup-linux-arm-gnueabihf@4.34.1': + resolution: {integrity: sha512-UBXdQ4+ATARuFgsFrQ+tAsKvBi/Hly99aSVdeCUiHV9dRTTpMU7OrM3WXGys1l40wKVNiOl0QYY6cZQJ2xhKlQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.32.1': - resolution: {integrity: sha512-9WHEMV6Y89eL606ReYowXuGF1Yb2vwfKWKdD1A5h+OYnPZSJvxbEjxTRKPgi7tkP2DSnW0YLab1ooy+i/FQp/Q==} + '@rollup/rollup-linux-arm-musleabihf@4.34.1': + resolution: {integrity: sha512-m/yfZ25HGdcCSwmopEJm00GP7xAUyVcBPjttGLRAqZ60X/bB4Qn6gP7XTwCIU6bITeKmIhhwZ4AMh2XLro+4+w==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.32.1': - resolution: {integrity: sha512-tZWc9iEt5fGJ1CL2LRPw8OttkCBDs+D8D3oEM8mH8S1ICZCtFJhD7DZ3XMGM8kpqHvhGUTvNUYVDnmkj4BDXnw==} + '@rollup/rollup-linux-arm64-gnu@4.34.1': + resolution: {integrity: sha512-Wy+cUmFuvziNL9qWRRzboNprqSQ/n38orbjRvd6byYWridp5TJ3CD+0+HUsbcWVSNz9bxkDUkyASGP0zS7GAvg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.32.1': - resolution: {integrity: sha512-FTYc2YoTWUsBz5GTTgGkRYYJ5NGJIi/rCY4oK/I8aKowx1ToXeoVVbIE4LGAjsauvlhjfl0MYacxClLld1VrOw==} + '@rollup/rollup-linux-arm64-musl@4.34.1': + resolution: {integrity: sha512-CQ3MAGgiFmQW5XJX5W3wnxOBxKwFlUAgSXFA2SwgVRjrIiVt5LHfcQLeNSHKq5OEZwv+VCBwlD1+YKCjDG8cpg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.32.1': - resolution: {integrity: sha512-F51qLdOtpS6P1zJVRzYM0v6MrBNypyPEN1GfMiz0gPu9jN8ScGaEFIZQwteSsGKg799oR5EaP7+B2jHgL+d+Kw==} + '@rollup/rollup-linux-loongarch64-gnu@4.34.1': + resolution: {integrity: sha512-rSzb1TsY4lSwH811cYC3OC2O2mzNMhM13vcnA7/0T6Mtreqr3/qs6WMDriMRs8yvHDI54qxHgOk8EV5YRAHFbw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.32.1': - resolution: {integrity: sha512-wO0WkfSppfX4YFm5KhdCCpnpGbtgQNj/tgvYzrVYFKDpven8w2N6Gg5nB6w+wAMO3AIfSTWeTjfVe+uZ23zAlg==} + '@rollup/rollup-linux-powerpc64le-gnu@4.34.1': + resolution: {integrity: sha512-fwr0n6NS0pG3QxxlqVYpfiY64Fd1Dqd8Cecje4ILAV01ROMp4aEdCj5ssHjRY3UwU7RJmeWd5fi89DBqMaTawg==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.32.1': - resolution: {integrity: sha512-iWswS9cIXfJO1MFYtI/4jjlrGb/V58oMu4dYJIKnR5UIwbkzR0PJ09O0PDZT0oJ3LYWXBSWahNf/Mjo6i1E5/g==} + '@rollup/rollup-linux-riscv64-gnu@4.34.1': + resolution: {integrity: sha512-4uJb9qz7+Z/yUp5RPxDGGGUcoh0PnKF33QyWgEZ3X/GocpWb6Mb+skDh59FEt5d8+Skxqs9mng6Swa6B2AmQZg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.32.1': - resolution: {integrity: sha512-RKt8NI9tebzmEthMnfVgG3i/XeECkMPS+ibVZjZ6mNekpbbUmkNWuIN2yHsb/mBPyZke4nlI4YqIdFPgKuoyQQ==} + '@rollup/rollup-linux-s390x-gnu@4.34.1': + resolution: {integrity: sha512-QlIo8ndocWBEnfmkYqj8vVtIUpIqJjfqKggjy7IdUncnt8BGixte1wDON7NJEvLg3Kzvqxtbo8tk+U1acYEBlw==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.32.1': - resolution: {integrity: sha512-WQFLZ9c42ECqEjwg/GHHsouij3pzLXkFdz0UxHa/0OM12LzvX7DzedlY0SIEly2v18YZLRhCRoHZDxbBSWoGYg==} + '@rollup/rollup-linux-x64-gnu@4.34.1': + resolution: {integrity: sha512-hzpleiKtq14GWjz3ahWvJXgU1DQC9DteiwcsY4HgqUJUGxZThlL66MotdUEK9zEo0PK/2ADeZGM9LIondE302A==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.32.1': - resolution: {integrity: sha512-BLoiyHDOWoS3uccNSADMza6V6vCNiphi94tQlVIL5de+r6r/CCQuNnerf+1g2mnk2b6edp5dk0nhdZ7aEjOBsA==} + '@rollup/rollup-linux-x64-musl@4.34.1': + resolution: {integrity: sha512-jqtKrO715hDlvUcEsPn55tZt2TEiBvBtCMkUuU0R6fO/WPT7lO9AONjPbd8II7/asSiNVQHCMn4OLGigSuxVQA==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.32.1': - resolution: {integrity: sha512-w2l3UnlgYTNNU+Z6wOR8YdaioqfEnwPjIsJ66KxKAf0p+AuL2FHeTX6qvM+p/Ue3XPBVNyVSfCrfZiQh7vZHLQ==} + '@rollup/rollup-win32-arm64-msvc@4.34.1': + resolution: {integrity: sha512-RnHy7yFf2Wz8Jj1+h8klB93N0NHNHXFhNwAmiy9zJdpY7DE01VbEVtPdrK1kkILeIbHGRJjvfBDBhnxBr8kD4g==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.32.1': - resolution: {integrity: sha512-Am9H+TGLomPGkBnaPWie4F3x+yQ2rr4Bk2jpwy+iV+Gel9jLAu/KqT8k3X4jxFPW6Zf8OMnehyutsd+eHoq1WQ==} + '@rollup/rollup-win32-ia32-msvc@4.34.1': + resolution: {integrity: sha512-i7aT5HdiZIcd7quhzvwQ2oAuX7zPYrYfkrd1QFfs28Po/i0q6kas/oRrzGlDhAEyug+1UfUtkWdmoVlLJj5x9Q==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.32.1': - resolution: {integrity: sha512-ar80GhdZb4DgmW3myIS9nRFYcpJRSME8iqWgzH2i44u+IdrzmiXVxeFnExQ5v4JYUSpg94bWjevMG8JHf1Da5Q==} + '@rollup/rollup-win32-x64-msvc@4.34.1': + resolution: {integrity: sha512-k3MVFD9Oq+laHkw2N2v7ILgoa9017ZMF/inTtHzyTVZjYs9cSH18sdyAf6spBAJIGwJ5UaC7et2ZH1WCdlhkMw==} cpu: [x64] os: [win32] @@ -937,6 +940,11 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + artalk@2.9.1: + resolution: {integrity: sha512-IFo9XqWDalsHy8BsmMA5SSB9bozBa/sBhTm/+O5KwA6DnC95lFKv7C6ScMx/Xa4ue5qSQ7VV5vxRgCh/raohkQ==} + peerDependencies: + marked: ^14.1.0 + autoprefixer@10.4.20: resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} @@ -1144,8 +1152,8 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fastq@1.18.0: - resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==} + fastq@1.19.0: + resolution: {integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==} feed@4.2.2: resolution: {integrity: sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==} @@ -1252,8 +1260,8 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} imurmurhash@0.1.4: @@ -1379,8 +1387,8 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 - marked@12.0.2: - resolution: {integrity: sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==} + marked@15.0.6: + resolution: {integrity: sha512-Y07CUOE+HQXbVDCGl3LXggqJDbXDP2pArc2C1N1RRMN0ONiShoSsIInMd5Gsxupe7fKLpgimTV+HOJ9r7bA+pg==} engines: {node: '>= 18'} hasBin: true @@ -1815,15 +1823,15 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} - react-router-dom@6.28.2: - resolution: {integrity: sha512-O81EWqNJWqvlN/a7eTudAdQm0TbI7hw+WIi7OwwMcTn5JMyZ0ibTFNGz+t+Lju0df4LcqowCegcrK22lB1q9Kw==} + react-router-dom@6.29.0: + resolution: {integrity: sha512-pkEbJPATRJ2iotK+wUwHfy0xs2T59YPEN8BQxVCPeBZvK7kfPESRc/nyxzdcxR17hXgUPYx2whMwl+eo9cUdnQ==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' - react-router@6.28.2: - resolution: {integrity: sha512-BgFY7+wEGVjHCiqaj2XiUBQ1kkzfg6UoKYwEe0wv+FF+HNPCxtS/MVPvLAPH++EsuCMReZl9RYVGqcHLk5ms3A==} + react-router@6.29.0: + resolution: {integrity: sha512-DXZJoE0q+KyeVw75Ck6GkPxFak63C4fGqZGNijnWgzB/HzSP1ZfTlBj5COaGWwhrMQ/R8bXiq5Ooy4KG+ReyjQ==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' @@ -1861,8 +1869,8 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.32.1: - resolution: {integrity: sha512-z+aeEsOeEa3mEbS1Tjl6sAZ8NE3+AalQz1RJGj81M+fizusbdDMoEJwdJNHfaB40Scr4qNu+welOfes7maKonA==} + rollup@4.34.1: + resolution: {integrity: sha512-iYZ/+PcdLYSGfH3S+dGahlW/RWmsqDhLgj1BT9DH/xXJ0ggZN7xkdP9wipPNjjNLczI+fmMLmTB9pye+d2r4GQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1968,8 +1976,8 @@ packages: toggle-selection@1.0.6: resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} - ts-api-utils@2.0.0: - resolution: {integrity: sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==} + ts-api-utils@2.0.1: + resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -2417,9 +2425,9 @@ snapshots: '@eslint-community/regexpp@4.12.1': {} - '@eslint/config-array@0.19.1': + '@eslint/config-array@0.19.2': dependencies: - '@eslint/object-schema': 2.1.5 + '@eslint/object-schema': 2.1.6 debug: 4.4.0 minimatch: 3.1.2 transitivePeerDependencies: @@ -2436,7 +2444,7 @@ snapshots: espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 - import-fresh: 3.3.0 + import-fresh: 3.3.1 js-yaml: 4.1.0 minimatch: 3.1.2 strip-json-comments: 3.1.1 @@ -2445,7 +2453,7 @@ snapshots: '@eslint/js@9.19.0': {} - '@eslint/object-schema@2.1.5': {} + '@eslint/object-schema@2.1.6': {} '@eslint/plugin-kit@0.2.5': dependencies: @@ -2501,7 +2509,7 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.18.0 + fastq: 1.19.0 '@pkgjs/parseargs@0.11.0': optional: true @@ -2575,63 +2583,63 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@remix-run/router@1.21.1': {} + '@remix-run/router@1.22.0': {} - '@rollup/rollup-android-arm-eabi@4.32.1': + '@rollup/rollup-android-arm-eabi@4.34.1': optional: true - '@rollup/rollup-android-arm64@4.32.1': + '@rollup/rollup-android-arm64@4.34.1': optional: true - '@rollup/rollup-darwin-arm64@4.32.1': + '@rollup/rollup-darwin-arm64@4.34.1': optional: true - '@rollup/rollup-darwin-x64@4.32.1': + '@rollup/rollup-darwin-x64@4.34.1': optional: true - '@rollup/rollup-freebsd-arm64@4.32.1': + '@rollup/rollup-freebsd-arm64@4.34.1': optional: true - '@rollup/rollup-freebsd-x64@4.32.1': + '@rollup/rollup-freebsd-x64@4.34.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.32.1': + '@rollup/rollup-linux-arm-gnueabihf@4.34.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.32.1': + '@rollup/rollup-linux-arm-musleabihf@4.34.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.32.1': + '@rollup/rollup-linux-arm64-gnu@4.34.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.32.1': + '@rollup/rollup-linux-arm64-musl@4.34.1': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.32.1': + '@rollup/rollup-linux-loongarch64-gnu@4.34.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.32.1': + '@rollup/rollup-linux-powerpc64le-gnu@4.34.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.32.1': + '@rollup/rollup-linux-riscv64-gnu@4.34.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.32.1': + '@rollup/rollup-linux-s390x-gnu@4.34.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.32.1': + '@rollup/rollup-linux-x64-gnu@4.34.1': optional: true - '@rollup/rollup-linux-x64-musl@4.32.1': + '@rollup/rollup-linux-x64-musl@4.34.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.32.1': + '@rollup/rollup-win32-arm64-msvc@4.34.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.32.1': + '@rollup/rollup-win32-ia32-msvc@4.34.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.32.1': + '@rollup/rollup-win32-x64-msvc@4.34.1': optional: true '@tailwindcss/typography@0.5.16(tailwindcss@3.4.17)': @@ -2717,7 +2725,7 @@ snapshots: graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 2.0.0(typescript@5.7.3) + ts-api-utils: 2.0.1(typescript@5.7.3) typescript: 5.7.3 transitivePeerDependencies: - supports-color @@ -2745,7 +2753,7 @@ snapshots: '@typescript-eslint/utils': 8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) debug: 4.4.0 eslint: 9.19.0(jiti@1.21.7) - ts-api-utils: 2.0.0(typescript@5.7.3) + ts-api-utils: 2.0.1(typescript@5.7.3) typescript: 5.7.3 transitivePeerDependencies: - supports-color @@ -2761,7 +2769,7 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.0 - ts-api-utils: 2.0.0(typescript@5.7.3) + ts-api-utils: 2.0.1(typescript@5.7.3) typescript: 5.7.3 transitivePeerDependencies: - supports-color @@ -2885,6 +2893,10 @@ snapshots: argparse@2.0.1: {} + artalk@2.9.1(marked@15.0.6): + dependencies: + marked: 15.0.6 + autoprefixer@10.4.20(postcss@8.5.1): dependencies: browserslist: 4.24.4 @@ -3072,7 +3084,7 @@ snapshots: dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0(jiti@1.21.7)) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.19.1 + '@eslint/config-array': 0.19.2 '@eslint/core': 0.10.0 '@eslint/eslintrc': 3.2.0 '@eslint/js': 9.19.0 @@ -3141,7 +3153,7 @@ snapshots: fast-levenshtein@2.0.6: {} - fastq@1.18.0: + fastq@1.19.0: dependencies: reusify: 1.0.4 @@ -3249,7 +3261,7 @@ snapshots: ignore@5.3.2: {} - import-fresh@3.3.0: + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 @@ -3357,7 +3369,7 @@ snapshots: dependencies: react: 18.3.1 - marked@12.0.2: {} + marked@15.0.6: {} merge2@1.4.1: {} @@ -3847,16 +3859,16 @@ snapshots: react-refresh@0.14.2: {} - react-router-dom@6.28.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-router-dom@6.29.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@remix-run/router': 1.21.1 + '@remix-run/router': 1.22.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-router: 6.28.2(react@18.3.1) + react-router: 6.29.0(react@18.3.1) - react-router@6.28.2(react@18.3.1): + react-router@6.29.0(react@18.3.1): dependencies: - '@remix-run/router': 1.21.1 + '@remix-run/router': 1.22.0 react: 18.3.1 react@18.3.1: @@ -3887,29 +3899,29 @@ snapshots: reusify@1.0.4: {} - rollup@4.32.1: + rollup@4.34.1: dependencies: '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.32.1 - '@rollup/rollup-android-arm64': 4.32.1 - '@rollup/rollup-darwin-arm64': 4.32.1 - '@rollup/rollup-darwin-x64': 4.32.1 - '@rollup/rollup-freebsd-arm64': 4.32.1 - '@rollup/rollup-freebsd-x64': 4.32.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.32.1 - '@rollup/rollup-linux-arm-musleabihf': 4.32.1 - '@rollup/rollup-linux-arm64-gnu': 4.32.1 - '@rollup/rollup-linux-arm64-musl': 4.32.1 - '@rollup/rollup-linux-loongarch64-gnu': 4.32.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.32.1 - '@rollup/rollup-linux-riscv64-gnu': 4.32.1 - '@rollup/rollup-linux-s390x-gnu': 4.32.1 - '@rollup/rollup-linux-x64-gnu': 4.32.1 - '@rollup/rollup-linux-x64-musl': 4.32.1 - '@rollup/rollup-win32-arm64-msvc': 4.32.1 - '@rollup/rollup-win32-ia32-msvc': 4.32.1 - '@rollup/rollup-win32-x64-msvc': 4.32.1 + '@rollup/rollup-android-arm-eabi': 4.34.1 + '@rollup/rollup-android-arm64': 4.34.1 + '@rollup/rollup-darwin-arm64': 4.34.1 + '@rollup/rollup-darwin-x64': 4.34.1 + '@rollup/rollup-freebsd-arm64': 4.34.1 + '@rollup/rollup-freebsd-x64': 4.34.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.34.1 + '@rollup/rollup-linux-arm-musleabihf': 4.34.1 + '@rollup/rollup-linux-arm64-gnu': 4.34.1 + '@rollup/rollup-linux-arm64-musl': 4.34.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.34.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.34.1 + '@rollup/rollup-linux-riscv64-gnu': 4.34.1 + '@rollup/rollup-linux-s390x-gnu': 4.34.1 + '@rollup/rollup-linux-x64-gnu': 4.34.1 + '@rollup/rollup-linux-x64-musl': 4.34.1 + '@rollup/rollup-win32-arm64-msvc': 4.34.1 + '@rollup/rollup-win32-ia32-msvc': 4.34.1 + '@rollup/rollup-win32-x64-msvc': 4.34.1 fsevents: 2.3.3 run-parallel@1.2.0: @@ -4027,7 +4039,7 @@ snapshots: toggle-selection@1.0.6: {} - ts-api-utils@2.0.0(typescript@5.7.3): + ts-api-utils@2.0.1(typescript@5.7.3): dependencies: typescript: 5.7.3 @@ -4076,7 +4088,7 @@ snapshots: dependencies: esbuild: 0.21.5 postcss: 8.5.1 - rollup: 4.32.1 + rollup: 4.34.1 optionalDependencies: '@types/node': 22.13.0 fsevents: 2.3.3 diff --git a/src/components/Comments.tsx b/src/components/Comments.tsx new file mode 100644 index 0000000..7ecacc3 --- /dev/null +++ b/src/components/Comments.tsx @@ -0,0 +1,71 @@ +import { useCallback, useRef, useEffect } from 'react' +import { useLocation } from 'react-router-dom' +import 'artalk/dist/Artalk.css' +import Artalk from 'artalk' + +interface CommentsProps { + title?: string; +} + +const Comments = ({ title }: CommentsProps) => { + const { pathname } = useLocation() + const artalkRef = useRef() + const containerRef = useRef(null) + + useEffect(() => { + if (!containerRef.current) return + + // Clean up previous instance + if (artalkRef.current) { + artalkRef.current.destroy() + artalkRef.current = undefined + } + + // Initialize new instance + artalkRef.current = Artalk.init({ + el: containerRef.current, + pageKey: pathname, + pageTitle: title || document.title, + server: 'https://comments.owu.one', + site: 'STARSET Mirror Homepage', + darkMode: document.documentElement.classList.contains('dark'), + useBackendConf: true, + pagination: { + pageSize: 15, + readMore: true, + }, + emoticons: true, + }) + + // Handle dark mode changes + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if (mutation.attributeName === 'class') { + const isDark = document.documentElement.classList.contains('dark') + artalkRef.current?.setDarkMode(isDark) + } + }) + }) + + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ['class'], + }) + + return () => { + observer.disconnect() + artalkRef.current?.destroy() + } + }, [pathname, title]) + + return ( +
+ ) +} + +export default Comments diff --git a/src/components/UpdateDetail.tsx b/src/components/UpdateDetail.tsx index 7b162c6..e84782e 100644 --- a/src/components/UpdateDetail.tsx +++ b/src/components/UpdateDetail.tsx @@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { ChevronLeft } from 'lucide-react'; import { Update } from '../utils/updates'; +import Comments from './Comments'; interface UpdateDetailProps { update: Update; @@ -51,6 +52,8 @@ const UpdateDetail: React.FC = ({ update, content }) => { {update.summary}

)} + +
); diff --git a/src/pages/UpdateDetailPage.tsx b/src/pages/UpdateDetailPage.tsx index 5d7c2cf..2cf5944 100644 --- a/src/pages/UpdateDetailPage.tsx +++ b/src/pages/UpdateDetailPage.tsx @@ -13,14 +13,9 @@ const UpdateDetailPage: React.FC = () => { const [content, setContent] = useState(null); useEffect(() => { - console.log(`[Debug] UpdateDetailPage - Effect triggered with id: ${id}`); - console.log(`[Debug] Current language: ${i18n.language}`); - console.log(`[Debug] Loading status: ${isLoading}`); - console.log(`[Debug] Available updates:`, allUpdates); const fetchUpdateData = async () => { if (!id) { - console.log('[Debug] No id provided, clearing update and content'); setUpdate(null); setContent(null); return; @@ -29,10 +24,8 @@ const UpdateDetailPage: React.FC = () => { try { // 查找对应 id 的更新条目 const foundUpdate = allUpdates.find(u => u.id === id); - console.log(`[Debug] Found update for id ${id}:`, foundUpdate); if (!foundUpdate) { - console.log(`[Debug] Update not found for id: ${id}`); setUpdate(null); setContent(null); return; @@ -42,47 +35,38 @@ const UpdateDetailPage: React.FC = () => { // 如果该更新有 link 属性,则说明为外链,详情页不需要加载内容 if (foundUpdate.link) { - console.log(`[Debug] Update is an external link: ${foundUpdate.link}`); setContent(null); return; } // 从日期中提取年份 const year = new Date(foundUpdate.date).getFullYear(); - console.log(`[Debug] Loading content for year: ${year}`); try { // 尝试加载 Markdown 文件 const mdPath = `/data/${i18n.language}/updates/${year}/${foundUpdate.id}.md`; - console.log(`[Debug] Attempting to load markdown from: ${mdPath}`); const response = await fetch(mdPath); // 检查响应状态和内容类型 const contentType = response.headers.get('content-type'); - console.log(`[Debug] Response content type: ${contentType}`); if (!response.ok || !contentType || !contentType.includes('text/markdown')) { - console.log(`[Debug] Markdown file not found or invalid content type at: ${mdPath}`); throw new Error('Markdown file not found or invalid'); } const mdText = await response.text(); // 简单验证内容是否看起来像 markdown if (mdText.includes(' => { - console.log(`[Debug] Fetching update years for language: ${language}`); try { const response = await fetch(`/data/${language}/updates.json`); if (!response.ok) { throw new Error(`Failed to load updates index, status: ${response.status}`); } const index: UpdatesIndex = await response.json(); - console.log(`[Debug] Found years:`, index.years); return index.years || []; } catch (error) { if (process.env.NODE_ENV === 'development') { @@ -39,14 +37,12 @@ const getUpdateYears = async (language: string): Promise => { // 动态获取指定的年度更新 const getYearUpdates = async (yearFile: string, language: string): Promise => { - console.log(`[Debug] Fetching updates for year file: ${yearFile}, language: ${language}`); try { const response = await fetch(`/data/${language}/updates/${yearFile}`); if (!response.ok) { throw new Error(`Failed to load updates from ${yearFile}, status: ${response.status}`); } const data: YearUpdates = await response.json(); - console.log(`[Debug] Loaded updates for ${yearFile}:`, data.updates?.length || 0, 'updates'); return data; } catch (error) { if (process.env.NODE_ENV === 'development') { @@ -58,7 +54,6 @@ const getYearUpdates = async (yearFile: string, language: string): Promise => { - console.log(`[Debug] Getting all updates for language: ${language}, selectedTags:`, selectedTags); const allUpdates: Update[] = []; // 从索引文件获取年份列表