@seafile/sdoc-editor 0.1.104 → 0.1.106

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,20 +1,33 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
- import React, { useCallback, useRef, useState } from 'react';
2
+ import classNames from 'classnames';
3
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
4
  import { withTranslation } from 'react-i18next';
5
+ import { Button } from 'reactstrap';
6
+ var getSubmitTip = function getSubmitTip(type, content) {
7
+ if (content) return 'Save';
8
+ return type === 'comment' ? 'Comment' : 'Reply';
9
+ };
4
10
  var CommentEditor = function CommentEditor(_ref) {
5
- var content = _ref.content,
11
+ var type = _ref.type,
12
+ className = _ref.className,
13
+ content = _ref.content,
6
14
  placeholder = _ref.placeholder,
7
15
  insertContent = _ref.insertContent,
8
16
  updateContent = _ref.updateContent,
9
17
  setIsEditing = _ref.setIsEditing,
10
18
  t = _ref.t;
11
- var inputRef = useRef();
12
- var _useState = useState(content || ''),
19
+ var commentRef = useRef();
20
+ var _useState = useState(false),
13
21
  _useState2 = _slicedToArray(_useState, 2),
14
- value = _useState2[0],
15
- setValue = _useState2[1];
16
- var onChange = useCallback(function (event) {
17
- setValue(event.target.value);
22
+ isFocus = _useState2[0],
23
+ setIsFocus = _useState2[1];
24
+
25
+ // onMount
26
+ useEffect(function () {
27
+ if (content) {
28
+ commentRef.current.innerHTML = content;
29
+ }
30
+ // eslint-disable-next-line react-hooks/exhaustive-deps
18
31
  }, []);
19
32
  var updateValue = useCallback(function (value) {
20
33
  if (!value || value.trim() === '') return;
@@ -24,30 +37,53 @@ var CommentEditor = function CommentEditor(_ref) {
24
37
  }
25
38
  updateContent(value);
26
39
  }, [content, insertContent, updateContent]);
27
- var onBlur = useCallback(function () {
40
+ var onSubmit = useCallback(function (event) {
41
+ event && event.stopPropagation();
42
+ var value = commentRef.current.innerHTML;
28
43
  updateValue(value);
29
- setValue('');
30
- }, [updateValue, value]);
44
+ commentRef.current.innerHTML = '';
45
+ }, [updateValue]);
46
+ var onCancel = useCallback(function (event) {
47
+ event.stopPropagation();
48
+ setIsFocus(false);
49
+ commentRef.current.innerHTML = '';
50
+ setIsEditing && setIsEditing(false);
51
+ }, [setIsEditing]);
31
52
  var onKeyDown = useCallback(function (event) {
32
53
  // enter
33
54
  if (event.keyCode === 13) {
34
- inputRef.current.blur();
55
+ event.preventDefault();
56
+ onSubmit();
35
57
  }
36
58
  if (event.keyCode === 27) {
37
- setValue('');
38
- setIsEditing && setIsEditing(false);
59
+ event.preventDefault();
60
+ onCancel();
39
61
  }
40
- }, [setIsEditing]);
62
+ }, [onCancel, onSubmit]);
41
63
  placeholder = t(placeholder);
42
- return /*#__PURE__*/React.createElement("input", {
43
- ref: inputRef,
64
+ var submitTip = useMemo(function () {
65
+ return getSubmitTip(type, content);
66
+ }, [content, type]);
67
+ return /*#__PURE__*/React.createElement("div", {
68
+ className: classNames('comment-editor-wrapper', className)
69
+ }, /*#__PURE__*/React.createElement("div", {
70
+ ref: commentRef,
71
+ contentEditable: "true",
44
72
  className: "comment-editor",
45
- value: value,
46
73
  placeholder: placeholder,
47
- onChange: onChange,
48
74
  onKeyDown: onKeyDown,
49
- onBlur: onBlur
50
- });
75
+ onFocus: function onFocus() {
76
+ return setIsFocus(true);
77
+ }
78
+ }), isFocus && /*#__PURE__*/React.createElement("div", {
79
+ className: "editor-operations"
80
+ }, /*#__PURE__*/React.createElement(Button, {
81
+ className: "mr-2",
82
+ onClick: onCancel
83
+ }, t('Cancel')), /*#__PURE__*/React.createElement(Button, {
84
+ color: "primary",
85
+ onClick: onSubmit
86
+ }, t(submitTip))));
51
87
  };
