mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 11:11:53 +00:00
[ExtensionPanel] Distinguish core and 3rd party extensions (#2020)
This commit is contained in:
@@ -5,7 +5,12 @@
|
|||||||
v-model="filters['global'].value"
|
v-model="filters['global'].value"
|
||||||
:placeholder="$t('g.searchExtensions') + '...'"
|
:placeholder="$t('g.searchExtensions') + '...'"
|
||||||
/>
|
/>
|
||||||
<Message v-if="hasChanges" severity="info" pt:text="w-full">
|
<Message
|
||||||
|
v-if="hasChanges"
|
||||||
|
severity="info"
|
||||||
|
pt:text="w-full"
|
||||||
|
class="max-h-96 overflow-y-auto"
|
||||||
|
>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="ext in changedExtensions" :key="ext.name">
|
<li v-for="ext in changedExtensions" :key="ext.name">
|
||||||
<span>
|
<span>
|
||||||
@@ -30,7 +35,15 @@
|
|||||||
size="small"
|
size="small"
|
||||||
:filters="filters"
|
:filters="filters"
|
||||||
>
|
>
|
||||||
<Column field="name" :header="$t('g.extensionName')" sortable></Column>
|
<Column :header="$t('g.extensionName')" sortable>
|
||||||
|
<template #body="slotProps">
|
||||||
|
{{ slotProps.data.name }}
|
||||||
|
<Tag
|
||||||
|
v-if="extensionStore.isCoreExtension(slotProps.data.name)"
|
||||||
|
value="Core"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
<Column
|
<Column
|
||||||
:pt="{
|
:pt="{
|
||||||
headerCell: 'flex items-center justify-end',
|
headerCell: 'flex items-center justify-end',
|
||||||
@@ -48,9 +61,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #body="slotProps">
|
<template #body="slotProps">
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
:disabled="
|
:disabled="extensionStore.isExtensionReadOnly(slotProps.data.name)"
|
||||||
extensionStore.isExtensionAlwaysEnabled(slotProps.data.name)
|
|
||||||
"
|
|
||||||
v-model="editingEnabledExtensions[slotProps.data.name]"
|
v-model="editingEnabledExtensions[slotProps.data.name]"
|
||||||
@change="updateExtensionStatus"
|
@change="updateExtensionStatus"
|
||||||
/>
|
/>
|
||||||
@@ -67,6 +78,7 @@ import { useSettingStore } from '@/stores/settingStore'
|
|||||||
import DataTable from 'primevue/datatable'
|
import DataTable from 'primevue/datatable'
|
||||||
import Column from 'primevue/column'
|
import Column from 'primevue/column'
|
||||||
import ToggleSwitch from 'primevue/toggleswitch'
|
import ToggleSwitch from 'primevue/toggleswitch'
|
||||||
|
import Tag from 'primevue/tag'
|
||||||
import Button from 'primevue/button'
|
import Button from 'primevue/button'
|
||||||
import ContextMenu from 'primevue/contextmenu'
|
import ContextMenu from 'primevue/contextmenu'
|
||||||
import Message from 'primevue/message'
|
import Message from 'primevue/message'
|
||||||
@@ -117,6 +129,8 @@ const updateExtensionStatus = () => {
|
|||||||
|
|
||||||
const enableAllExtensions = () => {
|
const enableAllExtensions = () => {
|
||||||
extensionStore.extensions.forEach((ext) => {
|
extensionStore.extensions.forEach((ext) => {
|
||||||
|
if (extensionStore.isExtensionReadOnly(ext.name)) return
|
||||||
|
|
||||||
editingEnabledExtensions.value[ext.name] = true
|
editingEnabledExtensions.value[ext.name] = true
|
||||||
})
|
})
|
||||||
updateExtensionStatus()
|
updateExtensionStatus()
|
||||||
@@ -124,7 +138,16 @@ const enableAllExtensions = () => {
|
|||||||
|
|
||||||
const disableAllExtensions = () => {
|
const disableAllExtensions = () => {
|
||||||
extensionStore.extensions.forEach((ext) => {
|
extensionStore.extensions.forEach((ext) => {
|
||||||
if (extensionStore.isExtensionAlwaysEnabled(ext.name)) return
|
if (extensionStore.isExtensionReadOnly(ext.name)) return
|
||||||
|
|
||||||
|
editingEnabledExtensions.value[ext.name] = false
|
||||||
|
})
|
||||||
|
updateExtensionStatus()
|
||||||
|
}
|
||||||
|
|
||||||
|
const disableThirdPartyExtensions = () => {
|
||||||
|
extensionStore.extensions.forEach((ext) => {
|
||||||
|
if (extensionStore.isCoreExtension(ext.name)) return
|
||||||
|
|
||||||
editingEnabledExtensions.value[ext.name] = false
|
editingEnabledExtensions.value[ext.name] = false
|
||||||
})
|
})
|
||||||
@@ -147,6 +170,12 @@ const contextMenuItems = [
|
|||||||
label: 'Disable All',
|
label: 'Disable All',
|
||||||
icon: 'pi pi-times',
|
icon: 'pi pi-times',
|
||||||
command: disableAllExtensions
|
command: disableAllExtensions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Disable 3rd Party',
|
||||||
|
icon: 'pi pi-times',
|
||||||
|
command: disableThirdPartyExtensions,
|
||||||
|
disabled: !extensionStore.hasThirdPartyExtensions
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1640,13 +1640,15 @@ export class ComfyApp {
|
|||||||
* Loads all extensions from the API into the window in parallel
|
* Loads all extensions from the API into the window in parallel
|
||||||
*/
|
*/
|
||||||
async #loadExtensions() {
|
async #loadExtensions() {
|
||||||
useExtensionStore().loadDisabledExtensionNames()
|
const extensionStore = useExtensionStore()
|
||||||
|
extensionStore.loadDisabledExtensionNames()
|
||||||
|
|
||||||
const extensions = await api.getExtensions()
|
const extensions = await api.getExtensions()
|
||||||
|
|
||||||
// Need to load core extensions first as some custom extensions
|
// Need to load core extensions first as some custom extensions
|
||||||
// may depend on them.
|
// may depend on them.
|
||||||
await import('../extensions/core/index')
|
await import('../extensions/core/index')
|
||||||
|
extensionStore.captureCoreExtensions()
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
extensions
|
extensions
|
||||||
.filter((extension) => !extension.includes('extensions/core'))
|
.filter((extension) => !extension.includes('extensions/core'))
|
||||||
|
|||||||
@@ -19,6 +19,17 @@ export const ALWAYS_ENABLED_EXTENSIONS: readonly string[] = [
|
|||||||
'Comfy.ColorPalette'
|
'Comfy.ColorPalette'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export const ALWAYS_DISABLED_EXTENSIONS: readonly string[] = [
|
||||||
|
// pysssss.Locking is replaced by pin/unpin in ComfyUI core.
|
||||||
|
// https://github.com/Comfy-Org/litegraph.js/pull/117
|
||||||
|
'pysssss.Locking',
|
||||||
|
// pysssss.SnapToGrid is replaced by Comfy.Graph.AlwaysSnapToGrid in ComfyUI core.
|
||||||
|
// pysssss.SnapToGrid tries to write global app.shiftDown state, which is no longer
|
||||||
|
// allowed since v1.3.12.
|
||||||
|
// https://github.com/Comfy-Org/ComfyUI_frontend/issues/1176
|
||||||
|
'pysssss.SnapToGrid'
|
||||||
|
]
|
||||||
|
|
||||||
export const useExtensionStore = defineStore('extension', () => {
|
export const useExtensionStore = defineStore('extension', () => {
|
||||||
// For legacy reasons, the name uniquely identifies an extension
|
// For legacy reasons, the name uniquely identifies an extension
|
||||||
const extensionByName = ref<Record<string, ComfyExtension>>({})
|
const extensionByName = ref<Record<string, ComfyExtension>>({})
|
||||||
@@ -42,8 +53,11 @@ export const useExtensionStore = defineStore('extension', () => {
|
|||||||
return extensions.value.filter((ext) => isExtensionEnabled(ext.name))
|
return extensions.value.filter((ext) => isExtensionEnabled(ext.name))
|
||||||
})
|
})
|
||||||
|
|
||||||
function isExtensionAlwaysEnabled(name: string) {
|
function isExtensionReadOnly(name: string) {
|
||||||
return ALWAYS_ENABLED_EXTENSIONS.includes(name)
|
return (
|
||||||
|
ALWAYS_DISABLED_EXTENSIONS.includes(name) ||
|
||||||
|
ALWAYS_ENABLED_EXTENSIONS.includes(name)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerExtension(extension: ComfyExtension) {
|
function registerExtension(extension: ComfyExtension) {
|
||||||
@@ -86,20 +100,31 @@ export const useExtensionStore = defineStore('extension', () => {
|
|||||||
disabledExtensionNames.value = new Set(
|
disabledExtensionNames.value = new Set(
|
||||||
useSettingStore().get('Comfy.Extension.Disabled')
|
useSettingStore().get('Comfy.Extension.Disabled')
|
||||||
)
|
)
|
||||||
// pysssss.Locking is replaced by pin/unpin in ComfyUI core.
|
for (const name of ALWAYS_DISABLED_EXTENSIONS) {
|
||||||
// https://github.com/Comfy-Org/litegraph.js/pull/117
|
disabledExtensionNames.value.add(name)
|
||||||
disabledExtensionNames.value.add('pysssss.Locking')
|
}
|
||||||
// pysssss.SnapToGrid is replaced by Comfy.Graph.AlwaysSnapToGrid in ComfyUI core.
|
|
||||||
// pysssss.SnapToGrid tries to write global app.shiftDown state, which is no longer
|
|
||||||
// allowed since v1.3.12.
|
|
||||||
// https://github.com/Comfy-Org/ComfyUI_frontend/issues/1176
|
|
||||||
disabledExtensionNames.value.add('pysssss.SnapToGrid')
|
|
||||||
|
|
||||||
for (const name of ALWAYS_ENABLED_EXTENSIONS) {
|
for (const name of ALWAYS_ENABLED_EXTENSIONS) {
|
||||||
disabledExtensionNames.value.delete(name)
|
disabledExtensionNames.value.delete(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core extensions are extensions that are defined in the core package.
|
||||||
|
* See /extensions/core/index.ts for the list.
|
||||||
|
*/
|
||||||
|
const coreExtensionNames = ref<string[]>([])
|
||||||
|
function captureCoreExtensions() {
|
||||||
|
coreExtensionNames.value = app.extensions.map((ext) => ext.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isCoreExtension(name: string) {
|
||||||
|
return coreExtensionNames.value.includes(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasThirdPartyExtensions = computed(() => {
|
||||||
|
return extensions.value.some((ext) => !isCoreExtension(ext.name))
|
||||||
|
})
|
||||||
|
|
||||||
// Some core extensions are registered before the store is initialized, e.g.
|
// Some core extensions are registered before the store is initialized, e.g.
|
||||||
// colorPalette.
|
// colorPalette.
|
||||||
// Register them manually here so the state of app.extensions and
|
// Register them manually here so the state of app.extensions and
|
||||||
@@ -113,8 +138,11 @@ export const useExtensionStore = defineStore('extension', () => {
|
|||||||
enabledExtensions,
|
enabledExtensions,
|
||||||
inactiveDisabledExtensionNames,
|
inactiveDisabledExtensionNames,
|
||||||
isExtensionEnabled,
|
isExtensionEnabled,
|
||||||
isExtensionAlwaysEnabled,
|
isExtensionReadOnly,
|
||||||
registerExtension,
|
registerExtension,
|
||||||
loadDisabledExtensionNames
|
loadDisabledExtensionNames,
|
||||||
|
captureCoreExtensions,
|
||||||
|
isCoreExtension,
|
||||||
|
hasThirdPartyExtensions
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user