Compare commits

...

6 Commits

Author SHA1 Message Date
Terry Jia
cb3c415065 [3d] flash preview screen board if reach out limitation 2025-02-19 15:30:38 -05:00
Terry Jia
d3ab23a532 [3d] flash preview screen board if reach out limitation 2025-02-19 15:27:22 -05:00
filtered
08a6867c00 [Desktop] Offer Troubleshoot page instead of Reinstall on start error (#2623)
Co-authored-by: github-actions <github-actions@github.com>
2025-02-19 10:30:23 -05:00
filtered
dbbe67dfcd [Desktop] Fix missing git logo in troubleshooting (#2633) 2025-02-19 10:29:48 -05:00
bymyself
40fa1d37bc Fix pasting image that was copied from browser (#2630) 2025-02-19 10:27:58 -05:00
filtered
0d6bc669f5 [Desktop] Fix invalid type assertion in API (#2631) 2025-02-19 21:59:17 +11:00
17 changed files with 108 additions and 53 deletions

8
package-lock.json generated
View File

@@ -10,7 +10,7 @@
"license": "GPL-3.0-only",
"dependencies": {
"@atlaskit/pragmatic-drag-and-drop": "^1.3.1",
"@comfyorg/comfyui-electron-types": "^0.4.16",
"@comfyorg/comfyui-electron-types": "^0.4.20",
"@comfyorg/litegraph": "^0.8.87",
"@primevue/forms": "^4.2.5",
"@primevue/themes": "^4.2.5",
@@ -1938,9 +1938,9 @@
"dev": true
},
"node_modules/@comfyorg/comfyui-electron-types": {
"version": "0.4.16",
"resolved": "https://registry.npmjs.org/@comfyorg/comfyui-electron-types/-/comfyui-electron-types-0.4.16.tgz",
"integrity": "sha512-AKy4WLVAuDka/Xjv8zrKwfU/wfRSQpFVE5DgxoLfvroCI0sw+rV1JqdL6xFVrYIoeprzbfKhQiyqlAWU+QgHyg==",
"version": "0.4.20",
"resolved": "https://registry.npmjs.org/@comfyorg/comfyui-electron-types/-/comfyui-electron-types-0.4.20.tgz",
"integrity": "sha512-JFKGk9wSx7CcYh9MRNo7bqTLJwQzVc+1Xg8V2Ghn9BS3RzpmkfktaWHi+waU7/CRQMzvjF+mnDPP58xk1xbVhA==",
"license": "GPL-3.0-only"
},
"node_modules/@comfyorg/litegraph": {

View File

@@ -83,7 +83,7 @@
},
"dependencies": {
"@atlaskit/pragmatic-drag-and-drop": "^1.3.1",
"@comfyorg/comfyui-electron-types": "^0.4.16",
"@comfyorg/comfyui-electron-types": "^0.4.20",
"@comfyorg/litegraph": "^0.8.87",
"@primevue/forms": "^4.2.5",
"@primevue/themes": "^4.2.5",

View File

@@ -13,7 +13,7 @@
:aria-label="$t('menu.showMenu')"
aria-live="assertive"
@click="exitFocusMode"
@contextmenu="showNativeMenu"
@contextmenu="showNativeSystemMenu"
/>
<div v-show="menuSetting !== 'Bottom'" class="window-actions-spacer" />
</div>
@@ -26,7 +26,7 @@ import { CSSProperties, computed, watchEffect } from 'vue'
import { app } from '@/scripts/app'
import { useSettingStore } from '@/stores/settingStore'
import { useWorkspaceStore } from '@/stores/workspaceStore'
import { showNativeMenu } from '@/utils/envUtil'
import { showNativeSystemMenu } from '@/utils/envUtil'
const workspaceState = useWorkspaceStore()
const settingStore = useSettingStore()

View File

@@ -21,7 +21,7 @@
v-tooltip="{ value: $t('menu.hideMenu'), showDelay: 300 }"
:aria-label="$t('menu.hideMenu')"
@click="workspaceState.focusMode = true"
@contextmenu="showNativeMenu"
@contextmenu="showNativeSystemMenu"
/>
<div
v-show="menuSetting !== 'Bottom'"
@@ -52,7 +52,7 @@ import {
electronAPI,
isElectron,
isNativeWindow,
showNativeMenu
showNativeSystemMenu
} from '@/utils/envUtil'
const workspaceState = useWorkspaceStore()

View File

@@ -27,7 +27,7 @@ export const DESKTOP_MAINTENANCE_TASKS: Readonly<MaintenanceTask>[] = [
},
{
id: 'git',
headerImg: '/assets/images/Git-Logo-White.svg',
headerImg: 'assets/images/Git-Logo-White.svg',
execute: () => openUrl('https://git-scm.com/downloads/'),
name: 'Download git',
shortDescription: 'Open the git download page.',

View File

@@ -198,24 +198,37 @@ class Load3d {
this.previewContainer = document.createElement('div')
this.previewContainer.style.cssText = `
position: absolute;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.2);
display: block;
`
position: absolute;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.2);
display: block;
transition: border-color 0.1s ease;
`
this.previewContainer.appendChild(this.previewRenderer.domElement)
const MIN_PREVIEW_WIDTH = 120
const MAX_PREVIEW_WIDTH = 240
this.previewContainer.addEventListener('wheel', (event) => {
event.preventDefault()
event.stopPropagation()
const delta = event.deltaY
const oldWidth = this.previewWidth
if (delta > 0) {
this.previewWidth = Math.max(120, this.previewWidth - 10)
this.previewWidth = Math.max(MIN_PREVIEW_WIDTH, this.previewWidth - 10)
} else {
this.previewWidth = Math.min(240, this.previewWidth + 10)
this.previewWidth = Math.min(MAX_PREVIEW_WIDTH, this.previewWidth + 10)
}
if (
oldWidth !== this.previewWidth &&
(this.previewWidth === MIN_PREVIEW_WIDTH ||
this.previewWidth === MAX_PREVIEW_WIDTH)
) {
this.flashPreviewBorder()
}
this.updatePreviewSize()
@@ -227,6 +240,19 @@ class Load3d {
container.appendChild(this.previewContainer)
}
flashPreviewBorder() {
const originalBorder = this.previewContainer.style.border
const originalBoxShadow = this.previewContainer.style.boxShadow
this.previewContainer.style.border = '2px solid rgba(255, 255, 255, 0.8)'
this.previewContainer.style.boxShadow = '0 0 8px rgba(255, 255, 255, 0.5)'
setTimeout(() => {
this.previewContainer.style.border = originalBorder
this.previewContainer.style.boxShadow = originalBoxShadow
}, 100)
}
updatePreviewRender() {
if (!this.previewRenderer || !this.previewContainer || !this.showPreview)
return

View File

@@ -264,7 +264,7 @@
"updateConsent": "You previously opted in to reporting crashes. We are now tracking event-based metrics to help identify bugs and improve the app. No personal identifiable information is collected."
},
"serverStart": {
"reinstall": "Reinstall",
"troubleshoot": "Troubleshoot",
"reportIssue": "Report Issue",
"openLogs": "Open Logs",
"showTerminal": "Show Terminal",

View File

@@ -654,9 +654,9 @@
"ready": "Finalisation...",
"starting-server": "Démarrage du serveur ComfyUI..."
},
"reinstall": "Réinstaller",
"reportIssue": "Signaler un problème",
"showTerminal": "Afficher le terminal"
"showTerminal": "Afficher le terminal",
"troubleshoot": "Dépannage"
},
"settingsCategories": {
"About": "À Propos",

View File

@@ -654,9 +654,9 @@
"ready": "完了中...",
"starting-server": "ComfyUIサーバーを起動中..."
},
"reinstall": "再インストール",
"reportIssue": "問題を報告",
"showTerminal": "ターミナルを表示"
"showTerminal": "ターミナルを表示",
"troubleshoot": "トラブルシューティング"
},
"settingsCategories": {
"About": "情報",

View File

@@ -654,9 +654,9 @@
"ready": "마무리 중...",
"starting-server": "ComfyUI 서버 시작 중..."
},
"reinstall": "재설치",
"reportIssue": "문제 보고",
"showTerminal": "터미널 보기"
"showTerminal": "터미널 보기",
"troubleshoot": "문제 해결"
},
"settingsCategories": {
"About": "정보",

View File

@@ -654,9 +654,9 @@
"ready": "Завершение…",
"starting-server": "Запуск сервера ComfyUI…"
},
"reinstall": "Переустановить",
"reportIssue": "Сообщить о проблеме",
"showTerminal": "Показать терминал"
"showTerminal": "Показать терминал",
"troubleshoot": "Устранение неполадок"
},
"settingsCategories": {
"About": "О программе",

View File

@@ -654,9 +654,9 @@
"ready": "完成中...",
"starting-server": "正在启动 ComfyUI 服务器..."
},
"reinstall": "重新安装",
"reportIssue": "报告问题",
"showTerminal": "显示终端"
"showTerminal": "显示终端",
"troubleshoot": "故障排除"
},
"settingsCategories": {
"About": "关于",

View File

@@ -3,15 +3,14 @@ import { defineStore } from 'pinia'
import { api } from '@/scripts/api'
import { ExecutedWsMessage, ResultItem } from '@/types/apiTypes'
import { parseFilePath } from '@/utils/formatUtil'
const toOutputs = (
filenames: string[],
type: string
): ExecutedWsMessage['output'] => {
return {
images: filenames.map((image) => {
return { filename: image, subfolder: '', type }
})
images: filenames.map((image) => ({ type, ...parseFilePath(image) }))
}
}

View File

@@ -1,7 +1,4 @@
import {
ElectronAPI,
ElectronContextMenuOptions
} from '@comfyorg/comfyui-electron-types'
import { ElectronAPI } from '@comfyorg/comfyui-electron-types'
export function isElectron() {
return 'electronAPI' in window && window.electronAPI !== undefined
@@ -11,8 +8,8 @@ export function electronAPI() {
return (window as any).electronAPI as ElectronAPI
}
export function showNativeMenu(event: MouseEvent) {
electronAPI()?.showContextMenu(event as ElectronContextMenuOptions)
export function showNativeSystemMenu() {
electronAPI()?.showContextMenu()
}
export function isNativeWindow() {

View File

@@ -232,3 +232,41 @@ export function createAnnotatedPath(
return `${createPath(item, subfolder)}${createAnnotation(rootFolder)}`
return `${createPath(item.filename ?? '', item.subfolder)}${createAnnotation(item.type)}`
}
/**
* Parses a filepath into its filename and subfolder components.
*
* @example
* parseFilePath('folder/file.txt') // → { filename: 'file.txt', subfolder: 'folder' }
* parseFilePath('/folder/file.txt') // → { filename: 'file.txt', subfolder: 'folder' }
* parseFilePath('file.txt') // → { filename: 'file.txt', subfolder: '' }
* parseFilePath('folder//file.txt') // → { filename: 'file.txt', subfolder: 'folder' }
*
* @param filepath The filepath to parse
* @returns Object containing filename and subfolder
*/
export function parseFilePath(filepath: string): {
filename: string
subfolder: string
} {
if (!filepath?.trim()) return { filename: '', subfolder: '' }
const normalizedPath = filepath
.replace(/[\\/]+/g, '/') // Normalize path separators
.replace(/^\//, '') // Remove leading slash
.replace(/\/$/, '') // Remove trailing slash
const lastSlashIndex = normalizedPath.lastIndexOf('/')
if (lastSlashIndex === -1) {
return {
filename: normalizedPath,
subfolder: ''
}
}
return {
filename: normalizedPath.slice(lastSlashIndex + 1),
subfolder: normalizedPath.slice(0, lastSlashIndex)
}
}

View File

@@ -135,12 +135,12 @@ const filterOptions = ref([
])
/** Filter binding; can be set to show all tasks, or only errors. */
const filter = ref<MaintenanceFilter>(filterOptions.value[1])
const filter = ref<MaintenanceFilter>(filterOptions.value[0])
/** If valid, leave the validation window. */
const completeValidation = async (alertOnFail = true) => {
const completeValidation = async () => {
const isValid = await electron.Validation.complete()
if (alertOnFail && !isValid) {
if (!isValid) {
toast.add({
severity: 'error',
summary: t('g.error'),
@@ -162,18 +162,13 @@ watch(
}
)
// If we're running a fix that may resolve all issues, auto-recheck and continue if everything is OK
watch(
() => taskStore.isRunningInstallationFix,
(value, oldValue) => {
if (!value && oldValue) completeValidation(false)
}
)
onMounted(async () => {
electron.Validation.onUpdate(processUpdate)
const update = await electron.Validation.getStatus()
if (Object.values(update).some((x) => x === 'error')) {
filter.value = filterOptions.value[1]
}
processUpdate(update)
})

View File

@@ -25,9 +25,9 @@
@click="openLogs"
/>
<Button
icon="pi pi-refresh"
:label="t('serverStart.reinstall')"
@click="reinstall"
icon="pi pi-wrench"
:label="t('serverStart.troubleshoot')"
@click="troubleshoot"
/>
</div>
<Button
@@ -88,7 +88,7 @@ const terminalCreated = (
terminal.options.cursorInactiveStyle = 'block'
}
const reinstall = () => electron.reinstall()
const troubleshoot = () => electron.startTroubleshooting()
const reportIssue = () => {
window.open('https://forum.comfy.org/c/v1-feedback/', '_blank')
}