From d77d3484c4656ecc424066ea7bd9c22d1237281f Mon Sep 17 00:00:00 2001 From: Jiang Feng Date: Sun, 27 Apr 2025 00:19:13 +0800 Subject: [PATCH] feat: use ReportEditor after research report completed --- web/package.json | 1 + web/pnpm-lock.yaml | 85 +------------------ .../app/_components/research-report-block.tsx | 12 ++- web/src/components/editor/index.tsx | 25 +++--- 4 files changed, 28 insertions(+), 95 deletions(-) diff --git a/web/package.json b/web/package.json index 261f232..9b3f93c 100644 --- a/web/package.json +++ b/web/package.json @@ -37,6 +37,7 @@ "@radix-ui/react-tooltip": "^1.2.0", "@t3-oss/env-nextjs": "^0.11.0", "@tailwindcss/typography": "^0.5.16", + "@tiptap/react": "^2.11.7", "best-effort-json-parser": "^1.1.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 019226f..79674f3 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -8,9 +8,6 @@ importers: .: dependencies: - '@ai-sdk/react': - specifier: ^1.2.9 - version: 1.2.9(react@19.1.0)(zod@3.24.3) '@ant-design/icons': specifier: ^6.0.0 version: 6.0.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -71,6 +68,9 @@ importers: '@tailwindcss/typography': specifier: ^0.5.16 version: 0.5.16(tailwindcss@4.1.4) + '@tiptap/react': + specifier: ^2.11.7 + version: 2.11.7(@tiptap/core@2.11.7(@tiptap/pm@2.11.7))(@tiptap/pm@2.11.7)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) best-effort-json-parser: specifier: ^1.1.3 version: 1.1.3 @@ -222,32 +222,6 @@ importers: packages: - '@ai-sdk/provider-utils@2.2.7': - resolution: {integrity: sha512-kM0xS3GWg3aMChh9zfeM+80vEZfXzR3JEUBdycZLtbRZ2TRT8xOj3WodGHPb06sUK5yD7pAXC/P7ctsi2fvUGQ==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.23.8 - - '@ai-sdk/provider@1.1.3': - resolution: {integrity: sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==} - engines: {node: '>=18'} - - '@ai-sdk/react@1.2.9': - resolution: {integrity: sha512-/VYm8xifyngaqFDLXACk/1czDRCefNCdALUyp+kIX6DUIYUWTM93ISoZ+qJ8+3E+FiJAKBQz61o8lIIl+vYtzg==} - engines: {node: '>=18'} - peerDependencies: - react: ^18 || ^19 || ^19.0.0-rc - zod: ^3.23.8 - peerDependenciesMeta: - zod: - optional: true - - '@ai-sdk/ui-utils@1.2.8': - resolution: {integrity: sha512-nls/IJCY+ks3Uj6G/agNhXqQeLVqhNfoJbuNgCny+nX2veY5ADB91EcZUqVeQ/ionul2SeUswPY6Q/DxteY29Q==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.23.8 - '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -2755,9 +2729,6 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -3609,9 +3580,6 @@ packages: resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} engines: {node: '>= 10.13.0'} - secure-json-parse@2.7.0: - resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} - selecto@1.26.3: resolution: {integrity: sha512-gZHgqMy5uyB6/2YDjv3Qqaf7bd2hTDOpPdxXlrez4R3/L0GiEWDCFaUfrflomgqdb3SxHF2IXY0Jw0EamZi7cw==} @@ -3801,10 +3769,6 @@ packages: engines: {node: '>=10'} hasBin: true - throttleit@2.1.0: - resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} - engines: {node: '>=18'} - tinyglobby@0.2.12: resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} engines: {node: '>=12.0.0'} @@ -4034,11 +3998,6 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - zod-to-json-schema@3.24.5: - resolution: {integrity: sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==} - peerDependencies: - zod: ^3.24.1 - zod@3.24.3: resolution: {integrity: sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==} @@ -4080,34 +4039,6 @@ packages: snapshots: - '@ai-sdk/provider-utils@2.2.7(zod@3.24.3)': - dependencies: - '@ai-sdk/provider': 1.1.3 - nanoid: 3.3.11 - secure-json-parse: 2.7.0 - zod: 3.24.3 - - '@ai-sdk/provider@1.1.3': - dependencies: - json-schema: 0.4.0 - - '@ai-sdk/react@1.2.9(react@19.1.0)(zod@3.24.3)': - dependencies: - '@ai-sdk/provider-utils': 2.2.7(zod@3.24.3) - '@ai-sdk/ui-utils': 1.2.8(zod@3.24.3) - react: 19.1.0 - swr: 2.3.3(react@19.1.0) - throttleit: 2.1.0 - optionalDependencies: - zod: 3.24.3 - - '@ai-sdk/ui-utils@1.2.8(zod@3.24.3)': - dependencies: - '@ai-sdk/provider': 1.1.3 - '@ai-sdk/provider-utils': 2.2.7(zod@3.24.3) - zod: 3.24.3 - zod-to-json-schema: 3.24.5(zod@3.24.3) - '@alloc/quick-lru@5.2.0': {} '@ant-design/colors@8.0.0': @@ -6747,8 +6678,6 @@ snapshots: json-schema-traverse@1.0.0: {} - json-schema@0.4.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} json5@1.0.2: @@ -7929,8 +7858,6 @@ snapshots: ajv-formats: 2.1.1(ajv@8.17.1) ajv-keywords: 5.1.0(ajv@8.17.1) - secure-json-parse@2.7.0: {} - selecto@1.26.3: dependencies: '@daybrush/utils': 1.13.0 @@ -8173,8 +8100,6 @@ snapshots: commander: 2.20.3 source-map-support: 0.5.21 - throttleit@2.1.0: {} - tinyglobby@0.2.12: dependencies: fdir: 6.4.3(picomatch@4.0.2) @@ -8495,10 +8420,6 @@ snapshots: yocto-queue@0.1.0: {} - zod-to-json-schema@3.24.5(zod@3.24.3): - dependencies: - zod: 3.24.3 - zod@3.24.3: {} zustand@4.5.6(@types/react@19.1.2)(react@19.1.0): diff --git a/web/src/app/_components/research-report-block.tsx b/web/src/app/_components/research-report-block.tsx index a2578c7..11275f4 100644 --- a/web/src/app/_components/research-report-block.tsx +++ b/web/src/app/_components/research-report-block.tsx @@ -3,6 +3,7 @@ import { useRef } from "react"; +import ReportEditor from "~/components/editor"; import { useMessage } from "~/core/store"; import { cn } from "~/lib/utils"; @@ -19,13 +20,20 @@ export function ResearchReportBlock({ }) { const message = useMessage(messageId); const contentRef = useRef(null); + const isCompleted = message?.isStreaming === false && message?.content !== ""; return (
- {message?.content} - {message?.isStreaming && } + {isCompleted ? ( + + ) : ( + <> + {message?.content} + {message?.isStreaming && } + + )}
); } diff --git a/web/src/components/editor/index.tsx b/web/src/components/editor/index.tsx index 50aee66..ac26c6f 100644 --- a/web/src/components/editor/index.tsx +++ b/web/src/components/editor/index.tsx @@ -14,6 +14,7 @@ import { handleImageDrop, handleImagePaste, } from "novel"; +import type { Content } from "@tiptap/react"; import { useEffect, useState } from "react"; import { useDebouncedCallback } from "use-debounce"; import { defaultExtensions } from "./extensions"; @@ -27,7 +28,7 @@ import GenerativeMenuSwitch from "./generative/generative-menu-switch"; import { uploadFn } from "./image-upload"; import { TextButtons } from "./selectors/text-buttons"; import { slashCommand, suggestionItems } from "./slash-command"; -import { defaultEditorContent } from "./content"; +// import { defaultEditorContent } from "./content"; import "~/styles/prosemirror.css"; @@ -35,10 +36,12 @@ const hljs = require("highlight.js"); const extensions = [...defaultExtensions, slashCommand]; -const ReportEditor = () => { - const [initialContent, setInitialContent] = useState( - null, - ); +export interface ReportEditorProps { + content: Content; +} + +const ReportEditor = ({ content }: ReportEditorProps) => { + const [initialContent, setInitialContent] = useState(() => content); const [saveStatus, setSaveStatus] = useState("Saved"); const [charsCount, setCharsCount] = useState(); @@ -76,11 +79,11 @@ const ReportEditor = () => { 500, ); - useEffect(() => { - const content = window.localStorage.getItem("novel-content"); - if (content) setInitialContent(JSON.parse(content)); - else setInitialContent(defaultEditorContent); - }, []); + // useEffect(() => { + // const content = window.localStorage.getItem("novel-content"); + // if (content) setInitialContent(JSON.parse(content)); + // else setInitialContent(defaultEditorContent); + // }, []); if (!initialContent) return null; @@ -103,7 +106,7 @@ const ReportEditor = () => {