@seafile/sdoc-editor 0.1.29 → 0.1.31
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/api/seafile-api.js +31 -0
- package/dist/assets/css/diff-viewer.css +19 -0
- package/dist/basic-sdk/extension/constants/element-type.js +29 -0
- package/dist/basic-sdk/extension/constants/index.js +11 -31
- package/dist/basic-sdk/extension/plugins/image/menu/index.js +0 -2
- package/dist/basic-sdk/extension/plugins/image/render-elem.js +11 -2
- package/dist/basic-sdk/extension/plugins/text-style/menu/index.js +2 -2
- package/dist/basic-sdk/utils/diff.js +191 -0
- package/dist/basic-sdk/utils/object-utils.js +57 -0
- package/dist/context.js +9 -102
- package/dist/pages/diff-viewer/diff-viewer.js +118 -0
- package/dist/pages/diff-viewer/history-version-viewer.js +10 -0
- package/dist/pages/diff-viewer/index.js +31 -0
- package/package.json +2 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
var SeafileAPI = /*#__PURE__*/function () {
|
|
5
|
+
function SeafileAPI(server, token) {
|
|
6
|
+
_classCallCheck(this, SeafileAPI);
|
|
7
|
+
this.req = axios.create({
|
|
8
|
+
baseURL: server,
|
|
9
|
+
headers: {
|
|
10
|
+
Authorization: 'Token ' + token
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
_createClass(SeafileAPI, [{
|
|
15
|
+
key: "uploadSdocImage",
|
|
16
|
+
value: function uploadSdocImage(docUuid, file) {
|
|
17
|
+
var url = '/api/v2.1/seadoc/upload-image/' + docUuid + '/';
|
|
18
|
+
var form = new FormData();
|
|
19
|
+
form.append('file', file);
|
|
20
|
+
return this.req.post(url, form);
|
|
21
|
+
}
|
|
22
|
+
}, {
|
|
23
|
+
key: "getSdocDownloadImageUrl",
|
|
24
|
+
value: function getSdocDownloadImageUrl(docUuid, imageName) {
|
|
25
|
+
var url = '/api/v2.1/seadoc/download-image/' + docUuid + '/' + encodeURIComponent(imageName);
|
|
26
|
+
return this.req.get(url);
|
|
27
|
+
}
|
|
28
|
+
}]);
|
|
29
|
+
return SeafileAPI;
|
|
30
|
+
}();
|
|
31
|
+
export default SeafileAPI;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.sdoc-diff {
|
|
2
|
+
padding: 0 5px;
|
|
3
|
+
margin: 0 -5px;
|
|
4
|
+
overflow: hidden;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.sdoc-diff-added {
|
|
8
|
+
background-color: #e6ffed;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.sdoc-diff-removed {
|
|
12
|
+
background-color: #ffeef0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.sdoc-diff-modify {
|
|
16
|
+
padding-left: 2px;
|
|
17
|
+
margin-left: -5px;
|
|
18
|
+
border-left: 3px solid #f9c513;
|
|
19
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export var BLOCKQUOTE = 'blockquote';
|
|
2
|
+
export var BOLD = 'bold';
|
|
3
|
+
export var ITALIC = 'italic';
|
|
4
|
+
export var HEADER = 'header';
|
|
5
|
+
export var HEADER1 = 'header1';
|
|
6
|
+
export var HEADER2 = 'header2';
|
|
7
|
+
export var HEADER3 = 'header3';
|
|
8
|
+
export var HEADER4 = 'header4';
|
|
9
|
+
export var HEADER5 = 'header5';
|
|
10
|
+
export var HEADER6 = 'header6';
|
|
11
|
+
export var ORDERED_LIST = 'ordered_list';
|
|
12
|
+
export var UNORDERED_LIST = 'unordered_list'; // unordered_list can not work
|
|
13
|
+
export var LIST_ITEM = 'list-item';
|
|
14
|
+
export var LIST_LIC = 'list-lic'; // placeholder
|
|
15
|
+
export var CHECK_LIST = 'check-list';
|
|
16
|
+
export var CHECK_LIST_ITEM = 'check-list-item';
|
|
17
|
+
export var PARAGRAPH = 'paragraph';
|
|
18
|
+
export var LINK = 'link';
|
|
19
|
+
export var HTML = 'html';
|
|
20
|
+
export var CODE_BLOCK = 'code-block';
|
|
21
|
+
export var CODE_LINE = 'code-line';
|
|
22
|
+
export var IMAGE = 'image';
|
|
23
|
+
export var TABLE = 'table';
|
|
24
|
+
export var TABLE_CELL = 'table-cell';
|
|
25
|
+
export var TABLE_ROW = 'table-row';
|
|
26
|
+
export var FORMULA = 'formula';
|
|
27
|
+
export var COLUMN = 'column';
|
|
28
|
+
export var TEXT_STYLE = 'text-style';
|
|
29
|
+
export var BOLD_ITALIC = 'bold-italic';
|
|
@@ -1,35 +1,8 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
2
2
|
var _MENUS_CONFIG_MAP, _HEADER_TITLE_MAP;
|
|
3
3
|
// extension plugin
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export var ITALIC = 'italic';
|
|
7
|
-
export var HEADER = 'header';
|
|
8
|
-
export var HEADER1 = 'header1';
|
|
9
|
-
export var HEADER2 = 'header2';
|
|
10
|
-
export var HEADER3 = 'header3';
|
|
11
|
-
export var HEADER4 = 'header4';
|
|
12
|
-
export var HEADER5 = 'header5';
|
|
13
|
-
export var HEADER6 = 'header6';
|
|
14
|
-
export var ORDERED_LIST = 'ordered_list';
|
|
15
|
-
export var UNORDERED_LIST = 'unordered_list'; // unordered_list can not work
|
|
16
|
-
export var LIST_ITEM = 'list-item';
|
|
17
|
-
export var LIST_LIC = 'list-lic'; // placeholder
|
|
18
|
-
export var CHECK_LIST = 'check-list';
|
|
19
|
-
export var CHECK_LIST_ITEM = 'check-list-item';
|
|
20
|
-
export var PARAGRAPH = 'paragraph';
|
|
21
|
-
export var LINK = 'link';
|
|
22
|
-
export var HTML = 'html';
|
|
23
|
-
export var CODE_BLOCK = 'code-block';
|
|
24
|
-
export var CODE_LINE = 'code-line';
|
|
25
|
-
export var IMAGE = 'image';
|
|
26
|
-
export var TABLE = 'table';
|
|
27
|
-
export var TABLE_CELL = 'table-cell';
|
|
28
|
-
export var TABLE_ROW = 'table-row';
|
|
29
|
-
export var FORMULA = 'formula';
|
|
30
|
-
export var COLUMN = 'column';
|
|
31
|
-
export var TEXTSTYLE = 'text-style';
|
|
32
|
-
export var BOLD_ITALIC = 'bold-italic';
|
|
4
|
+
import * as ELEMENT_TYPE from './element-type';
|
|
5
|
+
import { BLOCKQUOTE, BOLD, ITALIC, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, LIST_LIC, CHECK_LIST, CHECK_LIST_ITEM, PARAGRAPH, LINK, HTML, CODE_BLOCK, CODE_LINE, IMAGE, TABLE, TABLE_CELL, TABLE_ROW, FORMULA, COLUMN, TEXT_STYLE, BOLD_ITALIC } from './element-type';
|
|
33
6
|
|
|
34
7
|
// history
|
|
35
8
|
export var UNDO = 'undo';
|
|
@@ -64,7 +37,7 @@ export var MENUS_CONFIG_MAP = (_MENUS_CONFIG_MAP = {}, _defineProperty(_MENUS_CO
|
|
|
64
37
|
id: "sdoc_".concat(IMAGE),
|
|
65
38
|
iconClass: 'iconfont icon-image',
|
|
66
39
|
text: 'insert_image'
|
|
67
|
-
}), _defineProperty(_MENUS_CONFIG_MAP,
|
|
40
|
+
}), _defineProperty(_MENUS_CONFIG_MAP, TEXT_STYLE, [{
|
|
68
41
|
id: ITALIC,
|
|
69
42
|
iconClass: 'iconfont icon-italic',
|
|
70
43
|
text: 'italic',
|
|
@@ -85,4 +58,11 @@ export var MENUS_CONFIG_MAP = (_MENUS_CONFIG_MAP = {}, _defineProperty(_MENUS_CO
|
|
|
85
58
|
text: 'redo',
|
|
86
59
|
type: 'redo'
|
|
87
60
|
}), _MENUS_CONFIG_MAP);
|
|
88
|
-
export var HEADER_TITLE_MAP = (_HEADER_TITLE_MAP = {}, _defineProperty(_HEADER_TITLE_MAP, HEADER1, 'header_one'), _defineProperty(_HEADER_TITLE_MAP, HEADER2, 'header_two'), _defineProperty(_HEADER_TITLE_MAP, HEADER3, 'header_three'), _defineProperty(_HEADER_TITLE_MAP, HEADER4, 'header_four'), _defineProperty(_HEADER_TITLE_MAP, HEADER5, 'header_five'), _defineProperty(_HEADER_TITLE_MAP, HEADER6, 'header_six'), _defineProperty(_HEADER_TITLE_MAP, PARAGRAPH, 'paragraph'), _HEADER_TITLE_MAP);
|
|
61
|
+
export var HEADER_TITLE_MAP = (_HEADER_TITLE_MAP = {}, _defineProperty(_HEADER_TITLE_MAP, HEADER1, 'header_one'), _defineProperty(_HEADER_TITLE_MAP, HEADER2, 'header_two'), _defineProperty(_HEADER_TITLE_MAP, HEADER3, 'header_three'), _defineProperty(_HEADER_TITLE_MAP, HEADER4, 'header_four'), _defineProperty(_HEADER_TITLE_MAP, HEADER5, 'header_five'), _defineProperty(_HEADER_TITLE_MAP, HEADER6, 'header_six'), _defineProperty(_HEADER_TITLE_MAP, PARAGRAPH, 'paragraph'), _HEADER_TITLE_MAP);
|
|
62
|
+
export var DIFF_TYPE = {
|
|
63
|
+
ADD: 'add',
|
|
64
|
+
DELETE: 'delete',
|
|
65
|
+
MODIFY: 'modify',
|
|
66
|
+
COMMON: 'common'
|
|
67
|
+
};
|
|
68
|
+
export { BLOCKQUOTE, BOLD, ITALIC, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, LIST_LIC, CHECK_LIST, CHECK_LIST_ITEM, PARAGRAPH, LINK, HTML, CODE_BLOCK, CODE_LINE, IMAGE, TABLE, TABLE_CELL, TABLE_ROW, FORMULA, COLUMN, TEXT_STYLE, BOLD_ITALIC, ELEMENT_TYPE };
|
|
@@ -90,9 +90,7 @@ var ImageMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
90
90
|
var editor = _this.props.editor;
|
|
91
91
|
var file = event.target.files[0];
|
|
92
92
|
context.uploadLocalImage(file).then(function (fileUrl) {
|
|
93
|
-
console.log(fileUrl);
|
|
94
93
|
insertImage(editor, fileUrl, _this.selection);
|
|
95
|
-
console.log(editor.children);
|
|
96
94
|
});
|
|
97
95
|
};
|
|
98
96
|
_this.setInputRef = function (ref) {
|
|
@@ -5,10 +5,12 @@ import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
|
5
5
|
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
6
6
|
import { useSelected } from '@seafile/slate-react';
|
|
7
7
|
import React from 'react';
|
|
8
|
-
import { updateImage } from './helpers';
|
|
9
8
|
import classNames from 'classnames';
|
|
10
9
|
import { withTranslation } from 'react-i18next';
|
|
10
|
+
import urlJoin from 'url-join';
|
|
11
|
+
import { updateImage } from './helpers';
|
|
11
12
|
import ImagePreviewer from './dialogs/image-previewer';
|
|
13
|
+
import context from '../../../../context';
|
|
12
14
|
var Image = /*#__PURE__*/function (_React$Component) {
|
|
13
15
|
_inherits(Image, _React$Component);
|
|
14
16
|
var _super = _createSuper(Image);
|
|
@@ -87,6 +89,13 @@ var Image = /*#__PURE__*/function (_React$Component) {
|
|
|
87
89
|
return _this;
|
|
88
90
|
}
|
|
89
91
|
_createClass(Image, [{
|
|
92
|
+
key: "getImageURL",
|
|
93
|
+
value: function getImageURL(url) {
|
|
94
|
+
var serviceUrl = context.getSetting('serviceUrl');
|
|
95
|
+
var assetsUrl = context.getSetting('assetsUrl');
|
|
96
|
+
return urlJoin(serviceUrl, assetsUrl, url);
|
|
97
|
+
}
|
|
98
|
+
}, {
|
|
90
99
|
key: "render",
|
|
91
100
|
value: function render() {
|
|
92
101
|
var _this$props2 = this.props,
|
|
@@ -107,7 +116,7 @@ var Image = /*#__PURE__*/function (_React$Component) {
|
|
|
107
116
|
}, attributes), /*#__PURE__*/React.createElement("img", {
|
|
108
117
|
className: imageClassName,
|
|
109
118
|
ref: this.setImageRef,
|
|
110
|
-
src: data.src,
|
|
119
|
+
src: this.getImageURL(data.src),
|
|
111
120
|
style: imageStyle,
|
|
112
121
|
draggable: false,
|
|
113
122
|
alt: ""
|
|
@@ -4,7 +4,7 @@ import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
|
4
4
|
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
5
5
|
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
6
6
|
import React from 'react';
|
|
7
|
-
import {
|
|
7
|
+
import { TEXT_STYLE, MENUS_CONFIG_MAP } from '../../../constants';
|
|
8
8
|
import { focusEditor } from '../../../core';
|
|
9
9
|
import { MenuItem } from '../../../menu';
|
|
10
10
|
import { getValue, isMenuDisabled, addMark, removeMark } from '../helpers';
|
|
@@ -68,7 +68,7 @@ var TextStyleMenuList = /*#__PURE__*/function (_React$Component) {
|
|
|
68
68
|
value: function render() {
|
|
69
69
|
var textStyleMenuList = this.getTextStyleMenuList();
|
|
70
70
|
return /*#__PURE__*/React.createElement(React.Fragment, null, textStyleMenuList.map(function (menuItem, index) {
|
|
71
|
-
var menuItemConfig = MENUS_CONFIG_MAP[
|
|
71
|
+
var menuItemConfig = MENUS_CONFIG_MAP[TEXT_STYLE][index];
|
|
72
72
|
var menuItemProps = _objectSpread(_objectSpread({}, menuItem), menuItemConfig);
|
|
73
73
|
return /*#__PURE__*/React.createElement(MenuItem, Object.assign({
|
|
74
74
|
key: index
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
2
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
3
|
+
import { DIFF_TYPE, ELEMENT_TYPE } from '../../basic-sdk/extension/constants';
|
|
4
|
+
import ObjectUtils from './object-utils';
|
|
5
|
+
var getElementIndexInDiffDocument = function getElementIndexInDiffDocument(diffValue, element) {
|
|
6
|
+
return diffValue.findIndex(function (item) {
|
|
7
|
+
return item.id === element.id;
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var getNearestElementIndex = function getNearestElementIndex(diff, oldDocument, elementId) {
|
|
11
|
+
var diffValue = diff.value;
|
|
12
|
+
var elementInDiffDocumentIdx = getElementIndexInDiffDocument(diffValue, elementId);
|
|
13
|
+
if (elementInDiffDocumentIdx > -1) return elementInDiffDocumentIdx + 1;
|
|
14
|
+
var oldElementCount = oldDocument.length;
|
|
15
|
+
var elementInOldDocumentIndex = oldDocument.findIndex(function (item) {
|
|
16
|
+
return item.id === elementId;
|
|
17
|
+
});
|
|
18
|
+
var leftIndex = elementInOldDocumentIndex - 1;
|
|
19
|
+
leftIndex = leftIndex === -1 ? 0 : leftIndex;
|
|
20
|
+
var rightIndex = elementInOldDocumentIndex + 1;
|
|
21
|
+
rightIndex = rightIndex === oldElementCount - 1 ? oldElementCount - 1 : rightIndex;
|
|
22
|
+
while (elementInDiffDocumentIdx === -1 && leftIndex > -2 && rightIndex < oldElementCount + 1) {
|
|
23
|
+
if (leftIndex > -1) {
|
|
24
|
+
var oldLeftElement = oldDocument[leftIndex];
|
|
25
|
+
elementInDiffDocumentIdx = getElementIndexInDiffDocument(diffValue, oldLeftElement);
|
|
26
|
+
if (elementInDiffDocumentIdx > -1) {
|
|
27
|
+
return elementInDiffDocumentIdx + 1;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (rightIndex < oldElementCount) {
|
|
31
|
+
var oldLastElement = oldDocument[rightIndex];
|
|
32
|
+
elementInDiffDocumentIdx = getElementIndexInDiffDocument(diffValue, oldLastElement);
|
|
33
|
+
if (elementInDiffDocumentIdx > -1) {
|
|
34
|
+
return elementInDiffDocumentIdx;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
leftIndex--;
|
|
38
|
+
rightIndex++;
|
|
39
|
+
if (leftIndex === -2 && rightIndex < oldElementCount) {
|
|
40
|
+
leftIndex = -1;
|
|
41
|
+
}
|
|
42
|
+
if (rightIndex === oldElementCount && leftIndex > -1) {
|
|
43
|
+
rightIndex = oldElementCount;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return diffValue.length - 1;
|
|
47
|
+
};
|
|
48
|
+
var updateDiffValue = function updateDiffValue(diff, element, oldElement) {
|
|
49
|
+
if (!diff || !element || !oldElement) return;
|
|
50
|
+
if (ObjectUtils.isSameObject(element, oldElement)) {
|
|
51
|
+
diff.value.push(_objectSpread(_objectSpread({}, element), {}, {
|
|
52
|
+
diff_type: DIFF_TYPE.COMMON
|
|
53
|
+
}));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
var currentElementType = element.type;
|
|
57
|
+
var oldElementType = oldElement.type;
|
|
58
|
+
if (currentElementType !== oldElementType) {
|
|
59
|
+
diff.changes.push(oldElement.id);
|
|
60
|
+
diff.value.push(_objectSpread(_objectSpread({}, oldElement), {}, {
|
|
61
|
+
diff_type: DIFF_TYPE.DELETE
|
|
62
|
+
}));
|
|
63
|
+
diff.value.push(_objectSpread(_objectSpread({}, element), {}, {
|
|
64
|
+
diff_type: DIFF_TYPE.ADD
|
|
65
|
+
}));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
switch (currentElementType) {
|
|
69
|
+
case ELEMENT_TYPE.PARAGRAPH:
|
|
70
|
+
case ELEMENT_TYPE.HEADER1:
|
|
71
|
+
case ELEMENT_TYPE.HEADER2:
|
|
72
|
+
case ELEMENT_TYPE.HEADER3:
|
|
73
|
+
case ELEMENT_TYPE.HEADER4:
|
|
74
|
+
case ELEMENT_TYPE.HEADER5:
|
|
75
|
+
case ELEMENT_TYPE.HEADER6:
|
|
76
|
+
case ELEMENT_TYPE.BLOCKQUOTE:
|
|
77
|
+
case ELEMENT_TYPE.LINK:
|
|
78
|
+
case ELEMENT_TYPE.CHECK_LIST_ITEM:
|
|
79
|
+
case ELEMENT_TYPE.CODE_BLOCK:
|
|
80
|
+
case ELEMENT_TYPE.IMAGE:
|
|
81
|
+
{
|
|
82
|
+
diff.changes.push(oldElement.id);
|
|
83
|
+
diff.value.push(_objectSpread(_objectSpread({}, oldElement), {}, {
|
|
84
|
+
diff_type: DIFF_TYPE.DELETE
|
|
85
|
+
}));
|
|
86
|
+
diff.value.push(_objectSpread(_objectSpread({}, element), {}, {
|
|
87
|
+
diff_type: DIFF_TYPE.ADD
|
|
88
|
+
}));
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case ELEMENT_TYPE.ORDERED_LIST:
|
|
92
|
+
case ELEMENT_TYPE.UNORDERED_LIST:
|
|
93
|
+
case ELEMENT_TYPE.LIST_ITEM:
|
|
94
|
+
case ELEMENT_TYPE.LIST_LIC:
|
|
95
|
+
{
|
|
96
|
+
var _diff$changes;
|
|
97
|
+
var _getElementDiffValue = getElementDiffValue(element.children, oldElement.children),
|
|
98
|
+
diffValue = _getElementDiffValue.value,
|
|
99
|
+
diffChanges = _getElementDiffValue.changes;
|
|
100
|
+
(_diff$changes = diff.changes).push.apply(_diff$changes, _toConsumableArray(diffChanges));
|
|
101
|
+
diff.value.push(_objectSpread(_objectSpread({}, element), {}, {
|
|
102
|
+
children: diffValue,
|
|
103
|
+
diff_type: DIFF_TYPE.MODIFY
|
|
104
|
+
}));
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
default:
|
|
108
|
+
{
|
|
109
|
+
diff.changes.push(oldElement.id);
|
|
110
|
+
diff.value.push(_objectSpread(_objectSpread({}, oldElement), {}, {
|
|
111
|
+
diff_type: DIFF_TYPE.DELETE
|
|
112
|
+
}));
|
|
113
|
+
diff.value.push(_objectSpread(_objectSpread({}, element), {}, {
|
|
114
|
+
diff_type: DIFF_TYPE.ADD
|
|
115
|
+
}));
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* params:
|
|
123
|
+
* currentValue: current version document content
|
|
124
|
+
* oldValue: last version document content
|
|
125
|
+
* return { value: [], change: [] }
|
|
126
|
+
*/
|
|
127
|
+
var getElementDiffValue = function getElementDiffValue(currentContent, oldContent) {
|
|
128
|
+
// init
|
|
129
|
+
var diff = {
|
|
130
|
+
value: [],
|
|
131
|
+
changes: []
|
|
132
|
+
};
|
|
133
|
+
var currentContentMap = {};
|
|
134
|
+
var oldContentMap = {};
|
|
135
|
+
currentContent.forEach(function (element) {
|
|
136
|
+
currentContentMap[element.id] = element;
|
|
137
|
+
});
|
|
138
|
+
oldContent.forEach(function (element) {
|
|
139
|
+
oldContentMap[element.id] = element;
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// generator diff elements
|
|
143
|
+
for (var i = 0; i < currentContent.length; i++) {
|
|
144
|
+
var element = currentContent[i];
|
|
145
|
+
var isAdded = !oldContentMap[element.id]; // added
|
|
146
|
+
if (isAdded) {
|
|
147
|
+
diff.changes.push(element.id);
|
|
148
|
+
diff.value.push(_objectSpread(_objectSpread({}, element), {}, {
|
|
149
|
+
diff_type: DIFF_TYPE.ADD
|
|
150
|
+
}));
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
updateDiffValue(diff, element, oldContentMap[element.id]);
|
|
154
|
+
}
|
|
155
|
+
oldContent.forEach(function (oldElement) {
|
|
156
|
+
var oldElementId = oldElement.id;
|
|
157
|
+
if (!currentContentMap[oldElementId]) {
|
|
158
|
+
// deleted
|
|
159
|
+
diff.changes.push(oldElementId);
|
|
160
|
+
var elementIndex = getNearestElementIndex(diff, oldContent, oldElementId);
|
|
161
|
+
diff.value.splice(elementIndex, 0, _objectSpread(_objectSpread({}, oldElement), {}, {
|
|
162
|
+
diff_type: DIFF_TYPE.DELETE
|
|
163
|
+
}));
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
return diff;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* params:
|
|
171
|
+
* currentValue: current version document
|
|
172
|
+
* oldValue: last version document
|
|
173
|
+
* return { value: [], change: [] }
|
|
174
|
+
*/
|
|
175
|
+
export var getDiff = function getDiff() {
|
|
176
|
+
var currentValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
|
177
|
+
children: []
|
|
178
|
+
};
|
|
179
|
+
var oldValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
180
|
+
children: []
|
|
181
|
+
};
|
|
182
|
+
var currentVersion = currentValue.version,
|
|
183
|
+
currentContent = currentValue.children;
|
|
184
|
+
var oldVersion = oldValue.version,
|
|
185
|
+
oldContent = oldValue.children;
|
|
186
|
+
if (currentVersion === oldVersion) return {
|
|
187
|
+
value: currentContent,
|
|
188
|
+
changes: []
|
|
189
|
+
};
|
|
190
|
+
return getElementDiffValue(currentContent, oldContent);
|
|
191
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
3
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
4
|
+
var ObjectUtils = /*#__PURE__*/function () {
|
|
5
|
+
function ObjectUtils() {
|
|
6
|
+
_classCallCheck(this, ObjectUtils);
|
|
7
|
+
}
|
|
8
|
+
_createClass(ObjectUtils, null, [{
|
|
9
|
+
key: "getDataType",
|
|
10
|
+
value: function getDataType(data) {
|
|
11
|
+
var type = typeof data;
|
|
12
|
+
if (type !== 'object') {
|
|
13
|
+
return type;
|
|
14
|
+
}
|
|
15
|
+
return Object.prototype.toString.call(data).replace(/^\[object (\S+)\]$/, '$1');
|
|
16
|
+
}
|
|
17
|
+
}, {
|
|
18
|
+
key: "iterable",
|
|
19
|
+
value: function iterable(data) {
|
|
20
|
+
return ['Object', 'Array'].includes(this.getDataType(data));
|
|
21
|
+
}
|
|
22
|
+
}, {
|
|
23
|
+
key: "isObjectChanged",
|
|
24
|
+
value: function isObjectChanged(source, comparison, notIncludeKeys) {
|
|
25
|
+
var _this = this;
|
|
26
|
+
if (!this.iterable(source)) {
|
|
27
|
+
throw new Error("source should be a Object or Array , but got ".concat(this.getDataType(source)));
|
|
28
|
+
}
|
|
29
|
+
if (this.getDataType(source) !== this.getDataType(comparison)) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
var sourceKeys = Object.keys(source);
|
|
33
|
+
var comparisonKeys = Object.keys(_objectSpread(_objectSpread({}, source), comparison)).filter(function (key) {
|
|
34
|
+
return !notIncludeKeys.includes(key);
|
|
35
|
+
});
|
|
36
|
+
if (sourceKeys.length !== comparisonKeys.length) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
return comparisonKeys.some(function (key) {
|
|
40
|
+
if (_this.iterable(source[key])) {
|
|
41
|
+
return _this.isObjectChanged(source[key], comparison[key], notIncludeKeys);
|
|
42
|
+
} else {
|
|
43
|
+
return source[key] !== comparison[key];
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}, {
|
|
48
|
+
key: "isSameObject",
|
|
49
|
+
value: function isSameObject(source, comparison) {
|
|
50
|
+
var notIncludeKeys = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
51
|
+
if (!source || !comparison) return false;
|
|
52
|
+
return !this.isObjectChanged(source, comparison, notIncludeKeys);
|
|
53
|
+
}
|
|
54
|
+
}]);
|
|
55
|
+
return ObjectUtils;
|
|
56
|
+
}();
|
|
57
|
+
export default ObjectUtils;
|
package/dist/context.js
CHANGED
|
@@ -1,38 +1,20 @@
|
|
|
1
1
|
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
2
2
|
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
|
-
import cookie from 'react-cookies';
|
|
4
|
-
import { SeafileAPI } from 'seafile-js';
|
|
5
3
|
import Url from 'url-parse';
|
|
6
4
|
import SDocServerApi from './api/sdoc-server-api';
|
|
7
|
-
import
|
|
5
|
+
import SeafileAPI from './api/seafile-api';
|
|
8
6
|
var Context = /*#__PURE__*/function () {
|
|
9
7
|
function Context() {
|
|
10
8
|
var _this = this;
|
|
11
9
|
_classCallCheck(this, Context);
|
|
12
10
|
this.initSettings = function () {
|
|
13
11
|
_this.settings = window.seafile ? window.seafile : window.seafileConfig;
|
|
14
|
-
var isOpenSocket = _this.getSetting('isOpenSocket');
|
|
15
|
-
if (isOpenSocket) {
|
|
16
|
-
_this.sdocServerApi = new SDocServerApi(_this.settings);
|
|
17
|
-
}
|
|
18
12
|
};
|
|
19
13
|
this.uploadLocalImage = function (imageFile) {
|
|
20
|
-
var repoID = _this.getSetting('repoID');
|
|
21
14
|
var docUuid = _this.getSetting('docUuid');
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
var name = getImageFileNameWithTimestamp();
|
|
26
|
-
var newFile = new File([imageFile], name, {
|
|
27
|
-
type: imageFile.type
|
|
28
|
-
});
|
|
29
|
-
var formData = new FormData();
|
|
30
|
-
formData.append('parent_dir', '/');
|
|
31
|
-
formData.append('relative_path', relativePath);
|
|
32
|
-
formData.append('file', newFile);
|
|
33
|
-
return _this.api.uploadImage(uploadLink, formData);
|
|
34
|
-
}).then(function (res) {
|
|
35
|
-
return _this._getImageURL(res.data[0].name);
|
|
15
|
+
return _this.api.uploadSdocImage(docUuid, imageFile).then(function (res) {
|
|
16
|
+
var relative_path = res.data.relative_path;
|
|
17
|
+
return relative_path;
|
|
36
18
|
});
|
|
37
19
|
};
|
|
38
20
|
this.settings = null;
|
|
@@ -44,27 +26,10 @@ var Context = /*#__PURE__*/function () {
|
|
|
44
26
|
key: "initApi",
|
|
45
27
|
value: function initApi() {
|
|
46
28
|
this.initSettings(); // lazy init context class
|
|
47
|
-
var
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
var password = this.getSetting('password');
|
|
52
|
-
seafileAPI.init({
|
|
53
|
-
server: server,
|
|
54
|
-
username: username,
|
|
55
|
-
password: password
|
|
56
|
-
});
|
|
57
|
-
this.api = seafileAPI;
|
|
58
|
-
return seafileAPI.login();
|
|
59
|
-
} else {
|
|
60
|
-
var siteRoot = this.getSetting('siteRoot');
|
|
61
|
-
var xcsrfHeaders = cookie.load('dtable_csrftoken');
|
|
62
|
-
seafileAPI.initForSeahubUsage({
|
|
63
|
-
siteRoot: siteRoot,
|
|
64
|
-
xcsrfHeaders: xcsrfHeaders
|
|
65
|
-
});
|
|
66
|
-
this.api = seafileAPI;
|
|
67
|
-
}
|
|
29
|
+
var server = this.getSetting('serviceUrl');
|
|
30
|
+
var token = this.getSetting('accessToken');
|
|
31
|
+
this.api = new SeafileAPI(server, token);
|
|
32
|
+
this.sdocServerApi = new SDocServerApi(this.settings);
|
|
68
33
|
}
|
|
69
34
|
}, {
|
|
70
35
|
key: "getSettings",
|
|
@@ -109,71 +74,13 @@ var Context = /*#__PURE__*/function () {
|
|
|
109
74
|
}, {
|
|
110
75
|
key: "getFileContent",
|
|
111
76
|
value: function getFileContent() {
|
|
112
|
-
|
|
113
|
-
if (isOpenSocket) {
|
|
114
|
-
return this.getFileContent1();
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// visit by shared link
|
|
118
|
-
var rawPath = this.getSetting('rawPath');
|
|
119
|
-
if (rawPath) {
|
|
120
|
-
return this.api.getFileContent(rawPath);
|
|
121
|
-
}
|
|
122
|
-
return this.getFileContent2();
|
|
77
|
+
return this.sdocServerApi.getDocContent();
|
|
123
78
|
}
|
|
124
79
|
}, {
|
|
125
80
|
key: "saveContent",
|
|
126
81
|
value: function saveContent(content) {
|
|
127
|
-
var isOpenSocket = this.getSetting('isOpenSocket');
|
|
128
|
-
if (isOpenSocket) {
|
|
129
|
-
return this.saveContent1(content);
|
|
130
|
-
}
|
|
131
|
-
return this.saveContent2(content);
|
|
132
|
-
}
|
|
133
|
-
}, {
|
|
134
|
-
key: "getFileContent1",
|
|
135
|
-
value: function getFileContent1() {
|
|
136
|
-
return this.sdocServerApi.getDocContent();
|
|
137
|
-
}
|
|
138
|
-
}, {
|
|
139
|
-
key: "saveContent1",
|
|
140
|
-
value: function saveContent1(content) {
|
|
141
82
|
return this.sdocServerApi.saveDocContent(content);
|
|
142
83
|
}
|
|
143
|
-
}, {
|
|
144
|
-
key: "getFileContent2",
|
|
145
|
-
value: function getFileContent2() {
|
|
146
|
-
var _this2 = this;
|
|
147
|
-
var repoID = this.getSetting('repoID');
|
|
148
|
-
var docPath = this.getSetting('docPath');
|
|
149
|
-
return this.api.getFileDownloadLink(repoID, docPath).then(function (res) {
|
|
150
|
-
var downloadLink = res.data;
|
|
151
|
-
return _this2.api.getFileContent(downloadLink);
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
}, {
|
|
155
|
-
key: "saveContent2",
|
|
156
|
-
value: function saveContent2(content) {
|
|
157
|
-
var _this3 = this;
|
|
158
|
-
var settings = this.getSettings();
|
|
159
|
-
var repoID = settings.repoID,
|
|
160
|
-
docPath = settings.docPath,
|
|
161
|
-
docName = settings.docName;
|
|
162
|
-
var dirPath = getDirPath(docPath);
|
|
163
|
-
return this.api.getUpdateLink(repoID, dirPath).then(function (res) {
|
|
164
|
-
var uploadLink = res.data;
|
|
165
|
-
return _this3.api.updateFile(uploadLink, docPath, docName, content);
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
}, {
|
|
169
|
-
key: "_getImageURL",
|
|
170
|
-
value: function _getImageURL(fileName) {
|
|
171
|
-
var repoID = this.getSetting('repoID');
|
|
172
|
-
var serviceUrl = this.getSetting('serviceUrl');
|
|
173
|
-
var docUuid = this.getSetting('docUuid');
|
|
174
|
-
var url = serviceUrl + '/lib/' + repoID + '/file/images/sdoc/' + docUuid + '/' + fileName + '?raw=1';
|
|
175
|
-
return url;
|
|
176
|
-
}
|
|
177
84
|
}, {
|
|
178
85
|
key: "getCollaborators",
|
|
179
86
|
value: function getCollaborators() {
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
3
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
4
|
+
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
5
|
+
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
6
|
+
import React, { Component } from 'react';
|
|
7
|
+
import { Editable, Slate } from '@seafile/slate-react';
|
|
8
|
+
import editor, { renderLeaf, renderElement } from '../../basic-sdk/extension';
|
|
9
|
+
import withNodeId from '../../basic-sdk/node-id';
|
|
10
|
+
import { getDiff } from '../../basic-sdk/utils/diff';
|
|
11
|
+
import { DIFF_TYPE, ELEMENT_TYPE } from '../../basic-sdk/extension/constants';
|
|
12
|
+
import '../../assets/css/diff-viewer.css';
|
|
13
|
+
var DiffViewer = /*#__PURE__*/function (_Component) {
|
|
14
|
+
_inherits(DiffViewer, _Component);
|
|
15
|
+
var _super = _createSuper(DiffViewer);
|
|
16
|
+
function DiffViewer(_props) {
|
|
17
|
+
var _this;
|
|
18
|
+
_classCallCheck(this, DiffViewer);
|
|
19
|
+
_this = _super.call(this, _props);
|
|
20
|
+
_this.renderLeaf = function (props) {
|
|
21
|
+
return renderLeaf(props, _this.editor);
|
|
22
|
+
};
|
|
23
|
+
_this.renderElement = function (props) {
|
|
24
|
+
var element = props.element;
|
|
25
|
+
var diff_type = element.diff_type,
|
|
26
|
+
type = element.type;
|
|
27
|
+
if (diff_type === DIFF_TYPE.ADD) {
|
|
28
|
+
if (type === ELEMENT_TYPE.LIST_ITEM) {
|
|
29
|
+
return renderElement(_objectSpread(_objectSpread({}, props), {}, {
|
|
30
|
+
attributes: _objectSpread(_objectSpread({}, props.attributes), {}, {
|
|
31
|
+
className: 'sdoc-diff-added'
|
|
32
|
+
})
|
|
33
|
+
}), _this.editor);
|
|
34
|
+
}
|
|
35
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
36
|
+
className: "sdoc-diff sdoc-diff-added"
|
|
37
|
+
}, renderElement(_objectSpread(_objectSpread({}, props), {}, {
|
|
38
|
+
attributes: _objectSpread(_objectSpread({}, props.attributes), {}, {
|
|
39
|
+
className: 'sdoc-diff-added'
|
|
40
|
+
})
|
|
41
|
+
}), _this.editor));
|
|
42
|
+
}
|
|
43
|
+
if (diff_type === DIFF_TYPE.DELETE) {
|
|
44
|
+
if (type === ELEMENT_TYPE.LIST_ITEM) {
|
|
45
|
+
return renderElement(_objectSpread(_objectSpread({}, props), {}, {
|
|
46
|
+
attributes: _objectSpread(_objectSpread({}, props.attributes), {}, {
|
|
47
|
+
className: 'sdoc-diff-removed'
|
|
48
|
+
})
|
|
49
|
+
}), _this.editor);
|
|
50
|
+
}
|
|
51
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
52
|
+
className: "sdoc-diff sdoc-diff-removed"
|
|
53
|
+
}, renderElement(_objectSpread(_objectSpread({}, props), {}, {
|
|
54
|
+
attributes: _objectSpread(_objectSpread({}, props.attributes), {}, {
|
|
55
|
+
className: 'sdoc-diff-removed'
|
|
56
|
+
})
|
|
57
|
+
}), _this.editor));
|
|
58
|
+
}
|
|
59
|
+
if (diff_type === DIFF_TYPE.MODIFY) {
|
|
60
|
+
if (type === ELEMENT_TYPE.ORDERED_LIST || type === ELEMENT_TYPE.UNORDERED_LIST) {
|
|
61
|
+
return renderElement(_objectSpread(_objectSpread({}, props), {}, {
|
|
62
|
+
attributes: _objectSpread(_objectSpread({}, props.attributes), {}, {
|
|
63
|
+
className: 'sdoc-diff-modify'
|
|
64
|
+
})
|
|
65
|
+
}), _this.editor);
|
|
66
|
+
}
|
|
67
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
68
|
+
className: "sdoc-diff-modify"
|
|
69
|
+
}, renderElement(_objectSpread(_objectSpread({}, props), {}, {
|
|
70
|
+
attributes: _objectSpread(_objectSpread({}, props.attributes), {}, {
|
|
71
|
+
className: 'sdoc-diff-modify'
|
|
72
|
+
})
|
|
73
|
+
}), _this.editor));
|
|
74
|
+
}
|
|
75
|
+
return renderElement(props, _this.editor);
|
|
76
|
+
};
|
|
77
|
+
var currentContent = _props.currentContent,
|
|
78
|
+
lastContent = _props.lastContent;
|
|
79
|
+
_this.diff = currentContent ? getDiff(currentContent, lastContent) : {
|
|
80
|
+
value: [],
|
|
81
|
+
changes: []
|
|
82
|
+
};
|
|
83
|
+
_this.editor = withNodeId(editor);
|
|
84
|
+
return _this;
|
|
85
|
+
}
|
|
86
|
+
_createClass(DiffViewer, [{
|
|
87
|
+
key: "componentDidMount",
|
|
88
|
+
value: function componentDidMount() {
|
|
89
|
+
this.props.didMountCallback && this.props.didMountCallback(this.diff);
|
|
90
|
+
}
|
|
91
|
+
}, {
|
|
92
|
+
key: "render",
|
|
93
|
+
value: function render() {
|
|
94
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
95
|
+
className: "sdoc-editor-container"
|
|
96
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
97
|
+
className: "sdoc-editor-content"
|
|
98
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
99
|
+
className: "flex-fill o-auto"
|
|
100
|
+
}, /*#__PURE__*/React.createElement(Slate, {
|
|
101
|
+
editor: this.editor,
|
|
102
|
+
value: this.diff.value,
|
|
103
|
+
onChange: function onChange() {}
|
|
104
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
105
|
+
className: "article mx-auto"
|
|
106
|
+
}, /*#__PURE__*/React.createElement(Editable, {
|
|
107
|
+
readOnly: true,
|
|
108
|
+
placeholder: "",
|
|
109
|
+
renderElement: this.renderElement,
|
|
110
|
+
renderLeaf: this.renderLeaf,
|
|
111
|
+
onDOMBeforeInput: function onDOMBeforeInput() {},
|
|
112
|
+
onKeyDown: function onKeyDown() {}
|
|
113
|
+
}))))));
|
|
114
|
+
}
|
|
115
|
+
}]);
|
|
116
|
+
return DiffViewer;
|
|
117
|
+
}(Component);
|
|
118
|
+
export default DiffViewer;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SDocViewer } from '../../basic-sdk';
|
|
3
|
+
import { generateDefaultDocContent } from '../../utils';
|
|
4
|
+
function HistoryVersionViewer(props) {
|
|
5
|
+
var document = props.document;
|
|
6
|
+
return /*#__PURE__*/React.createElement(SDocViewer, {
|
|
7
|
+
document: document || generateDefaultDocContent()
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export default HistoryVersionViewer;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
|
+
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
4
|
+
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
5
|
+
import React, { Component } from 'react';
|
|
6
|
+
import HistoryVersionViewer from './history-version-viewer';
|
|
7
|
+
import DiffViewer from './diff-viewer';
|
|
8
|
+
var Index = /*#__PURE__*/function (_Component) {
|
|
9
|
+
_inherits(Index, _Component);
|
|
10
|
+
var _super = _createSuper(Index);
|
|
11
|
+
function Index() {
|
|
12
|
+
_classCallCheck(this, Index);
|
|
13
|
+
return _super.apply(this, arguments);
|
|
14
|
+
}
|
|
15
|
+
_createClass(Index, [{
|
|
16
|
+
key: "render",
|
|
17
|
+
value: function render() {
|
|
18
|
+
var _this$props = this.props,
|
|
19
|
+
currentContent = _this$props.currentContent,
|
|
20
|
+
lastContent = _this$props.lastContent;
|
|
21
|
+
if (!lastContent) {
|
|
22
|
+
return /*#__PURE__*/React.createElement(HistoryVersionViewer, {
|
|
23
|
+
document: currentContent
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return /*#__PURE__*/React.createElement(DiffViewer, this.props);
|
|
27
|
+
}
|
|
28
|
+
}]);
|
|
29
|
+
return Index;
|
|
30
|
+
}(Component);
|
|
31
|
+
export default Index;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seafile/sdoc-editor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "This is a sdoc editor",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"reactstrap": "8.9.0",
|
|
19
19
|
"slugid": "3.2.0",
|
|
20
20
|
"socket.io-client": "4.6.1",
|
|
21
|
+
"url-join": "4.0.1",
|
|
21
22
|
"url-parse": "1.5.10",
|
|
22
23
|
"uuid": "9.0.0"
|
|
23
24
|
},
|