diff --git a/src/components/common/DotSpinner.vue b/src/components/common/DotSpinner.vue new file mode 100644 index 000000000..d3559cb84 --- /dev/null +++ b/src/components/common/DotSpinner.vue @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/dialog/footer/ManagerProgressFooter.vue b/src/components/dialog/footer/ManagerProgressFooter.vue index a99456751..ce259a2c8 100644 --- a/src/components/dialog/footer/ManagerProgressFooter.vue +++ b/src/components/dialog/footer/ManagerProgressFooter.vue @@ -1,41 +1,44 @@ - + - + + {{ currentTaskName }} + + + 🎉 {{ currentTaskName }} - - {{ - $t('manager.restartToApplyChanges') - }} + ✅ + {{ $t('manager.restartToApplyChanges') }} - - {{ comfyManagerStore.uncompletedCount }} {{ $t('g.progressCountOf') }} + + {{ completedTasksCount }} {{ $t('g.progressCountOf') }} {{ comfyManagerStore.taskLogs.length }} - {{ $t('g.restart') }} + {{ $t('manager.applyChanges') }} import { useEventListener } from '@vueuse/core' import Button from 'primevue/button' -import { computed } from 'vue' +import { computed, ref } from 'vue' import { useI18n } from 'vue-i18n' +import DotSpinner from '@/components/common/DotSpinner.vue' import { api } from '@/scripts/api' import { useComfyManagerService } from '@/services/comfyManagerService' import { useWorkflowService } from '@/services/workflowService' @@ -77,41 +83,93 @@ import { } from '@/stores/comfyManagerStore' import { useCommandStore } from '@/stores/commandStore' import { useDialogStore } from '@/stores/dialogStore' +import { useSettingStore } from '@/stores/settingStore' const { t } = useI18n() const dialogStore = useDialogStore() const progressDialogContent = useManagerProgressDialogStore() const comfyManagerStore = useComfyManagerStore() +const settingStore = useSettingStore() -const isInProgress = computed(() => comfyManagerStore.isProcessingTasks) +// State management for restart process +const isRestarting = ref(false) +const isRestartCompleted = ref(false) + +const isInProgress = computed( + () => comfyManagerStore.isProcessingTasks || isRestarting.value +) + +const completedTasksCount = computed(() => { + return ( + comfyManagerStore.succeededTasksIds.length + + comfyManagerStore.failedTasksIds.length + ) +}) const closeDialog = () => { dialogStore.closeDialog({ key: 'global-manager-progress-dialog' }) } -const fallbackTaskName = t('g.installing') +const fallbackTaskName = t('manager.installingDependencies') const currentTaskName = computed(() => { + if (isRestarting.value) { + return t('manager.restartingBackend') + } + if (isRestartCompleted.value) { + return t('manager.extensionsSuccessfullyInstalled') + } if (!comfyManagerStore.taskLogs.length) return fallbackTaskName const task = comfyManagerStore.taskLogs.at(-1) return task?.taskName ?? fallbackTaskName }) const handleRestart = async () => { - const onReconnect = async () => { - // Refresh manager state + // Store original toast setting value + const originalToastSetting = settingStore.get( + 'Comfy.Toast.DisableReconnectingToast' + ) - comfyManagerStore.clearLogs() - comfyManagerStore.setStale() + try { + await settingStore.set('Comfy.Toast.DisableReconnectingToast', true) - // Refresh node definitions - await useCommandStore().execute('Comfy.RefreshNodeDefinitions') + isRestarting.value = true - // Reload workflow - await useWorkflowService().reloadCurrentWorkflow() + const onReconnect = async () => { + try { + comfyManagerStore.setStale() + + await useCommandStore().execute('Comfy.RefreshNodeDefinitions') + + await useWorkflowService().reloadCurrentWorkflow() + } finally { + await settingStore.set( + 'Comfy.Toast.DisableReconnectingToast', + originalToastSetting + ) + + isRestarting.value = false + isRestartCompleted.value = true + + setTimeout(() => { + closeDialog() + comfyManagerStore.resetTaskState() + }, 3000) + } + } + + useEventListener(api, 'reconnected', onReconnect, { once: true }) + + await useComfyManagerService().rebootComfyUI() + } catch (error) { + // If restart fails, restore settings and reset state + await settingStore.set( + 'Comfy.Toast.DisableReconnectingToast', + originalToastSetting + ) + isRestarting.value = false + isRestartCompleted.value = false + closeDialog() // Close dialog on error + throw error } - useEventListener(api, 'reconnected', onReconnect, { once: true }) - - await useComfyManagerService().rebootComfyUI() - closeDialog() } diff --git a/src/locales/en/main.json b/src/locales/en/main.json index 806b27f6f..29734d382 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -149,11 +149,15 @@ "dependencies": "Dependencies", "inWorkflow": "In Workflow", "infoPanelEmpty": "Click an item to see the info", - "restartToApplyChanges": "To apply changes, please restart ComfyUI", + "applyChanges": "Apply Changes", + "restartToApplyChanges": "Click 'Apply Changes' to finish setup", + "restartingBackend": "Restarting backend to apply changes...", + "extensionsSuccessfullyInstalled": "Extension(s) successfully installed and are ready to use!", "loadingVersions": "Loading versions...", "selectVersion": "Select Version", "downloads": "Downloads", "repository": "Repository", + "installingDependencies": "Installing dependencies...", "uninstall": "Uninstall", "uninstalling": "Uninstalling", "update": "Update", diff --git a/src/stores/comfyManagerStore.ts b/src/stores/comfyManagerStore.ts index 74c722aa3..1248a41f5 100644 --- a/src/stores/comfyManagerStore.ts +++ b/src/stores/comfyManagerStore.ts @@ -299,12 +299,31 @@ export const useComfyManagerStore = defineStore('comfyManager', () => { taskLogs.value = [] } + const resetTaskState = () => { + // Clear all task-related reactive state for fresh start after restart + taskLogs.value = [] + taskHistory.value = {} + succeededTasksIds.value = [] + failedTasksIds.value = [] + succeededTasksLogs.value = [] + failedTasksLogs.value = [] + + // Reset task queue to initial state + taskQueue.value = { + history: {}, + running_queue: [], + pending_queue: [], + installed_packs: {} + } + } + return { // Manager state isLoading: managerService.isLoading, error: managerService.error, taskLogs, clearLogs, + resetTaskState, setStale, // Installed packs state