@seafile/sdoc-editor 0.1.91 → 0.1.92

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.
Files changed (42) hide show
  1. package/dist/api/sdoc-server-api.js +58 -0
  2. package/dist/api/seafile-api.js +14 -1
  3. package/dist/basic-sdk/comment/comment/comment-editor.js +53 -0
  4. package/dist/basic-sdk/comment/{comment-item.js → comment/comment-item-content.js} +29 -14
  5. package/dist/basic-sdk/comment/comment/comment-item-reply.js +112 -0
  6. package/dist/basic-sdk/comment/comment/comment-item-wrapper.js +208 -0
  7. package/dist/basic-sdk/comment/{comment-list.js → comment/comment-list.js} +58 -71
  8. package/dist/basic-sdk/comment/{comment.js → comment/index.js} +4 -4
  9. package/dist/basic-sdk/comment/{style.css → comment/style.css} +43 -8
  10. package/dist/basic-sdk/comment/dialogs/delete-comment-dialog.js +11 -4
  11. package/dist/basic-sdk/comment/hooks/use-comment-mount.js +5 -1
  12. package/dist/basic-sdk/comment/reducer/comment-reducer.js +82 -0
  13. package/dist/basic-sdk/editor.js +3 -4
  14. package/dist/basic-sdk/extension/commons/color-menu/index.js +6 -5
  15. package/dist/basic-sdk/extension/plugins/table/helpers.js +85 -30
  16. package/dist/basic-sdk/extension/plugins/table/menu/active-table-menu/cell-bg-color-menu.js +35 -0
  17. package/dist/basic-sdk/extension/plugins/table/menu/active-table-menu/cell-text-align-menu.js +43 -0
  18. package/dist/basic-sdk/extension/plugins/table/menu/active-table-menu/index.js +31 -171
  19. package/dist/basic-sdk/extension/plugins/table/menu/active-table-menu/remove-table-menu.js +26 -0
  20. package/dist/basic-sdk/extension/plugins/table/menu/active-table-menu/table-column-menu.js +35 -0
  21. package/dist/basic-sdk/extension/plugins/table/menu/active-table-menu/table-row-menu.js +35 -0
  22. package/dist/basic-sdk/extension/plugins/table/popover/table-size-popover/index.js +1 -0
  23. package/dist/basic-sdk/extension/plugins/text-style/menu/index.js +6 -8
  24. package/dist/basic-sdk/hooks/use-color-context.js +48 -0
  25. package/dist/components/common-loading/index.css +54 -0
  26. package/dist/components/common-loading/index.js +8 -0
  27. package/dist/components/doc-info/index.js +5 -2
  28. package/dist/components/doc-operations/revision-operations/index.js +2 -1
  29. package/dist/components/doc-operations/revision-operations/revisions/index.css +16 -0
  30. package/dist/components/doc-operations/revision-operations/revisions/index.js +49 -0
  31. package/dist/components/doc-operations/revision-operations/revisions/revisions-dialog/index.css +120 -0
  32. package/dist/components/doc-operations/revision-operations/revisions/revisions-dialog/index.js +174 -0
  33. package/dist/components/doc-operations/style.css +13 -0
  34. package/dist/context.js +27 -0
  35. package/dist/model/index.js +2 -0
  36. package/dist/model/revision.js +35 -0
  37. package/package.json +1 -1
  38. package/public/locales/en/sdoc-editor.json +11 -1
  39. package/public/locales/zh-CN/sdoc-editor.json +11 -1
  40. package/dist/basic-sdk/comment/comment-editor.js +0 -73
  41. package/dist/basic-sdk/hooks/use-font-color-context.js +0 -28
  42. package/dist/basic-sdk/hooks/use-highlight-color-context.js +0 -28
