@underverse-ui/underverse 1.0.154 → 1.0.156

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@underverse-ui/underverse",
3
- "version": "1.0.154",
3
+ "version": "1.0.156",
4
4
  "sourceEntry": "src/index.ts",
5
5
  "totalExports": 232,
6
6
  "exports": [
package/dist/index.cjs CHANGED
@@ -1055,12 +1055,15 @@ var en_default = {
1055
1055
  clickToOpenNewTab: "Click to open this link in a new tab.",
1056
1056
  clickToOpenLink: "Click to open link.",
1057
1057
  noDescription: "No description available.",
1058
- failedToLoad: "Failed to load link preview. Click to open link."
1058
+ failedToLoad: "Failed to load link preview. Click to open link.",
1059
+ previewFailed: "Preview failed to load",
1060
+ retryPreview: "Retry preview"
1059
1061
  },
1060
1062
  fileCard: {
1061
1063
  unnamed: "Unnamed file",
1062
1064
  uploading: "(Uploading...)",
1063
- uploadFailed: "Upload failed"
1065
+ uploadFailed: "Upload failed",
1066
+ retryUpload: "Retry upload"
1064
1067
  },
1065
1068
  menubar: {
1066
1069
  file: "File",
@@ -1447,12 +1450,15 @@ var vi_default = {
1447
1450
  clickToOpenNewTab: "B\u1EA5m \u0111\u1EC3 m\u1EDF li\xEAn k\u1EBFt n\xE0y trong tab m\u1EDBi.",
1448
1451
  clickToOpenLink: "B\u1EA5m \u0111\u1EC3 m\u1EDF li\xEAn k\u1EBFt.",
1449
1452
  noDescription: "Kh\xF4ng c\xF3 m\xF4 t\u1EA3.",
1450
- failedToLoad: "T\u1EA3i b\u1EA3n xem tr\u01B0\u1EDBc th\u1EA5t b\u1EA1i. B\u1EA5m \u0111\u1EC3 m\u1EDF li\xEAn k\u1EBFt."
1453
+ failedToLoad: "T\u1EA3i b\u1EA3n xem tr\u01B0\u1EDBc th\u1EA5t b\u1EA1i. B\u1EA5m \u0111\u1EC3 m\u1EDF li\xEAn k\u1EBFt.",
1454
+ previewFailed: "Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c b\u1EA3n xem tr\u01B0\u1EDBc",
1455
+ retryPreview: "Th\u1EED l\u1EA1i"
1451
1456
  },
1452
1457
  fileCard: {
1453
1458
  unnamed: "T\u1EC7p kh\xF4ng t\xEAn",
1454
1459
  uploading: "(\u0110ang t\u1EA3i l\xEAn...)",
1455
- uploadFailed: "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i"
1460
+ uploadFailed: "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i",
1461
+ retryUpload: "T\u1EA3i l\u1EA1i"
1456
1462
  },
1457
1463
  menubar: {
1458
1464
  file: "T\u1EADp tin",
@@ -1839,12 +1845,15 @@ var ko_default = {
1839
1845
  clickToOpenNewTab: "\uD074\uB9AD\uD558\uC5EC \uC774 \uB9C1\uD06C\uB97C \uC0C8 \uD0ED\uC5D0\uC11C \uC5FD\uB2C8\uB2E4.",
1840
1846
  clickToOpenLink: "\uD074\uB9AD\uD558\uC5EC \uB9C1\uD06C\uB97C \uC5FD\uB2C8\uB2E4.",
1841
1847
  noDescription: "\uC124\uBA85\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
1842
- failedToLoad: "\uB9C1\uD06C \uBBF8\uB9AC\uBCF4\uAE30\uB97C \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uD074\uB9AD\uD558\uC5EC \uB9C1\uD06C\uB97C \uC5FD\uB2C8\uB2E4."
1848
+ failedToLoad: "\uB9C1\uD06C \uBBF8\uB9AC\uBCF4\uAE30\uB97C \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uD074\uB9AD\uD558\uC5EC \uB9C1\uD06C\uB97C \uC5FD\uB2C8\uB2E4.",
1849
+ previewFailed: "\uBBF8\uB9AC\uBCF4\uAE30\uB97C \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4",
1850
+ retryPreview: "\uB2E4\uC2DC \uC2DC\uB3C4"
1843
1851
  },
1844
1852
  fileCard: {
1845
1853
  unnamed: "\uC774\uB984 \uC5C6\uB294 \uD30C\uC77C",
1846
1854
  uploading: "(\uC5C5\uB85C\uB4DC \uC911...)",
1847
- uploadFailed: "\uC5C5\uB85C\uB4DC\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4."
1855
+ uploadFailed: "\uC5C5\uB85C\uB4DC\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.",
1856
+ retryUpload: "\uB2E4\uC2DC \uC5C5\uB85C\uB4DC"
1848
1857
  },
1849
1858
  menubar: {
1850
1859
  file: "\uD30C\uC77C",
@@ -2231,12 +2240,15 @@ var ja_default = {
2231
2240
  clickToOpenNewTab: "\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u3053\u306E\u30EA\u30F3\u30AF\u3092\u65B0\u3057\u3044\u30BF\u30D6\u3067\u958B\u304F\u3002",
2232
2241
  clickToOpenLink: "\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u30EA\u30F3\u30AF\u3092\u958B\u304F\u3002",
2233
2242
  noDescription: "\u8AAC\u660E\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
2234
- failedToLoad: "\u30D7\u30EC\u30D3\u30E5\u30FC\u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u30EA\u30F3\u30AF\u3092\u958B\u304F\u3002"
2243
+ failedToLoad: "\u30D7\u30EC\u30D3\u30E5\u30FC\u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u30EA\u30F3\u30AF\u3092\u958B\u304F\u3002",
2244
+ previewFailed: "\u30D7\u30EC\u30D3\u30E5\u30FC\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093\u3067\u3057\u305F",
2245
+ retryPreview: "\u518D\u8A66\u884C"
2235
2246
  },
2236
2247
  fileCard: {
2237
2248
  unnamed: "\u540D\u524D\u306A\u3057\u30D5\u30A1\u30A4\u30EB",
2238
2249
  uploading: "(\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u4E2D...)",
2239
- uploadFailed: "\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u5931\u6557"
2250
+ uploadFailed: "\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u5931\u6557",
2251
+ retryUpload: "\u518D\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9"
2240
2252
  },
2241
2253
  menubar: {
2242
2254
  file: "\u30D5\u30A1\u30A4\u30EB",
@@ -25025,7 +25037,7 @@ var import_core2 = require("@tiptap/core");
25025
25037
  var import_react45 = require("@tiptap/react");
25026
25038
 
25027
25039
  // src/components/UEditor/BookmarkView.tsx
25028
- var import_react43 = require("react");
25040
+ var import_react43 = __toESM(require("react"), 1);
25029
25041
  var import_react44 = require("@tiptap/react");
25030
25042
  var import_lucide_react41 = require("lucide-react");
25031
25043
  var import_jsx_runtime77 = require("react/jsx-runtime");
@@ -25034,12 +25046,18 @@ var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
25034
25046
  const { url, title, description, image, publisher } = node.attrs;
25035
25047
  const [loading2, setLoading] = (0, import_react43.useState)(false);
25036
25048
  const [error, setError] = (0, import_react43.useState)(false);
25049
+ const [retryToken, setRetryToken] = (0, import_react43.useState)(0);
25050
+ const fetchedRetryTokenRef = import_react43.default.useRef(-1);
25051
+ const fetchRequestIdRef = import_react43.default.useRef(0);
25037
25052
  (0, import_react43.useEffect)(() => {
25038
- if (title) return;
25039
- let active = true;
25053
+ if (title && retryToken === 0) return;
25054
+ if (fetchedRetryTokenRef.current === retryToken) return;
25055
+ fetchedRetryTokenRef.current = retryToken;
25056
+ const requestId = fetchRequestIdRef.current + 1;
25057
+ fetchRequestIdRef.current = requestId;
25040
25058
  const safeUpdateAttributes = (attrs) => {
25041
25059
  Promise.resolve().then(() => {
25042
- if (active && editor && !editor.isDestroyed) {
25060
+ if (fetchRequestIdRef.current === requestId && editor && !editor.isDestroyed) {
25043
25061
  updateAttributes(attrs);
25044
25062
  }
25045
25063
  });
@@ -25066,7 +25084,7 @@ var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
25066
25084
  setLoading(true);
25067
25085
  setError(false);
25068
25086
  fetchMetadata(url).then((meta) => {
25069
- if (!active) return;
25087
+ if (fetchRequestIdRef.current !== requestId) return;
25070
25088
  safeUpdateAttributes({
25071
25089
  title: meta.title || new URL(url).hostname || url,
25072
25090
  description: meta.description || t("bookmark.noDescription"),
@@ -25075,33 +25093,22 @@ var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
25075
25093
  });
25076
25094
  setLoading(false);
25077
25095
  }).catch(() => {
25078
- if (!active) return;
25096
+ if (fetchRequestIdRef.current !== requestId) return;
25079
25097
  setError(true);
25080
25098
  setLoading(false);
25081
- try {
25082
- const hostname = new URL(url).hostname;
25083
- safeUpdateAttributes({
25084
- title: hostname || url,
25085
- description: t("bookmark.failedToLoad"),
25086
- publisher: hostname
25087
- });
25088
- } catch {
25089
- safeUpdateAttributes({
25090
- title: url,
25091
- description: t("bookmark.clickToOpenLink"),
25092
- publisher: ""
25093
- });
25094
- }
25095
25099
  });
25096
- return () => {
25097
- active = false;
25098
- };
25099
- }, [url, title, editor, updateAttributes, t]);
25100
+ return void 0;
25101
+ }, [url, title, editor, updateAttributes, t, retryToken]);
25100
25102
  const handleOpenLink = (e) => {
25101
25103
  e.preventDefault();
25102
25104
  e.stopPropagation();
25103
25105
  window.open(url, "_blank", "noopener,noreferrer");
25104
25106
  };
25107
+ const handleRetryPreview = (event) => {
25108
+ event.preventDefault();
25109
+ event.stopPropagation();
25110
+ setRetryToken((value) => value + 1);
25111
+ };
25105
25112
  const displayPublisher = publisher || (() => {
25106
25113
  try {
25107
25114
  return new URL(url).hostname;
@@ -25137,6 +25144,24 @@ var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
25137
25144
  /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("span", { className: "text-[11px] text-primary/80 font-mono mt-2 truncate flex items-center gap-1", children: [
25138
25145
  url,
25139
25146
  /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(import_lucide_react41.ExternalLink, { className: "h-3 w-3 flex-shrink-0" })
25147
+ ] }),
25148
+ error && /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "mt-2 flex flex-wrap items-center gap-2 text-xs text-destructive", children: [
25149
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
25150
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(import_lucide_react41.AlertCircle, { className: "h-3.5 w-3.5" }),
25151
+ t("bookmark.previewFailed")
25152
+ ] }),
25153
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
25154
+ "button",
25155
+ {
25156
+ type: "button",
25157
+ onClick: handleRetryPreview,
25158
+ className: "inline-flex items-center gap-1 rounded-md border border-destructive/30 px-2 py-0.5 font-medium hover:bg-destructive/10",
25159
+ children: [
25160
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(import_lucide_react41.RefreshCw, { className: "h-3 w-3" }),
25161
+ t("bookmark.retryPreview")
25162
+ ]
25163
+ }
25164
+ )
25140
25165
  ] })
25141
25166
  ] }),
