mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-06 17:33:18 +00:00
@@ -1,28 +1,18 @@
|
||||
import React from 'react';
|
||||
import { SeafileEditor } from '@seafile/seafile-editor';
|
||||
import React, { Fragment } from 'react';
|
||||
import { SeafileEditor } from '@seafile/seafile-editor/dist/editor/editor.js';
|
||||
import 'whatwg-fetch';
|
||||
import { Value, Document, Block } from 'slate';
|
||||
import { seafileAPI } from './utils/seafile-api';
|
||||
import { Utils } from './utils/utils';
|
||||
import { gettext, isDocs } from './utils/constants';
|
||||
import io from 'socket.io-client';
|
||||
import toaster from './components/toast';
|
||||
import ModalPortal from './components/modal-portal';
|
||||
import EditFileTagDialog from './components/dialog/edit-filetag-dialog';
|
||||
import RelatedFileDialogs from './components/dialog/related-file-dialogs';
|
||||
import ShareDialog from './components/dialog/share-dialog';
|
||||
import CommentDialog from './components/markdown-view/comment-dialog';
|
||||
import InsertFileDialog from './components/dialog/insert-file-dialog';
|
||||
import MarkdownViewerSlate from '@seafile/seafile-editor/dist/viewer/markdown-viewer-slate';
|
||||
import { serialize, deserialize } from '@seafile/seafile-editor/dist/utils/slate2markdown';
|
||||
import LocalDraftDialog from './components/dialog/local-draft-dialog';
|
||||
import DiffViewer from '@seafile/seafile-editor/dist/viewer/diff-viewer';
|
||||
import MarkdownViewerToolbar from './components/toolbar/markdown-viewer-toolbar';
|
||||
import HistoryList from './components/markdown-view/history-list';
|
||||
import CommentPanel from './components/file-view/comment-panel';
|
||||
import OutlineView from './components/markdown-view/outline';
|
||||
import Loading from './components/loading';
|
||||
import { findRange } from '@seafile/slate-react';
|
||||
|
||||
import './css/markdown-viewer/markdown-editor.css';
|
||||
|
||||
@@ -274,7 +264,6 @@ class MarkdownEditor extends React.Component {
|
||||
this.draftPlainValue = '';
|
||||
this.state = {
|
||||
markdownContent: '',
|
||||
oldMarkdownContent: '',
|
||||
loading: true,
|
||||
mode: 'editor',
|
||||
fileInfo: {
|
||||
@@ -288,27 +277,20 @@ class MarkdownEditor extends React.Component {
|
||||
lastModifier: '',
|
||||
id: '',
|
||||
},
|
||||
editorMode: 'viewer',
|
||||
editorMode: 'rich',
|
||||
collabServer: seafileCollabServer ? seafileCollabServer : null,
|
||||
relatedFiles: [],
|
||||
fileTagList: [],
|
||||
localDraftDialog: false,
|
||||
showRelatedFileDialog: false,
|
||||
showEditFileTagDialog: false,
|
||||
showMarkdownEditorDialog: false,
|
||||
showShareLinkDialog: false,
|
||||
showCommentDialog: false,
|
||||
showInsertFileDialog: false,
|
||||
showDraftSaved: false,
|
||||
collabUsers: userInfo ?
|
||||
[{user: userInfo, is_editing: false}] : [],
|
||||
commentsNumber: null,
|
||||
loadingDiff: false,
|
||||
value: null,
|
||||
isShowComments: false,
|
||||
isShowHistory: false,
|
||||
isShowOutline: true,
|
||||
viewMode:'list_related_file',
|
||||
readOnly: true,
|
||||
};
|
||||
|
||||
if (this.state.collabServer) {
|
||||
@@ -389,11 +371,8 @@ class MarkdownEditor extends React.Component {
|
||||
|
||||
toggleCancel = () => {
|
||||
this.setState({
|
||||
showRelatedFileDialog: false,
|
||||
showEditFileTagDialog: false,
|
||||
showMarkdownEditorDialog: false,
|
||||
showShareLinkDialog: false,
|
||||
showCommentDialog: false,
|
||||
showInsertFileDialog: false,
|
||||
});
|
||||
}
|
||||
@@ -469,27 +448,8 @@ class MarkdownEditor extends React.Component {
|
||||
openDialogs = (option) => {
|
||||
switch(option)
|
||||
{
|
||||
case 'related_files':
|
||||
if (this.state.relatedFiles.length > 0) {
|
||||
this.setState({
|
||||
showRelatedFileDialog: true,
|
||||
showMarkdownEditorDialog: true,
|
||||
viewMode: 'list_related_file',
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.setState({
|
||||
showRelatedFileDialog: true,
|
||||
showMarkdownEditorDialog: true,
|
||||
viewMode: 'add_related_file',
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'tags':
|
||||
this.setState({
|
||||
showEditFileTagDialog: true,
|
||||
showMarkdownEditorDialog: true,
|
||||
});
|
||||
case 'help':
|
||||
window.richMarkdownEditor.showHelpDialog();
|
||||
break;
|
||||
case 'share_link':
|
||||
this.setState({
|
||||
@@ -497,12 +457,6 @@ class MarkdownEditor extends React.Component {
|
||||
showShareLinkDialog: true,
|
||||
});
|
||||
break;
|
||||
case 'comment':
|
||||
this.setState({
|
||||
showMarkdownEditorDialog: true,
|
||||
showCommentDialog: true,
|
||||
});
|
||||
break;
|
||||
case 'insert_file':
|
||||
this.setState({
|
||||
showMarkdownEditorDialog: true,
|
||||
@@ -525,7 +479,6 @@ class MarkdownEditor extends React.Component {
|
||||
contact_email: editorUtilities.contact_email,
|
||||
},
|
||||
});
|
||||
document.removeEventListener('selectionchange', this.setBtnPosition);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -562,7 +515,7 @@ class MarkdownEditor extends React.Component {
|
||||
// case1: If file is draft file
|
||||
// case2: If mode == 'edit' and the file has no draft
|
||||
// case3: The length of markDownContent is 1 when clear all content in editor and the file has no draft
|
||||
editorMode: (hasPermission && (isDraft || (isEditMode && !hasDraft) || (isBlankFile && !hasDraft))) ? 'rich' : 'viewer',
|
||||
readOnly: !(hasPermission && (isDraft || (isEditMode && !hasDraft) || (isBlankFile && !hasDraft))),
|
||||
value: value,
|
||||
});
|
||||
});
|
||||
@@ -587,11 +540,8 @@ class MarkdownEditor extends React.Component {
|
||||
});
|
||||
}
|
||||
this.checkDraft();
|
||||
this.listRelatedFiles();
|
||||
this.listFileTags();
|
||||
this.getCommentsNumber();
|
||||
|
||||
document.addEventListener('selectionchange', this.setBtnPosition);
|
||||
setTimeout(() => {
|
||||
let url = new URL(window.location.href);
|
||||
if (url.hash) {
|
||||
@@ -600,34 +550,6 @@ class MarkdownEditor extends React.Component {
|
||||
}, 100);
|
||||
}
|
||||
|
||||
listRelatedFiles = () => {
|
||||
seafileAPI.listRelatedFiles(repoID, filePath).then(res => {
|
||||
this.setState({
|
||||
relatedFiles: res.data.related_files
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
listFileTags = () => {
|
||||
seafileAPI.listFileTags(repoID, filePath).then(res => {
|
||||
let fileTagList = res.data.file_tags;
|
||||
for (let i = 0, length = fileTagList.length; i < length; i++) {
|
||||
fileTagList[i].id = fileTagList[i].file_tag_id;
|
||||
}
|
||||
this.setState({
|
||||
fileTagList: fileTagList
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onRelatedFileChange = () => {
|
||||
this.listRelatedFiles();
|
||||
}
|
||||
|
||||
onFileTagChanged = () => {
|
||||
this.listFileTags();
|
||||
}
|
||||
|
||||
setFileInfoMtime = (fileInfo) => {
|
||||
this.setState({
|
||||
fileInfo: Object.assign({}, this.state.fileInfo, { mtime: fileInfo.mtime, id: fileInfo.id, lastModifier: fileInfo.last_modifier_name })
|
||||
@@ -685,9 +607,12 @@ class MarkdownEditor extends React.Component {
|
||||
window.location.href = editorUtilities.getParentDectionaryUrl();
|
||||
}
|
||||
|
||||
onEdit = (event) => {
|
||||
event.preventDefault();
|
||||
this.setEditorMode('rich');
|
||||
onEdit = (mode) => {
|
||||
if (mode === 'rich') {
|
||||
window.seafileEditor.switchToRichTextEditor();
|
||||
} else if (mode === 'plain') {
|
||||
window.seafileEditor.switchToPlainTextEditor();
|
||||
}
|
||||
}
|
||||
|
||||
toggleShareLinkDialog = () => {
|
||||
@@ -708,242 +633,23 @@ class MarkdownEditor extends React.Component {
|
||||
this.toggleCancel();
|
||||
}
|
||||
|
||||
showDiffViewer = () => {
|
||||
this.setState({
|
||||
loadingDiff: false,
|
||||
});
|
||||
}
|
||||
|
||||
setDiffViewerContent = (markdownContent, oldMarkdownContent) => {
|
||||
this.setState({
|
||||
markdownContent: markdownContent,
|
||||
oldMarkdownContent: oldMarkdownContent
|
||||
});
|
||||
this.showDiffViewer();
|
||||
}
|
||||
|
||||
reloadDiffContent = () =>{
|
||||
this.setState({
|
||||
loadingDiff: true,
|
||||
});
|
||||
}
|
||||
|
||||
setBtnPosition = (e) => {
|
||||
if (!this.state.isShowComments) return;
|
||||
const nativeSelection = window.getSelection();
|
||||
if (!nativeSelection.rangeCount) {
|
||||
this.range = null;
|
||||
return;
|
||||
}
|
||||
if (nativeSelection.isCollapsed === false) {
|
||||
const nativeRange = nativeSelection.getRangeAt(0);
|
||||
const focusNode = nativeSelection.focusNode;
|
||||
if ((focusNode.tagName === 'I') ||
|
||||
(focusNode.nodeType !== 3 && focusNode.getAttribute('class') === 'language-type')) {
|
||||
// fix select last paragraph
|
||||
let fragment = nativeRange.cloneContents();
|
||||
let startNode = fragment.firstChild.firstChild;
|
||||
if (!startNode) return;
|
||||
let newNativeRange = document.createRange();
|
||||
newNativeRange.setStartBefore(startNode);
|
||||
newNativeRange.setEndAfter(startNode);
|
||||
|
||||
let editor = {value: this.state.value};
|
||||
this.range = findRange(nativeRange, editor);
|
||||
}
|
||||
|
||||
else {
|
||||
let editor = {value: this.state.value};
|
||||
this.range = findRange(nativeRange, editor);
|
||||
}
|
||||
if (!this.range) return;
|
||||
let rect = nativeRange.getBoundingClientRect();
|
||||
// fix Safari bug
|
||||
if (navigator.userAgent.indexOf('Chrome') < 0 && navigator.userAgent.indexOf('Safari') > 0) {
|
||||
if (nativeRange.collapsed && rect.top == 0 && rect.height == 0) {
|
||||
if (nativeRange.startOffset == 0) {
|
||||
nativeRange.setEnd(nativeRange.endContainer, 1);
|
||||
} else {
|
||||
nativeRange.setStart(nativeRange.startContainer, nativeRange.startOffset - 1);
|
||||
}
|
||||
rect = nativeRange.getBoundingClientRect();
|
||||
if (rect.top == 0 && rect.height == 0) {
|
||||
if (nativeRange.getClientRects().length) {
|
||||
rect = nativeRange.getClientRects()[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let style = this.refs.commentbtn.style;
|
||||
style.top = `${rect.top - 63 + this.refs.markdownContainer.scrollTop}px`;
|
||||
style.right = '0px';
|
||||
}
|
||||
else {
|
||||
let style = this.refs.commentbtn.style;
|
||||
style.top = '-1000px';
|
||||
}
|
||||
}
|
||||
|
||||
addComment = (e) => {
|
||||
e.stopPropagation();
|
||||
this.getQuote();
|
||||
this.openDialogs('comment');
|
||||
}
|
||||
|
||||
getQuote = () => {
|
||||
let range = this.range;
|
||||
if (!range) return;
|
||||
const { document } = this.state.value;
|
||||
let { anchor, focus } = range;
|
||||
const anchorText = document.getNode(anchor.key);
|
||||
const focusText = document.getNode(focus.key);
|
||||
const anchorInline = document.getClosestInline(anchor.key);
|
||||
const focusInline = document.getClosestInline(focus.key);
|
||||
// COMPAT: If the selection is at the end of a non-void inline node, and
|
||||
// there is a node after it, put it in the node after instead. This
|
||||
// standardizes the behavior, since it's indistinguishable to the user.
|
||||
if (anchorInline && anchor.offset == anchorText.text.length) {
|
||||
const block = document.getClosestBlock(anchor.key);
|
||||
const nextText = block.getNextText(anchor.key);
|
||||
if (nextText) {
|
||||
range = range.moveAnchorTo(nextText.key, 0);
|
||||
}
|
||||
}
|
||||
if (focusInline && focus.offset == focusText.text.length) {
|
||||
const block = document.getClosestBlock(focus.key);
|
||||
const nextText = block.getNextText(focus.key);
|
||||
if (nextText) {
|
||||
range = range.moveFocusTo(nextText.key, 0);
|
||||
}
|
||||
}
|
||||
let fragment = document.getFragmentAtRange(range);
|
||||
let nodes = this.removeNullNode(fragment.nodes);
|
||||
let newFragment = Document.create({
|
||||
nodes: nodes
|
||||
});
|
||||
let newValue = Value.create({
|
||||
document: newFragment
|
||||
});
|
||||
this.quote = serialize(newValue.toJSON());
|
||||
let selection = document.createSelection(range);
|
||||
selection = selection.setIsFocused(true);
|
||||
this.setState({
|
||||
commentPosition: selection.anchor.path
|
||||
});
|
||||
}
|
||||
|
||||
removeNullNode = (oldNodes) => {
|
||||
let newNodes = [];
|
||||
oldNodes.map((node) => {
|
||||
const text = node.text.trim();
|
||||
const childNodes = node.nodes;
|
||||
if (!text) return;
|
||||
if ((childNodes && childNodes.size === 1) || (!childNodes)) {
|
||||
newNodes.push(node);
|
||||
}
|
||||
else if (childNodes.size > 1) {
|
||||
let nodes = this.removeNullNode(childNodes);
|
||||
let newNode = Block.create({
|
||||
nodes: nodes,
|
||||
data: node.data,
|
||||
key: node.key,
|
||||
type: node.type
|
||||
});
|
||||
newNodes.push(newNode);
|
||||
}
|
||||
});
|
||||
return newNodes;
|
||||
}
|
||||
|
||||
scrollToNode = (node) => {
|
||||
let url = new URL(window.location.href);
|
||||
url.set('hash', 'user-content-' + node.text);
|
||||
window.location.href = url.toString();
|
||||
}
|
||||
|
||||
findScrollContainer = (el, window) => {
|
||||
let parent = el.parentNode;
|
||||
const OVERFLOWS = ['auto', 'overlay', 'scroll'];
|
||||
let scroller;
|
||||
while (!scroller) {
|
||||
if (!parent.parentNode) break;
|
||||
const style = window.getComputedStyle(parent);
|
||||
const { overflowY } = style;
|
||||
if (OVERFLOWS.includes(overflowY)) {
|
||||
scroller = parent;
|
||||
break;
|
||||
}
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
if (!scroller) {
|
||||
return window.document.body;
|
||||
}
|
||||
return scroller;
|
||||
}
|
||||
|
||||
scrollToQuote = (path) => {
|
||||
if (!path) return;
|
||||
const win = window;
|
||||
if (path.length > 2) {
|
||||
// deal with code block or chart
|
||||
path[0] = path[0] > 1 ? path[0] - 1 : path[0] + 1;
|
||||
path = path.slice(0, 1);
|
||||
}
|
||||
let node = this.state.value.document.getNode(path);
|
||||
if (!node) {
|
||||
path = path.slice(0, 1);
|
||||
node = this.state.value.document.getNode(path);
|
||||
}
|
||||
if (node) {
|
||||
let element = win.document.querySelector(`[data-key="${node.key}"]`);
|
||||
while (element.tagName === 'CODE') {
|
||||
element = element.parentNode;
|
||||
}
|
||||
const scroller = this.findScrollContainer(element, win);
|
||||
const isWindow = scroller == win.document.body || scroller == win.document.documentElement;
|
||||
if (isWindow) {
|
||||
win.scrollTo(0, element.offsetTop);
|
||||
} else {
|
||||
scroller.scrollTop = element.offsetTop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toggleHistory = () => {
|
||||
if (!isDocs) {
|
||||
window.location.href = siteRoot + 'repo/file_revisions/' + repoID + '/?p=' + Utils.encodePath(filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.state.isShowHistory) {
|
||||
this.setState({
|
||||
isShowHistory: false,
|
||||
isShowOutline: true,
|
||||
isShowComments: false,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
isShowHistory: true,
|
||||
isShowOutline: false,
|
||||
isShowComments: false,
|
||||
});
|
||||
}
|
||||
window.location.href = siteRoot + 'repo/file_revisions/' + repoID + '/?p=' + Utils.encodePath(filePath);
|
||||
}
|
||||
|
||||
toggleCommentList = () => {
|
||||
if (this.state.isShowComments) {
|
||||
this.setState({
|
||||
isShowHistory: false,
|
||||
isShowOutline: true,
|
||||
isShowComments: false,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
isShowHistory: false,
|
||||
isShowOutline: false,
|
||||
isShowComments: true,
|
||||
});
|
||||
}
|
||||
this.setState({ isShowComments: !this.state.isShowComments });
|
||||
}
|
||||
|
||||
getInsertLink = (repoID, filePath) => {
|
||||
@@ -965,8 +671,6 @@ class MarkdownEditor extends React.Component {
|
||||
render() {
|
||||
let component;
|
||||
let sidePanel = this.state.isShowHistory ? true : false;
|
||||
let markdownViewer = sidePanel ? 'seafile-md-viewer-slate side-panel-on' :
|
||||
(this.state.isShowComments ? 'seafile-md-viewer-slate comment-on' : 'seafile-md-viewer-slate');
|
||||
if (this.state.loading) {
|
||||
return (
|
||||
<div className="empty-loading-page">
|
||||
@@ -974,109 +678,61 @@ class MarkdownEditor extends React.Component {
|
||||
</div>
|
||||
);
|
||||
} else if (this.state.mode === 'editor') {
|
||||
if (this.state.editorMode === 'viewer') {
|
||||
component = (
|
||||
<div className="seafile-md-viewer d-flex flex-column">
|
||||
<MarkdownViewerToolbar
|
||||
isDocs={isDocs}
|
||||
hasDraft={hasDraft}
|
||||
isDraft={isDraft}
|
||||
editorUtilities={editorUtilities}
|
||||
collabUsers={this.state.collabUsers}
|
||||
fileInfo={this.state.fileInfo}
|
||||
toggleStar={this.toggleStar}
|
||||
backToParentDirectory={this.backToParentDirectory}
|
||||
openDialogs={this.openDialogs}
|
||||
fileTagList={this.state.fileTagList}
|
||||
relatedFiles={this.state.relatedFiles}
|
||||
toggleShareLinkDialog={this.toggleShareLinkDialog}
|
||||
onEdit={this.onEdit}
|
||||
toggleNewDraft={editorUtilities.createDraftFile}
|
||||
commentsNumber={this.state.commentsNumber}
|
||||
toggleCommentList={this.toggleCommentList}
|
||||
showFileHistory={this.state.isShowHistory ? false : true }
|
||||
toggleHistory={this.toggleHistory}
|
||||
/>
|
||||
<div className="seafile-md-viewer d-flex">
|
||||
<div className={sidePanel ? 'seafile-md-viewer-container side-panel-on' : 'seafile-md-viewer-container'} ref="markdownContainer">
|
||||
{
|
||||
this.state.isShowHistory ?
|
||||
<div className="diff-container">
|
||||
<div className="diff-wrapper article">
|
||||
{ this.state.loadingDiff ?
|
||||
<Loading/> :
|
||||
<DiffViewer
|
||||
newMarkdownContent={this.state.markdownContent}
|
||||
oldMarkdownContent={this.state.oldMarkdownContent}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div className={markdownViewer}>
|
||||
<MarkdownViewerSlate
|
||||
relatedFiles={this.state.relatedFiles}
|
||||
siteRoot={siteRoot}
|
||||
value={this.state.value}
|
||||
/>
|
||||
{this.state.isShowComments &&
|
||||
<i className="fa fa-plus-square seafile-viewer-comment-btn" ref="commentbtn" onMouseDown={this.addComment}></i>}
|
||||
</div>
|
||||
}
|
||||
{
|
||||
this.state.isShowOutline &&
|
||||
<OutlineView
|
||||
isViewer={true}
|
||||
document={this.state.value.document}
|
||||
scrollToNode={this.scrollToNode}
|
||||
/>
|
||||
}
|
||||
{this.state.isShowComments &&
|
||||
<CommentPanel toggleCommentPanel={this.toggleCommentList} commentsNumber={this.state.commentsNumber}/>}
|
||||
</div>
|
||||
<div className="seafile-md-viewer-side-panel">
|
||||
{
|
||||
this.state.isShowHistory &&
|
||||
<HistoryList
|
||||
editorUtilities={editorUtilities}
|
||||
showDiffViewer={this.showDiffViewer}
|
||||
setDiffViewerContent={this.setDiffViewerContent}
|
||||
reloadDiffContent={this.reloadDiffContent}
|
||||
toggleHistoryPanel={this.toggleHistory}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
component = (
|
||||
<Fragment>
|
||||
<MarkdownViewerToolbar
|
||||
isDocs={isDocs}
|
||||
hasDraft={hasDraft}
|
||||
isDraft={isDraft}
|
||||
editorUtilities={editorUtilities}
|
||||
collabUsers={this.state.collabUsers}
|
||||
fileInfo={this.state.fileInfo}
|
||||
toggleStar={this.toggleStar}
|
||||
backToParentDirectory={this.backToParentDirectory}
|
||||
openDialogs={this.openDialogs}
|
||||
toggleShareLinkDialog={this.toggleShareLinkDialog}
|
||||
onEdit={this.onEdit}
|
||||
toggleNewDraft={editorUtilities.createDraftFile}
|
||||
commentsNumber={this.state.commentsNumber}
|
||||
toggleCommentList={this.toggleCommentList}
|
||||
showFileHistory={this.state.isShowHistory ? false : true }
|
||||
toggleHistory={this.toggleHistory}
|
||||
readOnly={this.state.readOnly}
|
||||
mode={this.state.mode}
|
||||
editorMode={this.state.editorMode}
|
||||
/>
|
||||
<SeafileEditor
|
||||
fileInfo={this.state.fileInfo}
|
||||
markdownContent={this.state.markdownContent}
|
||||
editorUtilities={editorUtilities}
|
||||
collabUsers={this.state.collabUsers}
|
||||
setFileInfoMtime={this.setFileInfoMtime}
|
||||
toggleStar={this.toggleStar}
|
||||
showFileHistory={true}
|
||||
setEditorMode={this.setEditorMode}
|
||||
setContent={this.setContent}
|
||||
draftID={draftID}
|
||||
isDraft={isDraft}
|
||||
mode={this.state.mode}
|
||||
emitSwitchEditor={this.emitSwitchEditor}
|
||||
hasDraft={hasDraft}
|
||||
editorMode={this.state.editorMode}
|
||||
siteRoot={siteRoot}
|
||||
autoSaveDraft={this.autoSaveDraft}
|
||||
setDraftValue={this.setDraftValue}
|
||||
clearTimer={this.clearTimer}
|
||||
openDialogs={this.openDialogs}
|
||||
deleteDraft={this.deleteDraft}
|
||||
showDraftSaved={this.state.showDraftSaved}
|
||||
readOnly={this.state.readOnly}
|
||||
/>
|
||||
{this.state.isShowComments &&
|
||||
<div className="seafile-md-comment">
|
||||
<CommentPanel toggleCommentPanel={this.toggleCommentList} commentsNumber={this.state.commentsNumber}/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
component = <SeafileEditor
|
||||
fileInfo={this.state.fileInfo}
|
||||
markdownContent={this.state.markdownContent}
|
||||
editorUtilities={editorUtilities}
|
||||
collabUsers={this.state.collabUsers}
|
||||
setFileInfoMtime={this.setFileInfoMtime}
|
||||
toggleStar={this.toggleStar}
|
||||
showFileHistory={true}
|
||||
setEditorMode={this.setEditorMode}
|
||||
setContent={this.setContent}
|
||||
draftID={draftID}
|
||||
isDraft={isDraft}
|
||||
mode={this.state.mode}
|
||||
emitSwitchEditor={this.emitSwitchEditor}
|
||||
hasDraft={hasDraft}
|
||||
editorMode={this.state.editorMode}
|
||||
relatedFiles={this.state.relatedFiles}
|
||||
siteRoot={siteRoot}
|
||||
autoSaveDraft={this.autoSaveDraft}
|
||||
setDraftValue={this.setDraftValue}
|
||||
clearTimer={this.clearTimer}
|
||||
openDialogs={this.openDialogs}
|
||||
fileTagList={this.state.fileTagList}
|
||||
deleteDraft={this.deleteDraft}
|
||||
showDraftSaved={this.state.showDraftSaved}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
@@ -1093,30 +749,6 @@ class MarkdownEditor extends React.Component {
|
||||
{component}
|
||||
{this.state.showMarkdownEditorDialog && (
|
||||
<React.Fragment>
|
||||
{this.state.showEditFileTagDialog &&
|
||||
<ModalPortal>
|
||||
<EditFileTagDialog
|
||||
repoID={repoID}
|
||||
filePath={filePath}
|
||||
fileTagList={this.state.fileTagList}
|
||||
toggleCancel={this.toggleCancel}
|
||||
onFileTagChanged={this.onFileTagChanged}
|
||||
/>
|
||||
</ModalPortal>
|
||||
}
|
||||
{this.state.showRelatedFileDialog &&
|
||||
<ModalPortal>
|
||||
<RelatedFileDialogs
|
||||
repoID={repoID}
|
||||
filePath={filePath}
|
||||
relatedFiles={this.state.relatedFiles}
|
||||
toggleCancel={this.toggleCancel}
|
||||
onRelatedFileChange={this.onRelatedFileChange}
|
||||
dirent={this.state.fileInfo}
|
||||
viewMode={this.state.viewMode}
|
||||
/>
|
||||
</ModalPortal>
|
||||
}
|
||||
{this.state.showInsertFileDialog &&
|
||||
<ModalPortal>
|
||||
<InsertFileDialog
|
||||
@@ -1140,17 +772,6 @@ class MarkdownEditor extends React.Component {
|
||||
/>
|
||||
</ModalPortal>
|
||||
}
|
||||
{this.state.showCommentDialog &&
|
||||
<ModalPortal>
|
||||
<CommentDialog
|
||||
toggleCommentDialog={this.toggleCancel}
|
||||
editorUtilities={editorUtilities}
|
||||
onCommentAdded={this.onCommentAdded}
|
||||
commentPosition={this.state.commentPosition}
|
||||
quote={this.quote}
|
||||
/>
|
||||
</ModalPortal>
|
||||
}
|
||||
</React.Fragment>
|
||||
)}
|
||||
</React.Fragment>
|
||||
|
Reference in New Issue
Block a user