Skip to content

Commit 8941675

Browse files
committed
fix: Fixed issue where non-image inlined files would not correctly be imported from a Markdown file
1 parent a1317b2 commit 8941675

File tree

5 files changed

+46
-7
lines changed

5 files changed

+46
-7
lines changed

packages/ui-services/src/Import/Importer.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ export class Importer {
164164
return this.mutator.insertItem(note)
165165
}),
166166
)
167+
return insertedItems
168+
}
169+
170+
async uploadAndReplaceInlineFilesInInsertedItems(insertedItems: DecryptedItemInterface<ItemContent>[]) {
167171
for (const item of insertedItems) {
168172
if (!isNote(item)) {
169173
continue
@@ -185,6 +189,5 @@ export class Importer {
185189
console.error(error)
186190
}
187191
}
188-
return insertedItems
189192
}
190193
}

packages/web/src/javascripts/Components/ImportModal/ImportModalController.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export type ImportModalFile = (
2121
| { status: 'ready'; payloads?: DecryptedTransferPayload[] }
2222
| { status: 'parsing' }
2323
| { status: 'importing' }
24+
| { status: 'uploading-files' }
2425
| { status: 'success'; successMessage: string }
2526
| { status: 'error'; error: Error }
2627
) &
@@ -105,7 +106,14 @@ export class ImportModalController {
105106
})
106107

107108
try {
108-
await this.importer.importFromTransferPayloads(payloads)
109+
const insertedItems = await this.importer.importFromTransferPayloads(payloads)
110+
111+
this.updateFile({
112+
...file,
113+
status: 'uploading-files',
114+
})
115+
116+
await this.importer.uploadAndReplaceInlineFilesInInsertedItems(insertedItems)
109117

110118
const notesImported = payloads.filter((payload) => payload.content_type === ContentType.TYPES.Note)
111119
const tagsImported = payloads.filter((payload) => payload.content_type === ContentType.TYPES.Tag)

packages/web/src/javascripts/Components/ImportModal/ImportModalFileItem.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ const ImportModalFileItem = ({
103103
{file.status === 'pending' && 'Could not auto-detect service. Please select manually.'}
104104
{file.status === 'parsing' && 'Parsing...'}
105105
{file.status === 'importing' && 'Importing...'}
106+
{file.status === 'uploading-files' && 'Uploading and embedding files...'}
106107
{file.status === 'error' && JSON.stringify(file.error)}
107108
{file.status === 'success' && file.successMessage}
108109
</div>

packages/web/src/javascripts/Components/SuperEditor/MarkdownTransformers.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
$isRemoteImageNode,
3232
RemoteImageNode,
3333
} from './Plugins/RemoteImagePlugin/RemoteImageNode'
34+
import { $createInlineFileNode, $isInlineFileNode, InlineFileNode } from './Plugins/InlineFilePlugin/InlineFileNode'
3435

3536
const HorizontalRule: ElementTransformer = {
3637
dependencies: [HorizontalRuleNode],
@@ -72,6 +73,26 @@ const IMAGE: TextMatchTransformer = {
7273
type: 'text-match',
7374
}
7475

76+
const INLINE_FILE: TextMatchTransformer = {
77+
dependencies: [InlineFileNode],
78+
export: (node) => {
79+
if (!$isInlineFileNode(node)) {
80+
return null
81+
}
82+
83+
return node.getTextContent()
84+
},
85+
importRegExp: /(?:\[([^[]*)\])(?:\((data:(.*);[^(]+)\))/,
86+
regExp: /(?:\[([^[]*)\])(?:\((data:(.*);[^(]+)\))$/,
87+
replace: (textNode, match) => {
88+
const [, name, src, mimeType] = match
89+
const inlineFileNode = $createInlineFileNode(src, mimeType, name)
90+
textNode.replace(inlineFileNode)
91+
},
92+
trigger: ')',
93+
type: 'text-match',
94+
}
95+
7596
// Table transformer, taken from Lexical Playground
7697
const TABLE_ROW_REG_EXP = /^(?:\|)(.+)(?:\|)\s?$/
7798
const TABLE_ROW_DIVIDER_REG_EXP = /^(\| ?:?-*:? ?)+\|\s?$/
@@ -224,6 +245,7 @@ export const MarkdownTransformers = [
224245
TABLE,
225246
CHECK_LIST,
226247
IMAGE,
248+
INLINE_FILE,
227249
...ELEMENT_TRANSFORMERS,
228250
...TEXT_FORMAT_TRANSFORMERS,
229251
...TEXT_MATCH_TRANSFORMERS,

packages/web/src/javascripts/Components/SuperEditor/Tools/HeadlessSuperConverter.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ import { MarkdownTransformers } from '../MarkdownTransformers'
1616
import { $generateHtmlFromNodes, $generateNodesFromDOM } from '@lexical/html'
1717
import { FileNode } from '../Plugins/EncryptedFilePlugin/Nodes/FileNode'
1818
import { $createFileExportNode } from '../Lexical/Nodes/FileExportNode'
19-
import { $createInlineFileNode, InlineFileNode } from '../Plugins/InlineFilePlugin/InlineFileNode'
19+
import { $createInlineFileNode, $isInlineFileNode, InlineFileNode } from '../Plugins/InlineFilePlugin/InlineFileNode'
2020
import { $createFileNode } from '../Plugins/EncryptedFilePlugin/Nodes/FileUtils'
21+
import { RemoteImageNode } from '../Plugins/RemoteImagePlugin/RemoteImageNode'
2122
export class HeadlessSuperConverter implements SuperConverterServiceInterface {
2223
private importEditor: LexicalEditor
2324
private exportEditor: LexicalEditor
@@ -271,15 +272,19 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
271272
this.importEditor.update(
272273
() => {
273274
const inlineFileNodes = $nodesOfType(InlineFileNode)
274-
if (inlineFileNodes.length === 0) {
275+
const remoteImageNodes = $nodesOfType(RemoteImageNode).filter((node) => node.__src.startsWith('data:'))
276+
const concatenatedNodes = [...inlineFileNodes, ...remoteImageNodes]
277+
if (concatenatedNodes.length === 0) {
275278
resolve()
276279
return
277280
}
278281
Promise.all(
279-
inlineFileNodes.map(async (node) => {
282+
concatenatedNodes.map(async (node) => {
280283
const blob = await fetch(node.__src).then((response) => response.blob())
281-
const file = new File([blob], node.__fileName || generateUuid.execute().getValue(), {
282-
type: node.__mimeType,
284+
const name = $isInlineFileNode(node) ? node.__fileName : node.__alt
285+
const mimeType = $isInlineFileNode(node) ? node.__mimeType : node.__src.split(';')[0].split(':')[1]
286+
const file = new File([blob], name || generateUuid.execute().getValue(), {
287+
type: mimeType,
283288
})
284289

285290
const uploadedFile = await uploadFile(file)

0 commit comments

Comments
 (0)