Merge pull request #160 from fantasticit/pr159

This commit is contained in:
fantasticit 2022-08-15 11:31:52 +08:00 committed by GitHub
commit 23f2c037e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 69 additions and 23 deletions

View File

@ -79,7 +79,7 @@ export const DocumentActions: React.FC<IProps> = ({
visible={popoverVisible} visible={popoverVisible}
onVisibleChange={wrapOnVisibleChange} onVisibleChange={wrapOnVisibleChange}
content={ content={
<Dropdown.Menu> <Dropdown.Menu style={{ width: 112 }}>
{showCreateDocument && ( {showCreateDocument && (
<Dropdown.Item onClick={create}> <Dropdown.Item onClick={create}>
<Text> <Text>

View File

@ -42,7 +42,7 @@
width: auto; width: auto;
height: 100vh; height: 100vh;
min-height: 680px; min-height: 680px;
padding: 0 120px; padding: 60px 120px 0;
margin: 0 auto; margin: 0 auto;
overflow: auto; overflow: auto;
letter-spacing: 0.05em; letter-spacing: 0.05em;
@ -50,7 +50,10 @@
transition: width 0.3s linear, padding 0.3s linear; transition: width 0.3s linear, padding 0.3s linear;
.title { .title {
display: table-cell; display: flex;
align-items: flex-start;
flex-direction: column;
justify-content: center;
height: 100vh; height: 100vh;
font-size: 4rem; font-size: 4rem;
line-height: 4.6rem; line-height: 4.6rem;
@ -59,6 +62,24 @@
word-wrap: break-word; word-wrap: break-word;
vertical-align: middle; vertical-align: middle;
overflow-wrap: break-word; overflow-wrap: break-word;
.imgCover {
position: relative;
width: 100%;
height: 62.5%;
margin-bottom: 16px;
overflow: hidden;
> img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-position: center 50%;
object-fit: cover;
}
}
} }
.node-title.is-empty { .node-title.is-empty {
@ -76,15 +97,9 @@
padding: 12px; padding: 12px;
background-color: rgb(var(--semi-grey-9)); background-color: rgb(var(--semi-grey-9));
border-radius: var(--semi-border-radius-medium); border-radius: var(--semi-border-radius-medium);
opacity: 0;
transform: translateX(-50%); transform: translateX(-50%);
transition: opacity 0.3s ease-in-out; transition: opacity 0.3s ease-in-out;
&:hover {
opacity: 1;
transition: opacity 0.3s ease-in-out;
}
.selected { .selected {
background-color: rgb(var(--semi-grey-8)) !important; background-color: rgb(var(--semi-grey-8)) !important;
} }

View File

@ -7,9 +7,9 @@ import { IconPencil } from 'components/icons/IconPencil';
import { safeJSONParse } from 'helpers/json'; import { safeJSONParse } from 'helpers/json';
import { useDrawingCursor } from 'hooks/use-cursor'; import { useDrawingCursor } from 'hooks/use-cursor';
import { useToggle } from 'hooks/use-toggle'; import { useToggle } from 'hooks/use-toggle';
import React, { useCallback, useEffect } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { FullScreen, useFullScreenHandle } from 'react-full-screen'; import { FullScreen, useFullScreenHandle } from 'react-full-screen';
import { CollaborationKit } from 'tiptap/editor'; import { CollaborationKit, Document } from 'tiptap/editor';
import styles from './index.module.scss'; import styles from './index.module.scss';
@ -23,6 +23,7 @@ const FullscreenController = ({ handle: fullscreenHandler, isDrawing, toggleDraw
fullscreenHandler.exit(); fullscreenHandler.exit();
toggleDrawing(false); toggleDrawing(false);
}, [fullscreenHandler, toggleDrawing]); }, [fullscreenHandler, toggleDrawing]);
return ( return (
<div className={styles.fullScreenToolbar}> <div className={styles.fullScreenToolbar}>
<Space> <Space>
@ -53,17 +54,18 @@ export const DocumentFullscreen: React.FC<IProps> = ({ data }) => {
const fullscreenHandler = useFullScreenHandle(); const fullscreenHandler = useFullScreenHandle();
const [visible, toggleVisible] = useToggle(false); const [visible, toggleVisible] = useToggle(false);
const [isDrawing, toggleDrawing] = useToggle(false); const [isDrawing, toggleDrawing] = useToggle(false);
const [cover, setCover] = useState('');
const editor = useEditor({ const editor = useEditor({
editable: false, editable: false,
extensions: CollaborationKit, extensions: CollaborationKit.filter((ext) => ['title', 'doc'].indexOf(ext.name) < 0).concat(Document),
content: { type: 'doc', content: [] }, content: { type: 'doc', content: [] },
}); });
const startPowerpoint = () => { const startPowerpoint = useCallback(() => {
toggleVisible(true); toggleVisible(true);
fullscreenHandler.enter(); fullscreenHandler.enter();
}; }, [toggleVisible, fullscreenHandler]);
const fullscreenChange = useCallback( const fullscreenChange = useCallback(
(state) => { (state) => {
@ -76,11 +78,13 @@ export const DocumentFullscreen: React.FC<IProps> = ({ data }) => {
); );
useEffect(() => { useEffect(() => {
if (!editor) return; if (!editor || !visible) return;
const docJSON = safeJSONParse(data.content, { default: {} }).default; const docJSON = safeJSONParse(data.content, { default: {} }).default;
const titleNode = docJSON.content.find((item) => item.type === 'title');
docJSON.content = docJSON.content.filter((item) => item.type !== 'title'); docJSON.content = docJSON.content.filter((item) => item.type !== 'title');
setCover(titleNode.attrs.cover ?? '');
editor.commands.setContent(docJSON); editor.commands.setContent(docJSON);
}, [editor, data]); }, [editor, data, visible]);
const { Title } = Typography; const { Title } = Typography;
return ( return (
@ -109,7 +113,14 @@ export const DocumentFullscreen: React.FC<IProps> = ({ data }) => {
</Title> </Title>
</div> </div>
<div className={styles.content}> <div className={styles.content}>
<div className={styles.title}>{data.title || '未命名文档'}</div> <div className={styles.title}>
{cover && (
<div className={styles.imgCover}>
<img src={cover} alt="背景图" />
</div>
)}
<p>{data.title || '未命名文档'}</p>
</div>
<EditorContent editor={editor} /> <EditorContent editor={editor} />
</div> </div>
<DrawingCursor isDrawing={isDrawing} /> <DrawingCursor isDrawing={isDrawing} />

View File

@ -33,6 +33,11 @@ export const DocumentVersion: React.FC<Partial<IProps>> = ({ documentId, onSelec
const editor = useEditor({ const editor = useEditor({
editable: false, editable: false,
editorProps: {
attributes: {
class: 'is-editable',
},
},
extensions: CollaborationKit, extensions: CollaborationKit,
content: { type: 'doc', content: [] }, content: { type: 'doc', content: [] },
}); });

View File

@ -145,10 +145,10 @@ export const Dragable = Extension.create({
} }
const result = selectRootNodeByDom(dom, view); const result = selectRootNodeByDom(dom, view);
activeNode = result;
if ( if (
!result || !result ||
result.node.type.name === 'doc' ||
result.node.type.name === 'title' || result.node.type.name === 'title' ||
result.node.type.name === 'tableOfContents' || result.node.type.name === 'tableOfContents' ||
// empty paragraph // empty paragraph
@ -159,6 +159,8 @@ export const Dragable = Extension.create({
return false; return false;
} }
activeNode = result;
renderDragHandleDOM(view, result.el); renderDragHandleDOM(view, result.el);
return false; return false;
}, },

View File

@ -9,17 +9,25 @@
&::before { &::before {
position: absolute; position: absolute;
top: 0;
height: 0; height: 0;
color: var(--semi-color-text-0); color: var(--semi-color-text-0);
pointer-events: none; pointer-events: none;
content: attr(data-placeholder); content: attr(data-placeholder);
} }
}
&.is-withauthor {
.node-title::before {
bottom: 0;
transform: translateY(-4.2em);
}
}
&.is-editable { &.is-editable {
&::before { .node-title::before {
bottom: 0;
color: #aaa; color: #aaa;
} transform: translateY(-1.7em);
} }
} }
} }

View File

@ -54,6 +54,9 @@ export const EditorInstance = forwardRef((props: IProps, ref) => {
editorProps: { editorProps: {
// @ts-ignore // @ts-ignore
taskItemClickable: true, taskItemClickable: true,
attributes: {
class: 'is-withauthor',
},
}, },
extensions: [ extensions: [
...CollaborationKit, ...CollaborationKit,

View File

@ -72,6 +72,8 @@ const DocumentWithTitle = Document.extend({
content: 'title block+', content: 'title block+',
}); });
export { Document };
export const CollaborationKit = [ export const CollaborationKit = [
Paragraph, Paragraph,
Placeholder.configure({ Placeholder.configure({