mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-09 01:20:09 +00:00
refactor: replace runtime isElectron() with build-time isDesktop constant (#8710)
## Summary Replace all runtime `isElectron()` function calls with the build-time `isDesktop` constant from `@/platform/distribution/types`, enabling dead-code elimination in non-desktop builds. ## Changes - **What**: Migrate 30 files from runtime `isElectron()` detection (checking `window.electronAPI`) to the compile-time `isDesktop` constant (driven by `__DISTRIBUTION__` Vite define). Remove `isElectron` from `envUtil.ts`. Update `isNativeWindow()` to use `isDesktop`. Guard `electronAPI()` calls behind `isDesktop` checks in stores. Update 7 test files to use `vi.hoisted` + getter mock pattern for per-test `isDesktop` toggling. Add `DISTRIBUTION=desktop` to `dev:electron` script. ## Review Focus - The `electronDownloadStore.ts` now guards the top-level `electronAPI()` call behind `isDesktop` to prevent crashes on non-desktop builds. - Test mocking pattern uses `vi.hoisted` with a getter to allow per-test toggling of the `isDesktop` value. - Pre-existing issues not addressed: `as ElectronAPI` cast in `envUtil.ts`, `:class="[]"` in `BaseViewTemplate.vue`, `@ts-expect-error` in `ModelLibrarySidebarTab.vue`. - This subsumes PR #8627 and renders PR #6122 and PR #7374 obsolete. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8710-refactor-replace-runtime-isElectron-with-build-time-isDesktop-constant-3006d73d365081c08037f0e61c2f6c77) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
"collect-i18n": "pnpm exec playwright test --config=playwright.i18n.config.ts",
|
||||
"dev:cloud": "cross-env DEV_SERVER_COMFYUI_URL='https://testcloud.comfy.org/' nx serve",
|
||||
"dev:desktop": "nx dev @comfyorg/desktop-ui",
|
||||
"dev:electron": "nx serve --config vite.electron.config.mts",
|
||||
"dev:electron": "cross-env DISTRIBUTION=desktop nx serve --config vite.electron.config.mts",
|
||||
"dev:no-vue": "cross-env DISABLE_VUE_PLUGINS=true nx serve",
|
||||
"dev": "nx serve",
|
||||
"devtools:pycheck": "python3 -m compileall -q tools/devtools",
|
||||
|
||||
@@ -19,7 +19,8 @@ import config from '@/config'
|
||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||
import { useConflictDetection } from '@/workbench/extensions/manager/composables/useConflictDetection'
|
||||
|
||||
import { electronAPI, isElectron } from './utils/envUtil'
|
||||
import { electronAPI } from '@/utils/envUtil'
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
import { app } from '@/scripts/app'
|
||||
|
||||
const workspaceStore = useWorkspaceStore()
|
||||
@@ -42,7 +43,7 @@ const showContextMenu = (event: MouseEvent) => {
|
||||
onMounted(() => {
|
||||
window['__COMFYUI_FRONTEND_VERSION__'] = config.app_version
|
||||
|
||||
if (isElectron()) {
|
||||
if (isDesktop) {
|
||||
document.addEventListener('contextmenu', showContextMenu)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,8 @@ import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useExecutionStore } from '@/stores/executionStore'
|
||||
import { TaskItemImpl, useQueueStore } from '@/stores/queueStore'
|
||||
import { useSidebarTabStore } from '@/stores/workspace/sidebarTabStore'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
|
||||
const mockData = vi.hoisted(() => ({ isLoggedIn: false }))
|
||||
const mockData = vi.hoisted(() => ({ isLoggedIn: false, isDesktop: false }))
|
||||
|
||||
vi.mock('@/composables/auth/useCurrentUser', () => ({
|
||||
useCurrentUser: () => {
|
||||
@@ -30,7 +29,13 @@ vi.mock('@/composables/auth/useCurrentUser', () => ({
|
||||
}
|
||||
}))
|
||||
|
||||
vi.mock('@/utils/envUtil')
|
||||
vi.mock('@/platform/distribution/types', () => ({
|
||||
isCloud: false,
|
||||
isNightly: false,
|
||||
get isDesktop() {
|
||||
return mockData.isDesktop
|
||||
}
|
||||
}))
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: vi.fn(() => ({
|
||||
currentUser: null,
|
||||
@@ -107,6 +112,8 @@ describe('TopMenuSection', () => {
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks()
|
||||
localStorage.clear()
|
||||
mockData.isDesktop = false
|
||||
mockData.isLoggedIn = false
|
||||
})
|
||||
|
||||
describe('authentication state', () => {
|
||||
@@ -129,7 +136,7 @@ describe('TopMenuSection', () => {
|
||||
|
||||
describe('on desktop platform', () => {
|
||||
it('should display LoginButton and not display CurrentUserButton', () => {
|
||||
vi.mocked(isElectron).mockReturnValue(true)
|
||||
mockData.isDesktop = true
|
||||
const wrapper = createWrapper()
|
||||
expect(wrapper.findComponent(LoginButton).exists()).toBe(true)
|
||||
expect(wrapper.findComponent(CurrentUserButton).exists()).toBe(false)
|
||||
|
||||
@@ -153,7 +153,7 @@ import { useQueueStore, useQueueUIStore } from '@/stores/queueStore'
|
||||
import { useRightSidePanelStore } from '@/stores/workspace/rightSidePanelStore'
|
||||
import { useSidebarTabStore } from '@/stores/workspace/sidebarTabStore'
|
||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
import { useConflictAcknowledgment } from '@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
import { useManagerState } from '@/workbench/extensions/manager/composables/useManagerState'
|
||||
import { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
@@ -163,7 +163,6 @@ const workspaceStore = useWorkspaceStore()
|
||||
const rightSidePanelStore = useRightSidePanelStore()
|
||||
const managerState = useManagerState()
|
||||
const { isLoggedIn } = useCurrentUser()
|
||||
const isDesktop = isElectron()
|
||||
const { t, n } = useI18n()
|
||||
const { toastErrorHandler } = useErrorHandling()
|
||||
const commandStore = useCommandStore()
|
||||
|
||||
@@ -55,10 +55,17 @@ vi.mock('@/composables/bottomPanelTabs/useTerminal', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('@/utils/envUtil', () => ({
|
||||
isElectron: vi.fn(() => false),
|
||||
electronAPI: vi.fn(() => null)
|
||||
}))
|
||||
|
||||
const mockData = vi.hoisted(() => ({ isDesktop: false }))
|
||||
|
||||
vi.mock('@/platform/distribution/types', () => ({
|
||||
get isDesktop() {
|
||||
return mockData.isDesktop
|
||||
}
|
||||
}))
|
||||
|
||||
// Mock clipboard API
|
||||
Object.defineProperty(navigator, 'clipboard', {
|
||||
value: {
|
||||
|
||||
@@ -35,7 +35,8 @@ import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useTerminal } from '@/composables/bottomPanelTabs/useTerminal'
|
||||
import { electronAPI, isElectron } from '@/utils/envUtil'
|
||||
import { electronAPI } from '@/utils/envUtil'
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
|
||||
const { t } = useI18n()
|
||||
@@ -85,7 +86,7 @@ const showContextMenu = (event: MouseEvent) => {
|
||||
electronAPI()?.showContextMenu({ type: 'text' })
|
||||
}
|
||||
|
||||
if (isElectron()) {
|
||||
if (isDesktop) {
|
||||
useEventListener(terminalEl, 'contextmenu', showContextMenu)
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</div>
|
||||
<ListBox :options="missingModels" class="comfy-missing-models">
|
||||
<template #option="{ option }">
|
||||
<Suspense v-if="isElectron()">
|
||||
<Suspense v-if="isDesktop">
|
||||
<ElectronFileDownload
|
||||
:url="option.url"
|
||||
:label="option.label"
|
||||
@@ -40,7 +40,7 @@ import ElectronFileDownload from '@/components/common/ElectronFileDownload.vue'
|
||||
import FileDownload from '@/components/common/FileDownload.vue'
|
||||
import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
|
||||
// TODO: Read this from server internal API rather than hardcoding here
|
||||
// as some installations may wish to use custom sources
|
||||
|
||||
@@ -159,13 +159,13 @@ import { useI18n } from 'vue-i18n'
|
||||
|
||||
import PuzzleIcon from '@/components/icons/PuzzleIcon.vue'
|
||||
import { useExternalLink } from '@/composables/useExternalLink'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { isCloud, isDesktop } from '@/platform/distribution/types'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import type { ReleaseNote } from '@/platform/updates/common/releaseService'
|
||||
import { useReleaseStore } from '@/platform/updates/common/releaseStore'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { electronAPI, isElectron } from '@/utils/envUtil'
|
||||
import { electronAPI } from '@/utils/envUtil'
|
||||
import { formatVersionAnchor } from '@/utils/formatUtil'
|
||||
import { useConflictAcknowledgment } from '@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
import { useManagerState } from '@/workbench/extensions/manager/composables/useManagerState'
|
||||
@@ -241,7 +241,7 @@ const moreItems = computed<MenuItem[]>(() => {
|
||||
key: 'desktop-guide',
|
||||
type: 'item',
|
||||
label: t('helpCenter.desktopUserGuide'),
|
||||
visible: isElectron(),
|
||||
visible: isDesktop,
|
||||
action: () => {
|
||||
trackResourceClick('docs', true)
|
||||
openExternalLink(
|
||||
@@ -257,7 +257,7 @@ const moreItems = computed<MenuItem[]>(() => {
|
||||
key: 'dev-tools',
|
||||
type: 'item',
|
||||
label: t('helpCenter.openDevTools'),
|
||||
visible: isElectron(),
|
||||
visible: isDesktop,
|
||||
action: () => {
|
||||
openDevTools()
|
||||
emit('close')
|
||||
@@ -266,13 +266,13 @@ const moreItems = computed<MenuItem[]>(() => {
|
||||
{
|
||||
key: 'divider-1',
|
||||
type: 'divider',
|
||||
visible: isElectron()
|
||||
visible: isDesktop
|
||||
},
|
||||
{
|
||||
key: 'reinstall',
|
||||
type: 'item',
|
||||
label: t('helpCenter.reinstall'),
|
||||
visible: isElectron(),
|
||||
visible: isDesktop,
|
||||
action: () => {
|
||||
onReinstall()
|
||||
emit('close')
|
||||
@@ -374,7 +374,7 @@ const menuItems = computed<MenuItem[]>(() => {
|
||||
})
|
||||
}
|
||||
// Update ComfyUI - only for non-desktop, non-cloud with new manager UI
|
||||
if (!isElectron() && !isCloud && isNewManagerUI.value) {
|
||||
if (!isDesktop && !isCloud && isNewManagerUI.value) {
|
||||
items.push({
|
||||
key: 'update-comfyui',
|
||||
type: 'item',
|
||||
@@ -551,13 +551,13 @@ const onSubmenuLeave = (): void => {
|
||||
}
|
||||
|
||||
const openDevTools = (): void => {
|
||||
if (isElectron()) {
|
||||
if (isDesktop) {
|
||||
electronAPI().openDevTools()
|
||||
}
|
||||
}
|
||||
|
||||
const onReinstall = (): void => {
|
||||
if (isElectron()) {
|
||||
if (isDesktop) {
|
||||
void electronAPI().reinstall()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<ElectronDownloadItems v-if="isElectron()" />
|
||||
<ElectronDownloadItems v-if="isDesktop" />
|
||||
|
||||
<Divider type="dashed" class="m-2" />
|
||||
<TreeExplorer
|
||||
@@ -69,7 +69,7 @@ import type { ComfyModelDef, ModelFolder } from '@/stores/modelStore'
|
||||
import { ResourceState, useModelStore } from '@/stores/modelStore'
|
||||
import { useModelToNodeStore } from '@/stores/modelToNodeStore'
|
||||
import type { TreeExplorerNode, TreeNode } from '@/types/treeExplorerTypes'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
import { buildTree } from '@/utils/treeUtil'
|
||||
|
||||
const modelStore = useModelStore()
|
||||
|
||||
@@ -115,7 +115,7 @@ import type { ComfyWorkflow } from '@/platform/workflow/management/stores/workfl
|
||||
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
import { whileMouseDown } from '@/utils/mouseDownUtil'
|
||||
|
||||
import WorkflowOverflowMenu from './WorkflowOverflowMenu.vue'
|
||||
@@ -148,8 +148,6 @@ const showOverflowArrows = ref(false)
|
||||
const leftArrowEnabled = ref(false)
|
||||
const rightArrowEnabled = ref(false)
|
||||
|
||||
const isDesktop = isElectron()
|
||||
|
||||
const workflowToOption = (workflow: ComfyWorkflow): WorkflowOption => ({
|
||||
value: workflow.path,
|
||||
workflow
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { markRaw } from 'vue'
|
||||
|
||||
import ModelLibrarySidebarTab from '@/components/sidebar/tabs/ModelLibrarySidebarTab.vue'
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
import { useElectronDownloadStore } from '@/stores/electronDownloadStore'
|
||||
import type { SidebarTabExtension } from '@/types/extensionTypes'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
|
||||
export const useModelLibrarySidebarTab = (): SidebarTabExtension => {
|
||||
return {
|
||||
@@ -15,7 +15,7 @@ export const useModelLibrarySidebarTab = (): SidebarTabExtension => {
|
||||
component: markRaw(ModelLibrarySidebarTab),
|
||||
type: 'vue',
|
||||
iconBadge: () => {
|
||||
if (isElectron()) {
|
||||
if (isDesktop) {
|
||||
const electronDownloadStore = useElectronDownloadStore()
|
||||
if (electronDownloadStore.inProgressDownloads.length > 0) {
|
||||
return electronDownloadStore.inProgressDownloads.length.toString()
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const mockData = vi.hoisted(() => ({ isDesktop: false }))
|
||||
|
||||
vi.mock('@/platform/distribution/types', () => ({
|
||||
get isDesktop() {
|
||||
return mockData.isDesktop
|
||||
}
|
||||
}))
|
||||
|
||||
// Mock the environment utilities
|
||||
vi.mock('@/utils/envUtil', () => ({
|
||||
isElectron: vi.fn(),
|
||||
electronAPI: vi.fn()
|
||||
}))
|
||||
|
||||
@@ -20,14 +27,14 @@ vi.mock('@/i18n', () => ({
|
||||
|
||||
// Import after mocking to get the mocked versions
|
||||
import { useExternalLink } from '@/composables/useExternalLink'
|
||||
import { electronAPI, isElectron } from '@/utils/envUtil'
|
||||
import { electronAPI } from '@/utils/envUtil'
|
||||
|
||||
describe('useExternalLink', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
// Reset to default state
|
||||
i18n.global.locale.value = 'en'
|
||||
vi.mocked(isElectron).mockReturnValue(false)
|
||||
mockData.isDesktop = false
|
||||
})
|
||||
|
||||
describe('staticUrls', () => {
|
||||
@@ -95,7 +102,7 @@ describe('useExternalLink', () => {
|
||||
|
||||
it('should add platform suffix when requested', () => {
|
||||
i18n.global.locale.value = 'en'
|
||||
vi.mocked(isElectron).mockReturnValue(true)
|
||||
mockData.isDesktop = true
|
||||
vi.mocked(electronAPI).mockReturnValue({
|
||||
getPlatform: () => 'darwin'
|
||||
} as ReturnType<typeof electronAPI>)
|
||||
@@ -107,7 +114,7 @@ describe('useExternalLink', () => {
|
||||
|
||||
it('should add platform suffix with trailing slash', () => {
|
||||
i18n.global.locale.value = 'en'
|
||||
vi.mocked(isElectron).mockReturnValue(true)
|
||||
mockData.isDesktop = true
|
||||
vi.mocked(electronAPI).mockReturnValue({
|
||||
getPlatform: () => 'win32'
|
||||
} as ReturnType<typeof electronAPI>)
|
||||
@@ -119,7 +126,7 @@ describe('useExternalLink', () => {
|
||||
|
||||
it('should combine locale and platform', () => {
|
||||
i18n.global.locale.value = 'zh'
|
||||
vi.mocked(isElectron).mockReturnValue(true)
|
||||
mockData.isDesktop = true
|
||||
vi.mocked(electronAPI).mockReturnValue({
|
||||
getPlatform: () => 'darwin'
|
||||
} as ReturnType<typeof electronAPI>)
|
||||
@@ -136,7 +143,7 @@ describe('useExternalLink', () => {
|
||||
|
||||
it('should not add platform when not desktop', () => {
|
||||
i18n.global.locale.value = 'en'
|
||||
vi.mocked(isElectron).mockReturnValue(false)
|
||||
mockData.isDesktop = false
|
||||
|
||||
const { buildDocsUrl } = useExternalLink()
|
||||
const url = buildDocsUrl('/installation/desktop', { platform: true })
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { electronAPI, isElectron } from '@/utils/envUtil'
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
import { electronAPI } from '@/utils/envUtil'
|
||||
import { i18n } from '@/i18n'
|
||||
|
||||
/**
|
||||
@@ -30,7 +31,7 @@ export function useExternalLink() {
|
||||
})
|
||||
|
||||
const platform = computed(() => {
|
||||
if (!isElectron()) {
|
||||
if (!isDesktop) {
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,10 @@ import { useWorkflowStore } from '@/platform/workflow/management/stores/workflow
|
||||
import { app } from '@/scripts/app'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { checkMirrorReachable } from '@/utils/electronMirrorCheck'
|
||||
import { electronAPI as getElectronAPI, isElectron } from '@/utils/envUtil'
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
import { electronAPI as getElectronAPI } from '@/utils/envUtil'
|
||||
;(async () => {
|
||||
if (!isElectron()) return
|
||||
if (!isDesktop) return
|
||||
|
||||
const electronAPI = getElectronAPI()
|
||||
const desktopAppVersion = await electronAPI.getElectronVersion()
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
|
||||
/**
|
||||
* Distribution types and compile-time constants for managing
|
||||
* multi-distribution builds (Desktop, Localhost, Cloud)
|
||||
@@ -15,10 +13,8 @@ declare global {
|
||||
/** Current distribution - replaced at compile time */
|
||||
const DISTRIBUTION: Distribution = __DISTRIBUTION__
|
||||
|
||||
/** Distribution type checks */
|
||||
export const isDesktop = DISTRIBUTION === 'desktop' || isElectron() // TODO: replace with build var
|
||||
export const isDesktop = DISTRIBUTION === 'desktop'
|
||||
export const isCloud = DISTRIBUTION === 'cloud'
|
||||
// export const isLocalhost = DISTRIBUTION === 'localhost' || (!isDesktop && !isCloud)
|
||||
|
||||
/**
|
||||
* Whether this is a nightly build (from main branch).
|
||||
|
||||
@@ -6,11 +6,11 @@ import { useCurrentUser } from '@/composables/auth/useCurrentUser'
|
||||
import { useBillingContext } from '@/composables/billing/useBillingContext'
|
||||
import { useFeatureFlags } from '@/composables/useFeatureFlags'
|
||||
import { useVueFeatureFlags } from '@/composables/useVueFeatureFlags'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { isCloud, isDesktop } from '@/platform/distribution/types'
|
||||
import type { SettingTreeNode } from '@/platform/settings/settingStore'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import type { SettingParams } from '@/platform/settings/types'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
|
||||
import { normalizeI18nKey } from '@/utils/formatUtil'
|
||||
import { buildTree } from '@/utils/treeUtil'
|
||||
|
||||
@@ -226,7 +226,7 @@ export function useSettingUI(
|
||||
...(shouldShowWorkspacePanel.value ? [workspacePanel] : []),
|
||||
keybindingPanel,
|
||||
extensionPanel,
|
||||
...(isElectron() ? [serverConfigPanel] : []),
|
||||
...(isDesktop ? [serverConfigPanel] : []),
|
||||
...(shouldShowPlanCreditsPanel.value && subscriptionPanel
|
||||
? [subscriptionPanel]
|
||||
: []),
|
||||
@@ -283,7 +283,7 @@ export function useSettingUI(
|
||||
translateCategory(keybindingPanel.node),
|
||||
translateCategory(extensionPanel.node),
|
||||
translateCategory(aboutPanel.node),
|
||||
...(isElectron() ? [translateCategory(serverConfigPanel.node)] : [])
|
||||
...(isDesktop ? [translateCategory(serverConfigPanel.node)] : [])
|
||||
]
|
||||
}),
|
||||
// Custom node settings (only shown if custom nodes have registered settings)
|
||||
@@ -332,7 +332,7 @@ export function useSettingUI(
|
||||
keybindingPanel.node,
|
||||
extensionPanel.node,
|
||||
aboutPanel.node,
|
||||
...(isElectron() ? [serverConfigPanel.node] : [])
|
||||
...(isDesktop ? [serverConfigPanel.node] : [])
|
||||
].map(translateCategory)
|
||||
}
|
||||
])
|
||||
|
||||
@@ -9,7 +9,6 @@ import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useReleaseStore } from '@/platform/updates/common/releaseStore'
|
||||
import { useReleaseService } from '@/platform/updates/common/releaseService'
|
||||
import { useSystemStatsStore } from '@/stores/systemStatsStore'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
import { createTestingPinia } from '@pinia/testing'
|
||||
import type { SystemStats } from '@/types'
|
||||
|
||||
@@ -19,11 +18,14 @@ vi.mock('semver', () => ({
|
||||
valid: vi.fn(() => '1.0.0')
|
||||
}))
|
||||
|
||||
vi.mock('@/utils/envUtil', () => ({
|
||||
isElectron: vi.fn(() => true)
|
||||
}))
|
||||
const mockData = vi.hoisted(() => ({ isDesktop: true }))
|
||||
|
||||
vi.mock('@/platform/distribution/types', () => ({ isCloud: false }))
|
||||
vi.mock('@/platform/distribution/types', () => ({
|
||||
get isDesktop() {
|
||||
return mockData.isDesktop
|
||||
},
|
||||
isCloud: false
|
||||
}))
|
||||
|
||||
vi.mock('@/platform/updates/common/releaseService', () => {
|
||||
const getReleases = vi.fn()
|
||||
@@ -675,10 +677,10 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('isElectron environment checks', () => {
|
||||
describe('when running in Electron (desktop)', () => {
|
||||
describe('isDesktop environment checks', () => {
|
||||
describe('when running on desktop', () => {
|
||||
beforeEach(() => {
|
||||
vi.mocked(isElectron).mockReturnValue(true)
|
||||
mockData.isDesktop = true
|
||||
})
|
||||
|
||||
it('should show toast when conditions are met', () => {
|
||||
@@ -709,9 +711,9 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('when NOT running in Electron (web)', () => {
|
||||
describe('when NOT running on desktop (web)', () => {
|
||||
beforeEach(() => {
|
||||
vi.mocked(isElectron).mockReturnValue(false)
|
||||
mockData.isDesktop = false
|
||||
})
|
||||
|
||||
it('should NOT show toast even when all other conditions are met', () => {
|
||||
|
||||
@@ -3,10 +3,9 @@ import { defineStore } from 'pinia'
|
||||
import { compare, valid } from 'semver'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { isCloud, isDesktop } from '@/platform/distribution/types'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useSystemStatsStore } from '@/stores/systemStatsStore'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
import { stringToLocale } from '@/utils/formatUtil'
|
||||
|
||||
import { useReleaseService } from './releaseService'
|
||||
@@ -95,7 +94,7 @@ export const useReleaseStore = defineStore('release', () => {
|
||||
// Show toast if needed
|
||||
const shouldShowToast = computed(() => {
|
||||
// Only show on desktop version
|
||||
if (!isElectron() || isCloud) {
|
||||
if (!isDesktop || isCloud) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -127,7 +126,7 @@ export const useReleaseStore = defineStore('release', () => {
|
||||
// Show red-dot indicator
|
||||
const shouldShowRedDot = computed(() => {
|
||||
// Only show on desktop version
|
||||
if (!isElectron() || isCloud) {
|
||||
if (!isDesktop || isCloud) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -172,7 +171,7 @@ export const useReleaseStore = defineStore('release', () => {
|
||||
})
|
||||
|
||||
const shouldShowPopup = computed(() => {
|
||||
if (!isElectron() && !isCloud) {
|
||||
if (!isDesktop && !isCloud) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { ReleaseNote } from '../common/releaseService'
|
||||
import ReleaseNotificationToast from './ReleaseNotificationToast.vue'
|
||||
|
||||
interface TestWindow extends Window {
|
||||
electronAPI?: Record<string, unknown>
|
||||
}
|
||||
const mockData = vi.hoisted(() => ({ isDesktop: false }))
|
||||
|
||||
const { commandExecuteMock } = vi.hoisted(() => ({
|
||||
commandExecuteMock: vi.fn()
|
||||
@@ -17,6 +15,14 @@ const { toastErrorHandlerMock } = vi.hoisted(() => ({
|
||||
toastErrorHandlerMock: vi.fn()
|
||||
}))
|
||||
|
||||
vi.mock('@/platform/distribution/types', () => ({
|
||||
isCloud: false,
|
||||
isNightly: false,
|
||||
get isDesktop() {
|
||||
return mockData.isDesktop
|
||||
}
|
||||
}))
|
||||
|
||||
// Mock dependencies
|
||||
vi.mock('vue-i18n', () => ({
|
||||
useI18n: vi.fn(() => ({
|
||||
@@ -105,6 +111,7 @@ describe('ReleaseNotificationToast', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
mockData.isDesktop = false
|
||||
// Reset store state
|
||||
mockReleaseStore.recentRelease = null
|
||||
mockReleaseStore.shouldShowToast = true // Force show for testing
|
||||
@@ -183,7 +190,8 @@ describe('ReleaseNotificationToast', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('executes desktop updater flow when running in Electron', async () => {
|
||||
it('executes desktop updater flow when running on desktop', async () => {
|
||||
mockData.isDesktop = true
|
||||
mockReleaseStore.recentRelease = {
|
||||
version: '1.2.3',
|
||||
content: '# Test Release'
|
||||
@@ -196,7 +204,6 @@ describe('ReleaseNotificationToast', () => {
|
||||
value: mockWindowOpen,
|
||||
writable: true
|
||||
})
|
||||
;(window as TestWindow).electronAPI = {}
|
||||
|
||||
wrapper = mountComponent()
|
||||
await wrapper.vm.handleUpdate()
|
||||
@@ -206,11 +213,10 @@ describe('ReleaseNotificationToast', () => {
|
||||
)
|
||||
expect(mockWindowOpen).not.toHaveBeenCalled()
|
||||
expect(toastErrorHandlerMock).not.toHaveBeenCalled()
|
||||
|
||||
delete (window as TestWindow).electronAPI
|
||||
})
|
||||
|
||||
it('shows an error toast if the desktop updater flow fails in Electron', async () => {
|
||||
it('shows an error toast if the desktop updater flow fails on desktop', async () => {
|
||||
mockData.isDesktop = true
|
||||
mockReleaseStore.recentRelease = {
|
||||
version: '1.2.3',
|
||||
content: '# Test Release'
|
||||
@@ -224,15 +230,12 @@ describe('ReleaseNotificationToast', () => {
|
||||
value: mockWindowOpen,
|
||||
writable: true
|
||||
})
|
||||
;(window as TestWindow).electronAPI = {}
|
||||
|
||||
wrapper = mountComponent()
|
||||
await wrapper.vm.handleUpdate()
|
||||
|
||||
expect(toastErrorHandlerMock).toHaveBeenCalledWith(error)
|
||||
expect(mockWindowOpen).not.toHaveBeenCalled()
|
||||
|
||||
delete (window as TestWindow).electronAPI
|
||||
})
|
||||
|
||||
it('calls handleShowChangelog when learn more link is clicked', async () => {
|
||||
|
||||
@@ -72,7 +72,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import { useErrorHandling } from '@/composables/useErrorHandling'
|
||||
import { useExternalLink } from '@/composables/useExternalLink'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
import { formatVersionAnchor } from '@/utils/formatUtil'
|
||||
import { renderMarkdownToHtml } from '@/utils/markdownRendererUtil'
|
||||
|
||||
@@ -177,7 +177,7 @@ const handleLearnMore = () => {
|
||||
}
|
||||
|
||||
const handleUpdate = async () => {
|
||||
if (isElectron()) {
|
||||
if (isDesktop) {
|
||||
try {
|
||||
await useCommandStore().execute('Comfy-Desktop.CheckForUpdates')
|
||||
dismissToast()
|
||||
|
||||
@@ -8,12 +8,11 @@ import {
|
||||
import type { RouteLocationNormalized } from 'vue-router'
|
||||
|
||||
import { useFeatureFlags } from '@/composables/useFeatureFlags'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { isCloud, isDesktop } from '@/platform/distribution/types'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useUserStore } from '@/stores/userStore'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
import LayoutDefault from '@/views/layouts/LayoutDefault.vue'
|
||||
|
||||
import { installPreservedQueryTracker } from '@/platform/navigation/preservedQueryTracker'
|
||||
@@ -30,7 +29,7 @@ const isFileProtocol = window.location.protocol === 'file:'
|
||||
* to support deployments like http://mysite.com/ComfyUI/
|
||||
*/
|
||||
function getBasePath(): string {
|
||||
if (isElectron()) return '/'
|
||||
if (isDesktop) return '/'
|
||||
if (isCloud) return import.meta.env?.BASE_URL || '/'
|
||||
return window.location.pathname
|
||||
}
|
||||
@@ -182,7 +181,7 @@ if (isCloud) {
|
||||
// Handle other protected routes
|
||||
if (!isLoggedIn) {
|
||||
// For Electron, use dialog
|
||||
if (isElectron()) {
|
||||
if (isDesktop) {
|
||||
const dialogService = useDialogService()
|
||||
const loginSuccess = await dialogService.showSignInDialog()
|
||||
return loginSuccess ? next() : next(false)
|
||||
@@ -197,7 +196,7 @@ if (isCloud) {
|
||||
|
||||
// User is logged in - check if they need onboarding (when enabled)
|
||||
// For root path, check actual user status to handle waitlisted users
|
||||
if (!isElectron() && isLoggedIn && to.path === '/') {
|
||||
if (!isDesktop && isLoggedIn && to.path === '/') {
|
||||
if (!flags.onboardingSurveyEnabled) {
|
||||
return next()
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ import { defineStore } from 'pinia'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { useExternalLink } from '@/composables/useExternalLink'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { isCloud, isDesktop } from '@/platform/distribution/types'
|
||||
import type { AboutPageBadge } from '@/types/comfy'
|
||||
import { electronAPI, isElectron } from '@/utils/envUtil'
|
||||
import { electronAPI } from '@/utils/envUtil'
|
||||
import { formatCommitHash } from '@/utils/formatUtil'
|
||||
|
||||
import { useExtensionStore } from './extensionStore'
|
||||
@@ -24,7 +24,7 @@ export const useAboutPanelStore = defineStore('aboutPanel', () => {
|
||||
// so the python server's API doesn't have the version info.
|
||||
{
|
||||
label: `ComfyUI ${
|
||||
isElectron()
|
||||
isDesktop
|
||||
? 'v' + electronAPI().getComfyUIVersion()
|
||||
: formatCommitHash(coreVersion.value)
|
||||
}`,
|
||||
|
||||
@@ -3,7 +3,8 @@ import type { DownloadState } from '@comfyorg/comfyui-electron-types'
|
||||
import { defineStore } from 'pinia'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { electronAPI, isElectron } from '@/utils/envUtil'
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
import { electronAPI } from '@/utils/envUtil'
|
||||
|
||||
export interface ElectronDownload extends Pick<
|
||||
DownloadState,
|
||||
@@ -17,35 +18,34 @@ export interface ElectronDownload extends Pick<
|
||||
/** Electron downloads store handler */
|
||||
export const useElectronDownloadStore = defineStore('downloads', () => {
|
||||
const downloads = ref<ElectronDownload[]>([])
|
||||
const { DownloadManager } = electronAPI()
|
||||
const DownloadManager = isDesktop ? electronAPI().DownloadManager : undefined
|
||||
|
||||
const findByUrl = (url: string) =>
|
||||
downloads.value.find((download) => url === download.url)
|
||||
|
||||
const initialize = async () => {
|
||||
if (isElectron()) {
|
||||
const allDownloads = await DownloadManager.getAllDownloads()
|
||||
if (!isDesktop || !DownloadManager) return
|
||||
|
||||
for (const download of allDownloads) {
|
||||
downloads.value.push(download)
|
||||
const allDownloads = await DownloadManager.getAllDownloads()
|
||||
|
||||
for (const download of allDownloads) {
|
||||
downloads.value.push(download)
|
||||
}
|
||||
|
||||
DownloadManager.onDownloadProgress((data) => {
|
||||
if (!findByUrl(data.url)) {
|
||||
downloads.value.push(data)
|
||||
}
|
||||
|
||||
// ToDO: replace with ElectronDownload type
|
||||
DownloadManager.onDownloadProgress((data) => {
|
||||
if (!findByUrl(data.url)) {
|
||||
downloads.value.push(data)
|
||||
}
|
||||
const download = findByUrl(data.url)
|
||||
|
||||
const download = findByUrl(data.url)
|
||||
|
||||
if (download) {
|
||||
download.progress = data.progress
|
||||
download.status = data.status
|
||||
download.filename = data.filename
|
||||
download.savePath = data.savePath
|
||||
}
|
||||
})
|
||||
}
|
||||
if (download) {
|
||||
download.progress = data.progress
|
||||
download.status = data.status
|
||||
download.filename = data.filename
|
||||
download.savePath = data.savePath
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
void initialize()
|
||||
@@ -58,10 +58,10 @@ export const useElectronDownloadStore = defineStore('downloads', () => {
|
||||
url: string
|
||||
savePath: string
|
||||
filename: string
|
||||
}) => DownloadManager.startDownload(url, savePath, filename)
|
||||
const pause = (url: string) => DownloadManager.pauseDownload(url)
|
||||
const resume = (url: string) => DownloadManager.resumeDownload(url)
|
||||
const cancel = (url: string) => DownloadManager.cancelDownload(url)
|
||||
}) => DownloadManager!.startDownload(url, savePath, filename)
|
||||
const pause = (url: string) => DownloadManager!.pauseDownload(url)
|
||||
const resume = (url: string) => DownloadManager!.resumeDownload(url)
|
||||
const cancel = (url: string) => DownloadManager!.cancelDownload(url)
|
||||
|
||||
return {
|
||||
downloads,
|
||||
|
||||
@@ -5,7 +5,8 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { SystemStats } from '@/schemas/apiSchema'
|
||||
import { api } from '@/scripts/api'
|
||||
import { useSystemStatsStore } from '@/stores/systemStatsStore'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
|
||||
const mockData = vi.hoisted(() => ({ isDesktop: false }))
|
||||
|
||||
// Mock the API
|
||||
vi.mock('@/scripts/api', () => ({
|
||||
@@ -14,13 +15,13 @@ vi.mock('@/scripts/api', () => ({
|
||||
}
|
||||
}))
|
||||
|
||||
// Mock the envUtil
|
||||
vi.mock('@/utils/envUtil', () => ({
|
||||
isElectron: vi.fn()
|
||||
vi.mock('@/platform/distribution/types', () => ({
|
||||
get isDesktop() {
|
||||
return mockData.isDesktop
|
||||
},
|
||||
isCloud: false
|
||||
}))
|
||||
|
||||
vi.mock('@/platform/distribution/types', () => ({ isCloud: false }))
|
||||
|
||||
describe('useSystemStatsStore', () => {
|
||||
let store: ReturnType<typeof useSystemStatsStore>
|
||||
|
||||
@@ -161,9 +162,9 @@ describe('useSystemStatsStore', () => {
|
||||
expect(store.getFormFactor()).toBe('other')
|
||||
})
|
||||
|
||||
describe('desktop environment (Electron)', () => {
|
||||
describe('desktop environment', () => {
|
||||
beforeEach(() => {
|
||||
vi.mocked(isElectron).mockReturnValue(true)
|
||||
mockData.isDesktop = true
|
||||
})
|
||||
|
||||
it('should return "desktop-windows" for Windows desktop', () => {
|
||||
@@ -239,9 +240,9 @@ describe('useSystemStatsStore', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('git environment (non-Electron)', () => {
|
||||
describe('git environment (non-desktop)', () => {
|
||||
beforeEach(() => {
|
||||
vi.mocked(isElectron).mockReturnValue(false)
|
||||
mockData.isDesktop = false
|
||||
})
|
||||
|
||||
it('should return "git-windows" for Windows git', () => {
|
||||
@@ -319,7 +320,7 @@ describe('useSystemStatsStore', () => {
|
||||
|
||||
describe('case insensitive OS detection', () => {
|
||||
beforeEach(() => {
|
||||
vi.mocked(isElectron).mockReturnValue(false)
|
||||
mockData.isDesktop = false
|
||||
})
|
||||
|
||||
it('should handle uppercase OS names', () => {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { useAsyncState } from '@vueuse/core'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { isCloud, isDesktop } from '@/platform/distribution/types'
|
||||
import type { SystemStats } from '@/schemas/apiSchema'
|
||||
import { api } from '@/scripts/api'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
|
||||
export const useSystemStatsStore = defineStore('systemStats', () => {
|
||||
const fetchSystemStatsData = async () => {
|
||||
@@ -40,7 +39,6 @@ export const useSystemStatsStore = defineStore('systemStats', () => {
|
||||
}
|
||||
|
||||
const os = systemStats.value.system.os.toLowerCase()
|
||||
const isDesktop = isElectron()
|
||||
|
||||
if (isDesktop) {
|
||||
if (os.includes('windows')) {
|
||||
|
||||
@@ -48,8 +48,12 @@ vi.mock('@/stores/commandStore', () => ({
|
||||
})
|
||||
}))
|
||||
|
||||
vi.mock('@/utils/envUtil', () => ({
|
||||
isElectron: () => false
|
||||
const mockData = vi.hoisted(() => ({ isDesktop: false }))
|
||||
|
||||
vi.mock('@/platform/distribution/types', () => ({
|
||||
get isDesktop() {
|
||||
return mockData.isDesktop
|
||||
}
|
||||
}))
|
||||
|
||||
describe('useBottomPanelStore', () => {
|
||||
|
||||
@@ -3,10 +3,10 @@ import { computed, ref } from 'vue'
|
||||
|
||||
import { useShortcutsTab } from '@/composables/bottomPanelTabs/useShortcutsTab'
|
||||
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import type { ComfyExtension } from '@/types/comfy'
|
||||
import type { BottomPanelExtension } from '@/types/extensionTypes'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
|
||||
type PanelType = 'terminal' | 'shortcuts'
|
||||
|
||||
@@ -138,7 +138,7 @@ export const useBottomPanelStore = defineStore('bottomPanel', () => {
|
||||
const { useLogsTerminalTab, useCommandTerminalTab } =
|
||||
await import('@/composables/bottomPanelTabs/useTerminalTabs')
|
||||
registerBottomPanelTab(useLogsTerminalTab())
|
||||
if (isElectron()) {
|
||||
if (isDesktop) {
|
||||
registerBottomPanelTab(useCommandTerminalTab())
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { ElectronAPI } from '@comfyorg/comfyui-electron-types'
|
||||
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
|
||||
/**
|
||||
* Extend Window interface to include electronAPI
|
||||
* Used by desktop-ui app storybook stories
|
||||
@@ -9,10 +11,6 @@ export type ElectronWindow = typeof window & {
|
||||
electronAPI?: ElectronAPI
|
||||
}
|
||||
|
||||
export function isElectron() {
|
||||
return 'electronAPI' in window && window.electronAPI !== undefined
|
||||
}
|
||||
|
||||
export function electronAPI() {
|
||||
return (window as ElectronWindow).electronAPI as ElectronAPI
|
||||
}
|
||||
@@ -22,5 +20,5 @@ export function showNativeSystemMenu() {
|
||||
}
|
||||
|
||||
export function isNativeWindow() {
|
||||
return isElectron() && !!window.navigator.windowControlsOverlay?.visible
|
||||
return isDesktop && !!window.navigator.windowControlsOverlay?.visible
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<RerouteMigrationToast />
|
||||
<ModelImportProgressDialog />
|
||||
<ManagerProgressToast />
|
||||
<UnloadWindowConfirmDialog v-if="!isElectron()" />
|
||||
<UnloadWindowConfirmDialog v-if="!isDesktop" />
|
||||
<MenuHamburger />
|
||||
</template>
|
||||
|
||||
@@ -52,7 +52,7 @@ import { useProgressFavicon } from '@/composables/useProgressFavicon'
|
||||
import { SERVER_CONFIG_ITEMS } from '@/constants/serverConfig'
|
||||
import { i18n, loadLocale } from '@/i18n'
|
||||
import ModelImportProgressDialog from '@/platform/assets/components/ModelImportProgressDialog.vue'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { isCloud, isDesktop } from '@/platform/distribution/types'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { useFrontendVersionMismatchWarning } from '@/platform/updates/common/useFrontendVersionMismatchWarning'
|
||||
@@ -78,7 +78,7 @@ import { useServerConfigStore } from '@/stores/serverConfigStore'
|
||||
import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'
|
||||
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
||||
import { useSidebarTabStore } from '@/stores/workspace/sidebarTabStore'
|
||||
import { electronAPI, isElectron } from '@/utils/envUtil'
|
||||
import { electronAPI } from '@/utils/envUtil'
|
||||
import LinearView from '@/views/LinearView.vue'
|
||||
import ManagerProgressToast from '@/workbench/extensions/manager/components/ManagerProgressToast.vue'
|
||||
|
||||
@@ -111,7 +111,7 @@ watch(
|
||||
document.body.classList.add(DARK_THEME_CLASS)
|
||||
}
|
||||
|
||||
if (isElectron()) {
|
||||
if (isDesktop) {
|
||||
electronAPI().changeTheme({
|
||||
color: 'rgba(0, 0, 0, 0)',
|
||||
symbolColor: newTheme.colors.comfy_base['input-text']
|
||||
@@ -121,7 +121,7 @@ watch(
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
if (isElectron()) {
|
||||
if (isDesktop) {
|
||||
watch(
|
||||
() => queueStore.tasks,
|
||||
(newTasks, oldTasks) => {
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, ref } from 'vue'
|
||||
|
||||
import { electronAPI, isElectron, isNativeWindow } from '@/utils/envUtil'
|
||||
import { electronAPI, isNativeWindow } from '@/utils/envUtil'
|
||||
import { isDesktop } from '@/platform/distribution/types'
|
||||
|
||||
const { dark = false } = defineProps<{
|
||||
dark?: boolean
|
||||
@@ -40,7 +41,7 @@ const lightTheme = {
|
||||
|
||||
const topMenuRef = ref<HTMLDivElement | null>(null)
|
||||
onMounted(async () => {
|
||||
if (isElectron()) {
|
||||
if (isDesktop) {
|
||||
await nextTick()
|
||||
|
||||
electronAPI().changeTheme({
|
||||
|
||||
Reference in New Issue
Block a user