mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-13 09:00:16 +00:00
fix: dropdown widget fetching output files (#6734)
related https://github.com/Comfy-Org/ComfyUI_frontend/issues/5827#issuecomment-3539629932 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6734-fix-dropdown-widget-fetching-output-files-2af6d73d365081988340f74694b7cee7) by [Unito](https://www.unito.io) Co-authored-by: bymyself <cbyrne@comfy.org>
This commit is contained in:
@@ -7,6 +7,7 @@ import { useTransformCompatOverlayProps } from '@/composables/useTransformCompat
|
||||
import { appendCloudResParam } from '@/platform/distribution/cloudPreviewUtil'
|
||||
import { SUPPORTED_EXTENSIONS_ACCEPT } from '@/extensions/core/load3d/constants'
|
||||
import { useAssetFilterOptions } from '@/platform/assets/composables/useAssetFilterOptions'
|
||||
import { useMediaAssets } from '@/platform/assets/composables/media/useMediaAssets'
|
||||
import {
|
||||
filterItemByBaseModels,
|
||||
filterItemByOwnership
|
||||
@@ -33,9 +34,9 @@ import { useAssetWidgetData } from '@/renderer/extensions/vueNodes/widgets/compo
|
||||
import type { ResultItemType } from '@/schemas/apiSchema'
|
||||
import { api } from '@/scripts/api'
|
||||
import { useAssetsStore } from '@/stores/assetsStore'
|
||||
import { useQueueStore } from '@/stores/queueStore'
|
||||
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
import type { AssetKind } from '@/types/widgetTypes'
|
||||
import { getMediaTypeFromFilename } from '@/utils/formatUtil'
|
||||
import {
|
||||
PANEL_EXCLUDED_PROPS,
|
||||
filterWidgetProps
|
||||
@@ -68,7 +69,8 @@ const modelValue = defineModel<string | undefined>({
|
||||
|
||||
const { t } = useI18n()
|
||||
const toastStore = useToastStore()
|
||||
const queueStore = useQueueStore()
|
||||
|
||||
const outputMediaAssets = useMediaAssets('output')
|
||||
|
||||
const transformCompatProps = useTransformCompatOverlayProps()
|
||||
|
||||
@@ -147,36 +149,28 @@ const inputItems = computed<FormDropdownItem[]>(() => {
|
||||
label: getDisplayLabel(String(value))
|
||||
}))
|
||||
})
|
||||
function assetKindToMediaType(kind: AssetKind): string {
|
||||
return kind === 'mesh' ? '3D' : kind
|
||||
}
|
||||
|
||||
const outputItems = computed<FormDropdownItem[]>(() => {
|
||||
if (!['image', 'video', 'mesh'].includes(props.assetKind ?? '')) return []
|
||||
if (!['image', 'video', 'audio', 'mesh'].includes(props.assetKind ?? ''))
|
||||
return []
|
||||
|
||||
const outputs = new Set<string>()
|
||||
const targetMediaType = assetKindToMediaType(props.assetKind!)
|
||||
const outputFiles = outputMediaAssets.media.value.filter(
|
||||
(asset) => getMediaTypeFromFilename(asset.name) === targetMediaType
|
||||
)
|
||||
|
||||
// Extract output images/videos from queue history
|
||||
queueStore.historyTasks.forEach((task) => {
|
||||
task.flatOutputs.forEach((output) => {
|
||||
const isTargetType =
|
||||
(props.assetKind === 'image' && output.mediaType === 'images') ||
|
||||
(props.assetKind === 'video' && output.mediaType === 'video') ||
|
||||
(props.assetKind === 'mesh' && output.is3D)
|
||||
|
||||
if (output.type === 'output' && isTargetType) {
|
||||
const path = output.subfolder
|
||||
? `${output.subfolder}/${output.filename}`
|
||||
: output.filename
|
||||
// Add [output] annotation so the preview component knows the type
|
||||
const annotatedPath = `${path} [output]`
|
||||
outputs.add(annotatedPath)
|
||||
}
|
||||
})
|
||||
return outputFiles.map((asset) => {
|
||||
const annotatedPath = `${asset.name} [output]`
|
||||
return {
|
||||
id: `output-${annotatedPath}`,
|
||||
preview_url: asset.preview_url || getMediaUrl(asset.name, 'output'),
|
||||
name: annotatedPath,
|
||||
label: getDisplayLabel(annotatedPath)
|
||||
}
|
||||
})
|
||||
|
||||
return Array.from(outputs).map((output) => ({
|
||||
id: `output-${output}`,
|
||||
preview_url: getMediaUrl(output.replace(' [output]', ''), 'output'),
|
||||
name: output,
|
||||
label: getDisplayLabel(output)
|
||||
}))
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -465,11 +459,18 @@ function getMediaUrl(
|
||||
filename: string,
|
||||
type: 'input' | 'output' = 'input'
|
||||
): string {
|
||||
if (!['image', 'video'].includes(props.assetKind ?? '')) return ''
|
||||
if (!['image', 'video', 'audio', 'mesh'].includes(props.assetKind ?? ''))
|
||||
return ''
|
||||
const params = new URLSearchParams({ filename, type })
|
||||
appendCloudResParam(params, filename)
|
||||
return `/api/view?${params}`
|
||||
}
|
||||
|
||||
function handleIsOpenUpdate(isOpen: boolean) {
|
||||
if (isOpen && !outputMediaAssets.loading.value) {
|
||||
void outputMediaAssets.refresh()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -495,6 +496,7 @@ function getMediaUrl(
|
||||
class="w-full"
|
||||
@update:selected="updateSelectedItems"
|
||||
@update:files="handleFilesUpdate"
|
||||
@update:is-open="handleIsOpenUpdate"
|
||||
/>
|
||||
</WidgetLayoutField>
|
||||
</template>
|
||||
|
||||
@@ -90,11 +90,11 @@ const ownershipSelected = defineModel<OwnershipOption>('ownershipSelected', {
|
||||
const baseModelSelected = defineModel<Set<string>>('baseModelSelected', {
|
||||
default: () => new Set()
|
||||
})
|
||||
const isOpen = defineModel<boolean>('isOpen', { default: false })
|
||||
|
||||
const toastStore = useToastStore()
|
||||
const popoverRef = ref<InstanceType<typeof Popover>>()
|
||||
const triggerRef = useTemplateRef('triggerRef')
|
||||
const isOpen = ref(false)
|
||||
|
||||
const maxSelectable = computed(() => {
|
||||
if (multiple === true) return Infinity
|
||||
|
||||
Reference in New Issue
Block a user