diff --git a/packages/client/package.json b/packages/client/package.json index 3ec3debc..59538cfb 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -51,6 +51,7 @@ "@tiptap/extension-text-style": "^2.0.0-beta.23", "@tiptap/extension-underline": "^2.0.0-beta.23", "@tiptap/react": "^2.0.0-beta.107", + "@tiptap/suggestion": "^2.0.0-beta.90", "@traptitech/markdown-it-katex": "^3.5.0", "axios": "^0.25.0", "classnames": "^2.3.1", @@ -62,6 +63,8 @@ "lowlight": "^2.5.0", "markdown-it": "^12.3.2", "markdown-it-anchor": "^8.4.1", + "markdown-it-container": "^3.0.0", + "markdown-it-emoji": "^2.0.0", "markdown-it-footnote": "^3.0.3", "markdown-it-sub": "^1.0.0", "markdown-it-sup": "^1.0.0", @@ -69,11 +72,13 @@ "marked": "^4.0.12", "next": "12.0.10", "prosemirror-markdown": "^1.7.0", + "prosemirror-utils": "^0.9.6", "prosemirror-view": "^1.23.6", "react": "17.0.2", "react-dom": "17.0.2", "react-helmet": "^6.1.0", "react-split-pane": "^0.1.92", + "scroll-into-view-if-needed": "^2.2.29", "swr": "^1.2.0", "tippy.js": "^6.3.7" }, diff --git a/packages/client/src/components/document/reader/content.tsx b/packages/client/src/components/document/reader/content.tsx index a8da6abe..a08e101f 100644 --- a/packages/client/src/components/document/reader/content.tsx +++ b/packages/client/src/components/document/reader/content.tsx @@ -13,12 +13,12 @@ export const DocumentContent: React.FC = ({ document }) => { const c = safeJSONParse(document.content); let json = c.default || c; - if (json && json.content) { - json = { - type: 'doc', - content: json.content.slice(1), - }; - } + // if (json && json.content) { + // json = { + // type: 'doc', + // content: json.content.slice(1), + // }; + // } const editor = useEditor({ editable: false, diff --git a/packages/client/src/components/document/reader/editor.tsx b/packages/client/src/components/document/reader/editor.tsx index 6689ab80..6bb915f7 100644 --- a/packages/client/src/components/document/reader/editor.tsx +++ b/packages/client/src/components/document/reader/editor.tsx @@ -1,7 +1,7 @@ -import React, { useMemo, useEffect } from 'react'; +import React, { useMemo, useEffect, useRef } from 'react'; import { useEditor, EditorContent } from '@tiptap/react'; import { Layout } from '@douyinfe/semi-ui'; -import { ILoginUser } from '@think/domains'; +import { IDocument, ILoginUser } from '@think/domains'; import { useToggle } from 'hooks/useToggle'; import { DEFAULT_EXTENSION, @@ -13,6 +13,7 @@ import { } from 'components/tiptap'; import { DataRender } from 'components/data-render'; import { joinUser } from 'components/document/collaboration'; +import { CreateUser } from './user'; import styles from './index.module.scss'; const { Content } = Layout; @@ -20,11 +21,13 @@ const { Content } = Layout; interface IProps { user: ILoginUser; documentId: string; + document: IDocument; } -export const Editor: React.FC = ({ user, documentId }) => { +export const Editor: React.FC = ({ user, documentId, document }) => { if (!user) return null; + const $ref = useRef(); const provider = useMemo(() => { return getProvider({ targetId: documentId, @@ -68,7 +71,15 @@ export const Editor: React.FC = ({ user, documentId }) => { return ( <> - +
+ +
+ + window.document.querySelector('#js-reader-container .ProseMirror .title') + } + />
); diff --git a/packages/client/src/components/document/reader/index.tsx b/packages/client/src/components/document/reader/index.tsx index a6ed5a92..cb30646e 100644 --- a/packages/client/src/components/document/reader/index.tsx +++ b/packages/client/src/components/document/reader/index.tsx @@ -122,10 +122,12 @@ export const DocumentReader: React.FC = ({ documentId }) => { return ( <> - -
- -
+
diff --git a/packages/client/src/components/document/reader/public/index.tsx b/packages/client/src/components/document/reader/public/index.tsx index 714c30ac..e44b40b3 100644 --- a/packages/client/src/components/document/reader/public/index.tsx +++ b/packages/client/src/components/document/reader/public/index.tsx @@ -131,11 +131,15 @@ export const DocumentPublicReader: React.FC = ({ documentId, hideLogo = style={{ fontSize }} id="js-share-document-editor-container" > - {data.title} -
- -
+ + window.document.querySelector( + '#js-share-document-editor-container .ProseMirror .title' + ) + } + /> diff --git a/packages/client/src/components/document/reader/user.tsx b/packages/client/src/components/document/reader/user.tsx index 1cef6d3e..53432c25 100644 --- a/packages/client/src/components/document/reader/user.tsx +++ b/packages/client/src/components/document/reader/user.tsx @@ -1,15 +1,26 @@ +import { createPortal } from 'react-dom'; import { Space, Typography, Avatar } from '@douyinfe/semi-ui'; import { IconUser } from '@douyinfe/semi-icons'; import { IDocument } from '@think/domains'; import { LocaleTime } from 'components/locale-time'; -const { Text } = Typography; - -export const CreateUser: React.FC<{ document: IDocument }> = ({ document }) => { +export const CreateUser: React.FC<{ document: IDocument; container: () => HTMLElement }> = ({ + document, + container = null, +}) => { if (!document.createUser) return null; - return ( - + const content = ( +
@@ -27,6 +38,11 @@ export const CreateUser: React.FC<{ document: IDocument }> = ({ document }) => {

-
+ ); + + const el = container && container(); + + if (!el) return content; + return createPortal(content, el); }; diff --git a/packages/client/src/components/icons/IconSearchReplace.tsx b/packages/client/src/components/icons/IconSearchReplace.tsx new file mode 100644 index 00000000..5be3fabd --- /dev/null +++ b/packages/client/src/components/icons/IconSearchReplace.tsx @@ -0,0 +1,21 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconSearchReplace: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + + + + + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/index.tsx b/packages/client/src/components/icons/index.tsx index 91f5e7de..88212a14 100644 --- a/packages/client/src/components/icons/index.tsx +++ b/packages/client/src/components/icons/index.tsx @@ -34,3 +34,4 @@ export * from './IconSplitCell'; export * from './IconAttachment'; export * from './IconMath'; export * from './IconSearch'; +export * from './IconSearchReplace'; diff --git a/packages/client/src/components/tiptap/basekit.tsx b/packages/client/src/components/tiptap/basekit.tsx index f6558c42..cdb522b1 100644 --- a/packages/client/src/components/tiptap/basekit.tsx +++ b/packages/client/src/components/tiptap/basekit.tsx @@ -11,6 +11,7 @@ import { ColorHighlighter } from './extensions/colorHighlighter'; import { DocumentChildren } from './extensions/documentChildren'; import { DocumentReference } from './extensions/documentReference'; import { Dropcursor } from './extensions/dropCursor'; +import { Emoji } from './extensions/emoji'; import { FontSize } from './extensions/fontSize'; import { FootnoteDefinition } from './extensions/footnoteDefinition'; import { FootnoteReference } from './extensions/footnoteReference'; @@ -33,6 +34,7 @@ import { Paragraph } from './extensions/paragraph'; import { PasteFile } from './extensions/pasteFile'; import { PasteMarkdown } from './extensions/pasteMarkdown'; import { Placeholder } from './extensions/placeholder'; +import { SearchNReplace } from './extensions/search'; import { Status } from './extensions/status'; import { Strike } from './extensions/strike'; import { Table } from './extensions/table'; @@ -62,6 +64,7 @@ export const BaseKit = [ DocumentChildren, DocumentReference, Dropcursor, + Emoji, FontSize, FootnoteDefinition, FootnoteReference, @@ -83,15 +86,8 @@ export const BaseKit = [ Paragraph, PasteFile, PasteMarkdown, - Placeholder.configure({ - placeholder: ({ node }) => { - if (node.type.name === 'title') { - return '请输入标题'; - } - return '请输入内容'; - }, - showOnlyWhenEditable: true, - }), + Placeholder, + SearchNReplace, Status, Strike, Table, @@ -99,9 +95,7 @@ export const BaseKit = [ TableHeader, TableRow, Text, - TextAlign.configure({ - types: ['heading', 'paragraph', 'image'], - }), + TextAlign, TextStyle, TaskItem, TaskList, diff --git a/packages/client/src/components/tiptap/components/attachment/index.tsx b/packages/client/src/components/tiptap/components/attachment/index.tsx index ff6494d0..009bdc5c 100644 --- a/packages/client/src/components/tiptap/components/attachment/index.tsx +++ b/packages/client/src/components/tiptap/components/attachment/index.tsx @@ -1,6 +1,7 @@ import { NodeViewWrapper, NodeViewContent } from '@tiptap/react'; -import { Button, Tooltip } from '@douyinfe/semi-ui'; +import { Button } from '@douyinfe/semi-ui'; import { IconDownload } from '@douyinfe/semi-icons'; +import { Tooltip } from 'components/tooltip'; import { download } from '../../services/download'; import styles from './index.module.scss'; @@ -12,7 +13,7 @@ export const AttachmentWrapper = ({ node }) => {
{name} - + + ))} +
+ + ); +}); diff --git a/packages/client/src/components/tiptap/components/katex/index.tsx b/packages/client/src/components/tiptap/components/katex/index.tsx index 4fb32af8..bf7371b3 100644 --- a/packages/client/src/components/tiptap/components/katex/index.tsx +++ b/packages/client/src/components/tiptap/components/katex/index.tsx @@ -21,7 +21,7 @@ export const KatexWrapper = ({ editor, node, updateAttributes }) => { const content = text ? ( ) : ( - 请输入公式 + 点击输入公式 ); return ( @@ -32,7 +32,7 @@ export const KatexWrapper = ({ editor, node, updateAttributes }) => { content={