Feat: Remove the Nodes 2.0 Trial Banner (#7390)

## Summary

The option to try it out is still in the Menu if you're looking for it.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7390-Feat-Remove-the-Nodes-2-0-Trial-Banner-2c66d73d365081c3817ad5c89dd4029b)
by [Unito](https://www.unito.io)

---------

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Alexander Brown
2025-12-11 17:13:26 -08:00
committed by GitHub
parent ac8c3847d2
commit 03e9dd4789
20 changed files with 1 additions and 184 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 109 KiB

View File

@@ -4,7 +4,6 @@
synced with the stateStorage (localStorage). -->
<LiteGraphCanvasSplitterOverlay v-if="comfyAppReady">
<template v-if="showUI" #workflow-tabs>
<TryVueNodeBanner />
<div
v-if="workflowTabsPosition === 'Topbar'"
class="workflow-tabs-container pointer-events-auto relative h-9.5 w-full"
@@ -161,7 +160,6 @@ import { useSearchBoxStore } from '@/stores/workspace/searchBoxStore'
import { useWorkspaceStore } from '@/stores/workspaceStore'
import { isNativeWindow } from '@/utils/envUtil'
import TryVueNodeBanner from '../topbar/TryVueNodeBanner.vue'
import SelectionRectangle from './SelectionRectangle.vue'
const emit = defineEmits<{

View File

@@ -1,79 +0,0 @@
<template>
<Toast
group="vue-nodes-migration"
position="bottom-center"
class="w-auto"
@close="handleClose"
>
<template #message>
<div class="flex flex-auto items-center justify-between gap-4">
<span class="whitespace-nowrap">{{
t('vueNodesMigration.message')
}}</span>
<Button
class="whitespace-nowrap"
size="small"
:label="t('vueNodesMigration.button')"
text
@click="switchBack"
/>
</div>
</template>
</Toast>
<Toast
group="vue-nodes-check-main-menu"
position="bottom-center"
class="w-auto"
>
<template #message>
<div class="flex flex-auto items-center justify-between gap-4">
<span class="whitespace-nowrap">{{
t('vueNodesMigrationMainMenu.message')
}}</span>
</div>
</template>
</Toast>
</template>
<script setup lang="ts">
import { useToast } from 'primevue'
import Button from 'primevue/button'
import Toast from 'primevue/toast'
import { useI18n } from 'vue-i18n'
import { useVueNodesMigrationDismissed } from '@/composables/useVueNodesMigrationDismissed'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import { useToastStore } from '@/platform/updates/common/toastStore'
const { t } = useI18n()
const toast = useToast()
const isDismissed = useVueNodesMigrationDismissed()
const switchBack = async () => {
await disableVueNodes()
toast.removeGroup('vue-nodes-migration')
isDismissed.value = true
showMainMenuToast()
}
const handleClose = () => {
isDismissed.value = true
showMainMenuToast()
}
const disableVueNodes = async () => {
await useSettingStore().set('Comfy.VueNodes.Enabled', false)
useTelemetry()?.trackUiButtonClicked({
button_id: `vue_nodes_migration_toast_switch_back_clicked`
})
}
const showMainMenuToast = () => {
useToastStore().add({
group: 'vue-nodes-check-main-menu',
severity: 'info',
life: 5000
})
}
</script>

View File

@@ -1,74 +0,0 @@
<template>
<div
v-if="showVueNodesBanner"
class="pointer-events-auto relative w-full h-10 bg-gradient-to-r from-blue-600 to-blue-700 flex items-center justify-center px-4"
>
<div class="flex items-center text-sm text-white">
<i class="icon-[lucide--rocket]"></i>
<span class="pl-2">{{ $t('vueNodesBanner.title') }}</span>
<span class="pl-1.5 hidden md:inline">{{
$t('vueNodesBanner.desc')
}}</span>
<Button
class="cursor-pointer bg-transparent rounded h-7 px-3 border border-white text-white ml-4 text-xs"
@click="handleTryItOut"
>
{{ $t('vueNodesBanner.tryItOut') }}
</Button>
</div>
<Button
class="cursor-pointer bg-transparent border-0 outline-0 grid place-items-center absolute right-4 text-white"
unstyled
@click="handleDismiss"
>
<i class="w-5 h-5 icon-[lucide--x]"></i>
</Button>
</div>
</template>
<script setup lang="ts">
import { useLocalStorage } from '@vueuse/core'
import Button from 'primevue/button'
import { computed } from 'vue'
import { useSettingStore } from '@/platform/settings/settingStore'
const STORAGE_KEY = 'vueNodesBannerDismissed'
const settingStore = useSettingStore()
const bannerDismissed = useLocalStorage(STORAGE_KEY, false)
const vueNodesEnabled = computed(() => {
try {
return settingStore.get('Comfy.VueNodes.Enabled') ?? false
} catch {
return false
}
})
const showVueNodesBanner = computed(() => {
if (vueNodesEnabled.value) {
return false
}
if (bannerDismissed.value) {
return false
}
return true
})
const handleDismiss = (): void => {
bannerDismissed.value = true
}
const handleTryItOut = async (): Promise<void> => {
try {
await settingStore.set('Comfy.VueNodes.Enabled', true)
} catch (error) {
console.error('Failed to enable Nodes 2.0:', error)
} finally {
handleDismiss()
}
}
</script>

View File

@@ -4,7 +4,6 @@ import { shallowRef, watch } from 'vue'
import { useGraphNodeManager } from '@/composables/graph/useGraphNodeManager'
import type { GraphNodeManager } from '@/composables/graph/useGraphNodeManager'
import { useVueFeatureFlags } from '@/composables/useVueFeatureFlags'
import { useVueNodesMigrationDismissed } from '@/composables/useVueNodesMigrationDismissed'
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations'
@@ -13,7 +12,6 @@ import { useLayoutSync } from '@/renderer/core/layout/sync/useLayoutSync'
import { removeNodeTitleHeight } from '@/renderer/core/layout/utils/nodeSizeUtil'
import { ensureCorrectLayoutScale } from '@/renderer/extensions/vueNodes/layout/ensureCorrectLayoutScale'
import { app as comfyApp } from '@/scripts/app'
import { useToastStore } from '@/platform/updates/common/toastStore'
function useVueNodeLifecycleIndividual() {
const canvasStore = useCanvasStore()
@@ -22,10 +20,6 @@ function useVueNodeLifecycleIndividual() {
const nodeManager = shallowRef<GraphNodeManager | null>(null)
const { startSync } = useLayoutSync()
const isVueNodeToastDismissed = useVueNodesMigrationDismissed()
let hasShownMigrationToast = false
const initializeNodeManager = () => {
// Use canvas graph if available (handles subgraph contexts), fallback to app graph
const activeGraph = comfyApp.canvas?.graph
@@ -83,24 +77,12 @@ function useVueNodeLifecycleIndividual() {
// Watch for Vue nodes enabled state changes
watch(
() => shouldRenderVueNodes.value && Boolean(comfyApp.canvas?.graph),
(enabled, wasEnabled) => {
(enabled) => {
if (enabled) {
initializeNodeManager()
ensureCorrectLayoutScale(
comfyApp.canvas?.graph?.extra.workflowRendererVersion
)
if (
wasEnabled === false &&
!isVueNodeToastDismissed.value &&
!hasShownMigrationToast
) {
hasShownMigrationToast = true
useToastStore().add({
group: 'vue-nodes-migration',
severity: 'info',
life: 0
})
}
}
},
{ immediate: true }

View File

@@ -1,8 +0,0 @@
import { createSharedComposable, useLocalStorage } from '@vueuse/core'
// Browser storage events don't fire in the same tab, so separate
// useLocalStorage() calls create isolated reactive refs. Use shared
// composable to ensure all components use the same ref instance.
export const useVueNodesMigrationDismissed = createSharedComposable(() =>
useLocalStorage('comfy.vueNodesMigration.dismissed', false)
)

View File

@@ -17,7 +17,6 @@
<GlobalToast />
<RerouteMigrationToast />
<VueNodesMigrationToast />
<UnloadWindowConfirmDialog v-if="!isElectron()" />
<MenuHamburger />
</template>
@@ -44,7 +43,6 @@ import UnloadWindowConfirmDialog from '@/components/dialog/UnloadWindowConfirmDi
import GraphCanvas from '@/components/graph/GraphCanvas.vue'
import GlobalToast from '@/components/toast/GlobalToast.vue'
import RerouteMigrationToast from '@/components/toast/RerouteMigrationToast.vue'
import VueNodesMigrationToast from '@/components/toast/VueNodesMigrationToast.vue'
import { useBrowserTabTitle } from '@/composables/useBrowserTabTitle'
import { useCoreCommands } from '@/composables/useCoreCommands'
import { useErrorHandling } from '@/composables/useErrorHandling'