52
88
  CommentEditor.defaultProps = {
53
89
  placeholder: 'Enter_a_comment'
@@ -1,6 +1,6 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
- import React, { useCallback, useMemo, useRef, useState } from 'react';
3
+ import React, { useCallback, useMemo, useState } from 'react';
4
4
  import { withTranslation } from 'react-i18next';
5
5
  import { Dropdown, DropdownItem, DropdownMenu, DropdownToggle, UncontrolledTooltip } from 'reactstrap';
6
6
  import dayjs from 'dayjs';
@@ -121,10 +121,11 @@ var CommentItem = function CommentItem(_ref) {
121
121
  onClick: resubmit
122
122
  }, t('Resubmit')))))), /*#__PURE__*/React.createElement("div", {
123
123
  className: "comment-content"
124
- }, isEditing && /*#__PURE__*/React.createElement(CommentEditor, {
124
+ }, !isEditing && /*#__PURE__*/React.createElement(React.Fragment, null, comment.comment)), isEditing && /*#__PURE__*/React.createElement(CommentEditor, {
125
+ className: 'pb-3',
125
126
  content: comment.comment,
126
127
  updateContent: updateContent,
127
128
  setIsEditing: setIsEditing
128
- }), !isEditing && /*#__PURE__*/React.createElement(React.Fragment, null, comment.comment)));
129
+ }));
129
130
  };
130
131
  export default withTranslation('sdoc-editor')(CommentItem);
@@ -1,7 +1,7 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
- import React, { useCallback, useMemo, useRef, useState } from 'react';
2
+ import React, { useCallback, useState } from 'react';
3
3
  import { withTranslation } from 'react-i18next';
4
- import { Dropdown, DropdownItem, DropdownMenu, DropdownToggle, PopoverBody, UncontrolledPopover } from 'reactstrap';
4
+ import { Dropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap';
5
5
  import dayjs from 'dayjs';
6
6
  import context from '../../../context';
7
7
  import CommentEditor from './comment-editor';
@@ -86,11 +86,13 @@ var CommentItemReply = function CommentItemReply(_ref) {
86
86
  onClick: onDeleteToggle
87
87
  }, t('Delete')))))), /*#__PURE__*/React.createElement("div", {
88
88
  className: "comment-content"
89
- }, isEditing && /*#__PURE__*/React.createElement(CommentEditor, {
89
+ }, !isEditing && /*#__PURE__*/React.createElement(React.Fragment, null, reply.reply)), isEditing && /*#__PURE__*/React.createElement(CommentEditor, {
90
+ className: 'pb-3',
91
+ type: "reply",
90
92
  content: reply.reply,
91
93
  updateContent: updateContent,
92
94
  setIsEditing: setIsEditing
93
- }), !isEditing && /*#__PURE__*/React.createElement(React.Fragment, null, reply.reply)), isShowDeleteDialog && isActive && /*#__PURE__*/React.createElement(CommentDeleteShadow, {
95
+ }), isShowDeleteDialog && isActive && /*#__PURE__*/React.createElement(CommentDeleteShadow, {
94
96
  type: "reply",
95
97
  deleteConfirm: _deleteReply,
96
98
  setIsShowDeleteModal: setIsShowDeleteDialog
@@ -198,7 +198,11 @@ export default function CommentItemWrapper(_ref) {
198
198
  });
199
199
  case 18:
200
200
  setTimeout(function () {
201
- listRef.current.scrollTop = 10000;
201
+ var options = {
202
+ top: 10000,
203
+ behavior: 'smooth'
204
+ };
205
+ listRef.current.scrollTo(options);
202
206
  }, 0);
203
207
  case 19:
204
208
  case "end":
@@ -352,12 +356,12 @@ export default function CommentItemWrapper(_ref) {
352
356
  key: reply.id,
353
357
  reply: reply
354
358
  });
