@seafile/sdoc-editor 1.0.211-test-0.4 → 1.0.212-alph-0.0.1
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/assets/css/sdoc-editor-plugins.css +0 -56
- package/dist/basic-sdk/editor/revision-editor.js +1 -0
- package/dist/basic-sdk/extension/commons/file-insert-dialog/index.js +1 -1
- package/dist/basic-sdk/extension/commons/insert-element-dialog/index.js +21 -0
- package/dist/basic-sdk/extension/commons/select-file-dialog/helpers.js +8 -3
- package/dist/basic-sdk/extension/commons/select-file-dialog/index.js +48 -8
- package/dist/basic-sdk/extension/commons/select-file-dialog/local-files/index.css +1 -0
- package/dist/basic-sdk/extension/commons/select-file-dialog/local-files/index.js +6 -2
- package/dist/basic-sdk/extension/constants/element-type.js +2 -1
- package/dist/basic-sdk/extension/constants/index.js +2 -1
- package/dist/basic-sdk/extension/plugins/image/render-elem.js +15 -87
- package/dist/basic-sdk/extension/plugins/sdoc-link/helpers.js +3 -3
- package/dist/basic-sdk/extension/plugins/sdoc-link/render/render-elem.js +1 -1
- package/dist/basic-sdk/extension/plugins/video/dialog/add-video-link-dialog/index.js +99 -0
- package/dist/basic-sdk/extension/plugins/video/helpers.js +61 -8
- package/dist/basic-sdk/extension/plugins/video/index.css +4 -3
- package/dist/basic-sdk/extension/plugins/video/menu/index.js +24 -1
- package/dist/basic-sdk/extension/plugins/video/render-elem.js +20 -7
- package/dist/basic-sdk/views/revision-diff-viewer.js +1 -0
- package/dist/constants/index.js +1 -0
- package/dist/pages/simple-editor.js +1 -0
- package/package.json +1 -1
- package/public/locales/cs/sdoc-editor.json +5 -3
- package/public/locales/de/sdoc-editor.json +5 -3
- package/public/locales/en/sdoc-editor.json +5 -3
- package/public/locales/es/sdoc-editor.json +5 -3
- package/public/locales/es_AR/sdoc-editor.json +5 -3
- package/public/locales/es_MX/sdoc-editor.json +5 -3
- package/public/locales/fr/sdoc-editor.json +5 -3
- package/public/locales/it/sdoc-editor.json +5 -3
- package/public/locales/ru/sdoc-editor.json +5 -3
- package/public/locales/zh_CN/sdoc-editor.json +4 -2
|
@@ -62,62 +62,6 @@
|
|
|
62
62
|
caret-color: transparent;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
.sdoc-editor__article .sdoc-image-wrapper .sdoc-image-placeholder-wrapper {
|
|
66
|
-
/* width: 360px; */
|
|
67
|
-
width: 100%;
|
|
68
|
-
aspect-ratio: 1 / 1;
|
|
69
|
-
background-color: #f0f0f0;
|
|
70
|
-
border: 1px solid #ccc;
|
|
71
|
-
padding: 0 3%;
|
|
72
|
-
max-width: 100%;
|
|
73
|
-
user-select: all;
|
|
74
|
-
pointer-events: all;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.sdoc-editor__article .sdoc-image-wrapper .sdoc-image-tip-content,
|
|
78
|
-
.sdoc-editor__article .sdoc-image-wrapper .sdoc-image-title {
|
|
79
|
-
user-select: none;
|
|
80
|
-
pointer-events: none;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.sdoc-editor__article .sdoc-image-title .sdoc-exclamation-circle {
|
|
84
|
-
font-size: 18px;
|
|
85
|
-
align-items: center;
|
|
86
|
-
justify-content: center;
|
|
87
|
-
color: red;
|
|
88
|
-
display: flex;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.sdoc-editor__article .sdoc-image-title .sdoc-image-tip-title {
|
|
92
|
-
color: red;
|
|
93
|
-
font-size: 18px;
|
|
94
|
-
user-select: none;
|
|
95
|
-
pointer-events: none;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
.sdoc-editor__article .sdoc-image-process-container {
|
|
99
|
-
width: 40px;
|
|
100
|
-
height: 40px;
|
|
101
|
-
display: flex;
|
|
102
|
-
align-items: center;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.sdoc-editor__article .sdoc-image-process-container .loading-spinner {
|
|
106
|
-
border: 5px solid #d8d8d8;
|
|
107
|
-
border-top: 5px solid #939393;
|
|
108
|
-
border-radius: 50%;
|
|
109
|
-
width: 30px;
|
|
110
|
-
height: 30px;
|
|
111
|
-
animation: spin 1s linear infinite;
|
|
112
|
-
user-select: none;
|
|
113
|
-
pointer-events: none;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
@keyframes spin {
|
|
117
|
-
0% { transform: rotate(0deg); }
|
|
118
|
-
100% { transform: rotate(360deg); }
|
|
119
|
-
}
|
|
120
|
-
|
|
121
65
|
.sdoc-editor__article .sdoc-image-inner {
|
|
122
66
|
position: relative;
|
|
123
67
|
display: inline-block;
|
|
@@ -66,6 +66,7 @@ const RevisionEditor = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
|
|
|
66
66
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
67
67
|
}), [editorRef]);
|
|
68
68
|
if (isShowChanges) {
|
|
69
|
+
console.log('isShowchange', isShowChanges);
|
|
69
70
|
return /*#__PURE__*/_react.default.createElement(_views.RevisionDiffViewer, {
|
|
70
71
|
editor: editor,
|
|
71
72
|
revisionContent: revisionContent,
|
|
@@ -252,7 +252,7 @@ const FileLinkInsertDialog = _ref => {
|
|
|
252
252
|
}
|
|
253
253
|
}, /*#__PURE__*/_react.default.createElement("img", {
|
|
254
254
|
className: "file-item-img",
|
|
255
|
-
src: (0, _helpers2.
|
|
255
|
+
src: (0, _helpers2.getSdocFileIcon)(),
|
|
256
256
|
alt: ""
|
|
257
257
|
}), /*#__PURE__*/_react.default.createElement("span", {
|
|
258
258
|
className: "file-item-name"
|
|
@@ -23,6 +23,7 @@ var _index4 = _interopRequireDefault(require("../../../../components/toast/index
|
|
|
23
23
|
var _index5 = require("../../plugins/video/constants/index.js");
|
|
24
24
|
var _constants3 = require("../../../../basic-sdk/constants");
|
|
25
25
|
var _index6 = _interopRequireDefault(require("../../plugins/ai/ai-module/index.js"));
|
|
26
|
+
var _index7 = _interopRequireDefault(require("../../plugins/video/dialog/add-video-link-dialog/index.js"));
|
|
26
27
|
const InsertElementDialog = _ref => {
|
|
27
28
|
let {
|
|
28
29
|
editor
|
|
@@ -32,6 +33,7 @@ const InsertElementDialog = _ref => {
|
|
|
32
33
|
const [insertPosition, setInsertPosition] = (0, _react.useState)(_constants2.INSERT_POSITION.CURRENT);
|
|
33
34
|
const [slateNode, setSlateNode] = (0, _react.useState)(null);
|
|
34
35
|
const [insertLinkCallback, setInsertLinkCallback] = (0, _react.useState)(null);
|
|
36
|
+
const [insertVideoCallback, setInsertVideoCallback] = (0, _react.useState)(null);
|
|
35
37
|
const [validEditor, setValidEditor] = (0, _react.useState)(editor);
|
|
36
38
|
const [linkTitle, setLinkTitle] = (0, _react.useState)('');
|
|
37
39
|
const [handleSubmit, setHandleSubmit] = (0, _react.useState)(() => void 0);
|
|
@@ -90,6 +92,7 @@ const InsertElementDialog = _ref => {
|
|
|
90
92
|
slateNode,
|
|
91
93
|
insertFileLinkCallback,
|
|
92
94
|
insertSdocFileLinkCallback,
|
|
95
|
+
insertVideo,
|
|
93
96
|
editor: paramEditor,
|
|
94
97
|
linkTitle,
|
|
95
98
|
// link shortcut wrapping link
|
|
@@ -103,6 +106,9 @@ const InsertElementDialog = _ref => {
|
|
|
103
106
|
insertSdocFileLinkCallback,
|
|
104
107
|
insertFileLinkCallback
|
|
105
108
|
});
|
|
109
|
+
setInsertVideoCallback({
|
|
110
|
+
insertVideo
|
|
111
|
+
});
|
|
106
112
|
setLinkTitle(linkTitle);
|
|
107
113
|
setHandleSubmit(handleSubmit);
|
|
108
114
|
// Apply for comment editor, as it has a different editor instance
|
|
@@ -124,6 +130,7 @@ const InsertElementDialog = _ref => {
|
|
|
124
130
|
setElement('');
|
|
125
131
|
setDialogType('');
|
|
126
132
|
setInsertLinkCallback(null);
|
|
133
|
+
setInsertVideoCallback(null);
|
|
127
134
|
setValidEditor(null);
|
|
128
135
|
setLinkTitle('');
|
|
129
136
|
}, []);
|
|
@@ -169,6 +176,20 @@ const InsertElementDialog = _ref => {
|
|
|
169
176
|
};
|
|
170
177
|
return /*#__PURE__*/_react.default.createElement(_index.default, fileLinkProps);
|
|
171
178
|
}
|
|
179
|
+
case _constants2.ELEMENT_TYPE.VIDEO:
|
|
180
|
+
{
|
|
181
|
+
const videoProps = {
|
|
182
|
+
editor: validEditor,
|
|
183
|
+
dialogType,
|
|
184
|
+
insertVideoCallback,
|
|
185
|
+
closeDialog
|
|
186
|
+
};
|
|
187
|
+
return /*#__PURE__*/_react.default.createElement(_index.default, videoProps);
|
|
188
|
+
}
|
|
189
|
+
case _constants2.ELEMENT_TYPE.VIDEO_LINK:
|
|
190
|
+
{
|
|
191
|
+
return /*#__PURE__*/_react.default.createElement(_index7.default, props);
|
|
192
|
+
}
|
|
172
193
|
case _constants2.LOCAL_IMAGE:
|
|
173
194
|
{
|
|
174
195
|
return /*#__PURE__*/_react.default.createElement("input", {
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.
|
|
7
|
+
exports.getVideoFileIcon = exports.getSdocFileIcon = exports.addDataToTree = void 0;
|
|
8
8
|
var _context = _interopRequireDefault(require("../../../../context"));
|
|
9
9
|
const addDataToTree = (treeData, indexId, childrenData, path) => {
|
|
10
10
|
for (let i = 0; i < treeData.length; i++) {
|
|
@@ -24,8 +24,13 @@ const addDataToTree = (treeData, indexId, childrenData, path) => {
|
|
|
24
24
|
return treeData;
|
|
25
25
|
};
|
|
26
26
|
exports.addDataToTree = addDataToTree;
|
|
27
|
-
const
|
|
27
|
+
const getSdocFileIcon = () => {
|
|
28
28
|
const server = _context.default.getSetting('serviceUrl');
|
|
29
29
|
return `${server}/media/img/file/256/sdoc.png`;
|
|
30
30
|
};
|
|
31
|
-
exports.
|
|
31
|
+
exports.getSdocFileIcon = getSdocFileIcon;
|
|
32
|
+
const getVideoFileIcon = () => {
|
|
33
|
+
const server = _context.default.getSetting('serviceUrl');
|
|
34
|
+
return `${server}/media/img/file/256/video.png`;
|
|
35
|
+
};
|
|
36
|
+
exports.getVideoFileIcon = getVideoFileIcon;
|
|
@@ -21,9 +21,9 @@ const SelectSdocFileDialog = _ref => {
|
|
|
21
21
|
editor,
|
|
22
22
|
dialogType,
|
|
23
23
|
closeDialog,
|
|
24
|
-
insertLinkCallback
|
|
24
|
+
insertLinkCallback,
|
|
25
|
+
insertVideoCallback
|
|
25
26
|
} = _ref;
|
|
26
|
-
const modalTitle = dialogType === _constants.ELEMENT_TYPE.FILE_LINK ? 'Select_file' : 'Select_sdoc_document';
|
|
27
27
|
const {
|
|
28
28
|
t
|
|
29
29
|
} = (0, _reactI18next.useTranslation)('sdoc-editor');
|
|
@@ -31,6 +31,20 @@ const SelectSdocFileDialog = _ref => {
|
|
|
31
31
|
const [temSearchContent, setTemSearchContent] = (0, _react.useState)('');
|
|
32
32
|
const [searchContent, setSearchContent] = (0, _react.useState)('');
|
|
33
33
|
const [isOpenSearch, setIsOpenSearch] = (0, _react.useState)(false);
|
|
34
|
+
let modalTitle;
|
|
35
|
+
switch (dialogType) {
|
|
36
|
+
case _constants.ELEMENT_TYPE.FILE_LINK:
|
|
37
|
+
modalTitle = 'Select_file';
|
|
38
|
+
break;
|
|
39
|
+
case _constants.ELEMENT_TYPE.SDOC_LINK:
|
|
40
|
+
modalTitle = 'Select_sdoc_document';
|
|
41
|
+
break;
|
|
42
|
+
case _constants.ELEMENT_TYPE.VIDEO:
|
|
43
|
+
modalTitle = 'Select_video_file';
|
|
44
|
+
break;
|
|
45
|
+
default:
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
34
48
|
const onSelectedFile = (0, _react.useCallback)(fileInfo => {
|
|
35
49
|
setCurrentSelectedFile(fileInfo);
|
|
36
50
|
}, []);
|
|
@@ -38,13 +52,31 @@ const SelectSdocFileDialog = _ref => {
|
|
|
38
52
|
const {
|
|
39
53
|
insertFileLinkCallback,
|
|
40
54
|
insertSdocFileLinkCallback
|
|
41
|
-
} = insertLinkCallback;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
55
|
+
} = insertLinkCallback || {};
|
|
56
|
+
const {
|
|
57
|
+
insertVideo
|
|
58
|
+
} = insertVideoCallback || {};
|
|
59
|
+
switch (dialogType) {
|
|
60
|
+
case _constants.ELEMENT_TYPE.FILE_LINK:
|
|
61
|
+
insertFileLinkCallback && insertFileLinkCallback(editor, fileInfo.name, fileInfo.file_uuid);
|
|
62
|
+
break;
|
|
63
|
+
case _constants.ELEMENT_TYPE.SDOC_LINK:
|
|
64
|
+
insertSdocFileLinkCallback && insertSdocFileLinkCallback(editor, fileInfo.name, fileInfo.file_uuid);
|
|
65
|
+
break;
|
|
66
|
+
case _constants.ELEMENT_TYPE.VIDEO:
|
|
67
|
+
const repoID = _context.default.getSetting('repoID');
|
|
68
|
+
const fileServerRoot = _context.default.getSetting('fileServerRoot');
|
|
69
|
+
// Get seafile's video download url as src
|
|
70
|
+
const url = `${fileServerRoot}repos/${repoID}/files${fileInfo.path}/?op=download`;
|
|
71
|
+
const encodedUrl = encodeURI(url);
|
|
72
|
+
insertVideo && insertVideo(editor, [{
|
|
73
|
+
name: fileInfo.name
|
|
74
|
+
}], [encodedUrl]);
|
|
75
|
+
break;
|
|
76
|
+
default:
|
|
77
|
+
break;
|
|
46
78
|
}
|
|
47
|
-
}, [insertLinkCallback, dialogType, editor]);
|
|
79
|
+
}, [insertLinkCallback, insertVideoCallback, dialogType, editor]);
|
|
48
80
|
const onSubmit = (0, _react.useCallback)(() => {
|
|
49
81
|
if (!currentSelectedFile) return;
|
|
50
82
|
const {
|
|
@@ -53,6 +85,14 @@ const SelectSdocFileDialog = _ref => {
|
|
|
53
85
|
let fileInfo = {
|
|
54
86
|
...currentSelectedFile
|
|
55
87
|
};
|
|
88
|
+
|
|
89
|
+
// Insert video element in sdoc
|
|
90
|
+
if (dialogType === _constants.ELEMENT_TYPE.VIDEO) {
|
|
91
|
+
insertFile(fileInfo);
|
|
92
|
+
closeDialog();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
56
96
|
// File has no id
|
|
57
97
|
if (!file_uuid || file_uuid === '') {
|
|
58
98
|
_context.default.getSdocLocalFileId(currentSelectedFile.path).then(res => {
|
|
@@ -155,7 +155,7 @@ const LocalFiles = _ref => {
|
|
|
155
155
|
className: "sdoc-folder-children"
|
|
156
156
|
}, ((_item$children = item.children) === null || _item$children === void 0 ? void 0 : _item$children.length) === 0 && /*#__PURE__*/_react.default.createElement("div", {
|
|
157
157
|
className: "sdoc-folder-children-empty"
|
|
158
|
-
}, `(${t('Empty')})`), ((_item$children2 = item.children) === null || _item$children2 === void 0 ? void 0 : _item$children2.length) > 0 && renderFileTree(item.children))),
|
|
158
|
+
}, `(${t('Empty')})`), ((_item$children2 = item.children) === null || _item$children2 === void 0 ? void 0 : _item$children2.length) > 0 && renderFileTree(item.children))), ['file', 'video'].includes(type) && /*#__PURE__*/_react.default.createElement("div", {
|
|
159
159
|
className: (0, _classnames.default)('sdoc-file-info', {
|
|
160
160
|
'active': selected
|
|
161
161
|
}),
|
|
@@ -170,7 +170,11 @@ const LocalFiles = _ref => {
|
|
|
170
170
|
})
|
|
171
171
|
}), fileType === 'sdoc' && /*#__PURE__*/_react.default.createElement("img", {
|
|
172
172
|
className: "sdoc-file-img",
|
|
173
|
-
src: (0, _helpers.
|
|
173
|
+
src: (0, _helpers.getSdocFileIcon)(),
|
|
174
|
+
alt: ""
|
|
175
|
+
}), fileType === 'video' && /*#__PURE__*/_react.default.createElement("img", {
|
|
176
|
+
className: "video-file-img",
|
|
177
|
+
src: (0, _helpers.getVideoFileIcon)(),
|
|
174
178
|
alt: ""
|
|
175
179
|
})), /*#__PURE__*/_react.default.createElement("span", {
|
|
176
180
|
className: "sdoc-file-name"
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.WIKI_LINK = exports.VIDEO = exports.UNORDERED_LIST = exports.TWO_COLUMN = exports.TOP_LEVEL_TYPES = exports.TITLE = exports.THREE_COLUMN = exports.TABLE_ROW = exports.TABLE_CELL = exports.TABLE = exports.SUBTITLE = exports.SEATABLE_TABLE = exports.SEATABLE_COLUMN = exports.SDOC_LINK = exports.QUICK_INSERT = exports.PARAGRAPH = exports.ORDERED_LIST = exports.MULTI_COLUMN = exports.MENTION_TEMP = exports.MENTION = exports.LIST_ITEM = exports.LINK = exports.INLINE_LEVEL_TYPES = exports.IMAGE_BLOCK = exports.IMAGE = exports.HEADER6 = exports.HEADER5 = exports.HEADER4 = exports.HEADER3 = exports.HEADER2 = exports.HEADER1 = exports.HEADER = exports.FOUR_COLUMN = exports.FONT_SIZE_REDUCE = exports.FONT_SIZE_INCREASE = exports.FONT_SIZE = exports.FIVE_COLUMN = exports.FILE_LINK_INSET_INPUT_TEMP = exports.FILE_LINK = exports.COLUMN = exports.CODE_LINE = exports.CODE_BLOCK = exports.CHECK_LIST_ITEM = exports.CALL_OUT = exports.BLOCKQUOTE = exports.ASK_AI = void 0;
|
|
6
|
+
exports.WIKI_LINK = exports.VIDEO_LINK = exports.VIDEO = exports.UNORDERED_LIST = exports.TWO_COLUMN = exports.TOP_LEVEL_TYPES = exports.TITLE = exports.THREE_COLUMN = exports.TABLE_ROW = exports.TABLE_CELL = exports.TABLE = exports.SUBTITLE = exports.SEATABLE_TABLE = exports.SEATABLE_COLUMN = exports.SDOC_LINK = exports.QUICK_INSERT = exports.PARAGRAPH = exports.ORDERED_LIST = exports.MULTI_COLUMN = exports.MENTION_TEMP = exports.MENTION = exports.LIST_ITEM = exports.LINK = exports.INLINE_LEVEL_TYPES = exports.IMAGE_BLOCK = exports.IMAGE = exports.HEADER6 = exports.HEADER5 = exports.HEADER4 = exports.HEADER3 = exports.HEADER2 = exports.HEADER1 = exports.HEADER = exports.FOUR_COLUMN = exports.FONT_SIZE_REDUCE = exports.FONT_SIZE_INCREASE = exports.FONT_SIZE = exports.FIVE_COLUMN = exports.FILE_LINK_INSET_INPUT_TEMP = exports.FILE_LINK = exports.COLUMN = exports.CODE_LINE = exports.CODE_BLOCK = exports.CHECK_LIST_ITEM = exports.CALL_OUT = exports.BLOCKQUOTE = exports.ASK_AI = void 0;
|
|
7
7
|
const BLOCKQUOTE = exports.BLOCKQUOTE = 'blockquote';
|
|
8
8
|
const TITLE = exports.TITLE = 'title';
|
|
9
9
|
const SUBTITLE = exports.SUBTITLE = 'subtitle';
|
|
@@ -42,6 +42,7 @@ const MENTION = exports.MENTION = 'mention';
|
|
|
42
42
|
const MENTION_TEMP = exports.MENTION_TEMP = 'mention_temp';
|
|
43
43
|
const FILE_LINK_INSET_INPUT_TEMP = exports.FILE_LINK_INSET_INPUT_TEMP = 'file_link_insert_input_temp';
|
|
44
44
|
const QUICK_INSERT = exports.QUICK_INSERT = 'quick_insert';
|
|
45
|
+
const VIDEO_LINK = exports.VIDEO_LINK = 'video_link';
|
|
45
46
|
const SEATABLE_COLUMN = exports.SEATABLE_COLUMN = 'seatable_column';
|
|
46
47
|
const SEATABLE_TABLE = exports.SEATABLE_TABLE = 'seatable_table';
|
|
47
48
|
const ASK_AI = exports.ASK_AI = 'ask_ai';
|
|
@@ -532,7 +532,8 @@ const LIST_ITEM_SUPPORTED_TRANSFORMATION = exports.LIST_ITEM_SUPPORTED_TRANSFORM
|
|
|
532
532
|
const ADD_POSITION_OFFSET_TYPE = exports.ADD_POSITION_OFFSET_TYPE = [_elementType.PARAGRAPH, _elementType.SUBTITLE, _elementType.HEADER1, _elementType.HEADER2, _elementType.HEADER3, _elementType.HEADER4, _elementType.HEADER5, _elementType.HEADER6, _elementType.CHECK_LIST_ITEM, _elementType.IMAGE_BLOCK];
|
|
533
533
|
const FILE_TYPE = exports.FILE_TYPE = {
|
|
534
534
|
[_elementType.FILE_LINK]: 'file',
|
|
535
|
-
[_elementType.SDOC_LINK]: 'sdoc'
|
|
535
|
+
[_elementType.SDOC_LINK]: 'sdoc',
|
|
536
|
+
[_elementType.VIDEO]: 'video'
|
|
536
537
|
};
|
|
537
538
|
const SUPPORTED_SIDE_OPERATION_TYPE = exports.SUPPORTED_SIDE_OPERATION_TYPE = [_elementType.PARAGRAPH, _elementType.SUBTITLE, _elementType.HEADER1, _elementType.HEADER2, _elementType.HEADER3, _elementType.HEADER4, _elementType.HEADER5, _elementType.HEADER6, _elementType.CHECK_LIST_ITEM, _elementType.CODE_BLOCK, _elementType.TABLE, _elementType.BLOCKQUOTE, _elementType.CALL_OUT, _elementType.IMAGE_BLOCK, _elementType.VIDEO, _elementType.SEATABLE_TABLE, _elementType.MULTI_COLUMN];
|
|
538
539
|
const MOUSE_ENTER_EVENT_DISABLED_MAP = exports.MOUSE_ENTER_EVENT_DISABLED_MAP = {
|
|
@@ -20,8 +20,9 @@ var _useScrollContext = require("../../../hooks/use-scroll-context");
|
|
|
20
20
|
var _constants2 = require("./constants");
|
|
21
21
|
var _constants3 = require("../../constants");
|
|
22
22
|
var _constants4 = require("../../../../constants");
|
|
23
|
+
var _imagePlaceholder = _interopRequireDefault(require("../../../assets/images/image-placeholder.png"));
|
|
23
24
|
const Image = _ref => {
|
|
24
|
-
var _imageRef$current, _imageRef$current2
|
|
25
|
+
var _imageRef$current, _imageRef$current2;
|
|
25
26
|
let {
|
|
26
27
|
element,
|
|
27
28
|
editor,
|
|
@@ -56,7 +57,6 @@ const Image = _ref => {
|
|
|
56
57
|
const [isShowImageHoverMenu, setIsShowImageHoverMenu] = (0, _react.useState)(false);
|
|
57
58
|
const [menuPosition, setMenuPosition] = (0, _react.useState)({});
|
|
58
59
|
const [caption, setCaption] = (0, _react.useState)((data === null || data === void 0 ? void 0 : data.caption) || '');
|
|
59
|
-
const [isLoading, setIsLoading] = (0, _react.useState)(true);
|
|
60
60
|
const registerEvent = (0, _react.useCallback)(eventList => {
|
|
61
61
|
eventList.forEach(element => {
|
|
62
62
|
document.addEventListener(element.eventName, element.event);
|
|
@@ -71,17 +71,12 @@ const Image = _ref => {
|
|
|
71
71
|
var _resizerRef$current;
|
|
72
72
|
event.preventDefault();
|
|
73
73
|
event.stopPropagation();
|
|
74
|
-
if (!imageRef.current) return;
|
|
75
74
|
const changeX = event.clientX - ((_resizerRef$current = resizerRef.current) === null || _resizerRef$current === void 0 ? void 0 : _resizerRef$current.getBoundingClientRect().left) - 5;
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
imageRef.current.width = newWidth;
|
|
82
|
-
}
|
|
83
|
-
setMovingWidth(newWidth);
|
|
84
|
-
}, [isShowImagePlaceholder]);
|
|
75
|
+
const imageWidth = imageRef.current.width + changeX;
|
|
76
|
+
if (imageWidth < 20) return;
|
|
77
|
+
imageRef.current.width = imageWidth;
|
|
78
|
+
setMovingWidth(imageWidth);
|
|
79
|
+
}, []);
|
|
85
80
|
const onResizeEnd = (0, _react.useCallback)(event => {
|
|
86
81
|
event.preventDefault();
|
|
87
82
|
event.stopPropagation();
|
|
@@ -207,7 +202,6 @@ const Image = _ref => {
|
|
|
207
202
|
if (data.src.startsWith('data:image/jpeg;base64')) {
|
|
208
203
|
return (0, _helpers.handleBase64Image)(editor, path, data);
|
|
209
204
|
}
|
|
210
|
-
setIsLoading(false);
|
|
211
205
|
setIsShowImagePlaceholder(true);
|
|
212
206
|
// External network images do not reload after failure to load
|
|
213
207
|
if (!data.src.startsWith('http')) {
|
|
@@ -230,22 +224,7 @@ const Image = _ref => {
|
|
|
230
224
|
});
|
|
231
225
|
}
|
|
232
226
|
}, [data, editor, element]);
|
|
233
|
-
(
|
|
234
|
-
if (imageRef.current) {
|
|
235
|
-
imageRef.current.onload = () => setIsLoading(false);
|
|
236
|
-
imageRef.current.onerror = onImageLoadError;
|
|
237
|
-
}
|
|
238
|
-
}, [data, editor]);
|
|
239
|
-
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
|
|
240
|
-
className: "sdoc-image-process-container",
|
|
241
|
-
style: {
|
|
242
|
-
display: isLoading ? 'inline-block' : 'none'
|
|
243
|
-
}
|
|
244
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
245
|
-
className: "loading-spinner"
|
|
246
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
247
|
-
className: "spinner"
|
|
248
|
-
})), children), isShowImagePlaceholder && /*#__PURE__*/_react.default.createElement("span", Object.assign({
|
|
227
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isShowImagePlaceholder && /*#__PURE__*/_react.default.createElement("span", Object.assign({
|
|
249
228
|
className: (0, _classnames.default)('sdoc-image-wrapper', className)
|
|
250
229
|
}, attributes, {
|
|
251
230
|
style: {
|
|
@@ -254,64 +233,13 @@ const Image = _ref => {
|
|
|
254
233
|
onMouseOver: e => (0, _helpers.selectImageWhenSelectPartial)(e, editor, element, isSelected),
|
|
255
234
|
contentEditable: "false",
|
|
256
235
|
suppressContentEditableWarning: true
|
|
257
|
-
}), /*#__PURE__*/_react.default.createElement("
|
|
258
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
259
|
-
viewBox: "0 0 360 360",
|
|
260
|
-
preserveAspectRatio: "xMinYMin meet",
|
|
261
|
-
className: (0, _classnames.default)('sdoc-image-placeholder-wrapper', {
|
|
262
|
-
'image-selected': isSelected
|
|
263
|
-
}),
|
|
236
|
+
}), /*#__PURE__*/_react.default.createElement("img", {
|
|
264
237
|
ref: imageRef,
|
|
238
|
+
src: _imagePlaceholder.default,
|
|
265
239
|
style: getImageStyle(),
|
|
266
|
-
draggable: false
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
height: "100%",
|
|
270
|
-
fill: "#f0f0f0"
|
|
271
|
-
}), /*#__PURE__*/_react.default.createElement("g", {
|
|
272
|
-
className: "sdoc-image-content-wrapper",
|
|
273
|
-
textAnchor: "middle",
|
|
274
|
-
dominantBaseline: "middle",
|
|
275
|
-
transform: "translate(180, 180)"
|
|
276
|
-
}, /*#__PURE__*/_react.default.createElement("g", {
|
|
277
|
-
className: "sdoc-image-title",
|
|
278
|
-
transform: "translate(0, 0)"
|
|
279
|
-
}, /*#__PURE__*/_react.default.createElement("foreignObject", {
|
|
280
|
-
x: "-22%",
|
|
281
|
-
y: "-16",
|
|
282
|
-
width: "20",
|
|
283
|
-
height: "28"
|
|
284
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
285
|
-
className: "sdocfont sdoc-exclamation-circle"
|
|
286
|
-
})), /*#__PURE__*/_react.default.createElement("text", {
|
|
287
|
-
className: "sdoc-image-tip-title",
|
|
288
|
-
x: "5%",
|
|
289
|
-
fontSize: "20",
|
|
290
|
-
fill: "red",
|
|
291
|
-
fontFamily: "Arial, sans-serif"
|
|
292
|
-
}, t('Image_copy_error'))), /*#__PURE__*/_react.default.createElement("text", {
|
|
293
|
-
className: "sdoc-image-tip-content",
|
|
294
|
-
x: "0",
|
|
295
|
-
y: "10%",
|
|
296
|
-
fontSize: "12",
|
|
297
|
-
textAnchor: "middle",
|
|
298
|
-
fill: "black",
|
|
299
|
-
fontFamily: "Arial, sans-serif"
|
|
300
|
-
}, t('Image_cannot_be_copied_Please_download_the_source_image')), /*#__PURE__*/_react.default.createElement("text", {
|
|
301
|
-
className: "sdoc-image-tip-content",
|
|
302
|
-
x: "0",
|
|
303
|
-
y: "16%",
|
|
304
|
-
fontSize: "12",
|
|
305
|
-
textAnchor: "middle",
|
|
306
|
-
fill: "black",
|
|
307
|
-
fontFamily: "Arial, sans-serif"
|
|
308
|
-
}, t('And_select_insert_-_image_to_upload')))), isSelected && /*#__PURE__*/_react.default.createElement("span", {
|
|
309
|
-
className: "image-resizer",
|
|
310
|
-
ref: resizerRef,
|
|
311
|
-
onMouseDown: onResizeStart
|
|
312
|
-
}), isResizing && /*#__PURE__*/_react.default.createElement("span", {
|
|
313
|
-
className: "image-size"
|
|
314
|
-
}, /*#__PURE__*/_react.default.createElement("span", null, t('Width'), ':', parseInt(movingWidth || ((_imageRef$current = imageRef.current) === null || _imageRef$current === void 0 ? void 0 : _imageRef$current.clientWidth))), /*#__PURE__*/_react.default.createElement("span", null, "\xA0\xA0"), /*#__PURE__*/_react.default.createElement("span", null, t('Height'), ':', imageRef.current.clientHeight)), children), !isShowImagePlaceholder && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", Object.assign({
|
|
240
|
+
draggable: false,
|
|
241
|
+
alt: ""
|
|
242
|
+
}), children), !isShowImagePlaceholder && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", Object.assign({
|
|
315
243
|
"data-id": element.id,
|
|
316
244
|
className: (0, _classnames.default)('sdoc-image-wrapper', className)
|
|
317
245
|
}, attributes, {
|
|
@@ -344,12 +272,12 @@ const Image = _ref => {
|
|
|
344
272
|
onMouseDown: onResizeStart
|
|
345
273
|
}), isResizing && /*#__PURE__*/_react.default.createElement("span", {
|
|
346
274
|
className: "image-size"
|
|
347
|
-
}, /*#__PURE__*/_react.default.createElement("span", null, t('Width'), ':', parseInt(movingWidth || ((_imageRef$
|
|
275
|
+
}, /*#__PURE__*/_react.default.createElement("span", null, t('Width'), ':', parseInt(movingWidth || ((_imageRef$current = imageRef.current) === null || _imageRef$current === void 0 ? void 0 : _imageRef$current.clientWidth))), /*#__PURE__*/_react.default.createElement("span", null, "\xA0\xA0"), /*#__PURE__*/_react.default.createElement("span", null, t('Height'), ':', imageRef.current.clientHeight))), nodeEntry[0].type === _constants3.IMAGE_BLOCK && show_caption && /*#__PURE__*/_react.default.createElement("input", {
|
|
348
276
|
id: "sdoc-image-caption-input",
|
|
349
277
|
ref: imageCaptionInputRef,
|
|
350
278
|
className: "sdoc-image-caption-input-wrapper",
|
|
351
279
|
style: {
|
|
352
|
-
width: (data === null || data === void 0 ? void 0 : data.width) || ((_imageRef$
|
|
280
|
+
width: (data === null || data === void 0 ? void 0 : data.width) || ((_imageRef$current2 = imageRef.current) === null || _imageRef$current2 === void 0 ? void 0 : _imageRef$current2.clientWidth)
|
|
353
281
|
},
|
|
354
282
|
placeholder: t('Caption'),
|
|
355
283
|
autoComplete: "off",
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.unwrapLinkNode = exports.
|
|
7
|
+
exports.unwrapLinkNode = exports.removeTempInput = exports.removeShortCutSymbol = exports.onCopySdocLinkNode = exports.isTriggeredByShortcut = exports.isMenuDisabled = exports.insertTextWhenRemoveFileNameCollector = exports.insertTempInput = exports.insertSdocFileLink = exports.getUrl = exports.getType = exports.getSdocLinkEntry = exports.getSdocFileIcon = exports.getNewFileListData = exports.getFileSearchInputEntry = exports.getBeforeText = exports.generateSdocFileNode = void 0;
|
|
8
8
|
var _slateReact = require("@seafile/slate-react");
|
|
9
9
|
var _slate = require("@seafile/slate");
|
|
10
10
|
var _slugid = _interopRequireDefault(require("slugid"));
|
|
@@ -274,11 +274,11 @@ const insertTextWhenRemoveFileNameCollector = (editor, searchInputNode) => {
|
|
|
274
274
|
removeTempInput(editor, searchInputNode);
|
|
275
275
|
};
|
|
276
276
|
exports.insertTextWhenRemoveFileNameCollector = insertTextWhenRemoveFileNameCollector;
|
|
277
|
-
const
|
|
277
|
+
const getSdocFileIcon = () => {
|
|
278
278
|
const server = _context.default.getSetting('serviceUrl');
|
|
279
279
|
return `${server}/media/img/file/256/sdoc.png`;
|
|
280
280
|
};
|
|
281
|
-
exports.
|
|
281
|
+
exports.getSdocFileIcon = getSdocFileIcon;
|
|
282
282
|
const getSdocLinkEntry = function (editor) {
|
|
283
283
|
let at = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : editor.selection;
|
|
284
284
|
const aboveNodeEntry = _slate.Editor.above(editor, {
|
|
@@ -147,7 +147,7 @@ const SdocFileLink = _ref => {
|
|
|
147
147
|
style: style
|
|
148
148
|
}, element.type !== _elementType.WIKI_LINK && /*#__PURE__*/_react.default.createElement("img", {
|
|
149
149
|
className: "file-link-img",
|
|
150
|
-
src: (0, _helpers.
|
|
150
|
+
src: (0, _helpers.getSdocFileIcon)(),
|
|
151
151
|
alt: ""
|
|
152
152
|
}), element.type === _elementType.WIKI_LINK && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, icon && /*#__PURE__*/_react.default.createElement("span", null, icon), !icon && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isDir ? /*#__PURE__*/_react.default.createElement("span", {
|
|
153
153
|
className: "sf3-font sf3-font-files2"
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
var _reactI18next = require("react-i18next");
|
|
10
|
+
var _reactstrap = require("reactstrap");
|
|
11
|
+
var _helpers = require("../../helpers");
|
|
12
|
+
const AddVideoLinkDialog = _ref => {
|
|
13
|
+
let {
|
|
14
|
+
editor,
|
|
15
|
+
className,
|
|
16
|
+
closeDialog,
|
|
17
|
+
handleSubmit
|
|
18
|
+
} = _ref;
|
|
19
|
+
const {
|
|
20
|
+
t
|
|
21
|
+
} = (0, _reactI18next.useTranslation)('sdoc-editor');
|
|
22
|
+
const [linkErrorMessage, setLinkErrorMessage] = (0, _react.useState)('');
|
|
23
|
+
const [url, setURL] = (0, _react.useState)('');
|
|
24
|
+
const isValidVideoLink = link => {
|
|
25
|
+
const videoRegex = /v\.qq\.com|youtube\.com|v\.youku\.com|bilibili\.com/i;
|
|
26
|
+
return videoRegex.test(link);
|
|
27
|
+
};
|
|
28
|
+
const submit = (0, _react.useCallback)(() => {
|
|
29
|
+
setLinkErrorMessage('');
|
|
30
|
+
if (!url) {
|
|
31
|
+
setLinkErrorMessage(t('The_link_address_is_required'));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (!isValidVideoLink(url)) {
|
|
35
|
+
setLinkErrorMessage(t('The_link_address_is_invalid'));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
(0, _helpers.insertVideo)(editor, [{
|
|
39
|
+
name: url,
|
|
40
|
+
isEmbeddableLink: true
|
|
41
|
+
}], [url]);
|
|
42
|
+
handleSubmit && handleSubmit();
|
|
43
|
+
closeDialog();
|
|
44
|
+
|
|
45
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
46
|
+
}, [editor, url]);
|
|
47
|
+
const onKeyDown = (0, _react.useCallback)(event => {
|
|
48
|
+
if (event.keyCode === 13) {
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
submit();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
54
|
+
}, [editor, url]);
|
|
55
|
+
const handleUrlChange = (0, _react.useCallback)(event => {
|
|
56
|
+
const videoUrl = event.target.value;
|
|
57
|
+
if (videoUrl === url) return;
|
|
58
|
+
setURL(videoUrl);
|
|
59
|
+
}, [url]);
|
|
60
|
+
return /*#__PURE__*/_react.default.createElement(_reactstrap.Modal, {
|
|
61
|
+
isOpen: true,
|
|
62
|
+
autoFocus: false,
|
|
63
|
+
toggle: closeDialog,
|
|
64
|
+
className: className,
|
|
65
|
+
zIndex: 1071,
|
|
66
|
+
returnFocusAfterClose: false
|
|
67
|
+
}, /*#__PURE__*/_react.default.createElement(_reactstrap.ModalHeader, {
|
|
68
|
+
toggle: closeDialog
|
|
69
|
+
}, t('Insert_link')), /*#__PURE__*/_react.default.createElement(_reactstrap.ModalBody, null, /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
|
|
70
|
+
className: "form-group"
|
|
71
|
+
}, /*#__PURE__*/_react.default.createElement(_reactstrap.Label, {
|
|
72
|
+
for: "addLink"
|
|
73
|
+
}, t('Link_address')), /*#__PURE__*/_react.default.createElement("input", {
|
|
74
|
+
onKeyDown: onKeyDown,
|
|
75
|
+
autoFocus: true,
|
|
76
|
+
type: "url",
|
|
77
|
+
className: "form-control",
|
|
78
|
+
id: "addVideoLink",
|
|
79
|
+
value: url || '',
|
|
80
|
+
onChange: handleUrlChange
|
|
81
|
+
}), linkErrorMessage && /*#__PURE__*/_react.default.createElement(_reactstrap.Alert, {
|
|
82
|
+
color: "danger",
|
|
83
|
+
className: "mt-2"
|
|
84
|
+
}, t(linkErrorMessage))), /*#__PURE__*/_react.default.createElement("div", {
|
|
85
|
+
style: {
|
|
86
|
+
textAlign: 'center',
|
|
87
|
+
fontSize: '12px',
|
|
88
|
+
color: '#787774'
|
|
89
|
+
}
|
|
90
|
+
}, t('Support_Youtube_Tencent_Bilibili_and_more')))), /*#__PURE__*/_react.default.createElement(_reactstrap.ModalFooter, null, /*#__PURE__*/_react.default.createElement(_reactstrap.Button, {
|
|
91
|
+
color: "secondary",
|
|
92
|
+
onClick: closeDialog
|
|
93
|
+
}, t('Cancel')), /*#__PURE__*/_react.default.createElement(_reactstrap.Button, {
|
|
94
|
+
color: "primary",
|
|
95
|
+
disabled: false,
|
|
96
|
+
onClick: submit
|
|
97
|
+
}, t('Add_link'))));
|
|
98
|
+
};
|
|
99
|
+
var _default = exports.default = AddVideoLinkDialog;
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.videoFileIcon = exports.isInsertVideoMenuDisabled = exports.insertVideo = exports.getVideoURL = exports.generateVideoNode = exports.formatFileSize = void 0;
|
|
7
|
+
exports.videoFileIcon = exports.parseVideoLink = exports.isInsertVideoMenuDisabled = exports.insertVideo = exports.getVideoURL = exports.generateVideoNode = exports.formatFileSize = void 0;
|
|
8
8
|
var _urlJoin = _interopRequireDefault(require("url-join"));
|
|
9
9
|
var _slate = require("@seafile/slate");
|
|
10
10
|
var _core = require("../../core");
|
|
@@ -43,26 +43,79 @@ const isInsertVideoMenuDisabled = (editor, readonly) => {
|
|
|
43
43
|
return false;
|
|
44
44
|
};
|
|
45
45
|
exports.isInsertVideoMenuDisabled = isInsertVideoMenuDisabled;
|
|
46
|
-
const generateVideoNode = (src,
|
|
46
|
+
const generateVideoNode = (src, videoInfo) => {
|
|
47
47
|
const element = (0, _core.generateEmptyElement)(_constants.VIDEO);
|
|
48
|
-
|
|
48
|
+
const {
|
|
49
|
+
name,
|
|
50
|
+
size,
|
|
51
|
+
is_embeddable_link
|
|
52
|
+
} = videoInfo;
|
|
53
|
+
return [{
|
|
49
54
|
...element,
|
|
50
55
|
data: {
|
|
51
56
|
src,
|
|
52
|
-
|
|
57
|
+
name,
|
|
58
|
+
size,
|
|
59
|
+
is_embeddable_link
|
|
53
60
|
}
|
|
54
|
-
};
|
|
61
|
+
}];
|
|
55
62
|
};
|
|
56
63
|
exports.generateVideoNode = generateVideoNode;
|
|
64
|
+
const parseVideoLink = url => {
|
|
65
|
+
if (!url) return false;
|
|
66
|
+
|
|
67
|
+
// Youtube url conversion
|
|
68
|
+
if (url.includes('youtube.com')) {
|
|
69
|
+
const videoId = new URL(url).searchParams.get('v');
|
|
70
|
+
const videoUrl = videoId ? `https://www.youtube.com/embed/${videoId}/?rel=0` : false;
|
|
71
|
+
return videoUrl;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Tencent url conversion
|
|
75
|
+
if (url.includes('v.qq.com')) {
|
|
76
|
+
const vidMatch = url.match(/\/([^\/]+)\.html/);
|
|
77
|
+
const videoUrl = vidMatch !== null && vidMatch !== void 0 && vidMatch[1] ? `https://v.qq.com/txp/iframe/player.html?vid=${vidMatch[1]}` : false;
|
|
78
|
+
return videoUrl;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Bilibili url conversion
|
|
82
|
+
if (url.includes('bilibili.com')) {
|
|
83
|
+
const vidMatch = url.match(/\/video\/(BV[0-9A-Za-z]+)/);
|
|
84
|
+
const videoUrl = vidMatch !== null && vidMatch !== void 0 && vidMatch[1] ? `https://player.bilibili.com/player.html?bvid=${vidMatch[1]}` : false;
|
|
85
|
+
return videoUrl;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Youku url conversion
|
|
89
|
+
if (url.includes('v.youku.com')) {
|
|
90
|
+
const vidMatch = url.match(/id_([A-Za-z0-9=]+)\.html/);
|
|
91
|
+
const videoUrl = vidMatch !== null && vidMatch !== void 0 && vidMatch[1] ? `https://player.youku.com/embed/${vidMatch[1]}` : false;
|
|
92
|
+
return videoUrl;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Unsupported url
|
|
96
|
+
return false;
|
|
97
|
+
};
|
|
98
|
+
exports.parseVideoLink = parseVideoLink;
|
|
57
99
|
const insertVideo = function (editor, videoFiles, srcList, selection) {
|
|
58
100
|
let position = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : _constants.INSERT_POSITION.CURRENT;
|
|
59
101
|
if (!srcList) return;
|
|
60
102
|
if (position !== _constants.INSERT_POSITION.AFTER) {
|
|
61
103
|
if (isInsertVideoMenuDisabled(editor)) return;
|
|
62
104
|
}
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
105
|
+
const videoInfo = {
|
|
106
|
+
name: videoFiles[0].name || null,
|
|
107
|
+
size: videoFiles[0].size || null,
|
|
108
|
+
is_embeddable_link: videoFiles[0].isEmbeddableLink || false
|
|
109
|
+
};
|
|
110
|
+
let videoNodes;
|
|
111
|
+
// Return when embedding an invalid youtube, tencent or bilibili video url
|
|
112
|
+
if (videoInfo.is_embeddable_link) {
|
|
113
|
+
const parsedSrc = parseVideoLink(srcList[0]);
|
|
114
|
+
if (!parsedSrc) return;
|
|
115
|
+
videoNodes = generateVideoNode(parsedSrc, videoInfo);
|
|
116
|
+
} else {
|
|
117
|
+
videoNodes = generateVideoNode(srcList[0], videoInfo);
|
|
118
|
+
}
|
|
66
119
|
const validSelection = selection || editor.selection;
|
|
67
120
|
let path = _slate.Editor.path(editor, validSelection);
|
|
68
121
|
if (position === _constants.INSERT_POSITION.AFTER) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
.video-loading-placeholder {
|
|
2
2
|
background-color: #F2F2F2;
|
|
3
3
|
width: 100%;
|
|
4
|
-
height:
|
|
4
|
+
height: auto;
|
|
5
5
|
display: flex;
|
|
6
6
|
align-items: center;
|
|
7
7
|
}
|
|
@@ -49,14 +49,15 @@
|
|
|
49
49
|
|
|
50
50
|
.sdoc-video-wrapper .sdoc-video-inner {
|
|
51
51
|
position: relative;
|
|
52
|
-
width:
|
|
52
|
+
width: 100%;
|
|
53
|
+
aspect-ratio: 16 / 9;
|
|
53
54
|
display: flex;
|
|
54
55
|
margin-top: 5px;
|
|
55
56
|
margin-bottom: 10px;
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
.sdoc-video-inner .sdoc-video-element{
|
|
59
|
-
width:
|
|
60
|
+
width: 100%;
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
.sdoc-video-inner .sdoc-video-element:focus-visible {
|
|
@@ -17,6 +17,7 @@ const VideoMenu = _ref => {
|
|
|
17
17
|
let {
|
|
18
18
|
editor,
|
|
19
19
|
readonly,
|
|
20
|
+
toggle,
|
|
20
21
|
eventBus
|
|
21
22
|
} = _ref;
|
|
22
23
|
const disabled = (0, _helpers.isInsertVideoMenuDisabled)(editor, readonly);
|
|
@@ -30,6 +31,22 @@ const VideoMenu = _ref => {
|
|
|
30
31
|
editor
|
|
31
32
|
});
|
|
32
33
|
}, [editor, eventBus]);
|
|
34
|
+
const addVideoLink = (0, _react.useCallback)(() => {
|
|
35
|
+
eventBus.dispatch(_constants2.INTERNAL_EVENT.INSERT_ELEMENT, {
|
|
36
|
+
type: _constants.ELEMENT_TYPE.VIDEO_LINK,
|
|
37
|
+
editor
|
|
38
|
+
});
|
|
39
|
+
toggle && toggle();
|
|
40
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
|
+
}, [editor, eventBus]);
|
|
42
|
+
const openSelectVideoFileDialog = (0, _react.useCallback)(() => {
|
|
43
|
+
eventBus.dispatch(_constants2.INTERNAL_EVENT.INSERT_ELEMENT, {
|
|
44
|
+
type: _constants.ELEMENT_TYPE.VIDEO,
|
|
45
|
+
insertVideo: _helpers.insertVideo
|
|
46
|
+
});
|
|
47
|
+
toggle && toggle();
|
|
48
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
49
|
+
}, [toggle, eventBus]);
|
|
33
50
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_dropdownMenuItem.default, {
|
|
34
51
|
disabled: disabled,
|
|
35
52
|
menuConfig: menuConfig,
|
|
@@ -48,6 +65,12 @@ const VideoMenu = _ref => {
|
|
|
48
65
|
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
49
66
|
className: "sdoc-dropdown-menu-item",
|
|
50
67
|
onClick: openLocalVideoDialog
|
|
51
|
-
}, t('Upload_local_video'))
|
|
68
|
+
}, t('Upload_local_video')), /*#__PURE__*/_react.default.createElement("div", {
|
|
69
|
+
className: "sdoc-dropdown-menu-item",
|
|
70
|
+
onClick: addVideoLink
|
|
71
|
+
}, t('Add_video_link')), /*#__PURE__*/_react.default.createElement("div", {
|
|
72
|
+
className: "sdoc-dropdown-menu-item",
|
|
73
|
+
onClick: openSelectVideoFileDialog
|
|
74
|
+
}, t('Link_Seafile_video_file')))));
|
|
52
75
|
};
|
|
53
76
|
var _default = exports.default = VideoMenu;
|
|
@@ -12,7 +12,7 @@ var _reactI18next = require("react-i18next");
|
|
|
12
12
|
var _helpers = require("./helpers");
|
|
13
13
|
require("./index.css");
|
|
14
14
|
const Video = _ref => {
|
|
15
|
-
var
|
|
15
|
+
var _videoStates$element$;
|
|
16
16
|
let {
|
|
17
17
|
element,
|
|
18
18
|
editor
|
|
@@ -24,8 +24,9 @@ const Video = _ref => {
|
|
|
24
24
|
const [isLoaded, setIsLoaded] = (0, _react.useState)(false);
|
|
25
25
|
const [isSelected, setIsSelected] = (0, _react.useState)(false);
|
|
26
26
|
const [videoStates, setVideoStates] = (0, _react.useState)({});
|
|
27
|
-
const
|
|
28
|
-
const
|
|
27
|
+
const videoName = (data === null || data === void 0 ? void 0 : data.name) || (data === null || data === void 0 ? void 0 : data.src);
|
|
28
|
+
const videoSize = data === null || data === void 0 ? void 0 : data.size;
|
|
29
|
+
const isEmbeddableLink = data === null || data === void 0 ? void 0 : data.is_embeddable_link;
|
|
29
30
|
const handlePlay = () => {
|
|
30
31
|
setVideoStates(prev => ({
|
|
31
32
|
...prev,
|
|
@@ -75,9 +76,9 @@ const Video = _ref => {
|
|
|
75
76
|
alt: ""
|
|
76
77
|
}), /*#__PURE__*/_react.default.createElement("div", {
|
|
77
78
|
className: "video-file-info"
|
|
78
|
-
}, /*#__PURE__*/_react.default.createElement("div", null,
|
|
79
|
+
}, /*#__PURE__*/_react.default.createElement("div", null, videoName), /*#__PURE__*/_react.default.createElement("div", {
|
|
79
80
|
className: "file-size"
|
|
80
|
-
}, /*#__PURE__*/_react.default.createElement("span", null, (0, _helpers.formatFileSize)(
|
|
81
|
+
}, /*#__PURE__*/_react.default.createElement("span", null, (0, _helpers.formatFileSize)(videoSize), " \u2014 "), /*#__PURE__*/_react.default.createElement("div", {
|
|
81
82
|
className: "loading-spinner"
|
|
82
83
|
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
83
84
|
className: "spinner"
|
|
@@ -92,10 +93,10 @@ const Video = _ref => {
|
|
|
92
93
|
style: {
|
|
93
94
|
visibility: isLoaded ? 'visible' : 'hidden'
|
|
94
95
|
}
|
|
95
|
-
}, /*#__PURE__*/_react.default.createElement("video", {
|
|
96
|
+
}, !isEmbeddableLink && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("video", {
|
|
96
97
|
className: "sdoc-video-element",
|
|
97
98
|
ref: videoRef,
|
|
98
|
-
src: (0, _helpers.getVideoURL)(data
|
|
99
|
+
src: (0, _helpers.getVideoURL)(data),
|
|
99
100
|
controls: true,
|
|
100
101
|
onClick: onClickVideo,
|
|
101
102
|
draggable: false,
|
|
@@ -111,6 +112,18 @@ const Video = _ref => {
|
|
|
111
112
|
visibility: isPaused ? 'visible' : 'hidden'
|
|
112
113
|
},
|
|
113
114
|
contentEditable: "false"
|
|
115
|
+
})), isEmbeddableLink && /*#__PURE__*/_react.default.createElement("iframe", {
|
|
116
|
+
className: "sdoc-video-element",
|
|
117
|
+
title: data.src,
|
|
118
|
+
allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
|
|
119
|
+
allowFullScreen: true,
|
|
120
|
+
src: (0, _helpers.getVideoURL)(data),
|
|
121
|
+
onLoad: handleVideoLoad,
|
|
122
|
+
style: {
|
|
123
|
+
width: '100%',
|
|
124
|
+
height: '100%',
|
|
125
|
+
border: 'none'
|
|
126
|
+
}
|
|
114
127
|
}))));
|
|
115
128
|
};
|
|
116
129
|
const SdocVideo = (0, _reactI18next.withTranslation)('sdoc-editor')(Video);
|
|
@@ -31,6 +31,7 @@ const RevisionDiffViewer = _ref => {
|
|
|
31
31
|
let originContent = JSON.parse(originContentString);
|
|
32
32
|
originContent = (0, _formatSdocContent.formatSdocContent)(originContent);
|
|
33
33
|
const diff = (0, _diff.getDiff)(revisionContent, originContent);
|
|
34
|
+
console.log('diff', diff);
|
|
34
35
|
setDiff(diff);
|
|
35
36
|
didMountCallback && didMountCallback(diff);
|
|
36
37
|
setIsLoading(false);
|
package/dist/constants/index.js
CHANGED
|
@@ -36,6 +36,7 @@ const EXTERNAL_EVENT = exports.EXTERNAL_EVENT = {
|
|
|
36
36
|
PARTICIPANT_REMOVED: 'participant-removed',
|
|
37
37
|
CREATE_SDOC_FILE: 'create_sdoc_file',
|
|
38
38
|
CREATE_WIKI_PAGE: 'create_wiki_page',
|
|
39
|
+
ADD_VIDEO_LINK: 'add_video_link',
|
|
39
40
|
// wiki
|
|
40
41
|
INSERT_LINK: 'insert_link',
|
|
41
42
|
// document
|
|
@@ -52,6 +52,7 @@ const SimpleEditor = _ref => {
|
|
|
52
52
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
53
53
|
}, []);
|
|
54
54
|
const setDiffChanges = (0, _react.useCallback)(diff => {
|
|
55
|
+
console.log(32323);
|
|
55
56
|
setChanges(diff);
|
|
56
57
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
57
58
|
}, [isShowChanges]);
|
package/package.json
CHANGED
|
@@ -573,7 +573,7 @@
|
|
|
573
573
|
"Five_column": "5 columns",
|
|
574
574
|
"Full_width_mode": "Full width mode",
|
|
575
575
|
"Video": "Video",
|
|
576
|
-
"Upload_local_video": "
|
|
576
|
+
"Upload_local_video": "Upload local video",
|
|
577
577
|
"The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
|
|
578
578
|
"Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
|
|
579
579
|
"Link_to_page": "Link to page",
|
|
@@ -607,6 +607,8 @@
|
|
|
607
607
|
"Enter_reply": "Enter reply",
|
|
608
608
|
"Processing_content_cannot_be_empty": "Processing content cannot be empty",
|
|
609
609
|
"AI_error_message": "Request error, please try again",
|
|
610
|
-
"
|
|
611
|
-
"
|
|
610
|
+
"Add_video_link": "Add video link",
|
|
611
|
+
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
|
+
"Select_video_file": "Select video file",
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
612
614
|
}
|
|
@@ -573,7 +573,7 @@
|
|
|
573
573
|
"Five_column": "5 Spalten",
|
|
574
574
|
"Full_width_mode": "Full width mode",
|
|
575
575
|
"Video": "Video",
|
|
576
|
-
"Upload_local_video": "
|
|
576
|
+
"Upload_local_video": "Lokales Video hochladen",
|
|
577
577
|
"The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
|
|
578
578
|
"Token_expired_Please_refresh_the_page": "Der Token ist abgelaufen. Laden Sie die Seite neu.",
|
|
579
579
|
"Link_to_page": "Link to page",
|
|
@@ -607,6 +607,8 @@
|
|
|
607
607
|
"Enter_reply": "Antwort eingeben",
|
|
608
608
|
"Processing_content_cannot_be_empty": "Processing content cannot be empty",
|
|
609
609
|
"AI_error_message": "Request error, please try again",
|
|
610
|
-
"
|
|
611
|
-
"
|
|
610
|
+
"Add_video_link": "Videolink hinzufügen",
|
|
611
|
+
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
|
+
"Select_video_file": "Select video file",
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
612
614
|
}
|
|
@@ -573,7 +573,7 @@
|
|
|
573
573
|
"Five_column": "5 columns",
|
|
574
574
|
"Full_width_mode": "Full width mode",
|
|
575
575
|
"Video": "Video",
|
|
576
|
-
"Upload_local_video": "
|
|
576
|
+
"Upload_local_video": "Upload local video",
|
|
577
577
|
"The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
|
|
578
578
|
"Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
|
|
579
579
|
"Link_to_page": "Link to page",
|
|
@@ -607,6 +607,8 @@
|
|
|
607
607
|
"Enter_reply": "Enter reply",
|
|
608
608
|
"Processing_content_cannot_be_empty": "Processing content cannot be empty",
|
|
609
609
|
"AI_error_message": "Request error, please try again",
|
|
610
|
-
"
|
|
611
|
-
"
|
|
610
|
+
"Add_video_link": "Add video link",
|
|
611
|
+
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
|
+
"Select_video_file": "Select video file",
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
612
614
|
}
|
|
@@ -573,7 +573,7 @@
|
|
|
573
573
|
"Five_column": "5 columns",
|
|
574
574
|
"Full_width_mode": "Full width mode",
|
|
575
575
|
"Video": "Video",
|
|
576
|
-
"Upload_local_video": "
|
|
576
|
+
"Upload_local_video": "Upload local video",
|
|
577
577
|
"The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
|
|
578
578
|
"Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
|
|
579
579
|
"Link_to_page": "Link to page",
|
|
@@ -607,6 +607,8 @@
|
|
|
607
607
|
"Enter_reply": "Enter reply",
|
|
608
608
|
"Processing_content_cannot_be_empty": "Processing content cannot be empty",
|
|
609
609
|
"AI_error_message": "Request error, please try again",
|
|
610
|
-
"
|
|
611
|
-
"
|
|
610
|
+
"Add_video_link": "Add video link",
|
|
611
|
+
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
|
+
"Select_video_file": "Select video file",
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
612
614
|
}
|
|
@@ -573,7 +573,7 @@
|
|
|
573
573
|
"Five_column": "5 columns",
|
|
574
574
|
"Full_width_mode": "Full width mode",
|
|
575
575
|
"Video": "Video",
|
|
576
|
-
"Upload_local_video": "
|
|
576
|
+
"Upload_local_video": "Upload local video",
|
|
577
577
|
"The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
|
|
578
578
|
"Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
|
|
579
579
|
"Link_to_page": "Link to page",
|
|
@@ -607,6 +607,8 @@
|
|
|
607
607
|
"Enter_reply": "Enter reply",
|
|
608
608
|
"Processing_content_cannot_be_empty": "Processing content cannot be empty",
|
|
609
609
|
"AI_error_message": "Request error, please try again",
|
|
610
|
-
"
|
|
611
|
-
"
|
|
610
|
+
"Add_video_link": "Add video link",
|
|
611
|
+
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
|
+
"Select_video_file": "Select video file",
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
612
614
|
}
|
|
@@ -573,7 +573,7 @@
|
|
|
573
573
|
"Five_column": "5 columns",
|
|
574
574
|
"Full_width_mode": "Full width mode",
|
|
575
575
|
"Video": "Video",
|
|
576
|
-
"Upload_local_video": "
|
|
576
|
+
"Upload_local_video": "Upload local video",
|
|
577
577
|
"The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
|
|
578
578
|
"Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
|
|
579
579
|
"Link_to_page": "Link to page",
|
|
@@ -607,6 +607,8 @@
|
|
|
607
607
|
"Enter_reply": "Enter reply",
|
|
608
608
|
"Processing_content_cannot_be_empty": "Processing content cannot be empty",
|
|
609
609
|
"AI_error_message": "Request error, please try again",
|
|
610
|
-
"
|
|
611
|
-
"
|
|
610
|
+
"Add_video_link": "Add video link",
|
|
611
|
+
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
|
+
"Select_video_file": "Select video file",
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
612
614
|
}
|
|
@@ -573,7 +573,7 @@
|
|
|
573
573
|
"Five_column": "5 columns",
|
|
574
574
|
"Full_width_mode": "Full width mode",
|
|
575
575
|
"Video": "Vidéo",
|
|
576
|
-
"Upload_local_video": "
|
|
576
|
+
"Upload_local_video": "Upload local video",
|
|
577
577
|
"The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
|
|
578
578
|
"Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
|
|
579
579
|
"Link_to_page": "Link to page",
|
|
@@ -607,6 +607,8 @@
|
|
|
607
607
|
"Enter_reply": "Enter reply",
|
|
608
608
|
"Processing_content_cannot_be_empty": "Processing content cannot be empty",
|
|
609
609
|
"AI_error_message": "Request error, please try again",
|
|
610
|
-
"
|
|
611
|
-
"
|
|
610
|
+
"Add_video_link": "Add video link",
|
|
611
|
+
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
|
+
"Select_video_file": "Select video file",
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
612
614
|
}
|
|
@@ -573,7 +573,7 @@
|
|
|
573
573
|
"Five_column": "5 columns",
|
|
574
574
|
"Full_width_mode": "Full width mode",
|
|
575
575
|
"Video": "Video",
|
|
576
|
-
"Upload_local_video": "
|
|
576
|
+
"Upload_local_video": "Upload local video",
|
|
577
577
|
"The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
|
|
578
578
|
"Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
|
|
579
579
|
"Link_to_page": "Link to page",
|
|
@@ -607,6 +607,8 @@
|
|
|
607
607
|
"Enter_reply": "Enter reply",
|
|
608
608
|
"Processing_content_cannot_be_empty": "Processing content cannot be empty",
|
|
609
609
|
"AI_error_message": "Request error, please try again",
|
|
610
|
-
"
|
|
611
|
-
"
|
|
610
|
+
"Add_video_link": "Add video link",
|
|
611
|
+
"Link_Seafile_video_file": "Link Seafile video file",
|
|
612
|
+
"Select_video_file": "Select video file",
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
612
614
|
}
|
|
@@ -573,7 +573,7 @@
|
|
|
573
573
|
"Five_column": "5 столбцов",
|
|
574
574
|
"Full_width_mode": "Режим полной ширины",
|
|
575
575
|
"Video": "Видео",
|
|
576
|
-
"Upload_local_video": "
|
|
576
|
+
"Upload_local_video": "Загрузить локального видео",
|
|
577
577
|
"The_current_version_does_not_support_>5MB_video_file": "Текущая_версия_не_поддерживает_видео_файл_>5_МБ",
|
|
578
578
|
"Token_expired_Please_refresh_the_page": "Срок действия токена истек. Обновите страницу.",
|
|
579
579
|
"Link_to_page": "Ссылка на страницу",
|
|
@@ -607,6 +607,8 @@
|
|
|
607
607
|
"Enter_reply": "Введите ответ",
|
|
608
608
|
"Processing_content_cannot_be_empty": "Содержимое обработки не может быть пустым",
|
|
609
609
|
"AI_error_message": "Ошибка запроса, попробуйте еще раз",
|
|
610
|
-
"
|
|
611
|
-
"
|
|
610
|
+
"Add_video_link": "Добавить ссылку на видео",
|
|
611
|
+
"Link_Seafile_video_file": "Ссылка на видео файл Seafile",
|
|
612
|
+
"Select_video_file": "Выбрать видео файл",
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more"
|
|
612
614
|
}
|
|
@@ -607,6 +607,8 @@
|
|
|
607
607
|
"Enter_reply": "输入回复",
|
|
608
608
|
"Processing_content_cannot_be_empty": "处理内容不能为空",
|
|
609
609
|
"AI_error_message": "请求错误,请重试",
|
|
610
|
-
"
|
|
611
|
-
"
|
|
610
|
+
"Add_video_link": "添加视频链接",
|
|
611
|
+
"Link_Seafile_video_file": "链接Seafile视频文件",
|
|
612
|
+
"Select_video_file": "选择视频文件",
|
|
613
|
+
"Support_Youtube_Tencent_Bilibili_and_more": "支持Youtube,腾讯视频,B站及其他平台"
|
|
612
614
|
}
|