@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.
- package/dist/basic-sdk/comment/components/comment-delete-popover.js +34 -9
- package/dist/basic-sdk/comment/components/comment-item-reply.js +5 -5
- package/dist/basic-sdk/comment/components/comment-item-wrapper.js +6 -7
- package/dist/basic-sdk/comment/components/comment-list.css +1 -1
- package/dist/basic-sdk/comment/components/editor-comment.js +0 -1
- package/dist/basic-sdk/comment/components/elements-comment-count/index.js +1 -2
- package/dist/basic-sdk/comment/index.js +0 -1
- package/dist/basic-sdk/editor/sdoc-editor.js +11 -0
- package/dist/basic-sdk/extension/plugins/ai/ai-module/helpers.js +22 -0
- package/dist/basic-sdk/extension/plugins/ai/ai-module/index.js +20 -9
- package/dist/basic-sdk/extension/plugins/text-style/render-elem.js +7 -2
- package/package.json +3 -2
|
@@ -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
|
-
|
|
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
|
-
|
|
26
|
-
}, [
|
|
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: "
|
|
61
|
+
placement: "left",
|
|
38
62
|
className: "comment-delete-popover",
|
|
39
63
|
isOpen: true
|
|
40
|
-
}, /*#__PURE__*/_react.default.createElement(
|
|
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
|
-
},
|
|
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 [
|
|
40
|
+
const [isShowDeletePopover, setIsShowDeletePopover] = (0, _react.useState)(false);
|
|
41
41
|
const onDeleteToggle = (0, _react.useCallback)(event => {
|
|
42
42
|
event.stopPropagation();
|
|
43
|
-
|
|
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
|
-
|
|
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
|
-
}),
|
|
121
|
+
}), isShowDeletePopover && isActive && /*#__PURE__*/_react.default.createElement(_commentDeletePopover.default, {
|
|
122
122
|
parentDom: itemRef.current,
|
|
123
123
|
type: "reply",
|
|
124
124
|
deleteConfirm: _deleteReply,
|
|
125
|
-
|
|
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 [
|
|
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
|
-
|
|
241
|
+
setIsShowDeletePopover(true);
|
|
242
242
|
}, []);
|
|
243
243
|
const _deleteComment = (0, _react.useCallback)(() => {
|
|
244
244
|
deleteComment(comment.id);
|
|
245
|
-
|
|
245
|
+
setIsShowDeletePopover(false);
|
|
246
246
|
setCurrentCommentGroup && setCurrentCommentGroup(null);
|
|
247
247
|
}, [comment.id, deleteComment, setCurrentCommentGroup]);
|
|
248
248
|
(0, _react.useEffect)(() => {
|
|
249
249
|
if (!isActive) {
|
|
250
|
-
|
|
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
|
-
})),
|
|
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
|
-
|
|
307
|
+
setIsShowDeletePopover: setIsShowDeletePopover,
|
|
309
308
|
parentDom: listRef.current
|
|
310
309
|
}));
|
|
311
310
|
};
|
|
@@ -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:
|
|
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
|
|
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 = `${
|
|
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
|
-
|
|
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 = `${
|
|
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
|
|
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
|
-
|
|
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.
|
|
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": "
|
|
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",
|