mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-27 10:14:06 +00:00
Feat: Loading state while loading dropped workflows (#6464)
## Summary Indicate to the user that we're hard at work parsing their JSON behind the scenes. ## Changes - **What**: Turn on the loading spinner while processing a workflow - **What else**: Refactored the code around figuring out how to grab the data from the file to make this easier ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6464-WIP-Loading-state-for-dropped-workflows-29c6d73d3650812dba66f2a7d27a777c) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
29
src/scripts/metadata/json.ts
Normal file
29
src/scripts/metadata/json.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { isObject } from 'es-toolkit/compat'
|
||||
|
||||
export function getDataFromJSON(
|
||||
file: File
|
||||
): Promise<Record<string, object> | undefined> {
|
||||
return new Promise<Record<string, object> | undefined>((resolve) => {
|
||||
const reader = new FileReader()
|
||||
reader.onload = async () => {
|
||||
const readerResult = reader.result as string
|
||||
const jsonContent = JSON.parse(readerResult)
|
||||
if (jsonContent?.templates) {
|
||||
resolve({ templates: jsonContent.templates })
|
||||
return
|
||||
}
|
||||
if (isApiJson(jsonContent)) {
|
||||
resolve({ prompt: jsonContent })
|
||||
return
|
||||
}
|
||||
resolve({ workflow: jsonContent })
|
||||
return
|
||||
}
|
||||
reader.readAsText(file)
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
function isApiJson(data: unknown) {
|
||||
return isObject(data) && Object.values(data).every((v) => v.class_type)
|
||||
}
|
||||
75
src/scripts/metadata/parser.ts
Normal file
75
src/scripts/metadata/parser.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { getFromWebmFile } from '@/scripts/metadata/ebml'
|
||||
import { getGltfBinaryMetadata } from '@/scripts/metadata/gltf'
|
||||
import { getFromIsobmffFile } from '@/scripts/metadata/isobmff'
|
||||
import { getDataFromJSON } from '@/scripts/metadata/json'
|
||||
import { getMp3Metadata } from '@/scripts/metadata/mp3'
|
||||
import { getOggMetadata } from '@/scripts/metadata/ogg'
|
||||
import { getSvgMetadata } from '@/scripts/metadata/svg'
|
||||
import {
|
||||
getAvifMetadata,
|
||||
getWebpMetadata,
|
||||
getFlacMetadata,
|
||||
getLatentMetadata,
|
||||
getPngMetadata
|
||||
} from '@/scripts/pnginfo'
|
||||
|
||||
export async function getWorkflowDataFromFile(
|
||||
file: File
|
||||
): Promise<Record<string, string | object> | undefined> {
|
||||
if (file.type === 'image/png') {
|
||||
return await getPngMetadata(file)
|
||||
}
|
||||
if (file.type === 'image/avif') {
|
||||
return await getAvifMetadata(file)
|
||||
}
|
||||
if (file.type === 'image/webp') {
|
||||
const pngInfo = await getWebpMetadata(file)
|
||||
// Support loading workflows from that webp custom node.
|
||||
const workflow = pngInfo?.workflow || pngInfo?.Workflow
|
||||
const prompt = pngInfo?.prompt || pngInfo?.Prompt
|
||||
return { workflow, prompt }
|
||||
}
|
||||
if (file.type === 'audio/mpeg') {
|
||||
return await getMp3Metadata(file)
|
||||
}
|
||||
if (file.type === 'audio/ogg') {
|
||||
return await getOggMetadata(file)
|
||||
}
|
||||
if (file.type === 'audio/flac' || file.type === 'audio/x-flac') {
|
||||
const pngInfo = await getFlacMetadata(file)
|
||||
const workflow = pngInfo?.workflow || pngInfo?.Workflow
|
||||
const prompt = pngInfo?.prompt || pngInfo?.Prompt
|
||||
|
||||
return { workflow, prompt }
|
||||
}
|
||||
if (file.type === 'video/webm') {
|
||||
return (await getFromWebmFile(file)) as unknown as Record<string, object>
|
||||
}
|
||||
if (
|
||||
file.name?.endsWith('.mp4') ||
|
||||
file.name?.endsWith('.mov') ||
|
||||
file.name?.endsWith('.m4v') ||
|
||||
file.type === 'video/mp4' ||
|
||||
file.type === 'video/quicktime' ||
|
||||
file.type === 'video/x-m4v'
|
||||
) {
|
||||
return (await getFromIsobmffFile(file)) as unknown as Record<string, object>
|
||||
}
|
||||
if (file.type === 'image/svg+xml' || file.name?.endsWith('.svg')) {
|
||||
return (await getSvgMetadata(file)) as unknown as Record<string, object>
|
||||
}
|
||||
if (file.type === 'model/gltf-binary' || file.name?.endsWith('.glb')) {
|
||||
return (await getGltfBinaryMetadata(file)) as unknown as Record<
|
||||
string,
|
||||
object
|
||||
>
|
||||
}
|
||||
if (file.name?.endsWith('.latent') || file.name?.endsWith('.safetensors')) {
|
||||
return await getLatentMetadata(file)
|
||||
}
|
||||
|
||||
if (file.type === 'application/json' || file.name?.endsWith('.json')) {
|
||||
return getDataFromJSON(file)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/** @knipIgnoreUnusedButUsedByCustomNodes */
|
||||
export function getFromPngBuffer(buffer: ArrayBuffer) {
|
||||
export function getFromPngBuffer(buffer: ArrayBuffer): Record<string, string> {
|
||||
// Get the PNG data as a Uint8Array
|
||||
const pngData = new Uint8Array(buffer)
|
||||
const dataView = new DataView(pngData.buffer)
|
||||
@@ -7,7 +7,7 @@ export function getFromPngBuffer(buffer: ArrayBuffer) {
|
||||
// Check that the PNG signature is present
|
||||
if (dataView.getUint32(0) !== 0x89504e47) {
|
||||
console.error('Not a valid PNG file')
|
||||
return
|
||||
return {}
|
||||
}
|
||||
|
||||
// Start searching for chunks after the PNG signature
|
||||
|
||||
Reference in New Issue
Block a user