mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-17 19:07:32 +00:00
Compare commits
1 Commits
remove-flo
...
chore/incl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6afc2b62a7 |
@@ -67,9 +67,9 @@ This is critical for better file inspection:
|
||||
|
||||
Use git locally for much faster analysis:
|
||||
|
||||
1. Get list of changed files: `git diff --name-only "$BASE_SHA" > changed_files.txt`
|
||||
2. Get the full diff: `git diff "$BASE_SHA" > pr_diff.txt`
|
||||
3. Get detailed file changes with status: `git diff --name-status "$BASE_SHA" > file_changes.txt`
|
||||
1. Get list of changed files: `git diff --name-only "origin/$BASE_BRANCH" > changed_files.txt`
|
||||
2. Get the full diff: `git diff "origin/$BASE_BRANCH" > pr_diff.txt`
|
||||
3. Get detailed file changes with status: `git diff --name-status "origin/$BASE_BRANCH" > file_changes.txt`
|
||||
|
||||
### Step 1.5: Create Analysis Cache
|
||||
|
||||
|
||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -13,4 +13,4 @@
|
||||
|
||||
# Generated files
|
||||
src/types/comfyRegistryTypes.ts linguist-generated=true
|
||||
src/workbench/extensions/manager/types/generatedManagerTypes.ts linguist-generated=true
|
||||
src/types/generatedManagerTypes.ts linguist-generated=true
|
||||
|
||||
109
.github/workflows/backport.yaml
vendored
109
.github/workflows/backport.yaml
vendored
@@ -4,25 +4,10 @@ on:
|
||||
pull_request_target:
|
||||
types: [closed, labeled]
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pr_number:
|
||||
description: 'PR number to backport'
|
||||
required: true
|
||||
type: string
|
||||
force_rerun:
|
||||
description: 'Force rerun even if backports exist'
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
backport:
|
||||
if: >
|
||||
(github.event_name == 'pull_request_target' &&
|
||||
github.event.pull_request.merged == true &&
|
||||
contains(github.event.pull_request.labels.*.name, 'needs-backport')) ||
|
||||
github.event_name == 'workflow_dispatch'
|
||||
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'needs-backport')
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -30,35 +15,6 @@ jobs:
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- name: Validate inputs for manual triggers
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
run: |
|
||||
# Validate PR number format
|
||||
if ! [[ "${{ inputs.pr_number }}" =~ ^[0-9]+$ ]]; then
|
||||
echo "::error::Invalid PR number format. Must be a positive integer."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate PR exists and is merged
|
||||
if ! gh pr view "${{ inputs.pr_number }}" --json merged >/dev/null 2>&1; then
|
||||
echo "::error::PR #${{ inputs.pr_number }} not found or inaccessible."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MERGED=$(gh pr view "${{ inputs.pr_number }}" --json merged --jq '.merged')
|
||||
if [ "$MERGED" != "true" ]; then
|
||||
echo "::error::PR #${{ inputs.pr_number }} is not merged. Only merged PRs can be backported."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate PR has needs-backport label
|
||||
if ! gh pr view "${{ inputs.pr_number }}" --json labels --jq '.labels[].name' | grep -q "needs-backport"; then
|
||||
echo "::error::PR #${{ inputs.pr_number }} does not have 'needs-backport' label."
|
||||
exit 1
|
||||
fi
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -73,7 +29,7 @@ jobs:
|
||||
id: check-existing
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event_name == 'workflow_dispatch' && inputs.pr_number || github.event.pull_request.number }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
run: |
|
||||
# Check for existing backport PRs for this PR number
|
||||
EXISTING_BACKPORTS=$(gh pr list --state all --search "backport-${PR_NUMBER}-to" --json title,headRefName,baseRefName | jq -r '.[].headRefName')
|
||||
@@ -83,13 +39,6 @@ jobs:
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# For manual triggers with force_rerun, proceed anyway
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.force_rerun }}" = "true" ]; then
|
||||
echo "skip=false" >> $GITHUB_OUTPUT
|
||||
echo "::warning::Force rerun requested - existing backports will be updated"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Found existing backport PRs:"
|
||||
echo "$EXISTING_BACKPORTS"
|
||||
echo "skip=true" >> $GITHUB_OUTPUT
|
||||
@@ -101,17 +50,8 @@ jobs:
|
||||
run: |
|
||||
# Extract version labels (e.g., "1.24", "1.22")
|
||||
VERSIONS=""
|
||||
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
# For manual triggers, get labels from the PR
|
||||
LABELS=$(gh pr view ${{ inputs.pr_number }} --json labels | jq -r '.labels[].name')
|
||||
else
|
||||
# For automatic triggers, extract from PR event
|
||||
LABELS='${{ toJSON(github.event.pull_request.labels) }}'
|
||||
LABELS=$(echo "$LABELS" | jq -r '.[].name')
|
||||
fi
|
||||
|
||||
for label in $LABELS; do
|
||||
LABELS='${{ toJSON(github.event.pull_request.labels) }}'
|
||||
for label in $(echo "$LABELS" | jq -r '.[].name'); do
|
||||
# Match version labels like "1.24" (major.minor only)
|
||||
if [[ "$label" =~ ^[0-9]+\.[0-9]+$ ]]; then
|
||||
# Validate the branch exists before adding to list
|
||||
@@ -135,20 +75,12 @@ jobs:
|
||||
if: steps.check-existing.outputs.skip != 'true'
|
||||
id: backport
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event_name == 'workflow_dispatch' && inputs.pr_number || github.event.pull_request.number }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
MERGE_COMMIT: ${{ github.event.pull_request.merge_commit_sha }}
|
||||
run: |
|
||||
FAILED=""
|
||||
SUCCESS=""
|
||||
|
||||
# Get PR data for manual triggers
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
PR_DATA=$(gh pr view ${{ inputs.pr_number }} --json title,mergeCommit)
|
||||
PR_TITLE=$(echo "$PR_DATA" | jq -r '.title')
|
||||
MERGE_COMMIT=$(echo "$PR_DATA" | jq -r '.mergeCommit.oid')
|
||||
else
|
||||
PR_TITLE="${{ github.event.pull_request.title }}"
|
||||
MERGE_COMMIT="${{ github.event.pull_request.merge_commit_sha }}"
|
||||
fi
|
||||
|
||||
for version in ${{ steps.versions.outputs.versions }}; do
|
||||
echo "::group::Backporting to core/${version}"
|
||||
@@ -201,18 +133,10 @@ jobs:
|
||||
if: steps.check-existing.outputs.skip != 'true' && steps.backport.outputs.success
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.PR_GH_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event_name == 'workflow_dispatch' && inputs.pr_number || github.event.pull_request.number }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
|
||||
run: |
|
||||
# Get PR data for manual triggers
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
PR_DATA=$(gh pr view ${{ inputs.pr_number }} --json title,author)
|
||||
PR_TITLE=$(echo "$PR_DATA" | jq -r '.title')
|
||||
PR_AUTHOR=$(echo "$PR_DATA" | jq -r '.author.login')
|
||||
else
|
||||
PR_TITLE="${{ github.event.pull_request.title }}"
|
||||
PR_AUTHOR="${{ github.event.pull_request.user.login }}"
|
||||
fi
|
||||
|
||||
for backport in ${{ steps.backport.outputs.success }}; do
|
||||
IFS=':' read -r version branch <<< "${backport}"
|
||||
|
||||
@@ -241,16 +165,9 @@ jobs:
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
PR_DATA=$(gh pr view ${{ inputs.pr_number }} --json author,mergeCommit)
|
||||
PR_NUMBER="${{ inputs.pr_number }}"
|
||||
PR_AUTHOR=$(echo "$PR_DATA" | jq -r '.author.login')
|
||||
MERGE_COMMIT=$(echo "$PR_DATA" | jq -r '.mergeCommit.oid')
|
||||
else
|
||||
PR_NUMBER="${{ github.event.pull_request.number }}"
|
||||
PR_AUTHOR="${{ github.event.pull_request.user.login }}"
|
||||
MERGE_COMMIT="${{ github.event.pull_request.merge_commit_sha }}"
|
||||
fi
|
||||
PR_NUMBER="${{ github.event.pull_request.number }}"
|
||||
PR_AUTHOR="${{ github.event.pull_request.user.login }}"
|
||||
MERGE_COMMIT="${{ github.event.pull_request.merge_commit_sha }}"
|
||||
|
||||
for failure in ${{ steps.backport.outputs.failed }}; do
|
||||
IFS=':' read -r version reason conflicts <<< "${failure}"
|
||||
|
||||
@@ -9,7 +9,7 @@ module.exports = defineConfig({
|
||||
entry: 'src/locales/en',
|
||||
entryLocale: 'en',
|
||||
output: 'src/locales',
|
||||
outputLocales: ['zh', 'zh-TW', 'ru', 'ja', 'ko', 'fr', 'es', 'ar', 'tr'],
|
||||
outputLocales: ['zh', 'zh-TW', 'ru', 'ja', 'ko', 'fr', 'es', 'ar'],
|
||||
reference: `Special names to keep untranslated: flux, photomaker, clip, vae, cfg, stable audio, stable cascade, stable zero, controlnet, lora, HiDream.
|
||||
'latent' is the short form of 'latent space'.
|
||||
'mask' is in the context of image processing.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
{"id":"4412323e-2509-4258-8abc-68ddeea8f9e1","revision":0,"last_node_id":39,"last_link_id":29,"nodes":[{"id":37,"type":"KSampler","pos":[3635.923095703125,870.237548828125],"size":[428,437],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":null},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":null},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":null},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":null},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null},{"localized_name":"cfg","name":"cfg","type":"FLOAT","widget":{"name":"cfg"},"link":null},{"localized_name":"sampler_name","name":"sampler_name","type":"COMBO","widget":{"name":"sampler_name"},"link":null},{"localized_name":"scheduler","name":"scheduler","type":"COMBO","widget":{"name":"scheduler"},"link":null},{"localized_name":"denoise","name":"denoise","type":"FLOAT","widget":{"name":"denoise"},"link":null}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","links":null}],"properties":{"Node name for S&R":"KSampler"},"widgets_values":[0,"randomize",20,8,"euler","simple",1]},{"id":38,"type":"VAEDecode","pos":[4164.01611328125,925.5230712890625],"size":[193.25,107],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":null},{"localized_name":"vae","name":"vae","type":"VAE","link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":null}],"properties":{"Node name for S&R":"VAEDecode"}},{"id":39,"type":"CLIPTextEncode","pos":[3259.289794921875,927.2508544921875],"size":[239.9375,155],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":null},{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":null}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":null}],"properties":{"Node name for S&R":"CLIPTextEncode"},"widgets_values":[""]}],"links":[],"groups":[],"config":{},"extra":{"ds":{"scale":1.1576250000000001,"offset":[-2808.366467322067,-478.34316506594797]}},"version":0.4}
|
||||
@@ -1,104 +0,0 @@
|
||||
import type { ReadOnlyRect } from '../../src/lib/litegraph/src/interfaces'
|
||||
import type { ComfyPage } from '../fixtures/ComfyPage'
|
||||
|
||||
interface FitToViewOptions {
|
||||
selectionOnly?: boolean
|
||||
zoom?: number
|
||||
padding?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantly fits the canvas view to graph content without waiting for UI animation.
|
||||
*
|
||||
* Lives outside the shared fixture to keep the default ComfyPage interactions user-oriented.
|
||||
*/
|
||||
export async function fitToViewInstant(
|
||||
comfyPage: ComfyPage,
|
||||
options: FitToViewOptions = {}
|
||||
) {
|
||||
const { selectionOnly = false, zoom = 0.75, padding = 10 } = options
|
||||
|
||||
const rectangles = await comfyPage.page.evaluate<
|
||||
ReadOnlyRect[] | null,
|
||||
{ selectionOnly: boolean }
|
||||
>(
|
||||
({ selectionOnly }) => {
|
||||
const app = window['app']
|
||||
if (!app?.canvas) return null
|
||||
|
||||
const canvas = app.canvas
|
||||
const items = (() => {
|
||||
if (selectionOnly && canvas.selectedItems?.size) {
|
||||
return Array.from(canvas.selectedItems)
|
||||
}
|
||||
try {
|
||||
return Array.from(canvas.positionableItems ?? [])
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
})()
|
||||
|
||||
if (!items.length) return null
|
||||
|
||||
const rects: ReadOnlyRect[] = []
|
||||
|
||||
for (const item of items) {
|
||||
const rect = item?.boundingRect
|
||||
if (!rect) continue
|
||||
|
||||
const x = Number(rect[0])
|
||||
const y = Number(rect[1])
|
||||
const width = Number(rect[2])
|
||||
const height = Number(rect[3])
|
||||
|
||||
rects.push([x, y, width, height] as const)
|
||||
}
|
||||
|
||||
return rects.length ? rects : null
|
||||
},
|
||||
{ selectionOnly }
|
||||
)
|
||||
|
||||
if (!rectangles || rectangles.length === 0) return
|
||||
|
||||
let minX = Infinity
|
||||
let minY = Infinity
|
||||
let maxX = -Infinity
|
||||
let maxY = -Infinity
|
||||
|
||||
for (const [x, y, width, height] of rectangles) {
|
||||
minX = Math.min(minX, Number(x))
|
||||
minY = Math.min(minY, Number(y))
|
||||
maxX = Math.max(maxX, Number(x) + Number(width))
|
||||
maxY = Math.max(maxY, Number(y) + Number(height))
|
||||
}
|
||||
|
||||
const hasFiniteBounds =
|
||||
Number.isFinite(minX) &&
|
||||
Number.isFinite(minY) &&
|
||||
Number.isFinite(maxX) &&
|
||||
Number.isFinite(maxY)
|
||||
|
||||
if (!hasFiniteBounds) return
|
||||
|
||||
const bounds: ReadOnlyRect = [
|
||||
minX - padding,
|
||||
minY - padding,
|
||||
maxX - minX + 2 * padding,
|
||||
maxY - minY + 2 * padding
|
||||
]
|
||||
|
||||
await comfyPage.page.evaluate(
|
||||
({ bounds, zoom }) => {
|
||||
const app = window['app']
|
||||
if (!app?.canvas) return
|
||||
|
||||
const canvas = app.canvas
|
||||
canvas.ds.fitToBounds(bounds, { zoom })
|
||||
canvas.setDirty(true, true)
|
||||
},
|
||||
{ bounds, zoom }
|
||||
)
|
||||
|
||||
await comfyPage.nextFrame()
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import { VueNodeFixture } from '../../fixtures/utils/vueNodeFixtures'
|
||||
|
||||
test.describe('NodeHeader', () => {
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
await comfyPage.setSetting('Comfy.UseNewMenu', 'Top')
|
||||
await comfyPage.setSetting('Comfy.UseNewMenu', 'Enabled')
|
||||
await comfyPage.setSetting('Comfy.Graph.CanvasMenu', false)
|
||||
await comfyPage.setSetting('Comfy.EnableTooltips', true)
|
||||
await comfyPage.setSetting('Comfy.VueNodes.Enabled', true)
|
||||
|
||||
@@ -1,221 +0,0 @@
|
||||
import type { Locator } from '@playwright/test'
|
||||
|
||||
import { getSlotKey } from '../../../src/renderer/core/layout/slots/slotIdentifier'
|
||||
import {
|
||||
comfyExpect as expect,
|
||||
comfyPageFixture as test
|
||||
} from '../../fixtures/ComfyPage'
|
||||
import { fitToViewInstant } from '../../helpers/fitToView'
|
||||
|
||||
async function getCenter(locator: Locator): Promise<{ x: number; y: number }> {
|
||||
const box = await locator.boundingBox()
|
||||
if (!box) throw new Error('Slot bounding box not available')
|
||||
return {
|
||||
x: box.x + box.width / 2,
|
||||
y: box.y + box.height / 2
|
||||
}
|
||||
}
|
||||
|
||||
test.describe('Vue Node Link Interaction', () => {
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
await comfyPage.setSetting('Comfy.UseNewMenu', 'Top')
|
||||
await comfyPage.setSetting('Comfy.VueNodes.Enabled', true)
|
||||
await comfyPage.setup()
|
||||
await comfyPage.loadWorkflow('vueNodes/simple-triple')
|
||||
await comfyPage.vueNodes.waitForNodes()
|
||||
await fitToViewInstant(comfyPage)
|
||||
})
|
||||
|
||||
test('should show a link dragging out from a slot when dragging on a slot', async ({
|
||||
comfyPage,
|
||||
comfyMouse
|
||||
}) => {
|
||||
const samplerNodes = await comfyPage.getNodeRefsByType('KSampler')
|
||||
expect(samplerNodes.length).toBeGreaterThan(0)
|
||||
|
||||
const samplerNode = samplerNodes[0]
|
||||
const outputSlot = await samplerNode.getOutput(0)
|
||||
await outputSlot.removeLinks()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
const slotKey = getSlotKey(String(samplerNode.id), 0, false)
|
||||
const slotLocator = comfyPage.page.locator(`[data-slot-key="${slotKey}"]`)
|
||||
await expect(slotLocator).toBeVisible()
|
||||
|
||||
const start = await getCenter(slotLocator)
|
||||
const canvasBox = await comfyPage.canvas.boundingBox()
|
||||
if (!canvasBox) throw new Error('Canvas bounding box not available')
|
||||
|
||||
// Arbitrary value
|
||||
const dragTarget = {
|
||||
x: start.x + 180,
|
||||
y: start.y - 140
|
||||
}
|
||||
|
||||
await comfyMouse.move(start)
|
||||
await comfyMouse.drag(dragTarget)
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
try {
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'vue-node-dragging-link.png'
|
||||
)
|
||||
} finally {
|
||||
await comfyMouse.drop()
|
||||
}
|
||||
})
|
||||
|
||||
test('should create a link when dropping on a compatible slot', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const samplerNodes = await comfyPage.getNodeRefsByType('KSampler')
|
||||
expect(samplerNodes.length).toBeGreaterThan(0)
|
||||
const samplerNode = samplerNodes[0]
|
||||
|
||||
const vaeNodes = await comfyPage.getNodeRefsByType('VAEDecode')
|
||||
expect(vaeNodes.length).toBeGreaterThan(0)
|
||||
const vaeNode = vaeNodes[0]
|
||||
|
||||
const samplerOutput = await samplerNode.getOutput(0)
|
||||
const vaeInput = await vaeNode.getInput(0)
|
||||
|
||||
const outputSlotKey = getSlotKey(String(samplerNode.id), 0, false)
|
||||
const inputSlotKey = getSlotKey(String(vaeNode.id), 0, true)
|
||||
|
||||
const outputSlot = comfyPage.page.locator(
|
||||
`[data-slot-key="${outputSlotKey}"]`
|
||||
)
|
||||
const inputSlot = comfyPage.page.locator(
|
||||
`[data-slot-key="${inputSlotKey}"]`
|
||||
)
|
||||
|
||||
await expect(outputSlot).toBeVisible()
|
||||
await expect(inputSlot).toBeVisible()
|
||||
|
||||
await outputSlot.dragTo(inputSlot)
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
expect(await samplerOutput.getLinkCount()).toBe(1)
|
||||
expect(await vaeInput.getLinkCount()).toBe(1)
|
||||
|
||||
const linkDetails = await comfyPage.page.evaluate((sourceId) => {
|
||||
const app = window['app']
|
||||
const graph = app?.canvas?.graph ?? app?.graph
|
||||
if (!graph) return null
|
||||
|
||||
const source = graph.getNodeById(sourceId)
|
||||
if (!source) return null
|
||||
|
||||
const linkId = source.outputs[0]?.links?.[0]
|
||||
if (linkId == null) return null
|
||||
|
||||
const link = graph.links[linkId]
|
||||
if (!link) return null
|
||||
|
||||
return {
|
||||
originId: link.origin_id,
|
||||
originSlot: link.origin_slot,
|
||||
targetId: link.target_id,
|
||||
targetSlot: link.target_slot
|
||||
}
|
||||
}, samplerNode.id)
|
||||
|
||||
expect(linkDetails).not.toBeNull()
|
||||
expect(linkDetails).toMatchObject({
|
||||
originId: samplerNode.id,
|
||||
originSlot: 0,
|
||||
targetId: vaeNode.id,
|
||||
targetSlot: 0
|
||||
})
|
||||
})
|
||||
|
||||
test('should not create a link when slot types are incompatible', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const samplerNodes = await comfyPage.getNodeRefsByType('KSampler')
|
||||
expect(samplerNodes.length).toBeGreaterThan(0)
|
||||
const samplerNode = samplerNodes[0]
|
||||
|
||||
const clipNodes = await comfyPage.getNodeRefsByType('CLIPTextEncode')
|
||||
expect(clipNodes.length).toBeGreaterThan(0)
|
||||
const clipNode = clipNodes[0]
|
||||
|
||||
const samplerOutput = await samplerNode.getOutput(0)
|
||||
const clipInput = await clipNode.getInput(0)
|
||||
|
||||
const outputSlotKey = getSlotKey(String(samplerNode.id), 0, false)
|
||||
const inputSlotKey = getSlotKey(String(clipNode.id), 0, true)
|
||||
|
||||
const outputSlot = comfyPage.page.locator(
|
||||
`[data-slot-key="${outputSlotKey}"]`
|
||||
)
|
||||
const inputSlot = comfyPage.page.locator(
|
||||
`[data-slot-key="${inputSlotKey}"]`
|
||||
)
|
||||
|
||||
await expect(outputSlot).toBeVisible()
|
||||
await expect(inputSlot).toBeVisible()
|
||||
|
||||
await outputSlot.dragTo(inputSlot)
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
expect(await samplerOutput.getLinkCount()).toBe(0)
|
||||
expect(await clipInput.getLinkCount()).toBe(0)
|
||||
|
||||
const graphLinkCount = await comfyPage.page.evaluate((sourceId) => {
|
||||
const app = window['app']
|
||||
const graph = app?.canvas?.graph ?? app?.graph
|
||||
if (!graph) return 0
|
||||
|
||||
const source = graph.getNodeById(sourceId)
|
||||
if (!source) return 0
|
||||
|
||||
return source.outputs[0]?.links?.length ?? 0
|
||||
}, samplerNode.id)
|
||||
|
||||
expect(graphLinkCount).toBe(0)
|
||||
})
|
||||
|
||||
test('should not create a link when dropping onto a slot on the same node', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const samplerNodes = await comfyPage.getNodeRefsByType('KSampler')
|
||||
expect(samplerNodes.length).toBeGreaterThan(0)
|
||||
const samplerNode = samplerNodes[0]
|
||||
|
||||
const samplerOutput = await samplerNode.getOutput(0)
|
||||
const samplerInput = await samplerNode.getInput(3)
|
||||
|
||||
const outputSlotKey = getSlotKey(String(samplerNode.id), 0, false)
|
||||
const inputSlotKey = getSlotKey(String(samplerNode.id), 3, true)
|
||||
|
||||
const outputSlot = comfyPage.page.locator(
|
||||
`[data-slot-key="${outputSlotKey}"]`
|
||||
)
|
||||
const inputSlot = comfyPage.page.locator(
|
||||
`[data-slot-key="${inputSlotKey}"]`
|
||||
)
|
||||
|
||||
await expect(outputSlot).toBeVisible()
|
||||
await expect(inputSlot).toBeVisible()
|
||||
|
||||
await outputSlot.dragTo(inputSlot)
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
expect(await samplerOutput.getLinkCount()).toBe(0)
|
||||
expect(await samplerInput.getLinkCount()).toBe(0)
|
||||
|
||||
const graphLinkCount = await comfyPage.page.evaluate((sourceId) => {
|
||||
const app = window['app']
|
||||
const graph = app?.canvas?.graph ?? app?.graph
|
||||
if (!graph) return 0
|
||||
|
||||
const source = graph.getNodeById(sourceId)
|
||||
if (!source) return 0
|
||||
|
||||
return source.outputs[0]?.links?.length ?? 0
|
||||
}, samplerNode.id)
|
||||
|
||||
expect(graphLinkCount).toBe(0)
|
||||
})
|
||||
})
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 53 KiB |
@@ -1,5 +1,5 @@
|
||||
import path from 'path'
|
||||
import type { Plugin } from 'vite'
|
||||
import { Plugin } from 'vite'
|
||||
|
||||
interface ShimResult {
|
||||
code: string
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import glob from 'fast-glob'
|
||||
import fs from 'fs-extra'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { type HtmlTagDescriptor, type Plugin, normalizePath } from 'vite'
|
||||
import { HtmlTagDescriptor, Plugin, normalizePath } from 'vite'
|
||||
|
||||
interface ImportMapSource {
|
||||
name: string
|
||||
|
||||
@@ -22,7 +22,7 @@ const config: KnipConfig = {
|
||||
],
|
||||
ignore: [
|
||||
// Auto generated manager types
|
||||
'src/workbench/extensions/manager/types/generatedManagerTypes.ts',
|
||||
'src/types/generatedManagerTypes.ts',
|
||||
'src/types/comfyRegistryTypes.ts',
|
||||
// Used by a custom node (that should move off of this)
|
||||
'src/scripts/ui/components/splitButton.ts',
|
||||
|
||||
@@ -59,13 +59,14 @@ import { useI18n } from 'vue-i18n'
|
||||
import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
|
||||
import MissingCoreNodesMessage from '@/components/dialog/content/MissingCoreNodesMessage.vue'
|
||||
import { useMissingNodes } from '@/composables/nodePack/useMissingNodes'
|
||||
import { useManagerState } from '@/composables/useManagerState'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
import type { MissingNodeType } from '@/types/comfy'
|
||||
import PackInstallButton from '@/workbench/extensions/manager/components/manager/button/PackInstallButton.vue'
|
||||
import { useManagerState } from '@/workbench/extensions/manager/composables/useManagerState'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
import { ManagerTab } from '@/types/comfyManagerTypes'
|
||||
|
||||
import PackInstallButton from './manager/button/PackInstallButton.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
missingNodeTypes: MissingNodeType[]
|
||||
@@ -137,7 +138,7 @@ const allMissingNodesInstalled = computed(() => {
|
||||
})
|
||||
// Watch for completion and close dialog
|
||||
watch(allMissingNodesInstalled, async (allInstalled) => {
|
||||
if (allInstalled && showInstallAllButton.value) {
|
||||
if (allInstalled) {
|
||||
// Use nextTick to ensure state updates are complete
|
||||
await nextTick()
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ const defaultMockTaskLogs = [
|
||||
{ taskName: 'Task 2', logs: ['Log 3', 'Log 4'] }
|
||||
]
|
||||
|
||||
vi.mock('@/workbench/extensions/manager/stores/comfyManagerStore', () => ({
|
||||
vi.mock('@/stores/comfyManagerStore', () => ({
|
||||
useComfyManagerStore: vi.fn(() => ({
|
||||
taskLogs: [...defaultMockTaskLogs],
|
||||
succeededTasksLogs: [...defaultMockTaskLogs],
|
||||
@@ -88,7 +88,7 @@ import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import {
|
||||
useComfyManagerStore,
|
||||
useManagerProgressDialogStore
|
||||
} from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
} from '@/stores/comfyManagerStore'
|
||||
|
||||
const comfyManagerStore = useComfyManagerStore()
|
||||
const progressDialogContent = useManagerProgressDialogStore()
|
||||
@@ -43,11 +43,11 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import Message from 'primevue/message'
|
||||
import { compare } from 'semver'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { useSystemStatsStore } from '@/stores/systemStatsStore'
|
||||
import { compareVersions } from '@/utils/formatUtil'
|
||||
|
||||
const props = defineProps<{
|
||||
missingCoreNodes: Record<string, LGraphNode[]>
|
||||
@@ -68,7 +68,7 @@ const currentComfyUIVersion = computed<string | null>(() => {
|
||||
const sortedMissingCoreNodes = computed(() => {
|
||||
return Object.entries(props.missingCoreNodes).sort(([a], [b]) => {
|
||||
// Sort by version in descending order (newest first)
|
||||
return compare(b, a) // Reversed for descending order
|
||||
return compareVersions(b, a) // Reversed for descending order
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -143,24 +143,24 @@ import IconButton from '@/components/button/IconButton.vue'
|
||||
import ContentDivider from '@/components/common/ContentDivider.vue'
|
||||
import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
|
||||
import VirtualGrid from '@/components/common/VirtualGrid.vue'
|
||||
import ManagerNavSidebar from '@/components/dialog/content/manager/ManagerNavSidebar.vue'
|
||||
import InfoPanel from '@/components/dialog/content/manager/infoPanel/InfoPanel.vue'
|
||||
import InfoPanelMultiItem from '@/components/dialog/content/manager/infoPanel/InfoPanelMultiItem.vue'
|
||||
import PackCard from '@/components/dialog/content/manager/packCard/PackCard.vue'
|
||||
import RegistrySearchBar from '@/components/dialog/content/manager/registrySearchBar/RegistrySearchBar.vue'
|
||||
import GridSkeleton from '@/components/dialog/content/manager/skeleton/GridSkeleton.vue'
|
||||
import { useResponsiveCollapse } from '@/composables/element/useResponsiveCollapse'
|
||||
import { useManagerStatePersistence } from '@/composables/manager/useManagerStatePersistence'
|
||||
import { useInstalledPacks } from '@/composables/nodePack/useInstalledPacks'
|
||||
import { usePackUpdateStatus } from '@/composables/nodePack/usePackUpdateStatus'
|
||||
import { useWorkflowPacks } from '@/composables/nodePack/useWorkflowPacks'
|
||||
import { useConflictAcknowledgment } from '@/composables/useConflictAcknowledgment'
|
||||
import { useRegistrySearch } from '@/composables/useRegistrySearch'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import { useComfyRegistryStore } from '@/stores/comfyRegistryStore'
|
||||
import type { TabItem } from '@/types/comfyManagerTypes'
|
||||
import { ManagerTab } from '@/types/comfyManagerTypes'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import ManagerNavSidebar from '@/workbench/extensions/manager/components/manager/ManagerNavSidebar.vue'
|
||||
import InfoPanel from '@/workbench/extensions/manager/components/manager/infoPanel/InfoPanel.vue'
|
||||
import InfoPanelMultiItem from '@/workbench/extensions/manager/components/manager/infoPanel/InfoPanelMultiItem.vue'
|
||||
import PackCard from '@/workbench/extensions/manager/components/manager/packCard/PackCard.vue'
|
||||
import RegistrySearchBar from '@/workbench/extensions/manager/components/manager/registrySearchBar/RegistrySearchBar.vue'
|
||||
import GridSkeleton from '@/workbench/extensions/manager/components/manager/skeleton/GridSkeleton.vue'
|
||||
import { useManagerStatePersistence } from '@/workbench/extensions/manager/composables/useManagerStatePersistence'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import type { TabItem } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
import { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
|
||||
const { initialTab } = defineProps<{
|
||||
initialTab?: ManagerTab
|
||||
82
src/components/dialog/content/manager/ManagerHeader.test.ts
Normal file
82
src/components/dialog/content/manager/ManagerHeader.test.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { createPinia } from 'pinia'
|
||||
import PrimeVue from 'primevue/config'
|
||||
import Tag from 'primevue/tag'
|
||||
import Tooltip from 'primevue/tooltip'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
|
||||
import enMessages from '@/locales/en/main.json' with { type: 'json' }
|
||||
|
||||
import ManagerHeader from './ManagerHeader.vue'
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
messages: {
|
||||
en: enMessages
|
||||
}
|
||||
})
|
||||
|
||||
describe('ManagerHeader', () => {
|
||||
const createWrapper = () => {
|
||||
return mount(ManagerHeader, {
|
||||
global: {
|
||||
plugins: [createPinia(), PrimeVue, i18n],
|
||||
directives: {
|
||||
tooltip: Tooltip
|
||||
},
|
||||
components: {
|
||||
Tag
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
it('renders the component title', () => {
|
||||
const wrapper = createWrapper()
|
||||
|
||||
expect(wrapper.find('h2').text()).toBe(
|
||||
enMessages.manager.discoverCommunityContent
|
||||
)
|
||||
})
|
||||
|
||||
it('displays the legacy manager UI tag', () => {
|
||||
const wrapper = createWrapper()
|
||||
|
||||
const tag = wrapper.find('[data-pc-name="tag"]')
|
||||
expect(tag.exists()).toBe(true)
|
||||
expect(tag.text()).toContain(enMessages.manager.legacyManagerUI)
|
||||
})
|
||||
|
||||
it('applies info severity to the tag', () => {
|
||||
const wrapper = createWrapper()
|
||||
|
||||
const tag = wrapper.find('[data-pc-name="tag"]')
|
||||
expect(tag.classes()).toContain('p-tag-info')
|
||||
})
|
||||
|
||||
it('displays info icon in the tag', () => {
|
||||
const wrapper = createWrapper()
|
||||
|
||||
const icon = wrapper.find('.pi-info-circle')
|
||||
expect(icon.exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has cursor-help class on the tag', () => {
|
||||
const wrapper = createWrapper()
|
||||
|
||||
const tag = wrapper.find('[data-pc-name="tag"]')
|
||||
expect(tag.classes()).toContain('cursor-help')
|
||||
})
|
||||
|
||||
it('has proper structure with flex container', () => {
|
||||
const wrapper = createWrapper()
|
||||
|
||||
const flexContainer = wrapper.find('.flex.justify-end.ml-auto.pr-4')
|
||||
expect(flexContainer.exists()).toBe(true)
|
||||
|
||||
const tag = flexContainer.find('[data-pc-name="tag"]')
|
||||
expect(tag.exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
25
src/components/dialog/content/manager/ManagerHeader.vue
Normal file
25
src/components/dialog/content/manager/ManagerHeader.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<div class="flex items-center">
|
||||
<h2 class="text-lg font-normal text-left">
|
||||
{{ $t('manager.discoverCommunityContent') }}
|
||||
</h2>
|
||||
<div class="flex justify-end ml-auto pr-4 pl-2">
|
||||
<Tag
|
||||
v-tooltip.left="$t('manager.legacyManagerUIDescription')"
|
||||
severity="info"
|
||||
icon="pi pi-info-circle"
|
||||
:value="$t('manager.legacyManagerUI')"
|
||||
class="cursor-help ml-2"
|
||||
:pt="{
|
||||
root: { class: 'text-xs' }
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Tag from 'primevue/tag'
|
||||
</script>
|
||||
@@ -32,7 +32,7 @@ import Listbox from 'primevue/listbox'
|
||||
import ScrollPanel from 'primevue/scrollpanel'
|
||||
|
||||
import ContentDivider from '@/components/common/ContentDivider.vue'
|
||||
import type { TabItem } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
import type { TabItem } from '@/types/comfyManagerTypes'
|
||||
|
||||
defineProps<{
|
||||
tabs: TabItem[]
|
||||
@@ -35,7 +35,7 @@ const mockInstalledPacks = {
|
||||
|
||||
const mockIsPackEnabled = vi.fn(() => true)
|
||||
|
||||
vi.mock('@/workbench/extensions/manager/stores/comfyManagerStore', () => ({
|
||||
vi.mock('@/stores/comfyManagerStore', () => ({
|
||||
useComfyManagerStore: vi.fn(() => ({
|
||||
installedPacks: mockInstalledPacks,
|
||||
isPackInstalled: (id: string) =>
|
||||
@@ -43,13 +43,13 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import Popover from 'primevue/popover'
|
||||
import { valid as validSemver } from 'semver'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
import PackVersionSelectorPopover from '@/components/dialog/content/manager/PackVersionSelectorPopover.vue'
|
||||
import { usePackUpdateStatus } from '@/composables/nodePack/usePackUpdateStatus'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import PackVersionSelectorPopover from '@/workbench/extensions/manager/components/manager/PackVersionSelectorPopover.vue'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import { isSemVer } from '@/utils/formatUtil'
|
||||
|
||||
const TRUNCATED_HASH_LENGTH = 7
|
||||
|
||||
@@ -81,9 +81,7 @@ const installedVersion = computed(() => {
|
||||
'nightly'
|
||||
|
||||
// If Git hash, truncate to 7 characters
|
||||
return validSemver(version)
|
||||
? version
|
||||
: version.slice(0, TRUNCATED_HASH_LENGTH)
|
||||
return isSemVer(version) ? version : version.slice(0, TRUNCATED_HASH_LENGTH)
|
||||
})
|
||||
|
||||
const toggleVersionSelector = (event: Event) => {
|
||||
@@ -64,7 +64,7 @@ vi.mock('@/services/comfyRegistryService', () => ({
|
||||
}))
|
||||
|
||||
// Mock the manager store
|
||||
vi.mock('@/workbench/extensions/manager/stores/comfyManagerStore', () => ({
|
||||
vi.mock('@/stores/comfyManagerStore', () => ({
|
||||
useComfyManagerStore: vi.fn(() => ({
|
||||
installPack: {
|
||||
call: mockInstallPack,
|
||||
@@ -84,7 +84,6 @@ import { whenever } from '@vueuse/core'
|
||||
import Button from 'primevue/button'
|
||||
import Listbox from 'primevue/listbox'
|
||||
import ProgressSpinner from 'primevue/progressspinner'
|
||||
import { valid as validSemver } from 'semver'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
@@ -93,10 +92,11 @@ import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
|
||||
import VerifiedIcon from '@/components/icons/VerifiedIcon.vue'
|
||||
import { useConflictDetection } from '@/composables/useConflictDetection'
|
||||
import { useComfyRegistryService } from '@/services/comfyRegistryService'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import type { components as ManagerComponents } from '@/types/generatedManagerTypes'
|
||||
import { getJoinedConflictMessages } from '@/utils/conflictMessageUtil'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import type { components as ManagerComponents } from '@/workbench/extensions/manager/types/generatedManagerTypes'
|
||||
import { isSemVer } from '@/utils/formatUtil'
|
||||
|
||||
type ManagerChannel = ManagerComponents['schemas']['ManagerChannel']
|
||||
type ManagerDatabaseSource =
|
||||
@@ -142,7 +142,7 @@ onMounted(() => {
|
||||
getInitialSelectedVersion() ?? SelectedVersionValues.LATEST
|
||||
selectedVersion.value =
|
||||
// Use NIGHTLY when version is a Git hash
|
||||
validSemver(initialVersion) ? initialVersion : SelectedVersionValues.NIGHTLY
|
||||
isSemVer(initialVersion) ? initialVersion : SelectedVersionValues.NIGHTLY
|
||||
})
|
||||
|
||||
const getInitialSelectedVersion = () => {
|
||||
@@ -8,7 +8,7 @@ import { nextTick } from 'vue'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
|
||||
import enMessages from '@/locales/en/main.json' with { type: 'json' }
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
|
||||
import PackEnableToggle from './PackEnableToggle.vue'
|
||||
|
||||
@@ -33,7 +33,7 @@ const mockNodePack = {
|
||||
const mockIsPackEnabled = vi.fn()
|
||||
const mockEnablePack = { call: vi.fn().mockResolvedValue(undefined) }
|
||||
const mockDisablePack = vi.fn().mockResolvedValue(undefined)
|
||||
vi.mock('@/workbench/extensions/manager/stores/comfyManagerStore', () => ({
|
||||
vi.mock('@/stores/comfyManagerStore', () => ({
|
||||
useComfyManagerStore: vi.fn(() => ({
|
||||
isPackEnabled: mockIsPackEnabled,
|
||||
enablePack: mockEnablePack,
|
||||
@@ -36,10 +36,10 @@ import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { useConflictAcknowledgment } from '@/composables/useConflictAcknowledgment'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import { useConflictDetectionStore } from '@/stores/conflictDetectionStore'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import type { components as ManagerComponents } from '@/workbench/extensions/manager/types/generatedManagerTypes'
|
||||
import type { components as ManagerComponents } from '@/types/generatedManagerTypes'
|
||||
|
||||
const TOGGLE_DEBOUNCE_MS = 256
|
||||
|
||||
@@ -30,12 +30,12 @@ import DotSpinner from '@/components/common/DotSpinner.vue'
|
||||
import { useConflictDetection } from '@/composables/useConflictDetection'
|
||||
import { t } from '@/i18n'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import type { ButtonSize } from '@/types/buttonTypes'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import type { ConflictDetectionResult } from '@/types/conflictDetectionTypes'
|
||||
import type { ConflictDetail } from '@/types/conflictDetectionTypes'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import type { components as ManagerComponents } from '@/workbench/extensions/manager/types/generatedManagerTypes'
|
||||
import type { components as ManagerComponents } from '@/types/generatedManagerTypes'
|
||||
|
||||
type NodePack = components['schemas']['Node']
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import IconTextButton from '@/components/button/IconTextButton.vue'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import type { ButtonSize } from '@/types/buttonTypes'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import type { components as ManagerComponents } from '@/workbench/extensions/manager/types/generatedManagerTypes'
|
||||
import type { components as ManagerComponents } from '@/types/generatedManagerTypes'
|
||||
|
||||
type NodePack = components['schemas']['Node']
|
||||
|
||||
@@ -22,8 +22,8 @@ import { ref } from 'vue'
|
||||
|
||||
import IconTextButton from '@/components/button/IconTextButton.vue'
|
||||
import DotSpinner from '@/components/common/DotSpinner.vue'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
|
||||
type NodePack = components['schemas']['Node']
|
||||
|
||||
@@ -64,20 +64,20 @@ import { useScroll, whenever } from '@vueuse/core'
|
||||
import { computed, provide, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import PackStatusMessage from '@/components/dialog/content/manager/PackStatusMessage.vue'
|
||||
import PackVersionBadge from '@/components/dialog/content/manager/PackVersionBadge.vue'
|
||||
import PackEnableToggle from '@/components/dialog/content/manager/button/PackEnableToggle.vue'
|
||||
import InfoPanelHeader from '@/components/dialog/content/manager/infoPanel/InfoPanelHeader.vue'
|
||||
import InfoTabs from '@/components/dialog/content/manager/infoPanel/InfoTabs.vue'
|
||||
import MetadataRow from '@/components/dialog/content/manager/infoPanel/MetadataRow.vue'
|
||||
import { useConflictDetection } from '@/composables/useConflictDetection'
|
||||
import { useImportFailedDetection } from '@/composables/useImportFailedDetection'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import { useConflictDetectionStore } from '@/stores/conflictDetectionStore'
|
||||
import { IsInstallingKey } from '@/types/comfyManagerTypes'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import type { ConflictDetectionResult } from '@/types/conflictDetectionTypes'
|
||||
import { ImportFailedKey } from '@/types/importFailedTypes'
|
||||
import PackStatusMessage from '@/workbench/extensions/manager/components/manager/PackStatusMessage.vue'
|
||||
import PackVersionBadge from '@/workbench/extensions/manager/components/manager/PackVersionBadge.vue'
|
||||
import PackEnableToggle from '@/workbench/extensions/manager/components/manager/button/PackEnableToggle.vue'
|
||||
import InfoPanelHeader from '@/workbench/extensions/manager/components/manager/infoPanel/InfoPanelHeader.vue'
|
||||
import InfoTabs from '@/workbench/extensions/manager/components/manager/infoPanel/InfoTabs.vue'
|
||||
import MetadataRow from '@/workbench/extensions/manager/components/manager/infoPanel/MetadataRow.vue'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import { IsInstallingKey } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
|
||||
interface InfoItem {
|
||||
key: string
|
||||
@@ -45,14 +45,14 @@
|
||||
import { computed, inject, ref, watch } from 'vue'
|
||||
|
||||
import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
|
||||
import PackInstallButton from '@/components/dialog/content/manager/button/PackInstallButton.vue'
|
||||
import PackUninstallButton from '@/components/dialog/content/manager/button/PackUninstallButton.vue'
|
||||
import PackIcon from '@/components/dialog/content/manager/packIcon/PackIcon.vue'
|
||||
import { useConflictDetection } from '@/composables/useConflictDetection'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import type { ConflictDetail } from '@/types/conflictDetectionTypes'
|
||||
import { ImportFailedKey } from '@/types/importFailedTypes'
|
||||
import PackInstallButton from '@/workbench/extensions/manager/components/manager/button/PackInstallButton.vue'
|
||||
import PackUninstallButton from '@/workbench/extensions/manager/components/manager/button/PackUninstallButton.vue'
|
||||
import PackIcon from '@/workbench/extensions/manager/components/manager/packIcon/PackIcon.vue'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
|
||||
const { nodePacks, hasConflict } = defineProps<{
|
||||
nodePacks: components['schemas']['Node'][]
|
||||
@@ -57,6 +57,12 @@
|
||||
import { useAsyncState } from '@vueuse/core'
|
||||
import { computed, onUnmounted, provide, toRef } from 'vue'
|
||||
|
||||
import PackStatusMessage from '@/components/dialog/content/manager/PackStatusMessage.vue'
|
||||
import PackInstallButton from '@/components/dialog/content/manager/button/PackInstallButton.vue'
|
||||
import PackUninstallButton from '@/components/dialog/content/manager/button/PackUninstallButton.vue'
|
||||
import InfoPanelHeader from '@/components/dialog/content/manager/infoPanel/InfoPanelHeader.vue'
|
||||
import MetadataRow from '@/components/dialog/content/manager/infoPanel/MetadataRow.vue'
|
||||
import PackIconStacked from '@/components/dialog/content/manager/packIcon/PackIconStacked.vue'
|
||||
import { usePacksSelection } from '@/composables/nodePack/usePacksSelection'
|
||||
import { usePacksStatus } from '@/composables/nodePack/usePacksStatus'
|
||||
import { useConflictDetection } from '@/composables/useConflictDetection'
|
||||
@@ -64,12 +70,6 @@ import { useComfyRegistryStore } from '@/stores/comfyRegistryStore'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import type { ConflictDetail } from '@/types/conflictDetectionTypes'
|
||||
import { ImportFailedKey } from '@/types/importFailedTypes'
|
||||
import PackStatusMessage from '@/workbench/extensions/manager/components/manager/PackStatusMessage.vue'
|
||||
import PackInstallButton from '@/workbench/extensions/manager/components/manager/button/PackInstallButton.vue'
|
||||
import PackUninstallButton from '@/workbench/extensions/manager/components/manager/button/PackUninstallButton.vue'
|
||||
import InfoPanelHeader from '@/workbench/extensions/manager/components/manager/infoPanel/InfoPanelHeader.vue'
|
||||
import MetadataRow from '@/workbench/extensions/manager/components/manager/infoPanel/MetadataRow.vue'
|
||||
import PackIconStacked from '@/workbench/extensions/manager/components/manager/packIcon/PackIconStacked.vue'
|
||||
|
||||
const { nodePacks } = defineProps<{
|
||||
nodePacks: components['schemas']['Node'][]
|
||||
@@ -45,12 +45,12 @@ import TabPanels from 'primevue/tabpanels'
|
||||
import Tabs from 'primevue/tabs'
|
||||
import { computed, inject, ref, watchEffect } from 'vue'
|
||||
|
||||
import DescriptionTabPanel from '@/components/dialog/content/manager/infoPanel/tabs/DescriptionTabPanel.vue'
|
||||
import NodesTabPanel from '@/components/dialog/content/manager/infoPanel/tabs/NodesTabPanel.vue'
|
||||
import WarningTabPanel from '@/components/dialog/content/manager/infoPanel/tabs/WarningTabPanel.vue'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import type { ConflictDetectionResult } from '@/types/conflictDetectionTypes'
|
||||
import { ImportFailedKey } from '@/types/importFailedTypes'
|
||||
import DescriptionTabPanel from '@/workbench/extensions/manager/components/manager/infoPanel/tabs/DescriptionTabPanel.vue'
|
||||
import NodesTabPanel from '@/workbench/extensions/manager/components/manager/infoPanel/tabs/NodesTabPanel.vue'
|
||||
import WarningTabPanel from '@/workbench/extensions/manager/components/manager/infoPanel/tabs/WarningTabPanel.vue'
|
||||
|
||||
const { nodePack, hasCompatibilityIssues, conflictResult } = defineProps<{
|
||||
nodePack: components['schemas']['Node']
|
||||
@@ -22,7 +22,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import MarkdownText from '@/workbench/extensions/manager/components/manager/infoPanel/MarkdownText.vue'
|
||||
import MarkdownText from '@/components/dialog/content/manager/infoPanel/MarkdownText.vue'
|
||||
|
||||
export interface TextSection {
|
||||
title: string
|
||||
@@ -26,11 +26,11 @@
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import { isValidUrl } from '@/utils/formatUtil'
|
||||
import InfoTextSection, {
|
||||
type TextSection
|
||||
} from '@/workbench/extensions/manager/components/manager/infoPanel/InfoTextSection.vue'
|
||||
} from '@/components/dialog/content/manager/infoPanel/InfoTextSection.vue'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import { isValidUrl } from '@/utils/formatUtil'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@@ -75,17 +75,17 @@ import Card from 'primevue/card'
|
||||
import { computed, provide } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import PackVersionBadge from '@/components/dialog/content/manager/PackVersionBadge.vue'
|
||||
import PackBanner from '@/components/dialog/content/manager/packBanner/PackBanner.vue'
|
||||
import PackCardFooter from '@/components/dialog/content/manager/packCard/PackCardFooter.vue'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
||||
import PackVersionBadge from '@/workbench/extensions/manager/components/manager/PackVersionBadge.vue'
|
||||
import PackBanner from '@/workbench/extensions/manager/components/manager/packBanner/PackBanner.vue'
|
||||
import PackCardFooter from '@/workbench/extensions/manager/components/manager/packCard/PackCardFooter.vue'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import {
|
||||
IsInstallingKey,
|
||||
type MergedNodePack,
|
||||
type RegistryPack,
|
||||
isMergedNodePack
|
||||
} from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
} from '@/types/comfyManagerTypes'
|
||||
|
||||
const { nodePack, isSelected = false } = defineProps<{
|
||||
nodePack: MergedNodePack | RegistryPack
|
||||
@@ -25,13 +25,13 @@
|
||||
import { computed, inject } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import PackEnableToggle from '@/components/dialog/content/manager/button/PackEnableToggle.vue'
|
||||
import PackInstallButton from '@/components/dialog/content/manager/button/PackInstallButton.vue'
|
||||
import { useConflictDetection } from '@/composables/useConflictDetection'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import { IsInstallingKey } from '@/types/comfyManagerTypes'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import type { ConflictDetail } from '@/types/conflictDetectionTypes'
|
||||
import PackEnableToggle from '@/workbench/extensions/manager/components/manager/button/PackEnableToggle.vue'
|
||||
import PackInstallButton from '@/workbench/extensions/manager/components/manager/button/PackInstallButton.vue'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import { IsInstallingKey } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
|
||||
const { nodePack } = defineProps<{
|
||||
nodePack: components['schemas']['Node']
|
||||
@@ -18,8 +18,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import PackIcon from '@/components/dialog/content/manager/packIcon/PackIcon.vue'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import PackIcon from '@/workbench/extensions/manager/components/manager/packIcon/PackIcon.vue'
|
||||
|
||||
const {
|
||||
nodePacks,
|
||||
@@ -67,21 +67,21 @@ import AutoComplete from 'primevue/autocomplete'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import PackInstallButton from '@/components/dialog/content/manager/button/PackInstallButton.vue'
|
||||
import PackUpdateButton from '@/components/dialog/content/manager/button/PackUpdateButton.vue'
|
||||
import SearchFilterDropdown from '@/components/dialog/content/manager/registrySearchBar/SearchFilterDropdown.vue'
|
||||
import { useMissingNodes } from '@/composables/nodePack/useMissingNodes'
|
||||
import { useUpdateAvailableNodes } from '@/composables/nodePack/useUpdateAvailableNodes'
|
||||
import {
|
||||
type SearchOption,
|
||||
SortableAlgoliaField
|
||||
} from '@/types/comfyManagerTypes'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import type {
|
||||
QuerySuggestion,
|
||||
SearchMode,
|
||||
SortableField
|
||||
} from '@/types/searchServiceTypes'
|
||||
import PackInstallButton from '@/workbench/extensions/manager/components/manager/button/PackInstallButton.vue'
|
||||
import PackUpdateButton from '@/workbench/extensions/manager/components/manager/button/PackUpdateButton.vue'
|
||||
import SearchFilterDropdown from '@/workbench/extensions/manager/components/manager/registrySearchBar/SearchFilterDropdown.vue'
|
||||
import {
|
||||
type SearchOption,
|
||||
SortableAlgoliaField
|
||||
} from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
|
||||
const { searchResults, sortOptions } = defineProps<{
|
||||
searchResults?: components['schemas']['Node'][]
|
||||
@@ -22,7 +22,7 @@
|
||||
// eslint-disable-next-line no-restricted-imports -- TODO: Migrate to Select component
|
||||
import Dropdown from 'primevue/dropdown'
|
||||
|
||||
import type { SearchOption } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
import type { SearchOption } from '@/types/comfyManagerTypes'
|
||||
|
||||
defineProps<{
|
||||
options: SearchOption<T>[]
|
||||
@@ -5,7 +5,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import PackCardSkeleton from '@/workbench/extensions/manager/components/manager/skeleton/PackCardSkeleton.vue'
|
||||
import PackCardSkeleton from '@/components/dialog/content/manager/skeleton/PackCardSkeleton.vue'
|
||||
|
||||
const { skeletonCardCount = 12, gridStyle } = defineProps<{
|
||||
skeletonCardCount?: number
|
||||
@@ -78,13 +78,13 @@ import { useConflictDetection } from '@/composables/useConflictDetection'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useWorkflowService } from '@/platform/workflow/core/services/workflowService'
|
||||
import { api } from '@/scripts/api'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
import { useComfyManagerService } from '@/workbench/extensions/manager/services/comfyManagerService'
|
||||
import { useComfyManagerService } from '@/services/comfyManagerService'
|
||||
import {
|
||||
useComfyManagerStore,
|
||||
useManagerProgressDialogStore
|
||||
} from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
} from '@/stores/comfyManagerStore'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
|
||||
const { t } = useI18n()
|
||||
const dialogStore = useDialogStore()
|
||||
@@ -24,7 +24,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import {
|
||||
useComfyManagerStore,
|
||||
useManagerProgressDialogStore
|
||||
} from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
} from '@/stores/comfyManagerStore'
|
||||
|
||||
const progressDialogContent = useManagerProgressDialogStore()
|
||||
const comfyManagerStore = useComfyManagerStore()
|
||||
@@ -76,7 +76,6 @@
|
||||
import { useEventListener, whenever } from '@vueuse/core'
|
||||
import {
|
||||
computed,
|
||||
nextTick,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
provide,
|
||||
@@ -118,7 +117,6 @@ import { useWorkflowAutoSave } from '@/platform/workflow/persistence/composables
|
||||
import { useWorkflowPersistence } from '@/platform/workflow/persistence/composables/useWorkflowPersistence'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import { SelectedNodeIdsKey } from '@/renderer/core/canvas/injectionKeys'
|
||||
import { attachSlotLinkPreviewRenderer } from '@/renderer/core/canvas/links/slotLinkPreviewRenderer'
|
||||
import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteractions'
|
||||
import TransformPane from '@/renderer/core/layout/transform/TransformPane.vue'
|
||||
import MiniMap from '@/renderer/extensions/minimap/MiniMap.vue'
|
||||
@@ -183,26 +181,6 @@ const viewportCulling = useViewportCulling(
|
||||
)
|
||||
const nodeEventHandlers = useNodeEventHandlers(vueNodeLifecycle.nodeManager)
|
||||
|
||||
const handleVueNodeLifecycleReset = async () => {
|
||||
if (isVueNodesEnabled.value) {
|
||||
vueNodeLifecycle.disposeNodeManagerAndSyncs()
|
||||
await nextTick()
|
||||
vueNodeLifecycle.initializeNodeManager()
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => canvasStore.currentGraph, handleVueNodeLifecycleReset)
|
||||
|
||||
watch(
|
||||
() => canvasStore.isInSubgraph,
|
||||
async (newValue, oldValue) => {
|
||||
if (oldValue && !newValue) {
|
||||
useWorkflowStore().updateActiveGraph()
|
||||
}
|
||||
await handleVueNodeLifecycleReset()
|
||||
}
|
||||
)
|
||||
|
||||
const nodePositions = vueNodeLifecycle.nodePositions
|
||||
const nodeSizes = vueNodeLifecycle.nodeSizes
|
||||
const allNodes = viewportCulling.allNodes
|
||||
@@ -426,7 +404,6 @@ onMounted(async () => {
|
||||
|
||||
// @ts-expect-error fixme ts strict error
|
||||
await comfyApp.setup(canvasRef.value)
|
||||
attachSlotLinkPreviewRenderer(comfyApp.canvas)
|
||||
canvasStore.canvas = comfyApp.canvas
|
||||
canvasStore.canvas.render_canvas_border = false
|
||||
workspaceStore.spinner = false
|
||||
|
||||
@@ -68,7 +68,7 @@ const onIdle = () => {
|
||||
ctor.title_mode !== LiteGraph.NO_TITLE &&
|
||||
canvas.graph_mouse[1] < node.pos[1] // If we are over a node, but not within the node then we are on its title
|
||||
) {
|
||||
return showTooltip(nodeDef?.description)
|
||||
return showTooltip(nodeDef.description)
|
||||
}
|
||||
|
||||
if (node.flags?.collapsed) return
|
||||
@@ -83,7 +83,7 @@ const onIdle = () => {
|
||||
const inputName = node.inputs[inputSlot].name
|
||||
const translatedTooltip = st(
|
||||
`nodeDefs.${normalizeI18nKey(node.type ?? '')}.inputs.${normalizeI18nKey(inputName)}.tooltip`,
|
||||
nodeDef?.inputs[inputName]?.tooltip ?? ''
|
||||
nodeDef.inputs[inputName]?.tooltip ?? ''
|
||||
)
|
||||
return showTooltip(translatedTooltip)
|
||||
}
|
||||
@@ -97,7 +97,7 @@ const onIdle = () => {
|
||||
if (outputSlot !== -1) {
|
||||
const translatedTooltip = st(
|
||||
`nodeDefs.${normalizeI18nKey(node.type ?? '')}.outputs.${outputSlot}.tooltip`,
|
||||
nodeDef?.outputs[outputSlot]?.tooltip ?? ''
|
||||
nodeDef.outputs[outputSlot]?.tooltip ?? ''
|
||||
)
|
||||
return showTooltip(translatedTooltip)
|
||||
}
|
||||
@@ -107,7 +107,7 @@ const onIdle = () => {
|
||||
if (widget && !isDOMWidget(widget)) {
|
||||
const translatedTooltip = st(
|
||||
`nodeDefs.${normalizeI18nKey(node.type ?? '')}.inputs.${normalizeI18nKey(widget.name)}.tooltip`,
|
||||
nodeDef?.inputs[widget.name]?.tooltip ?? ''
|
||||
nodeDef.inputs[widget.name]?.tooltip ?? ''
|
||||
)
|
||||
// Widget tooltip can be set dynamically, current translation collection does not support this.
|
||||
return showTooltip(widget.tooltip ?? translatedTooltip)
|
||||
|
||||
@@ -142,14 +142,14 @@ import { useI18n } from 'vue-i18n'
|
||||
|
||||
import PuzzleIcon from '@/components/icons/PuzzleIcon.vue'
|
||||
import { useConflictAcknowledgment } from '@/composables/useConflictAcknowledgment'
|
||||
import { useManagerState } from '@/composables/useManagerState'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import type { ReleaseNote } from '@/platform/updates/common/releaseService'
|
||||
import { useReleaseStore } from '@/platform/updates/common/releaseStore'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { ManagerTab } from '@/types/comfyManagerTypes'
|
||||
import { electronAPI, isElectron } from '@/utils/envUtil'
|
||||
import { formatVersionAnchor } from '@/utils/formatUtil'
|
||||
import { useManagerState } from '@/workbench/extensions/manager/composables/useManagerState'
|
||||
import { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
|
||||
// Types
|
||||
interface MenuItem {
|
||||
|
||||
@@ -82,6 +82,7 @@ import { useI18n } from 'vue-i18n'
|
||||
|
||||
import SubgraphBreadcrumb from '@/components/breadcrumb/SubgraphBreadcrumb.vue'
|
||||
import SettingDialogHeader from '@/components/dialog/header/SettingDialogHeader.vue'
|
||||
import { useManagerState } from '@/composables/useManagerState'
|
||||
import SettingDialogContent from '@/platform/settings/components/SettingDialogContent.vue'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useColorPaletteService } from '@/services/colorPaletteService'
|
||||
@@ -89,11 +90,10 @@ import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
import { useMenuItemStore } from '@/stores/menuItemStore'
|
||||
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
||||
import { ManagerTab } from '@/types/comfyManagerTypes'
|
||||
import { showNativeSystemMenu } from '@/utils/envUtil'
|
||||
import { normalizeI18nKey } from '@/utils/formatUtil'
|
||||
import { whileMouseDown } from '@/utils/mouseDownUtil'
|
||||
import { useManagerState } from '@/workbench/extensions/manager/composables/useManagerState'
|
||||
import { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
|
||||
const colorPaletteStore = useColorPaletteStore()
|
||||
const colorPaletteService = useColorPaletteService()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { computed, watch } from 'vue'
|
||||
import { whenever } from '@vueuse/core'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { t } from '@/i18n'
|
||||
@@ -38,12 +39,7 @@ export const useCurrentUser = () => {
|
||||
callback(resolvedUserInfo.value)
|
||||
}
|
||||
|
||||
const stop = watch(resolvedUserInfo, (value) => {
|
||||
if (value) {
|
||||
callback(value)
|
||||
}
|
||||
})
|
||||
|
||||
const stop = whenever(resolvedUserInfo, callback)
|
||||
return () => stop()
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { Ref } from 'vue'
|
||||
import { useCanvasTransformSync } from '@/composables/canvas/useCanvasTransformSync'
|
||||
import { useSelectedLiteGraphItems } from '@/composables/canvas/useSelectedLiteGraphItems'
|
||||
import { useVueFeatureFlags } from '@/composables/useVueFeatureFlags'
|
||||
import type { Rect } from '@/lib/litegraph/src/interfaces'
|
||||
import type { ReadOnlyRect } from '@/lib/litegraph/src/interfaces'
|
||||
import { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import { layoutStore } from '@/renderer/core/layout/store/layoutStore'
|
||||
@@ -71,7 +71,7 @@ export function useSelectionToolboxPosition(
|
||||
visible.value = true
|
||||
|
||||
// Get bounds for all selected items
|
||||
const allBounds: Rect[] = []
|
||||
const allBounds: ReadOnlyRect[] = []
|
||||
for (const item of selectableItems) {
|
||||
// Skip items without valid IDs
|
||||
if (item.id == null) continue
|
||||
|
||||
@@ -57,12 +57,10 @@ export function useVueNodeLifecycle(isVueNodesEnabled: Ref<boolean>) {
|
||||
const isNodeManagerReady = computed(() => nodeManager.value !== null)
|
||||
|
||||
const initializeNodeManager = () => {
|
||||
// Use canvas graph if available (handles subgraph contexts), fallback to app graph
|
||||
const activeGraph = comfyApp.canvas?.graph || comfyApp.graph
|
||||
if (!activeGraph || nodeManager.value) return
|
||||
if (!comfyApp.graph || nodeManager.value) return
|
||||
|
||||
// Initialize the core node manager
|
||||
const manager = useGraphNodeManager(activeGraph)
|
||||
const manager = useGraphNodeManager(comfyApp.graph)
|
||||
nodeManager.value = manager
|
||||
cleanupNodeManager.value = manager.cleanup
|
||||
|
||||
@@ -73,8 +71,8 @@ export function useVueNodeLifecycle(isVueNodesEnabled: Ref<boolean>) {
|
||||
nodeSizes.value = manager.nodeSizes
|
||||
detectChangesInRAF.value = manager.detectChangesInRAF
|
||||
|
||||
// Initialize layout system with existing nodes from active graph
|
||||
const nodes = activeGraph._nodes.map((node: LGraphNode) => ({
|
||||
// Initialize layout system with existing nodes
|
||||
const nodes = comfyApp.graph._nodes.map((node: LGraphNode) => ({
|
||||
id: node.id.toString(),
|
||||
pos: [node.pos[0], node.pos[1]] as [number, number],
|
||||
size: [node.size[0], node.size[1]] as [number, number]
|
||||
@@ -82,7 +80,7 @@ export function useVueNodeLifecycle(isVueNodesEnabled: Ref<boolean>) {
|
||||
layoutStore.initializeFromLiteGraph(nodes)
|
||||
|
||||
// Seed reroutes into the Layout Store so hit-testing uses the new path
|
||||
for (const reroute of activeGraph.reroutes.values()) {
|
||||
for (const reroute of comfyApp.graph.reroutes.values()) {
|
||||
const [x, y] = reroute.pos
|
||||
const parent = reroute.parentId ?? undefined
|
||||
const linkIds = Array.from(reroute.linkIds)
|
||||
@@ -90,7 +88,7 @@ export function useVueNodeLifecycle(isVueNodesEnabled: Ref<boolean>) {
|
||||
}
|
||||
|
||||
// Seed existing links into the Layout Store (topology only)
|
||||
for (const link of activeGraph._links.values()) {
|
||||
for (const link of comfyApp.graph._links.values()) {
|
||||
layoutMutations.createLink(
|
||||
link.id,
|
||||
link.origin_id,
|
||||
@@ -144,9 +142,7 @@ export function useVueNodeLifecycle(isVueNodesEnabled: Ref<boolean>) {
|
||||
|
||||
// Watch for Vue nodes enabled state changes
|
||||
watch(
|
||||
() =>
|
||||
isVueNodesEnabled.value &&
|
||||
Boolean(comfyApp.canvas?.graph || comfyApp.graph),
|
||||
() => isVueNodesEnabled.value && Boolean(comfyApp.graph),
|
||||
(enabled) => {
|
||||
if (enabled) {
|
||||
initializeNodeManager()
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import type { ManagerState } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
import {
|
||||
ManagerTab,
|
||||
SortableAlgoliaField
|
||||
} from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
import type { ManagerState } from '@/types/comfyManagerTypes'
|
||||
import { ManagerTab, SortableAlgoliaField } from '@/types/comfyManagerTypes'
|
||||
|
||||
const STORAGE_KEY = 'Comfy.Manager.UI.State'
|
||||
|
||||
@@ -2,9 +2,9 @@ import { whenever } from '@vueuse/core'
|
||||
import { computed, onUnmounted, ref } from 'vue'
|
||||
|
||||
import { useNodePacks } from '@/composables/nodePack/useNodePacks'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import type { UseNodePacksOptions } from '@/types/comfyManagerTypes'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import type { UseNodePacksOptions } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
|
||||
export const useInstalledPacks = (options: UseNodePacksOptions = {}) => {
|
||||
const comfyManagerStore = useComfyManagerStore()
|
||||
|
||||
@@ -5,10 +5,10 @@ import { useWorkflowPacks } from '@/composables/nodePack/useWorkflowPacks'
|
||||
import type { NodeProperty } from '@/lib/litegraph/src/LGraphNode'
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { app } from '@/scripts/app'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import { useNodeDefStore } from '@/stores/nodeDefStore'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import { collectAllNodes } from '@/utils/graphTraversalUtil'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
|
||||
/**
|
||||
* Composable to find missing NodePacks from workflow
|
||||
|
||||
@@ -2,7 +2,7 @@ import { get, useAsyncState } from '@vueuse/core'
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
import { useComfyRegistryStore } from '@/stores/comfyRegistryStore'
|
||||
import type { UseNodePacksOptions } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
import type { UseNodePacksOptions } from '@/types/comfyManagerTypes'
|
||||
|
||||
/**
|
||||
* Handles fetching node packs from the registry given a list of node pack IDs
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { compare, valid } from 'semver'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import { compareVersions, isSemVer } from '@/utils/formatUtil'
|
||||
|
||||
export const usePackUpdateStatus = (
|
||||
nodePack: components['schemas']['Node']
|
||||
@@ -16,14 +16,14 @@ export const usePackUpdateStatus = (
|
||||
const latestVersion = computed(() => nodePack.latest_version?.version)
|
||||
|
||||
const isNightlyPack = computed(
|
||||
() => !!installedVersion.value && !valid(installedVersion.value)
|
||||
() => !!installedVersion.value && !isSemVer(installedVersion.value)
|
||||
)
|
||||
|
||||
const isUpdateAvailable = computed(() => {
|
||||
if (!isInstalled.value || isNightlyPack.value || !latestVersion.value) {
|
||||
return false
|
||||
}
|
||||
return compare(latestVersion.value, installedVersion.value) > 0
|
||||
return compareVersions(latestVersion.value, installedVersion.value) > 0
|
||||
})
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { type Ref, computed } from 'vue'
|
||||
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
|
||||
type NodePack = components['schemas']['Node']
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { compare, valid } from 'semver'
|
||||
import { computed, onMounted } from 'vue'
|
||||
|
||||
import { useInstalledPacks } from '@/composables/nodePack/useInstalledPacks'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import { compareVersions, isSemVer } from '@/utils/formatUtil'
|
||||
|
||||
/**
|
||||
* Composable to find NodePacks that have updates available
|
||||
@@ -25,13 +25,13 @@ export const useUpdateAvailableNodes = () => {
|
||||
)
|
||||
const latestVersion = pack.latest_version?.version
|
||||
|
||||
const isNightlyPack = !!installedVersion && !valid(installedVersion)
|
||||
const isNightlyPack = !!installedVersion && !isSemVer(installedVersion)
|
||||
|
||||
if (isNightlyPack || !latestVersion) {
|
||||
return false
|
||||
}
|
||||
|
||||
return compare(latestVersion, installedVersion) > 0
|
||||
return compareVersions(latestVersion, installedVersion) > 0
|
||||
}
|
||||
|
||||
// Same filtering logic as ManagerDialogContent.vue
|
||||
|
||||
@@ -7,9 +7,9 @@ import { app } from '@/scripts/app'
|
||||
import { useComfyRegistryStore } from '@/stores/comfyRegistryStore'
|
||||
import { useNodeDefStore } from '@/stores/nodeDefStore'
|
||||
import { useSystemStatsStore } from '@/stores/systemStatsStore'
|
||||
import type { UseNodePacksOptions } from '@/types/comfyManagerTypes'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import { collectAllNodes } from '@/utils/graphTraversalUtil'
|
||||
import type { UseNodePacksOptions } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
|
||||
type WorkflowPack = {
|
||||
id:
|
||||
|
||||
@@ -5,7 +5,9 @@ import { computed, getCurrentInstance, onUnmounted, readonly, ref } from 'vue'
|
||||
import { useInstalledPacks } from '@/composables/nodePack/useInstalledPacks'
|
||||
import { useConflictAcknowledgment } from '@/composables/useConflictAcknowledgment'
|
||||
import config from '@/config'
|
||||
import { useComfyManagerService } from '@/services/comfyManagerService'
|
||||
import { useComfyRegistryService } from '@/services/comfyRegistryService'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import { useConflictDetectionStore } from '@/stores/conflictDetectionStore'
|
||||
import { useSystemStatsStore } from '@/stores/systemStatsStore'
|
||||
import type { SystemStats } from '@/types'
|
||||
@@ -26,8 +28,6 @@ import {
|
||||
satisfiesVersion,
|
||||
utilCheckVersionCompatibility
|
||||
} from '@/utils/versionUtil'
|
||||
import { useComfyManagerService } from '@/workbench/extensions/manager/services/comfyManagerService'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
|
||||
/**
|
||||
* Composable for conflict detection system.
|
||||
@@ -641,9 +641,7 @@ export function useConflictDetection() {
|
||||
async function initializeConflictDetection(): Promise<void> {
|
||||
try {
|
||||
// Check if manager is new Manager before proceeding
|
||||
const { useManagerState } = await import(
|
||||
'@/workbench/extensions/manager/composables/useManagerState'
|
||||
)
|
||||
const { useManagerState } = await import('@/composables/useManagerState')
|
||||
const managerState = useManagerState()
|
||||
|
||||
if (!managerState.isNewManagerUI.value) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useSelectedLiteGraphItems } from '@/composables/canvas/useSelectedLiteGraphItems'
|
||||
import { ManagerUIState, useManagerState } from '@/composables/useManagerState'
|
||||
import { useModelSelectorDialog } from '@/composables/useModelSelectorDialog'
|
||||
import {
|
||||
DEFAULT_DARK_COLOR_PALETTE,
|
||||
@@ -40,16 +41,12 @@ import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'
|
||||
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
||||
import { useSearchBoxStore } from '@/stores/workspace/searchBoxStore'
|
||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||
import { ManagerTab } from '@/types/comfyManagerTypes'
|
||||
import {
|
||||
getAllNonIoNodesInSubgraph,
|
||||
getExecutionIdsForSelectedNodes
|
||||
} from '@/utils/graphTraversalUtil'
|
||||
import { filterOutputNodes } from '@/utils/nodeFilterUtil'
|
||||
import {
|
||||
ManagerUIState,
|
||||
useManagerState
|
||||
} from '@/workbench/extensions/manager/composables/useManagerState'
|
||||
import { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
|
||||
const moveSelectedNodesVersionAdded = '1.22.2'
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ import { type ComputedRef, computed, unref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
|
||||
import { useConflictDetectionStore } from '@/stores/conflictDetectionStore'
|
||||
import type { ConflictDetail } from '@/types/conflictDetectionTypes'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
|
||||
/**
|
||||
* Extracting import failed conflicts from conflict list
|
||||
|
||||
@@ -5,8 +5,8 @@ import { computed, ref } from 'vue'
|
||||
|
||||
import { app } from '@/scripts/app'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import type { components } from '@/types/generatedManagerTypes'
|
||||
import { normalizePackKeys } from '@/utils/packUtils'
|
||||
import type { components } from '@/workbench/extensions/manager/types/generatedManagerTypes'
|
||||
|
||||
type ManagerTaskHistory = Record<
|
||||
string,
|
||||
@@ -7,7 +7,7 @@ import { api } from '@/scripts/api'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useSystemStatsStore } from '@/stores/systemStatsStore'
|
||||
import { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
import { ManagerTab } from '@/types/comfyManagerTypes'
|
||||
|
||||
export enum ManagerUIState {
|
||||
DISABLED = 'disabled',
|
||||
@@ -5,9 +5,9 @@ import { computed, ref, watch } from 'vue'
|
||||
import { DEFAULT_PAGE_SIZE } from '@/constants/searchConstants'
|
||||
import { useRegistrySearchGateway } from '@/services/gateway/registrySearchGateway'
|
||||
import type { SearchAttribute } from '@/types/algoliaTypes'
|
||||
import { SortableAlgoliaField } from '@/types/comfyManagerTypes'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
import type { QuerySuggestion, SearchMode } from '@/types/searchServiceTypes'
|
||||
import { SortableAlgoliaField } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
|
||||
type RegistryNodePack = components['schemas']['Node']
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { onUnmounted, ref } from 'vue'
|
||||
|
||||
import type { LogsWsMessage } from '@/schemas/apiSchema'
|
||||
import { api } from '@/scripts/api'
|
||||
import type { components } from '@/workbench/extensions/manager/types/generatedManagerTypes'
|
||||
import type { components } from '@/types/generatedManagerTypes'
|
||||
|
||||
const LOGS_MESSAGE_TYPE = 'logs'
|
||||
const MANAGER_WS_TASK_DONE_NAME = 'cm-task-completed'
|
||||
|
||||
@@ -11,16 +11,16 @@ import {
|
||||
} from '@/lib/litegraph/src/litegraph'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
import {
|
||||
type ComfyLink,
|
||||
type ComfyNode,
|
||||
type ComfyWorkflowJSON
|
||||
ComfyLink,
|
||||
ComfyNode,
|
||||
ComfyWorkflowJSON
|
||||
} from '@/platform/workflow/validation/schemas/workflowSchema'
|
||||
import type { ComfyNodeDef } from '@/schemas/nodeDefSchema'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useExecutionStore } from '@/stores/executionStore'
|
||||
import { useNodeDefStore } from '@/stores/nodeDefStore'
|
||||
import { useWidgetStore } from '@/stores/widgetStore'
|
||||
import { type ComfyExtension } from '@/types/comfy'
|
||||
import { ComfyExtension } from '@/types/comfy'
|
||||
import { ExecutableGroupNodeChildDTO } from '@/utils/executableGroupNodeChildDTO'
|
||||
import { GROUP } from '@/utils/executableGroupNodeDto'
|
||||
import { deserialiseAndCreate, serialise } from '@/utils/vintageClipboard'
|
||||
|
||||
@@ -9,7 +9,7 @@ import Load3dUtils from '@/extensions/core/load3d/Load3dUtils'
|
||||
import { t } from '@/i18n'
|
||||
import type { IStringWidget } from '@/lib/litegraph/src/types/widgets'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
import { type CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import { api } from '@/scripts/api'
|
||||
import { ComfyApp, app } from '@/scripts/app'
|
||||
import { ComponentWidgetImpl, addWidget } from '@/scripts/domWidget'
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as THREE from 'three'
|
||||
|
||||
import {
|
||||
type AnimationItem,
|
||||
type AnimationManagerInterface,
|
||||
type EventManagerInterface
|
||||
AnimationItem,
|
||||
AnimationManagerInterface,
|
||||
EventManagerInterface
|
||||
} from '@/extensions/core/load3d/interfaces'
|
||||
|
||||
export class AnimationManager implements AnimationManagerInterface {
|
||||
|
||||
@@ -2,11 +2,11 @@ import * as THREE from 'three'
|
||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||
|
||||
import {
|
||||
type CameraManagerInterface,
|
||||
type CameraState,
|
||||
type CameraType,
|
||||
type EventManagerInterface,
|
||||
type NodeStorageInterface
|
||||
CameraManagerInterface,
|
||||
CameraState,
|
||||
CameraType,
|
||||
EventManagerInterface,
|
||||
NodeStorageInterface
|
||||
} from './interfaces'
|
||||
|
||||
export class CameraManager implements CameraManagerInterface {
|
||||
|
||||
@@ -2,9 +2,9 @@ import * as THREE from 'three'
|
||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||
|
||||
import {
|
||||
type ControlsManagerInterface,
|
||||
type EventManagerInterface,
|
||||
type NodeStorageInterface
|
||||
ControlsManagerInterface,
|
||||
EventManagerInterface,
|
||||
NodeStorageInterface
|
||||
} from './interfaces'
|
||||
|
||||
export class ControlsManager implements ControlsManagerInterface {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type EventCallback, type EventManagerInterface } from './interfaces'
|
||||
import { EventCallback, EventManagerInterface } from './interfaces'
|
||||
|
||||
export class EventManager implements EventManagerInterface {
|
||||
private listeners: { [key: string]: EventCallback[] } = {}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import * as THREE from 'three'
|
||||
|
||||
import {
|
||||
type EventManagerInterface,
|
||||
type LightingManagerInterface
|
||||
} from './interfaces'
|
||||
import { EventManagerInterface, LightingManagerInterface } from './interfaces'
|
||||
|
||||
export class LightingManager implements LightingManagerInterface {
|
||||
lights: THREE.Light[] = []
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as THREE from 'three'
|
||||
|
||||
import { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { type CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
|
||||
import { CameraManager } from './CameraManager'
|
||||
import { ControlsManager } from './ControlsManager'
|
||||
@@ -16,11 +16,11 @@ import { SceneManager } from './SceneManager'
|
||||
import { SceneModelManager } from './SceneModelManager'
|
||||
import { ViewHelperManager } from './ViewHelperManager'
|
||||
import {
|
||||
type CameraState,
|
||||
type CaptureResult,
|
||||
type Load3DOptions,
|
||||
type MaterialMode,
|
||||
type UpDirection
|
||||
CameraState,
|
||||
CaptureResult,
|
||||
Load3DOptions,
|
||||
MaterialMode,
|
||||
UpDirection
|
||||
} from './interfaces'
|
||||
|
||||
class Load3d {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
|
||||
import { AnimationManager } from './AnimationManager'
|
||||
import Load3d from './Load3d'
|
||||
import { type Load3DOptions } from './interfaces'
|
||||
import { Load3DOptions } from './interfaces'
|
||||
|
||||
class Load3dAnimation extends Load3d {
|
||||
private animationManager: AnimationManager
|
||||
|
||||
@@ -9,9 +9,9 @@ import { t } from '@/i18n'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
|
||||
import {
|
||||
type EventManagerInterface,
|
||||
type LoaderManagerInterface,
|
||||
type ModelManagerInterface
|
||||
EventManagerInterface,
|
||||
LoaderManagerInterface,
|
||||
ModelManagerInterface
|
||||
} from './interfaces'
|
||||
|
||||
export class LoaderManager implements LoaderManagerInterface {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
|
||||
import { type NodeStorageInterface } from './interfaces'
|
||||
import { NodeStorageInterface } from './interfaces'
|
||||
|
||||
export class NodeStorage implements NodeStorageInterface {
|
||||
private node: LGraphNode
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import * as THREE from 'three'
|
||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||
|
||||
import {
|
||||
type EventManagerInterface,
|
||||
type PreviewManagerInterface
|
||||
} from './interfaces'
|
||||
import { EventManagerInterface, PreviewManagerInterface } from './interfaces'
|
||||
|
||||
export class PreviewManager implements PreviewManagerInterface {
|
||||
previewCamera: THREE.Camera
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as THREE from 'three'
|
||||
|
||||
import { type EventManagerInterface } from './interfaces'
|
||||
import { EventManagerInterface } from './interfaces'
|
||||
|
||||
export class RecordingManager {
|
||||
private mediaRecorder: MediaRecorder | null = null
|
||||
|
||||
@@ -2,10 +2,7 @@ import * as THREE from 'three'
|
||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||
|
||||
import Load3dUtils from './Load3dUtils'
|
||||
import {
|
||||
type EventManagerInterface,
|
||||
type SceneManagerInterface
|
||||
} from './interfaces'
|
||||
import { EventManagerInterface, SceneManagerInterface } from './interfaces'
|
||||
|
||||
export class SceneManager implements SceneManagerInterface {
|
||||
scene: THREE.Scene
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as THREE from 'three'
|
||||
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial'
|
||||
import { LineSegments2 } from 'three/examples/jsm/lines/LineSegments2'
|
||||
import { LineSegmentsGeometry } from 'three/examples/jsm/lines/LineSegmentsGeometry'
|
||||
import { type GLTF } from 'three/examples/jsm/loaders/GLTFLoader'
|
||||
import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader'
|
||||
import { mergeVertices } from 'three/examples/jsm/utils/BufferGeometryUtils'
|
||||
|
||||
import { ColoredShadowMaterial } from './conditional-lines/ColoredShadowMaterial'
|
||||
@@ -11,11 +11,11 @@ import { ConditionalEdgesShader } from './conditional-lines/ConditionalEdgesShad
|
||||
import { ConditionalLineMaterial } from './conditional-lines/Lines2/ConditionalLineMaterial'
|
||||
import { ConditionalLineSegmentsGeometry } from './conditional-lines/Lines2/ConditionalLineSegmentsGeometry'
|
||||
import {
|
||||
type EventManagerInterface,
|
||||
type Load3DOptions,
|
||||
type MaterialMode,
|
||||
type ModelManagerInterface,
|
||||
type UpDirection
|
||||
EventManagerInterface,
|
||||
Load3DOptions,
|
||||
MaterialMode,
|
||||
ModelManagerInterface,
|
||||
UpDirection
|
||||
} from './interfaces'
|
||||
|
||||
export class SceneModelManager implements ModelManagerInterface {
|
||||
|
||||
@@ -2,10 +2,7 @@ import * as THREE from 'three'
|
||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||
import { ViewHelper } from 'three/examples/jsm/helpers/ViewHelper'
|
||||
|
||||
import {
|
||||
type NodeStorageInterface,
|
||||
type ViewHelperManagerInterface
|
||||
} from './interfaces'
|
||||
import { NodeStorageInterface, ViewHelperManagerInterface } from './interfaces'
|
||||
|
||||
export class ViewHelperManager implements ViewHelperManagerInterface {
|
||||
viewHelper: ViewHelper = {} as ViewHelper
|
||||
|
||||
@@ -2,13 +2,13 @@ import * as THREE from 'three'
|
||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||
import { ViewHelper } from 'three/examples/jsm/helpers/ViewHelper'
|
||||
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
|
||||
import { type GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
|
||||
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
|
||||
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader'
|
||||
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
|
||||
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
|
||||
|
||||
import { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { type CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
|
||||
export type Load3DNodeType = 'Load3D' | 'Preview3D'
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ https://github.com/rgthree/rgthree-comfy/blob/main/py/display_any.py
|
||||
upstream requested in https://github.com/Kosinkadink/rfcs/blob/main/rfcs/0000-corenodes.md#preview-nodes
|
||||
*/
|
||||
import { app } from '@/scripts/app'
|
||||
import { type DOMWidget } from '@/scripts/domWidget'
|
||||
import { DOMWidget } from '@/scripts/domWidget'
|
||||
import { ComfyWidgets } from '@/scripts/widgets'
|
||||
import { useExtensionService } from '@/services/extensionService'
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { nextTick } from 'vue'
|
||||
|
||||
import Load3D from '@/components/load3d/Load3D.vue'
|
||||
import Load3DConfiguration from '@/extensions/core/load3d/Load3DConfiguration'
|
||||
import { type CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import { CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import { ComponentWidgetImpl, addWidget } from '@/scripts/domWidget'
|
||||
import { useExtensionService } from '@/services/extensionService'
|
||||
import { useLoad3dService } from '@/services/load3dService'
|
||||
|
||||
@@ -15,7 +15,7 @@ import type { ResultItemType } from '@/schemas/apiSchema'
|
||||
import type { ComfyNodeDef } from '@/schemas/nodeDefSchema'
|
||||
import type { DOMWidget } from '@/scripts/domWidget'
|
||||
import { useAudioService } from '@/services/audioService'
|
||||
import { type NodeLocatorId } from '@/types'
|
||||
import { NodeLocatorId } from '@/types'
|
||||
import { getNodeByLocatorId } from '@/utils/graphTraversalUtil'
|
||||
|
||||
import { api } from '../../scripts/api'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
type ComfyNodeDef,
|
||||
type InputSpec,
|
||||
ComfyNodeDef,
|
||||
InputSpec,
|
||||
isComboInputSpecV1
|
||||
} from '@/schemas/nodeDefSchema'
|
||||
|
||||
|
||||
@@ -28,10 +28,6 @@ import ruCommands from './locales/ru/commands.json' with { type: 'json' }
|
||||
import ru from './locales/ru/main.json' with { type: 'json' }
|
||||
import ruNodes from './locales/ru/nodeDefs.json' with { type: 'json' }
|
||||
import ruSettings from './locales/ru/settings.json' with { type: 'json' }
|
||||
import trCommands from './locales/tr/commands.json' with { type: 'json' }
|
||||
import tr from './locales/tr/main.json' with { type: 'json' }
|
||||
import trNodes from './locales/tr/nodeDefs.json' with { type: 'json' }
|
||||
import trSettings from './locales/tr/settings.json' with { type: 'json' }
|
||||
import zhTWCommands from './locales/zh-TW/commands.json' with { type: 'json' }
|
||||
import zhTW from './locales/zh-TW/main.json' with { type: 'json' }
|
||||
import zhTWNodes from './locales/zh-TW/nodeDefs.json' with { type: 'json' }
|
||||
@@ -59,8 +55,7 @@ const messages = {
|
||||
ko: buildLocale(ko, koNodes, koCommands, koSettings),
|
||||
fr: buildLocale(fr, frNodes, frCommands, frSettings),
|
||||
es: buildLocale(es, esNodes, esCommands, esSettings),
|
||||
ar: buildLocale(ar, arNodes, arCommands, arSettings),
|
||||
tr: buildLocale(tr, trNodes, trCommands, trSettings)
|
||||
ar: buildLocale(ar, arNodes, arCommands, arSettings)
|
||||
}
|
||||
|
||||
export const i18n = createI18n({
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user