@@ -1,17 +1,27 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
3
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
4
  function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, defineProperty = Object.defineProperty || function (obj, key, desc) { obj[key] = desc.value; }, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return defineProperty(generator, "_invoke", { value: makeInvokeMethod(innerFn, self, context) }), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; defineProperty(this, "_invoke", { value: function value(method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; } function maybeInvokeDelegate(delegate, context) { var methodName = context.method, method = delegate.iterator[methodName]; if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel; var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), defineProperty(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (val) { var object = Object(val), keys = []; for (var key in object) keys.push(key); return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, catch: function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; }
4
- import React, { useCallback, useRef } from 'react';
5
- import CommentItem from './comment-item';
5
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
6
+ import dayjs from 'dayjs';
7
+ import context from '../../../context';
8
+ import { useCommentListPosition } from '../../hooks/use-selection-position';
9
+ import { useCommentContext } from '../hooks/use-comment-context';
6
10
  import CommentEditor from './comment-editor';
7
- import { useCommentListPosition } from '../hooks/use-selection-position';
8
- import { useCommentContext } from './hooks/use-comment-context';
9
- import context from '../../context';
11
+ import CommentItemWrapper from './comment-item-wrapper';
10
12
  var CommentList = function CommentList(_ref) {
11
13
  var comments = _ref.comments,
12
14
  selectionElement = _ref.selectionElement;
13
- var listRef = useRef(null);
15
+ var commentRef = useRef(null);
14
16
  var position = useCommentListPosition();
17
+ var _useState = useState(false),
18
+ _useState2 = _slicedToArray(_useState, 2),
19
+ activeComment = _useState2[0],
20
+ setActiveComment = _useState2[1];
21
+ var onCommentClick = useCallback(function (comment) {
22
+ if (activeComment && activeComment.id === comment.id) return;
23
+ setActiveComment(comment);
24
+ }, [activeComment]);
15
25
  var _useCommentContext = useCommentContext(),
16
26
  dispatch = _useCommentContext.dispatch;
17
27
  var insertComment = useCallback( /*#__PURE__*/function () {
@@ -28,7 +38,8 @@ var CommentList = function CommentList(_ref) {
28
38
  newComment = _objectSpread(_objectSpread({}, comment), {}, {
29
39
  id: returnComment.id,
30
40
  user_name: returnComment.user_name,
31
- avatar_url: returnComment.avatar_url
41
+ avatar_url: returnComment.avatar_url,
42
+ replies: []
32
43
  });
33
44
  dispatch({
34
45
  type: 'INSERT_COMMENT',
@@ -37,10 +48,7 @@ var CommentList = function CommentList(_ref) {
37
48
  comment: newComment
38
49
  }
39
50
  });
40
- setTimeout(function () {
41
- listRef.current.scrollTop = 10000;
42
- }, 0);
43
- case 7:
51
+ case 6:
44
52
  case "end":
45
53
  return _context.stop();
46
54
  }
@@ -50,79 +58,58 @@ var CommentList = function CommentList(_ref) {
50
58
  return _ref2.apply(this, arguments);
51
59
  };
52
60
  }(), [dispatch]);
53
- var deleteComment = useCallback( /*#__PURE__*/function () {
54
- var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(commentId) {
55
- var elementId;
56
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
57
- while (1) switch (_context2.prev = _context2.next) {
58
- case 0:
59
- elementId = selectionElement.id;
60
- _context2.next = 3;
61
- return context.deleteComment(commentId);
62
- case 3:
63
- dispatch({
64
- type: 'DELETE_COMMENT',
65
- payload: {
66
- element_id: elementId,
67
- comment_id: commentId
68
- }
69
- });
70
- case 4:
71
- case "end":
72
- return _context2.stop();
73
- }
74
- }, _callee2);
75
- }));
76
- return function (_x3) {
77
- return _ref3.apply(this, arguments);
61
+ var insertContent = useCallback(function (content) {
62
+ var user = context.getUserInfo();
63
+ var elementId = selectionElement.id;
64
+ var time = dayjs().format('YYYY-MM-DD HH:mm:ss');
65
+ var comment = {
66
+ comment: content,
67
+ detail: {
68
+ element_id: elementId,
69
+ comment: content
70
+ },
71
+ author: user.username,
72
+ updated_at: time
78
73
  };
79
- }(), [dispatch, selectionElement]);
80
- var updateComment = useCallback( /*#__PURE__*/function () {
81
- var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(elementId, commentId, newComment) {
82
- return _regeneratorRuntime().wrap(function _callee3$(_context3) {
83
- while (1) switch (_context3.prev = _context3.next) {
84
- case 0:
85
- _context3.next = 2;
86
- return context.updateComment(commentId, newComment);
87
- case 2:
88
- dispatch({
89
- type: 'UPDATE_COMMENT',
90
- payload: {
91
- element_id: elementId,
92
- comment_id: commentId,
93
- comment: newComment
94
- }
95
- });
96
- case 3:
97
- case "end":
98
- return _context3.stop();
99
- }
100
- }, _callee3);
101
- }));
102
- return function (_x4, _x5, _x6) {
103
- return _ref4.apply(this, arguments);
74
+ insertComment(elementId, comment);
75
+ }, [insertComment, selectionElement.id]);
76
+ var resetActiveComment = useCallback(function (e) {
77
+ var menu = commentRef.current;
78
+ var clickIsInMenu = menu && menu.contains(e.target) && menu !== e.target;
79
+ if (clickIsInMenu) return;
80
+ setActiveComment(null);
81
+ }, []);
82
+ useEffect(function () {
83
+ document.addEventListener('click', resetActiveComment);
84
+ return function () {
85
+ document.removeEventListener('click', resetActiveComment);
104
86
  };
105
- }(), [dispatch]);
87
+ }, [resetActiveComment]);
106
88
  return /*#__PURE__*/React.createElement("div", {
89
+ ref: commentRef,
107
90
  className: "comment-list-container",
108
91
  style: {
109
92
  top: position.y
110
93
  }
111
- }, comments.length > 0 && /*#__PURE__*/React.createElement("ul", {
112
- ref: listRef,
94
+ }, comments.length > 0 && /*#__PURE__*/React.createElement("div", {
113
95
  className: "comment-list"
114
96
  }, comments.map(function (comment) {
115
- return /*#__PURE__*/React.createElement(CommentItem, {
97
+ var isActive = activeComment && activeComment.id === comment.id;
98
+ var props = {
116
99
  key: comment.id,
117
100
  comment: comment,
118
- deleteComment: deleteComment,
119
- updateComment: updateComment
120
- });
121
- })), /*#__PURE__*/React.createElement("div", {
101
+ isActive: isActive,
102
+ selectionElement: selectionElement,
103
+ onCommentClick: onCommentClick
104
+ };
105
+ return /*#__PURE__*/React.createElement(CommentItemWrapper, props);
106
+ })), comments.length === 0 && /*#__PURE__*/React.createElement("div", {
107
+ className: "comment-ui-container active"
108
+ }, /*#__PURE__*/React.createElement("div", {
122
109
  className: "comment-editor-wrapper"
123
110
  }, /*#__PURE__*/React.createElement(CommentEditor, {
124
- insertComment: insertComment,
111
+ insertContent: insertContent,
125
112
  selectionElement: selectionElement
126
- })));
113
+ }))));
127
114
  };
