mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-07 16:40:05 +00:00
feat: hide capture button when 'On Run' mode is selected in webcam widget
- Add updateVueWidgetOptions to GraphNodeManager to update widget options and trigger Vue reactivity - Implement capture button visibility toggle based on capture_on_queue value - Default capture mode to 'Manually' (false) - Use Vue watch to reactively hide/show capture button when mode changes
This commit is contained in:
@@ -75,6 +75,13 @@ export interface GraphNodeManager {
|
||||
// Access to original LiteGraph nodes (non-reactive)
|
||||
getNode(id: string): LGraphNode | undefined
|
||||
|
||||
// Update widget options (e.g., hidden, disabled) - triggers Vue reactivity
|
||||
updateVueWidgetOptions(
|
||||
nodeId: string,
|
||||
widgetName: string,
|
||||
options: Record<string, unknown>
|
||||
): void
|
||||
|
||||
// Lifecycle methods
|
||||
cleanup(): void
|
||||
}
|
||||
@@ -298,6 +305,35 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates Vue state when widget options change (e.g., hidden, disabled)
|
||||
*/
|
||||
const updateVueWidgetOptions = (
|
||||
nodeId: string,
|
||||
widgetName: string,
|
||||
options: Record<string, unknown>
|
||||
): void => {
|
||||
try {
|
||||
const currentData = vueNodeData.get(nodeId)
|
||||
if (!currentData?.widgets) return
|
||||
|
||||
const updatedWidgets = currentData.widgets.map((w) =>
|
||||
w.name === widgetName
|
||||
? { ...w, options: { ...w.options, ...options } }
|
||||
: w
|
||||
)
|
||||
// Create a completely new object to ensure Vue reactivity triggers
|
||||
const updatedData = {
|
||||
...currentData,
|
||||
widgets: updatedWidgets
|
||||
}
|
||||
|
||||
vueNodeData.set(nodeId, updatedData)
|
||||
} catch (error) {
|
||||
// Ignore widget update errors to prevent cascade failures
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a wrapped callback for a widget that maintains LiteGraph/Vue sync
|
||||
*/
|
||||
@@ -624,6 +660,7 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager {
|
||||
return {
|
||||
vueNodeData,
|
||||
getNode,
|
||||
updateVueWidgetOptions,
|
||||
cleanup
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,9 +58,11 @@ import {
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
ref,
|
||||
toRaw
|
||||
toRaw,
|
||||
watch
|
||||
} from 'vue'
|
||||
|
||||
import { useVueNodeLifecycle } from '@/composables/graph/useVueNodeLifecycle'
|
||||
import { t } from '@/i18n'
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
|
||||
import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets'
|
||||
@@ -70,6 +72,8 @@ import { api } from '@/scripts/api'
|
||||
import { app } from '@/scripts/app'
|
||||
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
|
||||
const { nodeManager } = useVueNodeLifecycle()
|
||||
|
||||
const props = defineProps<{
|
||||
widget: SimplifiedWidget<string | number | undefined>
|
||||
readonly?: boolean
|
||||
@@ -149,7 +153,10 @@ function applyWidgetVisibility(
|
||||
// Mutate in place to preserve object identity for serializeValue closure
|
||||
widget.type = 'selectToggle'
|
||||
widget.label = 'Capture Image'
|
||||
widget.value = widget.value ?? false
|
||||
// Default to false (Manual mode) - only set if undefined/null
|
||||
if (widget.value === undefined || widget.value === null) {
|
||||
widget.value = false
|
||||
}
|
||||
widget.options = {
|
||||
...widget.options,
|
||||
hidden,
|
||||
@@ -196,6 +203,53 @@ function createActionWidget({
|
||||
}
|
||||
}
|
||||
|
||||
function updateCaptureButtonVisibility(isOnRunMode: boolean) {
|
||||
withLitegraphNode((node) => {
|
||||
// Update the LiteGraph widget options
|
||||
const captureWidget = node.widgets?.find(
|
||||
(w) => w.name === CAPTURE_WIDGET_NAME
|
||||
)
|
||||
if (captureWidget) {
|
||||
captureWidget.options = {
|
||||
...captureWidget.options,
|
||||
hidden: isOnRunMode
|
||||
}
|
||||
}
|
||||
|
||||
// Update Vue state directly to trigger reactivity
|
||||
nodeManager.value?.updateVueWidgetOptions(
|
||||
String(node.id),
|
||||
CAPTURE_WIDGET_NAME,
|
||||
{ hidden: isOnRunMode }
|
||||
)
|
||||
|
||||
app.graph.setDirtyCanvas(true, true)
|
||||
})
|
||||
}
|
||||
|
||||
// Computed to get capture_on_queue widget value from Vue state
|
||||
const captureOnQueueValue = computed(() => {
|
||||
const vueNodeData = nodeManager.value?.vueNodeData.get(props.nodeId)
|
||||
const widget = vueNodeData?.widgets?.find(
|
||||
(w) => w.name === 'capture_on_queue'
|
||||
)
|
||||
return widget?.value === true
|
||||
})
|
||||
|
||||
function setupCaptureOnQueueWatcher() {
|
||||
// Set initial visibility
|
||||
updateCaptureButtonVisibility(captureOnQueueValue.value)
|
||||
|
||||
// Watch for changes using Vue reactivity
|
||||
watch(
|
||||
captureOnQueueValue,
|
||||
(isOnRunMode) => {
|
||||
updateCaptureButtonVisibility(isOnRunMode)
|
||||
},
|
||||
{ immediate: false }
|
||||
)
|
||||
}
|
||||
|
||||
function removeWidgetsByName(names: string[]) {
|
||||
withLitegraphNode((node) => {
|
||||
if (!node.widgets?.length) return
|
||||
@@ -288,6 +342,12 @@ function setupSerializeValue() {
|
||||
|
||||
function showWidgets() {
|
||||
withLitegraphNode((node) => {
|
||||
// Get current capture_on_queue value to determine initial button visibility
|
||||
const captureOnQueueWidget = node.widgets?.find(
|
||||
(w) => w.name === 'capture_on_queue'
|
||||
)
|
||||
const isOnRunMode = captureOnQueueWidget?.value === true
|
||||
|
||||
updateNodeWidgets(node, (widgets) => {
|
||||
const sanitizedWidgets = widgets
|
||||
.map((widget) => applyWidgetVisibility(widget, false))
|
||||
@@ -304,8 +364,19 @@ function showWidgets() {
|
||||
onClick: () => captureImage(node)
|
||||
})
|
||||
|
||||
// Hide capture button if in "On Run" mode
|
||||
if (isOnRunMode) {
|
||||
captureWidget.options = {
|
||||
...captureWidget.options,
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
|
||||
return [...sanitizedWidgets, captureWidget]
|
||||
})
|
||||
|
||||
// Set up watcher to toggle capture button visibility when mode changes
|
||||
setupCaptureOnQueueWatcher()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user