@seafile/sdoc-editor 0.4.17 → 0.4.19
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-input/helpers.js +15 -0
- package/dist/basic-sdk/comment/components/comment-input/index.js +11 -4
- package/dist/basic-sdk/editor/revision-editor.js +1 -0
- package/dist/basic-sdk/editor/sdoc-editor.js +1 -0
- package/dist/basic-sdk/extension/plugins/file-link/render-elem.js +4 -2
- package/dist/basic-sdk/extension/plugins/sdoc-link/render-elem.js +18 -5
- package/dist/basic-sdk/extension/toolbar/side-toolbar/helpers.js +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import context from '../../../../context';
|
|
2
|
+
|
|
3
|
+
// Sort collaborators by participants, move mentioned members to the top
|
|
4
|
+
export const sortCollaborators = function (collaborators) {
|
|
5
|
+
let participants = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
6
|
+
const loginEmail = context.getUserInfo().email;
|
|
7
|
+
const participantsMap = {};
|
|
8
|
+
participants.forEach(item => {
|
|
9
|
+
if (item.email === loginEmail) return;
|
|
10
|
+
participantsMap[item.email] = item;
|
|
11
|
+
});
|
|
12
|
+
const newCollaborators = collaborators.filter(item => !participantsMap[item.email] && item.email !== loginEmail);
|
|
13
|
+
const newParticipants = Object.values(participantsMap);
|
|
14
|
+
return [...newParticipants, ...newCollaborators];
|
|
15
|
+
};
|
|
@@ -9,6 +9,7 @@ import { DOWN, UP, POPOVER_ADDING_HEIGHT, FONT_SIZE_WIDTH, LINE_HEIGHT } from '.
|
|
|
9
9
|
import { eventStopPropagation } from '../../../utils/mouse-event';
|
|
10
10
|
import CommentParticipantItem from './comment-participant-item';
|
|
11
11
|
import { Hotkey, getSelectionCoords } from '../../../../utils';
|
|
12
|
+
import { sortCollaborators } from './helpers';
|
|
12
13
|
import './index.css';
|
|
13
14
|
const CommentInput = forwardRef((_ref, ref) => {
|
|
14
15
|
let {
|
|
@@ -27,11 +28,13 @@ const CommentInput = forwardRef((_ref, ref) => {
|
|
|
27
28
|
collaborators
|
|
28
29
|
} = useCollaborators();
|
|
29
30
|
const {
|
|
30
|
-
addParticipants
|
|
31
|
+
addParticipants,
|
|
32
|
+
participants
|
|
31
33
|
} = useParticipantsContext();
|
|
32
34
|
const [range, setRange] = useState();
|
|
33
35
|
const [searchedCollaborators, setSearchedCollaborators] = useState([]);
|
|
34
36
|
const [activeCollaboratorIndex, setActiveCollaboratorIndex] = useState(-1);
|
|
37
|
+
const [validCollaborators, setValidCollaborators] = useState([]);
|
|
35
38
|
const commentUtilities = new CommentUtilities();
|
|
36
39
|
|
|
37
40
|
// onMount: comment content
|
|
@@ -40,6 +43,10 @@ const CommentInput = forwardRef((_ref, ref) => {
|
|
|
40
43
|
commentRef.current.textContent = content;
|
|
41
44
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
42
45
|
}, []);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const sortedCollaborators = sortCollaborators(collaborators, participants);
|
|
48
|
+
setValidCollaborators(sortedCollaborators);
|
|
49
|
+
}, [collaborators, participants]);
|
|
43
50
|
|
|
44
51
|
// onMount: set input focus
|
|
45
52
|
useEffect(() => {
|
|
@@ -147,11 +154,11 @@ const CommentInput = forwardRef((_ref, ref) => {
|
|
|
147
154
|
anchorOffset
|
|
148
155
|
} = _ref2;
|
|
149
156
|
if (atIndex !== 0 && text[atIndex - 1] !== ' ') return [];
|
|
150
|
-
if (atIndex === anchorOffset - 1) return
|
|
157
|
+
if (atIndex === anchorOffset - 1) return validCollaborators;
|
|
151
158
|
const searchingText = text.substring(atIndex + 1);
|
|
152
|
-
if (searchingText) return searchCollaborators(
|
|
159
|
+
if (searchingText) return searchCollaborators(validCollaborators, searchingText);
|
|
153
160
|
return [];
|
|
154
|
-
}, [
|
|
161
|
+
}, [validCollaborators]);
|
|
155
162
|
const handleInvolvedKeyUp = useCallback(event => {
|
|
156
163
|
// atIndex: Positional index of @
|
|
157
164
|
const {
|
|
@@ -68,14 +68,16 @@ const FileLink = _ref => {
|
|
|
68
68
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
69
69
|
}, [isShowInsertHoverMenu]);
|
|
70
70
|
const onClickFile = useCallback(e => {
|
|
71
|
-
|
|
71
|
+
if (isShowInsertHoverMenu) {
|
|
72
|
+
e.stopPropagation();
|
|
73
|
+
}
|
|
72
74
|
setPosition(e.currentTarget);
|
|
73
75
|
setIsShowInsertHoverMenu(true);
|
|
74
76
|
setTimeout(() => {
|
|
75
77
|
registerEventHandle();
|
|
76
78
|
}, 0);
|
|
77
79
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
78
|
-
}, []);
|
|
80
|
+
}, [isShowInsertHoverMenu]);
|
|
79
81
|
const onHideInsertHoverMenu = useCallback(e => {
|
|
80
82
|
setIsShowInsertHoverMenu(false);
|
|
81
83
|
unregisterEventHandle();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
2
|
import React, { useCallback, useEffect, useState, useRef } from 'react';
|
|
3
|
-
import { Range } from '@seafile/slate';
|
|
4
|
-
import { useReadOnly } from '@seafile/slate-react';
|
|
3
|
+
import { Range, Transforms } from '@seafile/slate';
|
|
4
|
+
import { ReactEditor, useReadOnly } from '@seafile/slate-react';
|
|
5
5
|
import { useScrollContext } from '../../../hooks/use-scroll-context';
|
|
6
6
|
import { unwrapLinkNode, getUrl } from './helpers';
|
|
7
7
|
import HoverMenu from './hover-menu';
|
|
@@ -70,14 +70,27 @@ const SdocFileLink = _ref => {
|
|
|
70
70
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
71
71
|
}, [isShowInsertHoverMenu]);
|
|
72
72
|
const onClickFile = useCallback(e => {
|
|
73
|
-
|
|
73
|
+
if (isShowInsertHoverMenu) {
|
|
74
|
+
e.stopPropagation();
|
|
75
|
+
}
|
|
76
|
+
const path = ReactEditor.findPath(editor, element);
|
|
77
|
+
Transforms.setSelection(editor, {
|
|
78
|
+
anchor: {
|
|
79
|
+
offset: 1,
|
|
80
|
+
path: [path[0], path[1], 0]
|
|
81
|
+
},
|
|
82
|
+
focus: {
|
|
83
|
+
offset: 1,
|
|
84
|
+
path: [path[0], path[1], 0]
|
|
85
|
+
}
|
|
86
|
+
});
|
|
74
87
|
setPosition(e.currentTarget);
|
|
75
88
|
setIsShowInsertHoverMenu(true);
|
|
76
89
|
setTimeout(() => {
|
|
77
90
|
registerEventHandle();
|
|
78
91
|
}, 0);
|
|
79
92
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
80
|
-
}, []);
|
|
93
|
+
}, [isShowInsertHoverMenu]);
|
|
81
94
|
const onHideInsertHoverMenu = useCallback(e => {
|
|
82
95
|
setIsShowInsertHoverMenu(false);
|
|
83
96
|
unregisterEventHandle();
|
|
@@ -118,7 +131,7 @@ const SdocFileLink = _ref => {
|
|
|
118
131
|
e.preventDefault();
|
|
119
132
|
},
|
|
120
133
|
title: element.title
|
|
121
|
-
}, children))), isShowInsertHoverMenu &&
|
|
134
|
+
}, children))), isShowInsertHoverMenu && !readOnly && editor.selection && Range.isCollapsed(editor.selection) && /*#__PURE__*/React.createElement(HoverMenu, {
|
|
122
135
|
editor: editor,
|
|
123
136
|
menuPosition: menuPosition,
|
|
124
137
|
element: element,
|
|
@@ -168,11 +168,11 @@ export const getListNode = (editor, path) => {
|
|
|
168
168
|
export const onWrapListItem = (editor, targetPath, sourcePath) => {
|
|
169
169
|
const nextPath = Path.next(targetPath);
|
|
170
170
|
const listNode = getListNode(editor, sourcePath);
|
|
171
|
-
Transforms.insertNodes(editor, listNode, {
|
|
172
|
-
at: nextPath
|
|
173
|
-
});
|
|
174
171
|
Transforms.removeNodes(editor, {
|
|
175
172
|
at: sourcePath
|
|
176
173
|
});
|
|
174
|
+
Transforms.insertNodes(editor, listNode, {
|
|
175
|
+
at: nextPath
|
|
176
|
+
});
|
|
177
177
|
return;
|
|
178
178
|
};
|