128
115
  export default CommentList;
@@ -1,10 +1,10 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
3
- import useSelectionUpdate from '../hooks/use-selection-update';
4
- import { useCursorPosition } from './helper';
3
+ import useSelectionUpdate from '../../hooks/use-selection-update';
4
+ import { useCursorPosition } from '../helper';
5
5
  import CommentList from './comment-list';
6
- import { useSelectionElement } from '../hooks/use-selection-element';
7
- import { useCommentContext } from './hooks/use-comment-context';
6
+ import { useSelectionElement } from '../../hooks/use-selection-element';
7
+ import { useCommentContext } from '../hooks/use-comment-context';
8
8
  import './style.css';
9
9
  var Comment = function Comment() {
10
10
  useSelectionUpdate();
@@ -38,17 +38,33 @@
38
38
 
39
39
  .sdoc-comment-container .comment-list-container {
40
40
  position: absolute;
41
- background: rgba(255,255,255,.92);
41
+ /* background: rgba(255,255,255,.92);
42
+ border-radius: 8px;
43
+ box-shadow: 0 0 2px rgba(0,0,0,.04);
44
+ padding: 16px 0; */
45
+ }
46
+
47
+ .sdoc-comment-container .comment-ui-container {
48
+ background-color: #edf2fa;
42
49
  border-radius: 8px;
43
50
  box-shadow: 0 0 2px rgba(0,0,0,.04);
44
51
  padding: 16px 0;
52
+ margin-bottom: 20px;
53
+ }
54
+
55
+ .sdoc-comment-container .comment-ui-container.active {
56
+ position: relative;
57
+ left: -24px;
58
+ background: rgba(255, 255, 255, .92);
59
+ box-shadow: 0 1px 3px rgba(0,0,0,.3), 0 4px 8px 3px rgba(0,0,0,.15);
45
60
  }
46
61
 
47
- .sdoc-comment-container .comment-list-container .comment-list {
62
+ .sdoc-comment-container .comment-list-container .comment-item-list {
48
63
  max-height: 350px;
49
64
  min-width: 280px;
50
65
  overflow-x: hidden;
51
66
  overflow-y: auto;
67
+ margin: 0;
52
68
  }
53
69
 
54
70
  .sdoc-comment-container .comment-list-container .comment-item {
@@ -75,22 +91,41 @@
75
91
  }
76
92
 
77
93
  .sdoc-comment-container .comment-header .comment-author__avatar {
78
- margin-right: 10px;
79
94
  display: flex;
80
95
  align-items: center;
81
96
  }
82
97
 
83
98
  .sdoc-comment-container .comment-header .comment-author__avatar img {
84
- width: 20px;
85
- height: 20px;
99
+ width: 32px;
100
+ height: 32px;
101
+ border-radius: 50%;
86
102
  }
87
103
 
88
- .sdoc-comment-container .comment-header .comment-time {
89
- color: #777;
90
- font-size: 12px;
104
+ .sdoc-comment-container .comment-header .comment-author__info {
105
+ display: flex;
106
+ flex-direction: column;
107
+ align-items: start;
108
+ justify-content: center;
109
+ padding-left: 10px;
110
+ overflow: hidden;
111
+ white-space: nowrap;
112
+ text-overflow: ellipsis;
91
113
  cursor: pointer;
92
114
  }
93
115
 
116
+ .sdoc-comment-container .comment-header .comment-author__info .name {
117
+ color: #1f1f1f;
118
+ font-size: 14px;
119
+ line-height: 20px;
120
+ font-weight: 500;
121
+ }
122
+
123
+ .sdoc-comment-container .comment-header .comment-author__info .time {
124
+ color: #444746;
125
+ font-size: 12px;
126
+ line-height: 16px;
127
+ }
128
+
94
129
  .sdoc-comment-container .comment-header .comment-operation {
95
130
  line-height: 20px;
96
131
  font-size: 20px;
@@ -2,9 +2,13 @@ import React from 'react';
2
2
  import { withTranslation } from 'react-i18next';
3
3
  import { Button, ModalHeader, Modal, ModalBody, ModalFooter } from 'reactstrap';
4
4
  var DeleteCommentDialog = function DeleteCommentDialog(_ref) {
5
- var setIsShowDeleteModal = _ref.setIsShowDeleteModal,
6
- deleteComment = _ref.deleteComment,
5
+ var type = _ref.type,
6
+ setIsShowDeleteModal = _ref.setIsShowDeleteModal,
7
+ deleteConfirm = _ref.deleteConfirm,
7
8
  t = _ref.t;
9
+ var message = type === 'comment' ? 'comment' : 'reply';
10
+ var title = t("Delete_".concat(message));
11
+ var content = t("Are_you_sure_to_delete_this_".concat(message));
8
12
  return /*#__PURE__*/React.createElement(Modal, {
9
13
  className: "comment-delete-modal",
10
14
  isOpen: true,
@@ -13,14 +17,17 @@ var DeleteCommentDialog = function DeleteCommentDialog(_ref) {
13
17
  toggle: function toggle() {
14
18
  setIsShowDeleteModal(false);
15
19
  }
16
- }, t('Delete_comment')), /*#__PURE__*/React.createElement(ModalBody, null, t('Are_you_sure_to_delete_this_comment')), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(Button, {
20
+ }, title), /*#__PURE__*/React.createElement(ModalBody, null, content), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(Button, {
17
21
  color: "secondary",
18
22
  onClick: function onClick() {
19
23
  setIsShowDeleteModal(false);
20
24
  }
21
25
  }, t('Cancel')), /*#__PURE__*/React.createElement(Button, {
22
26
  color: "primary",
23
- onClick: deleteComment
27
+ onClick: deleteConfirm
24
28
  }, t('Confirm'))));
25
29
  };
30
+ DeleteCommentDialog.defaultProps = {
31
+ type: 'comment'
32
+ };
26
33
  export default withTranslation('sdoc-editor')(DeleteCommentDialog);
@@ -6,7 +6,11 @@ var formatCommentsData = function formatCommentsData(comments) {
6
6
  var commentsMap = {};
7
7
  for (var i = 0; i < comments.length; i++) {
8
8
  var item = comments[i];
9
- item.detail = JSON.parse(item.detail);
9
+ try {
10
+ item.detail = JSON.parse(item.detail);
11
+ } catch (err) {
12
+ item.detail = {};
13
+ }
10
14
  var element_id = item.detail.element_id;
11
15
  if (!commentsMap[element_id]) {
12
16
  commentsMap[element_id] = [];
@@ -76,6 +76,88 @@ export var commentReducer = function commentReducer(state, action) {
76
76
  comments_map: _objectSpread({}, _comments_map2)
77
77
  });
78
78
  }
79
+ case 'UPDATE_COMMENT_STATE':
80
+ {
81
+ var _comments_map3 = state.comments_map;
82
+ var _action$payload4 = action.payload,
83
+ _element_id3 = _action$payload4.element_id,
84
+ _comment_id2 = _action$payload4.comment_id,
85
+ resolved = _action$payload4.resolved;
86
+ _comments_map3[_element_id3] = _comments_map3[_element_id3].map(function (item) {
87
+ if (item.id === _comment_id2) {
88
+ item.resolved = resolved ? 'true' : 'false';
89
+ return item;
90
+ }
91
+ return item;
92
+ });
93
+ return _objectSpread(_objectSpread({}, state), {}, {
94
+ comments_map: _objectSpread({}, _comments_map3)
95
+ });
96
+ }
97
+ case 'INSERT_REPLY':
98
+ {
99
+ var _comments_map4 = state.comments_map;
100
+ var _action$payload5 = action.payload,
101
+ _element_id4 = _action$payload5.element_id,
102
+ _comment_id3 = _action$payload5.comment_id,
103
+ reply = _action$payload5.reply;
104
+ _comments_map4[_element_id4] = _comments_map4[_element_id4].map(function (item) {
105
+ if (item.id === _comment_id3) {
106
+ console.log('xiaoqaing');
107
+ item.replies = [].concat(_toConsumableArray(item.replies), [reply]);
108
+ return item;
109
+ }
110
+ return item;
111
+ });
112
+ return _objectSpread(_objectSpread({}, state), {}, {
113
+ comments_map: _objectSpread({}, _comments_map4)
114
+ });
115
+ }
116
+ case 'DELETE_REPLY':
117
+ {
118
+ var _comments_map5 = state.comments_map;
119
+ var _action$payload6 = action.payload,
120
+ _element_id5 = _action$payload6.element_id,
121
+ _comment_id4 = _action$payload6.comment_id,
122
+ reply_id = _action$payload6.reply_id;
123
+ _comments_map5[_element_id5] = _comments_map5[_element_id5].map(function (item) {
124
+ if (item.id === _comment_id4) {
125
+ item.replies = item.replies.filter(function (reply) {
126
+ return reply.id !== reply_id;
127
+ });
128
+ return item;
129
+ }
130
+ return item;
131
+ });
132
+ return _objectSpread(_objectSpread({}, state), {}, {
133
+ comments_map: _objectSpread({}, _comments_map5)
134
+ });
135
+ }
136
+ case 'UPDATE_REPLY':
137
+ {
138
+ var _comments_map6 = state.comments_map;
139
+ var _action$payload7 = action.payload,
140
+ _element_id6 = _action$payload7.element_id,
141
+ _comment_id5 = _action$payload7.comment_id,
142
+ _reply_id = _action$payload7.reply_id,
143
+ _reply = _action$payload7.reply;
144
+ _comments_map6[_element_id6] = _comments_map6[_element_id6].map(function (item) {
145
+ if (item.id === _comment_id5) {
146
+ item.replies = item.replies.map(function (replyItem) {
147
+ if (replyItem.id === _reply_id) {
148
+ // need update replay updated_at
149
+ return _objectSpread(_objectSpread({}, replyItem), _reply);
150
+ }
151
+ return replyItem;
152
+ });
153
+ return item;
154
+ }
155
+ return item;
156
+ });
157
+ return _objectSpread(_objectSpread({}, state), {}, {
158
+ comments_map: _objectSpread({}, _comments_map6)
159
+ });
160
+ }
79
161
  default:
80
162
  return state;
81
163
  }
@@ -16,8 +16,7 @@ import CommentWrapper from './comment';
16
16
  import { usePipDecorate } from './decorates';
17
17
  import { getCursorPosition, getDomHeight, getDomMarginTop } from './utils/dom-utils';
18
18
  import EventBus from './utils/event-bus';
19
- import { FontColorProvider } from './hooks/use-font-color-context';
20
- import { HighlightColorProvider } from './hooks/use-highlight-color-context';
19
+ import { ColorProvider } from './hooks/use-color-context';
21
20
  import './assets/css/layout.css';
22
21
  import './assets/css/sdoc-editor-plugins.css';
23
22
  import './assets/css/dropdown-menu.css';
@@ -208,7 +207,7 @@ var SDocEditor = function SDocEditor(_ref) {
208
207
  }, []);
209
208
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
210
209
  className: "sdoc-editor-container"
211
- }, /*#__PURE__*/React.createElement(FontColorProvider, null, /*#__PURE__*/React.createElement(HighlightColorProvider, null, /*#__PURE__*/React.createElement(Toolbar, {
210
+ }, /*#__PURE__*/React.createElement(ColorProvider, null, /*#__PURE__*/React.createElement(Toolbar, {
212
211
  editor: editor
213
212
  }), /*#__PURE__*/React.createElement("div", {
214
213
  className: "sdoc-editor-content"
@@ -246,6 +245,6 @@ var SDocEditor = function SDocEditor(_ref) {
246
245
  onMouseDown: onMouseDown,
247
246
  decorate: decorate,
248
247
  onCut: eventProxy.onCut
249
- })), /*#__PURE__*/React.createElement(CommentWrapper, null))))))))))));
248
+ })), /*#__PURE__*/React.createElement(CommentWrapper, null)))))))))));
250
249
  };