25142
25167
  image && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "relative w-full sm:w-44 h-32 sm:h-auto flex-shrink-0 bg-muted overflow-hidden border-t sm:border-t-0 sm:border-l border-border/50", children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
@@ -25321,6 +25346,7 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
25321
25346
  const { src, fileName, fileSize, fileType } = node.attrs;
25322
25347
  const FileIcon = getFileIcon2(fileType);
25323
25348
  const [uploadError, setUploadError] = (0, import_react46.useState)(null);
25349
+ const [retryToken, setRetryToken] = (0, import_react46.useState)(0);
25324
25350
  const uploadAttemptedRef = (0, import_react46.useRef)(false);
25325
25351
  (0, import_react46.useEffect)(() => {
25326
25352
  if (!src || !src.startsWith("data:")) {
@@ -25352,7 +25378,7 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
25352
25378
  }
25353
25379
  };
25354
25380
  void runUpload();
25355
- }, [src, fileName, fileType, editor, updateAttributes]);
25381
+ }, [src, fileName, fileType, editor, updateAttributes, retryToken]);
25356
25382
  const handleDownload = (e) => {
25357
25383
  e.preventDefault();
25358
25384
  e.stopPropagation();
@@ -25365,6 +25391,13 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
25365
25391
  document.body.removeChild(link);
25366
25392
  };
