@seafile/sdoc-editor 2.0.22 → 2.0.24-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.
@@ -205,11 +205,14 @@ class SeafileAPI {
205
205
  form.append('file_uuid', docUuid);
206
206
  return this.req.post(url, form);
207
207
  }
208
- writingAssistant(docUuid, text, type) {
208
+ writingAssistant(docUuid, text, type, custom_prompt) {
209
209
  const url = '/api/v2.1/ai/writing-assistant/';
210
210
  let form = new FormData();
211
211
  form.append('text', text);
212
212
  form.append('writing_type', type);
213
+ if (custom_prompt) {
214
+ form.append('custom_prompt', custom_prompt);
215
+ }
213
216
  form.append('file_uuid', docUuid);
214
217
  return this.req.post(url, form);
215
218
  }
@@ -40,6 +40,7 @@ function AIModule(_ref) {
40
40
  const [opType, setOpType] = (0, _react.useState)('');
41
41
  const [selectedValue, setSelectedValue] = (0, _react.useState)('');
42
42
  const [searchValue, setSearchValue] = (0, _react.useState)('');
43
+ const [oldSearchValue, setOldSearchValue] = (0, _react.useState)('');
43
44
  const [isGenerating, setIsGenerating] = (0, _react.useState)(false);
44
45
  const [searchResult, setSearchResult] = (0, _react.useState)(null);
45
46
  const [currentLang, setCurrentLang] = (0, _react.useState)('en');
@@ -160,13 +161,10 @@ function AIModule(_ref) {
160
161
  }, [onDocumentClick]);
161
162
  const onScroll = (0, _react.useCallback)(event => {
162
163
  if (!element) {
163
- console.log(selectDom);
164
164
  const newRect = selectDom.getBoundingClientRect();
165
165
  const aboveNode = (0, _core.getAboveBlockNode)(editor);
166
166
  const slateDom = _slateReact.ReactEditor.toDOMNode(editor, aboveNode[0]);
167
167
  const slateRect = slateDom.getBoundingClientRect();
168
- console.log(newRect);
169
- console.log(slateRect);
170
168
  const el = aiRef.current;
171
169
  el.style.top = `${newRect.bottom + 8}px`; // top = Current top + Element height
172
170
  el.style.left = `${slateRect.left}px`;
@@ -203,20 +201,25 @@ function AIModule(_ref) {
203
201
  if (!searchValue) return;
204
202
  setOpType(_constants.OPERATION_TYPES.DEFAULT);
205
203
  setIsGenerating(true);
206
- const defaultContent = searchValue || selectedValue;
207
- if (!defaultContent) {
204
+ const defaultContent = selectedValue;
205
+ const custom_prompt = searchValue;
206
+ if (!custom_prompt) {
208
207
  _toast.default.danger(t('Processing_content_cannot_be_empty'));
209
208
  return;
210
209
  }
211
- _context.default.writingAssistant(defaultContent, 'ask').then(res => {
210
+ _context.default.writingAssistant(defaultContent, 'ask', custom_prompt).then(res => {
212
211
  const {
213
212
  content
214
213
  } = res.data;
215
214
  setSearchResult(content);
216
215
  setIsGenerating(false);
216
+ setSearchValue('');
217
+ setOldSearchValue(searchValue);
217
218
  }).catch(err => {
218
219
  setIsGenerating(false);
219
220
  _toast.default.danger('AI_error_message');
221
+ setSearchValue('');
222
+ setOldSearchValue(searchValue);
220
223
  });
221
224
  }, [searchValue, selectedValue, t]);
222
225
  const onKeyDown = (0, _react.useCallback)(event => {
@@ -233,7 +236,7 @@ function AIModule(_ref) {
233
236
  const onContinuationClick = (0, _react.useCallback)(() => {
234
237
  setOpType(_constants.OPERATION_TYPES.CONTINUATION);
235
238
  setIsGenerating(true);
236
- const defaultContent = searchValue || selectedValue;
239
+ const defaultContent = selectedValue;
237
240
  if (!defaultContent) {
238
241
  _toast.default.danger(t('Processing_content_cannot_be_empty'));
239
242
  return;
@@ -248,11 +251,11 @@ function AIModule(_ref) {
248
251
  setIsGenerating(false);
249
252
  _toast.default.danger('AI_error_message');
250
253
  });
251
- }, [searchValue, selectedValue, t]);
254
+ }, [selectedValue, t]);
252
255
  const onMoreDetailsClick = (0, _react.useCallback)(() => {
253
256
  setOpType(_constants.OPERATION_TYPES.MORE_DETAILS);
254
257
  setIsGenerating(true);
255
- const defaultContent = searchValue || selectedValue;
258
+ const defaultContent = selectedValue;
256
259
  if (!defaultContent) {
257
260
  _toast.default.danger(t('Processing_content_cannot_be_empty'));
258
261
  return;
@@ -267,11 +270,11 @@ function AIModule(_ref) {
267
270
  setIsGenerating(false);
268
271
  _toast.default.danger('AI_error_message');
269
272
  });
270
- }, [searchValue, selectedValue, t]);
273
+ }, [selectedValue, t]);
271
274
  const onMoreConciseClick = (0, _react.useCallback)(() => {
272
275
  setOpType(_constants.OPERATION_TYPES.MORE_CONCISE);
273
276
  setIsGenerating(true);
274
- const defaultContent = searchValue || selectedValue;
277
+ const defaultContent = selectedValue;
275
278
  if (!defaultContent) {
276
279
  _toast.default.danger(t('Processing_content_cannot_be_empty'));
277
280
  return;
@@ -286,11 +289,11 @@ function AIModule(_ref) {
286
289
  setIsGenerating(false);
287
290
  _toast.default.danger('AI_error_message');
288
291
  });
289
- }, [searchValue, selectedValue, t]);
292
+ }, [selectedValue, t]);
290
293
  const onMoreVividClick = (0, _react.useCallback)(() => {
291
294
  setOpType(_constants.OPERATION_TYPES.MORE_VIVID);
292
295
  setIsGenerating(true);
293
- const defaultContent = searchValue || selectedValue;
296
+ const defaultContent = selectedValue;
294
297
  if (!defaultContent) {
295
298
  _toast.default.danger(t('Processing_content_cannot_be_empty'));
296
299
  return;
@@ -305,9 +308,9 @@ function AIModule(_ref) {
305
308
  setIsGenerating(false);
306
309
  _toast.default.danger('Translation_error_message');
307
310
  });
308
- }, [searchValue, selectedValue, t]);
311
+ }, [selectedValue, t]);
309
312
  const onTranslateClick = (0, _react.useCallback)(lang => {
310
- const translateValue = searchValue ? searchValue : selectedValue;
313
+ const translateValue = selectedValue;
311
314
  if (!translateValue) {
312
315
  _toast.default.warning(t('The_translation_content_cannot_be_empty'));
313
316
  return;
@@ -326,7 +329,7 @@ function AIModule(_ref) {
326
329
  setIsGenerating(false);
327
330
  _toast.default.danger('Translation_error_message');
328
331
  });
329
- }, [currentLang, searchValue, selectedValue, t]);
332
+ }, [currentLang, selectedValue, t]);
330
333
  const focusToEndPath = (0, _react.useCallback)(path => {
331
334
  setTimeout(() => {
332
335
  const endOfLastNodePoint = _slate.Editor.end(editor, path);
@@ -349,15 +352,24 @@ function AIModule(_ref) {
349
352
  const path = _slateReact.ReactEditor.findPath(editor, element);
350
353
  nextPath = _slate.Path.next(path);
351
354
  }
355
+
356
+ // Prevent '\\n' from being pre-wrapped
357
+ const tempResult = searchResult.replace(/\\n/g, '\v');
358
+ const paragraphs = tempResult.split('\n').map(line => line.replace(/\v/g, '\\n')).filter(line => line.trim() !== '');
352
359
  const p = (0, _core.generateEmptyElement)(_constants2.PARAGRAPH);
353
- p.children[0].text = searchResult;
354
- _slate.Transforms.insertNodes(editor, p, {
355
- at: nextPath
360
+ paragraphs.forEach((line, index) => {
361
+ p.children[0].text = line;
362
+ _slate.Transforms.insertNodes(editor, p, {
363
+ at: nextPath
364
+ });
365
+ if (index < paragraphs.length - 1) {
366
+ nextPath = _slate.Path.next(nextPath);
367
+ }
356
368
  });
357
369
  onCloseClick();
358
370
  focusToEndPath(nextPath);
359
371
  }, [editor, element, focusToEndPath, onCloseClick, searchResult]);
360
- const onTryAgainClick = (0, _react.useCallback)(() => {
372
+ const onTryAgainClick = (0, _react.useCallback)(event => {
361
373
  switch (opType) {
362
374
  case _constants.OPERATION_TYPES.TRANSLATE:
363
375
  onTranslateClick();
@@ -374,10 +386,17 @@ function AIModule(_ref) {
374
386
  case _constants.OPERATION_TYPES.CONTINUATION:
375
387
  onContinuationClick();
376
388
  return;
389
+ case _constants.OPERATION_TYPES.DEFAULT:
390
+ event.stopPropagation();
391
+ event.nativeEvent.stopImmediatePropagation();
392
+ setSearchValue(oldSearchValue);
393
+ setSearchResult('');
394
+ setOldSearchValue('');
395
+ return;
377
396
  default:
378
397
  return;
379
398
  }
380
- }, [onContinuationClick, onMoreConciseClick, onMoreDetailsClick, onMoreVividClick, onTranslateClick, opType]);
399
+ }, [oldSearchValue, onContinuationClick, onMoreConciseClick, onMoreDetailsClick, onMoreVividClick, onTranslateClick, opType]);
381
400
  const onReplaceClick = (0, _react.useCallback)(() => {
382
401
  if (!element) {
383
402
  editor.deleteFragment();
@@ -410,7 +429,8 @@ function AIModule(_ref) {
410
429
  hasCloseButton: false,
411
430
  duration: 2
412
431
  });
413
- }, [searchResult, t]);
432
+ onCloseClick();
433
+ }, [onCloseClick, searchResult, t]);
414
434
  const onDeprecationClick = (0, _react.useCallback)(() => {
415
435
  onCloseClick();
416
436
  }, [onCloseClick]);
@@ -446,7 +466,7 @@ function AIModule(_ref) {
446
466
  }), /*#__PURE__*/_react.default.createElement("span", {
447
467
  className: `sdocfont sdoc-send-arrow ${!searchValue ? 'disable' : ''}`,
448
468
  onClick: onEnter
449
- }))), /*#__PURE__*/_react.default.createElement("div", {
469
+ }))), !searchValue && /*#__PURE__*/_react.default.createElement("div", {
450
470
  className: "sdoc-ai-operations sdoc-dropdown-menu"
451
471
  }, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
452
472
  className: "op-type"
@@ -483,7 +503,9 @@ function AIModule(_ref) {
483
503
  className: "sdoc-ai-result"
484
504
  }, /*#__PURE__*/_react.default.createElement("div", {
485
505
  className: "sdoc-ai-result-content"
486
- }, isGenerating ? t('Processing_message') : searchResult)), /*#__PURE__*/_react.default.createElement("div", {
506
+ }, isGenerating ? t('Processing_message') : searchResult.split('\n').map((paragraph, index) => /*#__PURE__*/_react.default.createElement("p", {
507
+ key: index
508
+ }, paragraph)))), /*#__PURE__*/_react.default.createElement("div", {
487
509
  className: "sdoc-ai-search"
488
510
  }, /*#__PURE__*/_react.default.createElement(_aiIcon.default, null), /*#__PURE__*/_react.default.createElement("input", {
489
511
  placeholder: t('Ask_AI_anything'),
@@ -493,7 +515,7 @@ function AIModule(_ref) {
493
515
  }), /*#__PURE__*/_react.default.createElement("span", {
494
516
  className: `sdocfont sdoc-send-arrow ${!searchValue ? 'disable' : ''}`,
495
517
  onClick: onEnter
496
- }))), /*#__PURE__*/_react.default.createElement("div", {
518
+ }))), !searchValue && /*#__PURE__*/_react.default.createElement("div", {
497
519
  className: "sdoc-ai-operations sdoc-dropdown-menu"
498
520
  }, /*#__PURE__*/_react.default.createElement(_dropdownMenuItem.default, {
499
521
  menuConfig: _constants.OPERATION_MENUS_CONFIG.ADJUSTMENT,
@@ -83,6 +83,18 @@
83
83
  pointer-events: all;
84
84
  }
85
85
 
86
+ .sdoc-ai-module-container .sdoc-ai-result .sdoc-ai-result-content {
87
+ font-size: 11pt;
88
+ height: auto;
89
+ overflow-y: auto;
90
+ }
91
+
92
+ .sdoc-ai-module-container .sdoc-ai-result .sdoc-ai-result-content p {
93
+ line-height: 1.6;
94
+ padding: 5px 0;
95
+ margin-bottom: 0 !important;
96
+ }
97
+
86
98
  .sdoc-ai-module-container .sdoc-ai-result .sdoc-ai-result-header {
87
99
  display: flex;
88
100
  justify-content: space-between;
@@ -125,4 +125,6 @@ const LANG_MENU_CONFIG = exports.LANG_MENU_CONFIG = {
125
125
  iconClass: 'sdocfont sdoc-ai-translate'
126
126
  }
127
127
  };
128
- const AI_MIN_HEIGHT = exports.AI_MIN_HEIGHT = 358;
128
+
129
+ // 358 is default height of ai menu and 300 is max-height of shown result
130
+ const AI_MIN_HEIGHT = exports.AI_MIN_HEIGHT = 358 + 300;
@@ -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.updateImage = exports.selectImageWhenSelectPartial = exports.resetCursor = exports.queryCopyMoveProgressView = exports.isInsertImageMenuDisabled = exports.isImagUrlIsFromCopy = exports.insertImageFiles = exports.insertImage = exports.hasSdocImages = exports.handleBase64Image = exports.getSingleImageFromFragment = exports.getImageURL = exports.getImageData = exports.generateImageNode = void 0;
7
+ exports.updateImage = exports.selectImageWhenSelectPartial = exports.resetCursor = exports.removeImageBlockNode = exports.queryCopyMoveProgressView = exports.isInsertImageMenuDisabled = exports.isImagUrlIsFromCopy = exports.insertImageFiles = exports.insertImage = exports.hasSdocImages = exports.handleBase64Image = exports.getSingleImageFromFragment = exports.getImageURL = exports.getImageData = exports.generateImageNode = void 0;
8
8
  var _urlJoin = _interopRequireDefault(require("url-join"));
9
9
  var _slate = require("@seafile/slate");
10
10
  var _slateReact = require("@seafile/slate-react");
@@ -283,4 +283,15 @@ const isImagUrlIsFromCopy = url => {
283
283
  if (url && url.startsWith('attachment')) return true; // from yuque
284
284
  return false;
285
285
  };
286
- exports.isImagUrlIsFromCopy = isImagUrlIsFromCopy;
286
+ exports.isImagUrlIsFromCopy = isImagUrlIsFromCopy;
287
+ const removeImageBlockNode = (editor, path) => {
288
+ _slate.Transforms.removeNodes(editor, {
289
+ at: path
290
+ });
291
+ const p = (0, _core.generateEmptyElement)(_constants2.ELEMENT_TYPE.PARAGRAPH);
292
+ _slate.Transforms.insertNodes(editor, p, {
293
+ at: path
294
+ });
295
+ (0, _core.focusEditor)(editor, path);
296
+ };
297
+ exports.removeImageBlockNode = removeImageBlockNode;
@@ -165,7 +165,7 @@ const ImageHoverMenu = _ref => {
165
165
  style: menuPosition
166
166
  }, /*#__PURE__*/_react.default.createElement("div", {
167
167
  className: "hover-menu-container"
168
- }, ![_constants2.TABLE, _constants2.BLOCKQUOTE, _constants2.CALL_OUT].includes(type) && !readonly && /*#__PURE__*/_react.default.createElement("span", {
168
+ }, ![_constants2.TABLE, _constants2.BLOCKQUOTE, _constants2.CALL_OUT, _constants2.MULTI_COLUMN].includes(type) && !readonly && /*#__PURE__*/_react.default.createElement("span", {
169
169
  className: "op-group-item"
170
170
  }, /*#__PURE__*/_react.default.createElement("span", {
171
171
  role: "button",
@@ -173,6 +173,20 @@ const withImage = editor => {
173
173
  if (imageBlock) {
174
174
  const path = selection.anchor.path;
175
175
  const deletePath = [path[0]];
176
+
177
+ // Delete image_block element in multi-column node
178
+ const currentTopNode = (0, _core.getNode)(editor, deletePath);
179
+ const currentBlockNode = (0, _core.getNode)(editor, path.slice(0, 3));
180
+ // Image_block not in callout or blockquote
181
+ if (currentTopNode.type === _constants.MULTI_COLUMN && ![_constants.CALL_OUT, _constants.BLOCKQUOTE].includes(currentBlockNode.type)) {
182
+ (0, _helpers.removeImageBlockNode)(editor, path.slice(0, 3));
183
+ return;
184
+ }
185
+ // Image_block in callout or blockquote
186
+ if (currentTopNode.type === _constants.MULTI_COLUMN && [_constants.CALL_OUT, _constants.BLOCKQUOTE].includes(currentBlockNode.type)) {
187
+ (0, _helpers.removeImageBlockNode)(editor, path.slice(0, 4));
188
+ return;
189
+ }
176
190
  _slate.Transforms.removeNodes(editor, {
177
191
  at: deletePath
178
192
  });
@@ -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.updateColumnWidthOnDeletion = exports.updateColumnWidth = exports.insertMultiColumn = exports.handleInsertMultiColumn = exports.getCurrentPageWidth = exports.generateEmptyMultiColumn = void 0;
7
+ exports.updateColumnWidthOnDeletion = exports.updateColumnWidth = exports.insertMultiColumn = exports.hasImageInColumn = exports.handleInsertMultiColumn = exports.getCurrentPageWidth = exports.generateEmptyMultiColumn = void 0;
8
8
  var _slugid = _interopRequireDefault(require("slugid"));
9
9
  var _slate = require("@seafile/slate");
10
10
  var _slateReact = require("@seafile/slate-react");
@@ -178,4 +178,15 @@ const getCurrentPageWidth = editor => {
178
178
  }
179
179
  return pageWidth;
180
180
  };
181
- exports.getCurrentPageWidth = getCurrentPageWidth;
181
+ exports.getCurrentPageWidth = getCurrentPageWidth;
182
+ const hasImageInColumn = (editor, columnPath) => {
183
+ for (const [node] of _slate.Editor.nodes(editor, {
184
+ at: columnPath
185
+ })) {
186
+ if ([_constants.IMAGE_BLOCK, _constants.IMAGE].includes(node === null || node === void 0 ? void 0 : node.type)) {
187
+ return true;
188
+ }
189
+ }
190
+ return false;
191
+ };
192
+ exports.hasImageInColumn = hasImageInColumn;
@@ -8,6 +8,7 @@ var _slate = require("@seafile/slate");
8
8
  var _core = require("../../core");
9
9
  var _constants = require("../../constants");
10
10
  var _helper = require("./helper");
11
+ var _unwrapList = require("../list/transforms/unwrap-list");
11
12
  const withMultiColumn = editor => {
12
13
  const {
13
14
  normalizeNode,
@@ -54,9 +55,41 @@ const withMultiColumn = editor => {
54
55
  const currentColumnEntry = (0, _core.getSelectedNodeEntryByType)(editor, _constants.ELEMENT_TYPE.COLUMN);
55
56
  const isOnlyOneChild = currentColumnEntry[0].children.length === 1;
56
57
  const isAtStart = _slate.Editor.isStart(editor, selection.focus, selection.anchor.path.slice(0, 2));
58
+ const currentNodeInColumn = currentColumnEntry[0].children[0];
59
+ const currentNodePathInColumn = (0, _core.findPath)(editor, currentNodeInColumn);
60
+ // Only one child inline-image in current column
61
+ // Return if cursor is at the start of only one child image
62
+ if (isOnlyOneChild && currentNodeInColumn.children.length === 3) {
63
+ const isImageType = currentNodeInColumn.children[1].type === _constants.IMAGE;
64
+ if (isImageType && selection.anchor.path[3] === 0 && selection.anchor.offset === 0) {
65
+ return;
66
+ }
67
+ }
57
68
 
58
69
  // When selection is at start of the only one existed child nodes in current column node, delete column node
59
70
  if (isOnlyOneChild && isAtStart) {
71
+ // Transform non-paragraph elements without callout element to paragraph elements
72
+ if (currentNodeInColumn.type !== _constants.PARAGRAPH) {
73
+ var _currentNodeInColumn$;
74
+ // Unwrap list if list-item exists in the current column node
75
+ if ([_constants.UNORDERED_LIST, _constants.ORDERED_LIST].includes(currentNodeInColumn.type)) {
76
+ (0, _unwrapList.unwrapList)(editor);
77
+ return;
78
+ }
79
+ if ([_constants.UNORDERED_LIST, _constants.ORDERED_LIST].includes(currentNodeInColumn === null || currentNodeInColumn === void 0 ? void 0 : (_currentNodeInColumn$ = currentNodeInColumn.children[0]) === null || _currentNodeInColumn$ === void 0 ? void 0 : _currentNodeInColumn$.type)) {
80
+ _slate.Transforms.unwrapNodes(editor, {
81
+ at: currentNodePathInColumn
82
+ });
83
+ } else {
84
+ _slate.Transforms.setNodes(editor, {
85
+ type: _constants.PARAGRAPH
86
+ }, {
87
+ at: currentNodePathInColumn
88
+ });
89
+ }
90
+ return;
91
+ }
92
+
60
93
  // Delete multi_column and column wrap when only one child column node exists
61
94
  if (childColumn.length <= 2) {
62
95
  deleteBackward();
@@ -89,6 +122,13 @@ const withMultiColumn = editor => {
89
122
  } = currentMultiColumnEntry[0];
90
123
  const isOnlyOneChild = childColumn[nextColumnIndex].children.length === 1;
91
124
  const isAtEnd = _slate.Editor.isEnd(editor, selection.focus, selection.anchor.path.slice(0, 2));
125
+
126
+ // When deleteForwarding only one child including image or image-block in next column, return
127
+ const hasImageInOnlyOneChild = isOnlyOneChild && (0, _helper.hasImageInColumn)(editor, nextNode[1].slice(0, 2));
128
+ if (isOnlyOneChild && isAtEnd && hasImageInOnlyOneChild) {
129
+ return;
130
+ }
131
+
92
132
  // When selection is at end and the only one existed child nodes in next column node, delete column node
93
133
  if (isOnlyOneChild && isAtEnd) {
94
134
  // Delete multi_column and column wrap when only one child column node exists and selection is on the first column node
@@ -150,6 +150,12 @@ const QuickInsertBlockMenu = _ref => {
150
150
  });
151
151
  return !!callout;
152
152
  }, [editor]);
153
+ const isDisableCodeBlock = (0, _react.useMemo)(() => {
154
+ const callout = (0, _core.getAboveBlockNode)(editor, {
155
+ match: n => [_constants.ELEMENT_TYPE.MULTI_COLUMN].includes(n.type)
156
+ });
157
+ return !!callout;
158
+ }, [editor]);
153
159
  const createMultiColumn = (0, _react.useCallback)(type => {
154
160
  callback && callback();
155
161
  const newInsertPosition = slateNode.type === _constants.ELEMENT_TYPE.LIST_ITEM ? _constants.INSERT_POSITION.AFTER : insertPosition;
@@ -209,6 +215,7 @@ const QuickInsertBlockMenu = _ref => {
209
215
  }),
210
216
  [_constants.CODE_BLOCK]: /*#__PURE__*/_react.default.createElement(_dropdownMenuItem.default, {
211
217
  isHidden: !quickInsertMenuSearchMap[_constants.CODE_BLOCK],
218
+ disabled: isDisableCodeBlock,
212
219
  key: "sdoc-insert-menu-code-block",
213
220
  menuConfig: {
214
221
  ..._constants.SIDE_INSERT_MENUS_CONFIG[_constants.ELEMENT_TYPE.CODE_BLOCK]
@@ -119,6 +119,11 @@ const SideToolbar = () => {
119
119
  if ([_constants2.ORDERED_LIST, _constants2.UNORDERED_LIST, _constants2.BLOCKQUOTE].includes(parentNode.type)) {
120
120
  domLeft = document.querySelector(`[data-id="${parentNode.id}"]`) && document.querySelector(`[data-id="${parentNode.id}"]`).getBoundingClientRect().left;
121
121
  }
122
+ if ([_constants2.IMAGE_BLOCK].includes(node.type)) {
123
+ var _dom$querySelectorAll;
124
+ const imageWrapperDomId = (_dom$querySelectorAll = dom.querySelectorAll('span')[1]) === null || _dom$querySelectorAll === void 0 ? void 0 : _dom$querySelectorAll.getAttribute('data-id');
125
+ domLeft = document.querySelector(`[data-id="${imageWrapperDomId}"]`) && document.querySelector(`[data-id="${imageWrapperDomId}"]`).getBoundingClientRect().left;
126
+ }
122
127
  const {
123
128
  left: containerLeft
124
129
  } = document.querySelector('.sdoc-editor__article').getBoundingClientRect();
package/dist/context.js CHANGED
@@ -263,9 +263,9 @@ class Context {
263
263
  const docUuid = this.getDocUuid();
264
264
  return this.api.aiTranslate(docUuid, text, lang);
265
265
  }
266
- writingAssistant(text, type) {
266
+ writingAssistant(text, type, custom_prompt) {
267
267
  const docUuid = this.getDocUuid();
268
- return this.api.writingAssistant(docUuid, text, type);
268
+ return this.api.writingAssistant(docUuid, text, type, custom_prompt);
269
269
  }
270
270
  updateConfigUuid(docUuid) {
271
271
  if (!this.config) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "2.0.22",
3
+ "version": "2.0.24-alph-0.0.1",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -613,5 +613,11 @@
613
613
  "Support_Youtube_Tencent_Bilibili_and_more": "Support Youtube, Tencent, Bilibili and more",
614
614
  "Image_cannot_be_copied_Please_download_the_source_image": "Image cannot be copied. Please download the source image,",
615
615
  "And_select_insert_-_image_to_upload": "and select 「insert」 - 「image」 to upload.",
616
- "Image_copy_error": "Image copy error"
616
+ "Image_copy_error": "Image copy error",
617
+ "Image_is_uploading": "Image is uploading...",
618
+ "Select_at_least_one_row_record": "Select at least one row record",
619
+ "Selected_row_records_cannot_exceed_10_rows": "Selected row records cannot exceed 10 rows",
620
+ "Select_seatable_rows": "Select seatable rows",
621
+ "Add_rows_record": "Add rows record",
622
+ "Double_click_then_adjust_field_width": "Double click, then adjust field width"
617
623
  }