@seafile/sdoc-editor 2.0.43 → 2.0.45

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,47 +1,72 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
3
4
  var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
5
  Object.defineProperty(exports, "__esModule", {
5
6
  value: true
6
7
  });
7
8
  exports.default = void 0;
8
9
  var _react = _interopRequireWildcard(require("react"));
10
+ var _isHotkey = _interopRequireDefault(require("is-hotkey"));
9
11
  var _reactI18next = require("react-i18next");
10
12
  var _reactstrap = require("reactstrap");
13
+ var _utils = require("../../extension/plugins/seatable-tables/seatable-settings/utils/utils");
11
14
  require("./comment-list.css");
12
15
  const CommentDeletePopover = _ref => {
13
16
  let {
14
17
  type,
15
- setIsShowDeleteModal,
18
+ setIsShowDeletePopover,
16
19
  deleteConfirm,
17
20
  targetId,
18
21
  parentDom
19
22
  } = _ref;
23
+ const popoverRef = (0, _react.useRef)(null);
24
+ const hide = (0, _react.useCallback)(event => {
25
+ if (popoverRef.current && !(0, _utils.getEventClassName)(event).includes('popover') && !popoverRef.current.contains(event.target)) {
26
+ setIsShowDeletePopover(false);
27
+ event.preventDefault();
28
+ event.stopPropagation();
29
+ return false;
30
+ }
31
+ }, [setIsShowDeletePopover]);
32
+ const onHotKey = (0, _react.useCallback)(event => {
33
+ if ((0, _isHotkey.default)('esc', event)) {
34
+ event.preventDefault();
35
+ setIsShowDeletePopover(false);
36
+ }
37
+ }, [setIsShowDeletePopover]);
38
+ (0, _react.useEffect)(() => {
39
+ document.addEventListener('click', hide, true);
40
+ document.addEventListener('keydown', onHotKey);
41
+ return () => {
42
+ document.removeEventListener('click', hide, true);
43
+ document.removeEventListener('keydown', onHotKey);
44
+ };
45
+ }, []);
20
46
  const {
21
47
  t
22
48
  } = (0, _reactI18next.useTranslation)('sdoc-editor');
23
49
  const onDeleteCancel = (0, _react.useCallback)(event => {
24
50
  event.stopPropagation();
25
- setIsShowDeleteModal(false);
26
- }, [setIsShowDeleteModal]);
51
+ setIsShowDeletePopover(false);
52
+ }, [setIsShowDeletePopover]);
27
53
  const handleConfirm = (0, _react.useCallback)(event => {
28
54
  event.stopPropagation();
29
55
  deleteConfirm();
30
56
  }, [deleteConfirm]);
