4
4
<nav class =" help-menu-section" role =" menubar" >
5
5
<button
6
6
v-for =" menuItem in menuItems"
7
- v-show =" menuItem.visible !== false"
8
7
:key =" menuItem.key"
9
8
type =" button"
10
9
class =" help-menu-item"
30
29
@mouseenter =" onSubmenuHover"
31
30
@mouseleave =" onSubmenuLeave"
32
31
>
33
- <template
34
- v-for =" submenuItem in moreMenuItem ?.items "
35
- :key =" submenuItem .key "
36
- >
37
- <div
38
- v-if =" submenuItem.type === 'divider'"
39
- v-show =" submenuItem.visible !== false"
40
- class =" submenu-divider"
41
- />
32
+ <template v-for =" submenuItem in submenuItems " :key =" submenuItem .key " >
33
+ <div v-if =" submenuItem.type === 'divider'" class =" submenu-divider" />
42
34
<button
43
35
v-else
44
- v-show =" submenuItem.visible !== false"
45
36
type =" button"
46
37
class =" help-menu-item submenu-item"
38
+ :class =" { disabled: submenuItem.disabled }"
39
+ :disabled =" submenuItem.disabled"
47
40
role =" menuitem"
48
41
@click =" submenuItem.action"
49
42
>
72
65
<i class =" pi pi-refresh help-menu-icon" aria-hidden =" true" />
73
66
<div class =" release-content" >
74
67
<span class =" release-title" >
75
- {{
76
- $t('g.releaseTitle', {
77
- package: 'Comfy',
78
- version: release.version
79
- })
80
- }}
68
+ Comfy {{ release.version }} Release
81
69
</span >
82
70
<time class =" release-date" :datetime =" release.published_at" >
83
71
<span class =" normal-state" >
@@ -124,28 +112,32 @@ import { type CSSProperties, computed, nextTick, onMounted, ref } from 'vue'
124
112
import { useI18n } from ' vue-i18n'
125
113
126
114
import { type ReleaseNote } from ' @/services/releaseService'
127
- import { useCommandStore } from ' @/stores/commandStore'
128
115
import { useReleaseStore } from ' @/stores/releaseStore'
129
116
import { electronAPI , isElectron } from ' @/utils/envUtil'
130
117
import { formatVersionAnchor } from ' @/utils/formatUtil'
131
118
132
119
// Types
133
120
interface MenuItem {
134
121
key: string
135
- icon? : string
122
+ icon: string
123
+ label: string
124
+ action: () => void
125
+ }
126
+
127
+ interface SubmenuItem {
128
+ key: string
129
+ type? : ' item' | ' divider'
136
130
label? : string
137
131
action? : () => void
138
- visible? : boolean
139
- type? : ' item' | ' divider'
140
- items? : MenuItem []
132
+ disabled? : boolean
141
133
}
142
134
143
135
// Constants
144
136
const EXTERNAL_LINKS = {
145
137
DOCS: ' https://docs.comfy.org/' ,
146
138
DISCORD: ' https://www.comfy.org/discord' ,
147
139
GITHUB: ' https://github.com/comfyanonymous/ComfyUI' ,
148
- DESKTOP_GUIDE: ' https://comfyorg.notion.site/ ' ,
140
+ DESKTOP_GUIDE: ' https://docs.comfy.org/installation/desktop ' ,
149
141
UPDATE_GUIDE: ' https://docs.comfy.org/installation/update_comfyui'
150
142
} as const
151
143
@@ -167,12 +159,6 @@ const SUBMENU_CONFIG = {
167
159
// Composables
168
160
const { t, locale } = useI18n ()
169
161
const releaseStore = useReleaseStore ()
170
- const commandStore = useCommandStore ()
171
-
172
- // Emits
173
- const emit = defineEmits <{
174
- close: []
175
- }>()
176
162
177
163
// State
178
164
const isSubmenuVisible = ref (false )
@@ -183,99 +169,66 @@ let hoverTimeout: number | null = null
183
169
// Computed
184
170
const hasReleases = computed (() => releaseStore .releases .length > 0 )
185
171
186
- const moreMenuItem = computed (() =>
187
- menuItems .value .find ((item ) => item .key === ' more' )
188
- )
189
-
190
- const menuItems = computed <MenuItem []>(() => {
191
- const moreItems: MenuItem [] = [
192
- {
193
- key: ' desktop-guide' ,
194
- type: ' item' ,
195
- label: t (' helpCenter.desktopUserGuide' ),
196
- action : () => {
197
- openExternalLink (EXTERNAL_LINKS .DESKTOP_GUIDE )
198
- emit (' close' )
199
- }
200
- },
201
- {
202
- key: ' dev-tools' ,
203
- type: ' item' ,
204
- label: t (' helpCenter.openDevTools' ),
205
- visible: isElectron (),
206
- action : () => {
207
- openDevTools ()
208
- emit (' close' )
209
- }
210
- },
211
- {
212
- key: ' divider-1' ,
213
- type: ' divider' ,
214
- visible: isElectron ()
215
- },
216
- {
217
- key: ' reinstall' ,
218
- type: ' item' ,
219
- label: t (' helpCenter.reinstall' ),
220
- visible: isElectron (),
221
- action : () => {
222
- onReinstall ()
223
- emit (' close' )
224
- }
225
- }
226
- ]
227
-
228
- return [
229
- {
230
- key: ' docs' ,
231
- type: ' item' ,
232
- icon: ' pi pi-book' ,
233
- label: t (' helpCenter.docs' ),
234
- action : () => {
235
- openExternalLink (EXTERNAL_LINKS .DOCS )
236
- emit (' close' )
237
- }
238
- },
239
- {
240
- key: ' discord' ,
241
- type: ' item' ,
242
- icon: ' pi pi-discord' ,
243
- label: ' Discord' ,
244
- action : () => {
245
- openExternalLink (EXTERNAL_LINKS .DISCORD )
246
- emit (' close' )
247
- }
248
- },
249
- {
250
- key: ' github' ,
251
- type: ' item' ,
252
- icon: ' pi pi-github' ,
253
- label: t (' helpCenter.github' ),
254
- action : () => {
255
- openExternalLink (EXTERNAL_LINKS .GITHUB )
256
- emit (' close' )
257
- }
258
- },
259
- {
260
- key: ' help' ,
261
- type: ' item' ,
262
- icon: ' pi pi-question-circle' ,
263
- label: t (' helpCenter.helpFeedback' ),
264
- action : () => {
265
- void commandStore .execute (' Comfy.Feedback' )
266
- emit (' close' )
267
- }
268
- },
269
- {
270
- key: ' more' ,
271
- type: ' item' ,
272
- icon: ' ' ,
273
- label: t (' helpCenter.more' ),
274
- action : () => {}, // No action for more item
275
- items: moreItems
276
- }
277
- ]
278
- })
172
+ const menuItems = computed <MenuItem []>(() => [
173
+ {
174
+ key: ' docs' ,
175
+ icon: ' pi pi-book' ,
176
+ label: t (' helpCenter.docs' ),
177
+ action : () => openExternalLink (EXTERNAL_LINKS .DOCS )
178
+ },
179
+ {
180
+ key: ' discord' ,
181
+ icon: ' pi pi-discord' ,
182
+ label: ' Discord' ,
183
+ action : () => openExternalLink (EXTERNAL_LINKS .DISCORD )
184
+ },
185
+ {
186
+ key: ' github' ,
187
+ icon: ' pi pi-github' ,
188
+ label: t (' helpCenter.github' ),
189
+ action : () => openExternalLink (EXTERNAL_LINKS .GITHUB )
190
+ },
191
+ {
192
+ key: ' help' ,
193
+ icon: ' pi pi-question-circle' ,
194
+ label: t (' helpCenter.helpFeedback' ),
195
+ action : () => openExternalLink (EXTERNAL_LINKS .DISCORD )
196
+ },
197
+ {
198
+ key: ' more' ,
199
+ icon: ' ' ,
200
+ label: t (' helpCenter.more' ),
201
+ action : () => {} // No action for more item
202
+ }
203
+ ])
204
+
205
+ const submenuItems = computed <SubmenuItem []>(() => [
206
+ {
207
+ key: ' desktop-guide' ,
208
+ type: ' item' ,
209
+ label: t (' helpCenter.desktopUserGuide' ),
210
+ action : () => openExternalLink (EXTERNAL_LINKS .DESKTOP_GUIDE ),
211
+ disabled: false
212
+ },
213
+ {
214
+ key: ' dev-tools' ,
215
+ type: ' item' ,
216
+ label: t (' helpCenter.openDevTools' ),
217
+ action: openDevTools ,
218
+ disabled: ! isElectron ()
219
+ },
220
+ {
221
+ key: ' divider-1' ,
222
+ type: ' divider'
223
+ },
224
+ {
225
+ key: ' reinstall' ,
226
+ type: ' item' ,
227
+ label: t (' helpCenter.reinstall' ),
228
+ action: onReinstall ,
229
+ disabled: ! isElectron ()
230
+ }
231
+ ])
279
232
280
233
// Utility Functions
281
234
const openExternalLink = (url : string ): void => {
@@ -293,12 +246,8 @@ const calculateSubmenuPosition = (button: HTMLElement): CSSProperties => {
293
246
const rect = button .getBoundingClientRect ()
294
247
const submenuWidth = 210 // Width defined in CSS
295
248
296
- // Get actual submenu height if available, otherwise estimate based on visible item count
297
- const visibleItemCount =
298
- moreMenuItem .value ?.items ?.filter ((item ) => item .visible !== false )
299
- .length || 0
300
- const estimatedHeight = visibleItemCount * 48 + 16 // ~48px per item + padding
301
- const submenuHeight = submenuRef .value ?.offsetHeight || estimatedHeight
249
+ // Get actual submenu height if available, otherwise use estimated height
250
+ const submenuHeight = submenuRef .value ?.offsetHeight || 120 // More realistic estimate for 2 items
302
251
303
252
// Get viewport dimensions
304
253
const viewportWidth = window .innerWidth
@@ -328,8 +277,6 @@ const calculateSubmenuPosition = (button: HTMLElement): CSSProperties => {
328
277
top = SUBMENU_CONFIG .OFFSET_PX
329
278
}
330
279
331
- top -= 8
332
-
333
280
return {
334
281
position: ' fixed' ,
335
282
top: ` ${top }px ` ,
@@ -376,13 +323,7 @@ const onMenuItemHover = async (
376
323
key : string ,
377
324
event : MouseEvent
378
325
): Promise <void > => {
379
- if (key !== ' more' || ! moreMenuItem .value ?.items ) return
380
-
381
- // Don't show submenu if all items are hidden
382
- const hasVisibleItems = moreMenuItem .value .items .some (
383
- (item ) => item .visible !== false
384
- )
385
- if (! hasVisibleItems ) return
326
+ if (key !== ' more' ) return
386
327
387
328
clearHoverTimeout ()
388
329
@@ -434,12 +375,10 @@ const onReleaseClick = (release: ReleaseNote): void => {
434
375
const versionAnchor = formatVersionAnchor (release .version )
435
376
const changelogUrl = ` ${getChangelogUrl ()}#${versionAnchor } `
436
377
openExternalLink (changelogUrl )
437
- emit (' close' )
438
378
}
439
379
440
380
const onUpdate = (_ : ReleaseNote ): void => {
441
381
openExternalLink (EXTERNAL_LINKS .UPDATE_GUIDE )
442
- emit (' close' )
443
382
}
444
383
445
384
// Generate language-aware changelog URL
@@ -607,6 +546,13 @@ onMounted(async () => {
607
546
box-shadow : none ;
608
547
}
609
548
549
+ .submenu-item.disabled ,
550
+ .submenu-item :disabled {
551
+ opacity : 0.5 ;
552
+ cursor : not-allowed ;
553
+ pointer-events : none ;
554
+ }
555
+
610
556
.submenu-divider {
611
557
height : 1px ;
612
558
background : #3e3e3e ;
0 commit comments