Skip to content

Commit

Permalink
Pin reroute on link release searchbox (#469)
Browse files Browse the repository at this point in the history
* Correctly handle wildcard type

* Add test

* nit

* Pin reroute on link release search

* Connect wildcard

* nit
  • Loading branch information
huchenlei committed Aug 16, 2024
1 parent d171597 commit 9cea546
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 12 deletions.
10 changes: 8 additions & 2 deletions browser_tests/ComfyPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,20 @@ class ComfyNodeSearchBox {
)
}

async fillAndSelectFirstNode(nodeName: string) {
async fillAndSelectFirstNode(
nodeName: string,
options?: { suggestionIndex: number }
) {
await this.input.waitFor({ state: 'visible' })
await this.input.fill(nodeName)
await this.dropdown.waitFor({ state: 'visible' })
// Wait for some time for the auto complete list to update.
// The auto complete list is debounced and may take some time to update.
await this.page.waitForTimeout(500)
await this.dropdown.locator('li').nth(0).click()
await this.dropdown
.locator('li')
.nth(options?.suggestionIndex || 0)
.click()
}
}

Expand Down
10 changes: 8 additions & 2 deletions browser_tests/nodeSearchBox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ test.describe('Node search box', () => {

test('Can auto link node', async ({ comfyPage }) => {
await comfyPage.disconnectEdge()
await comfyPage.searchBox.fillAndSelectFirstNode('CLIPTextEncode')
// Select the second item as the first item is always reroute
await comfyPage.searchBox.fillAndSelectFirstNode('CLIPTextEncode', {
suggestionIndex: 1
})
await expect(comfyPage.canvas).toHaveScreenshot('auto-linked-node.png')
})

Expand All @@ -54,7 +57,10 @@ test.describe('Node search box', () => {
await comfyPage.dragAndDrop(outputSlot1Pos, emptySpacePos)
await comfyPage.page.keyboard.up('Shift')

await comfyPage.searchBox.fillAndSelectFirstNode('Load Checkpoint')
// Select the second item as the first item is always reroute
await comfyPage.searchBox.fillAndSelectFirstNode('Load Checkpoint', {
suggestionIndex: 1
})
await expect(comfyPage.canvas).toHaveScreenshot(
'auto-linked-node-batch.png'
)
Expand Down
18 changes: 12 additions & 6 deletions src/components/searchbox/NodeSearchBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ const props = defineProps({
searchLimit: {
type: Number,
default: 64
},
// TODO: Find a more flexible mechanism to add pinned nodes
includeReroute: {
type: Boolean,
default: false
}
})
Expand All @@ -91,13 +96,14 @@ const placeholder = computed(() => {
const search = (query: string) => {
currentQuery.value = query
suggestions.value = useNodeDefStore().nodeSearchService.searchNode(
query,
props.filters,
{
suggestions.value = [
...(props.includeReroute
? [useNodeDefStore().nodeDefsByName['Reroute']]
: []),
...useNodeDefStore().nodeSearchService.searchNode(query, props.filters, {
limit: props.searchLimit
}
)
})
]
}
const highlightQuery = (text: string, query: string) => {
Expand Down
4 changes: 4 additions & 0 deletions src/components/searchbox/NodeSearchBoxPopover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<template #container>
<NodeSearchBox
:filters="nodeFilters"
:includeReroute="includeReroute"
@add-filter="addFilter"
@remove-filter="removeFilter"
@add-node="addNode"
Expand Down Expand Up @@ -61,6 +62,7 @@ const getNewNodeLocation = (): [number, number] => {
return [originalEvent.canvasX, originalEvent.canvasY]
}
const nodeFilters = reactive([])
const includeReroute = ref(false)
const addFilter = (filter: FilterAndValue) => {
nodeFilters.push(filter)
}
Expand Down Expand Up @@ -100,6 +102,7 @@ const linkReleaseTriggerMode = computed(() => {
})
const canvasEventHandler = (e: LiteGraphCanvasEvent) => {
includeReroute.value = false
const shiftPressed = (e.detail.originalEvent as KeyboardEvent).shiftKey
if (e.detail.subType === 'empty-release') {
Expand All @@ -123,6 +126,7 @@ const canvasEventHandler = (e: LiteGraphCanvasEvent) => {
)
const dataType = firstLink.type
addFilter([filter, dataType])
includeReroute.value = true
}
triggerEvent.value = e
visible.value = true
Expand Down
8 changes: 7 additions & 1 deletion src/services/nodeSearchService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@ export abstract class NodeFilter<FilterOptionT = string> {
public abstract getNodeOptions(node: ComfyNodeDefImpl): FilterOptionT[]

public matches(node: ComfyNodeDefImpl, value: FilterOptionT): boolean {
return this.getNodeOptions(node).includes(value)
if (value === '*') {
return true
}
const options = this.getNodeOptions(node)
return (
options.includes(value) || _.some(options, (option) => option === '*')
)
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/types/litegraphTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ export class ConnectingLinkImpl implements ConnectingLink {
const newNodeSlots =
this.releaseSlotType === 'output' ? newNode.outputs : newNode.inputs
const newNodeSlot = newNodeSlots.findIndex(
(slot: INodeSlot) => slot.type === this.type
(slot: INodeSlot) =>
slot.type === this.type || slot.type === '*' || this.type === '*'
)

if (newNodeSlot === -1) {
Expand Down
2 changes: 2 additions & 0 deletions tests-ui/tests/nodeSearchService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ describe('nodeSearchService', () => {
const service = new NodeSearchService(EXAMPLE_NODE_DEFS)
const inputFilter = service.getFilterById('input')
expect(service.searchNode('L', [[inputFilter, 'LATENT']])).toHaveLength(1)
// Wildcard should match all.
expect(service.searchNode('L', [[inputFilter, '*']])).toHaveLength(2)
expect(service.searchNode('L')).toHaveLength(2)
})
})

0 comments on commit 9cea546

Please sign in to comment.