31
- const message = type === 'comment' ? 'comment' : 'reply';
32
- const content = t(`Are_you_sure_to_delete_this_${message}`);
33
57
  return /*#__PURE__*/_react.default.createElement(_reactstrap.UncontrolledPopover, {
34
58
  container: parentDom,
35
59
  target: targetId,
36
60
  onClick: event => event.stopPropagation(),
37
- placement: "bottom",
61
+ placement: "left",
38
62
  className: "comment-delete-popover",
39
63
  isOpen: true
40
- }, /*#__PURE__*/_react.default.createElement(_reactstrap.PopoverBody, {
41
- className: "comment-delete-popover-container"
64
+ }, /*#__PURE__*/_react.default.createElement("div", {
65
+ className: "comment-delete-popover-container",
66
+ ref: popoverRef
42
67
  }, /*#__PURE__*/_react.default.createElement("div", {
43
68
  className: "delete-tip"
44
- }, content), /*#__PURE__*/_react.default.createElement("div", {
69
+ }, t(`Are_you_sure_to_delete_this_${type === 'comment' ? 'comment' : 'reply'}`)), /*#__PURE__*/_react.default.createElement("div", {
45
70
  className: "delete-control mt-5"
46
71
  }, /*#__PURE__*/_react.default.createElement("button", {
47
72
  className: "btn btn-secondary mr-2",
@@ -37,10 +37,10 @@ const CommentItemReply = _ref => {
37
37
  event.stopPropagation();
38
38
  setIsEditing(true);
39
39
  }, []);
40
- const [isShowDeleteDialog, setIsShowDeleteDialog] = (0, _react.useState)(false);
40
+ const [isShowDeletePopover, setIsShowDeletePopover] = (0, _react.useState)(false);
41
41
  const onDeleteToggle = (0, _react.useCallback)(event => {
42
42
  event.stopPropagation();
43
- setIsShowDeleteDialog(true);
43
+ setIsShowDeletePopover(true);
44
44
  }, []);
45
45
  const transferHtml = async mdString => {
46
46
  const htmlString = await _mdToHtml.default.process(mdString);
@@ -52,7 +52,7 @@ const CommentItemReply = _ref => {
52
52
  }, [reply.reply]);
53
53
  const _deleteReply = (0, _react.useCallback)(() => {
54
54
  deleteReply(reply.id);
55
- setIsShowDeleteDialog(false);
55
+ setIsShowDeletePopover(false);
56
56
  }, [reply.id, deleteReply]);
57
57
  const updateContent = (0, _react.useCallback)(content => {
58
58
  if (reply.reply !== content) {
@@ -118,11 +118,11 @@ const CommentItemReply = _ref => {
118
118
  content: editorContent,
119
119
  updateContent: updateContent,
120
120
  setIsEditing: setIsEditing
121
- }), isShowDeleteDialog && isActive && /*#__PURE__*/_react.default.createElement(_commentDeletePopover.default, {
121
+ }), isShowDeletePopover && isActive && /*#__PURE__*/_react.default.createElement(_commentDeletePopover.default, {
122
122
  parentDom: itemRef.current,
123
123
  type: "reply",
124
124
  deleteConfirm: _deleteReply,
125
- setIsShowDeleteModal: setIsShowDeleteDialog,
125
+ setIsShowDeletePopover: setIsShowDeletePopover,
126
126
  targetId: replyOpToolsId
127
127
  }));
128
128
  };
@@ -37,7 +37,7 @@ const CommentItemWrapper = _ref => {
37
37
  dispatch
38
38
  } = (0, _useCommentContext.useCommentContext)();
39
39
  const scrollRef = (0, _react.useRef)(document.querySelector('.sdoc-scroll-container'));
40
- const [isShowDeleteDialog, setIsShowDeleteDialog] = (0, _react.useState)(false);
40
+ const [isShowDeletePopover, setIsShowDeletePopover] = (0, _react.useState)(false);
41
41
  const commentOpToolsId = `commentOpTools_${comment === null || comment === void 0 ? void 0 : comment.id}`;
42
42
  const style = !isGlobalComment && isCollapseCommentEditor ? {
43
43
  maxHeight: '341px'
@@ -238,16 +238,16 @@ const CommentItemWrapper = _ref => {
238
238
  onCommentClick && onCommentClick(comment);
239
239
  }, [comment, onCommentClick]);
240
240
  const onDeleteComment = (0, _react.useCallback)(() => {
241
- setIsShowDeleteDialog(true);
241
+ setIsShowDeletePopover(true);
242
242
  }, []);
243
243
  const _deleteComment = (0, _react.useCallback)(() => {
244
244
  deleteComment(comment.id);
245
- setIsShowDeleteDialog(false);
245
+ setIsShowDeletePopover(false);
246
246
  setCurrentCommentGroup && setCurrentCommentGroup(null);
247
247
  }, [comment.id, deleteComment, setCurrentCommentGroup]);
248
248
  (0, _react.useEffect)(() => {
249
249
  if (!isActive) {
250
- setIsShowDeleteDialog(false);
250
+ setIsShowDeletePopover(false);
251
251
  }
252
252
  }, [isActive]);
253
253
  const className = (0, _classnames.default)('comment-ui-container', {
@@ -300,12 +300,11 @@ const CommentItemWrapper = _ref => {
300
300
  updateReply
301
301
  };
302
302
  return /*#__PURE__*/_react.default.createElement(_commentItemReply.default, props);
303
- })), isShowDeleteDialog && isActive && /*#__PURE__*/_react.default.createElement(_commentDeletePopover.default, {
303
+ })), isShowDeletePopover && isActive && /*#__PURE__*/_react.default.createElement(_commentDeletePopover.default, {
304
304
  type: "comment",
305
- setIsShowDeleteDialog: setIsShowDeleteDialog,
306
305
  targetId: commentOpToolsId,
307
306
  deleteConfirm: _deleteComment,
308
- setIsShowDeleteModal: setIsShowDeleteDialog,
307
+ setIsShowDeletePopover: setIsShowDeletePopover,
309
308
  parentDom: listRef.current
310
309
  }));
311
310
  };
@@ -51,7 +51,7 @@
51
51
  padding: 16px;
52
52
  }