355
- })), isActive && /*#__PURE__*/React.createElement("div", {
356
- className: "comment-editor-wrapper mt-4"
357
- }, /*#__PURE__*/React.createElement(CommentEditor, {
359
+ })), isActive && /*#__PURE__*/React.createElement(CommentEditor, {
360
+ className: "mt-4",
361
+ type: "reply",
358
362
  placeholder: tip,
359
363
  insertContent: insertContent
360
- })), isShowDeleteDialog && isActive && /*#__PURE__*/React.createElement(CommentDeleteShadow, {
364
+ }), isShowDeleteDialog && isActive && /*#__PURE__*/React.createElement(CommentDeleteShadow, {
361
365
  type: 'comment',
362
366
  deleteConfirm: _deleteComment,
363
367
  setIsShowDeleteModal: setIsShowDeleteDialog
@@ -63,6 +63,8 @@
63
63
  padding-bottom: 10px;
64
64
  margin-top: 10px;
65
65
  margin-left: 30px;
66
+ width: 222px;
67
+ word-break: break-all;
66
68
  }
67
69
 
68
70
  .sdoc-comment-list-container .comment-header .comment-author__avatar {
@@ -158,18 +160,22 @@
158
160
 
159
161
  .sdoc-comment-list-container .comment-editor-wrapper {
160
162
  display: flex;
161
- align-items: center;
163
+ flex-direction: column;
162
164
  justify-content: center;
163
165
  padding: 0 16px;
166
+ cursor: text;
164
167
  }
165
168
 
166
169
  .sdoc-comment-list-container .comment-editor-wrapper .comment-editor {
167
- height: 40px;
168
- width: 248px;
170
+ margin-bottom: 10px;
171
+ min-height: 40px;
172
+ max-height: 120px;
173
+ overflow: auto;
169
174
  background: #fff;
170
175
  border: 1px solid rgba(0, 0, 0, .12);
171
176
  border-radius: 4px;
172
177
  padding: 8px;
178
+ word-break: break-all;
173
179
  }
174
180
 
175
181
  .sdoc-comment-list-container .comment-editor-wrapper .comment-editor:focus-visible {
@@ -107,11 +107,10 @@ var CommentList = function CommentList(_ref) {
107
107
  return /*#__PURE__*/React.createElement(CommentItemWrapper, props);
108
108
  })), comments.length === 0 && /*#__PURE__*/React.createElement("div", {
109
109
  className: "comment-ui-container active"
110
- }, /*#__PURE__*/React.createElement("div", {
111
- className: "comment-editor-wrapper"
112
110
  }, /*#__PURE__*/React.createElement(CommentEditor, {
111
+ type: "comment",
113
112
  insertContent: insertContent,
114
113
  selectionElement: selectionElement
115
- }))));
114
+ })));
116
115
  };
117
116
  export default CommentList;
@@ -1,5 +1,5 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
- import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import React, { useCallback, useEffect, useMemo, useRef, useState, forwardRef, useImperativeHandle } from 'react';
3
3
  import { Editable, ReactEditor, Slate } from '@seafile/slate-react';
4
4
  import defaultEditor, { renderLeaf, renderElement, Toolbar, ContextToolbar } from './extension';
5
5
  import { focusEditor, getAboveBlockNode, getNextNode, getPrevNode, isSelectionAtBlockEnd, isSelectionAtBlockStart } from './extension/core';
