From 09e7d1040e2b9d393c94f10bd2ffcf8f1ec3f92c Mon Sep 17 00:00:00 2001 From: filtered <176114999+webfiltered@users.noreply.github.com> Date: Thu, 18 Sep 2025 13:32:53 +1000 Subject: [PATCH] Add desktop dialogs framework (#5605) ### Summary Adds desktop dialog framework with data-driven dialog definitions. ### Changes - Data-driven dialog structure in `desktopDialogs.ts` - Dynamic dialog view component with i18n support - Button action types: openUrl, close, cancel - Button severity levels for styling (primary, secondary, danger, warn) - Fallback invalid dialog for error handling - i18n collection script updated for dialog strings --- scripts/collect-i18n-general.ts | 21 ++++++++- src/assets/css/style.css | 6 +++ src/constants/desktopDialogs.ts | 75 +++++++++++++++++++++++++++++++++ src/router.ts | 6 +++ src/views/DesktopDialogView.vue | 70 ++++++++++++++++++++++++++++++ 5 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 src/constants/desktopDialogs.ts create mode 100644 src/views/DesktopDialogView.vue diff --git a/scripts/collect-i18n-general.ts b/scripts/collect-i18n-general.ts index f0b6dde0c..53c813fb7 100644 --- a/scripts/collect-i18n-general.ts +++ b/scripts/collect-i18n-general.ts @@ -2,6 +2,7 @@ import * as fs from 'fs' import { comfyPageFixture as test } from '../browser_tests/fixtures/ComfyPage' import { CORE_MENU_COMMANDS } from '../src/constants/coreMenuCommands' +import { DESKTOP_DIALOGS } from '../src/constants/desktopDialogs' import { SERVER_CONFIG_ITEMS } from '../src/constants/serverConfig' import type { FormItem, SettingParams } from '../src/platform/settings/types' import type { ComfyCommandImpl } from '../src/stores/commandStore' @@ -131,6 +132,23 @@ test('collect-i18n-general', async ({ comfyPage }) => { ]) ) + // Desktop Dialogs + const allDesktopDialogsLocale = Object.fromEntries( + Object.values(DESKTOP_DIALOGS).map((dialog) => [ + normalizeI18nKey(dialog.id), + { + title: dialog.title, + message: dialog.message, + buttons: Object.fromEntries( + dialog.buttons.map((button) => [ + normalizeI18nKey(button.label), + button.label + ]) + ) + } + ]) + ) + fs.writeFileSync( localePath, JSON.stringify( @@ -144,7 +162,8 @@ test('collect-i18n-general', async ({ comfyPage }) => { ...allSettingCategoriesLocale }, serverConfigItems: allServerConfigsLocale, - serverConfigCategories: allServerConfigCategoriesLocale + serverConfigCategories: allServerConfigCategoriesLocale, + desktopDialogs: allDesktopDialogsLocale }, null, 2 diff --git a/src/assets/css/style.css b/src/assets/css/style.css index 747c3d1f6..cad8a1b3b 100644 --- a/src/assets/css/style.css +++ b/src/assets/css/style.css @@ -66,6 +66,8 @@ --color-charcoal-700: #202121; --color-charcoal-800: #171718; + --color-neutral-550: #636363; + --color-stone-100: #444444; --color-stone-200: #828282; --color-stone-300: #bbbbbb; @@ -103,6 +105,10 @@ --color-danger-100: #c02323; --color-danger-200: #d62952; + --color-coral-red-600: #973a40; + --color-coral-red-500: #c53f49; + --color-coral-red-400: #dd424e; + --color-bypass: #6a246a; --color-error: #962a2a; diff --git a/src/constants/desktopDialogs.ts b/src/constants/desktopDialogs.ts new file mode 100644 index 000000000..d43e80de2 --- /dev/null +++ b/src/constants/desktopDialogs.ts @@ -0,0 +1,75 @@ +export interface DialogAction { + readonly label: string + readonly action: 'openUrl' | 'close' | 'cancel' + readonly url?: string + readonly severity?: 'danger' | 'primary' | 'secondary' | 'warn' + readonly returnValue: string +} + +interface DesktopDialog { + readonly title: string + readonly message: string + readonly buttons: DialogAction[] +} + +export const DESKTOP_DIALOGS = { + /** Shown when a corrupt venv is detected. */ + reinstallVenv: { + title: 'Reinstall ComfyUI (Fresh Start)?', + message: `Sorry, we can't launch ComfyUI because some installed packages aren't compatible. + +Click Reinstall to restore ComfyUI and get back up and running. + +Please note: if you've added custom nodes, you'll need to reinstall them after this process.`, + buttons: [ + { + label: 'Learn More', + action: 'openUrl', + url: 'https://docs.comfy.org', + returnValue: 'openDocs' + }, + { + label: 'Reinstall', + action: 'close', + severity: 'danger', + returnValue: 'resetVenv' + } + ] + }, + /** A dialog that is shown when an invalid dialog ID is provided. */ + invalidDialog: { + title: 'Invalid Dialog', + message: `Invalid dialog ID was provided.`, + buttons: [ + { + label: 'Close', + action: 'cancel', + returnValue: 'cancel' + } + ] + } +} as const satisfies { [K: string]: DesktopDialog } + +/** The ID of a desktop dialog. */ +type DesktopDialogId = keyof typeof DESKTOP_DIALOGS + +/** + * Checks if {@link id} is a valid dialog ID. + * @param id The string to check + * @returns `true` if the ID is a valid dialog ID, otherwise `false` + */ +function isDialogId(id: unknown): id is DesktopDialogId { + return typeof id === 'string' && id in DESKTOP_DIALOGS +} + +/** + * Gets the dialog with the given ID. + * @param dialogId The ID of the dialog to get + * @returns The dialog with the given ID + */ +export function getDialog( + dialogId: string | string[] +): DesktopDialog & { id: DesktopDialogId } { + const id = isDialogId(dialogId) ? dialogId : 'invalidDialog' + return { id, ...structuredClone(DESKTOP_DIALOGS[id]) } +} diff --git a/src/router.ts b/src/router.ts index fceca8efa..f28b46030 100644 --- a/src/router.ts +++ b/src/router.ts @@ -115,6 +115,12 @@ const router = createRouter({ name: 'DesktopUpdateView', component: () => import('@/views/DesktopUpdateView.vue'), beforeEnter: guardElectronAccess + }, + { + path: 'desktop-dialog/:dialogId', + name: 'DesktopDialogView', + component: () => import('@/views/DesktopDialogView.vue'), + beforeEnter: guardElectronAccess } ] } diff --git a/src/views/DesktopDialogView.vue b/src/views/DesktopDialogView.vue new file mode 100644 index 000000000..b250d1559 --- /dev/null +++ b/src/views/DesktopDialogView.vue @@ -0,0 +1,70 @@ + + + + {{ t(`desktopDialogs.${id}.title`, title) }} + + + {{ t(`desktopDialogs.${id}.message`, message) }} + + + + + + + + + +
+ {{ t(`desktopDialogs.${id}.message`, message) }} +