Skip to content

Commit

Permalink
Fix routing and layout issue (#923)
Browse files Browse the repository at this point in the history
* fix router and move graph related parts to GraphView.vue

* (fix) add back child element in UnloadWindowConfirmDialog

* (cleanup) remove empty callback
  • Loading branch information
dmx974 authored and huchenlei committed Sep 23, 2024
1 parent c7a6249 commit eb597f5
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 168 deletions.
165 changes: 2 additions & 163 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,183 +4,22 @@
v-if="isLoading"
class="absolute inset-0 flex justify-center items-center h-screen"
/>
<BlockUI full-screen :blocked="isLoading" />
<GlobalDialog />
<GlobalToast />
<UnloadWindowConfirmDialog />
<BrowserTabTitle />
<AppMenu />
<BlockUI full-screen :blocked="isLoading" />
</template>

<script setup lang="ts">
import {
computed,
markRaw,
onMounted,
onUnmounted,
watch,
watchEffect
} from 'vue'
import config from '@/config'
import { app } from '@/scripts/app'
import { useSettingStore } from '@/stores/settingStore'
import { useI18n } from 'vue-i18n'
import { computed, onMounted, onBeforeUnmount } from 'vue'
import { useWorkspaceStore } from '@/stores/workspaceStateStore'
import { api } from '@/scripts/api'
import { StatusWsMessageStatus } from '@/types/apiTypes'
import { useQueuePendingTaskCountStore } from '@/stores/queueStore'
import type { ToastMessageOptions } from 'primevue/toast'
import { useToast } from 'primevue/usetoast'
import { i18n } from '@/i18n'
import { useExecutionStore } from '@/stores/executionStore'
import { useWorkflowBookmarkStore, useWorkflowStore } from '@/stores/workflowStore'
import BlockUI from 'primevue/blockui'
import ProgressSpinner from 'primevue/progressspinner'
import QueueSidebarTab from '@/components/sidebar/tabs/QueueSidebarTab.vue'
import NodeLibrarySidebarTab from '@/components/sidebar/tabs/NodeLibrarySidebarTab.vue'
import GlobalDialog from '@/components/dialog/GlobalDialog.vue'
import GlobalToast from '@/components/toast/GlobalToast.vue'
import UnloadWindowConfirmDialog from '@/components/dialog/UnloadWindowConfirmDialog.vue'
import BrowserTabTitle from '@/components/BrowserTabTitle.vue'
import AppMenu from '@/components/appMenu/AppMenu.vue'
import WorkflowsSidebarTab from './components/sidebar/tabs/WorkflowsSidebarTab.vue'
import { setupAutoQueueHandler } from './services/autoQueueService'
const isLoading = computed<boolean>(() => useWorkspaceStore().spinner)
const { t } = useI18n()
const toast = useToast()
const settingStore = useSettingStore()
const queuePendingTaskCountStore = useQueuePendingTaskCountStore()
const executionStore = useExecutionStore()
const workflowStore = useWorkflowStore()
const workflowBookmarkStore = useWorkflowBookmarkStore()
const theme = computed<string>(() => settingStore.get('Comfy.ColorPalette'))
watch(
theme,
(newTheme) => {
const DARK_THEME_CLASS = 'dark-theme'
const isDarkTheme = newTheme !== 'light'
if (isDarkTheme) {
document.body.classList.add(DARK_THEME_CLASS)
} else {
document.body.classList.remove(DARK_THEME_CLASS)
}
},
{ immediate: true }
)
setupAutoQueueHandler()
watchEffect(() => {
const fontSize = settingStore.get('Comfy.TextareaWidget.FontSize')
document.documentElement.style.setProperty(
'--comfy-textarea-font-size',
`${fontSize}px`
)
})
watchEffect(() => {
const padding = settingStore.get('Comfy.TreeExplorer.ItemPadding')
document.documentElement.style.setProperty(
'--comfy-tree-explorer-item-padding',
`${padding}px`
)
})
watchEffect(() => {
const locale = settingStore.get('Comfy.Locale')
if (locale) {
i18n.global.locale.value = locale as 'en' | 'zh'
}
})
const init = () => {
settingStore.addSettings(app.ui.settings)
app.extensionManager = useWorkspaceStore()
app.extensionManager.registerSidebarTab({
id: 'queue',
icon: 'pi pi-history',
iconBadge: () => {
const value = useQueuePendingTaskCountStore().count.toString()
return value === '0' ? null : value
},
title: t('sideToolbar.queue'),
tooltip: t('sideToolbar.queue'),
component: markRaw(QueueSidebarTab),
type: 'vue'
})
app.extensionManager.registerSidebarTab({
id: 'node-library',
icon: 'pi pi-book',
title: t('sideToolbar.nodeLibrary'),
tooltip: t('sideToolbar.nodeLibrary'),
component: markRaw(NodeLibrarySidebarTab),
type: 'vue'
})
app.extensionManager.registerSidebarTab({
id: 'workflows',
icon: 'pi pi-folder-open',
iconBadge: () => {
const value = useWorkflowStore().openWorkflows.length.toString()
return value === '0' ? null : value
},
title: t('sideToolbar.workflows'),
tooltip: t('sideToolbar.workflows'),
component: markRaw(WorkflowsSidebarTab),
type: 'vue'
})
}
const onStatus = (e: CustomEvent<StatusWsMessageStatus>) => {
queuePendingTaskCountStore.update(e)
}
const reconnectingMessage: ToastMessageOptions = {
severity: 'error',
summary: t('reconnecting')
}
const onReconnecting = () => {
toast.remove(reconnectingMessage)
toast.add(reconnectingMessage)
}
const onReconnected = () => {
toast.remove(reconnectingMessage)
toast.add({
severity: 'success',
summary: t('reconnected'),
life: 2000
})
}
app.workflowManager.executionStore = executionStore
app.workflowManager.workflowStore = workflowStore
app.workflowManager.workflowBookmarkStore = workflowBookmarkStore
onMounted(() => {
window['__COMFYUI_FRONTEND_VERSION__'] = config.app_version
console.log('ComfyUI Front-end version:', config.app_version)
api.addEventListener('status', onStatus)
api.addEventListener('reconnecting', onReconnecting)
api.addEventListener('reconnected', onReconnected)
executionStore.bindExecutionEvents()
try {
init()
} catch (e) {
console.error('Failed to init ComfyUI frontend', e)
}
})
onUnmounted(() => {
api.removeEventListener('status', onStatus)
api.removeEventListener('reconnecting', onReconnecting)
api.removeEventListener('reconnected', onReconnected)
executionStore.unbindExecutionEvents()
})
</script>
14 changes: 9 additions & 5 deletions src/components/dialog/UnloadWindowConfirmDialog.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
<template>
<div>
<!-- This component does not render anything visible. It is used to confirm
the user wants to close the window, and if they do, it will call the
beforeunload event. -->
<!--
UnloadWindowConfirmDialog: This component does not render
anything visible. It is used to confirm the user wants to
close the window, and if they do, it will call the
beforeunload event.
-->
</div>
</template>

<script setup lang="ts">
import { useSettingStore } from '@/stores/settingStore'
import { onMounted, onUnmounted } from 'vue'
import { onMounted, onBeforeUnmount } from 'vue'
const settingStore = useSettingStore()
const handleBeforeUnload = (event: BeforeUnloadEvent) => {
if (settingStore.get('Comfy.Window.UnloadConfirmation')) {
event.preventDefault()
Expand All @@ -23,7 +27,7 @@ onMounted(() => {
window.addEventListener('beforeunload', handleBeforeUnload)
})
onUnmounted(() => {
onBeforeUnmount(() => {
window.removeEventListener('beforeunload', handleBeforeUnload)
})
</script>
149 changes: 149 additions & 0 deletions src/views/GraphView.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,156 @@
<template>
<GraphCanvas />
<GlobalToast />
<UnloadWindowConfirmDialog />
<BrowserTabTitle />
</template>

<script setup lang="ts">
import GraphCanvas from '@/components/graph/GraphCanvas.vue'
import {
computed,
markRaw,
onMounted,
onBeforeUnmount,
watch,
watchEffect
} from 'vue'
import { app } from '@/scripts/app'
import { useSettingStore } from '@/stores/settingStore'
import { useI18n } from 'vue-i18n'
import { useWorkspaceStore } from '@/stores/workspaceStateStore'
import { api } from '@/scripts/api'
import { StatusWsMessageStatus } from '@/types/apiTypes'
import { useQueuePendingTaskCountStore } from '@/stores/queueStore'
import type { ToastMessageOptions } from 'primevue/toast'
import { useToast } from 'primevue/usetoast'
import { i18n } from '@/i18n'
import { useExecutionStore } from '@/stores/executionStore'
import { useWorkflowStore } from '@/stores/workflowStore'
import QueueSidebarTab from '@/components/sidebar/tabs/QueueSidebarTab.vue'
import NodeLibrarySidebarTab from '@/components/sidebar/tabs/NodeLibrarySidebarTab.vue'
import GlobalToast from '@/components/toast/GlobalToast.vue'
import UnloadWindowConfirmDialog from '@/components/dialog/UnloadWindowConfirmDialog.vue'
import BrowserTabTitle from '@/components/BrowserTabTitle.vue'
const { t } = useI18n()
const toast = useToast()
const settingStore = useSettingStore()
const executionStore = useExecutionStore()
const theme = computed<string>(() => settingStore.get('Comfy.ColorPalette'))
watch(
theme,
(newTheme) => {
const DARK_THEME_CLASS = 'dark-theme'
const isDarkTheme = newTheme !== 'light'
if (isDarkTheme) {
document.body.classList.add(DARK_THEME_CLASS)
} else {
document.body.classList.remove(DARK_THEME_CLASS)
}
},
{ immediate: true }
)
watchEffect(() => {
const fontSize = settingStore.get('Comfy.TextareaWidget.FontSize')
document.documentElement.style.setProperty(
'--comfy-textarea-font-size',
`${fontSize}px`
)
})
watchEffect(() => {
const padding = settingStore.get('Comfy.TreeExplorer.ItemPadding')
document.documentElement.style.setProperty(
'--comfy-tree-explorer-item-padding',
`${padding}px`
)
})
watchEffect(() => {
const locale = settingStore.get('Comfy.Locale')
if (locale) {
i18n.global.locale.value = locale as 'en' | 'zh'
}
})
const init = () => {
settingStore.addSettings(app.ui.settings)
app.extensionManager = useWorkspaceStore()
app.extensionManager.registerSidebarTab({
id: 'queue',
icon: 'pi pi-history',
iconBadge: () => {
const value = useQueuePendingTaskCountStore().count.toString()
return value === '0' ? null : value
},
title: t('sideToolbar.queue'),
tooltip: t('sideToolbar.queue'),
component: markRaw(QueueSidebarTab),
type: 'vue'
})
app.extensionManager.registerSidebarTab({
id: 'node-library',
icon: 'pi pi-book',
title: t('sideToolbar.nodeLibrary'),
tooltip: t('sideToolbar.nodeLibrary'),
component: markRaw(NodeLibrarySidebarTab),
type: 'vue'
})
}
const queuePendingTaskCountStore = useQueuePendingTaskCountStore()
const onStatus = (e: CustomEvent<StatusWsMessageStatus>) => {
queuePendingTaskCountStore.update(e)
}
const reconnectingMessage: ToastMessageOptions = {
severity: 'error',
summary: t('reconnecting')
}
const onReconnecting = () => {
toast.remove(reconnectingMessage)
toast.add(reconnectingMessage)
}
const onReconnected = () => {
toast.remove(reconnectingMessage)
toast.add({
severity: 'success',
summary: t('reconnected'),
life: 2000
})
}
const workflowStore = useWorkflowStore()
app.workflowManager.executionStore = executionStore
watchEffect(() => {
app.menu.workflows.buttonProgress.style.width = `${executionStore.executionProgress}%`
})
app.workflowManager.workflowStore = workflowStore
onMounted(() => {
api.addEventListener('status', onStatus)
api.addEventListener('reconnecting', onReconnecting)
api.addEventListener('reconnected', onReconnected)
executionStore.bindExecutionEvents()
try {
init()
} catch (e) {
console.error('Failed to init ComfyUI frontend', e)
}
})
onBeforeUnmount(() => {
api.removeEventListener('status', onStatus)
api.removeEventListener('reconnecting', onReconnecting)
api.removeEventListener('reconnected', onReconnected)
executionStore.unbindExecutionEvents()
})
</script>

0 comments on commit eb597f5

Please sign in to comment.