mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-07-02 21:28:08 +00:00
Compare commits
4 Commits
codex/cove
...
ponytail/o
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52d2c8b483 | ||
|
|
434e6534fb | ||
|
|
1cacae1b34 | ||
|
|
85992db615 |
@@ -5,7 +5,7 @@
|
||||
</h2>
|
||||
<div class="space-y-2">
|
||||
<a
|
||||
v-for="badge in aboutPanelStore.badges"
|
||||
v-for="badge in badges"
|
||||
:key="badge.url"
|
||||
:href="badge.url"
|
||||
target="_blank"
|
||||
@@ -34,11 +34,75 @@
|
||||
<script setup lang="ts">
|
||||
import Divider from 'primevue/divider'
|
||||
import Tag from 'primevue/tag'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import SystemStatsPanel from '@/components/common/SystemStatsPanel.vue'
|
||||
import { useAboutPanelStore } from '@/stores/aboutPanelStore'
|
||||
import { useExternalLink } from '@/composables/useExternalLink'
|
||||
import { isCloud, isDesktop } from '@/platform/distribution/types'
|
||||
import { useExtensionStore } from '@/stores/extensionStore'
|
||||
import { useSystemStatsStore } from '@/stores/systemStatsStore'
|
||||
import type { AboutPageBadge } from '@/types/comfy'
|
||||
import { electronAPI } from '@/utils/envUtil'
|
||||
import { formatCommitHash } from '@/utils/formatUtil'
|
||||
|
||||
const systemStatsStore = useSystemStatsStore()
|
||||
const aboutPanelStore = useAboutPanelStore()
|
||||
const extensionStore = useExtensionStore()
|
||||
const { staticUrls } = useExternalLink()
|
||||
|
||||
const frontendVersion = __COMFYUI_FRONTEND_VERSION__
|
||||
const coreVersion = computed(
|
||||
() => systemStatsStore?.systemStats?.system?.comfyui_version ?? ''
|
||||
)
|
||||
const templatesVersion = computed(
|
||||
() => systemStatsStore?.systemStats?.system?.installed_templates_version ?? ''
|
||||
)
|
||||
const requiredTemplatesVersion = computed(
|
||||
() => systemStatsStore?.systemStats?.system?.required_templates_version ?? ''
|
||||
)
|
||||
const isTemplatesOutdated = computed(
|
||||
() =>
|
||||
templatesVersion.value !== '' &&
|
||||
requiredTemplatesVersion.value !== '' &&
|
||||
templatesVersion.value !== requiredTemplatesVersion.value
|
||||
)
|
||||
|
||||
const coreBadges = computed<AboutPageBadge[]>(() => [
|
||||
// In electron, ComfyUI is packaged without the git repo, so the python
|
||||
// server's API doesn't have the version info.
|
||||
{
|
||||
label: `ComfyUI ${
|
||||
isDesktop
|
||||
? 'v' + electronAPI().getComfyUIVersion()
|
||||
: formatCommitHash(coreVersion.value)
|
||||
}`,
|
||||
url: isCloud ? staticUrls.comfyOrg : staticUrls.github,
|
||||
icon: isCloud ? 'pi pi-cloud' : 'pi pi-github'
|
||||
},
|
||||
{
|
||||
label: `ComfyUI_frontend v${frontendVersion}`,
|
||||
url: staticUrls.githubFrontend,
|
||||
icon: 'pi pi-github'
|
||||
},
|
||||
...(templatesVersion.value
|
||||
? [
|
||||
{
|
||||
label: `Templates v${templatesVersion.value}`,
|
||||
url: 'https://pypi.org/project/comfyui-workflow-templates/',
|
||||
icon: 'pi pi-book',
|
||||
...(isTemplatesOutdated.value ? { severity: 'danger' as const } : {})
|
||||
}
|
||||
]
|
||||
: []),
|
||||
{
|
||||
label: 'Discord',
|
||||
url: staticUrls.discord,
|
||||
icon: 'pi pi-discord'
|
||||
},
|
||||
{ label: 'ComfyOrg', url: staticUrls.comfyOrg, icon: 'pi pi-globe' }
|
||||
])
|
||||
|
||||
const badges = computed<AboutPageBadge[]>(() => [
|
||||
...coreBadges.value,
|
||||
...extensionStore.extensions.flatMap((e) => e.aboutPageBadges ?? [])
|
||||
])
|
||||
</script>
|
||||
|
||||
@@ -51,7 +51,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'
|
||||
import ToggleGroup from '@/components/ui/toggle-group/ToggleGroup.vue'
|
||||
import ToggleGroupItem from '@/components/ui/toggle-group/ToggleGroupItem.vue'
|
||||
import type { GizmoMode } from '@/extensions/core/load3d/interfaces'
|
||||
|
||||
const gizmoEnabled = defineModel<boolean>('gizmoEnabled')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex h-full shrink-0 items-center">
|
||||
<TopbarBadge
|
||||
v-for="badge in topbarBadgeStore.badges"
|
||||
v-for="badge in badges"
|
||||
:key="badge.text"
|
||||
:badge
|
||||
:display-mode="displayMode"
|
||||
@@ -15,7 +15,8 @@
|
||||
import { breakpointsTailwind, useBreakpoints } from '@vueuse/core'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { useTopbarBadgeStore } from '@/stores/topbarBadgeStore'
|
||||
import { useExtensionStore } from '@/stores/extensionStore'
|
||||
import type { TopbarBadge as TopbarBadgeType } from '@/types/comfy'
|
||||
|
||||
import TopbarBadge from './TopbarBadge.vue'
|
||||
|
||||
@@ -34,5 +35,8 @@ const displayMode = computed<'full' | 'compact' | 'icon-only'>(() => {
|
||||
return 'icon-only'
|
||||
})
|
||||
|
||||
const topbarBadgeStore = useTopbarBadgeStore()
|
||||
const extensionStore = useExtensionStore()
|
||||
const badges = computed<TopbarBadgeType[]>(() =>
|
||||
extensionStore.extensions.flatMap((e) => e.topbarBadges ?? [])
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export { default as ToggleGroup } from './ToggleGroup.vue'
|
||||
export { default as ToggleGroupItem } from './ToggleGroupItem.vue'
|
||||
@@ -1,4 +1,3 @@
|
||||
// import { useSelectedLiteGraphItems } from '@/composables/canvas/useSelectedLiteGraphItems' // Unused for now
|
||||
import { t } from '@/i18n'
|
||||
import { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
@@ -14,7 +13,6 @@ import { useDialogService } from '@/services/dialogService'
|
||||
* Composable for handling basic selection operations like copy, paste, duplicate, delete, rename
|
||||
*/
|
||||
export function useSelectionOperations() {
|
||||
// const { getSelectedNodes } = useSelectedLiteGraphItems() // Unused for now
|
||||
const canvasStore = useCanvasStore()
|
||||
const toastStore = useToastStore()
|
||||
const dialogService = useDialogService()
|
||||
|
||||
@@ -818,8 +818,6 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
options ||= {}
|
||||
this.options = options
|
||||
|
||||
// if(graph === undefined)
|
||||
// throw ("No graph assigned");
|
||||
this.background_image = LGraphCanvas.DEFAULT_BACKGROUND_IMAGE
|
||||
|
||||
this.ds = new DragAndScale(canvas)
|
||||
@@ -4178,7 +4176,6 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
}
|
||||
const { created, nodes, links, reroutes } = results
|
||||
|
||||
// const failedNodes: ISerialisedNode[] = []
|
||||
const subgraphIdMap: Record<string, string> = {}
|
||||
// SubgraphV2: Remove always-clone behaviour
|
||||
//Update subgraph ids
|
||||
|
||||
@@ -257,7 +257,7 @@ export const useWorkflowStore = defineStore('workflow', () => {
|
||||
workflowData?: ComfyWorkflowJSON
|
||||
): ComfyWorkflowJSON => {
|
||||
const base = workflowData
|
||||
? (JSON.parse(JSON.stringify(workflowData)) as ComfyWorkflowJSON)
|
||||
? structuredClone(workflowData)
|
||||
: (JSON.parse(defaultGraphJSON) as ComfyWorkflowJSON)
|
||||
|
||||
if (!base.id) {
|
||||
|
||||
@@ -184,7 +184,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'
|
||||
import ToggleGroup from '@/components/ui/toggle-group/ToggleGroup.vue'
|
||||
import ToggleGroupItem from '@/components/ui/toggle-group/ToggleGroupItem.vue'
|
||||
import { useSliderFromMouse } from '@/platform/workflow/sharing/composables/useSliderFromMouse'
|
||||
import type { ThumbnailType } from '@/platform/workflow/sharing/types/comfyHubTypes'
|
||||
import {
|
||||
|
||||
@@ -5,7 +5,8 @@ import { defineComponent } from 'vue'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'
|
||||
import ToggleGroup from '@/components/ui/toggle-group/ToggleGroup.vue'
|
||||
import ToggleGroupItem from '@/components/ui/toggle-group/ToggleGroupItem.vue'
|
||||
import type { IWidgetOptions } from '@/lib/litegraph/src/types/widgets'
|
||||
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ import ToggleSwitch from 'primevue/toggleswitch'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'
|
||||
import ToggleGroup from '@/components/ui/toggle-group/ToggleGroup.vue'
|
||||
import ToggleGroupItem from '@/components/ui/toggle-group/ToggleGroupItem.vue'
|
||||
import type { IWidgetOptions } from '@/lib/litegraph/src/types/widgets'
|
||||
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
import { useHideLayoutField } from '@/types/widgetTypes'
|
||||
|
||||
@@ -108,7 +108,6 @@ The following table lists ALL 46 store instances in the system as of 2026-01-29:
|
||||
|
||||
| File | Store | Description | Category |
|
||||
| ---------------------------- | ----------------------------- | ------------------------------------------------------- | ---------- |
|
||||
| aboutPanelStore.ts | useAboutPanelStore | Manages the About panel state and badges | UI |
|
||||
| apiKeyAuthStore.ts | useApiKeyAuthStore | Handles API key authentication | Auth |
|
||||
| comfyManagerStore.ts | useComfyManagerStore | Manages ComfyUI application state | Core |
|
||||
| comfyRegistryStore.ts | useComfyRegistryStore | Handles extensions registry | Registry |
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { useExternalLink } from '@/composables/useExternalLink'
|
||||
import { isCloud, isDesktop } from '@/platform/distribution/types'
|
||||
import type { AboutPageBadge } from '@/types/comfy'
|
||||
import { electronAPI } from '@/utils/envUtil'
|
||||
import { formatCommitHash } from '@/utils/formatUtil'
|
||||
|
||||
import { useExtensionStore } from './extensionStore'
|
||||
import { useSystemStatsStore } from './systemStatsStore'
|
||||
|
||||
export const useAboutPanelStore = defineStore('aboutPanel', () => {
|
||||
const frontendVersion = __COMFYUI_FRONTEND_VERSION__
|
||||
const extensionStore = useExtensionStore()
|
||||
const systemStatsStore = useSystemStatsStore()
|
||||
const { staticUrls } = useExternalLink()
|
||||
const coreVersion = computed(
|
||||
() => systemStatsStore?.systemStats?.system?.comfyui_version ?? ''
|
||||
)
|
||||
const templatesVersion = computed(
|
||||
() =>
|
||||
systemStatsStore?.systemStats?.system?.installed_templates_version ?? ''
|
||||
)
|
||||
const requiredTemplatesVersion = computed(
|
||||
() =>
|
||||
systemStatsStore?.systemStats?.system?.required_templates_version ?? ''
|
||||
)
|
||||
const isTemplatesOutdated = computed(
|
||||
() =>
|
||||
templatesVersion.value !== '' &&
|
||||
requiredTemplatesVersion.value !== '' &&
|
||||
templatesVersion.value !== requiredTemplatesVersion.value
|
||||
)
|
||||
|
||||
const coreBadges = computed<AboutPageBadge[]>(() => [
|
||||
// In electron, the ComfyUI is packaged without the git repo,
|
||||
// so the python server's API doesn't have the version info.
|
||||
{
|
||||
label: `ComfyUI ${
|
||||
isDesktop
|
||||
? 'v' + electronAPI().getComfyUIVersion()
|
||||
: formatCommitHash(coreVersion.value)
|
||||
}`,
|
||||
url: isCloud ? staticUrls.comfyOrg : staticUrls.github,
|
||||
icon: isCloud ? 'pi pi-cloud' : 'pi pi-github'
|
||||
},
|
||||
{
|
||||
label: `ComfyUI_frontend v${frontendVersion}`,
|
||||
url: staticUrls.githubFrontend,
|
||||
icon: 'pi pi-github'
|
||||
},
|
||||
...(templatesVersion.value
|
||||
? [
|
||||
{
|
||||
label: `Templates v${templatesVersion.value}`,
|
||||
url: 'https://pypi.org/project/comfyui-workflow-templates/',
|
||||
icon: 'pi pi-book',
|
||||
...(isTemplatesOutdated.value
|
||||
? { severity: 'danger' as const }
|
||||
: {})
|
||||
}
|
||||
]
|
||||
: []),
|
||||
{
|
||||
label: 'Discord',
|
||||
url: staticUrls.discord,
|
||||
icon: 'pi pi-discord'
|
||||
},
|
||||
{ label: 'ComfyOrg', url: staticUrls.comfyOrg, icon: 'pi pi-globe' }
|
||||
])
|
||||
|
||||
const allBadges = computed<AboutPageBadge[]>(() => [
|
||||
...coreBadges.value,
|
||||
...extensionStore.extensions.flatMap((e) => e.aboutPageBadges ?? [])
|
||||
])
|
||||
|
||||
return {
|
||||
badges: allBadges
|
||||
}
|
||||
})
|
||||
@@ -1,18 +0,0 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import type { TopbarBadge } from '@/types/comfy'
|
||||
|
||||
import { useExtensionStore } from './extensionStore'
|
||||
|
||||
export const useTopbarBadgeStore = defineStore('topbarBadge', () => {
|
||||
const extensionStore = useExtensionStore()
|
||||
|
||||
const badges = computed<TopbarBadge[]>(() =>
|
||||
extensionStore.extensions.flatMap((e) => e.topbarBadges ?? [])
|
||||
)
|
||||
|
||||
return {
|
||||
badges
|
||||
}
|
||||
})
|
||||
@@ -325,7 +325,7 @@ export const migrateLegacyRerouteNodes = (
|
||||
}
|
||||
|
||||
// Create a deep copy of the workflow to avoid mutating the original
|
||||
const newWorkflow = JSON.parse(JSON.stringify(workflow)) as WorkflowJSON04
|
||||
const newWorkflow = structuredClone(workflow) as WorkflowJSON04
|
||||
|
||||
// Initialize extra structure if needed
|
||||
if (!newWorkflow.extra) {
|
||||
|
||||
@@ -1,34 +1,15 @@
|
||||
import { v4 } from 'uuid'
|
||||
|
||||
/**
|
||||
* @deprecated Use `v4` from `uuid` directly. Kept as litegraph's public API
|
||||
* (`LiteGraph.uuidv4`, exported `createUuidv4`). uuid's v4 uses
|
||||
* crypto.getRandomValues, so it works in non-secure contexts (LAN HTTP) where
|
||||
* crypto.randomUUID() is unavailable.
|
||||
*/
|
||||
export const createUuidv4 = v4
|
||||
|
||||
// Using a template string for this is resulting in complex type workarounds. No current benefit beyond dev reading.
|
||||
export type UUID = string
|
||||
|
||||
/** Special-case zero-UUID, consisting entirely of zeros. Used as a default value. */
|
||||
export const zeroUuid = '00000000-0000-0000-0000-000000000000'
|
||||
|
||||
/** Pre-allocated storage for uuid random values. */
|
||||
const randomStorage = new Uint32Array(31)
|
||||
|
||||
/**
|
||||
* Creates a UUIDv4 string.
|
||||
* @returns A new UUIDv4 string
|
||||
* @remarks
|
||||
* Original implementation from https://gist.github.com/jed/982883?permalink_comment_id=852670#gistcomment-852670
|
||||
*
|
||||
* Prefers the {@link crypto.randomUUID} method if available, falling back to
|
||||
* {@link crypto.getRandomValues}, then finally the legacy {@link Math.random} method.
|
||||
*/
|
||||
export function createUuidv4(): UUID {
|
||||
if (typeof crypto?.randomUUID === 'function') return crypto.randomUUID()
|
||||
if (typeof crypto?.getRandomValues === 'function') {
|
||||
const random = crypto.getRandomValues(randomStorage)
|
||||
let i = 0
|
||||
return '10000000-1000-4000-8000-100000000000'.replaceAll(/[018]/g, (a) =>
|
||||
(
|
||||
Number(a) ^
|
||||
((random[i++] * 3.725_290_298_461_914e-9) >> (Number(a) * 0.25))
|
||||
).toString(16)
|
||||
)
|
||||
}
|
||||
return '10000000-1000-4000-8000-100000000000'.replaceAll(/[018]/g, (a) =>
|
||||
(Number(a) ^ ((Math.random() * 16) >> (Number(a) * 0.25))).toString(16)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -28,12 +28,6 @@ export const PANEL_EXCLUDED_PROPS = [
|
||||
'overlayClass'
|
||||
] as const
|
||||
|
||||
// export const IMAGE_EXCLUDED_PROPS = [
|
||||
// ...STANDARD_EXCLUDED_PROPS,
|
||||
// 'imageClass',
|
||||
// 'imageStyle'
|
||||
// ] as const
|
||||
|
||||
export const GALLERIA_EXCLUDED_PROPS = [
|
||||
...STANDARD_EXCLUDED_PROPS,
|
||||
'thumbnailsPosition',
|
||||
|
||||
Reference in New Issue
Block a user