25367
25393
  const isUploading = (src || "").startsWith("data:");
25394
+ const handleRetryUpload = (event) => {
25395
+ event.preventDefault();
25396
+ event.stopPropagation();
25397
+ uploadAttemptedRef.current = false;
25398
+ setUploadError(null);
25399
+ setRetryToken((value) => value + 1);
25400
+ };
25368
25401
  return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
25369
25402
  import_react47.NodeViewWrapper,
25370
25403
  {
@@ -25383,7 +25416,19 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
25383
25416
  isUploading && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: cn(
25384
25417
  "font-medium truncate max-w-[200px]",
25385
25418
  uploadError ? "text-destructive" : "text-primary animate-pulse"
25386
- ), children: uploadError ? `${t("fileCard.uploadFailed") || "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i"}: ${uploadError}` : t("fileCard.uploading") })
25419
+ ), children: uploadError ? `${t("fileCard.uploadFailed") || "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i"}: ${uploadError}` : t("fileCard.uploading") }),
25420
+ isUploading && uploadError && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
25421
+ "button",
25422
+ {
25423
+ type: "button",
25424
+ onClick: handleRetryUpload,
25425
+ className: "inline-flex items-center gap-1 rounded-md border border-destructive/30 px-1.5 py-0.5 text-[11px] font-medium text-destructive hover:bg-destructive/10",
25426
+ children: [
25427
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react42.RefreshCw, { className: "h-3 w-3" }),
25428
+ t("fileCard.retryUpload")
25429
+ ]
25430
+ }
25431
+ )
25387
25432
  ] })
