Skip to content

Commit

Permalink
Don't upload images that were already uploaded elsewhere
Browse files Browse the repository at this point in the history
Users can paste image URLs directly into the editor without triggering
uploads.
  • Loading branch information
cesardeazevedo committed Nov 24, 2024
1 parent 35b1955 commit 35cac0d
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 9 deletions.
9 changes: 5 additions & 4 deletions examples/react/src/components/Image/ImageEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { UploadingProgress } from '../UploadingProgress'
import { Image } from './Image'

export function ImageEditor(props: NodeViewProps) {
const { src, alt, uploadUrl, uploading, uploadError, sha256 } = props.node.attrs as ImageAttributes
const { src, alt, uploadUrl, uploading, uploadError } = props.node.attrs as ImageAttributes
const isUploaded = !src.startsWith('blob://http')
return (
<NodeViewWrapper
data-drag-handle=''
Expand All @@ -20,16 +21,16 @@ export function ImageEditor(props: NodeViewProps) {
<UploadingProgress uploading={uploading} />
<Image src={src} />
<MediaFooter>
{!sha256 ? <AltButton value={alt} onChange={(alt) => props.updateAttributes({ alt })} /> : <div />}
{!sha256 && (
{!isUploaded && <AltButton value={alt} onChange={(alt) => props.updateAttributes({ alt })} />}
{!isUploaded && (
<UploadChip
uploadUrl={uploadUrl}
onChange={(uploadType, uploadUrl) => {
props.updateAttributes({ uploadType, uploadUrl })
}}
/>
)}
{sha256 && (
{isUploaded && (
<span data-tooltip={src}>
<IconCheck
size={26}
Expand Down
9 changes: 5 additions & 4 deletions examples/react/src/components/Video/VideoEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { UploadingProgress } from '../UploadingProgress'
import { Video } from './Video'

export function VideoEditor(props: NodeViewProps) {
const { src, alt, sha256, uploadError, uploadUrl, uploading } = props.node.attrs as VideoAttributes
const { src, alt, uploadError, uploadUrl, uploading } = props.node.attrs as VideoAttributes
const isUploaded = !src.startsWith('blob://http')
return (
<NodeViewWrapper
data-drag-handle=''
Expand All @@ -20,14 +21,14 @@ export function VideoEditor(props: NodeViewProps) {
<UploadingProgress uploading={uploading} />
<Video controls={false} src={src} />
<MediaFooter>
{!sha256 ? <AltButton value={alt} onChange={(alt) => props.updateAttributes({ alt })} /> : <div />}
{!sha256 && (
{!isUploaded ? <AltButton value={alt} onChange={(alt) => props.updateAttributes({ alt })} /> : <div />}
{!isUploaded && (
<UploadChip
uploadUrl={uploadUrl}
onChange={(uploadType, uploadUrl) => props.updateAttributes({ uploadType, uploadUrl })}
/>
)}
{sha256 && (
{isUploaded && (
<span data-tooltip={src}>
<IconCheck
size={26}
Expand Down
30 changes: 30 additions & 0 deletions src/__tests__/upload.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { hash1, hash2, responses, mockBlossomServer } from './mockBlossom'
import { test } from './fixtures'
import { fakeEvent } from './testUtils'

function getReponse(hash: typeof hash1 | typeof hash2) {
const res = responses[hash]
Expand Down Expand Up @@ -129,4 +130,33 @@ describe('FileUpload', () => {
expect(spyUploadError).not.toHaveBeenCalled()
expect(spyComplete).toHaveBeenCalledOnce()
})

test('assert blob urls as pending uploads and real urls as uploaded', async ({
editor,
getFile,
fileUploadExtension,
}) => {
const fileUpload = fileUploadExtension(editor)
editor.commands.setEventContent(fakeEvent({ content: 'test link https://nostr.com/image.jpg' }))
await expect(editor.storage.fileUpload.uploader.start()).resolves.toEqual([
{
alt: null,
file: null,
sha256: null,
src: 'https://nostr.com/image.jpg',
tags: null,
uploadError: null,
uploadType: 'blossom',
uploadUrl: 'https://localhost:3000',
uploading: false,
},
])
editor.commands.clearContent()
const file = await getFile('test_upload.png')
editor.commands.addFile(file, editor.$doc.size - 2)
await new Promise<void>((resolve) => setTimeout(() => resolve(), 100))
const found = fileUpload.storage.uploader?.['findNodes'](false)
expect(found).toHaveLength(1)
expect(found?.[0][0].type.name).toBe('image')
})
})
3 changes: 2 additions & 1 deletion src/extensions/FileUploadExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ class Uploader {
return
}
if (uploaded !== undefined) {
if (!!node.attrs.sha256 !== uploaded) {
const isUploaded = !node.attrs.src.startsWith('blob:')
if (isUploaded !== uploaded) {
return
}
}
Expand Down

0 comments on commit 35cac0d

Please sign in to comment.