Files
ComfyUI_frontend/src/renderer/extensions/vueNodes/preview/useNodePreviewState.ts
Christian Byrne 0483630f82 Show sampling previews on Vue nodes (#5579)
* refactor: simplify preview state provider

- Remove unnecessary event listeners and manual syncing
- Use computed() to directly reference app.nodePreviewImages
- Eliminate data duplication and any types
- Rely on Vue's reactivity for automatic updates
- Follow established patterns from execution state provider

* feat: optimize Vue node preview image display with reactive store

- Move preview display logic from inline ternaries to computed properties
- Add useNodePreviewState composable for preview state management
- Implement reactive store approach using Pinia storeToRefs
- Use VueUse useTimeoutFn for modern timeout management instead of window.setTimeout
- Add v-memo optimization for preview image template rendering
- Maintain proper sync between app.nodePreviewImages and reactive store state

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: update props usage for Vue 3.5 destructured props syntax

* [refactor] improve code style and architecture based on review feedback

- Replace inject pattern with direct store access in useNodePreviewState
- Use optional chaining for more concise conditional checks
- Use modern Array.at(-1) for accessing last element
- Remove provide/inject for nodePreviewImages in favor of direct store refs
- Update preview image styling: remove rounded borders, use flexible height
- Simplify scheduleRevoke function with optional chaining

Co-authored-by: DrJKL <DrJKL@users.noreply.github.com>

* [cleanup] remove unused NodePreviewImagesKey injection key

Addresses knip unused export warning after switching from provide/inject
to direct store access pattern.

* [test] add mock for useNodePreviewState in LGraphNode test

Fixes test failure after adding preview functionality to LGraphNode component.

* [fix] update workflowStore import path after rebase

Updates import to new location: @/platform/workflow/management/stores/workflowStore

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: DrJKL <DrJKL@users.noreply.github.com>
2025-09-16 17:34:04 -07:00

52 lines
1.3 KiB
TypeScript

import { storeToRefs } from 'pinia'
import { type Ref, computed } from 'vue'
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
export const useNodePreviewState = (
nodeId: string,
options?: {
isMinimalLOD?: Ref<boolean>
isCollapsed?: Ref<boolean>
}
) => {
const workflowStore = useWorkflowStore()
const { nodePreviewImages } = storeToRefs(useNodeOutputStore())
const locatorId = computed(() => workflowStore.nodeIdToNodeLocatorId(nodeId))
const previewUrls = computed(() => {
const key = locatorId.value
if (!key) return undefined
const urls = nodePreviewImages.value[key]
return urls?.length ? urls : undefined
})
const hasPreview = computed(() => !!previewUrls.value?.length)
const latestPreviewUrl = computed(() => {
const urls = previewUrls.value
return urls?.length ? urls.at(-1) : ''
})
const shouldShowPreviewImg = computed(() => {
if (!options?.isMinimalLOD || !options?.isCollapsed) {
return hasPreview.value
}
return (
!options.isMinimalLOD.value &&
!options.isCollapsed.value &&
hasPreview.value
)
})
return {
locatorId,
previewUrls,
hasPreview,
latestPreviewUrl,
shouldShowPreviewImg
}
}