251
250
  export default SDocEditor;
@@ -88,7 +88,7 @@ var ColorMenu = function ColorMenu(_ref) {
88
88
  onSetColor(validColor, false);
89
89
 
90
90
  // eslint-disable-next-line react-hooks/exhaustive-deps
91
- }, []);
91
+ }, [disabled]);
92
92
  var validClassName = classnames(className, 'sdoc-color-menu sdoc-menu-with-dropdown', {
93
93
  'menu-show': isShowMenu,
94
94
  'disabled': disabled,
@@ -97,12 +97,12 @@ var ColorMenu = function ColorMenu(_ref) {
97
97
  'rich-icon-btn-hover': isRichEditor && !disabled,
98
98
  'btn btn-icon btn-secondary btn-active d-flex': !isRichEditor
99
99
  });
100
- var setRecentUsedColor = useCallback(function (event) {
100
+ var setLastUsedColor = useCallback(function (event) {
101
101
  eventStopPropagation(event);
102
- onSetColor(recentUsedColors[0], false);
102
+ onSetColor(lastUsedColor, false);
103
103
 
104
104
  // eslint-disable-next-line react-hooks/exhaustive-deps
105
- }, [recentUsedColors]);
105
+ }, [recentUsedColors, lastUsedColor, disabled]);
106
106
  var buttonId = "button-".concat(id);
107
107
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("button", {
108
108
  type: "button",
@@ -113,7 +113,7 @@ var ColorMenu = function ColorMenu(_ref) {
113
113
  className: classnames('last-used-color-container sdoc-menu-with-dropdown-icon', {
114
114
  'disabled': disabled
115
115
  }),
116
- onClick: setRecentUsedColor
116
+ onClick: setLastUsedColor
117
117
  }, /*#__PURE__*/React.createElement("i", {
118
118
  className: classnames(iconClass, 'sdoc-color-icon')
119
119
  }), /*#__PURE__*/React.createElement("div", {
@@ -203,6 +203,7 @@ var ColorMenu = function ColorMenu(_ref) {
203
203
  trigger: "hover",
204
204
  placement: "left-end",
205
205
  hideArrow: true,
206
+ fade: false,
206
207
  toggle: moreColorsPopoverToggle,
207
208
  ref: moreColorsPopoverRef
208
209
  }, /*#__PURE__*/React.createElement("div", {