Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
c0a0467
Add desktop dialog data structure
webfiltered Sep 15, 2025
b7a502c
Prefer template literal for multiline string
webfiltered Sep 15, 2025
f17985e
Fix TypeScript and linting issues
webfiltered Sep 15, 2025
6ba1d49
Fix TypeScript types for DESKTOP_DIALOGS
webfiltered Sep 15, 2025
91e4f30
Add desktop dialogs to i18n collection script
webfiltered Sep 15, 2025
046339d
Add i18n support to DesktopDialogView
webfiltered Sep 15, 2025
bd3718c
Add route for desktop dialog view
webfiltered Sep 16, 2025
7bee571
Make DesktopDialogView accept dynamic dialog ID
webfiltered Sep 16, 2025
106008e
Fix type assertion
webfiltered Sep 16, 2025
fb3d210
nit
webfiltered Sep 16, 2025
5e8b753
Use satisfies for type-safe DESKTOP_DIALOGS
webfiltered Sep 16, 2025
e4853ac
Add type assertion after runtime validation
webfiltered Sep 16, 2025
01ef9e3
Remove implementation comments
webfiltered Sep 16, 2025
04f4e84
Properly type DESKTOP_DIALOGS to avoid assertions
webfiltered Sep 16, 2025
dbc3ec9
Use type guard for exact dialog types
webfiltered Sep 16, 2025
71d8054
Clean up types
webfiltered Sep 16, 2025
74334e9
nit - Docs
webfiltered Sep 16, 2025
4727b82
Add invalid dialog for graceful error display
webfiltered Sep 16, 2025
485849c
Remove repeated id param
webfiltered Sep 16, 2025
d281aea
Add cancel action type
webfiltered Sep 16, 2025
fb9a6fd
Use id return type
webfiltered Sep 16, 2025
3815a4b
Clean up dialog interface
webfiltered Sep 16, 2025
673cea4
Remove redundant code
webfiltered Sep 16, 2025
05fe2bd
nit - Doc
webfiltered Sep 16, 2025
37e778a
Update id to match actual task
webfiltered Sep 16, 2025
bb7f561
Simplify ternary
webfiltered Sep 16, 2025
687a856
Guard against mutation
webfiltered Sep 16, 2025
9f502b9
Guard against mutation
webfiltered Sep 16, 2025
2712db0
Remove redundant classes
webfiltered Sep 16, 2025
6e63afa
Add danger button colors to Tailwind theme
webfiltered Sep 16, 2025
0f99470
Use @apply with Tailwind utility classes for danger button
webfiltered Sep 16, 2025
f7501a9
Rename theme colors to semantic names
webfiltered Sep 16, 2025
e6ebe26
Remove alpha from button colours
webfiltered Sep 16, 2025
d77db3d
Update DesktopDialogView to use renamed coral-red colors
webfiltered Sep 16, 2025
fa5a9e9
Use Tailwind palette colors for button styles
webfiltered Sep 16, 2025
47c7142
Match colours to original impl.
webfiltered Sep 16, 2025
c4ff58b
Match button styles to Figma
webfiltered Sep 16, 2025
a3ef85f
Add charcoal 900 for active button state
webfiltered Sep 16, 2025
75a8186
Fix neutral-550 to be midpoint between 500 and 600
webfiltered Sep 16, 2025
06766b6
Revert "Add charcoal 900 for active button state"
webfiltered Sep 16, 2025
77d48df
Add proper async to button click event handler
webfiltered Sep 16, 2025
420d7d4
Remove unused DesktopDialog export
webfiltered Sep 16, 2025
1ea3131
Remove useless CSS - from blind pattern-following
webfiltered Sep 16, 2025
ca086e1
Remove unwanted border from active danger button
webfiltered Sep 16, 2025
87c5846
Remove redundant CSS - duplicated on button
webfiltered Sep 16, 2025
7149143
Remove unused colour
webfiltered Sep 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion scripts/collect-i18n-general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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(
Expand All @@ -144,7 +162,8 @@ test('collect-i18n-general', async ({ comfyPage }) => {
...allSettingCategoriesLocale
},
serverConfigItems: allServerConfigsLocale,
serverConfigCategories: allServerConfigCategoriesLocale
serverConfigCategories: allServerConfigCategoriesLocale,
desktopDialogs: allDesktopDialogsLocale
},
null,
2
Expand Down
6 changes: 6 additions & 0 deletions src/assets/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
75 changes: 75 additions & 0 deletions src/constants/desktopDialogs.ts
Original file line number Diff line number Diff line change
@@ -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]) }
}
6 changes: 6 additions & 0 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
]
}
Expand Down
70 changes: 70 additions & 0 deletions src/views/DesktopDialogView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<template>
<div class="w-full h-full flex flex-col rounded-lg p-6 justify-between">
<h1 class="font-inter font-semibold text-xl m-0 italic">
{{ t(`desktopDialogs.${id}.title`, title) }}
</h1>
<p class="whitespace-pre-wrap">
{{ t(`desktopDialogs.${id}.message`, message) }}
</p>
<div class="flex w-full gap-2">
<Button
v-for="button in buttons"
:key="button.label"
class="rounded-lg first:mr-auto"
:label="
t(
`desktopDialogs.${id}.buttons.${normalizeI18nKey(button.label)}`,
button.label
)
"
:severity="button.severity ?? 'secondary'"
@click="handleButtonClick(button)"
/>
</div>
</div>
</template>

<script setup lang="ts">
import Button from 'primevue/button'
import { useRoute } from 'vue-router'

import { type DialogAction, getDialog } from '@/constants/desktopDialogs'
import { t } from '@/i18n'
import { electronAPI } from '@/utils/envUtil'
import { normalizeI18nKey } from '@/utils/formatUtil'

const route = useRoute()
const { id, title, message, buttons } = getDialog(route.params.dialogId)

const handleButtonClick = async (button: DialogAction) => {
await electronAPI().Dialog.clickButton(button.returnValue)
}
</script>

<style scoped>
@reference '../assets/css/style.css';

.p-button-secondary {
@apply text-white border-none bg-neutral-600;
}

.p-button-secondary:hover {
@apply bg-neutral-550;
}

.p-button-secondary:active {
@apply bg-neutral-500;
}

.p-button-danger {
@apply bg-coral-red-600;
}

.p-button-danger:hover {
@apply bg-coral-red-500;
}

.p-button-danger:active {
@apply bg-coral-red-400;
}
</style>
Loading