mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-27 10:14:06 +00:00
## Summary - fix sizing of sidebars in app mode - update feedback button to match design - update job queue notification - clickable queue spinner item to allow clear queue - refactor mode out of store to specific workflow instance - support different saved vs active mode - other styling/layout tweaks ## Changes - **What**: Changes the store to a composable and moves the mode state to the workflow. - This enables switching between tabs and maintaining the mode they were in ## Screenshots (if applicable) <img width="1866" height="1455" alt="image" src="https://github.com/user-attachments/assets/f9a8cd36-181f-4948-b48c-dd27bd9127cf" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9137-App-mode-more-updates-fixes-3106d73d365081a18ccff6ffe24fdec7) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions <github-actions@github.com>
95 lines
2.8 KiB
TypeScript
95 lines
2.8 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { reactive, computed, watch } from 'vue'
|
|
|
|
import { useAppMode } from '@/composables/useAppMode'
|
|
import { t } from '@/i18n'
|
|
import type { NodeId } from '@/lib/litegraph/src/LGraphNode'
|
|
import type { LinearData } from '@/platform/workflow/management/stores/comfyWorkflow'
|
|
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
|
import { useDialogService } from '@/services/dialogService'
|
|
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
|
|
|
|
export const useAppModeStore = defineStore('appMode', () => {
|
|
const { getCanvas } = useCanvasStore()
|
|
const workflowStore = useWorkflowStore()
|
|
const { mode, setMode, isBuilderMode } = useAppMode()
|
|
|
|
const selectedInputs = reactive<[NodeId, string][]>([])
|
|
const selectedOutputs = reactive<NodeId[]>([])
|
|
const hasOutputs = computed(() => !!selectedOutputs.length)
|
|
|
|
function loadSelections(data: Partial<LinearData> | undefined) {
|
|
selectedInputs.splice(0, selectedInputs.length, ...(data?.inputs ?? []))
|
|
selectedOutputs.splice(0, selectedOutputs.length, ...(data?.outputs ?? []))
|
|
}
|
|
|
|
function resetSelectedToWorkflow() {
|
|
const { activeWorkflow } = workflowStore
|
|
if (!activeWorkflow) return
|
|
|
|
loadSelections(activeWorkflow.changeTracker?.activeState?.extra?.linearData)
|
|
}
|
|
|
|
function flushSelections() {
|
|
const workflow = workflowStore.activeWorkflow
|
|
if (workflow) {
|
|
workflow.dirtyLinearData = {
|
|
inputs: [...selectedInputs],
|
|
outputs: [...selectedOutputs]
|
|
}
|
|
}
|
|
}
|
|
|
|
watch(
|
|
() => workflowStore.activeWorkflow,
|
|
(newWorkflow, oldWorkflow) => {
|
|
// Persist in-progress builder selections to the outgoing workflow
|
|
if (oldWorkflow && isBuilderMode.value) {
|
|
oldWorkflow.dirtyLinearData = {
|
|
inputs: [...selectedInputs],
|
|
outputs: [...selectedOutputs]
|
|
}
|
|
}
|
|
// Load from incoming workflow: dirty state first, then persisted
|
|
if (newWorkflow) {
|
|
loadSelections(
|
|
newWorkflow.dirtyLinearData ??
|
|
newWorkflow.changeTracker?.activeState?.extra?.linearData
|
|
)
|
|
} else {
|
|
loadSelections(undefined)
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
watch(
|
|
() => mode.value === 'builder:select',
|
|
(inSelect) => (getCanvas().read_only = inSelect)
|
|
)
|
|
|
|
async function exitBuilder() {
|
|
if (
|
|
!(await useDialogService().confirm({
|
|
title: t('linearMode.builder.exitConfirmTitle'),
|
|
message: t('linearMode.builder.exitConfirmMessage')
|
|
}))
|
|
)
|
|
return
|
|
|
|
const workflow = workflowStore.activeWorkflow
|
|
if (workflow) workflow.dirtyLinearData = null
|
|
resetSelectedToWorkflow()
|
|
setMode('graph')
|
|
}
|
|
|
|
return {
|
|
exitBuilder,
|
|
hasOutputs,
|
|
flushSelections,
|
|
resetSelectedToWorkflow,
|
|
selectedInputs,
|
|
selectedOutputs
|
|
}
|
|
})
|