From efc242b96876f8bb6674e5828aa0e2b5226c565c Mon Sep 17 00:00:00 2001 From: AustinMroz Date: Wed, 14 Jan 2026 20:49:13 -0800 Subject: [PATCH] Linear mode bug fixes (#8054) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8054-Linear-mode-bug-fixes-2e86d73d365081ed8d75d6e2af679f6c) by [Unito](https://www.unito.io) --- src/components/topbar/TopMenuHelpButton.vue | 2 +- src/composables/useCoreCommands.ts | 2 +- src/locales/en/commands.json | 2 +- src/locales/en/main.json | 4 +- .../extensions/linearMode/LinearControls.vue | 23 ++++++++-- .../extensions/linearMode/LinearPreview.vue | 4 +- .../extensions/linearMode/OutputHistory.vue | 1 + .../extensions/linearMode/Preview3d.vue | 44 +++++++++++++++++++ src/views/LinearView.vue | 11 +++-- 9 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 src/renderer/extensions/linearMode/Preview3d.vue diff --git a/src/components/topbar/TopMenuHelpButton.vue b/src/components/topbar/TopMenuHelpButton.vue index afdca83e5..b7f1fe5a8 100644 --- a/src/components/topbar/TopMenuHelpButton.vue +++ b/src/components/topbar/TopMenuHelpButton.vue @@ -4,7 +4,7 @@ variant="textonly" @click="toggleHelpCenter" > - {{ $t('menu.helpAndFeedback') }} +
{{ $t('menu.helpAndFeedback') }}
{ const newMode = !canvasStore.linearMode app.rootGraph.extra.linearMode = newMode diff --git a/src/locales/en/commands.json b/src/locales/en/commands.json index fb5f9957d..60f906db0 100644 --- a/src/locales/en/commands.json +++ b/src/locales/en/commands.json @@ -276,7 +276,7 @@ "label": "Help Center" }, "Comfy_ToggleLinear": { - "label": "toggle linear mode" + "label": "Toggle Simple Mode" }, "Comfy_ToggleQPOV2": { "label": "Toggle Queue Panel V2" diff --git a/src/locales/en/main.json b/src/locales/en/main.json index 75c4bb3fb..295b46c46 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -1187,7 +1187,7 @@ "Experimental: Enable AssetAPI": "Experimental: Enable AssetAPI", "Canvas Performance": "Canvas Performance", "Help Center": "Help Center", - "toggle linear mode": "toggle simple mode", + "toggle linear mode": "Toggle Simple Mode", "Toggle Queue Panel V2": "Toggle Queue Panel V2", "Toggle Theme (Dark/Light)": "Toggle Theme (Dark/Light)", "Undo": "Undo", @@ -2494,7 +2494,7 @@ "linearMode": "Simple Mode", "beta": "Beta - Give Feedback", "graphMode": "Graph Mode", - "dragAndDropImage": "Drag and drop an image", + "dragAndDropImage": "Click to browse or drag an image", "runCount": "Run count:", "rerun": "Rerun", "reuseParameters": "Reuse Parameters", diff --git a/src/renderer/extensions/linearMode/LinearControls.vue b/src/renderer/extensions/linearMode/LinearControls.vue index 36e3514e6..1f35caf41 100644 --- a/src/renderer/extensions/linearMode/LinearControls.vue +++ b/src/renderer/extensions/linearMode/LinearControls.vue @@ -23,6 +23,7 @@ import { useCommandStore } from '@/stores/commandStore' import { useExecutionStore } from '@/stores/executionStore' import { useQueueSettingsStore } from '@/stores/queueStore' import type { SimplifiedWidget } from '@/types/simplifiedWidget' +import { cn } from '@/utils/tailwindUtil' const commandStore = useCommandStore() const executionStore = useExecutionStore() @@ -55,13 +56,16 @@ function nodeToNodeData(node: LGraphNode) { ? undefined : { iconClass: 'icon-[lucide--image]', - label: t('linearMode.dragAndDropImage') + label: t('linearMode.dragAndDropImage'), + onClick: () => node.widgets?.[1]?.callback?.(undefined) } const nodeData = extractVueNodeData(node) for (const widget of nodeData.widgets ?? []) widget.slotMetadata = undefined return { ...nodeData, + //note lastNodeErrors uses exeuctionid, node.id is execution for root + hasErrors: !!executionStore.lastNodeErrors?.[node.id], dropIndicator, onDragDrop: node.onDragDrop, @@ -69,13 +73,18 @@ function nodeToNodeData(node: LGraphNode) { } } const partitionedNodes = computed(() => { - return partition( + const parts = partition( graphNodes.value .filter((node) => node.mode === 0 && node.widgets?.length) .map(nodeToNodeData) .reverse(), (node) => ['MarkdownNote', 'Note'].includes(node.type) ) + for (const noteNode of parts[0]) { + for (const widget of noteNode.widgets ?? []) + widget.options = { ...widget.options, read_only: true } + } + return parts }) const batchCountWidget: SimplifiedWidget = { @@ -165,7 +174,7 @@ defineExpose({ runButtonClick }) diff --git a/src/renderer/extensions/linearMode/LinearPreview.vue b/src/renderer/extensions/linearMode/LinearPreview.vue index 2e466b80e..e74a5a989 100644 --- a/src/renderer/extensions/linearMode/LinearPreview.vue +++ b/src/renderer/extensions/linearMode/LinearPreview.vue @@ -2,7 +2,6 @@ import { computed } from 'vue' import { downloadFile } from '@/base/common/downloadUtil' -import Load3dViewerContent from '@/components/load3d/Load3dViewerContent.vue' import Popover from '@/components/ui/Popover.vue' import Button from '@/components/ui/button/Button.vue' import { d, t } from '@/i18n' @@ -12,6 +11,7 @@ import type { AssetItem } from '@/platform/assets/schemas/assetSchema' import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore' import { extractWorkflowFromAsset } from '@/platform/workflow/utils/workflowExtractionUtil' import ImagePreview from '@/renderer/extensions/linearMode/ImagePreview.vue' +import Preview3d from '@/renderer/extensions/linearMode/Preview3d.vue' import VideoPreview from '@/renderer/extensions/linearMode/VideoPreview.vue' import { getMediaType, @@ -172,7 +172,7 @@ async function rerun(e: Event) { class="w-full max-w-128 m-auto my-12 overflow-y-auto" v-text="selectedOutput!.url" /> - diff --git a/src/renderer/extensions/linearMode/OutputHistory.vue b/src/renderer/extensions/linearMode/OutputHistory.vue index 2e3bd1a5e..46d7eb90e 100644 --- a/src/renderer/extensions/linearMode/OutputHistory.vue +++ b/src/renderer/extensions/linearMode/OutputHistory.vue @@ -277,6 +277,7 @@ useEventListener(document.body, 'keydown', (e: KeyboardEvent) => { 'border-2' ) " + @click="selectedIndex = [index, key]" > +import { useTemplateRef, watch } from 'vue' + +import AnimationControls from '@/components/load3d/controls/AnimationControls.vue' +import { useLoad3dViewer } from '@/composables/useLoad3dViewer' + +const { modelUrl } = defineProps<{ + modelUrl: string +}>() + +const containerRef = useTemplateRef('containerRef') + +const viewer = useLoad3dViewer() + +watch([containerRef, () => modelUrl], async () => { + if (!containerRef.value || !modelUrl) return + + await viewer.initializeStandaloneViewer(containerRef.value, modelUrl) +}) + +//TODO: refactor to add control buttons + + diff --git a/src/views/LinearView.vue b/src/views/LinearView.vue index c8c970620..d30b5f48a 100644 --- a/src/views/LinearView.vue +++ b/src/views/LinearView.vue @@ -44,7 +44,10 @@ const bottomRightRef = useTemplateRef('bottomRightRef') const linearWorkflowRef = useTemplateRef('linearWorkflowRef')