mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
- Updated all imports from '@comfyorg/litegraph' to '@/lib/litegraph/src/' - Replaced deep dist imports with direct source paths - Updated CSS import in main.ts - All imports now use the @ alias consistently
114 lines
2.9 KiB
TypeScript
114 lines
2.9 KiB
TypeScript
import { useNodeDragAndDrop } from '@/composables/node/useNodeDragAndDrop'
|
|
import { useNodeFileInput } from '@/composables/node/useNodeFileInput'
|
|
import { useNodePaste } from '@/composables/node/useNodePaste'
|
|
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
|
import type { ResultItemType } from '@/schemas/apiSchema'
|
|
import { api } from '@/scripts/api'
|
|
import { useToastStore } from '@/stores/toastStore'
|
|
|
|
const PASTED_IMAGE_EXPIRY_MS = 2000
|
|
|
|
interface ImageUploadFormFields {
|
|
/**
|
|
* The folder to upload the file to.
|
|
* @example 'input', 'output', 'temp'
|
|
*/
|
|
type: ResultItemType
|
|
}
|
|
|
|
const uploadFile = async (
|
|
file: File,
|
|
isPasted: boolean,
|
|
formFields: Partial<ImageUploadFormFields> = {}
|
|
) => {
|
|
const body = new FormData()
|
|
body.append('image', file)
|
|
if (isPasted) body.append('subfolder', 'pasted')
|
|
if (formFields.type) body.append('type', formFields.type)
|
|
|
|
const resp = await api.fetchApi('/upload/image', {
|
|
method: 'POST',
|
|
body
|
|
})
|
|
|
|
if (resp.status !== 200) {
|
|
useToastStore().addAlert(resp.status + ' - ' + resp.statusText)
|
|
return
|
|
}
|
|
|
|
const data = await resp.json()
|
|
return data.subfolder ? `${data.subfolder}/${data.name}` : data.name
|
|
}
|
|
|
|
interface ImageUploadOptions {
|
|
fileFilter?: (file: File) => boolean
|
|
onUploadComplete: (paths: string[]) => void
|
|
allow_batch?: boolean
|
|
/**
|
|
* The file types to accept.
|
|
* @example 'image/png,image/jpeg,image/webp,video/webm,video/mp4'
|
|
*/
|
|
accept?: string
|
|
/**
|
|
* The folder to upload the file to.
|
|
* @example 'input', 'output', 'temp'
|
|
*/
|
|
folder?: ResultItemType
|
|
}
|
|
|
|
/**
|
|
* Adds image upload to a node via drag & drop, paste, and file input.
|
|
*/
|
|
export const useNodeImageUpload = (
|
|
node: LGraphNode,
|
|
options: ImageUploadOptions
|
|
) => {
|
|
const { fileFilter, onUploadComplete, allow_batch, accept } = options
|
|
|
|
const isPastedFile = (file: File): boolean =>
|
|
file.name === 'image.png' &&
|
|
file.lastModified - Date.now() < PASTED_IMAGE_EXPIRY_MS
|
|
|
|
const handleUpload = async (file: File) => {
|
|
try {
|
|
const path = await uploadFile(file, isPastedFile(file), {
|
|
type: options.folder
|
|
})
|
|
if (!path) return
|
|
return path
|
|
} catch (error) {
|
|
useToastStore().addAlert(String(error))
|
|
}
|
|
}
|
|
|
|
const handleUploadBatch = async (files: File[]) => {
|
|
const paths = await Promise.all(files.map(handleUpload))
|
|
const validPaths = paths.filter((p): p is string => !!p)
|
|
if (validPaths.length) onUploadComplete(validPaths)
|
|
return validPaths
|
|
}
|
|
|
|
// Handle drag & drop
|
|
useNodeDragAndDrop(node, {
|
|
fileFilter,
|
|
onDrop: handleUploadBatch
|
|
})
|
|
|
|
// Handle paste
|
|
useNodePaste(node, {
|
|
fileFilter,
|
|
allow_batch,
|
|
onPaste: handleUploadBatch
|
|
})
|
|
|
|
// Handle file input
|
|
const { openFileSelection } = useNodeFileInput(node, {
|
|
fileFilter,
|
|
allow_batch,
|
|
accept,
|
|
onSelect: handleUploadBatch
|
|
})
|
|
|
|
return { openFileSelection, handleUpload }
|
|
}
|