mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-19 22:34:15 +00:00
#8598 made primitve widgets connected to an asset have the asset type, but the `nodeType` parameter required to actually resolve valid models wasn't getting passed correctly. This `nodeType`, introduced by me back in #7576, was a mistake. I'm pulling it out now and instead passing nodeType as an option. Of note: code changes are only required to pass the option, not to utilize it. | Before | After | | ------ | ----- | | <img width="360" alt="before" src="https://github.com/user-attachments/assets/f1abfbd1-2502-4b82-841c-7ef697b3a431" /> | <img width="360" alt="after" src="https://github.com/user-attachments/assets/099cd511-0101-496c-b24e-ee2c19f23384"/>| The backport PR was made first in #8878. Fixing the bug was time sensitive and backport would not be clean due to the `widget.value` changes. Changes were still simpler than expected. I probably should have made this PR first and then backported, but I misjudged the complexity of conflict resolution. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8879-Fix-primitive-assets-3076d73d365081b89ed4e6400dbf8e74) by [Unito](https://www.unito.io)
115 lines
3.4 KiB
TypeScript
115 lines
3.4 KiB
TypeScript
import { t } from '@/i18n'
|
|
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
|
import type {
|
|
IBaseWidget,
|
|
IWidgetAssetOptions
|
|
} from '@/lib/litegraph/src/types/widgets'
|
|
import { useAssetBrowserDialog } from '@/platform/assets/composables/useAssetBrowserDialog'
|
|
import {
|
|
assetFilenameSchema,
|
|
assetItemSchema
|
|
} from '@/platform/assets/schemas/assetSchema'
|
|
import { useToastStore } from '@/platform/updates/common/toastStore'
|
|
import { getAssetFilename } from '@/platform/assets/utils/assetMetadataUtils'
|
|
|
|
interface CreateAssetWidgetParams {
|
|
/** The node to add the widget to */
|
|
node: LGraphNode
|
|
/** The widget name */
|
|
widgetName: string
|
|
/** The node type to show in asset browser (may differ from node.comfyClass for PrimitiveNode) */
|
|
nodeTypeForBrowser: string
|
|
/** Input name for asset browser filtering (defaults to widgetName if not provided) */
|
|
inputNameForBrowser?: string
|
|
/** Default value for the widget */
|
|
defaultValue?: string
|
|
/** Callback when widget value changes */
|
|
onValueChange?: (
|
|
widget: IBaseWidget,
|
|
newValue: string,
|
|
oldValue: unknown
|
|
) => void
|
|
}
|
|
|
|
/**
|
|
* Creates an asset widget that opens the Asset Browser dialog for model selection.
|
|
* Used by both regular nodes (via useComboWidget) and PrimitiveNode.
|
|
*
|
|
* @param params - Configuration for the asset widget
|
|
* @returns The created asset widget
|
|
*/
|
|
export function createAssetWidget(
|
|
params: CreateAssetWidgetParams
|
|
): IBaseWidget {
|
|
const {
|
|
node,
|
|
widgetName,
|
|
nodeTypeForBrowser,
|
|
inputNameForBrowser,
|
|
defaultValue,
|
|
onValueChange
|
|
} = params
|
|
|
|
const displayLabel = defaultValue ?? t('widgets.selectModel')
|
|
const assetBrowserDialog = useAssetBrowserDialog()
|
|
|
|
async function openModal(widget: IBaseWidget) {
|
|
const toastStore = useToastStore()
|
|
|
|
await assetBrowserDialog.show({
|
|
nodeType: nodeTypeForBrowser,
|
|
inputName: inputNameForBrowser ?? widgetName,
|
|
currentValue: widget.value as string,
|
|
onAssetSelected: (asset) => {
|
|
const validatedAsset = assetItemSchema.safeParse(asset)
|
|
|
|
if (!validatedAsset.success) {
|
|
console.error(
|
|
'Invalid asset item:',
|
|
validatedAsset.error.errors,
|
|
'Received:',
|
|
asset
|
|
)
|
|
toastStore.add({
|
|
severity: 'error',
|
|
summary: t('assetBrowser.invalidAsset'),
|
|
detail: t('assetBrowser.invalidAssetDetail'),
|
|
life: 5000
|
|
})
|
|
return
|
|
}
|
|
|
|
const filename = getAssetFilename(validatedAsset.data)
|
|
const validatedFilename = assetFilenameSchema.safeParse(filename)
|
|
|
|
if (!validatedFilename.success) {
|
|
console.error(
|
|
'Invalid asset filename:',
|
|
validatedFilename.error.errors,
|
|
'for asset:',
|
|
validatedAsset.data.id
|
|
)
|
|
toastStore.add({
|
|
severity: 'error',
|
|
summary: t('assetBrowser.invalidFilename'),
|
|
detail: t('assetBrowser.invalidFilenameDetail'),
|
|
life: 5000
|
|
})
|
|
return
|
|
}
|
|
|
|
const oldValue = widget.value
|
|
widget.value = validatedFilename.data
|
|
onValueChange?.(widget, validatedFilename.data, oldValue)
|
|
}
|
|
})
|
|
}
|
|
|
|
const options: IWidgetAssetOptions = {
|
|
openModal,
|
|
nodeType: nodeTypeForBrowser
|
|
}
|
|
|
|
return node.addWidget('asset', widgetName, displayLabel, () => {}, options)
|
|
}
|