1
1
'use client'
2
- import type { SerializedDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode.js'
3
- import type { DOMConversionMap , DOMConversionOutput , LexicalNode , Spread } from 'lexical'
2
+ import type { DOMConversionMap , LexicalNode } from 'lexical'
4
3
import type { JSX } from 'react'
5
4
6
5
import ObjectID from 'bson-objectid'
7
6
import { $applyNodeReplacement } from 'lexical'
8
7
import * as React from 'react'
9
8
10
- import type { UploadData } from '../../server/nodes/UploadNode.js'
9
+ import type {
10
+ Internal_UploadData ,
11
+ SerializedUploadNode ,
12
+ UploadData ,
13
+ } from '../../server/nodes/UploadNode.js'
11
14
12
- import { isGoogleDocCheckboxImg , UploadServerNode } from '../../server/nodes/UploadNode.js'
15
+ import { $convertUploadElement } from '../../server/nodes/conversions.js'
16
+ import { UploadServerNode } from '../../server/nodes/UploadNode.js'
17
+ import { PendingUploadComponent } from '../component/pending/index.js'
13
18
14
19
const RawUploadComponent = React . lazy ( ( ) =>
15
20
import ( '../../client/component/index.js' ) . then ( ( module ) => ( { default : module . UploadComponent } ) ) ,
16
21
)
17
22
18
- function $convertUploadElement ( domNode : HTMLImageElement ) : DOMConversionOutput | null {
19
- if (
20
- domNode . hasAttribute ( 'data-lexical-upload-relation-to' ) &&
21
- domNode . hasAttribute ( 'data-lexical-upload-id' )
22
- ) {
23
- const id = domNode . getAttribute ( 'data-lexical-upload-id' )
24
- const relationTo = domNode . getAttribute ( 'data-lexical-upload-relation-to' )
25
-
26
- if ( id != null && relationTo != null ) {
27
- const node = $createUploadNode ( {
28
- data : {
29
- fields : { } ,
30
- relationTo,
31
- value : id ,
32
- } ,
33
- } )
34
- return { node }
35
- }
36
- }
37
- const img = domNode
38
- if ( img . src . startsWith ( 'file:///' ) || isGoogleDocCheckboxImg ( img ) ) {
39
- return null
40
- }
41
- // TODO: Auto-upload functionality here!
42
- //}
43
- return null
44
- }
45
-
46
- export type SerializedUploadNode = {
47
- children ?: never // required so that our typed editor state doesn't automatically add children
48
- type : 'upload'
49
- } & Spread < UploadData , SerializedDecoratorBlockNode >
50
-
51
23
export class UploadNode extends UploadServerNode {
52
24
static override clone ( node : UploadServerNode ) : UploadServerNode {
53
25
return super . clone ( node )
@@ -60,7 +32,7 @@ export class UploadNode extends UploadServerNode {
60
32
static override importDOM ( ) : DOMConversionMap < HTMLImageElement > {
61
33
return {
62
34
img : ( node ) => ( {
63
- conversion : $convertUploadElement ,
35
+ conversion : ( domNode ) => $convertUploadElement ( domNode , $createUploadNode ) ,
64
36
priority : 0 ,
65
37
} ) ,
66
38
}
@@ -75,9 +47,10 @@ export class UploadNode extends UploadServerNode {
75
47
serializedNode . version = 3
76
48
}
77
49
78
- const importedData : UploadData = {
50
+ const importedData : Internal_UploadData = {
79
51
id : serializedNode . id ,
80
52
fields : serializedNode . fields ,
53
+ pending : ( serializedNode as Internal_UploadData ) . pending ,
81
54
relationTo : serializedNode . relationTo ,
82
55
value : serializedNode . value ,
83
56
}
@@ -89,6 +62,9 @@ export class UploadNode extends UploadServerNode {
89
62
}
90
63
91
64
override decorate ( ) : JSX . Element {
65
+ if ( ( this . __data as Internal_UploadData ) . pending ) {
66
+ return < PendingUploadComponent />
67
+ }
92
68
return < RawUploadComponent data = { this . __data } nodeKey = { this . getKey ( ) } />
93
69
}
94
70
@@ -105,6 +81,7 @@ export function $createUploadNode({
105
81
if ( ! data ?. id ) {
106
82
data . id = new ObjectID . default ( ) . toHexString ( )
107
83
}
84
+
108
85
return $applyNodeReplacement ( new UploadNode ( { data : data as UploadData } ) )
109
86
}
110
87
0 commit comments