53
53
 
54
- .comment-delete-popover-container .delete-control {
54
+ .comment-delete-popover .comment-delete-popover-container .delete-control {
55
55
  display: flex;
56
56
  justify-content: flex-end;
57
57
  width: 100%;
@@ -19,7 +19,6 @@ var _constants = require("../../extension/constants");
19
19
  var _constants2 = require("../../constants");
20
20
  const EditorComment = _ref => {
21
21
  let {
22
- deleteUnseenNotifications,
23
22
  editor
24
23
  } = _ref;
25
24
  (0, _useSelectionUpdate.default)();
@@ -24,11 +24,10 @@ const ElementsCommentCount = _ref => {
24
24
  const unresolvedComment = comments.filter(item => !item.resolved);
25
25
  const unresolvedCommentCount = unresolvedComment.length;
26
26
  if (unresolvedCommentCount === 0) return null;
27
- const isSelected = selectionElement && selectionElement.id === elementId;
28
27
  return /*#__PURE__*/_react.default.createElement(_elementCommentCount.default, {
29
28
  key: elementId,
30
29
  elementId: elementId,
31
- isElementSelected: isSelected,
30
+ isElementSelected: selectionElement && selectionElement.id === elementId,
32
31
  commentsCount: unresolvedCommentCount,
33
32
  editor: editor,
34
33
  onSelectElement: onSelectElement
@@ -56,7 +56,6 @@ const CommentWrapper = _ref => {
56
56
  } = _context.default.getSettings('isFreezed');
57
57
  if (commentsInfo.isFetching) return null;
58
58
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, type === 'editor' && !isFreezed && /*#__PURE__*/_react.default.createElement(_components.EditorComment, {
59
- deleteUnseenNotifications: deleteUnseenNotifications,
60
59
  editor: editor
61
60
  }), type === 'global' && /*#__PURE__*/_react.default.createElement(_components.GlobalComment, {
62
61
  deleteUnseenNotifications: deleteUnseenNotifications,
@@ -26,6 +26,7 @@ var _basicSdk = require("../../basic-sdk");
26
26
  var _constants2 = require("../../constants");
27
27
  var _outlineModule = require("../../android/outline-module");
28
28
  var _jsBridge = _interopRequireDefault(require("../../android/js-bridge"));
29
+ var _helpers = require("../extension/plugins/ai/ai-module/helpers");
29
30
  const SdocEditor = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
30
31
  let {
31
32
  editor: propsEditor,
@@ -118,6 +119,16 @@ const SdocEditor = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
118
119
  (0, _react.useEffect)(() => {
119
120
  const eventBus = _basicSdk.EventBus.getInstance();
120
121
  eventBus.subscribe(_constants2.EXTERNAL_EVENT.REFRESH_DOCUMENT, onRefreshDocument);
122
+
123
+ // Remove aiMarks on special conditions like unexpected exit or refresh page using AI
124
+ const hasAIMark = !_slate.Editor.nodes(validEditor, {
125
+ at: [],
126
+ match: n => _slate.Text.isText(n) && n.sdoc_ai === true
127
+ }).next().done;
128
+ if (hasAIMark) {
129
+ (0, _helpers.removeMarks)(validEditor);
130
+ }
131
+ // eslint-disable-next-line react-hooks/exhaustive-deps
121
132
  }, [onRefreshDocument]);
122
133
 
123
134
  // The parent component can call the method of this component through ref
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.removeMarks = void 0;
7
+ var _slate = require("@seafile/slate");
8
+ const removeMarks = editor => {
9
+ const {
10
+ selection
11
+ } = editor;
12
+ _slate.Transforms.unsetNodes(editor, 'sdoc_ai', {
13
+ at: [],
14
+ match: n => _slate.Text.isText(n) && n.sdoc_ai === true
15
+ });
16
+ if (selection) {
17
+ _slate.Transforms.select(editor, selection);
18
+ } else {
19
+ _slate.Transforms.deselect(editor);
20
+ }
21
+ };
22
+ exports.removeMarks = removeMarks;
@@ -23,6 +23,7 @@ var _tipDialog = _interopRequireDefault(require("./tip-dialog"));
23
23
  var _core = require("../../../core");
24
24
  var _constants2 = require("../../../constants");
25
25
  var _aiIcon = _interopRequireDefault(require("../ai-icon"));
26
+ var _helpers = require("./helpers");
26
27
  require("./style.css");
27
28
  function AIModule(_ref) {
28
29
  let {
@@ -45,8 +46,9 @@ function AIModule(_ref) {
45
46
  const [searchResult, setSearchResult] = (0, _react.useState)(null);
46
47
  const [currentLang, setCurrentLang] = (0, _react.useState)('en');
47
48
  const [isShowTipDialog, setIsShowTipDialog] = (0, _react.useState)(false);
48
- const [selectDom, setSelectDom] = (0, _react.useState)(null);
49
49
  const toggleAskAI = (0, _react.useCallback)(() => {
50
+ // Add marks for selection
51
+ _slate.Editor.addMark(editor, 'sdoc_ai', true);
50
52
  scrollRef.current = document.querySelector('.sdoc-scroll-container');
51
53
  const {
52
54
  scrollTop,
@@ -59,7 +61,6 @@ function AIModule(_ref) {
59
61
  }
60
62
  const domSelection = window.getSelection();
61
63
  const domRange = domSelection.getRangeAt(0);
62
- setSelectDom(domRange);
63
64
  const rect = domRange.getBoundingClientRect();
64
65
  const needPaddingBottomHeight = scrollTop + rect.bottom + _constants.AI_MIN_HEIGHT - scrollHeight;
65
66
  if (needPaddingBottomHeight > 0) {
@@ -74,13 +75,17 @@ function AIModule(_ref) {
74
75
  });
75
76
  }
76
77
  setTimeout(() => {
77
- var _inputRef$current;
78
+ var _rect, _inputRef$current;
78
79
  const aboveNode = (0, _core.getAboveBlockNode)(editor);
79
80
  const slateDom = _slateReact.ReactEditor.toDOMNode(editor, aboveNode[0]);
80
81
  const slateRect = slateDom.getBoundingClientRect();
81
- const newRect = domRange.getBoundingClientRect();
82
+ const markedSpan = document.querySelectorAll('span[data-slate-leaf="true"].sdoc_ai');
83
+ let rect;
84
+ if (markedSpan.length) {
85
+ rect = markedSpan[markedSpan.length - 1].getBoundingClientRect();
86
+ }
82
87
  const el = aiRef.current;
83
- el.style.top = `${newRect.bottom + 8}px`; // top = Current top + Element height
88
+ el.style.top = `${((_rect = rect) === null || _rect === void 0 ? void 0 : _rect.bottom) + 8 - 3.23}px`; // top = Current top + Element height - Element padding bottom
84
89
  el.style.left = `${slateRect.left}px`;
85
90
  el.style.display = 'block';
86
91
  setIsShowAIPopover(true);
@@ -118,6 +123,7 @@ function AIModule(_ref) {
118
123
  }, 500);
119
124
  }, [editor, element]);
120
125
  const onCloseClick = (0, _react.useCallback)(() => {
126
+ (0, _helpers.removeMarks)(editor);
121
127
  const element = aiRef.current;
122
128
  element.style.display = 'none';
123
129
  const articleDom = document.querySelector('.sdoc-editor__article');
@@ -126,7 +132,7 @@ function AIModule(_ref) {
126
132
  setSearchResult('');
127
133
  setIsShowAIPopover(false);
128
134
  closeModule();
129
- }, [closeModule]);
135
+ }, [closeModule, editor]);
130
136
  const onDocumentClick = (0, _react.useCallback)(event => {
131
137
  // not in ai container
132
138
  if (aiRef.current && aiRef.current.contains(event.target) && aiRef.current !== event.target) return;
@@ -161,12 +167,17 @@ function AIModule(_ref) {
161
167
  }, [onDocumentClick]);
162
168
  const onScroll = (0, _react.useCallback)(event => {
163
169
  if (!element) {
164
- const newRect = selectDom.getBoundingClientRect();
170
+ var _rect2;
171
+ const markedSpan = document.querySelectorAll('span[data-slate-leaf="true"].sdoc_ai');
172
+ let rect;
173
+ if (markedSpan.length) {
174
+ rect = markedSpan[markedSpan.length - 1].getBoundingClientRect();
175
+ }
165
176
  const aboveNode = (0, _core.getAboveBlockNode)(editor);
166
177
  const slateDom = _slateReact.ReactEditor.toDOMNode(editor, aboveNode[0]);
167
178
  const slateRect = slateDom.getBoundingClientRect();
168
179
  const el = aiRef.current;
169
- el.style.top = `${newRect.bottom + 8}px`; // top = Current top + Element height
180
+ el.style.top = `${((_rect2 = rect) === null || _rect2 === void 0 ? void 0 : _rect2.bottom) + 8 - 3.23}px`; // top = Current top + Element height - Element padding bottom
170
181
  el.style.left = `${slateRect.left}px`;
171
182
  el.style.display = 'block';
172
183
  } else {
@@ -177,7 +188,7 @@ function AIModule(_ref) {
177
188
  el.style.left = `${slateRect.left}px`;
178
189
  el.style.display = 'block';
179
190
  }
180
- }, [editor, element, selectDom]);
191
+ }, [editor, element]);
181
192
  (0, _react.useEffect)(() => {
182
193
  let observerRefValue = null;
183
194
  if (isShowAIPopover) {
@@ -9,8 +9,7 @@ var _react = _interopRequireDefault(require("react"));
9
9
  var _caret = _interopRequireDefault(require("./caret"));
10
10
  var _constants = require("../../constants");
11
11
  var _helpers = require("../font/helpers");
12
- var _InlineBugFixWrapper = _interopRequireDefault(require("../../commons/Inline-bug-fix-wrapper"));
13
- const renderText = (props, editor) => {
12
+ const renderText = props => {
14
13
  const {
15
14
  attributes,
16
15
  children,
@@ -35,6 +34,12 @@ const renderText = (props, editor) => {
35
34
  style['display'] = 'inline-block';
36
35
  style['minWidth'] = '2px';
37
36
  }
37
+
38
+ // Add temporary marks for selection in AI
39
+ if (leaf.sdoc_ai && leaf.text.trim()) {
40
+ style['padding'] = '3.23px 0';
41
+ style['background'] = '#a9c9ed';
42
+ }
38
43
  if (leaf.computed_background_color) {
39
44
  style['backgroundColor'] = leaf.computed_background_color;
40
45
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "2.0.43",
3
+ "version": "2.0.45",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -25,6 +25,7 @@
25
25
  "randomcolor": "0.6.2",
26
26
  "react-color": "2.19.3",
27
27
  "react-cookies": "0.1.1",
28
+ "react-transition-group": "4.4.5",
28
29
  "reactstrap": "9.2.3",
29
30
  "rehype-format": "5.0.0",
30
31
  "rehype-mathjax": "5.0.0",
@@ -38,7 +39,7 @@
38
39
  "remark-parse": "11.0.0",
39
40
  "remark-rehype": "11.0.0",
40
41
  "remark-stringify": "11.0.0",
41
- "sea-chart": "2.0.8",
42
+ "sea-chart": "1.1.82",
42
43
  "slugid": "3.2.0",
43
44
  "socket.io-client": "4.8.1",
44
45
  "type-of": "2.0.1",