From 995979a4e152d826602ba2b36b2c317470839316 Mon Sep 17 00:00:00 2001 From: duckcomfy Date: Wed, 11 Jun 2025 15:35:49 +0200 Subject: [PATCH 1/3] feat: add keyboard shortcut to move selected nodes (unbound by default) (#4066) Co-authored-by: duckcomfy Co-authored-by: filtered <176114999+webfiltered@users.noreply.github.com> --- browser_tests/fixtures/ComfyPage.ts | 9 ++-- browser_tests/tests/interaction.spec.ts | 71 +++++++++++++++++++++++-- src/composables/useCoreCommands.ts | 45 ++++++++++++++++ 3 files changed, 119 insertions(+), 6 deletions(-) diff --git a/browser_tests/fixtures/ComfyPage.ts b/browser_tests/fixtures/ComfyPage.ts index 2f6fc0b14..1c2fbd78c 100644 --- a/browser_tests/fixtures/ComfyPage.ts +++ b/browser_tests/fixtures/ComfyPage.ts @@ -762,7 +762,7 @@ export class ComfyPage { y: 625 } }) - this.page.mouse.move(10, 10) + await this.page.mouse.move(10, 10) await this.nextFrame() } @@ -774,7 +774,7 @@ export class ComfyPage { }, button: 'right' }) - this.page.mouse.move(10, 10) + await this.page.mouse.move(10, 10) await this.nextFrame() } @@ -1046,6 +1046,8 @@ export class ComfyPage { } } +export const testComfySnapToGridGridSize = 50 + export const comfyPageFixture = base.extend<{ comfyPage: ComfyPage comfyMouse: ComfyMouse @@ -1072,7 +1074,8 @@ export const comfyPageFixture = base.extend<{ 'Comfy.EnableTooltips': false, 'Comfy.userId': userId, // Set tutorial completed to true to avoid loading the tutorial workflow. - 'Comfy.TutorialCompleted': true + 'Comfy.TutorialCompleted': true, + 'Comfy.SnapToGrid.GridSize': testComfySnapToGridGridSize }) } catch (e) { console.error(e) diff --git a/browser_tests/tests/interaction.spec.ts b/browser_tests/tests/interaction.spec.ts index 552878a26..fc1b5e8e1 100644 --- a/browser_tests/tests/interaction.spec.ts +++ b/browser_tests/tests/interaction.spec.ts @@ -1,6 +1,12 @@ import { expect } from '@playwright/test' +import { Position } from '@vueuse/core' -import { type ComfyPage, comfyPageFixture as test } from '../fixtures/ComfyPage' +import { + type ComfyPage, + comfyPageFixture as test, + testComfySnapToGridGridSize +} from '../fixtures/ComfyPage' +import { type NodeReference } from '../fixtures/utils/litegraphUtils' test.describe('Item Interaction', () => { test('Can select/delete all items', async ({ comfyPage }) => { @@ -57,8 +63,10 @@ test.describe('Node Interaction', () => { await expect(comfyPage.canvas).toHaveScreenshot('selected-node2.png') }) - test('Can drag-select nodes with Meta (mac)', async ({ comfyPage }) => { - const clipNodes = await comfyPage.getNodeRefsByType('CLIPTextEncode') + const dragSelectNodes = async ( + comfyPage: ComfyPage, + clipNodes: NodeReference[] + ) => { const clipNode1Pos = await clipNodes[0].getPosition() const clipNode2Pos = await clipNodes[1].getPosition() const offset = 64 @@ -74,10 +82,67 @@ test.describe('Node Interaction', () => { } ) await comfyPage.page.keyboard.up('Meta') + } + + test('Can drag-select nodes with Meta (mac)', async ({ comfyPage }) => { + const clipNodes = await comfyPage.getNodeRefsByType('CLIPTextEncode') + await dragSelectNodes(comfyPage, clipNodes) expect(await comfyPage.getSelectedGraphNodesCount()).toBe( clipNodes.length ) }) + + test('Can move selected nodes using the Comfy.Canvas.MoveSelectedNodes.{Up|Down|Left|Right} commands', async ({ + comfyPage + }) => { + const clipNodes = await comfyPage.getNodeRefsByType('CLIPTextEncode') + const getPositions = () => + Promise.all(clipNodes.map((node) => node.getPosition())) + const testDirection = async ({ + direction, + expectedPosition + }: { + direction: string + expectedPosition: (originalPosition: Position) => Position + }) => { + const originalPositions = await getPositions() + await dragSelectNodes(comfyPage, clipNodes) + await comfyPage.executeCommand( + `Comfy.Canvas.MoveSelectedNodes.${direction}` + ) + await comfyPage.canvas.press(`Control+Arrow${direction}`) + const newPositions = await getPositions() + expect(newPositions).toEqual(originalPositions.map(expectedPosition)) + } + await testDirection({ + direction: 'Down', + expectedPosition: (originalPosition) => ({ + ...originalPosition, + y: originalPosition.y + testComfySnapToGridGridSize + }) + }) + await testDirection({ + direction: 'Right', + expectedPosition: (originalPosition) => ({ + ...originalPosition, + x: originalPosition.x + testComfySnapToGridGridSize + }) + }) + await testDirection({ + direction: 'Up', + expectedPosition: (originalPosition) => ({ + ...originalPosition, + y: originalPosition.y - testComfySnapToGridGridSize + }) + }) + await testDirection({ + direction: 'Left', + expectedPosition: (originalPosition) => ({ + ...originalPosition, + x: originalPosition.x - testComfySnapToGridGridSize + }) + }) + }) }) test('Can drag node', async ({ comfyPage }) => { diff --git a/src/composables/useCoreCommands.ts b/src/composables/useCoreCommands.ts index 46070dfe9..ac0ac4c17 100644 --- a/src/composables/useCoreCommands.ts +++ b/src/composables/useCoreCommands.ts @@ -4,6 +4,7 @@ import { LGraphNode, LiteGraph } from '@comfyorg/litegraph' +import { Point } from '@comfyorg/litegraph' import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions' import { @@ -27,6 +28,8 @@ import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore' import { useSearchBoxStore } from '@/stores/workspace/searchBoxStore' import { useWorkspaceStore } from '@/stores/workspaceStore' +const moveSelectedNodesVersionAdded = '1.22.2' + export function useCoreCommands(): ComfyCommand[] { const workflowService = useWorkflowService() const workflowStore = useWorkflowStore() @@ -58,6 +61,20 @@ export function useCoreCommands(): ComfyCommand[] { }) } + const moveSelectedNodes = ( + positionUpdater: (pos: Point, gridSize: number) => Point + ) => { + const selectedNodes = getSelectedNodes() + if (selectedNodes.length === 0) return + + const gridSize = useSettingStore().get('Comfy.SnapToGrid.GridSize') + selectedNodes.forEach((node) => { + node.pos = positionUpdater(node.pos, gridSize) + }) + app.canvas.state.selectionChanged = true + app.canvas.setDirty(true, true) + } + const commands = [ { id: 'Comfy.NewBlankWorkflow', @@ -673,6 +690,34 @@ export function useCoreCommands(): ComfyCommand[] { function: async () => { await firebaseAuthActions.logout() } + }, + { + id: 'Comfy.Canvas.MoveSelectedNodes.Up', + icon: 'pi pi-arrow-up', + label: 'Move Selected Nodes Up', + versionAdded: moveSelectedNodesVersionAdded, + function: () => moveSelectedNodes(([x, y], gridSize) => [x, y - gridSize]) + }, + { + id: 'Comfy.Canvas.MoveSelectedNodes.Down', + icon: 'pi pi-arrow-down', + label: 'Move Selected Nodes Down', + versionAdded: moveSelectedNodesVersionAdded, + function: () => moveSelectedNodes(([x, y], gridSize) => [x, y + gridSize]) + }, + { + id: 'Comfy.Canvas.MoveSelectedNodes.Left', + icon: 'pi pi-arrow-left', + label: 'Move Selected Nodes Left', + versionAdded: moveSelectedNodesVersionAdded, + function: () => moveSelectedNodes(([x, y], gridSize) => [x - gridSize, y]) + }, + { + id: 'Comfy.Canvas.MoveSelectedNodes.Right', + icon: 'pi pi-arrow-right', + label: 'Move Selected Nodes Right', + versionAdded: moveSelectedNodesVersionAdded, + function: () => moveSelectedNodes(([x, y], gridSize) => [x + gridSize, y]) } ] From a937ac59ad3c0f2c451a6668c23fe0b6dac3f384 Mon Sep 17 00:00:00 2001 From: Christian Byrne Date: Wed, 11 Jun 2025 06:41:35 -0700 Subject: [PATCH 2/3] Revert Algolia proxy changes (#4133) --- src/services/algoliaSearchService.ts | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/services/algoliaSearchService.ts b/src/services/algoliaSearchService.ts index 47fcd68db..5b306987a 100644 --- a/src/services/algoliaSearchService.ts +++ b/src/services/algoliaSearchService.ts @@ -124,19 +124,7 @@ export const useAlgoliaSearchService = ( maxCacheSize = DEFAULT_MAX_CACHE_SIZE, minCharsForSuggestions = DEFAULT_MIN_CHARS_FOR_SUGGESTIONS } = options - const searchClient = algoliasearch(__ALGOLIA_APP_ID__, __ALGOLIA_API_KEY__, { - hosts: [ - { - url: 'search.comfy.org/api/search', - accept: 'read', - protocol: 'https' - } - ], - baseHeaders: { - 'X-Algolia-Application-Id': __ALGOLIA_APP_ID__, - 'X-Algolia-API-Key': __ALGOLIA_API_KEY__ - } - }) + const searchClient = algoliasearch(__ALGOLIA_APP_ID__, __ALGOLIA_API_KEY__) const searchPacksCache = new QuickLRU({ maxSize: maxCacheSize }) From 9ca705381ca17ee4ebd9c7c044235da4c42ad47d Mon Sep 17 00:00:00 2001 From: Jin Yi Date: Fri, 13 Jun 2025 03:04:55 +0900 Subject: [PATCH 3/3] Update fallback banner layout (#4141) Co-authored-by: github-actions --- .../content/manager/packBanner/PackBanner.vue | 49 ++++++++++++++----- src/locales/en/commands.json | 12 +++++ src/locales/en/main.json | 4 ++ src/locales/es/commands.json | 12 +++++ src/locales/es/main.json | 4 ++ src/locales/fr/commands.json | 12 +++++ src/locales/fr/main.json | 4 ++ src/locales/ja/commands.json | 12 +++++ src/locales/ja/main.json | 4 ++ src/locales/ko/commands.json | 12 +++++ src/locales/ko/main.json | 4 ++ src/locales/ru/commands.json | 12 +++++ src/locales/ru/main.json | 4 ++ src/locales/zh/commands.json | 12 +++++ src/locales/zh/main.json | 4 ++ 15 files changed, 148 insertions(+), 13 deletions(-) diff --git a/src/components/dialog/content/manager/packBanner/PackBanner.vue b/src/components/dialog/content/manager/packBanner/PackBanner.vue index d7386cb54..f6b9e93cd 100644 --- a/src/components/dialog/content/manager/packBanner/PackBanner.vue +++ b/src/components/dialog/content/manager/packBanner/PackBanner.vue @@ -1,11 +1,37 @@