mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-31 05:19:53 +00:00
Queue media preview (#449)
* output url * Basic image previews * Split out task item component * Move task actions to context menu * simplify * Move spinner * Lift context menu to tab scope * Better tag * Fix placeholder style * nit * Correctly handle cancelled * nit * Split out result item as separate component * nit * Fix center crop * nit * Simplify task item * Flat list * Show prompt id * Make image draggable * Disable preview for dragging * Fix key * Correctly handle task in expanded view * Add preview
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
import { api } from '@/scripts/api'
|
||||
import { app } from '@/scripts/app'
|
||||
import {
|
||||
validateTaskItem,
|
||||
import type {
|
||||
TaskItem,
|
||||
TaskType,
|
||||
TaskPrompt,
|
||||
TaskStatus,
|
||||
StatusWsMessageStatus,
|
||||
TaskOutput,
|
||||
StatusWsMessageStatus
|
||||
ResultItem
|
||||
} from '@/types/apiTypes'
|
||||
import { plainToClass } from 'class-transformer'
|
||||
import { validateTaskItem } from '@/types/apiTypes'
|
||||
import type { NodeId } from '@/types/comfyWorkflow'
|
||||
import { instanceToPlain, plainToClass } from 'class-transformer'
|
||||
import _ from 'lodash'
|
||||
import { defineStore } from 'pinia'
|
||||
import { toRaw } from 'vue'
|
||||
@@ -25,11 +27,43 @@ export enum TaskItemDisplayStatus {
|
||||
Cancelled = 'Cancelled'
|
||||
}
|
||||
|
||||
export class ResultItemImpl {
|
||||
filename: string
|
||||
subfolder?: string
|
||||
type: string
|
||||
|
||||
nodeId: NodeId
|
||||
// 'audio' | 'images' | ...
|
||||
mediaType: string
|
||||
|
||||
get url(): string {
|
||||
return api.apiURL(`/view?filename=${encodeURIComponent(this.filename)}&type=${this.type}&
|
||||
subfolder=${encodeURIComponent(this.subfolder || '')}&t=${+new Date()}`)
|
||||
}
|
||||
}
|
||||
|
||||
export class TaskItemImpl {
|
||||
taskType: TaskType
|
||||
prompt: TaskPrompt
|
||||
status?: TaskStatus
|
||||
outputs?: TaskOutput
|
||||
outputs: TaskOutput
|
||||
|
||||
get flatOutputs(): ResultItemImpl[] {
|
||||
if (!this.outputs) {
|
||||
return []
|
||||
}
|
||||
return Object.entries(this.outputs).flatMap(([nodeId, nodeOutputs]) =>
|
||||
Object.entries(nodeOutputs).flatMap(([mediaType, items]) =>
|
||||
(items as ResultItem[]).flatMap((item: ResultItem) =>
|
||||
plainToClass(ResultItemImpl, {
|
||||
...item,
|
||||
nodeId,
|
||||
mediaType
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
get apiTaskType(): APITaskType {
|
||||
switch (this.taskType) {
|
||||
@@ -41,6 +75,10 @@ export class TaskItemImpl {
|
||||
}
|
||||
}
|
||||
|
||||
get key() {
|
||||
return this.promptId + this.displayStatus
|
||||
}
|
||||
|
||||
get queueIndex() {
|
||||
return this.prompt[0]
|
||||
}
|
||||
@@ -174,6 +212,31 @@ export const useQueueStore = defineStore('queue', {
|
||||
...state.historyTasks
|
||||
]
|
||||
},
|
||||
flatTasks(): TaskItemImpl[] {
|
||||
return this.tasks.flatMap((task: TaskItemImpl) => {
|
||||
if (task.displayStatus !== TaskItemDisplayStatus.Completed) {
|
||||
return [task]
|
||||
}
|
||||
|
||||
return task.flatOutputs.map((output: ResultItemImpl, i: number) =>
|
||||
plainToClass(TaskItemImpl, {
|
||||
...instanceToPlain(task),
|
||||
prompt: [
|
||||
task.queueIndex,
|
||||
`${task.promptId}-${i}`,
|
||||
task.promptInputs,
|
||||
task.extraData,
|
||||
task.outputsToExecute
|
||||
],
|
||||
outputs: {
|
||||
[output.nodeId]: {
|
||||
[output.mediaType]: [instanceToPlain(output)]
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
},
|
||||
lastHistoryQueueIndex(state) {
|
||||
return state.historyTasks.length ? state.historyTasks[0].queueIndex : -1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user