25388
25433
  ] })
25389
25434
  ] }),
@@ -30642,6 +30687,20 @@ function safeFindCell2(map, relativePos) {
30642
30687
  function getCellText(cellNode) {
30643
30688
  return cellNode.textBetween(0, cellNode.content.size, "\n").trim();
30644
30689
  }
30690
+ function getSelectionTableCellNode(editor) {
30691
+ const { $from } = editor.state.selection;
30692
+ for (let depth = $from.depth; depth > 0; depth -= 1) {
30693
+ const node = $from.node(depth);
30694
+ if (node.type.name === "tableCell" || node.type.name === "tableHeader") {
30695
+ return node;
30696
+ }
30697
+ }
30698
+ return null;
30699
+ }
30700
+ function isEditingTableFormulaText(editor) {
30701
+ const cellNode = getSelectionTableCellNode(editor);
30702
+ return Boolean(cellNode && getCellText(cellNode).startsWith("="));
30703
+ }
30645
30704
  function createCellDisplayContent(cellNode, displayValue) {
30646
30705
  const paragraphType = cellNode.type.schema.nodes.paragraph;
30647
30706
  if (!paragraphType || !displayValue) {
@@ -38894,7 +38953,6 @@ var UEditor = import_react71.default.forwardRef(({
38894
38953
  fetchMetadata,
38895
38954
  uploadFile,
38896
38955
  uploadFileForSave,
38897
- collaborationOptions,
38898
38956
  extraExtensions,
38899
38957
  showMenuBar = false,
38900
38958
  onSave,
@@ -38907,6 +38965,17 @@ var UEditor = import_react71.default.forwardRef(({
38907
38965
  const inFlightPrepareRef = (0, import_react71.useRef)(null);
38908
38966
  const lastAppliedContentRef = (0, import_react71.useRef)(content ?? "");
38909
38967
  const scheduledFormulaRecalculateRef = (0, import_react71.useRef)(false);
38968
+ const scheduleFormulaRecalculate = import_react71.default.useCallback((editor2, options) => {
38969
+ if (editor2.isDestroyed || scheduledFormulaRecalculateRef.current) return;
38970
+ if (!options?.force && isEditingTableFormulaText(editor2)) return;
38971
+ scheduledFormulaRecalculateRef.current = true;
38972
+ queueMicrotask(() => {
38973
+ scheduledFormulaRecalculateRef.current = false;
38974
+ if (!editor2.isDestroyed && (options?.force || !isEditingTableFormulaText(editor2))) {
38975
+ recalculateAllTableFormulas(editor2);
38976
+ }
38977
+ });
38978
+ }, []);
38910
38979
  const resolvedUploadFile = (0, import_react71.useMemo)(() => {
38911
38980
  if (uploadFile) return uploadFile;
38912
38981
  if (uploadFileForSave) {
@@ -38971,19 +39040,19 @@ var UEditor = import_react71.default.forwardRef(({
38971
39040
  }
38972
39041
  },
38973
39042
  onUpdate: ({ editor: editor2, transaction }) => {
38974
- if (!transaction.getMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META) && !scheduledFormulaRecalculateRef.current) {
38975
- scheduledFormulaRecalculateRef.current = true;
38976
- queueMicrotask(() => {
38977
- scheduledFormulaRecalculateRef.current = false;
38978
- if (!editor2.isDestroyed) {
38979
- recalculateAllTableFormulas(editor2);
38980
- }
38981
- });
39043
+ if (!transaction.getMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META)) {
39044
+ scheduleFormulaRecalculate(editor2);
38982
39045
  }
38983
39046
  const html = editor2.getHTML();
38984
39047
  onChange?.(html);
38985
39048
  onHtmlChange?.(html);
38986
39049
  onJsonChange?.(editor2.getJSON());
39050
+ },
39051
+ onSelectionUpdate: ({ editor: editor2 }) => {
39052
+ scheduleFormulaRecalculate(editor2);
39053
+ },
39054
+ onBlur: ({ editor: editor2 }) => {
39055
+ scheduleFormulaRecalculate(editor2, { force: true });
38987
39056
  }
38988
39057
  });
38989
39058
  const {