mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
## 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)
116 lines
2.8 KiB
Vue
116 lines
2.8 KiB
Vue
<template>
|
|
<div
|
|
ref="rootEl"
|
|
class="relative h-full w-full overflow-hidden bg-neutral-900"
|
|
>
|
|
<div class="p-terminal h-full w-full rounded-none p-2">
|
|
<div ref="terminalEl" class="terminal-host h-full" />
|
|
</div>
|
|
<Button
|
|
v-tooltip.left="{
|
|
value: tooltipText,
|
|
showDelay: 300
|
|
}"
|
|
variant="secondary"
|
|
size="sm"
|
|
:class="
|
|
cn('absolute top-2 right-8 transition-opacity', {
|
|
'opacity-0 pointer-events-none select-none': !isHovered
|
|
})
|
|
"
|
|
:aria-label="tooltipText"
|
|
@click="handleCopy"
|
|
>
|
|
<i class="pi pi-copy" />
|
|
</Button>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { useElementHover, useEventListener } from '@vueuse/core'
|
|
import type { IDisposable } from '@xterm/xterm'
|
|
import type { Ref } from 'vue'
|
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
import Button from '@/components/ui/button/Button.vue'
|
|
import { useTerminal } from '@/composables/bottomPanelTabs/useTerminal'
|
|
import { electronAPI } from '@/utils/envUtil'
|
|
import { isDesktop } from '@/platform/distribution/types'
|
|
import { cn } from '@/utils/tailwindUtil'
|
|
|
|
const { t } = useI18n()
|
|
|
|
const emit = defineEmits<{
|
|
created: [ReturnType<typeof useTerminal>, Ref<HTMLElement | undefined>]
|
|
unmounted: []
|
|
}>()
|
|
const terminalEl = ref<HTMLElement | undefined>()
|
|
const rootEl = ref<HTMLElement | undefined>()
|
|
const hasSelection = ref(false)
|
|
|
|
const isHovered = useElementHover(rootEl)
|
|
|
|
const terminalData = useTerminal(terminalEl)
|
|
emit('created', terminalData, ref(rootEl))
|
|
|
|
const { terminal } = terminalData
|
|
let selectionDisposable: IDisposable | undefined
|
|
|
|
const tooltipText = computed(() => {
|
|
return hasSelection.value
|
|
? t('serverStart.copySelectionTooltip')
|
|
: t('serverStart.copyAllTooltip')
|
|
})
|
|
|
|
const handleCopy = async () => {
|
|
const existingSelection = terminal.getSelection()
|
|
const shouldSelectAll = !existingSelection
|
|
if (shouldSelectAll) terminal.selectAll()
|
|
|
|
const selectedText = shouldSelectAll
|
|
? terminal.getSelection()
|
|
: existingSelection
|
|
|
|
if (selectedText) {
|
|
await navigator.clipboard.writeText(selectedText)
|
|
|
|
if (shouldSelectAll) {
|
|
terminal.clearSelection()
|
|
}
|
|
}
|
|
}
|
|
|
|
const showContextMenu = (event: MouseEvent) => {
|
|
event.preventDefault()
|
|
electronAPI()?.showContextMenu({ type: 'text' })
|
|
}
|
|
|
|
if (isDesktop) {
|
|
useEventListener(terminalEl, 'contextmenu', showContextMenu)
|
|
}
|
|
|
|
onMounted(() => {
|
|
selectionDisposable = terminal.onSelectionChange(() => {
|
|
hasSelection.value = terminal.hasSelection()
|
|
})
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
selectionDisposable?.dispose()
|
|
emit('unmounted')
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
@reference '../../../../assets/css/style.css';
|
|
|
|
:deep(.p-terminal) .xterm {
|
|
@apply overflow-hidden;
|
|
}
|
|
|
|
:deep(.p-terminal) .xterm-screen {
|
|
@apply bg-neutral-900 overflow-hidden;
|
|
}
|
|
</style>
|