@@ -20,7 +20,7 @@ import { ColorProvider } from './hooks/use-color-context';
20
20
  import './assets/css/layout.css';
21
21
  import './assets/css/sdoc-editor-plugins.css';
22
22
  import './assets/css/dropdown-menu.css';
23
- var SDocEditor = function SDocEditor(_ref) {
23
+ var SDocEditor = forwardRef(function (_ref, ref) {
24
24
  var document = _ref.document,
25
25
  config = _ref.config;
26
26
  // init editor
@@ -51,6 +51,16 @@ var SDocEditor = function SDocEditor(_ref) {
51
51
  return new EventProxy(editor);
52
52
  }, []);
53
53
 
54
+ // The parent component can call the method of this component through ref
55
+ useImperativeHandle(ref, function () {
56
+ return {
57
+ // get latest value
58
+ getValue: function getValue() {
59
+ return slateValue;
60
+ }
61
+ };
62
+ }, [slateValue]);
63
+
54
64
  // useMount: init socket connection
55
65
  useEffect(function () {
56
66
  editor.openConnection();
@@ -246,5 +256,5 @@ var SDocEditor = function SDocEditor(_ref) {
246
256
  decorate: decorate,
247
257
  onCut: eventProxy.onCut
248
258
  })), /*#__PURE__*/React.createElement(CommentWrapper, null)))))))))));
249
- };
259
+ });
250
260
  export default SDocEditor;
@@ -89,6 +89,7 @@ var CodeBlock = function CodeBlock(_ref) {
89
89
  }, []);
