Fix doubled player on VHS LoadAudio in vue (#8206)

In vue mode, the VHS Load Audio (Upload) node had 2 audio previews. This
occurred because the native AudioPreview widget was being applied to any
combo widget with the name `audio`. This native preview does not support
the advanced preview functions VHS provides like seeking to specific
start time, trimming to a target duration, or converting from formats
the browser may not support.

This is fixed through a fairly involved cleanup to instead display the
litegraph AudioUI widget as an AudioPreview widget when in vue mode.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8206-Fix-doubled-player-on-VHS-LoadAudio-in-vue-2ef6d73d365081ce8907dca2706214a1)
by [Unito](https://www.unito.io)

---------

Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
This commit is contained in:
AustinMroz
2026-01-21 00:14:37 -08:00
committed by GitHub
parent 7a1a2c1abb
commit 9a6ead37cb
11 changed files with 84 additions and 259 deletions

View File

@@ -11,7 +11,6 @@ import {
import type { SafeWidgetData } from '@/composables/graph/useGraphNodeManager'
const {
WidgetAudioUI,
WidgetButton,
WidgetColorPicker,
WidgetInputNumber,
@@ -44,75 +43,75 @@ describe('widgetRegistry', () => {
// Test number type mappings
describe('number types', () => {
it('should map int types to slider widget', () => {
expect(getComponent('int', 'bar')).toBe(WidgetInputNumber)
expect(getComponent('INT', 'bar')).toBe(WidgetInputNumber)
expect(getComponent('int')).toBe(WidgetInputNumber)
expect(getComponent('INT')).toBe(WidgetInputNumber)
})
it('should map float types to slider widget', () => {
expect(getComponent('float', 'cfg')).toBe(WidgetInputNumber)
expect(getComponent('FLOAT', 'cfg')).toBe(WidgetInputNumber)
expect(getComponent('number', 'cfg')).toBe(WidgetInputNumber)
expect(getComponent('slider', 'cfg')).toBe(WidgetInputNumber)
expect(getComponent('float')).toBe(WidgetInputNumber)
expect(getComponent('FLOAT')).toBe(WidgetInputNumber)
expect(getComponent('number')).toBe(WidgetInputNumber)
expect(getComponent('slider')).toBe(WidgetInputNumber)
})
})
// Test text type mappings
describe('text types', () => {
it('should map text variations to input text widget', () => {
expect(getComponent('text', 'text')).toBe(WidgetInputText)
expect(getComponent('string', 'text')).toBe(WidgetInputText)
expect(getComponent('STRING', 'text')).toBe(WidgetInputText)
expect(getComponent('text')).toBe(WidgetInputText)
expect(getComponent('string')).toBe(WidgetInputText)
expect(getComponent('STRING')).toBe(WidgetInputText)
})
it('should map multiline text types to textarea widget', () => {
expect(getComponent('multiline', 'text')).toBe(WidgetTextarea)
expect(getComponent('textarea', 'text')).toBe(WidgetTextarea)
expect(getComponent('TEXTAREA', 'text')).toBe(WidgetTextarea)
expect(getComponent('customtext', 'text')).toBe(WidgetTextarea)
expect(getComponent('multiline')).toBe(WidgetTextarea)
expect(getComponent('textarea')).toBe(WidgetTextarea)
expect(getComponent('TEXTAREA')).toBe(WidgetTextarea)
expect(getComponent('customtext')).toBe(WidgetTextarea)
})
it('should map markdown to markdown widget', () => {
expect(getComponent('MARKDOWN', 'text')).toBe(WidgetMarkdown)
expect(getComponent('markdown', 'text')).toBe(WidgetMarkdown)
expect(getComponent('MARKDOWN')).toBe(WidgetMarkdown)
expect(getComponent('markdown')).toBe(WidgetMarkdown)
})
})
// Test selection type mappings
describe('selection types', () => {
it('should map combo types to select widget', () => {
expect(getComponent('combo', 'image')).toBe(WidgetSelect)
expect(getComponent('COMBO', 'video')).toBe(WidgetSelect)
expect(getComponent('combo')).toBe(WidgetSelect)
expect(getComponent('COMBO')).toBe(WidgetSelect)
})
})
// Test boolean type mappings
describe('boolean types', () => {
it('should map boolean types to toggle switch widget', () => {
expect(getComponent('toggle', 'image')).toBe(WidgetToggleSwitch)
expect(getComponent('boolean', 'image')).toBe(WidgetToggleSwitch)
expect(getComponent('BOOLEAN', 'image')).toBe(WidgetToggleSwitch)
expect(getComponent('toggle')).toBe(WidgetToggleSwitch)
expect(getComponent('boolean')).toBe(WidgetToggleSwitch)
expect(getComponent('BOOLEAN')).toBe(WidgetToggleSwitch)
})
})
// Test advanced widget mappings
describe('advanced widgets', () => {
it('should map color types to color picker widget', () => {
expect(getComponent('color', 'color')).toBe(WidgetColorPicker)
expect(getComponent('COLOR', 'color')).toBe(WidgetColorPicker)
expect(getComponent('color')).toBe(WidgetColorPicker)
expect(getComponent('COLOR')).toBe(WidgetColorPicker)
})
it('should map button types to button widget', () => {
expect(getComponent('button', '')).toBe(WidgetButton)
expect(getComponent('BUTTON', '')).toBe(WidgetButton)
expect(getComponent('button')).toBe(WidgetButton)
expect(getComponent('BUTTON')).toBe(WidgetButton)
})
})
// Test fallback behavior
describe('fallback behavior', () => {
it('should return null for unknown types', () => {
expect(getComponent('unknown', 'unknown')).toBe(null)
expect(getComponent('custom_widget', 'custom_widget')).toBe(null)
expect(getComponent('', '')).toBe(null)
expect(getComponent('unknown')).toBe(null)
expect(getComponent('custom_widget')).toBe(null)
expect(getComponent('')).toBe(null)
})
})
})
@@ -176,16 +175,10 @@ describe('widgetRegistry', () => {
it('should handle case sensitivity correctly through aliases', () => {
// Test that both lowercase and uppercase work
expect(getComponent('string', '')).toBe(WidgetInputText)
expect(getComponent('STRING', '')).toBe(WidgetInputText)
expect(getComponent('combo', '')).toBe(WidgetSelect)
expect(getComponent('COMBO', '')).toBe(WidgetSelect)
})
it('should handle combo additional widgets', () => {
// Test that both lowercase and uppercase work
expect(getComponent('combo', 'audio')).toBe(WidgetAudioUI)
expect(getComponent('combo', 'image')).toBe(WidgetSelect)
expect(getComponent('string')).toBe(WidgetInputText)
expect(getComponent('STRING')).toBe(WidgetInputText)
expect(getComponent('combo')).toBe(WidgetSelect)
expect(getComponent('COMBO')).toBe(WidgetSelect)
})
})
})