Files
ComfyUI_frontend/src/extensions/core/electronAdapter.ts
ComfyUI Wiki b347dd1734 Centralized management of external links (#4471)
Update the desktop guide links to make them platform and locale-aware

Edited by Terry:
Refactor external link management by introducing a centralized
useExternalLink composable with automatic locale and platform detection
for documentation URLs.

- Created useExternalLink composable - A new centralized utility for
managing all external links
- Dynamic docs URL builder (buildDocsUrl) - Automatically constructs
docs.comfy.org URLs with:
  - Locale detection (Chinese vs English)
  - Platform detection (macOS vs Windows for desktop)
  - Flexible path construction with options

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-4471-Add-platform-and-locale-aware-desktop-guide-URL-2346d73d3650815ea4a4dd64be575bbe)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Terry Jia <terryjia88@gmail.com>
2025-11-13 21:35:28 -08:00

310 lines
9.2 KiB
TypeScript

import log from 'loglevel'
import { useExternalLink } from '@/composables/useExternalLink'
import { PYTHON_MIRROR } from '@/constants/uvMirrors'
import { t } from '@/i18n'
import { useToastStore } from '@/platform/updates/common/toastStore'
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
import { app } from '@/scripts/app'
import { useDialogService } from '@/services/dialogService'
import { checkMirrorReachable } from '@/utils/electronMirrorCheck'
import { electronAPI as getElectronAPI, isElectron } from '@/utils/envUtil'
;(async () => {
if (!isElectron()) return
const electronAPI = getElectronAPI()
const desktopAppVersion = await electronAPI.getElectronVersion()
const workflowStore = useWorkflowStore()
const toastStore = useToastStore()
const { staticUrls, buildDocsUrl } = useExternalLink()
const onChangeRestartApp = (newValue: string, oldValue: string) => {
// Add a delay to allow changes to take effect before restarting.
if (oldValue !== undefined && newValue !== oldValue) {
electronAPI.restartApp('Restart ComfyUI to apply changes.', 1500)
}
}
app.registerExtension({
name: 'Comfy.ElectronAdapter',
settings: [
{
id: 'Comfy-Desktop.AutoUpdate',
category: ['Comfy-Desktop', 'General', 'AutoUpdate'],
name: 'Automatically check for updates',
type: 'boolean',
defaultValue: true,
onChange: onChangeRestartApp
},
{
id: 'Comfy-Desktop.SendStatistics',
category: ['Comfy-Desktop', 'General', 'Send Statistics'],
name: 'Send anonymous usage metrics',
type: 'boolean',
defaultValue: true,
onChange: onChangeRestartApp
},
{
id: 'Comfy-Desktop.WindowStyle',
category: ['Comfy-Desktop', 'General', 'Window Style'],
name: 'Window Style',
tooltip: "Custom: Replace the system title bar with ComfyUI's Top menu",
type: 'combo',
experimental: true,
defaultValue: 'default',
options: ['default', 'custom'],
onChange: (
newValue: 'default' | 'custom',
oldValue?: 'default' | 'custom'
) => {
if (!oldValue) return
electronAPI.Config.setWindowStyle(newValue)
}
},
{
id: 'Comfy-Desktop.UV.PythonInstallMirror',
name: 'Python Install Mirror',
tooltip: `Managed Python installations are downloaded from the Astral python-build-standalone project. This variable can be set to a mirror URL to use a different source for Python installations. The provided URL will replace https://github.com/astral-sh/python-build-standalone/releases/download in, e.g., https://github.com/astral-sh/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-aarch64-apple-darwin-install_only.tar.gz. Distributions can be read from a local directory by using the file:// URL scheme.`,
type: 'url',
defaultValue: '',
attrs: {
validateUrlFn(mirror: string) {
return checkMirrorReachable(
mirror + PYTHON_MIRROR.validationPathSuffix
)
}
}
},
{
id: 'Comfy-Desktop.UV.PypiInstallMirror',
name: 'Pypi Install Mirror',
tooltip: `Default pip install mirror`,
type: 'url',
defaultValue: '',
attrs: {
validateUrlFn: checkMirrorReachable
}
},
{
id: 'Comfy-Desktop.UV.TorchInstallMirror',
name: 'Torch Install Mirror',
tooltip: `Pip install mirror for pytorch`,
type: 'url',
defaultValue: '',
attrs: {
validateUrlFn: checkMirrorReachable
}
}
],
commands: [
{
id: 'Comfy-Desktop.Folders.OpenLogsFolder',
label: 'Open Logs Folder',
icon: 'pi pi-folder-open',
function() {
electronAPI.openLogsFolder()
}
},
{
id: 'Comfy-Desktop.Folders.OpenModelsFolder',
label: 'Open Models Folder',
icon: 'pi pi-folder-open',
function() {
electronAPI.openModelsFolder()
}
},
{
id: 'Comfy-Desktop.Folders.OpenOutputsFolder',
label: 'Open Outputs Folder',
icon: 'pi pi-folder-open',
function() {
electronAPI.openOutputsFolder()
}
},
{
id: 'Comfy-Desktop.Folders.OpenInputsFolder',
label: 'Open Inputs Folder',
icon: 'pi pi-folder-open',
function() {
electronAPI.openInputsFolder()
}
},
{
id: 'Comfy-Desktop.Folders.OpenCustomNodesFolder',
label: 'Open Custom Nodes Folder',
icon: 'pi pi-folder-open',
function() {
electronAPI.openCustomNodesFolder()
}
},
{
id: 'Comfy-Desktop.Folders.OpenModelConfig',
label: 'Open extra_model_paths.yaml',
icon: 'pi pi-file',
function() {
electronAPI.openModelConfig()
}
},
{
id: 'Comfy-Desktop.OpenDevTools',
label: 'Open DevTools',
icon: 'pi pi-code',
function() {
electronAPI.openDevTools()
}
},
{
id: 'Comfy-Desktop.OpenUserGuide',
label: 'Desktop User Guide',
icon: 'pi pi-book',
function() {
window.open(
buildDocsUrl('/installation/desktop', {
includeLocale: true,
platform: true
}),
'_blank'
)
}
},
{
id: 'Comfy-Desktop.CheckForUpdates',
label: 'Check for Updates',
icon: 'pi pi-sync',
async function() {
try {
const updateInfo = await electronAPI.checkForUpdates({
disableUpdateReadyAction: true
})
if (!updateInfo.isUpdateAvailable) {
toastStore.add({
severity: 'info',
summary: t('desktopUpdate.noUpdateFound'),
life: 5_000
})
return
}
const proceed = await useDialogService().confirm({
title: t('desktopUpdate.updateFoundTitle', {
version: updateInfo.version
}),
message: t('desktopUpdate.updateAvailableMessage'),
type: 'default'
})
if (proceed) {
try {
electronAPI.restartAndInstall()
} catch (error) {
log.error('Error installing update:', error)
toastStore.add({
severity: 'error',
summary: t('g.error'),
detail: t('desktopUpdate.errorInstallingUpdate'),
life: 10_000
})
}
}
} catch (error) {
log.error('Error checking for updates:', error)
toastStore.add({
severity: 'error',
summary: t('g.error'),
detail: t('desktopUpdate.errorCheckingUpdate'),
life: 10_000
})
}
}
},
{
id: 'Comfy-Desktop.Reinstall',
label: 'Reinstall',
icon: 'pi pi-refresh',
async function() {
const proceed = await useDialogService().confirm({
message: t('desktopMenu.confirmReinstall'),
title: t('desktopMenu.reinstall'),
type: 'reinstall'
})
if (proceed) electronAPI.reinstall()
}
},
{
id: 'Comfy-Desktop.Restart',
label: 'Restart',
icon: 'pi pi-refresh',
function() {
electronAPI.restartApp()
}
},
{
id: 'Comfy-Desktop.Quit',
label: 'Quit',
icon: 'pi pi-sign-out',
async function() {
// Confirm if unsaved workflows are open
if (workflowStore.modifiedWorkflows.length > 0) {
const confirmed = await useDialogService().confirm({
message: t('desktopMenu.confirmQuit'),
title: t('desktopMenu.quit'),
type: 'default'
})
if (!confirmed) return
}
electronAPI.quit()
}
}
],
menuCommands: [
{
path: ['Help'],
commands: ['Comfy-Desktop.OpenUserGuide']
},
{
path: ['Help'],
commands: ['Comfy-Desktop.OpenDevTools']
},
{
path: ['Help', 'Open Folder'],
commands: [
'Comfy-Desktop.Folders.OpenLogsFolder',
'Comfy-Desktop.Folders.OpenModelsFolder',
'Comfy-Desktop.Folders.OpenOutputsFolder',
'Comfy-Desktop.Folders.OpenInputsFolder',
'Comfy-Desktop.Folders.OpenCustomNodesFolder',
'Comfy-Desktop.Folders.OpenModelConfig'
]
},
{
path: ['Help'],
commands: ['Comfy-Desktop.CheckForUpdates', 'Comfy-Desktop.Reinstall']
}
],
keybindings: [
{
commandId: 'Workspace.CloseWorkflow',
combo: {
key: 'w',
ctrl: true
}
}
],
aboutPageBadges: [
{
label: 'ComfyUI_desktop v' + desktopAppVersion,
url: staticUrls.githubElectron,
icon: 'pi pi-github'
}
]
})
})()