90
90
  var onScroll = useCallback(function (e) {
91
91
  if (readOnly) return;
92
+ if (!showHoverMenu) return;
92
93
  if (e.currentTarget.scrollTop) {
93
94
  var _codeBlockRef$current2 = codeBlockRef.current.getBoundingClientRect(),
94
95
  top = _codeBlockRef$current2.top,
@@ -101,17 +102,18 @@ var CodeBlock = function CodeBlock(_ref) {
101
102
 
102
103
  setMenuPosition(newMenuPosition);
103
104
  }
104
- // eslint-disable-next-line react-hooks/exhaustive-deps
105
- }, []);
105
+ }, [readOnly, showHoverMenu]);
106
106
  useEffect(function () {
107
107
  if (readOnly) return;
108
- if (showHoverMenu) {
109
- scrollRef.current && scrollRef.current.addEventListener('scroll', onScroll);
110
- } else {
111
- scrollRef.current && scrollRef.current.removeEventListener('scroll', onScroll);
108
+ var observerRefValue = null;
109
+ if (scrollRef.current) {
110
+ scrollRef.current.addEventListener('scroll', onScroll);
111
+ observerRefValue = scrollRef.current;
112
112
  }
113
- // eslint-disable-next-line react-hooks/exhaustive-deps
114
- }, [showHoverMenu]);
113
+ return function () {
114
+ observerRefValue.removeEventListener('scroll', onScroll);
115
+ };
116
+ }, [onScroll, readOnly, scrollRef]);
115
117
  var isEntering = useCallback(function (e) {
116
118
  return !editor.operations.every(function (operation) {
117
119
  return operation.type === 'set_selection';
@@ -1,6 +1,8 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
1
2
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
- import React, { useCallback, useEffect, useState } from 'react';
3
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
3
4
  import { withTranslation } from 'react-i18next';
5
+ import deepCopy from 'deep-copy';
4
6
  import { SDocEditor } from '../basic-sdk';
5
7
  import Loading from '../components/loading';
6
8
  import DocInfo from '../components/doc-info';
@@ -15,6 +17,7 @@ var SimpleEditor = function SimpleEditor(_ref) {
15
17
  var isStarred = _ref.isStarred,
16
18
  isDraft = _ref.isDraft,
17
19
  t = _ref.t;
20
+ var editorRef = useRef(null);
18
21
  var _useState = useState(true),
19
22
  _useState2 = _slicedToArray(_useState, 2),
20
23
  isFirstLoad = _useState2[0],
@@ -77,35 +80,28 @@ var SimpleEditor = function SimpleEditor(_ref) {
77
80
  var initChangesData = useCallback(function () {
78
81
  setShowChanges(true);
79
82
  context.getSeadocRevisionDownloadLinks().then(function (res) {
80
- var _res$data = res.data,
81
- fileDownloadLink = _res$data.file_download_link,
82
- originFileDownloadLink = _res$data.origin_file_download_link;
83
- fetch(fileDownloadLink).then(function (res) {
84
- return res.json();
85
- }).then(function (revisionContent) {
86
- fetch(originFileDownloadLink).then(function (res) {
87
- return res.json();
88
- }).then(function (originContent) {
89
- setCurrentContent(revisionContent);
90
- setLastContent(originContent);
91
- setErrorMessage(null);
92
- setContextInit(true);
93
- }).catch(function (error) {
94
- setErrorMessage('Load_doc_content_error');
95
- setContextInit(true);
96
- });
97
- }).catch(function (error) {
98
- setErrorMessage('Load_doc_content_error');
99
- setContextInit(true);
100
- });
83
+ var originFileDownloadLink = res.data.origin_file_download_link;
84
+ return fetch(originFileDownloadLink);
85
+ }).then(function (res) {
86
+ return res.json();
87
+ }).then(function (originContent) {
88
+ setLastContent(originContent);
89
+ setErrorMessage(null);
90
+ setContextInit(true);
101
91
  }).catch(function (error) {
102
92
  setErrorMessage('Load_doc_content_error');
103
93
  setContextInit(true);
104
94
  });
105
95
 
106
96
  // eslint-disable-next-line react-hooks/exhaustive-deps
107
- }, []);
97
+ }, [document]);
108
98
  var toggleViewChanges = useCallback(function (isShowChanges) {
99
+ if (isShowChanges) {
100
+ var newestValue = editorRef.current.getValue();
101
+ setCurrentContent(deepCopy(_objectSpread(_objectSpread({}, document), {}, {
102
+ children: newestValue
103
+ })));
104
+ }
109
105
  setContextInit(false);
110
106
  if (isShowChanges) {
111
107
  initChangesData();
@@ -114,7 +110,7 @@ var SimpleEditor = function SimpleEditor(_ref) {
114
110
  initDocumentData(false);
115
111
 
116
112
  // eslint-disable-next-line react-hooks/exhaustive-deps
117
- }, []);
113
+ }, [document]);
118
114
  if (isFirstLoad && !isContextInit) {
119
115
  return /*#__PURE__*/React.createElement(Loading, null);
120
116
  }
@@ -140,6 +136,7 @@ var SimpleEditor = function SimpleEditor(_ref) {
140
136
  }) : /*#__PURE__*/React.createElement(SDocEditor, {
141
137
  config: context.getEditorConfig(),
142
138
  document: document,
139
+ ref: editorRef,
143
140
  isOpenSocket: context.getSetting('isOpenSocket')
144
141
  })))));
145
142
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.1.104",
3
+ "version": "0.1.106",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -94,6 +94,8 @@
94
94
  "Publish": "Publish",
95
95
  "This_file_has_a_draft": "This file has a draft.",
96
96
  "Delete": "Delete",
97
+ "Reply": "Reply",
98
+ "Comment": "Comment",
97
99
  "Comments": "Comments",
98
100
  "All_comments": "All comments",
99
101
  "Resolved_comments": "Resolved comments",
@@ -94,6 +94,8 @@
94
94
  "Publish": "发布",
95
95
  "This_file_has_a_draft": "这个文件有一个草稿.",
96
96
  "Delete": "删除",
97
+ "Reply": "回复",
98
+ "Comment": "评论",
97
99
  "Comments": "评论",
98
100
  "All_comments": "所有评论",
99
101
  "Resolved_comments": "已解决评论",