@underverse-ui/underverse 1.0.155 → 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.
package/dist/index.d.cts CHANGED
@@ -6,6 +6,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
6
6
  import * as react_hook_form from 'react-hook-form';
7
7
  import { FieldValues, SubmitHandler, FieldPath, ControllerProps } from 'react-hook-form';
8
8
  import { ClassValue } from 'clsx';
9
+ import { Extension, Editor } from '@tiptap/core';
9
10
 
10
11
  declare const VARIANT_STYLES_BTN: {
11
12
  default: string;
@@ -3252,7 +3253,7 @@ type UEditorPrepareContentForSaveOptions = {
3252
3253
  throwOnError?: boolean;
3253
3254
  };
3254
3255
  interface UEditorRef {
3255
- editor?: any;
3256
+ editor?: Editor | null;
3256
3257
  prepareContentForSave: (options?: UEditorPrepareContentForSaveOptions) => Promise<UEditorPrepareContentForSaveResult>;
3257
3258
  }
3258
3259
  type UEditorFontFamilyOption = {
@@ -3273,13 +3274,21 @@ type UEditorLetterSpacingOption = {
3273
3274
  };
3274
3275
  /** Public props for the `UEditor` component. */
3275
3276
  interface UEditorProps {
3277
+ /** Initial or controlled HTML content for the editor. */
3276
3278
  content?: string;
3279
+ /** Called with the current HTML after editor updates. Kept for backward compatibility with `onHtmlChange`. */
3277
3280
  onChange?: (content: string) => void;
3281
+ /** Called with the current HTML after editor updates. Prefer this when the consumer stores HTML. */
3278
3282
  onHtmlChange?: (html: string) => void;
3283
+ /** Called with the current TipTap JSON document after editor updates. */
3279
3284
  onJsonChange?: (json: object) => void;
3285
+ /** Uploads images immediately when they are inserted in `imageInsertMode="upload"`. */
3280
3286
  uploadImage?: (file: File) => Promise<string> | string;
3287
+ /** Uploads embedded/base64 images during `prepareContentForSave`; use this for save-time normalization. */
3281
3288
  uploadImageForSave?: UEditorUploadImageForSave;
3289
+ /** Maximum number of concurrent save-time image/file uploads. */
3282
3290
  uploadImageConcurrency?: number;
3291
+ /** Whether inserted images are kept as base64 in editor state or uploaded immediately. */
3283
3292
  imageInsertMode?: "base64" | "upload";
3284
3293
  maxImageFileSize?: number;
3285
3294
  allowedImageMimeTypes?: string[];
@@ -3306,12 +3315,14 @@ interface UEditorProps {
3306
3315
  image?: string;
3307
3316
  publisher?: string;
3308
3317
  }>;
3318
+ /** Uploads file cards immediately after insertion when available. */
3309
3319
  uploadFile?: (file: File) => Promise<string> | string;
3320
+ /** Uploads embedded/base64 file cards during `prepareContentForSave`; falls back to `uploadImageForSave` if omitted. */
3310
3321
  uploadFileForSave?: (file: File) => Promise<string | ({
3311
3322
  url: string;
3312
3323
  } & Record<string, unknown>)>;
3313
- collaborationOptions?: any;
3314
- extraExtensions?: any[];
3324
+ /** Additional TipTap extensions appended after the built-in UEditor extensions. */
3325
+ extraExtensions?: Extension[];
3315
3326
  showMenuBar?: boolean;
3316
3327
  onSave?: () => void;
3317
3328
  onExport?: () => void;
@@ -3645,11 +3656,14 @@ declare const underverseMessages: {
3645
3656
  clickToOpenLink: string;
3646
3657
  noDescription: string;
3647
3658
  failedToLoad: string;
3659
+ previewFailed: string;
3660
+ retryPreview: string;
3648
3661
  };
3649
3662
  fileCard: {
3650
3663
  unnamed: string;
3651
3664
  uploading: string;
3652
3665
  uploadFailed: string;
3666
+ retryUpload: string;
3653
3667
  };
3654
3668
  menubar: {
3655
3669
  file: string;
@@ -4035,11 +4049,14 @@ declare const underverseMessages: {
4035
4049
  clickToOpenLink: string;
4036
4050
  noDescription: string;
4037
4051
  failedToLoad: string;
4052
+ previewFailed: string;
4053
+ retryPreview: string;
4038
4054
  };
4039
4055
  fileCard: {
4040
4056
  unnamed: string;
4041
4057
  uploading: string;
4042
4058
  uploadFailed: string;
4059
+ retryUpload: string;
4043
4060
  };
4044
4061
  menubar: {
4045
4062
  file: string;
@@ -4425,11 +4442,14 @@ declare const underverseMessages: {
4425
4442
  clickToOpenLink: string;
4426
4443
  noDescription: string;
4427
4444
  failedToLoad: string;
4445
+ previewFailed: string;
4446
+ retryPreview: string;
4428
4447
  };
4429
4448
  fileCard: {
4430
4449
  unnamed: string;
4431
4450
  uploading: string;
4432
4451
  uploadFailed: string;
4452
+ retryUpload: string;
4433
4453
  };
4434
4454
  menubar: {
4435
4455
  file: string;
@@ -4815,11 +4835,14 @@ declare const underverseMessages: {
4815
4835
  clickToOpenLink: string;
4816
4836
  noDescription: string;
4817
4837
  failedToLoad: string;
4838
+ previewFailed: string;
4839
+ retryPreview: string;
4818
4840
  };
4819
4841
  fileCard: {
4820
4842
  unnamed: string;
4821
4843
  uploading: string;
4822
4844
  uploadFailed: string;
4845
+ retryUpload: string;
4823
4846
  };
4824
4847
  menubar: {
4825
4848
  file: string;
@@ -5208,11 +5231,14 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
5208
5231
  clickToOpenLink: string;
5209
5232
  noDescription: string;
5210
5233
  failedToLoad: string;
5234
+ previewFailed: string;
5235
+ retryPreview: string;
5211
5236
  };
5212
5237
  fileCard: {
5213
5238
  unnamed: string;
5214
5239
  uploading: string;
5215
5240
  uploadFailed: string;
5241
+ retryUpload: string;
5216
5242
  };
5217
5243
  menubar: {
5218
5244
  file: string;
@@ -5597,11 +5623,14 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
5597
5623
  clickToOpenLink: string;
5598
5624
  noDescription: string;
5599
5625
  failedToLoad: string;
5626
+ previewFailed: string;
5627
+ retryPreview: string;
5600
5628
  };
5601
5629
  fileCard: {
5602
5630
  unnamed: string;
5603
5631
  uploading: string;
5604
5632
  uploadFailed: string;
5633
+ retryUpload: string;
5605
5634
  };
5606
5635
  menubar: {
5607
5636
  file: string;
@@ -5986,11 +6015,14 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
5986
6015
  clickToOpenLink: string;
5987
6016
  noDescription: string;
5988
6017
  failedToLoad: string;
6018
+ previewFailed: string;
6019
+ retryPreview: string;
5989
6020
  };
5990
6021
  fileCard: {
5991
6022
  unnamed: string;
5992
6023
  uploading: string;
5993
6024
  uploadFailed: string;
6025
+ retryUpload: string;
5994
6026
  };
5995
6027
  menubar: {
5996
6028
  file: string;
@@ -6375,11 +6407,14 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
6375
6407
  clickToOpenLink: string;
6376
6408
  noDescription: string;
6377
6409
  failedToLoad: string;
6410
+ previewFailed: string;
6411
+ retryPreview: string;
6378
6412
  };
6379
6413
  fileCard: {
6380
6414
  unnamed: string;
6381
6415
  uploading: string;
6382
6416
  uploadFailed: string;
6417
+ retryUpload: string;
6383
6418
  };
6384
6419
  menubar: {
6385
6420
  file: string;
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
6
6
  import * as react_hook_form from 'react-hook-form';
7
7
  import { FieldValues, SubmitHandler, FieldPath, ControllerProps } from 'react-hook-form';
8
8
  import { ClassValue } from 'clsx';
9
+ import { Extension, Editor } from '@tiptap/core';
9
10
 
10
11
  declare const VARIANT_STYLES_BTN: {
11
12
  default: string;
@@ -3252,7 +3253,7 @@ type UEditorPrepareContentForSaveOptions = {
3252
3253
  throwOnError?: boolean;
3253
3254
  };
3254
3255
  interface UEditorRef {
3255
- editor?: any;
3256
+ editor?: Editor | null;
3256
3257
  prepareContentForSave: (options?: UEditorPrepareContentForSaveOptions) => Promise<UEditorPrepareContentForSaveResult>;
3257
3258
  }
3258
3259
  type UEditorFontFamilyOption = {
@@ -3273,13 +3274,21 @@ type UEditorLetterSpacingOption = {
3273
3274
  };
3274
3275
  /** Public props for the `UEditor` component. */
3275
3276
  interface UEditorProps {
3277
+ /** Initial or controlled HTML content for the editor. */
3276
3278
  content?: string;
3279
+ /** Called with the current HTML after editor updates. Kept for backward compatibility with `onHtmlChange`. */
3277
3280
  onChange?: (content: string) => void;
3281
+ /** Called with the current HTML after editor updates. Prefer this when the consumer stores HTML. */
3278
3282
  onHtmlChange?: (html: string) => void;
3283
+ /** Called with the current TipTap JSON document after editor updates. */
3279
3284
  onJsonChange?: (json: object) => void;
3285
+ /** Uploads images immediately when they are inserted in `imageInsertMode="upload"`. */
3280
3286
  uploadImage?: (file: File) => Promise<string> | string;
3287
+ /** Uploads embedded/base64 images during `prepareContentForSave`; use this for save-time normalization. */
3281
3288
  uploadImageForSave?: UEditorUploadImageForSave;
3289
+ /** Maximum number of concurrent save-time image/file uploads. */
3282
3290
  uploadImageConcurrency?: number;
3291
+ /** Whether inserted images are kept as base64 in editor state or uploaded immediately. */
3283
3292
  imageInsertMode?: "base64" | "upload";
3284
3293
  maxImageFileSize?: number;
3285
3294
  allowedImageMimeTypes?: string[];
@@ -3306,12 +3315,14 @@ interface UEditorProps {
3306
3315
  image?: string;
3307
3316
  publisher?: string;
3308
3317
  }>;
3318
+ /** Uploads file cards immediately after insertion when available. */
3309
3319
  uploadFile?: (file: File) => Promise<string> | string;
3320
+ /** Uploads embedded/base64 file cards during `prepareContentForSave`; falls back to `uploadImageForSave` if omitted. */
3310
3321
  uploadFileForSave?: (file: File) => Promise<string | ({
3311
3322
  url: string;
3312
3323
  } & Record<string, unknown>)>;
3313
- collaborationOptions?: any;
3314
- extraExtensions?: any[];
3324
+ /** Additional TipTap extensions appended after the built-in UEditor extensions. */
3325
+ extraExtensions?: Extension[];
3315
3326
  showMenuBar?: boolean;
3316
3327
  onSave?: () => void;
3317
3328
  onExport?: () => void;
@@ -3645,11 +3656,14 @@ declare const underverseMessages: {
3645
3656
  clickToOpenLink: string;
3646
3657
  noDescription: string;
3647
3658
  failedToLoad: string;
3659
+ previewFailed: string;
3660
+ retryPreview: string;
3648
3661
  };
3649
3662
  fileCard: {
3650
3663
  unnamed: string;
3651
3664
  uploading: string;
3652
3665
  uploadFailed: string;
3666
+ retryUpload: string;
3653
3667
  };
3654
3668
  menubar: {
3655
3669
  file: string;
@@ -4035,11 +4049,14 @@ declare const underverseMessages: {
4035
4049
  clickToOpenLink: string;
4036
4050
  noDescription: string;
4037
4051
  failedToLoad: string;
4052
+ previewFailed: string;
4053
+ retryPreview: string;
4038
4054
  };
4039
4055
  fileCard: {
4040
4056
  unnamed: string;
4041
4057
  uploading: string;
4042
4058
  uploadFailed: string;
4059
+ retryUpload: string;
4043
4060
  };
4044
4061
  menubar: {
4045
4062
  file: string;
@@ -4425,11 +4442,14 @@ declare const underverseMessages: {
4425
4442
  clickToOpenLink: string;
4426
4443
  noDescription: string;
4427
4444
  failedToLoad: string;
4445
+ previewFailed: string;
4446
+ retryPreview: string;
4428
4447
  };
4429
4448
  fileCard: {
4430
4449
  unnamed: string;
4431
4450
  uploading: string;
4432
4451
  uploadFailed: string;
4452
+ retryUpload: string;
4433
4453
  };
4434
4454
  menubar: {
4435
4455
  file: string;
@@ -4815,11 +4835,14 @@ declare const underverseMessages: {
4815
4835
  clickToOpenLink: string;
4816
4836
  noDescription: string;
4817
4837
  failedToLoad: string;
4838
+ previewFailed: string;
4839
+ retryPreview: string;
4818
4840
  };
4819
4841
  fileCard: {
4820
4842
  unnamed: string;
4821
4843
  uploading: string;
4822
4844
  uploadFailed: string;
4845
+ retryUpload: string;
4823
4846
  };
4824
4847
  menubar: {
4825
4848
  file: string;
@@ -5208,11 +5231,14 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
5208
5231
  clickToOpenLink: string;
5209
5232
  noDescription: string;
5210
5233
  failedToLoad: string;
5234
+ previewFailed: string;
5235
+ retryPreview: string;
5211
5236
  };
5212
5237
  fileCard: {
5213
5238
  unnamed: string;
5214
5239
  uploading: string;
5215
5240
  uploadFailed: string;
5241
+ retryUpload: string;
5216
5242
  };
5217
5243
  menubar: {
5218
5244
  file: string;
@@ -5597,11 +5623,14 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
5597
5623
  clickToOpenLink: string;
5598
5624
  noDescription: string;
5599
5625
  failedToLoad: string;
5626
+ previewFailed: string;
5627
+ retryPreview: string;
5600
5628
  };
5601
5629
  fileCard: {
5602
5630
  unnamed: string;
5603
5631
  uploading: string;
5604
5632
  uploadFailed: string;
5633
+ retryUpload: string;
5605
5634
  };
5606
5635
  menubar: {
5607
5636
  file: string;
@@ -5986,11 +6015,14 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
5986
6015
  clickToOpenLink: string;
5987
6016
  noDescription: string;
5988
6017
  failedToLoad: string;
6018
+ previewFailed: string;
6019
+ retryPreview: string;
5989
6020
  };
5990
6021
  fileCard: {
5991
6022
  unnamed: string;
5992
6023
  uploading: string;
5993
6024
  uploadFailed: string;
6025
+ retryUpload: string;
5994
6026
  };
5995
6027
  menubar: {
5996
6028
  file: string;
@@ -6375,11 +6407,14 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
6375
6407
  clickToOpenLink: string;
6376
6408
  noDescription: string;
6377
6409
  failedToLoad: string;
6410
+ previewFailed: string;
6411
+ retryPreview: string;
6378
6412
  };
6379
6413
  fileCard: {
6380
6414
  unnamed: string;
6381
6415
  uploading: string;
6382
6416
  uploadFailed: string;
6417
+ retryUpload: string;
6383
6418
  };
6384
6419
  menubar: {
6385
6420
  file: string;
package/dist/index.js CHANGED
@@ -869,12 +869,15 @@ var en_default = {
869
869
  clickToOpenNewTab: "Click to open this link in a new tab.",
870
870
  clickToOpenLink: "Click to open link.",
871
871
  noDescription: "No description available.",
872
- failedToLoad: "Failed to load link preview. Click to open link."
872
+ failedToLoad: "Failed to load link preview. Click to open link.",
873
+ previewFailed: "Preview failed to load",
874
+ retryPreview: "Retry preview"
873
875
  },
874
876
  fileCard: {
875
877
  unnamed: "Unnamed file",
876
878
  uploading: "(Uploading...)",
877
- uploadFailed: "Upload failed"
879
+ uploadFailed: "Upload failed",
880
+ retryUpload: "Retry upload"
878
881
  },
879
882
  menubar: {
880
883
  file: "File",
@@ -1261,12 +1264,15 @@ var vi_default = {
1261
1264
  clickToOpenNewTab: "B\u1EA5m \u0111\u1EC3 m\u1EDF li\xEAn k\u1EBFt n\xE0y trong tab m\u1EDBi.",
1262
1265
  clickToOpenLink: "B\u1EA5m \u0111\u1EC3 m\u1EDF li\xEAn k\u1EBFt.",
1263
1266
  noDescription: "Kh\xF4ng c\xF3 m\xF4 t\u1EA3.",
1264
- failedToLoad: "T\u1EA3i b\u1EA3n xem tr\u01B0\u1EDBc th\u1EA5t b\u1EA1i. B\u1EA5m \u0111\u1EC3 m\u1EDF li\xEAn k\u1EBFt."
1267
+ failedToLoad: "T\u1EA3i b\u1EA3n xem tr\u01B0\u1EDBc th\u1EA5t b\u1EA1i. B\u1EA5m \u0111\u1EC3 m\u1EDF li\xEAn k\u1EBFt.",
1268
+ previewFailed: "Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c b\u1EA3n xem tr\u01B0\u1EDBc",
1269
+ retryPreview: "Th\u1EED l\u1EA1i"
1265
1270
  },
1266
1271
  fileCard: {
1267
1272
  unnamed: "T\u1EC7p kh\xF4ng t\xEAn",
1268
1273
  uploading: "(\u0110ang t\u1EA3i l\xEAn...)",
1269
- uploadFailed: "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i"
1274
+ uploadFailed: "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i",
1275
+ retryUpload: "T\u1EA3i l\u1EA1i"
1270
1276
  },
1271
1277
  menubar: {
1272
1278
  file: "T\u1EADp tin",
@@ -1653,12 +1659,15 @@ var ko_default = {
1653
1659
  clickToOpenNewTab: "\uD074\uB9AD\uD558\uC5EC \uC774 \uB9C1\uD06C\uB97C \uC0C8 \uD0ED\uC5D0\uC11C \uC5FD\uB2C8\uB2E4.",
1654
1660
  clickToOpenLink: "\uD074\uB9AD\uD558\uC5EC \uB9C1\uD06C\uB97C \uC5FD\uB2C8\uB2E4.",
1655
1661
  noDescription: "\uC124\uBA85\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
1656
- 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."
1662
+ 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.",
1663
+ previewFailed: "\uBBF8\uB9AC\uBCF4\uAE30\uB97C \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4",
1664
+ retryPreview: "\uB2E4\uC2DC \uC2DC\uB3C4"
1657
1665
  },
1658
1666
  fileCard: {
1659
1667
  unnamed: "\uC774\uB984 \uC5C6\uB294 \uD30C\uC77C",
1660
1668
  uploading: "(\uC5C5\uB85C\uB4DC \uC911...)",
1661
- uploadFailed: "\uC5C5\uB85C\uB4DC\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4."
1669
+ uploadFailed: "\uC5C5\uB85C\uB4DC\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.",
1670
+ retryUpload: "\uB2E4\uC2DC \uC5C5\uB85C\uB4DC"
1662
1671
  },
1663
1672
  menubar: {
1664
1673
  file: "\uD30C\uC77C",
@@ -2045,12 +2054,15 @@ var ja_default = {
2045
2054
  clickToOpenNewTab: "\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u3053\u306E\u30EA\u30F3\u30AF\u3092\u65B0\u3057\u3044\u30BF\u30D6\u3067\u958B\u304F\u3002",
2046
2055
  clickToOpenLink: "\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u30EA\u30F3\u30AF\u3092\u958B\u304F\u3002",
2047
2056
  noDescription: "\u8AAC\u660E\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
2048
- 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"
2057
+ 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",
2058
+ previewFailed: "\u30D7\u30EC\u30D3\u30E5\u30FC\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093\u3067\u3057\u305F",
2059
+ retryPreview: "\u518D\u8A66\u884C"
2049
2060
  },
2050
2061
  fileCard: {
2051
2062
  unnamed: "\u540D\u524D\u306A\u3057\u30D5\u30A1\u30A4\u30EB",
2052
2063
  uploading: "(\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u4E2D...)",
2053
- uploadFailed: "\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u5931\u6557"
2064
+ uploadFailed: "\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u5931\u6557",
2065
+ retryUpload: "\u518D\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9"
2054
2066
  },
2055
2067
  menubar: {
2056
2068
  file: "\u30D5\u30A1\u30A4\u30EB",
@@ -24855,21 +24867,27 @@ import { Node as Node3, mergeAttributes as mergeAttributes2 } from "@tiptap/core
24855
24867
  import { ReactNodeViewRenderer as ReactNodeViewRenderer2 } from "@tiptap/react";
24856
24868
 
24857
24869
  // src/components/UEditor/BookmarkView.tsx
24858
- import { useEffect as useEffect31, useState as useState42 } from "react";
24870
+ import React68, { useEffect as useEffect31, useState as useState42 } from "react";
24859
24871
  import { NodeViewWrapper as NodeViewWrapper2 } from "@tiptap/react";
24860
- import { ExternalLink as ExternalLink2, Globe as Globe2 } from "lucide-react";
24872
+ import { AlertCircle as AlertCircle4, ExternalLink as ExternalLink2, Globe as Globe2, RefreshCw } from "lucide-react";
24861
24873
  import { jsx as jsx77, jsxs as jsxs63 } from "react/jsx-runtime";
24862
24874
  var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
24863
24875
  const t = useSmartTranslations("UEditor");
24864
24876
  const { url, title, description, image, publisher } = node.attrs;
24865
24877
  const [loading2, setLoading] = useState42(false);
24866
24878
  const [error, setError] = useState42(false);
24879
+ const [retryToken, setRetryToken] = useState42(0);
24880
+ const fetchedRetryTokenRef = React68.useRef(-1);
24881
+ const fetchRequestIdRef = React68.useRef(0);
24867
24882
  useEffect31(() => {
24868
- if (title) return;
24869
- let active = true;
24883
+ if (title && retryToken === 0) return;
24884
+ if (fetchedRetryTokenRef.current === retryToken) return;
24885
+ fetchedRetryTokenRef.current = retryToken;
24886
+ const requestId = fetchRequestIdRef.current + 1;
24887
+ fetchRequestIdRef.current = requestId;
24870
24888
  const safeUpdateAttributes = (attrs) => {
24871
24889
  Promise.resolve().then(() => {
24872
- if (active && editor && !editor.isDestroyed) {
24890
+ if (fetchRequestIdRef.current === requestId && editor && !editor.isDestroyed) {
24873
24891
  updateAttributes(attrs);
24874
24892
  }
24875
24893
  });
@@ -24896,7 +24914,7 @@ var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
24896
24914
  setLoading(true);
24897
24915
  setError(false);
24898
24916
  fetchMetadata(url).then((meta) => {
24899
- if (!active) return;
24917
+ if (fetchRequestIdRef.current !== requestId) return;
24900
24918
  safeUpdateAttributes({
24901
24919
  title: meta.title || new URL(url).hostname || url,
24902
24920
  description: meta.description || t("bookmark.noDescription"),
@@ -24905,33 +24923,22 @@ var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
24905
24923
  });
24906
24924
  setLoading(false);
24907
24925
  }).catch(() => {
24908
- if (!active) return;
24926
+ if (fetchRequestIdRef.current !== requestId) return;
24909
24927
  setError(true);
24910
24928
  setLoading(false);
24911
- try {
24912
- const hostname = new URL(url).hostname;
24913
- safeUpdateAttributes({
24914
- title: hostname || url,
24915
- description: t("bookmark.failedToLoad"),
24916
- publisher: hostname
24917
- });
24918
- } catch {
24919
- safeUpdateAttributes({
24920
- title: url,
24921
- description: t("bookmark.clickToOpenLink"),
24922
- publisher: ""
24923
- });
24924
- }
24925
24929
  });
24926
- return () => {
24927
- active = false;
24928
- };
24929
- }, [url, title, editor, updateAttributes, t]);
24930
+ return void 0;
24931
+ }, [url, title, editor, updateAttributes, t, retryToken]);
24930
24932
  const handleOpenLink = (e) => {
24931
24933
  e.preventDefault();
24932
24934
  e.stopPropagation();
24933
24935
  window.open(url, "_blank", "noopener,noreferrer");
24934
24936
  };
24937
+ const handleRetryPreview = (event) => {
24938
+ event.preventDefault();
24939
+ event.stopPropagation();
24940
+ setRetryToken((value) => value + 1);
24941
+ };
24935
24942
  const displayPublisher = publisher || (() => {
24936
24943
  try {
24937
24944
  return new URL(url).hostname;
@@ -24967,6 +24974,24 @@ var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
24967
24974
  /* @__PURE__ */ jsxs63("span", { className: "text-[11px] text-primary/80 font-mono mt-2 truncate flex items-center gap-1", children: [
24968
24975
  url,
24969
24976
  /* @__PURE__ */ jsx77(ExternalLink2, { className: "h-3 w-3 flex-shrink-0" })
24977
+ ] }),
24978
+ error && /* @__PURE__ */ jsxs63("div", { className: "mt-2 flex flex-wrap items-center gap-2 text-xs text-destructive", children: [
24979
+ /* @__PURE__ */ jsxs63("span", { className: "inline-flex items-center gap-1", children: [
24980
+ /* @__PURE__ */ jsx77(AlertCircle4, { className: "h-3.5 w-3.5" }),
24981
+ t("bookmark.previewFailed")
24982
+ ] }),
24983
+ /* @__PURE__ */ jsxs63(
24984
+ "button",
24985
+ {
24986
+ type: "button",
24987
+ onClick: handleRetryPreview,
24988
+ className: "inline-flex items-center gap-1 rounded-md border border-destructive/30 px-2 py-0.5 font-medium hover:bg-destructive/10",
24989
+ children: [
24990
+ /* @__PURE__ */ jsx77(RefreshCw, { className: "h-3 w-3" }),
24991
+ t("bookmark.retryPreview")
24992
+ ]
24993
+ }
24994
+ )
24970
24995
  ] })
24971
24996
  ] }),
24972
24997
  image && /* @__PURE__ */ jsx77("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__ */ jsx77(
@@ -25104,7 +25129,7 @@ import { ReactNodeViewRenderer as ReactNodeViewRenderer3 } from "@tiptap/react";
25104
25129
  // src/components/UEditor/FileCardView.tsx
25105
25130
  import { useEffect as useEffect32, useState as useState43, useRef as useRef27 } from "react";
25106
25131
  import { NodeViewWrapper as NodeViewWrapper3 } from "@tiptap/react";
25107
- import { Download as Download2, File as LucideFile, FileText as FileText2, Image as Image3, Music, Video } from "lucide-react";
25132
+ import { Download as Download2, File as LucideFile, FileText as FileText2, Image as Image3, Music, RefreshCw as RefreshCw2, Video } from "lucide-react";
25108
25133
  import { jsx as jsx78, jsxs as jsxs64 } from "react/jsx-runtime";
25109
25134
  function formatBytes(bytes, decimals = 1) {
25110
25135
  if (!bytes || bytes <= 0) return "0 Bytes";
@@ -25151,6 +25176,7 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
25151
25176
  const { src, fileName, fileSize, fileType } = node.attrs;
25152
25177
  const FileIcon = getFileIcon2(fileType);
25153
25178
  const [uploadError, setUploadError] = useState43(null);
25179
+ const [retryToken, setRetryToken] = useState43(0);
25154
25180
  const uploadAttemptedRef = useRef27(false);
25155
25181
  useEffect32(() => {
25156
25182
  if (!src || !src.startsWith("data:")) {
@@ -25182,7 +25208,7 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
25182
25208
  }
25183
25209
  };
25184
25210
  void runUpload();
25185
- }, [src, fileName, fileType, editor, updateAttributes]);
25211
+ }, [src, fileName, fileType, editor, updateAttributes, retryToken]);
25186
25212
  const handleDownload = (e) => {
25187
25213
  e.preventDefault();
25188
25214
  e.stopPropagation();
@@ -25195,6 +25221,13 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
25195
25221
  document.body.removeChild(link);
25196
25222
  };
25197
25223
  const isUploading = (src || "").startsWith("data:");
25224
+ const handleRetryUpload = (event) => {
25225
+ event.preventDefault();
25226
+ event.stopPropagation();
25227
+ uploadAttemptedRef.current = false;
25228
+ setUploadError(null);
25229
+ setRetryToken((value) => value + 1);
25230
+ };
25198
25231
  return /* @__PURE__ */ jsxs64(
25199
25232
  NodeViewWrapper3,
25200
25233
  {
@@ -25213,7 +25246,19 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
25213
25246
  isUploading && /* @__PURE__ */ jsx78("span", { className: cn(
25214
25247
  "font-medium truncate max-w-[200px]",
25215
25248
  uploadError ? "text-destructive" : "text-primary animate-pulse"
25216
- ), children: uploadError ? `${t("fileCard.uploadFailed") || "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i"}: ${uploadError}` : t("fileCard.uploading") })
25249
+ ), children: uploadError ? `${t("fileCard.uploadFailed") || "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i"}: ${uploadError}` : t("fileCard.uploading") }),
25250
+ isUploading && uploadError && /* @__PURE__ */ jsxs64(
25251
+ "button",
25252
+ {
25253
+ type: "button",
25254
+ onClick: handleRetryUpload,
25255
+ 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",
25256
+ children: [
25257
+ /* @__PURE__ */ jsx78(RefreshCw2, { className: "h-3 w-3" }),
25258
+ t("fileCard.retryUpload")
25259
+ ]
25260
+ }
25261
+ )
25217
25262
  ] })
25218
25263
  ] })
25219
25264
  ] }),
@@ -38852,7 +38897,6 @@ var UEditor = React83.forwardRef(({
38852
38897
  fetchMetadata,
38853
38898
  uploadFile,
38854
38899
  uploadFileForSave,
38855
- collaborationOptions,
38856
38900
  extraExtensions,
38857
38901
  showMenuBar = false,
38858
38902
  onSave,