@@ -42,12 +42,6 @@ import {
4242 isComboInputSpecV2
4343} from '@/schemas/nodeDefSchema'
4444import { type BaseDOMWidget , DOMWidgetImpl } from '@/scripts/domWidget'
45- import { getFromWebmFile } from '@/scripts/metadata/ebml'
46- import { getGltfBinaryMetadata } from '@/scripts/metadata/gltf'
47- import { getFromIsobmffFile } from '@/scripts/metadata/isobmff'
48- import { getMp3Metadata } from '@/scripts/metadata/mp3'
49- import { getOggMetadata } from '@/scripts/metadata/ogg'
50- import { getSvgMetadata } from '@/scripts/metadata/svg'
5145import { useDialogService } from '@/services/dialogService'
5246import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
5347import { useExtensionService } from '@/services/extensionService'
@@ -89,20 +83,14 @@ import { deserialiseAndCreate } from '@/utils/vintageClipboard'
8983
9084import { type ComfyApi , PromptExecutionError , api } from './api'
9185import { defaultGraph } from './defaultGraph'
92- import {
93- getAvifMetadata ,
94- getFlacMetadata ,
95- getLatentMetadata ,
96- getPngMetadata ,
97- getWebpMetadata ,
98- importA1111
99- } from './pnginfo'
86+ import { importA1111 } from './pnginfo'
10087import { $el , ComfyUI } from './ui'
10188import { ComfyAppMenu } from './ui/menu/index'
10289import { clone } from './utils'
10390import { type ComfyWidgetConstructor } from './widgets'
10491import { ensureCorrectLayoutScale } from '@/renderer/extensions/vueNodes/layout/ensureCorrectLayoutScale'
10592import { extractFileFromDragEvent } from '@/utils/eventUtils'
93+ import { getWorkflowDataFromFile } from '@/scripts/metadata/parser'
10694
10795export const ANIM_PREVIEW_WIDGET = '$$comfy_animation_preview'
10896
@@ -1396,208 +1384,49 @@ export class ComfyApp {
13961384 */
13971385 async handleFile ( file : File , openSource ?: WorkflowOpenSource ) {
13981386 const fileName = file . name . replace ( / \. \w + $ / , '' ) // Strip file extension
1399- if ( file . type === 'image/png' ) {
1400- const pngInfo = await getPngMetadata ( file )
1401- if ( pngInfo ?. workflow ) {
1402- await this . loadGraphData (
1403- JSON . parse ( pngInfo . workflow ) ,
1404- true ,
1405- true ,
1406- fileName ,
1407- { openSource }
1408- )
1409- return
1410- }
1411- if ( pngInfo ?. prompt ) {
1412- this . loadApiJson ( JSON . parse ( pngInfo . prompt ) , fileName )
1413- return
1414- }
1415- if ( pngInfo ?. parameters ) {
1416- // Note: Not putting this in `importA1111` as it is mostly not used
1417- // by external callers, and `importA1111` has no access to `app`.
1418- useWorkflowService ( ) . beforeLoadNewGraph ( )
1419- importA1111 ( this . graph , pngInfo . parameters )
1420- useWorkflowService ( ) . afterLoadNewGraph (
1421- fileName ,
1422- this . graph . serialize ( ) as unknown as ComfyWorkflowJSON
1423- )
1424- return
1425- }
1387+ const workflowData = await getWorkflowDataFromFile ( file )
1388+ if ( ! workflowData ) {
1389+ this . showErrorOnFileLoad ( file )
1390+ return
14261391 }
1427- if ( file . type === 'image/avif' ) {
1428- const { workflow, prompt } = await getAvifMetadata ( file )
14291392
1430- if ( workflow ) {
1431- this . loadGraphData ( JSON . parse ( workflow ) , true , true , fileName , {
1432- openSource
1433- } )
1434- return
1435- }
1436- if ( prompt ) {
1437- this . loadApiJson ( JSON . parse ( prompt ) , fileName )
1438- return
1439- }
1440- }
1441- if ( file . type === 'image/webp' ) {
1442- const pngInfo = await getWebpMetadata ( file )
1443- // Support loading workflows from that webp custom node.
1444- const workflow = pngInfo ?. workflow || pngInfo ?. Workflow
1445- const prompt = pngInfo ?. prompt || pngInfo ?. Prompt
1446-
1447- if ( workflow ) {
1448- this . loadGraphData ( JSON . parse ( workflow ) , true , true , fileName , {
1449- openSource
1450- } )
1451- return
1452- }
1453- if ( prompt ) {
1454- this . loadApiJson ( JSON . parse ( prompt ) , fileName )
1455- return
1456- }
1457- }
1458- if ( file . type === 'audio/mpeg' ) {
1459- const { workflow, prompt } = await getMp3Metadata ( file )
1460- if ( workflow ) {
1461- this . loadGraphData ( workflow , true , true , fileName )
1462- return
1463- }
1464- if ( prompt ) {
1465- this . loadApiJson ( prompt , fileName )
1466- return
1467- }
1468- }
1469- if ( file . type === 'audio/ogg' ) {
1470- const { workflow, prompt } = await getOggMetadata ( file )
1471- if ( workflow ) {
1472- this . loadGraphData ( workflow , true , true , fileName , { openSource } )
1473- return
1474- }
1475- if ( prompt ) {
1476- this . loadApiJson ( prompt , fileName )
1477- return
1478- }
1479- }
1480- if ( file . type === 'audio/flac' || file . type === 'audio/x-flac' ) {
1481- const pngInfo = await getFlacMetadata ( file )
1482- const workflow = pngInfo ?. workflow || pngInfo ?. Workflow
1483- const prompt = pngInfo ?. prompt || pngInfo ?. Prompt
1484-
1485- if ( workflow ) {
1486- this . loadGraphData ( JSON . parse ( workflow ) , true , true , fileName , {
1487- openSource
1488- } )
1489- return
1490- }
1491- if ( prompt ) {
1492- this . loadApiJson ( JSON . parse ( prompt ) , fileName )
1493- return
1494- }
1495- }
1496- if ( file . type === 'video/webm' ) {
1497- const webmInfo = await getFromWebmFile ( file )
1498- if ( webmInfo . workflow ) {
1499- this . loadGraphData ( webmInfo . workflow , true , true , fileName , {
1500- openSource
1501- } )
1502- return
1503- }
1504- if ( webmInfo . prompt ) {
1505- this . loadApiJson ( webmInfo . prompt , fileName )
1506- return
1507- }
1508- }
1509- if (
1510- file . type === 'video/mp4' ||
1511- file . name ?. endsWith ( '.mp4' ) ||
1512- file . name ?. endsWith ( '.mov' ) ||
1513- file . name ?. endsWith ( '.m4v' ) ||
1514- file . type === 'video/quicktime' ||
1515- file . type === 'video/x-m4v'
1516- ) {
1517- const mp4Info = await getFromIsobmffFile ( file )
1518- if ( mp4Info . workflow ) {
1519- this . loadGraphData ( mp4Info . workflow , true , true , fileName , {
1520- openSource
1521- } )
1522- return
1523- }
1524- if ( mp4Info . prompt ) {
1525- this . loadApiJson ( mp4Info . prompt , fileName )
1526- return
1527- }
1528- }
1529- if ( file . type === 'image/svg+xml' || file . name ?. endsWith ( '.svg' ) ) {
1530- const svgInfo = await getSvgMetadata ( file )
1531- if ( svgInfo . workflow ) {
1532- this . loadGraphData ( svgInfo . workflow , true , true , fileName , {
1533- openSource
1534- } )
1535- return
1536- }
1537- if ( svgInfo . prompt ) {
1538- this . loadApiJson ( svgInfo . prompt , fileName )
1539- return
1540- }
1393+ const { workflow, prompt, parameters, templates } = workflowData
1394+
1395+ if ( templates ) {
1396+ this . loadTemplateData ( { templates } )
15411397 }
1542- if ( file . type === 'model/gltf-binary' || file . name ?. endsWith ( '.glb' ) ) {
1543- const gltfInfo = await getGltfBinaryMetadata ( file )
1544- if ( gltfInfo . workflow ) {
1545- this . loadGraphData ( gltfInfo . workflow , true , true , fileName , {
1546- openSource
1547- } )
1548- return
1549- }
1550- if ( gltfInfo . prompt ) {
1551- this . loadApiJson ( gltfInfo . prompt , fileName )
1552- return
1553- }
1398+
1399+ if ( parameters ) {
1400+ // Note: Not putting this in `importA1111` as it is mostly not used
1401+ // by external callers, and `importA1111` has no access to `app`.
1402+ useWorkflowService ( ) . beforeLoadNewGraph ( )
1403+ importA1111 ( this . graph , parameters )
1404+ useWorkflowService ( ) . afterLoadNewGraph (
1405+ fileName ,
1406+ this . graph . serialize ( ) as unknown as ComfyWorkflowJSON
1407+ )
1408+ return
15541409 }
1555- if ( file . type === 'application/json' || file . name ?. endsWith ( '.json' ) ) {
1556- const reader = new FileReader ( )
1557- reader . onload = async ( ) => {
1558- const readerResult = reader . result as string
1559- const jsonContent = JSON . parse ( readerResult )
1560- if ( jsonContent ?. templates ) {
1561- this . loadTemplateData ( jsonContent )
1562- return
1563- }
1564- if ( this . isApiJson ( jsonContent ) ) {
1565- this . loadApiJson ( jsonContent , fileName )
1566- return
1567- }
1568- await this . loadGraphData (
1569- JSON . parse ( readerResult ) ,
1570- true ,
1571- true ,
1572- fileName ,
1573- { openSource }
1574- )
1575- }
1576- reader . readAsText ( file )
1410+
1411+ if ( workflow ) {
1412+ const workflowObj =
1413+ typeof workflow === 'string' ? JSON . parse ( workflow ) : workflow
1414+ await this . loadGraphData ( workflowObj , true , true , fileName , {
1415+ openSource
1416+ } )
15771417 return
15781418 }
1579- if ( file . name ?. endsWith ( '.latent' ) || file . name ?. endsWith ( '.safetensors' ) ) {
1580- const info = await getLatentMetadata ( file )
1581- // TODO define schema to LatentMetadata
1582- if ( info . workflow ) {
1583- await this . loadGraphData (
1584- JSON . parse ( info . workflow ) ,
1585- true ,
1586- true ,
1587- fileName ,
1588- { openSource }
1589- )
1590- return
1591- }
1592- if ( info . prompt ) {
1593- this . loadApiJson ( JSON . parse ( info . prompt ) , fileName )
1594- return
1595- }
1419+
1420+ if ( prompt ) {
1421+ const promptObj = typeof prompt === 'string' ? JSON . parse ( prompt ) : prompt
1422+ this . loadApiJson ( promptObj , fileName )
1423+ return
15961424 }
15971425
15981426 this . showErrorOnFileLoad ( file )
15991427 }
16001428
1429+ // @deprecated
16011430 isApiJson ( data : unknown ) {
16021431 return _ . isObject ( data ) && Object . values ( data ) . every ( ( v ) => v . class_type )
16031432 }
0 commit comments